quick update for garmin

This commit is contained in:
Brett Weiland 2025-09-03 09:37:50 -05:00
parent 91a1a81d96
commit 558ace6e76
123 changed files with 37923 additions and 26779 deletions

View File

@ -1,17 +0,0 @@
LCSC Part,Mfr. Part #,Mfr. #,Customer#,Quantity,Target Price($),Target Lead Time,Unit Price($),Ext Price($),Lead Time (business days),Pricing Valid,Remarks,Status
C2888573,TSD003A04126A02,BZCN,,150,-,,-,-,,,,Inquiring
C8734,STM32F103C8T6,STMicroelectronics,,15,-,,-,-,,,,Inquiring
C2890616,N096-1608TBBIG11-H13,Newvisio,,15,-,,-,-,,,,Inquiring
C182965,MT9216,XI'AN Aerosemi Tech,,20,-,,-,-,,,,Inquiring
C1607,CL10A225KP8NNNC,Samsung Electro-Mechanics,,100,-,,-,-,,,,Inquiring
C42412253,F8-4.3-4-0.4Z,Sam&wing,,60,-,,-,-,,,,Inquiring
C5137636,FCC0603B104K500CT,FOJAN,,200,-,,-,-,,,,Inquiring
C6119842,CGA0603X5R106K100JT,HRE,,100,-,,-,-,,,,Inquiring
C100044,RC0603FR-070RL,YAGEO,,100,-,,-,-,,,,Inquiring
C14675,RC0603FR-07100KL,YAGEO,,100,-,,-,-,,,,Inquiring
C2907113,FRC0603J102 TS,FOJAN,,100,-,,-,-,,,,Inquiring
C2930027,FRC0603J103TS,FOJAN,,100,-,,-,-,,,,Inquiring
C2929429,CY54-4.7UH,SHOU HAN,,20,-,,-,-,,,,Inquiring
C8032,CL10A475KQ8NNNC,Samsung Electro-Mechanics,,50,-,,-,-,,,,Inquiring
C1653,CL10C220JB8NNNC,Samsung Electro-Mechanics,,100,-,,-,-,,,,Inquiring
C3013969,AR05BTCW4003,Viking Tech,,20,-,,-,-,,,,Inquiring
1 LCSC Part Mfr. Part # Mfr. # Customer# Quantity Target Price($) Target Lead Time Unit Price($) Ext Price($) Lead Time (business days) Pricing Valid Remarks Status
2 C2888573 TSD003A04126A02 BZCN 150 - - - Inquiring
3 C8734 STM32F103C8T6 STMicroelectronics 15 - - - Inquiring
4 C2890616 N096-1608TBBIG11-H13 Newvisio 15 - - - Inquiring
5 C182965 MT9216 XI'AN Aerosemi Tech 20 - - - Inquiring
6 C1607 CL10A225KP8NNNC Samsung Electro-Mechanics 100 - - - Inquiring
7 C42412253 F8-4.3-4-0.4Z Sam&wing 60 - - - Inquiring
8 C5137636 FCC0603B104K500CT FOJAN 200 - - - Inquiring
9 C6119842 CGA0603X5R106K100JT HRE 100 - - - Inquiring
10 C100044 RC0603FR-070RL YAGEO 100 - - - Inquiring
11 C14675 RC0603FR-07100KL YAGEO 100 - - - Inquiring
12 C2907113 FRC0603J102 TS FOJAN 100 - - - Inquiring
13 C2930027 FRC0603J103TS FOJAN 100 - - - Inquiring
14 C2929429 CY54-4.7UH SHOU HAN 20 - - - Inquiring
15 C8032 CL10A475KQ8NNNC Samsung Electro-Mechanics 50 - - - Inquiring
16 C1653 CL10C220JB8NNNC Samsung Electro-Mechanics 100 - - - Inquiring
17 C3013969 AR05BTCW4003 Viking Tech 20 - - - Inquiring

View File

@ -1,3 +1,7 @@
# THIS README IS NOW OUTDATED. THE PROJECT IS WAY COOLER AND AN ARTICLE IS COMING SOON!
I've implimented my own border tracing algorithim to dramatically speed up rendering. There's a few other optimizations, such as shifting around image buffers, etc. <br>
Software is still in disarray and could be optimized, however it runs smoothly. Hardware is working, I haven't had time to test all functionallity though. The battery does charge and discharge safely (cut off at 1v).<br>
# STM32 Mandelbrot Explorer Buisness Card
A battery powered business card that can explore the Mandelbrot set. Meant to be cheaply made for handing out. Will likely include a flappy bird clone to encourage recruiter competition.
# Project in development! See below for a brief write up.

30
buyme
View File

@ -1,30 +0,0 @@
bat charger - imported
2 22uf ceramic capacitors (done)
leds+resistors (done)
in+out filters: 22uf (done)
20 must take 1a
timing capacitor (done) - 270nF
schotty diode (done)
inductor (done)
bat to 3v - imported
100nf/.1uf cap (done)
2 10/22uf caps (done)
check 4.7 uh inductor (done)
usb to 3v
voltage div resistors (done)
2 1uf ceramic caps (done)
comparator - imported
boost converter is high=on
1uf caps (done)
1uf between vdd/gnd (done)
1000pf between vout and gnd (done)
15nF timer cap (done)
TODO:
check list
check layout
set inductors

BIN
datasheets/AO3400.pdf Normal file

Binary file not shown.

BIN
datasheets/AO3401.pdf Normal file

Binary file not shown.

BIN
imgs/border_demo.mkv Normal file

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,19 @@
{
"board": {
"active_layer": 0,
"active_layer_preset": "Front Layers",
"active_layer_preset": "",
"auto_track_width": true,
"hidden_netclasses": [],
"hidden_nets": [],
"high_contrast_mode": 0,
"net_color_mode": 1,
"opacity": {
"images": 0.5299999713897705,
"images": 1.0,
"pads": 1.0,
"shapes": 1.0,
"tracks": 1.0,
"vias": 1.0,
"zones": 0.7300000190734863
"zones": 0.7099999785423279
},
"selection_filter": {
"dimensions": true,
@ -36,7 +36,6 @@
"footprints_front",
"footprints_back",
"footprint_values",
"footprint_references",
"tracks",
"drc_errors",
"drawing_sheet",

View File

@ -37,9 +37,9 @@
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.762,
"height": 1.524,
"width": 1.524
"drill": 0.6,
"height": 1.7,
"width": 1.1
},
"silk_line_width": 0.1,
"silk_text_italic": false,
@ -528,7 +528,7 @@
"gencad": "",
"idf": "",
"netlist": "",
"plot": "../../v2_output_thermalpads/",
"plot": "../../v3_career_fair/",
"pos_files": "",
"specctra_dsn": "",
"step": "",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"hostname":"indigo","username":"indigo"}

View File

@ -1 +0,0 @@
{"hostname":"indigosDesktop","username":"indigo"}

View File

@ -1 +0,0 @@
{"hostname":"indigosDesktop","username":"indigo"}

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.2*%
%TF.CreationDate,2025-07-13T16:14:15-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Bot*%
%TF.FilePolarity,Negative*%
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:41-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Soldermask,Bot*
G04 #@! TF.FilePolarity,Negative*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.2) date 2025-07-13 16:14:15*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:41*
%MOMM*%
%LPD*%
G01*
@ -552,10 +552,8 @@ X187824358Y-89246001D01*
X187824358Y-90312671D01*
G37*
D11*
%TO.C,J1*%
X146394466Y-88130000D03*
X146394466Y-84330000D03*
X137754466Y-88130000D03*
X137754466Y-84330000D03*
%TD*%
X137754466Y-88130000D03*
M02*

View File

@ -0,0 +1,15 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:40-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Paste,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:40*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.2*%
%TF.CreationDate,2025-07-13T16:14:14-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Legend,Bot*%
%TF.FilePolarity,Positive*%
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:40-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Legend,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.2) date 2025-07-13 16:14:14*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:40*
%MOMM*%
%LPD*%
G01*
@ -4159,7 +4159,6 @@ X200530439Y-101470705D01*
X200530439Y-100759225D01*
G37*
D11*
%TO.C,G\u002A\u002A\u002A*%
G36*
X116961419Y-110351990D02*
G01*
@ -38655,7 +38654,6 @@ X148277451Y-72572242D01*
X148258898Y-72603373D01*
X148173873Y-72746043D01*
G37*
%TD*%
%LPC*%
D12*
G36*
@ -39195,11 +39193,9 @@ X187824358Y-89246001D01*
X187824358Y-90312671D01*
G37*
D13*
%TO.C,J1*%
X146394466Y-88130000D03*
X146394466Y-84330000D03*
X137754466Y-88130000D03*
X137754466Y-84330000D03*
%TD*%
X137754466Y-88130000D03*
%LPD*%
M02*

View File

@ -1,18 +1,18 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.2*%
%TF.CreationDate,2025-07-13T16:14:15-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Profile,NP*%
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:41-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Profile,NP*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.2) date 2025-07-13 16:14:15*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:41*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%TA.AperFunction,Profile*%
G04 #@! TA.AperFunction,Profile*
%ADD10C,0.050000*%
%TD*%
G04 #@! TD*
G04 APERTURE END LIST*
D10*
X137564466Y-132335534D02*

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,424 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:41-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Soldermask,Top*
G04 #@! TF.FilePolarity,Negative*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:41*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
%ADD11RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
%ADD12R,1.800000X1.200000*%
%ADD13RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*%
%ADD14RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
%ADD15R,3.000000X5.500000*%
%ADD16RoundRect,0.200000X-0.275000X0.200000X-0.275000X-0.200000X0.275000X-0.200000X0.275000X0.200000X0*%
%ADD17RoundRect,0.200000X0.275000X-0.200000X0.275000X0.200000X-0.275000X0.200000X-0.275000X-0.200000X0*%
%ADD18RoundRect,0.200000X0.200000X0.275000X-0.200000X0.275000X-0.200000X-0.275000X0.200000X-0.275000X0*%
%ADD19R,3.500000X2.350000*%
%ADD20C,2.000000*%
%ADD21RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD22RoundRect,0.200000X-0.200000X-0.275000X0.200000X-0.275000X0.200000X0.275000X-0.200000X0.275000X0*%
%ADD23RoundRect,0.112500X0.112500X-0.187500X0.112500X0.187500X-0.112500X0.187500X-0.112500X-0.187500X0*%
%ADD24RoundRect,0.250000X0.650000X-1.000000X0.650000X1.000000X-0.650000X1.000000X-0.650000X-1.000000X0*%
%ADD25R,2.200000X0.400000*%
%ADD26RoundRect,0.100000X-0.225000X-0.100000X0.225000X-0.100000X0.225000X0.100000X-0.225000X0.100000X0*%
%ADD27R,6.450000X5.300000*%
%ADD28RoundRect,0.150000X0.150000X-0.587500X0.150000X0.587500X-0.150000X0.587500X-0.150000X-0.587500X0*%
%ADD29RoundRect,0.102000X0.350000X0.600000X-0.350000X0.600000X-0.350000X-0.600000X0.350000X-0.600000X0*%
%ADD30RoundRect,0.102000X0.380000X0.600000X-0.380000X0.600000X-0.380000X-0.600000X0.380000X-0.600000X0*%
%ADD31RoundRect,0.102000X0.400000X0.600000X-0.400000X0.600000X-0.400000X-0.600000X0.400000X-0.600000X0*%
%ADD32O,1.304000X1.904000*%
%ADD33RoundRect,0.243750X0.456250X-0.243750X0.456250X0.243750X-0.456250X0.243750X-0.456250X-0.243750X0*%
%ADD34R,1.070000X0.530000*%
%ADD35RoundRect,0.150000X0.587500X0.150000X-0.587500X0.150000X-0.587500X-0.150000X0.587500X-0.150000X0*%
%ADD36R,1.200000X0.270000*%
%ADD37R,0.270000X1.200000*%
%ADD38R,1.200000X1.800000*%
%ADD39RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD40R,0.600000X1.000000*%
%ADD41R,1.200000X0.600000*%
%ADD42R,2.400000X3.300000*%
%ADD43RoundRect,0.100000X-0.100000X0.225000X-0.100000X-0.225000X0.100000X-0.225000X0.100000X0.225000X0*%
%ADD44RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD45R,1.200000X0.500000*%
G04 APERTURE END LIST*
D10*
X186594442Y-122410210D03*
X188144442Y-122410210D03*
D11*
X168458966Y-118260712D03*
X166908966Y-118260712D03*
D10*
X158188180Y-107195974D03*
X159738180Y-107195974D03*
D12*
X202951133Y-104665534D03*
X210951133Y-104665534D03*
X202951133Y-109165534D03*
X210951133Y-109165534D03*
D10*
X186498159Y-120535261D03*
X188048159Y-120535261D03*
D13*
X163141120Y-116686961D03*
X163141120Y-118586961D03*
X165016120Y-117636961D03*
D14*
X159771321Y-108741969D03*
X159771321Y-110291969D03*
D15*
X158924572Y-102960590D03*
X154264572Y-102960590D03*
D16*
X148272523Y-93543316D03*
X148272523Y-95193316D03*
D17*
X161212267Y-117283573D03*
X161212267Y-115633573D03*
D14*
X148265612Y-90338172D03*
X148265612Y-91888172D03*
D18*
X161041538Y-127096790D03*
X159391538Y-127096790D03*
D19*
X151018909Y-89007494D03*
X151018909Y-83307494D03*
D20*
X164428408Y-125040799D03*
X164428408Y-129563379D03*
D21*
X150718124Y-96870191D03*
X152618124Y-96870191D03*
D22*
X174374351Y-129940450D03*
X176024351Y-129940450D03*
X158138180Y-111847959D03*
X159788180Y-111847959D03*
D10*
X176162472Y-126786884D03*
X177712472Y-126786884D03*
D23*
X156386756Y-120670500D03*
X156386756Y-118570500D03*
D24*
X150343692Y-117402201D03*
X150343692Y-113402201D03*
D25*
X174559466Y-111035534D03*
X174559466Y-110335534D03*
X174559466Y-109635534D03*
X174559466Y-108935534D03*
X174559466Y-108235534D03*
X174559466Y-107535534D03*
X174559466Y-106835534D03*
X174559466Y-106135534D03*
X174559466Y-105435534D03*
X174559466Y-104735534D03*
X174559466Y-104035534D03*
X174559466Y-103335534D03*
X174559466Y-102635534D03*
D10*
X178467267Y-124578690D03*
X180017267Y-124578690D03*
D18*
X171606612Y-129942382D03*
X169956612Y-129942382D03*
D20*
X138326311Y-91051939D03*
D26*
X158155852Y-120238248D03*
X158155852Y-120888248D03*
X158155852Y-121538248D03*
X160055852Y-121538248D03*
X160055852Y-120888248D03*
X160055852Y-120238248D03*
D16*
X142831133Y-89980534D03*
X142831133Y-91630534D03*
D18*
X156601572Y-97546454D03*
X154951572Y-97546454D03*
D22*
X145769655Y-97587083D03*
X147419655Y-97587083D03*
D10*
X181710179Y-116398550D03*
X183260179Y-116398550D03*
X158188180Y-113473015D03*
X159738180Y-113473015D03*
D22*
X159028030Y-86593369D03*
X160678030Y-86593369D03*
D18*
X154307133Y-124486382D03*
X152657133Y-124486382D03*
D16*
X158155040Y-108691969D03*
X158155040Y-110341969D03*
D11*
X180017267Y-121658690D03*
X178467267Y-121658690D03*
D22*
X183488159Y-120535261D03*
X185138159Y-120535261D03*
X161559017Y-122220255D03*
X163209017Y-122220255D03*
D10*
X186482004Y-118016635D03*
X188032004Y-118016635D03*
D27*
X161087776Y-90140150D03*
X216827776Y-90140150D03*
D28*
X159208406Y-125258345D03*
X161108406Y-125258345D03*
X160158406Y-123383345D03*
D12*
X210951133Y-113132201D03*
X218951133Y-113132201D03*
X210951133Y-117632201D03*
X218951133Y-117632201D03*
D10*
X178467267Y-123118690D03*
X180017267Y-123118690D03*
D12*
X194951133Y-113132201D03*
X202951133Y-113132201D03*
X194951133Y-117632201D03*
X202951133Y-117632201D03*
D22*
X161689189Y-120596440D03*
X163339189Y-120596440D03*
D10*
X164761789Y-120488899D03*
X166311789Y-120488899D03*
D22*
X183584442Y-122410210D03*
X185234442Y-122410210D03*
D10*
X154004818Y-111915048D03*
X155554818Y-111915048D03*
D13*
X158379151Y-97346136D03*
X158379151Y-99246136D03*
X160254151Y-98296136D03*
D29*
X142574466Y-88210000D03*
D30*
X140554466Y-88210000D03*
D31*
X139324466Y-88210000D03*
D29*
X141574466Y-88210000D03*
D30*
X143594466Y-88210000D03*
D31*
X144824466Y-88210000D03*
D32*
X146394466Y-88130000D03*
X146394466Y-84330000D03*
X137754466Y-84330000D03*
X137754466Y-88130000D03*
D33*
X146287603Y-91915281D03*
X146287603Y-90040281D03*
D22*
X183472004Y-118016635D03*
X185122004Y-118016635D03*
D20*
X180271664Y-127327070D03*
D34*
X153629818Y-106919279D03*
X153629818Y-107869279D03*
X153629818Y-108819279D03*
X155929818Y-108819279D03*
X155929818Y-107869279D03*
X155929818Y-106919279D03*
D20*
X218169305Y-94883903D03*
D10*
X168864228Y-116560375D03*
X170414228Y-116560375D03*
D35*
X160229235Y-95781538D03*
X160229235Y-93881538D03*
X158354235Y-94831538D03*
D18*
X163796670Y-97394465D03*
X162146670Y-97394465D03*
D10*
X164569017Y-122220255D03*
X166119017Y-122220255D03*
D36*
X176341495Y-125291194D03*
X176341495Y-124791194D03*
X176341495Y-124291194D03*
X176341495Y-123791194D03*
X176341495Y-123291194D03*
X176341495Y-122791194D03*
X176341495Y-122291194D03*
X176341495Y-121791194D03*
X176341495Y-121291194D03*
X176341495Y-120791194D03*
X176341495Y-120291194D03*
X176341495Y-119791194D03*
D37*
X174991495Y-118441194D03*
X174491495Y-118441194D03*
X173991495Y-118441194D03*
X173491495Y-118441194D03*
X172991495Y-118441194D03*
X172491495Y-118441194D03*
X171991495Y-118441194D03*
X171491495Y-118441194D03*
X170991495Y-118441194D03*
X170491495Y-118441194D03*
X169991495Y-118441194D03*
X169491495Y-118441194D03*
D36*
X168141495Y-119791194D03*
X168141495Y-120291194D03*
X168141495Y-120791194D03*
X168141495Y-121291194D03*
X168141495Y-121791194D03*
X168141495Y-122291194D03*
X168141495Y-122791194D03*
X168141495Y-123291194D03*
X168141495Y-123791194D03*
X168141495Y-124291194D03*
X168141495Y-124791194D03*
X168141495Y-125291194D03*
D37*
X169491495Y-126641194D03*
X169991495Y-126641194D03*
X170491495Y-126641194D03*
X170991495Y-126641194D03*
X171491495Y-126641194D03*
X171991495Y-126641194D03*
X172491495Y-126641194D03*
X172991495Y-126641194D03*
X173491495Y-126641194D03*
X173991495Y-126641194D03*
X174491495Y-126641194D03*
X174991495Y-126641194D03*
D10*
X154607149Y-116828160D03*
X156157149Y-116828160D03*
D22*
X158167759Y-118711221D03*
X159817759Y-118711221D03*
D38*
X146357799Y-127848868D03*
X146357799Y-119848868D03*
X150857799Y-127848868D03*
X150857799Y-119848868D03*
D12*
X210951133Y-126098868D03*
X202951133Y-126098868D03*
X210951133Y-121598868D03*
X202951133Y-121598868D03*
D39*
X144507305Y-91561135D03*
X144507305Y-89986135D03*
D22*
X153954818Y-110310463D03*
X155604818Y-110310463D03*
D40*
X154476567Y-120794558D03*
X153526567Y-120794558D03*
X152576567Y-120794558D03*
X152576567Y-122994558D03*
X154476567Y-122994558D03*
D41*
X156493169Y-94952776D03*
X156493169Y-93682776D03*
X156493169Y-92402776D03*
X156493169Y-91132776D03*
X150673169Y-91132776D03*
X150673169Y-92402776D03*
X150673169Y-93682776D03*
X150673169Y-94952776D03*
D42*
X153583169Y-93042776D03*
D18*
X167345504Y-116264585D03*
X165695504Y-116264585D03*
D14*
X157124998Y-88594361D03*
X157124998Y-90144361D03*
D22*
X178700179Y-116398550D03*
X180350179Y-116398550D03*
D16*
X157597011Y-124014185D03*
X157597011Y-125664185D03*
D43*
X159575680Y-115376388D03*
X158925680Y-115376388D03*
X158275680Y-115376388D03*
X158275680Y-117276388D03*
X158925680Y-117276388D03*
X159575680Y-117276388D03*
D44*
X159921580Y-84036310D03*
X155921580Y-84036310D03*
D20*
X167611415Y-129563379D03*
D16*
X172991495Y-128364551D03*
X172991495Y-130014551D03*
D10*
X174424341Y-128485724D03*
X175974341Y-128485724D03*
D14*
X155695101Y-123373307D03*
X155695101Y-124923307D03*
D11*
X154681287Y-119188736D03*
X153131287Y-119188736D03*
D38*
X146357799Y-110915534D03*
X146357799Y-102915534D03*
X150857799Y-110915534D03*
X150857799Y-102915534D03*
D11*
X167991495Y-126525753D03*
X166441495Y-126525753D03*
D22*
X152629250Y-125997645D03*
X154279250Y-125997645D03*
D45*
X153429818Y-113589341D03*
X153429818Y-114539341D03*
X153429818Y-115489341D03*
X156129818Y-115489341D03*
X156129818Y-113589341D03*
D16*
X141331133Y-89980534D03*
X141331133Y-91630534D03*
M02*

View File

@ -0,0 +1,406 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:30:40-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Paste,Top*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:30:40*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
%ADD11RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
%ADD12R,1.800000X1.200000*%
%ADD13RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*%
%ADD14RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
%ADD15R,3.000000X5.500000*%
%ADD16RoundRect,0.200000X-0.275000X0.200000X-0.275000X-0.200000X0.275000X-0.200000X0.275000X0.200000X0*%
%ADD17RoundRect,0.200000X0.275000X-0.200000X0.275000X0.200000X-0.275000X0.200000X-0.275000X-0.200000X0*%
%ADD18RoundRect,0.200000X0.200000X0.275000X-0.200000X0.275000X-0.200000X-0.275000X0.200000X-0.275000X0*%
%ADD19R,3.500000X2.350000*%
%ADD20RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD21RoundRect,0.200000X-0.200000X-0.275000X0.200000X-0.275000X0.200000X0.275000X-0.200000X0.275000X0*%
%ADD22RoundRect,0.112500X0.112500X-0.187500X0.112500X0.187500X-0.112500X0.187500X-0.112500X-0.187500X0*%
%ADD23RoundRect,0.250000X0.650000X-1.000000X0.650000X1.000000X-0.650000X1.000000X-0.650000X-1.000000X0*%
%ADD24R,2.200000X0.400000*%
%ADD25RoundRect,0.100000X-0.225000X-0.100000X0.225000X-0.100000X0.225000X0.100000X-0.225000X0.100000X0*%
%ADD26R,6.450000X5.300000*%
%ADD27RoundRect,0.150000X0.150000X-0.587500X0.150000X0.587500X-0.150000X0.587500X-0.150000X-0.587500X0*%
%ADD28R,0.700000X1.200000*%
%ADD29R,0.760000X1.200000*%
%ADD30R,0.800000X1.200000*%
%ADD31RoundRect,0.243750X0.456250X-0.243750X0.456250X0.243750X-0.456250X0.243750X-0.456250X-0.243750X0*%
%ADD32R,1.070000X0.530000*%
%ADD33RoundRect,0.150000X0.587500X0.150000X-0.587500X0.150000X-0.587500X-0.150000X0.587500X-0.150000X0*%
%ADD34R,1.200000X0.270000*%
%ADD35R,0.270000X1.200000*%
%ADD36R,1.200000X1.800000*%
%ADD37RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD38R,0.600000X1.000000*%
%ADD39R,1.200000X0.600000*%
%ADD40R,2.400000X3.300000*%
%ADD41RoundRect,0.100000X-0.100000X0.225000X-0.100000X-0.225000X0.100000X-0.225000X0.100000X0.225000X0*%
%ADD42RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD43R,1.200000X0.500000*%
G04 APERTURE END LIST*
D10*
X186594442Y-122410210D03*
X188144442Y-122410210D03*
D11*
X168458966Y-118260712D03*
X166908966Y-118260712D03*
D10*
X158188180Y-107195974D03*
X159738180Y-107195974D03*
D12*
X202951133Y-104665534D03*
X210951133Y-104665534D03*
X202951133Y-109165534D03*
X210951133Y-109165534D03*
D10*
X186498159Y-120535261D03*
X188048159Y-120535261D03*
D13*
X163141120Y-116686961D03*
X163141120Y-118586961D03*
X165016120Y-117636961D03*
D14*
X159771321Y-108741969D03*
X159771321Y-110291969D03*
D15*
X158924572Y-102960590D03*
X154264572Y-102960590D03*
D16*
X148272523Y-93543316D03*
X148272523Y-95193316D03*
D17*
X161212267Y-117283573D03*
X161212267Y-115633573D03*
D14*
X148265612Y-90338172D03*
X148265612Y-91888172D03*
D18*
X161041538Y-127096790D03*
X159391538Y-127096790D03*
D19*
X151018909Y-89007494D03*
X151018909Y-83307494D03*
D20*
X150718124Y-96870191D03*
X152618124Y-96870191D03*
D21*
X174374351Y-129940450D03*
X176024351Y-129940450D03*
X158138180Y-111847959D03*
X159788180Y-111847959D03*
D10*
X176162472Y-126786884D03*
X177712472Y-126786884D03*
D22*
X156386756Y-120670500D03*
X156386756Y-118570500D03*
D23*
X150343692Y-117402201D03*
X150343692Y-113402201D03*
D24*
X174559466Y-111035534D03*
X174559466Y-110335534D03*
X174559466Y-109635534D03*
X174559466Y-108935534D03*
X174559466Y-108235534D03*
X174559466Y-107535534D03*
X174559466Y-106835534D03*
X174559466Y-106135534D03*
X174559466Y-105435534D03*
X174559466Y-104735534D03*
X174559466Y-104035534D03*
X174559466Y-103335534D03*
X174559466Y-102635534D03*
D10*
X178467267Y-124578690D03*
X180017267Y-124578690D03*
D18*
X171606612Y-129942382D03*
X169956612Y-129942382D03*
D25*
X158155852Y-120238248D03*
X158155852Y-120888248D03*
X158155852Y-121538248D03*
X160055852Y-121538248D03*
X160055852Y-120888248D03*
X160055852Y-120238248D03*
D16*
X142831133Y-89980534D03*
X142831133Y-91630534D03*
D18*
X156601572Y-97546454D03*
X154951572Y-97546454D03*
D21*
X145769655Y-97587083D03*
X147419655Y-97587083D03*
D10*
X181710179Y-116398550D03*
X183260179Y-116398550D03*
X158188180Y-113473015D03*
X159738180Y-113473015D03*
D21*
X159028030Y-86593369D03*
X160678030Y-86593369D03*
D18*
X154307133Y-124486382D03*
X152657133Y-124486382D03*
D16*
X158155040Y-108691969D03*
X158155040Y-110341969D03*
D11*
X180017267Y-121658690D03*
X178467267Y-121658690D03*
D21*
X183488159Y-120535261D03*
X185138159Y-120535261D03*
X161559017Y-122220255D03*
X163209017Y-122220255D03*
D10*
X186482004Y-118016635D03*
X188032004Y-118016635D03*
D26*
X161087776Y-90140150D03*
X216827776Y-90140150D03*
D27*
X159208406Y-125258345D03*
X161108406Y-125258345D03*
X160158406Y-123383345D03*
D12*
X210951133Y-113132201D03*
X218951133Y-113132201D03*
X210951133Y-117632201D03*
X218951133Y-117632201D03*
D10*
X178467267Y-123118690D03*
X180017267Y-123118690D03*
D12*
X194951133Y-113132201D03*
X202951133Y-113132201D03*
X194951133Y-117632201D03*
X202951133Y-117632201D03*
D21*
X161689189Y-120596440D03*
X163339189Y-120596440D03*
D10*
X164761789Y-120488899D03*
X166311789Y-120488899D03*
D21*
X183584442Y-122410210D03*
X185234442Y-122410210D03*
D10*
X154004818Y-111915048D03*
X155554818Y-111915048D03*
D13*
X158379151Y-97346136D03*
X158379151Y-99246136D03*
X160254151Y-98296136D03*
D28*
X142574466Y-88210000D03*
D29*
X140554466Y-88210000D03*
D30*
X139324466Y-88210000D03*
D28*
X141574466Y-88210000D03*
D29*
X143594466Y-88210000D03*
D30*
X144824466Y-88210000D03*
D31*
X146287603Y-91915281D03*
X146287603Y-90040281D03*
D21*
X183472004Y-118016635D03*
X185122004Y-118016635D03*
D32*
X153629818Y-106919279D03*
X153629818Y-107869279D03*
X153629818Y-108819279D03*
X155929818Y-108819279D03*
X155929818Y-107869279D03*
X155929818Y-106919279D03*
D10*
X168864228Y-116560375D03*
X170414228Y-116560375D03*
D33*
X160229235Y-95781538D03*
X160229235Y-93881538D03*
X158354235Y-94831538D03*
D18*
X163796670Y-97394465D03*
X162146670Y-97394465D03*
D10*
X164569017Y-122220255D03*
X166119017Y-122220255D03*
D34*
X176341495Y-125291194D03*
X176341495Y-124791194D03*
X176341495Y-124291194D03*
X176341495Y-123791194D03*
X176341495Y-123291194D03*
X176341495Y-122791194D03*
X176341495Y-122291194D03*
X176341495Y-121791194D03*
X176341495Y-121291194D03*
X176341495Y-120791194D03*
X176341495Y-120291194D03*
X176341495Y-119791194D03*
D35*
X174991495Y-118441194D03*
X174491495Y-118441194D03*
X173991495Y-118441194D03*
X173491495Y-118441194D03*
X172991495Y-118441194D03*
X172491495Y-118441194D03*
X171991495Y-118441194D03*
X171491495Y-118441194D03*
X170991495Y-118441194D03*
X170491495Y-118441194D03*
X169991495Y-118441194D03*
X169491495Y-118441194D03*
D34*
X168141495Y-119791194D03*
X168141495Y-120291194D03*
X168141495Y-120791194D03*
X168141495Y-121291194D03*
X168141495Y-121791194D03*
X168141495Y-122291194D03*
X168141495Y-122791194D03*
X168141495Y-123291194D03*
X168141495Y-123791194D03*
X168141495Y-124291194D03*
X168141495Y-124791194D03*
X168141495Y-125291194D03*
D35*
X169491495Y-126641194D03*
X169991495Y-126641194D03*
X170491495Y-126641194D03*
X170991495Y-126641194D03*
X171491495Y-126641194D03*
X171991495Y-126641194D03*
X172491495Y-126641194D03*
X172991495Y-126641194D03*
X173491495Y-126641194D03*
X173991495Y-126641194D03*
X174491495Y-126641194D03*
X174991495Y-126641194D03*
D10*
X154607149Y-116828160D03*
X156157149Y-116828160D03*
D21*
X158167759Y-118711221D03*
X159817759Y-118711221D03*
D36*
X146357799Y-127848868D03*
X146357799Y-119848868D03*
X150857799Y-127848868D03*
X150857799Y-119848868D03*
D12*
X210951133Y-126098868D03*
X202951133Y-126098868D03*
X210951133Y-121598868D03*
X202951133Y-121598868D03*
D37*
X144507305Y-91561135D03*
X144507305Y-89986135D03*
D21*
X153954818Y-110310463D03*
X155604818Y-110310463D03*
D38*
X154476567Y-120794558D03*
X153526567Y-120794558D03*
X152576567Y-120794558D03*
X152576567Y-122994558D03*
X154476567Y-122994558D03*
D39*
X156493169Y-94952776D03*
X156493169Y-93682776D03*
X156493169Y-92402776D03*
X156493169Y-91132776D03*
X150673169Y-91132776D03*
X150673169Y-92402776D03*
X150673169Y-93682776D03*
X150673169Y-94952776D03*
D40*
X153583169Y-93042776D03*
D18*
X167345504Y-116264585D03*
X165695504Y-116264585D03*
D14*
X157124998Y-88594361D03*
X157124998Y-90144361D03*
D21*
X178700179Y-116398550D03*
X180350179Y-116398550D03*
D16*
X157597011Y-124014185D03*
X157597011Y-125664185D03*
D41*
X159575680Y-115376388D03*
X158925680Y-115376388D03*
X158275680Y-115376388D03*
X158275680Y-117276388D03*
X158925680Y-117276388D03*
X159575680Y-117276388D03*
D42*
X159921580Y-84036310D03*
X155921580Y-84036310D03*
D16*
X172991495Y-128364551D03*
X172991495Y-130014551D03*
D10*
X174424341Y-128485724D03*
X175974341Y-128485724D03*
D14*
X155695101Y-123373307D03*
X155695101Y-124923307D03*
D11*
X154681287Y-119188736D03*
X153131287Y-119188736D03*
D36*
X146357799Y-110915534D03*
X146357799Y-102915534D03*
X150857799Y-110915534D03*
X150857799Y-102915534D03*
D11*
X167991495Y-126525753D03*
X166441495Y-126525753D03*
D21*
X152629250Y-125997645D03*
X154279250Y-125997645D03*
D43*
X153429818Y-113589341D03*
X153429818Y-114539341D03*
X153429818Y-115489341D03*
X156129818Y-115489341D03*
X156129818Y-113589341D03*
D16*
X141331133Y-89980534D03*
X141331133Y-91630534D03*
M02*

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.2*%
%TF.CreationDate,2025-07-13T16:14:11-05:00*%
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*%
%TF.CreationDate,2025-08-27T19:31:05-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.2) date 2025-07-13 16:14:11*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:05*
%MOMM*%
%LPD*%
G01*

View File

@ -0,0 +1,12 @@
M48
; DRILL file {KiCad 9.0.3} date 2025-08-27T19:31:05-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-08-27T19:31:05-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
METRIC
%
G90
G05
M30

View File

@ -1,12 +1,12 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.2*%
%TF.CreationDate,2025-07-13T16:14:11-05:00*%
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*%
%TF.CreationDate,2025-08-27T19:31:05-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.2) date 2025-07-13 16:14:11*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:05*
%MOMM*%
%LPD*%
G01*
@ -62,78 +62,70 @@ X14467134Y-8660086D02*
X14497134Y-8690086D01*
X14497134Y-8660086D02*
X14467134Y-8690086D01*
X14886315Y-9709309D02*
X14916315Y-9739309D01*
X14916315Y-9709309D02*
X14886315Y-9739309D01*
X15188362Y-9176103D02*
X15218362Y-9206103D01*
X15218362Y-9176103D02*
X15188362Y-9206103D01*
X15233510Y-10771928D02*
X15263510Y-10801928D01*
X15263510Y-10771928D02*
X15233510Y-10801928D01*
X15243494Y-11782910D02*
X15273494Y-11812910D01*
X15273494Y-11782910D02*
X15243494Y-11812910D01*
X14927040Y-9274355D02*
X14957040Y-9304355D01*
X14957040Y-9274355D02*
X14927040Y-9304355D01*
X15250880Y-10923202D02*
X15280880Y-10953202D01*
X15280880Y-10923202D02*
X15250880Y-10953202D01*
X15255483Y-9421812D02*
X15285483Y-9451812D01*
X15285483Y-9421812D02*
X15255483Y-9451812D01*
X15258314Y-9157217D02*
X15288314Y-9187217D01*
X15288314Y-9157217D02*
X15258314Y-9187217D01*
X15281530Y-11802242D02*
X15311530Y-11832242D01*
X15311530Y-11802242D02*
X15281530Y-11832242D01*
X15320740Y-11606959D02*
X15350740Y-11636959D01*
X15350740Y-11606959D02*
X15320740Y-11636959D01*
X15537470Y-12587115D02*
X15567470Y-12617115D01*
X15567470Y-12587115D02*
X15537470Y-12617115D01*
X15544511Y-11785922D02*
X15574511Y-11815922D01*
X15574511Y-11785922D02*
X15544511Y-11815922D01*
X15560449Y-9662996D02*
X15590449Y-9692996D01*
X15590449Y-9662996D02*
X15560449Y-9692996D01*
X15564025Y-9400149D02*
X15594025Y-9430149D01*
X15594025Y-9400149D02*
X15564025Y-9430149D01*
X15646597Y-9531967D02*
X15676597Y-9561967D01*
X15676597Y-9531967D02*
X15646597Y-9561967D01*
X15343317Y-9289278D02*
X15373317Y-9319278D01*
X15373317Y-9289278D02*
X15343317Y-9319278D01*
X15425889Y-9421096D02*
X15455889Y-9451096D01*
X15455889Y-9421096D02*
X15425889Y-9451096D01*
X15429465Y-9158248D02*
X15459465Y-9188248D01*
X15459465Y-9158248D02*
X15429465Y-9188248D01*
X15554052Y-12614941D02*
X15584052Y-12644941D01*
X15584052Y-12614941D02*
X15554052Y-12644941D01*
X15604647Y-8950185D02*
X15634647Y-8980185D01*
X15634647Y-8950185D02*
X15604647Y-8980185D01*
X15662903Y-9909614D02*
X15692903Y-9939614D01*
X15692903Y-9909614D02*
X15662903Y-9939614D01*
X15674446Y-11176505D02*
X15704446Y-11206505D01*
X15704446Y-11176505D02*
X15674446Y-11206505D01*
X15728012Y-12761537D02*
X15758012Y-12791537D01*
X15758012Y-12761537D02*
X15728012Y-12791537D01*
X15731600Y-9664028D02*
X15761600Y-9694028D01*
X15761600Y-9664028D02*
X15731600Y-9694028D01*
X15734431Y-9399433D02*
X15764431Y-9429433D01*
X15764431Y-9399433D02*
X15734431Y-9429433D01*
X15779696Y-9044834D02*
X15809696Y-9074834D01*
X15809696Y-9044834D02*
X15779696Y-9074834D01*
X15876636Y-11950008D02*
X15906636Y-11980008D01*
X15906636Y-11950008D02*
X15876636Y-11980008D01*
X15879252Y-12431608D02*
X15909252Y-12461608D01*
X15909252Y-12431608D02*
X15879252Y-12461608D01*
X15719035Y-12051950D02*
X15749035Y-12081950D01*
X15749035Y-12051950D02*
X15719035Y-12081950D01*
X15882247Y-11094987D02*
X15912247Y-11124987D01*
X15912247Y-11094987D02*
X15882247Y-11124987D01*
X15884145Y-11795548D02*
X15914145Y-11825548D01*
X15914145Y-11795548D02*
X15884145Y-11825548D01*
X15891310Y-11431009D02*
X15921310Y-11461009D01*
X15921310Y-11431009D02*
@ -142,54 +134,50 @@ X16061449Y-10704597D02*
X16091449Y-10734597D01*
X16091449Y-10704597D02*
X16061449Y-10734597D01*
X16506486Y-12657137D02*
X16536486Y-12687137D01*
X16536486Y-12657137D02*
X16506486Y-12687137D01*
X16612488Y-8417432D02*
X16642488Y-8447432D01*
X16642488Y-8417432D02*
X16612488Y-8447432D01*
X16711450Y-11721343D02*
X16741450Y-11751343D01*
X16741450Y-11721343D02*
X16711450Y-11751343D01*
X16890776Y-12443088D02*
X16920776Y-12473088D01*
X16920776Y-12443088D02*
X16890776Y-12473088D01*
X16970140Y-12854044D02*
X17000140Y-12884044D01*
X17000140Y-12854044D02*
X16970140Y-12884044D01*
X17001361Y-11510728D02*
X17031361Y-11540728D01*
X17031361Y-11510728D02*
X17001361Y-11540728D01*
X17382855Y-12523096D02*
X17412855Y-12553096D01*
X17412855Y-12523096D02*
X17382855Y-12553096D01*
X17469624Y-12182906D02*
X17499624Y-12212906D01*
X17499624Y-12182906D02*
X17469624Y-12212906D01*
X16087075Y-12116620D02*
X16117075Y-12146620D01*
X16117075Y-12116620D02*
X16087075Y-12146620D01*
X16531548Y-12657844D02*
X16561548Y-12687844D01*
X16561548Y-12657844D02*
X16531548Y-12687844D01*
X16548441Y-11843696D02*
X16578441Y-11873696D01*
X16578441Y-11843696D02*
X16548441Y-11873696D01*
X16915838Y-12443795D02*
X16945838Y-12473795D01*
X16945838Y-12443795D02*
X16915838Y-12473795D01*
X16995202Y-12854751D02*
X17025202Y-12884751D01*
X17025202Y-12854751D02*
X16995202Y-12884751D01*
X17026423Y-11533452D02*
X17056423Y-11563452D01*
X17056423Y-11533452D02*
X17026423Y-11563452D01*
X17279775Y-10249839D02*
X17309775Y-10279839D01*
X17309775Y-10249839D02*
X17279775Y-10279839D01*
X17407917Y-12523803D02*
X17437917Y-12553803D01*
X17437917Y-12523803D02*
X17407917Y-12553803D01*
X17494686Y-12183613D02*
X17524686Y-12213613D01*
X17524686Y-12183613D02*
X17494686Y-12213613D01*
X17602115Y-10598553D02*
X17632115Y-10628553D01*
X17632115Y-10598553D02*
X17602115Y-10628553D01*
X17604964Y-10248553D02*
X17634964Y-10278553D01*
X17634964Y-10248553D02*
X17604964Y-10278553D01*
X17604964Y-10388553D02*
X17634964Y-10418553D01*
X17634964Y-10388553D02*
X17604964Y-10418553D01*
X17681471Y-12832865D02*
X17711471Y-12862865D01*
X17711471Y-12832865D02*
X17681471Y-12862865D01*
X17706533Y-12833572D02*
X17736533Y-12863572D01*
X17736533Y-12833572D02*
X17706533Y-12863572D01*
X17736654Y-11624855D02*
X17766654Y-11654855D01*
X17766654Y-11624855D02*
@ -210,6 +198,10 @@ X18215680Y-11786663D02*
X18245680Y-11816663D01*
X18245680Y-11786663D02*
X18215680Y-11816663D01*
X21667778Y-8647536D02*
X21697778Y-8677536D01*
X21697778Y-8647536D02*
X21667778Y-8677536D01*
X13805447Y-8433000D02*
G75*
G02*
@ -859,22 +851,74 @@ X16800438Y-13777061D02*
X16819486Y-13748489D01*
X16819486Y-13748489D02*
X16829010Y-13738966D01*
X16990914Y-13834204D02*
X16990914Y-13967537D01*
X16943295Y-13758013D02*
X16895676Y-13900870D01*
X16895676Y-13900870D02*
X17019486Y-13900870D01*
X17200438Y-13967537D02*
X17086152Y-13967537D01*
X16886152Y-13767537D02*
X17009962Y-13767537D01*
X17009962Y-13767537D02*
X16943295Y-13843728D01*
X16943295Y-13843728D02*
X16971867Y-13843728D01*
X16971867Y-13843728D02*
X16990914Y-13853251D01*
X16990914Y-13853251D02*
X17000438Y-13862775D01*
X17000438Y-13862775D02*
X17009962Y-13881823D01*
X17009962Y-13881823D02*
X17009962Y-13929442D01*
X17009962Y-13929442D02*
X17000438Y-13948489D01*
X17000438Y-13948489D02*
X16990914Y-13958013D01*
X16990914Y-13958013D02*
X16971867Y-13967537D01*
X16971867Y-13967537D02*
X16914724Y-13967537D01*
X16914724Y-13967537D02*
X16895676Y-13958013D01*
X16895676Y-13958013D02*
X16886152Y-13948489D01*
X17105200Y-13967537D02*
X17143295Y-13967537D01*
X17143295Y-13967537D02*
X17143295Y-13767537D01*
X17143295Y-13767537D02*
X17124248Y-13796109D01*
X17124248Y-13796109D02*
X17105200Y-13815156D01*
X17105200Y-13815156D02*
X17086152Y-13824680D01*
X17162343Y-13958013D01*
X17162343Y-13958013D02*
X17171867Y-13948489D01*
X17171867Y-13948489D02*
X17190914Y-13919918D01*
X17190914Y-13919918D02*
X17200438Y-13881823D01*
X17200438Y-13881823D02*
X17200438Y-13805632D01*
X17200438Y-13805632D02*
X17190914Y-13786585D01*
X17190914Y-13786585D02*
X17181390Y-13777061D01*
X17181390Y-13777061D02*
X17162343Y-13767537D01*
X17162343Y-13767537D02*
X17124248Y-13767537D01*
X17124248Y-13767537D02*
X17105200Y-13777061D01*
X17105200Y-13777061D02*
X17095676Y-13786585D01*
X17095676Y-13786585D02*
X17086152Y-13805632D01*
X17086152Y-13805632D02*
X17086152Y-13853251D01*
X17086152Y-13853251D02*
X17095676Y-13872299D01*
X17095676Y-13872299D02*
X17105200Y-13881823D01*
X17105200Y-13881823D02*
X17124248Y-13891347D01*
X17124248Y-13891347D02*
X17162343Y-13891347D01*
X17162343Y-13891347D02*
X17181390Y-13881823D01*
X17181390Y-13881823D02*
X17190914Y-13872299D01*
X17190914Y-13872299D02*
X17200438Y-13853251D01*
X17438533Y-13967537D02*
X17438533Y-13767537D01*
X17524248Y-13967537D02*

View File

@ -1,8 +1,8 @@
M48
; DRILL file {KiCad 9.0.2} date 2025-07-13T16:14:11-0500
; DRILL file {KiCad 9.0.3} date 2025-08-27T19:31:05-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-07-13T16:14:11-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.2
; #@! TF.CreationDate,2025-08-27T19:31:05-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
METRIC
@ -18,43 +18,41 @@ X139.329Y-86.794
X141.331Y-92.806
X142.831Y-92.806
X144.821Y-86.751
X149.013Y-97.243
X152.034Y-91.911
X152.485Y-107.869
X152.585Y-117.979
X149.42Y-92.894
X152.659Y-109.382
X152.705Y-94.368
X152.733Y-91.722
X152.965Y-118.172
X153.357Y-116.22
X155.525Y-126.021
X155.595Y-118.009
X155.754Y-96.78
X155.79Y-94.151
X156.616Y-95.47
X153.583Y-93.043
X154.409Y-94.361
X154.445Y-91.732
X155.691Y-126.299
X156.196Y-89.652
X156.779Y-99.246
X156.894Y-111.915
X157.43Y-127.765
X157.466Y-96.79
X157.494Y-94.144
X157.947Y-90.598
X158.916Y-119.65
X158.943Y-124.466
X157.34Y-120.669
X158.972Y-111.1
X158.991Y-118.105
X159.063Y-114.46
X160.764Y-107.196
X165.215Y-126.721
X166.275Y-84.324
X167.265Y-117.363
X169.058Y-124.581
X169.851Y-128.69
X170.164Y-115.257
X173.979Y-125.381
X174.846Y-121.979
X161.021Y-121.316
X165.465Y-126.728
X165.634Y-118.587
X169.308Y-124.588
X170.102Y-128.698
X170.414Y-115.485
X172.948Y-102.648
X174.229Y-125.388
X175.097Y-121.986
X176.171Y-106.136
X176.2Y-102.636
X176.2Y-104.036
X176.965Y-128.479
X177.215Y-128.486
X177.517Y-116.399
X181.016Y-123.112
X182.194Y-122.41
X182.291Y-120.535
X182.307Y-118.017
X216.828Y-86.625
T2
X137.754Y-84.63G85X137.754Y-84.03
G05

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.0*%
%TF.CreationDate,2025-03-23T23:43:45-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Soldermask,Bot*%
%TF.FilePolarity,Negative*%
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:31:25-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Soldermask,Bot*
G04 #@! TF.FilePolarity,Negative*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.0) date 2025-03-23 23:43:45*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:25*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.200000*%
%ADD11O,1.100000X1.700000*%
%ADD11O,1.304000X1.904000*%
G04 APERTURE END LIST*
D10*
G36*
@ -552,10 +552,8 @@ X187824358Y-89246001D01*
X187824358Y-90312671D01*
G37*
D11*
%TO.C,J1*%
X146394466Y-88130000D03*
X146394466Y-84330000D03*
X137754466Y-88130000D03*
X137754466Y-84330000D03*
%TD*%
X137754466Y-88130000D03*
M02*

View File

@ -0,0 +1,15 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:31:24-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Paste,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 APERTURE END LIST*
M02*

View File

@ -0,0 +1,46 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:31:26-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Profile,NP*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:26*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 #@! TA.AperFunction,Profile*
%ADD10C,0.050000*%
G04 #@! TD*
G04 APERTURE END LIST*
D10*
X137564466Y-132335534D02*
X216464466Y-132335534D01*
X137564466Y-132335534D02*
G75*
G02*
X132564466Y-127335534I34J5000034D01*
G01*
X132564466Y-86535534D02*
X132564466Y-127335534D01*
X216464466Y-81535534D02*
G75*
G02*
X221464466Y-86535534I34J-4999966D01*
G01*
X221464466Y-127335534D02*
X221464466Y-86535534D01*
X216464466Y-81535534D02*
X137564466Y-81535534D01*
X132564466Y-86535534D02*
G75*
G02*
X137564466Y-81535536I4999914J84D01*
G01*
X221464466Y-127335534D02*
G75*
G02*
X216464466Y-132335566I-5000066J34D01*
G01*
M02*

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,424 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:31:25-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Soldermask,Top*
G04 #@! TF.FilePolarity,Negative*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:25*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
%ADD11RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
%ADD12R,1.800000X1.200000*%
%ADD13RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*%
%ADD14RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
%ADD15R,3.000000X5.500000*%
%ADD16RoundRect,0.200000X-0.275000X0.200000X-0.275000X-0.200000X0.275000X-0.200000X0.275000X0.200000X0*%
%ADD17RoundRect,0.200000X0.275000X-0.200000X0.275000X0.200000X-0.275000X0.200000X-0.275000X-0.200000X0*%
%ADD18RoundRect,0.200000X0.200000X0.275000X-0.200000X0.275000X-0.200000X-0.275000X0.200000X-0.275000X0*%
%ADD19R,3.500000X2.350000*%
%ADD20C,2.000000*%
%ADD21RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD22RoundRect,0.200000X-0.200000X-0.275000X0.200000X-0.275000X0.200000X0.275000X-0.200000X0.275000X0*%
%ADD23RoundRect,0.112500X0.112500X-0.187500X0.112500X0.187500X-0.112500X0.187500X-0.112500X-0.187500X0*%
%ADD24RoundRect,0.250000X0.650000X-1.000000X0.650000X1.000000X-0.650000X1.000000X-0.650000X-1.000000X0*%
%ADD25R,2.200000X0.400000*%
%ADD26RoundRect,0.100000X-0.225000X-0.100000X0.225000X-0.100000X0.225000X0.100000X-0.225000X0.100000X0*%
%ADD27R,6.450000X5.300000*%
%ADD28RoundRect,0.150000X0.150000X-0.587500X0.150000X0.587500X-0.150000X0.587500X-0.150000X-0.587500X0*%
%ADD29RoundRect,0.102000X0.350000X0.600000X-0.350000X0.600000X-0.350000X-0.600000X0.350000X-0.600000X0*%
%ADD30RoundRect,0.102000X0.380000X0.600000X-0.380000X0.600000X-0.380000X-0.600000X0.380000X-0.600000X0*%
%ADD31RoundRect,0.102000X0.400000X0.600000X-0.400000X0.600000X-0.400000X-0.600000X0.400000X-0.600000X0*%
%ADD32O,1.304000X1.904000*%
%ADD33RoundRect,0.243750X0.456250X-0.243750X0.456250X0.243750X-0.456250X0.243750X-0.456250X-0.243750X0*%
%ADD34R,1.070000X0.530000*%
%ADD35RoundRect,0.150000X0.587500X0.150000X-0.587500X0.150000X-0.587500X-0.150000X0.587500X-0.150000X0*%
%ADD36R,1.200000X0.270000*%
%ADD37R,0.270000X1.200000*%
%ADD38R,1.200000X1.800000*%
%ADD39RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD40R,0.600000X1.000000*%
%ADD41R,1.200000X0.600000*%
%ADD42R,2.400000X3.300000*%
%ADD43RoundRect,0.100000X-0.100000X0.225000X-0.100000X-0.225000X0.100000X-0.225000X0.100000X0.225000X0*%
%ADD44RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD45R,1.200000X0.500000*%
G04 APERTURE END LIST*
D10*
X186594442Y-122410210D03*
X188144442Y-122410210D03*
D11*
X168458966Y-118260712D03*
X166908966Y-118260712D03*
D10*
X158188180Y-107195974D03*
X159738180Y-107195974D03*
D12*
X202951133Y-104665534D03*
X210951133Y-104665534D03*
X202951133Y-109165534D03*
X210951133Y-109165534D03*
D10*
X186498159Y-120535261D03*
X188048159Y-120535261D03*
D13*
X163141120Y-116686961D03*
X163141120Y-118586961D03*
X165016120Y-117636961D03*
D14*
X159771321Y-108741969D03*
X159771321Y-110291969D03*
D15*
X158924572Y-102960590D03*
X154264572Y-102960590D03*
D16*
X148272523Y-93543316D03*
X148272523Y-95193316D03*
D17*
X161212267Y-117283573D03*
X161212267Y-115633573D03*
D14*
X148265612Y-90338172D03*
X148265612Y-91888172D03*
D18*
X161041538Y-127096790D03*
X159391538Y-127096790D03*
D19*
X151018909Y-89007494D03*
X151018909Y-83307494D03*
D20*
X164428408Y-125040799D03*
X164428408Y-129563379D03*
D21*
X150718124Y-96870191D03*
X152618124Y-96870191D03*
D22*
X174374351Y-129940450D03*
X176024351Y-129940450D03*
X158138180Y-111847959D03*
X159788180Y-111847959D03*
D10*
X176162472Y-126786884D03*
X177712472Y-126786884D03*
D23*
X156386756Y-120670500D03*
X156386756Y-118570500D03*
D24*
X150343692Y-117402201D03*
X150343692Y-113402201D03*
D25*
X174559466Y-111035534D03*
X174559466Y-110335534D03*
X174559466Y-109635534D03*
X174559466Y-108935534D03*
X174559466Y-108235534D03*
X174559466Y-107535534D03*
X174559466Y-106835534D03*
X174559466Y-106135534D03*
X174559466Y-105435534D03*
X174559466Y-104735534D03*
X174559466Y-104035534D03*
X174559466Y-103335534D03*
X174559466Y-102635534D03*
D10*
X178467267Y-124578690D03*
X180017267Y-124578690D03*
D18*
X171606612Y-129942382D03*
X169956612Y-129942382D03*
D20*
X138326311Y-91051939D03*
D26*
X158155852Y-120238248D03*
X158155852Y-120888248D03*
X158155852Y-121538248D03*
X160055852Y-121538248D03*
X160055852Y-120888248D03*
X160055852Y-120238248D03*
D16*
X142831133Y-89980534D03*
X142831133Y-91630534D03*
D18*
X156601572Y-97546454D03*
X154951572Y-97546454D03*
D22*
X145769655Y-97587083D03*
X147419655Y-97587083D03*
D10*
X181710179Y-116398550D03*
X183260179Y-116398550D03*
X158188180Y-113473015D03*
X159738180Y-113473015D03*
D22*
X159028030Y-86593369D03*
X160678030Y-86593369D03*
D18*
X154307133Y-124486382D03*
X152657133Y-124486382D03*
D16*
X158155040Y-108691969D03*
X158155040Y-110341969D03*
D11*
X180017267Y-121658690D03*
X178467267Y-121658690D03*
D22*
X183488159Y-120535261D03*
X185138159Y-120535261D03*
X161559017Y-122220255D03*
X163209017Y-122220255D03*
D10*
X186482004Y-118016635D03*
X188032004Y-118016635D03*
D27*
X161087776Y-90140150D03*
X216827776Y-90140150D03*
D28*
X159208406Y-125258345D03*
X161108406Y-125258345D03*
X160158406Y-123383345D03*
D12*
X210951133Y-113132201D03*
X218951133Y-113132201D03*
X210951133Y-117632201D03*
X218951133Y-117632201D03*
D10*
X178467267Y-123118690D03*
X180017267Y-123118690D03*
D12*
X194951133Y-113132201D03*
X202951133Y-113132201D03*
X194951133Y-117632201D03*
X202951133Y-117632201D03*
D22*
X161689189Y-120596440D03*
X163339189Y-120596440D03*
D10*
X164761789Y-120488899D03*
X166311789Y-120488899D03*
D22*
X183584442Y-122410210D03*
X185234442Y-122410210D03*
D10*
X154004818Y-111915048D03*
X155554818Y-111915048D03*
D13*
X158379151Y-97346136D03*
X158379151Y-99246136D03*
X160254151Y-98296136D03*
D29*
X142574466Y-88210000D03*
D30*
X140554466Y-88210000D03*
D31*
X139324466Y-88210000D03*
D29*
X141574466Y-88210000D03*
D30*
X143594466Y-88210000D03*
D31*
X144824466Y-88210000D03*
D32*
X146394466Y-88130000D03*
X146394466Y-84330000D03*
X137754466Y-84330000D03*
X137754466Y-88130000D03*
D33*
X146287603Y-91915281D03*
X146287603Y-90040281D03*
D22*
X183472004Y-118016635D03*
X185122004Y-118016635D03*
D20*
X180271664Y-127327070D03*
D34*
X153629818Y-106919279D03*
X153629818Y-107869279D03*
X153629818Y-108819279D03*
X155929818Y-108819279D03*
X155929818Y-107869279D03*
X155929818Y-106919279D03*
D20*
X218169305Y-94883903D03*
D10*
X168864228Y-116560375D03*
X170414228Y-116560375D03*
D35*
X160229235Y-95781538D03*
X160229235Y-93881538D03*
X158354235Y-94831538D03*
D18*
X163796670Y-97394465D03*
X162146670Y-97394465D03*
D10*
X164569017Y-122220255D03*
X166119017Y-122220255D03*
D36*
X176341495Y-125291194D03*
X176341495Y-124791194D03*
X176341495Y-124291194D03*
X176341495Y-123791194D03*
X176341495Y-123291194D03*
X176341495Y-122791194D03*
X176341495Y-122291194D03*
X176341495Y-121791194D03*
X176341495Y-121291194D03*
X176341495Y-120791194D03*
X176341495Y-120291194D03*
X176341495Y-119791194D03*
D37*
X174991495Y-118441194D03*
X174491495Y-118441194D03*
X173991495Y-118441194D03*
X173491495Y-118441194D03*
X172991495Y-118441194D03*
X172491495Y-118441194D03*
X171991495Y-118441194D03*
X171491495Y-118441194D03*
X170991495Y-118441194D03*
X170491495Y-118441194D03*
X169991495Y-118441194D03*
X169491495Y-118441194D03*
D36*
X168141495Y-119791194D03*
X168141495Y-120291194D03*
X168141495Y-120791194D03*
X168141495Y-121291194D03*
X168141495Y-121791194D03*
X168141495Y-122291194D03*
X168141495Y-122791194D03*
X168141495Y-123291194D03*
X168141495Y-123791194D03*
X168141495Y-124291194D03*
X168141495Y-124791194D03*
X168141495Y-125291194D03*
D37*
X169491495Y-126641194D03*
X169991495Y-126641194D03*
X170491495Y-126641194D03*
X170991495Y-126641194D03*
X171491495Y-126641194D03*
X171991495Y-126641194D03*
X172491495Y-126641194D03*
X172991495Y-126641194D03*
X173491495Y-126641194D03*
X173991495Y-126641194D03*
X174491495Y-126641194D03*
X174991495Y-126641194D03*
D10*
X154607149Y-116828160D03*
X156157149Y-116828160D03*
D22*
X158167759Y-118711221D03*
X159817759Y-118711221D03*
D38*
X146357799Y-127848868D03*
X146357799Y-119848868D03*
X150857799Y-127848868D03*
X150857799Y-119848868D03*
D12*
X210951133Y-126098868D03*
X202951133Y-126098868D03*
X210951133Y-121598868D03*
X202951133Y-121598868D03*
D39*
X144507305Y-91561135D03*
X144507305Y-89986135D03*
D22*
X153954818Y-110310463D03*
X155604818Y-110310463D03*
D40*
X154476567Y-120794558D03*
X153526567Y-120794558D03*
X152576567Y-120794558D03*
X152576567Y-122994558D03*
X154476567Y-122994558D03*
D41*
X156493169Y-94952776D03*
X156493169Y-93682776D03*
X156493169Y-92402776D03*
X156493169Y-91132776D03*
X150673169Y-91132776D03*
X150673169Y-92402776D03*
X150673169Y-93682776D03*
X150673169Y-94952776D03*
D42*
X153583169Y-93042776D03*
D18*
X167345504Y-116264585D03*
X165695504Y-116264585D03*
D14*
X157124998Y-88594361D03*
X157124998Y-90144361D03*
D22*
X178700179Y-116398550D03*
X180350179Y-116398550D03*
D16*
X157597011Y-124014185D03*
X157597011Y-125664185D03*
D43*
X159575680Y-115376388D03*
X158925680Y-115376388D03*
X158275680Y-115376388D03*
X158275680Y-117276388D03*
X158925680Y-117276388D03*
X159575680Y-117276388D03*
D44*
X159921580Y-84036310D03*
X155921580Y-84036310D03*
D20*
X167611415Y-129563379D03*
D16*
X172991495Y-128364551D03*
X172991495Y-130014551D03*
D10*
X174424341Y-128485724D03*
X175974341Y-128485724D03*
D14*
X155695101Y-123373307D03*
X155695101Y-124923307D03*
D11*
X154681287Y-119188736D03*
X153131287Y-119188736D03*
D38*
X146357799Y-110915534D03*
X146357799Y-102915534D03*
X150857799Y-110915534D03*
X150857799Y-102915534D03*
D11*
X167991495Y-126525753D03*
X166441495Y-126525753D03*
D22*
X152629250Y-125997645D03*
X154279250Y-125997645D03*
D45*
X153429818Y-113589341D03*
X153429818Y-114539341D03*
X153429818Y-115489341D03*
X156129818Y-115489341D03*
X156129818Y-113589341D03*
D16*
X141331133Y-89980534D03*
X141331133Y-91630534D03*
M02*

View File

@ -0,0 +1,406 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*
G04 #@! TF.CreationDate,2025-08-27T19:31:24-05:00*
G04 #@! TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*
G04 #@! TF.SameCoordinates,Original*
G04 #@! TF.FileFunction,Paste,Top*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:24*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
%ADD11RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
%ADD12R,1.800000X1.200000*%
%ADD13RoundRect,0.150000X-0.587500X-0.150000X0.587500X-0.150000X0.587500X0.150000X-0.587500X0.150000X0*%
%ADD14RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
%ADD15R,3.000000X5.500000*%
%ADD16RoundRect,0.200000X-0.275000X0.200000X-0.275000X-0.200000X0.275000X-0.200000X0.275000X0.200000X0*%
%ADD17RoundRect,0.200000X0.275000X-0.200000X0.275000X0.200000X-0.275000X0.200000X-0.275000X-0.200000X0*%
%ADD18RoundRect,0.200000X0.200000X0.275000X-0.200000X0.275000X-0.200000X-0.275000X0.200000X-0.275000X0*%
%ADD19R,3.500000X2.350000*%
%ADD20RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD21RoundRect,0.200000X-0.200000X-0.275000X0.200000X-0.275000X0.200000X0.275000X-0.200000X0.275000X0*%
%ADD22RoundRect,0.112500X0.112500X-0.187500X0.112500X0.187500X-0.112500X0.187500X-0.112500X-0.187500X0*%
%ADD23RoundRect,0.250000X0.650000X-1.000000X0.650000X1.000000X-0.650000X1.000000X-0.650000X-1.000000X0*%
%ADD24R,2.200000X0.400000*%
%ADD25RoundRect,0.100000X-0.225000X-0.100000X0.225000X-0.100000X0.225000X0.100000X-0.225000X0.100000X0*%
%ADD26R,6.450000X5.300000*%
%ADD27RoundRect,0.150000X0.150000X-0.587500X0.150000X0.587500X-0.150000X0.587500X-0.150000X-0.587500X0*%
%ADD28R,0.700000X1.200000*%
%ADD29R,0.760000X1.200000*%
%ADD30R,0.800000X1.200000*%
%ADD31RoundRect,0.243750X0.456250X-0.243750X0.456250X0.243750X-0.456250X0.243750X-0.456250X-0.243750X0*%
%ADD32R,1.070000X0.530000*%
%ADD33RoundRect,0.150000X0.587500X0.150000X-0.587500X0.150000X-0.587500X-0.150000X0.587500X-0.150000X0*%
%ADD34R,1.200000X0.270000*%
%ADD35R,0.270000X1.200000*%
%ADD36R,1.200000X1.800000*%
%ADD37RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD38R,0.600000X1.000000*%
%ADD39R,1.200000X0.600000*%
%ADD40R,2.400000X3.300000*%
%ADD41RoundRect,0.100000X-0.100000X0.225000X-0.100000X-0.225000X0.100000X-0.225000X0.100000X0.225000X0*%
%ADD42RoundRect,0.250000X1.000000X0.650000X-1.000000X0.650000X-1.000000X-0.650000X1.000000X-0.650000X0*%
%ADD43R,1.200000X0.500000*%
G04 APERTURE END LIST*
D10*
X186594442Y-122410210D03*
X188144442Y-122410210D03*
D11*
X168458966Y-118260712D03*
X166908966Y-118260712D03*
D10*
X158188180Y-107195974D03*
X159738180Y-107195974D03*
D12*
X202951133Y-104665534D03*
X210951133Y-104665534D03*
X202951133Y-109165534D03*
X210951133Y-109165534D03*
D10*
X186498159Y-120535261D03*
X188048159Y-120535261D03*
D13*
X163141120Y-116686961D03*
X163141120Y-118586961D03*
X165016120Y-117636961D03*
D14*
X159771321Y-108741969D03*
X159771321Y-110291969D03*
D15*
X158924572Y-102960590D03*
X154264572Y-102960590D03*
D16*
X148272523Y-93543316D03*
X148272523Y-95193316D03*
D17*
X161212267Y-117283573D03*
X161212267Y-115633573D03*
D14*
X148265612Y-90338172D03*
X148265612Y-91888172D03*
D18*
X161041538Y-127096790D03*
X159391538Y-127096790D03*
D19*
X151018909Y-89007494D03*
X151018909Y-83307494D03*
D20*
X150718124Y-96870191D03*
X152618124Y-96870191D03*
D21*
X174374351Y-129940450D03*
X176024351Y-129940450D03*
X158138180Y-111847959D03*
X159788180Y-111847959D03*
D10*
X176162472Y-126786884D03*
X177712472Y-126786884D03*
D22*
X156386756Y-120670500D03*
X156386756Y-118570500D03*
D23*
X150343692Y-117402201D03*
X150343692Y-113402201D03*
D24*
X174559466Y-111035534D03*
X174559466Y-110335534D03*
X174559466Y-109635534D03*
X174559466Y-108935534D03*
X174559466Y-108235534D03*
X174559466Y-107535534D03*
X174559466Y-106835534D03*
X174559466Y-106135534D03*
X174559466Y-105435534D03*
X174559466Y-104735534D03*
X174559466Y-104035534D03*
X174559466Y-103335534D03*
X174559466Y-102635534D03*
D10*
X178467267Y-124578690D03*
X180017267Y-124578690D03*
D18*
X171606612Y-129942382D03*
X169956612Y-129942382D03*
D25*
X158155852Y-120238248D03*
X158155852Y-120888248D03*
X158155852Y-121538248D03*
X160055852Y-121538248D03*
X160055852Y-120888248D03*
X160055852Y-120238248D03*
D16*
X142831133Y-89980534D03*
X142831133Y-91630534D03*
D18*
X156601572Y-97546454D03*
X154951572Y-97546454D03*
D21*
X145769655Y-97587083D03*
X147419655Y-97587083D03*
D10*
X181710179Y-116398550D03*
X183260179Y-116398550D03*
X158188180Y-113473015D03*
X159738180Y-113473015D03*
D21*
X159028030Y-86593369D03*
X160678030Y-86593369D03*
D18*
X154307133Y-124486382D03*
X152657133Y-124486382D03*
D16*
X158155040Y-108691969D03*
X158155040Y-110341969D03*
D11*
X180017267Y-121658690D03*
X178467267Y-121658690D03*
D21*
X183488159Y-120535261D03*
X185138159Y-120535261D03*
X161559017Y-122220255D03*
X163209017Y-122220255D03*
D10*
X186482004Y-118016635D03*
X188032004Y-118016635D03*
D26*
X161087776Y-90140150D03*
X216827776Y-90140150D03*
D27*
X159208406Y-125258345D03*
X161108406Y-125258345D03*
X160158406Y-123383345D03*
D12*
X210951133Y-113132201D03*
X218951133Y-113132201D03*
X210951133Y-117632201D03*
X218951133Y-117632201D03*
D10*
X178467267Y-123118690D03*
X180017267Y-123118690D03*
D12*
X194951133Y-113132201D03*
X202951133Y-113132201D03*
X194951133Y-117632201D03*
X202951133Y-117632201D03*
D21*
X161689189Y-120596440D03*
X163339189Y-120596440D03*
D10*
X164761789Y-120488899D03*
X166311789Y-120488899D03*
D21*
X183584442Y-122410210D03*
X185234442Y-122410210D03*
D10*
X154004818Y-111915048D03*
X155554818Y-111915048D03*
D13*
X158379151Y-97346136D03*
X158379151Y-99246136D03*
X160254151Y-98296136D03*
D28*
X142574466Y-88210000D03*
D29*
X140554466Y-88210000D03*
D30*
X139324466Y-88210000D03*
D28*
X141574466Y-88210000D03*
D29*
X143594466Y-88210000D03*
D30*
X144824466Y-88210000D03*
D31*
X146287603Y-91915281D03*
X146287603Y-90040281D03*
D21*
X183472004Y-118016635D03*
X185122004Y-118016635D03*
D32*
X153629818Y-106919279D03*
X153629818Y-107869279D03*
X153629818Y-108819279D03*
X155929818Y-108819279D03*
X155929818Y-107869279D03*
X155929818Y-106919279D03*
D10*
X168864228Y-116560375D03*
X170414228Y-116560375D03*
D33*
X160229235Y-95781538D03*
X160229235Y-93881538D03*
X158354235Y-94831538D03*
D18*
X163796670Y-97394465D03*
X162146670Y-97394465D03*
D10*
X164569017Y-122220255D03*
X166119017Y-122220255D03*
D34*
X176341495Y-125291194D03*
X176341495Y-124791194D03*
X176341495Y-124291194D03*
X176341495Y-123791194D03*
X176341495Y-123291194D03*
X176341495Y-122791194D03*
X176341495Y-122291194D03*
X176341495Y-121791194D03*
X176341495Y-121291194D03*
X176341495Y-120791194D03*
X176341495Y-120291194D03*
X176341495Y-119791194D03*
D35*
X174991495Y-118441194D03*
X174491495Y-118441194D03*
X173991495Y-118441194D03*
X173491495Y-118441194D03*
X172991495Y-118441194D03*
X172491495Y-118441194D03*
X171991495Y-118441194D03*
X171491495Y-118441194D03*
X170991495Y-118441194D03*
X170491495Y-118441194D03*
X169991495Y-118441194D03*
X169491495Y-118441194D03*
D34*
X168141495Y-119791194D03*
X168141495Y-120291194D03*
X168141495Y-120791194D03*
X168141495Y-121291194D03*
X168141495Y-121791194D03*
X168141495Y-122291194D03*
X168141495Y-122791194D03*
X168141495Y-123291194D03*
X168141495Y-123791194D03*
X168141495Y-124291194D03*
X168141495Y-124791194D03*
X168141495Y-125291194D03*
D35*
X169491495Y-126641194D03*
X169991495Y-126641194D03*
X170491495Y-126641194D03*
X170991495Y-126641194D03*
X171491495Y-126641194D03*
X171991495Y-126641194D03*
X172491495Y-126641194D03*
X172991495Y-126641194D03*
X173491495Y-126641194D03*
X173991495Y-126641194D03*
X174491495Y-126641194D03*
X174991495Y-126641194D03*
D10*
X154607149Y-116828160D03*
X156157149Y-116828160D03*
D21*
X158167759Y-118711221D03*
X159817759Y-118711221D03*
D36*
X146357799Y-127848868D03*
X146357799Y-119848868D03*
X150857799Y-127848868D03*
X150857799Y-119848868D03*
D12*
X210951133Y-126098868D03*
X202951133Y-126098868D03*
X210951133Y-121598868D03*
X202951133Y-121598868D03*
D37*
X144507305Y-91561135D03*
X144507305Y-89986135D03*
D21*
X153954818Y-110310463D03*
X155604818Y-110310463D03*
D38*
X154476567Y-120794558D03*
X153526567Y-120794558D03*
X152576567Y-120794558D03*
X152576567Y-122994558D03*
X154476567Y-122994558D03*
D39*
X156493169Y-94952776D03*
X156493169Y-93682776D03*
X156493169Y-92402776D03*
X156493169Y-91132776D03*
X150673169Y-91132776D03*
X150673169Y-92402776D03*
X150673169Y-93682776D03*
X150673169Y-94952776D03*
D40*
X153583169Y-93042776D03*
D18*
X167345504Y-116264585D03*
X165695504Y-116264585D03*
D14*
X157124998Y-88594361D03*
X157124998Y-90144361D03*
D21*
X178700179Y-116398550D03*
X180350179Y-116398550D03*
D16*
X157597011Y-124014185D03*
X157597011Y-125664185D03*
D41*
X159575680Y-115376388D03*
X158925680Y-115376388D03*
X158275680Y-115376388D03*
X158275680Y-117276388D03*
X158925680Y-117276388D03*
X159575680Y-117276388D03*
D42*
X159921580Y-84036310D03*
X155921580Y-84036310D03*
D16*
X172991495Y-128364551D03*
X172991495Y-130014551D03*
D10*
X174424341Y-128485724D03*
X175974341Y-128485724D03*
D14*
X155695101Y-123373307D03*
X155695101Y-124923307D03*
D11*
X154681287Y-119188736D03*
X153131287Y-119188736D03*
D36*
X146357799Y-110915534D03*
X146357799Y-102915534D03*
X150857799Y-110915534D03*
X150857799Y-102915534D03*
D11*
X167991495Y-126525753D03*
X166441495Y-126525753D03*
D21*
X152629250Y-125997645D03*
X154279250Y-125997645D03*
D43*
X153429818Y-113589341D03*
X153429818Y-114539341D03*
X153429818Y-115489341D03*
X156129818Y-115489341D03*
X156129818Y-113589341D03*
D16*
X141331133Y-89980534D03*
X141331133Y-91630534D03*
M02*

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,18 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.0*%
%TF.CreationDate,2025-03-23T23:41:23-05:00*%
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*%
%TF.CreationDate,2025-08-27T19:31:21-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.0) date 2025-03-23 23:41:23*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:21*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.050000*%
%ADD11C,1.600000*%
%ADD12C,0.200000*%
%ADD11C,0.200000*%
G04 APERTURE END LIST*
D10*
X13756447Y-13233553D02*
@ -37,35 +36,14 @@ X13756447Y-8153553D01*
X13256447Y-8653553D02*
G75*
G02*
X13756447Y-8153547I500003J3D01*
X13756447Y-8153554I499991J8D01*
G01*
X22146447Y-12733553D02*
G75*
G02*
X21646447Y-13233547I-499997J3D01*
X21646447Y-13233557I-500007J3D01*
G01*
D11*
X15825353Y-9000238D02*
G75*
G02*
X15665353Y-9000238I-80000J0D01*
G01*
X15665353Y-9000238D02*
G75*
G02*
X15825353Y-9000238I80000J0D01*
G01*
X21815353Y-9000238D02*
G75*
G02*
X21655353Y-9000238I-80000J0D01*
G01*
X21655353Y-9000238D02*
G75*
G02*
X21815353Y-9000238I80000J0D01*
G01*
D12*
X13514723Y-13547537D02*
X13514723Y-13347537D01*
X13514723Y-13347537D02*

View File

@ -0,0 +1,12 @@
M48
; DRILL file {KiCad 9.0.3} date 2025-08-27T19:31:21-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-08-27T19:31:21-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
; #@! TF.FileFunction,NonPlated,1,2,NPTH
FMAT,2
METRIC
%
G90
G05
M30

View File

@ -1,20 +1,19 @@
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.0*%
%TF.CreationDate,2025-03-23T23:41:23-05:00*%
%TF.GenerationSoftware,KiCad,Pcbnew,9.0.3*%
%TF.CreationDate,2025-08-27T19:31:21-05:00*%
%TF.ProjectId,stm32card,73746d33-3263-4617-9264-2e6b69636164,rev?*%
%TF.SameCoordinates,Original*%
%TF.FileFunction,Drillmap*%
%TF.FilePolarity,Positive*%
%FSLAX45Y45*%
G04 Gerber Fmt 4.5, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 9.0.0) date 2025-03-23 23:41:23*
G04 Created by KiCad (PCBNEW 9.0.3) date 2025-08-27 19:31:21*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.050000*%
%ADD11C,1.600000*%
%ADD12C,0.200000*%
%ADD13C,0.100000*%
%ADD11C,0.200000*%
%ADD12C,0.100000*%
G04 APERTURE END LIST*
D10*
X13756447Y-13233553D02*
@ -38,40 +37,19 @@ X13756447Y-8153553D01*
X13256447Y-8653553D02*
G75*
G02*
X13756447Y-8153547I500003J3D01*
X13756447Y-8153554I499991J8D01*
G01*
X22146447Y-12733553D02*
G75*
G02*
X21646447Y-13233547I-499997J3D01*
X21646447Y-13233557I-500007J3D01*
G01*
D11*
X15825353Y-9000238D02*
G75*
G02*
X15665353Y-9000238I-80000J0D01*
G01*
X15665353Y-9000238D02*
G75*
G02*
X15825353Y-9000238I80000J0D01*
G01*
X21815353Y-9000238D02*
G75*
G02*
X21655353Y-9000238I-80000J0D01*
G01*
X21655353Y-9000238D02*
G75*
G02*
X21815353Y-9000238I80000J0D01*
G01*
D12*
D13*
X13918113Y-8940553D02*
X13948113Y-8970553D01*
X13948113Y-8940553D02*
X13918113Y-8970553D01*
X13917892Y-8664431D02*
X13947892Y-8694431D01*
X13947892Y-8664431D02*
X13917892Y-8694431D01*
X14118113Y-9265553D02*
X14148113Y-9295553D01*
X14148113Y-9265553D02*
@ -80,94 +58,126 @@ X14268113Y-9265553D02*
X14298113Y-9295553D01*
X14298113Y-9265553D02*
X14268113Y-9295553D01*
X14467447Y-8940553D02*
X14497447Y-8970553D01*
X14497447Y-8940553D02*
X14467447Y-8970553D01*
X14480025Y-9463069D02*
X14510025Y-9493069D01*
X14510025Y-9463069D02*
X14480025Y-9493069D01*
X14760287Y-9819910D02*
X14790287Y-9849910D01*
X14790287Y-9819910D02*
X14760287Y-9849910D01*
X14862376Y-9467836D02*
X14892376Y-9497836D01*
X14892376Y-9467836D02*
X14862376Y-9497836D01*
X15334395Y-9898177D02*
X15364395Y-9928177D01*
X15364395Y-9898177D02*
X15334395Y-9928177D01*
X15667855Y-11963740D02*
X15697855Y-11993740D01*
X15697855Y-11963740D02*
X15667855Y-11993740D01*
X15670144Y-12113600D02*
X15700144Y-12143600D01*
X15700144Y-12113600D02*
X15670144Y-12143600D01*
X15817569Y-10323323D02*
X15847569Y-10353323D01*
X15847569Y-10323323D02*
X15817569Y-10353323D01*
X16008863Y-10671007D02*
X16038863Y-10701007D01*
X16038863Y-10671007D02*
X16008863Y-10701007D01*
X16496773Y-12636868D02*
X16526773Y-12666868D01*
X16526773Y-12636868D02*
X16496773Y-12666868D01*
X16518870Y-11809091D02*
X16548870Y-11839091D01*
X16548870Y-11809091D02*
X16518870Y-11839091D01*
X16835898Y-12978531D02*
X16865898Y-13008531D01*
X16865898Y-12978531D02*
X16835898Y-13008531D01*
X16890776Y-12443088D02*
X16920776Y-12473088D01*
X16920776Y-12443088D02*
X16890776Y-12473088D01*
X17001361Y-11510728D02*
X17031361Y-11540728D01*
X17031361Y-11510728D02*
X17001361Y-11540728D01*
X17382855Y-12523096D02*
X17412855Y-12553096D01*
X17412855Y-12523096D02*
X17382855Y-12553096D01*
X17415353Y-8521558D02*
X17445353Y-8551558D01*
X17445353Y-8521558D02*
X17415353Y-8551558D01*
X17415353Y-9484882D02*
X17445353Y-9514882D01*
X17445353Y-9484882D02*
X17415353Y-9514882D01*
X17469624Y-12182906D02*
X17499624Y-12212906D01*
X17499624Y-12182906D02*
X17469624Y-12212906D01*
X14467134Y-8660086D02*
X14497134Y-8690086D01*
X14497134Y-8660086D02*
X14467134Y-8690086D01*
X14927040Y-9274355D02*
X14957040Y-9304355D01*
X14957040Y-9274355D02*
X14927040Y-9304355D01*
X15250880Y-10923202D02*
X15280880Y-10953202D01*
X15280880Y-10923202D02*
X15250880Y-10953202D01*
X15255483Y-9421812D02*
X15285483Y-9451812D01*
X15285483Y-9421812D02*
X15255483Y-9451812D01*
X15258314Y-9157217D02*
X15288314Y-9187217D01*
X15288314Y-9157217D02*
X15258314Y-9187217D01*
X15281530Y-11802242D02*
X15311530Y-11832242D01*
X15311530Y-11802242D02*
X15281530Y-11832242D01*
X15320740Y-11606959D02*
X15350740Y-11636959D01*
X15350740Y-11606959D02*
X15320740Y-11636959D01*
X15343317Y-9289278D02*
X15373317Y-9319278D01*
X15373317Y-9289278D02*
X15343317Y-9319278D01*
X15425889Y-9421096D02*
X15455889Y-9451096D01*
X15455889Y-9421096D02*
X15425889Y-9451096D01*
X15429465Y-9158248D02*
X15459465Y-9188248D01*
X15459465Y-9158248D02*
X15429465Y-9188248D01*
X15554052Y-12614941D02*
X15584052Y-12644941D01*
X15584052Y-12614941D02*
X15554052Y-12644941D01*
X15604647Y-8950185D02*
X15634647Y-8980185D01*
X15634647Y-8950185D02*
X15604647Y-8980185D01*
X15662903Y-9909614D02*
X15692903Y-9939614D01*
X15692903Y-9909614D02*
X15662903Y-9939614D01*
X15674446Y-11176505D02*
X15704446Y-11206505D01*
X15704446Y-11176505D02*
X15674446Y-11206505D01*
X15719035Y-12051950D02*
X15749035Y-12081950D01*
X15749035Y-12051950D02*
X15719035Y-12081950D01*
X15882247Y-11094987D02*
X15912247Y-11124987D01*
X15912247Y-11094987D02*
X15882247Y-11124987D01*
X15884145Y-11795548D02*
X15914145Y-11825548D01*
X15914145Y-11795548D02*
X15884145Y-11825548D01*
X15891310Y-11431009D02*
X15921310Y-11461009D01*
X15921310Y-11431009D02*
X15891310Y-11461009D01*
X16061449Y-10704597D02*
X16091449Y-10734597D01*
X16091449Y-10704597D02*
X16061449Y-10734597D01*
X16087075Y-12116620D02*
X16117075Y-12146620D01*
X16117075Y-12116620D02*
X16087075Y-12146620D01*
X16531548Y-12657844D02*
X16561548Y-12687844D01*
X16561548Y-12657844D02*
X16531548Y-12687844D01*
X16548441Y-11843696D02*
X16578441Y-11873696D01*
X16578441Y-11843696D02*
X16548441Y-11873696D01*
X16915838Y-12443795D02*
X16945838Y-12473795D01*
X16945838Y-12443795D02*
X16915838Y-12473795D01*
X16995202Y-12854751D02*
X17025202Y-12884751D01*
X17025202Y-12854751D02*
X16995202Y-12884751D01*
X17026423Y-11533452D02*
X17056423Y-11563452D01*
X17056423Y-11533452D02*
X17026423Y-11563452D01*
X17279775Y-10249839D02*
X17309775Y-10279839D01*
X17309775Y-10249839D02*
X17279775Y-10279839D01*
X17407917Y-12523803D02*
X17437917Y-12553803D01*
X17437917Y-12523803D02*
X17407917Y-12553803D01*
X17494686Y-12183613D02*
X17524686Y-12213613D01*
X17524686Y-12183613D02*
X17494686Y-12213613D01*
X17602115Y-10598553D02*
X17632115Y-10628553D01*
X17632115Y-10598553D02*
X17602115Y-10628553D01*
X17604964Y-10248553D02*
X17634964Y-10278553D01*
X17634964Y-10248553D02*
X17604964Y-10278553D01*
X17604964Y-10388553D02*
X17634964Y-10418553D01*
X17634964Y-10388553D02*
X17604964Y-10418553D01*
X17681471Y-12832865D02*
X17711471Y-12862865D01*
X17711471Y-12832865D02*
X17681471Y-12862865D01*
X17706533Y-12833572D02*
X17736533Y-12863572D01*
X17736533Y-12833572D02*
X17706533Y-12863572D01*
X17736654Y-11624855D02*
X17766654Y-11654855D01*
X17766654Y-11624855D02*
@ -188,22 +198,10 @@ X18215680Y-11786663D02*
X18245680Y-11816663D01*
X18245680Y-11786663D02*
X18215680Y-11816663D01*
X18725353Y-8521558D02*
X18755353Y-8551558D01*
X18755353Y-8521558D02*
X18725353Y-8551558D01*
X18725353Y-9484882D02*
X18755353Y-9514882D01*
X18755353Y-9484882D02*
X18725353Y-9514882D01*
X20035353Y-8521558D02*
X20065353Y-8551558D01*
X20065353Y-8521558D02*
X20035353Y-8551558D01*
X20035353Y-9484882D02*
X20065353Y-9514882D01*
X20065353Y-9484882D02*
X20035353Y-9514882D01*
X21667778Y-8647536D02*
X21697778Y-8677536D01*
X21697778Y-8647536D02*
X21667778Y-8677536D01*
X13805447Y-8433000D02*
G75*
G02*
@ -300,7 +298,7 @@ G75*
G03*
X14669447Y-8843000I30000J0D01*
G01*
D12*
D11*
X13514723Y-13547537D02*
X13514723Y-13347537D01*
X13514723Y-13347537D02*
@ -439,12 +437,12 @@ X14876628Y-13433251D02*
X14886152Y-13423728D01*
X14886152Y-13423728D02*
X14886152Y-13442775D01*
D13*
D12*
X13223947Y-13861053D02*
X13253947Y-13891053D01*
X13253947Y-13861053D02*
X13223947Y-13891053D01*
D12*
D11*
X13552819Y-13767537D02*
X13571866Y-13767537D01*
X13571866Y-13767537D02*
@ -879,12 +877,48 @@ X16914724Y-13967537D02*
X16895676Y-13958013D01*
X16895676Y-13958013D02*
X16886152Y-13948489D01*
X17181390Y-13834204D02*
X17181390Y-13967537D01*
X17133771Y-13758013D02*
X17086152Y-13900870D01*
X17086152Y-13900870D02*
X17209962Y-13900870D01*
X17105200Y-13967537D02*
X17143295Y-13967537D01*
X17143295Y-13967537D02*
X17162343Y-13958013D01*
X17162343Y-13958013D02*
X17171867Y-13948489D01*
X17171867Y-13948489D02*
X17190914Y-13919918D01*
X17190914Y-13919918D02*
X17200438Y-13881823D01*
X17200438Y-13881823D02*
X17200438Y-13805632D01*
X17200438Y-13805632D02*
X17190914Y-13786585D01*
X17190914Y-13786585D02*
X17181390Y-13777061D01*
X17181390Y-13777061D02*
X17162343Y-13767537D01*
X17162343Y-13767537D02*
X17124248Y-13767537D01*
X17124248Y-13767537D02*
X17105200Y-13777061D01*
X17105200Y-13777061D02*
X17095676Y-13786585D01*
X17095676Y-13786585D02*
X17086152Y-13805632D01*
X17086152Y-13805632D02*
X17086152Y-13853251D01*
X17086152Y-13853251D02*
X17095676Y-13872299D01*
X17095676Y-13872299D02*
X17105200Y-13881823D01*
X17105200Y-13881823D02*
X17124248Y-13891347D01*
X17124248Y-13891347D02*
X17162343Y-13891347D01*
X17162343Y-13891347D02*
X17181390Y-13881823D01*
X17181390Y-13881823D02*
X17190914Y-13872299D01*
X17190914Y-13872299D02*
X17200438Y-13853251D01*
X17438533Y-13967537D02*
X17438533Y-13767537D01*
X17524248Y-13967537D02*
@ -1013,7 +1047,7 @@ X18248057Y-13777061D02*
X18229010Y-13748489D01*
X18229010Y-13748489D02*
X18219486Y-13738966D01*
D13*
D12*
X13253947Y-14140053D02*
G75*
G02*
@ -1024,7 +1058,7 @@ G75*
G02*
X13253947Y-14140053I30000J0D01*
G01*
D12*
D11*
X13552819Y-14031537D02*
X13571866Y-14031537D01*
X13571866Y-14031537D02*

View File

@ -0,0 +1,65 @@
M48
; DRILL file {KiCad 9.0.3} date 2025-08-27T19:31:21-0500
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2025-08-27T19:31:21-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,9.0.3
; #@! TF.FileFunction,Plated,1,2,PTH
FMAT,2
METRIC
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T1C0.300
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T2C0.600
%
G90
G05
T1
X139.329Y-86.794
X141.331Y-92.806
X142.831Y-92.806
X144.821Y-86.751
X149.42Y-92.894
X152.659Y-109.382
X152.705Y-94.368
X152.733Y-91.722
X152.965Y-118.172
X153.357Y-116.22
X153.583Y-93.043
X154.409Y-94.361
X154.445Y-91.732
X155.691Y-126.299
X156.196Y-89.652
X156.779Y-99.246
X156.894Y-111.915
X157.34Y-120.669
X158.972Y-111.1
X158.991Y-118.105
X159.063Y-114.46
X160.764Y-107.196
X161.021Y-121.316
X165.465Y-126.728
X165.634Y-118.587
X169.308Y-124.588
X170.102Y-128.698
X170.414Y-115.485
X172.948Y-102.648
X174.229Y-125.388
X175.097Y-121.986
X176.171Y-106.136
X177.215Y-128.486
X177.517Y-116.399
X181.016Y-123.112
X182.194Y-122.41
X182.291Y-120.535
X182.307Y-118.017
X216.828Y-86.625
T2
X137.754Y-84.63G85X137.754Y-84.03
G05
X137.754Y-88.43G85X137.754Y-87.83
G05
X146.394Y-84.63G85X146.394Y-84.03
G05
X146.394Y-88.43G85X146.394Y-87.83
G05
M30

Binary file not shown.

BIN
mandrel_border_sample.xcf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 946 B

View File

@ -1,256 +1,256 @@
ptype render_mandelbrot:cam
ptype render_mandelbrot:camera
set draw_mandelbrot:cam
set draw_mandelbrot()::cam
draw_mandelbrot()::cam
print $3
ptype $3
bruh = 1
set bruh = 1
set $bruh = 1
set $bruh = {
min_r = -1,
min_i = -0.5,
max_r = 1,
max_i = 0.5
}
set $bruh = {1, 2, 3, 4}
bruh
print $bruh
set draw_mandelbrot()::cam
set draw_mandelbrot()::cam = $bruh
set draw_mandelbrot()::cam.min_r = -2
set draw_mandelbrot()::cam
set draw_mandelbrot()::cam = 0
set draw_mandelbrot()::cam = {0}
print $bruh
print draw_mandelbrot()::cam
print draw_mandelbrot()::cam
set draw_mandelbrot()::cam = {
min_r = 0,
min_i = 0,
max_r = 0,
max_i = 0
}
set draw_mandelbrot()::cam = {0, 0, 0, 0}
set draw_mandelbrot()::cam = {0, 1, 2, 3}
print draw_mandelbrot()::cam
bruh
print $bruh
set draw_mandelbrot()::cam = bruh
set draw_mandelbrot()::cam = $bruh
set bruh = draw_mandelbrot()::cam
set $bruh = draw_mandelbrot()::cam
print $bruh
set draw_mandelbrot()::cam = $bruh
bruh = { asdf = 0 }
set $bruh = { asdf = 0 }
set $bruh = { min_r = 0 }
print bruh
print bruh
print $bruh
bruh.min_r
set $bruh.min_r = 1
set #bruh
print $bruh
set draw_mandelbrot()::cam = $bruh
print draw_mandelbrot()::cam
print $bruh[0]
print $bruh
set $bruh = {$bruh, $bruh}
bruh
print $bruh
print $bruh[0]
print $bruh[1]
load
c
c
print draw_mandelbrot()::cam
set $asdf = {
min_r = -1,
min_i = -0.5,
max_r = 1,
max_i = 0.5
}
set $bruh = {
min_r = -1,
min_i = -0.5,
max_r = 1,
max_i = 0.5
}
set $bruh[0] = {
min_r = -1,
min_i = -0.5,
max_r = 1,
max_i = 0.5
}
set $bruh[0] = {
.min_r = -1,
min_i = -0.5,
max_r = 1,
max_i = 0.5
}
print camera
print *cam
print draw_mandelbrot()::cam
c
quit
d
c
quit
c
quit
c
load
c
print *cam
print draw_mandelbrot()::cam
x
c
print draw_mandelbrot()::cam
c
load
c
print draw_mandelbrot()::cam
printf "%1.20f\n" draw_mandelbrot()::cam
printf "%1.20f\n", draw_mandelbrot()::cam.min_i
printf "%1.20f\n", draw_mandelbrot()::cam.max_r
print 3
print -1.4054856689592869e-05
for
while
exit
quit
len(vi
len(vi)
quit
quit
quit
quit
command render_mandelbrot(0xff)
c
command render_mandelbrot(0xff)
c
quit
c
quit
quit
quit
print render_mandelbrot
quit
quit
c
set draw_mandelbrot()::view_mode 0
set draw_mandelbrot()::view_mode = 0
quit
quit
load
c
quit
c
c
quit
disp benchmark_stop:time
disp benchmark_stop.time
disp benchmark_stop()::time
quit
quit
quit
exit
quit
quit
quit
c
c
load
quit
c
load
load
exit
load
c
quit
quit
quit
quit
load
c
b mandelbrot.c:102
c
c
c
c
c
c
c
load
c
quit
info b
b render_mandelbrot
c
c
c
c
c
c
c
c
c
c
quit
b render_mandelbrot
c
context
next
context
p sizeof(bool)
p sizeof(uint16_t)
context
print bruh
print &bruh
print &framebuffer
context
f 1
print &framebuffer
context
p &view_mode
print bottom_buffered
print &bottom_buffered
print &bottom_buffered
print &view_mode
f 0
print bruh
print &bruh
print &bruh
exit
load
quit
quit
c
quit
c
b render_mandelbrot
c
c
d
b 80012d0
b 0x80012d0
b *0x80012d0
c
next
reg
p _sbss
p (uintptr_32)_sbss
p/x_sbss
p/x _sbss
p (void *)_sbss
p (void)_sbss
p (void *)&_sbss
p (void *)&__bss_start__
p sp
reg
n
print borders
n
print nei_dir
n
n
print nei_dir
print this_index
print pixels[this_index]
print framebuffer[this_index]
print framebuffer[this_index] & G_MASK
print framebuffer[this_index+1] & G_MASK
next
print gchan_info
next
print i
print this_coord
print get_neighbor_coord(this_coord, nei_dir, scale)
print FIXED_TO_DOUBLE(this_coord.r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, nei_dir, scale))
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, nei_dir, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 0, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 0, scale).r) 1
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 0, scale).r), 1
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 0, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 1, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 2, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 3, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 4, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 5, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 6, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 7, scale).r)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 0, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 1, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 2, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 3, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 4, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 5, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 6, scale).i)
print FIXED_TO_DOUBLE(get_neighbor_coord(this_coord, 7, scale).i)
print FIXED_TO_DOUBLE(this_coord.i)
c
c
quit
c
c
quit
c
quit
c
c
quit
quit
c
c
quit
next
qiot
quit
c
quit
quit
c
c
f 2
context
quit
c
quit
c
quit
'c
c
c
quit
c
HAL_GPIO_TogglePin
print HAL_GPIO_TogglePin()
b idle
c
print HAL_GPIO_TogglePin()
quit
c
c
quit
quit
c
quit
c
b idle
c
next
print charging_bat
print charging_bat()
print charging_batt()
b charging_batt
c
print HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN)
print ~HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN)
print ~(HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN))
print !(HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN))
print (HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN))
print GPIO_PIN_SET
ptype GPIO_PIN_SET
quit
print HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN)
b charging_batt
c
step
quit
b idle
c
next
print charing_batt()
print charging_batt()
print event_peek()
next
next
c
next
next
next
b idle
d
c
b idle
c
next
print event_peek
print event_peek()
print ST7735_wake()
b ST7735_wake
c
c
next
next
next
c
next
quit
c
quit
c
b idle.c:23
c
c
quit
c
c
c
print ST7735_sleep()
c
print ST7735_wake()
quit
b main
c
next
print ST7735_sleep()
print ST7735_wake()
exit
c
quit
c
quit
c
quit
c
quit
c
quit
quit
c
quit
c
quit
c
quit
c
quit
c
quit
c
quit
c
quit
quit
c
quit
c
quit
c
next
quit
c
print on_pixel
next
quit
c
next
quit
quit
c
print y
print x
next
next
print framebuffer[on_pixel] & G_MASK
print framebuffer[on_pixel]
print framebuffer[on_pixel] & ~G_MASK
quit
c
c
quit
c
c
quit
c
next
next
quit
quit
c
c
step
print on_pixel
quit
c
next
print border
print borders
next
print iterate(this_coord)
quit
c
quit
c
print framebuffer[this_index]
print framebuffer[this_index] & GCHAN
print framebuffer[this_index] & G_MASK
print framebuffer[nei_i] & G_MASK
print nei_i
print framebuffer[nei_i] & G_MASK
next
print i
print colorscheme[i]
print ITERS
quit
c
c
c
c
quit
quit

View File

@ -0,0 +1,24 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "stm32f1xx_hal.h"
/** all external interupts will be on GPIOB due to hardware layout and software convinience
TODO move to gpio.h or somethin
**/
#define GPIO_EXTI_REG GPIOB
#define BUTTON_UP GPIO_PIN_3
#define BUTTON_RIGHT GPIO_PIN_2
#define BUTTON_DOWN GPIO_PIN_0
#define BUTTON_LEFT GPIO_PIN_1
#define BUTTON_A GPIO_PIN_13
#define BUTTON_B GPIO_PIN_14
#define CHARGING_PIN GPIO_PIN_12
#define EVENT_NONE 0
extern int button;
void HAL_GPIO_EXTI_Callback(uint16_t pin);
int event_get();
int event_peek();
bool charging_batt();

View File

@ -0,0 +1,2 @@
#pragma once
void idle();

View File

@ -35,7 +35,8 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
void SystemClock_Config();
extern TIM_HandleTypeDef htim2;
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
@ -58,13 +59,6 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN Private defines */
#define GPIO_BUTTON_REG GPIOB
#define BUTTON_UP GPIO_PIN_3
#define BUTTON_RIGHT GPIO_PIN_2
#define BUTTON_DOWN GPIO_PIN_0
#define BUTTON_LEFT GPIO_PIN_1
#define BUTTON_A GPIO_PIN_13
#define BUTTON_B GPIO_PIN_14
/* USER CODE END Private defines */

View File

@ -1,11 +1,3 @@
#pragma once
extern int state;
enum states {
MANDELBROT,
BURNINGSHIP,
SCREENSAVER,
HELP,
};
void draw_mandelbrot(int key_pressed);
void draw_mandelbrot();

View File

@ -27,6 +27,9 @@ extern SPI_HandleTypeDef ST7735_SPI_PORT;
#define ST7735_DC_Pin GPIO_PIN_0 //data command pin - RS on datasheet
#define ST7735_DC_GPIO_Port GPIOB
#define BACKLIGHT_PORT GPIOB
#define BACKLIGHT_PIN GPIO_PIN_15
// AliExpress/eBay 1.8" display, default orientation
/*
#define ST7735_IS_160X128 1

View File

@ -14,3 +14,7 @@ void benchmark_stop() {
__NOP();
// __BKPT();
}
void benchmark() {
}

View File

@ -0,0 +1,16 @@
#include "gpio.h"
#include <stdint.h>
#include <stdbool.h>
int gpio_event = EVENT_NONE;
void HAL_GPIO_EXTI_Callback(uint16_t pin) { gpio_event = pin; }
int event_get() {
int event = gpio_event;
gpio_event = EVENT_NONE;
return event;
}
int event_peek() { return gpio_event; }
bool charging_batt() { return !HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN); }
//bool charging_batt() { return ~HAL_GPIO_ReadPin(GPIO_EXTI_REG, CHARGING_PIN); }

View File

@ -0,0 +1,33 @@
#include "stm32f1xx_hal.h"
#include "st7735.h"
#include "gpio.h"
#include "idle.h"
#include "main.h"
void idle() {
while(charging_batt() && (event_peek() == EVENT_NONE)) {
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
if(!charging_batt() && (event_peek() == EVENT_NONE)) {
HAL_TIM_Base_Stop_IT(&htim2);
HAL_SuspendTick();
__HAL_TIM_SET_COUNTER(&htim2, 0);
HAL_TIM_Base_Start_IT(&htim2);
//in this power state we still recieve timer interrupts
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI); //TODO ajust time
}
SystemClock_Config();
HAL_ResumeTick();
if(!charging_batt() && (event_peek() == EVENT_NONE)) {
ST7735_sleep();
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
ST7735_wake();
event_get();
}
}

View File

@ -25,6 +25,7 @@
#include "st7735.h"
#include "mandelbrot.h"
#include "benchmark.h"
#include "stm32f1xx_it.h"
//#include "mandelbrot.h"
/* USER CODE END Includes */
@ -81,10 +82,6 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) {
int button_pressed = 0;
bool button_event;
void HAL_GPIO_EXTI_Callback(uint16_t pin) {
button_event = true;
button_pressed = pin;
}
/* USER CODE END 0 */
/**
@ -103,7 +100,7 @@ int main(void)
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USE CODE BEGIN Init */
/* USER CODE BEGIN Init */
/* USER CODE END Init */
@ -122,39 +119,15 @@ int main(void)
/* USER CODE BEGIN 2 */
ST7735_Init();
ST7735_InvertColors(false);
//ST7735_FillScreenFast(ST7735_MAGENTA);
ST7735_FillScreenFast(ST7735_BLUE);
HAL_ResumeTick();
/* USER CODE END 2 */
//HAL_GPIO_EXTI_Callback(0xff);
draw_mandelbrot(button_pressed);
BENCHMARK_INIT: //for benchmarking gdb script
HAL_SuspendTick();
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
//we'll clean everything up later
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//later we'll impliment menu
if(button_event) {
button_event = false;
HAL_ResumeTick();
draw_mandelbrot(button_pressed);
HAL_TIM_Base_Stop_IT(&htim2);
HAL_SuspendTick();
__HAL_TIM_SET_COUNTER(&htim2, 0);
HAL_TIM_Base_Start_IT(&htim2);
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();
}
else { //zzzzz
//ST7735_sleep();
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
ST7735_wake();
}
draw_mandelbrot();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
@ -346,6 +319,9 @@ static void MX_GPIO_Init(void)
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
/*Configure GPIO pins : PA0 PA1 PA2 PA3 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
@ -359,12 +335,25 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PB12 */
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PB13 PB14 */
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PB15 */
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);

View File

@ -2,8 +2,9 @@
#include <string.h>
#include "mandelbrot.h"
#include "st7735.h"
#include "benchmark.h"
#include "main.h"
#include "gpio.h"
#include "idle.h"
#define RES_X 160
#define RES_Y 80
@ -29,6 +30,8 @@
#define G_BITS 6
#define B_BITS 5
#define G_MASK 0xe007
//imaginary axis set automatically
#define CAM_DEF_MIN_R -1
#define CAM_DEF_MAX_R 1
@ -41,21 +44,92 @@
#define CAM_ZOOM_IN BUTTON_A
#define CAM_ZOOM_OUT BUTTON_B
#define BACKSTACK_SIZE 32
#define GCHAN_UNRENDERED 0 //don't change; green channel zero'd on cam move
#define GCHAN_BLOCKED (1 << 2) //interior element or visiteed
#define GCHAN_INTERNAL (1 << 1) //part of set, 0x20
#define GCHAN_EXTERNAL (1 << 0) //not part of set, 0x10
enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
struct camera {
double min_r, min_i, max_r, max_i;
};
struct window {
unsigned int x0, y0, w, h;
};
//C does remainder, not modulo.
//TODO optimize for mod 8. Benchmark
inline int mod(int n, int d) {
int r = n % d;
return (r < 0) ? r + d : r;
}
int mod(int n, int d);
inline FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i; //up
if((direction > N) && (direction < S)) from_coord.r += step.r; //right
if((direction > E) && (direction < W)) from_coord.i -= step.i; //down
if(direction > S) from_coord.r -= step.r; //left
return from_coord;
}
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction, struct window win) {
//TODO gross since window is no longer constant
int neighbor_index_accl[8] =
{-win.w, -win.w + 1, 1, win.w + 1, win.w, win.w - 1, -1, -win.w - 1};
from_pixel += neighbor_index_accl[direction];
return from_pixel;
}
void detect_borders(bool borders[8], size_t i, struct window win) {
//if this is too slow, it's easy to do it without the modulos.
int index_mod = i % win.w;
bzero(borders, sizeof(*borders) * 8);
if((i + win.w) >= (win.w * win.h)) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
borders[nei_dir] = true;
}
else if(((int)(i - win.w)) < 0) {
borders[NE] = true;
borders[N] = true;
borders[NW] = true;
}
if(index_mod == 0) {
for(int nei_dir = SW; nei_dir <= NW; nei_dir++)
borders[nei_dir] = true;
}
else if(index_mod == (win.w - 1)) {
for(int nei_dir = NE; nei_dir <= SE; nei_dir++)
borders[nei_dir] = true;
}
}
enum VIEW_MODES { VIEW_UNINIT, VIEW_MANDREL, VIEW_SHIP };
void init_colorscheme_mandrel(uint16_t *scheme) {
void init_colorscheme(uint16_t *scheme) {
uint16_t *tc = scheme;
for(unsigned int i = 0; i < ITERS; i++) {
if((i == 0) || (i == ITERS)) *tc = 0;
else if(i < 128) *tc = (((((i - 64) << 2)+0x1f) & 0x1f) | (((((i - 128) << 1)+0x1f) & 0x1f) << (5+6)));
for(unsigned int i = 0; i <= ITERS; i++) {
if(i < 128) *tc = (((((i - 64) << 2)+0x1f) & 0x1f) | (((((i - 128) << 1)+0x1f) & 0x1f) << (5+6)));
else *tc = (-2*(i - 128)+0x1f) & 0xff;
*tc = (*tc << 8) | (*tc >> 8); //convert to little endian
*tc &= ~0b111;
tc++;
}
scheme[0] = 0;
scheme[ITERS] = 0;
}
void init_colorscheme_ship(uint16_t *scheme) {
@ -85,10 +159,183 @@ void cam_zoom(struct camera *cam, double zoom) {
cam->max_r -= r_scale;
}
inline int __attribute__((always_inline)) iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
for(int it = 0; it < ITERS; it++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
//TODO look into border tracing; this is too slow. Change name
//
void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, int x0, int y0, int w, int h) {
zn_r = z_r_2 - z_i_2 + c.r;
//zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
z_i = zn_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) return it;
}
return ITERS;
}
int iterate(FixedCord c);
unsigned int mandelbrot_bordertrace(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, const struct window win) {
unsigned int total_iters = 0;
size_t on_pixel = 0;
bool border_scanning = false;
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y)
};
FixedCord c = {
.i = DOUBLE_TO_FIXED((((cam.max_i - cam.min_i) * (RES_Y - win.y0)) / RES_Y) + cam.min_i),
.r = DOUBLE_TO_FIXED((((cam.max_r - cam.min_r) * win.x0) / RES_X) + cam.min_r)
};
uint64_t r0 = c.r;
for(int y = win.y0; y < (win.y0 + win.h); y++) {
border_scanning = false;
c.r = r0;
for(int x = win.x0; x < (win.x0 + win.w); x++) {
if(framebuffer[on_pixel] & G_MASK) {
border_scanning = false;
framebuffer[on_pixel] &= G_MASK;
}
else if(border_scanning) { framebuffer[on_pixel] &= G_MASK; }
else {
int i = iterate(c);
total_iters += i;
framebuffer[on_pixel] = colorscheme[i];
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
bool seperated_from_start = false;
bool nei_canidate[8];
int nei_presort[8];
size_t backstack[BACKSTACK_SIZE];
int backstack_i = 0;
int backstack_calls = 0;
int nei_dir;
bool borders[8];
detect_borders(borders, this_index, win);
//interior check
for(nei_dir = 0; nei_dir < 8; nei_dir++) {
if(borders[nei_dir] || (framebuffer[get_neighbor_index(on_pixel, nei_dir, win)] & GCHAN_EXTERNAL)) break;
}
if(nei_dir < 8) {
while(true) {
bzero(nei_presort, sizeof(nei_presort));
bzero(nei_canidate, sizeof(nei_canidate));
detect_borders(borders, this_index, win);
//step 1: check pixels around us, fill in neighbors.
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
bool start_is_nei = false;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(borders[nei_dir]) {
nei_presort[nei_dir] = GCHAN_EXTERNAL;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir, win);
gchan_info = framebuffer[nei_i] & G_MASK;
if(nei_i == on_pixel) start_is_nei = true;
if(gchan_info) nei_presort[nei_dir] = gchan_info;
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
framebuffer[nei_i] = colorscheme[i];
nei_presort[nei_dir] =
(i >= ITERS) ? GCHAN_INTERNAL : GCHAN_EXTERNAL;
framebuffer[nei_i] |= nei_presort[nei_dir];
}
}
if(!start_is_nei && !seperated_from_start && (this_index != on_pixel)) seperated_from_start = true;
if(start_is_nei && seperated_from_start) {
framebuffer[this_index] |= GCHAN_BLOCKED;
break;
}
int edge_cnt = 0;
//see what neighbors are good canidates for the next pixel in our path
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
int nei_edge_i;
if(nei_presort[nei_dir] != GCHAN_INTERNAL) {
continue;
}
for(nei_edge_i = -2; nei_edge_i <= 2; nei_edge_i++) {
int nei_edge_mod = mod((nei_dir + nei_edge_i), 8);
if((nei_presort[nei_edge_mod] == GCHAN_EXTERNAL) || borders[nei_edge_mod]) break;
}
//no edge found
if(nei_edge_i > 2) continue;
//narrow bridge scenario
if(nei_presort[mod((nei_dir + 1), 8)] & nei_presort[mod((nei_dir - 1), 8)] & GCHAN_EXTERNAL)
continue;
edge_cnt++;
nei_canidate[nei_dir] = true;
}
if(edge_cnt >= 2) backstack[backstack_i++ % BACKSTACK_SIZE] = this_index;
//now go to canidate with lowest prioraty
framebuffer[this_index] |= GCHAN_BLOCKED;
for(nei_dir = 0; nei_dir < 8; nei_dir += 2) {
if(!nei_canidate[nei_dir]) continue;
backstack_calls = 0;
this_index = get_neighbor_index(this_index, nei_dir, win);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
break;
}
if(nei_dir >= 8) {
if((backstack_calls++ > BACKSTACK_SIZE) || (backstack_i < 1)) break;
this_index = backstack[--backstack_i % BACKSTACK_SIZE];
this_coord.r = DOUBLE_TO_FIXED(((((this_index % win.w) + win.x0) / (double)RES_X) * (cam.max_r - cam.min_r)) + cam.min_r);
this_coord.i = DOUBLE_TO_FIXED(((((this_index / (double)win.w) + win.y0) / (double)RES_Y) * (cam.min_i - cam.max_i)) + cam.max_i);
}
}
}
else border_scanning = true;
}
else framebuffer[on_pixel] |= GCHAN_EXTERNAL;
}
on_pixel++;
c.r += scale.r;
}
c.i -= scale.i;
}
for(size_t i = 0; i < (win.w * win.h); i++) framebuffer[i] &= ~G_MASK;
return total_iters;
}
//TODO rename
unsigned int render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, int x0, int y0, int w, int h) {
int32_t scale_i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y);
int32_t scale_r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X);
int32_t c_i = DOUBLE_TO_FIXED((((cam.max_i - cam.min_i) * (RES_Y - y0)) / RES_Y) + cam.min_i);
@ -96,17 +343,7 @@ void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct came
int32_t c_r, z_i, z_r, zn_r, z_r_2, z_i_2;
size_t fb_index = 0;
int i;
/**
bool bruh[RES_X * (RES_Y/2)];
for(size_t i = 0; i < sizeof(bruh) / sizeof(bruh[0]); i++) {
bruh[i] = i % 1;
}
for(size_t i = sizeof(bruh) / sizeof(bruh[0]); i > 0; i--) {
framebuffer[i] = bruh[i];
}
**/
unsigned int total_iters = 0;
for(int y = y0; y < y0 + h; y++) {
c_r = c_r0;
@ -125,106 +362,98 @@ void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct came
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) break;
}
total_iters += i;
framebuffer[fb_index++] = colorscheme[i];
c_r += scale_r;
}
c_i -= scale_i;
}
return total_iters;
}
#define FB_SIZE_X RES_X
#define FB_SIZE_Y RES_Y/2
#define FB_SIZE_X RES_X/2
#define FB_SIZE_Y RES_Y
//TODO rename
void draw_mandelbrot(int key_pressed) {
static uint16_t framebuffer[FB_SIZE_X * FB_SIZE_Y];
uint16_t columnbuffer[8*RES_Y];
static bool bottom_buffered = true;
void draw_mandelbrot() {
uint16_t framebuffer[FB_SIZE_X * FB_SIZE_Y];
uint16_t columnbuffer[(size_t)(STEP_SIZE * RES_X * RES_Y)];
uint16_t left_line = 0;
//program flow is awful atm becuase I was planning something different; will be improved soon.
/**
static struct camera cam = {
.min_r = CAM_DEF_MIN_R,
.max_r = CAM_DEF_MAX_R,
.min_i = ((double)RES_Y / RES_X) * CAM_DEF_MIN_R,
.max_i = ((double)RES_Y / RES_X) * CAM_DEF_MAX_R,
};
static int view_mode = VIEW_UNINIT;
static uint16_t colorscheme[ITERS];
**/
struct camera cam = {
.min_r = 1.511138965827779623297, .min_i = -0.000099833545397436595, .max_r = 1.513299500557251375810, .max_i = 0.000980433819429512915
};
uint16_t colorscheme[ITERS + 1];
//yes, I know the following is disgusting. Before I clean it, I just wanna get the general idea out,
//it's more efficient in that order
//TODO once you get your idea ironed out, clean the code and improve the flow
benchmark_start();
if(view_mode == VIEW_UNINIT) {
view_mode = VIEW_MANDREL;
init_colorscheme_mandrel(colorscheme);
render_mandelbrot(framebuffer, colorscheme, cam, 0, 0, RES_X, RES_Y/2);
ST7735_DrawImage(0, 0, RES_X, (RES_Y / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, 0, RES_Y/2, RES_X, RES_Y/2);
ST7735_DrawImage(0, (RES_Y / 2), RES_X, (RES_Y / 2), framebuffer);
bottom_buffered = true;
}
else {
const int y_offset = STEP_SIZE * RES_Y;
/** yes, I know the following is disgusting. Before I clean it, I just wanna get the general idea out,
it's more efficient in that order
TODO once you get your idea ironed out, clean code **/
init_colorscheme(colorscheme);
bzero(framebuffer, sizeof(framebuffer));
bzero(columnbuffer, sizeof(columnbuffer));
while(true) {
const int y_offset = STEP_SIZE * FB_SIZE_Y;
const int x_offset = STEP_SIZE * RES_X;
const size_t bottom_space = RES_X * ((RES_Y/2) - y_offset) * sizeof(uint16_t);
uint16_t top_line = bottom_buffered ? (RES_Y/2) : 0;
switch(key_pressed) {
const size_t top_space = FB_SIZE_X * (FB_SIZE_Y - y_offset) * sizeof(uint16_t);
left_line = left_line ? (RES_X/2) : 0;
switch(event_get()) {
case BUTTON_UP:
cam_shift(&cam, 0, STEP_SIZE);
memmove(framebuffer + (RES_X * y_offset), framebuffer, bottom_space);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, y_offset);
memmove(framebuffer + (FB_SIZE_X * y_offset), framebuffer, top_space);
mandelbrot_bordertrace(framebuffer, colorscheme, cam, (struct window){left_line, 0, FB_SIZE_X, y_offset});
break;
case BUTTON_DOWN:
uint16_t bottom_line = (bottom_buffered ? RES_Y : (RES_Y/2)) - y_offset;
cam_shift(&cam, 0, -STEP_SIZE);
memmove(framebuffer, framebuffer + (RES_X * y_offset), bottom_space);
render_mandelbrot(framebuffer + (RES_X*((RES_Y/2)-y_offset)), colorscheme, cam, 0, bottom_line, RES_X, y_offset);
memmove(framebuffer, framebuffer + (FB_SIZE_X * y_offset), top_space);
mandelbrot_bordertrace(framebuffer + (FB_SIZE_X * (FB_SIZE_Y - y_offset)), colorscheme, cam, (struct window){left_line, (RES_Y - y_offset), FB_SIZE_X, y_offset});
break;
case BUTTON_RIGHT:
cam_shift(&cam, STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, RES_X - x_offset, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y), framebuffer + (RES_X * y) + x_offset, (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y) + (RES_X - x_offset), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
mandelbrot_bordertrace(columnbuffer, colorscheme, cam, (struct window){left_line + (FB_SIZE_X - x_offset), 0, x_offset, FB_SIZE_Y});
for(uint16_t y = 0; y < FB_SIZE_Y; y++) {
memmove(framebuffer + (FB_SIZE_X * y), framebuffer + (FB_SIZE_X * y) + x_offset, (FB_SIZE_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (FB_SIZE_X * y) + (FB_SIZE_X - x_offset), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_LEFT:
cam_shift(&cam, -STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, 0, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y) + x_offset, framebuffer + (RES_X * y), (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
mandelbrot_bordertrace(columnbuffer, colorscheme, cam, (struct window){left_line, 0, x_offset, FB_SIZE_Y});
for(uint16_t y = 0; y < FB_SIZE_Y; y++) {
memmove(framebuffer + (FB_SIZE_X * y) + x_offset, framebuffer + (FB_SIZE_X * y), (FB_SIZE_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (FB_SIZE_X * y), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_A:
cam_zoom(&cam, ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
mandelbrot_bordertrace(framebuffer, colorscheme, cam, (struct window){left_line, 0, FB_SIZE_X, FB_SIZE_Y});
break;
case BUTTON_B:
cam_zoom(&cam, -ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
mandelbrot_bordertrace(framebuffer, colorscheme, cam, (struct window){left_line, 0, FB_SIZE_X, FB_SIZE_Y});
break;
default:
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
mandelbrot_bordertrace(framebuffer, colorscheme, cam, (struct window){left_line, 0, FB_SIZE_X, FB_SIZE_Y});
}
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
ST7735_DrawImage(left_line, 0, FB_SIZE_X, FB_SIZE_Y, framebuffer);
bottom_buffered = !bottom_buffered;
top_line = bottom_buffered ? (RES_Y/2) : 0;
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
left_line = left_line ? 0 : FB_SIZE_X;
mandelbrot_bordertrace(framebuffer, colorscheme, cam, (struct window){left_line, 0, FB_SIZE_X, FB_SIZE_Y});
ST7735_DrawImage(left_line, 0, FB_SIZE_X, FB_SIZE_Y, framebuffer);
idle();
}
benchmark_stop();
/**
render_mandelbrot(framebuffer, colorscheme, cam, false, key_pressed);
ST7735_DrawImage(0, 0, ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, true, key_pressed);
ST7735_DrawImage(0, (ST7735_HEIGHT / 2), ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
**/
// ST7735_DrawImage(0, 0, ST7735_WIDTH - 1, ST7735_HEIGHT - 1, (uint16_t *)0x80000000);
}

View File

@ -7,6 +7,7 @@
#include "malloc.h"
#include "stm32f1xx_hal_spi.h"
#include "string.h"
#include "gpio.h"
#define DELAY 0x80
@ -314,6 +315,7 @@ void ST7735_sleep() {
ST7735_Select();
ST7735_WriteCommand(ST7735_SLPIN);
ST7735_Unselect();
HAL_GPIO_WritePin(BACKLIGHT_PORT, BACKLIGHT_PIN, GPIO_PIN_RESET);
HAL_Delay(200);
}
@ -322,5 +324,6 @@ void ST7735_wake() {
ST7735_Select();
ST7735_WriteCommand(ST7735_SLPOUT);
ST7735_Unselect();
HAL_GPIO_WritePin(BACKLIGHT_PORT, BACKLIGHT_PIN, GPIO_PIN_SET);
HAL_Delay(200);
}

View File

@ -84,6 +84,7 @@ void NMI_Handler(void)
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
__BKPT();
/* USER CODE END HardFault_IRQn 0 */
while (1)
@ -276,6 +277,7 @@ void EXTI15_10_IRQHandler(void)
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */

View File

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Tue May 13 23:21:12 CDT 2025]
# File automatically-generated by tool: [projectgenerator] version: [4.5.0-RC5] date: [Wed Sep 03 06:02:40 CDT 2025]
##########################################################################################################################
# ------------------------------------------------
@ -20,7 +20,7 @@ TARGET = stm32f1_buisnesscard_v1
# building variables
######################################
# debug build?
DEBUG = 1
DEBUG = 0
# optimization
OPT = -Ofast
@ -46,6 +46,8 @@ Core/Src/st7735.c \
Core/Src/fonts.c \
Core/Src/mandelbrot.c \
Core/Src/stm32f1xx_hal_msp.c \
Core/Src/gpio.c \
Core/Src/idle.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \

View File

@ -0,0 +1,604 @@
/** READ BEFORE JUDING!
* Yes, I know this code is a mess. Debug code is added
* happhazardly, two cameras are used, etc.
* That's because it's a temporary program
* to create optimizations and debug rendering issues without hardware.
* None of this is going to be included in the project, and the code is thus
* not extensible or organized; it really doesn't save any effort to do so.
*
* This code is meant for my eyes only. You've been warned!
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <raylib.h>
#include <raymath.h>
#include <limits.h>
#include <complex.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define WINDOW_SIZE_X 1600
#define WINDOW_SIZE_Y 800
#define RES_X 160
#define RES_Y 80
#define DEFAULT_CENTER_X 0
#define DEFAULT_CENTER_Y 0
#define MOUSE_BUTTON 0
#define STEP_SIZE .1
#define ZOOM_SIZE .1
#define DECIMAL_LOC 28
#define DOUBLE_SCALER (1 << DECIMAL_LOC)
#define DOUBLE_TO_FIXED(val) (int32_t)((val) * DOUBLE_SCALER)
#define FIXED_MULTIPLY(x,y) ((((uint64_t)(x))*(y)) >> DECIMAL_LOC)
#define FIXED_TO_DOUBLE(val) ((val) / (double)DOUBLE_SCALER)
#define INFTY 2
#define INFTY_SQR INFTY * INFTY
#define ITERS 255
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//#define SHIP
//#undef SHIP
//#define COLOR_DEBUG
//#define SHIP
Color get_color_dbg(int i) {
if(i == ITERS) return (Color){0,0,255,255};
// if(i == 0) return (Color){255,255,255,255};
return (Color){255,0,255,255};
}
#ifdef COLOR_DEBUG
Color get_color(int i) {
if(i == ITERS) return (Color){0, 0, 0, 255};
if(i == 0) return (Color){0, 0, 0, 255};
return (Color) {
2*(i - 128)+255,
0,
0,
255
};
}
#else
Color get_color(int i) {
// if((i == ITERS) || (i == 0)) return (Color){0, 0, 0, 255};
if(i == ITERS) return (Color){0,0,0,255};
if(i == 0) return (Color){0,0,1,255};
if(i < 128) {
return (Color) {
(8*(i - 128)+255) & 0xff,
0,
(16*(i - 64)+255) & 0xff,
255
};
}
return (Color) {
0,
0,
((unsigned int)-2*(i - 128)+255) & 0xff,
255
};
}
#endif
//C does remainder, not modulo.
//TODO optimize for mod 8. Benchmark
inline int mod(int n, int d) {
int r = n % d;
return (r < 0) ? r + d : r;
}
int mod(int n, int d);
struct camera {
double min_r, min_i, max_r, max_i;
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
static inline int iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
for(int it = 0; it < ITERS; it++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + c.r;
#ifdef SHIP
zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#else
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#endif
z_i = zn_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) return it;
}
return ITERS;
}
//blllluuuuurg, matracies and vectors in raylib are floats and we need doubles
void shift_cam(struct camera *cam, double step_r, double step_i) {
double i_offset = (cam->max_i - cam->min_i) * step_i;
double r_offset = (cam->max_r - cam->min_r) * step_r;
cam->min_i += i_offset;
cam->max_i += i_offset;
cam->min_r += r_offset;
cam->max_r += r_offset;
}
void zoom_cam(struct camera *cam, double zoom) {
double i_scale = (cam->max_i - cam->min_i) * zoom;
double r_scale = (cam->max_r - cam->min_r) * zoom;
cam->min_i += i_scale;
cam->max_i -= i_scale;
cam->min_r += r_scale;
cam->max_r -= r_scale;
}
enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
inline FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i;
if((direction > N) && (direction < S)) from_coord.r += step.r;
if((direction > E) && (direction < W)) from_coord.i -= step.i;
if(direction > S) from_coord.r -= step.r;
return from_coord;
}
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction) {
const int neighbor_index_accl[8] =
{-RES_X, -RES_X + 1, 1, RES_X + 1, RES_X, RES_X - 1, -1, -RES_X - 1};
from_pixel += neighbor_index_accl[direction];
//canidate for optimization; lots of branches. maybe inline
return from_pixel;
}
//we'll be storing info in the green channel to utalize available memory
//per pixel.
#define BACKSTACK_SIZE 32
#define GCHAN_UNRENDERED 0 //don't change; green channel zero'd on cam move
#define GCHAN_BLOCKED (1 << 7) //interior element or visiteed
#define GCHAN_INTERNAL (1 << 5) //part of set, 0x20
#define GCHAN_EXTERNAL (1 << 0) //not part of set, 0x10
#define GCHAN_INNER_VISITED (1 << 3)
#define GCHAN_INNER_CLOSED (1 << 2)
/**
void switch_pixel(coord &this_coord, const coord step, size_t this_index, int dir) {
}
**/
void debug_step(Color *pix, Texture *tex, size_t index, bool pause) {
return;
// SetTargetFPS(0);
static bool fuckin_manual_pause_iguess = false;
static Camera2D cam = {0};
if(!cam.zoom) cam.zoom = (float)GetRenderWidth()/RES_X;
static int debug_color = 0;
const float dbg_cam_step = 100;
const float dbg_cam_zoom = 1.5;
(pause || fuckin_manual_pause_iguess) ? SetTargetFPS(60) : SetTargetFPS(0);
for(;;) {
switch(GetKeyPressed()) {
case KEY_UP:
cam.offset.y += dbg_cam_step;
break;
case KEY_DOWN:
cam.offset.y -= dbg_cam_step;
break;
case KEY_RIGHT:
cam.offset.x += dbg_cam_step;
break;
case KEY_LEFT:
cam.offset.x -= dbg_cam_step;
break;
case KEY_W:
cam.zoom *= dbg_cam_zoom;
break;
case KEY_S:
cam.zoom /= dbg_cam_zoom;
break;
case KEY_SPACE:
Vector2 mouse_pos =
Vector2Multiply(GetMousePosition(), (Vector2){(double)RES_X / WINDOW_SIZE_X, (double)RES_Y / WINDOW_SIZE_Y});
//mouse_pos = Vector2Divide(mouse_pos, (Vector2){cam.zoom, cam.zoom});
printf("%f, %f (%lu)\n", mouse_pos.x, mouse_pos.y, ((size_t)mouse_pos.y * RES_X) + (size_t)mouse_pos.x);
break;
case KEY_ENTER:
return;
default:
BeginDrawing();
pix[index] =
(Color) {debug_color, pix[index].g, 0, 255};
BeginDrawing();
UpdateTexture(*tex, pix);
DrawTextureEx(*tex, (Vector2)
{0 - cam.offset.x, cam.offset.y}, 0,
cam.zoom, WHITE);
EndDrawing();
if(!pause && !fuckin_manual_pause_iguess) return;
}
}
}
//only need four indecies, however we use 8 because it's more convinient.
void detect_borders(bool borders[8], size_t i) {
//if this is too slow, it's easy to do it without the modulos.
int index_mod = i % RES_X;
bzero(borders, sizeof(*borders) * 8);
if((i + RES_X) > (RES_X * RES_Y)) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(((int)i - RES_X) < 0) {
borders[NE] = GCHAN_EXTERNAL;
borders[N] = GCHAN_EXTERNAL;
borders[NW] = GCHAN_EXTERNAL;
}
if(index_mod == 0) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(index_mod == (RES_X - 1)) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
}
void debug_nei_arrays(int *priority, int *presort, size_t index) {
int debug_x = index % RES_X;
int debug_y = index / RES_X;
printf("(%i, %i) %lu: pre [", debug_x, debug_y, index);
for(int nd = 0; nd < 8; nd++) printf("%i, ", presort[nd]);
printf("], pri [");
for(int nd = 0; nd < 8; nd++) printf("%i, ", priority[nd]);
printf("]\n");
}
enum {
SCAN_MODE_NONE,
SCAN_MODE_SAFE,
SCAN_MODE_INTERIOR
} scan_mode;
unsigned int mandelbrot_bordertrace(struct camera *cam, Color *pixels) {
//these lookup tables r cheap cuz on the stm32f1, 1 memory read is 1 instruction
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = {.r = 0, .i = DOUBLE_TO_FIXED(cam->max_i)};
unsigned int total_iters = 0;
size_t on_pixel = 0;
int border_scanning = 0;
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture debug_tex = LoadTextureFromImage(img);
UnloadImage(img);
// bzero(pixels, RES_X * RES_Y * sizeof(Color));
// for(size_t c = 0; c < (RES_X * RES_Y); c++) pixels[c] = (Color){0,0,0,255};
for(int y = 0; y < RES_Y; y++) {
border_scanning = 0;
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
//c.r = DOUBLE_TO_FIXED((((on_pixel % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
//c.i = DOUBLE_TO_FIXED((((on_pixel / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
switch(pixels[on_pixel].g) {
case GCHAN_UNRENDERED:
if(border_scanning) {
//pixels[on_pixel] = get_color(ITERS);
//printf("interior\n");
pixels[on_pixel] = (Color){0xfe,0,0xfe,0xff};
break;
}
//printf("rendering %i, %i (%lu)\n", x, y, on_pixel);
int i = iterate(c);
total_iters += i;
pixels[on_pixel] = get_color(i);
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
bool seperated_from_start = false;
bool nei_canidate[8];
int last_nei_canidate[8];
int nei_presort[8];
size_t backstack[BACKSTACK_SIZE];
size_t backstack_i = 0;
int backstack_calls = 0;
int nei_dir;
debug_step(pixels, &debug_tex, this_index, false);
bool debug_mode = false;
bool borders[8];
detect_borders(borders, on_pixel);
for(nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
if(borders[nei_dir]) break;
nei_i = get_neighbor_index(on_pixel, nei_dir);
if(pixels[nei_i].g & GCHAN_EXTERNAL) break;
}
if(nei_dir >= 8) {
border_scanning = SCAN_MODE_INTERIOR;
break;
}
while(true) {
detect_borders(borders, this_index);
debug_step(pixels, &debug_tex, this_index, false);
if(debug_mode) debug_step(pixels, &debug_tex, on_pixel, debug_mode);
//step 1: check pixels around us, fill in neighbors.
bzero(nei_presort, sizeof(nei_presort));
this_coord.r = DOUBLE_TO_FIXED((((this_index % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
this_coord.i = DOUBLE_TO_FIXED((((this_index / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
bool start_is_nei = false;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(borders[nei_dir]) {
nei_presort[nei_dir] = GCHAN_EXTERNAL;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir);
gchan_info = pixels[nei_i].g;
if(nei_i == on_pixel) start_is_nei = true;
//note that when we move this over, there will be no alpha channel.
//gchan_info will be extracted differently!!!
if(gchan_info) nei_presort[nei_dir] = gchan_info;
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
pixels[nei_i] = get_color(i);
nei_presort[nei_dir] = (i >= ITERS) ? GCHAN_INTERNAL : GCHAN_EXTERNAL;
pixels[nei_i].g = nei_presort[nei_dir];
}
}
if(!start_is_nei && !seperated_from_start && (this_index != on_pixel)) seperated_from_start = true;
if(start_is_nei && seperated_from_start) {
pixels[this_index].g = GCHAN_BLOCKED;
break;
}
int edge_cnt = 0;
//see what neighbors are good canidates for the next pixel in our path
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
int nei_edge_i;
if(nei_presort[nei_dir] != GCHAN_INTERNAL) {
continue;
}
for(nei_edge_i = -2; nei_edge_i <= 2; nei_edge_i++) {
int nei_edge_mod = mod((nei_dir + nei_edge_i), 8);
if((nei_presort[nei_edge_mod] == GCHAN_EXTERNAL) || borders[nei_edge_mod]) break;
}
//no edge found
if(nei_edge_i > 2) continue;
//narrow bridge scenario
if(nei_presort[mod((nei_dir + 1), 8)] & nei_presort[mod((nei_dir - 1), 8)] & GCHAN_EXTERNAL)
continue;
edge_cnt++;
nei_canidate[nei_dir] = true;
}
if(edge_cnt >= 2) backstack[backstack_i++ % BACKSTACK_SIZE] = this_index;
//now go to canidate with lowest prioraty
pixels[this_index].g = GCHAN_BLOCKED;
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
if(!nei_canidate[nei_dir]) continue;
backstack_calls = 0;
this_index = get_neighbor_index(this_index, nei_dir);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
goto NEXT_PIXEL;
}
if((backstack_calls++ > BACKSTACK_SIZE) || (backstack_i < 1)) break;
this_index = backstack[--backstack_i % BACKSTACK_SIZE];
NEXT_PIXEL:
for(int i = 0; i < 8; i++) nei_canidate[i] = false;
}
debug_step(pixels, &debug_tex, this_index, true);
}
else pixels[on_pixel].g = GCHAN_EXTERNAL;
break;
/**
case GCHAN_INNER_CLOSED:
if(((x + 2) < RES_X) && (pixels[on_pixel + 1].g == GCHAN_UNRENDERED)) border_scanning = SCAN_MODE_NONE;
break;
**/
default:
border_scanning = SCAN_MODE_NONE;
}
on_pixel++;
c.r += scale.r;
}
c.i += scale.i;
border_scanning = false;
}
debug_step(pixels, &debug_tex, 0, true);
for(size_t i = 0; i < (RES_X * RES_Y); i++) pixels[i].g = 0;
return total_iters;
}
unsigned int mandelbrot_unoptimized(struct camera *cam, Color *pixels) {
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = { .r = DOUBLE_TO_FIXED(cam->min_r), .i = DOUBLE_TO_FIXED(cam->max_i) };
unsigned int total_iters = 0;
size_t on_pixel = 0;
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
//c.r = DOUBLE_TO_FIXED((((on_pixel % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
//c.i = DOUBLE_TO_FIXED((((on_pixel / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
total_iters += i;
pixels[((y * RES_X) + x)] = get_color(i);
on_pixel++;
c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
int main() {
//test();
//return 0;
Color *pixels_unoptimized = malloc(RES_X * RES_Y * sizeof(Color));
Color *pixels_optimized = malloc(RES_X * RES_Y * sizeof(Color));
bool optimized = false;
//(1.514379082621093886019, 0.000033222739567139065) - (1.514381385800912305228, 0.000034374329476534746)
struct camera cam_default = {
.min_r = -1,
.max_r = 1
};
cam_default.min_i = ((double)RES_Y / RES_X) * cam_default.min_r;
cam_default.max_i = ((double)RES_Y / RES_X) * cam_default.max_r;
//done
//.min_r = 0.340060821337554164412, .min_i = -0.076399869494282027227, .max_r = 0.340671385211165078655, .max_i = -0.076094587557451340287
//done
//.min_r = 0.348347456407892719366, .min_i = -0.092130353675640097588, .max_r = 0.349033773135021985201, .max_i = -0.091787195312047098472
//has internal noise
//.min_r = 0.348416088080605645949, .min_i = -0.092130353675640097588, .max_r = 0.349102404807734911785, .max_i = -0.091787195312047098472
//needs diagnol transfer
//.min_r = 0.352126044212195454808, .min_i = -0.101818891004586714599, .max_r = 0.354169737175103083171, .max_i = -0.100797044523048578979
//works
//.min_r = 1.514379082621093886019, .min_i = 0.000033222739567139065, .max_r = 1.514381385800912305228, .max_i = 0.000034374329476534746
// unusual issue; complete rendered border
// .min_r = 0.426539347230382670517, .min_i = 0.218210183100018217939, .max_r = 0.427445609943903681582, .max_i = 0.218663314456816582076
struct camera cam = {
//.min_r = 0.348416088080605645949, .min_i = -0.092130353675640097588, .max_r = 0.349102404807734911785, .max_i = -0.091787195312047098472
.min_r = 0.348347456407892719366, .min_i = -0.092130353675640097588, .max_r = 0.349033773135021985201, .max_i = -0.091787195312047098472
};
InitWindow(WINDOW_SIZE_X, WINDOW_SIZE_Y, "mandelbrot fixed point test");
SetTraceLogLevel(LOG_ERROR);
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture tex = LoadTextureFromImage(img);
UnloadImage(img);
SetTargetFPS(60);
while(!WindowShouldClose()) {
switch(GetKeyPressed()) {
case KEY_UP:
shift_cam(&cam, 0, STEP_SIZE);
break;
case KEY_DOWN:
shift_cam(&cam, 0, -STEP_SIZE);
break;
case KEY_RIGHT:
shift_cam(&cam, STEP_SIZE, 0);
break;
case KEY_LEFT:
shift_cam(&cam, -STEP_SIZE, 0);
break;
case KEY_W:
zoom_cam(&cam, ZOOM_SIZE);
break;
case KEY_S:
zoom_cam(&cam, -ZOOM_SIZE);
break;
case KEY_SPACE:
optimized = !optimized;
break;
default:
BeginDrawing();
EndDrawing();
continue;
break;
}
printf(".min_r = %.21f, .min_i = %.21f, .max_r = %.21f, .max_i = %.21f\n", cam.min_r, cam.min_i, cam.max_r, cam.max_i);
clock_t begin, end;
double time_unoptimized;
double time_optimized;
for(int i = 0; i < (RES_X * RES_Y); i++) { pixels_unoptimized[i] = (Color){0, 0, 0, 0xff}; }
for(int i = 0; i < (RES_X * RES_Y); i++) { pixels_optimized[i] = (Color){0, 0, 0, 0xff}; }
begin = clock();
unsigned int unoptimized_iters = mandelbrot_unoptimized(&cam, pixels_unoptimized);
end = clock();
time_unoptimized = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Unoptimized: %u iterations, %f seconds\n", unoptimized_iters, time_unoptimized);
begin = clock();
unsigned int optimized_iters = mandelbrot_bordertrace(&cam, pixels_optimized);
end = clock();
time_optimized = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Border tracing: %u iterations, %f seconds\n", optimized_iters, time_optimized);
printf("border tracing does %f%% of nieve approach\n", ((float)optimized_iters / unoptimized_iters) * 100);
BeginDrawing();
printf("%s\n", optimized ? "optimized mode" : "unoptimized mode");
UpdateTexture(tex, optimized ? pixels_optimized : pixels_unoptimized);
DrawTextureEx(tex, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
}
return 0;
}

View File

@ -24,11 +24,13 @@
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//TODO move to some hardware.h or somethin
//channel order: B, G, R
#define R_BITS 5
#define G_BITS 6
//channel order: G, R, B
#define R_BITS 6
#define G_BITS 5
#define B_BITS 5
#define G_MASK 0xe007u //little endian
//imaginary axis set automatically
#define CAM_DEF_MIN_R -1
#define CAM_DEF_MAX_R 1
@ -41,10 +43,84 @@
#define CAM_ZOOM_IN BUTTON_A
#define CAM_ZOOM_OUT BUTTON_B
#define BACKSTACK_SIZE 32
#define GCHAN_UNRENDERED 0 //don't change; green channel zero'd on cam move
#define GCHAN_BLOCKED (1 << 0) //interior element or visiteed
#define GCHAN_INTERNAL (1 << 1) //part of set, 0x20
#define GCHAN_EXTERNAL (1 << 2) //not part of set, 0x10
enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
enum { //TODO remove
SCAN_MODE_NONE,
SCAN_MODE_SAFE,
SCAN_MODE_INTERIOR
} scan_mode;
struct camera {
double min_r, min_i, max_r, max_i;
};
struct window {
unsigned int x0, y0, xn, yn;
};
//C does remainder, not modulo.
//TODO optimize for mod 8. Benchmark
inline int mod(int n, int d) {
int r = n % d;
return (r < 0) ? r + d : r;
}
int mod(int n, int d);
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i; //up
if((direction > N) && (direction < S)) from_coord.r += step.r; //right
if((direction > E) && (direction < W)) from_coord.i -= step.i; //down
if(direction > S) from_coord.r -= step.r; //left
return from_coord;
}
//FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction) {
const int neighbor_index_accl[8] =
{-RES_X, -RES_X + 1, 1, RES_X + 1, RES_X, RES_X - 1, -1, -RES_X - 1};
from_pixel += neighbor_index_accl[direction];
return from_pixel;
}
void detect_borders(bool borders[8], size_t i) {
//if this is too slow, it's easy to do it without the modulos.
int index_mod = i % RES_X;
bzero(borders, sizeof(*borders) * 8);
if((i + RES_X) > (RES_X * RES_Y)) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(((int)i - RES_X) < 0) {
borders[NE] = GCHAN_EXTERNAL;
borders[N] = GCHAN_EXTERNAL;
borders[NW] = GCHAN_EXTERNAL;
}
if(index_mod == 0) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(index_mod == (RES_X - 1)) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
}
enum VIEW_MODES { VIEW_UNINIT, VIEW_MANDREL, VIEW_SHIP };
void init_colorscheme_mandrel(uint16_t *scheme) {
@ -85,10 +161,184 @@ void cam_zoom(struct camera *cam, double zoom) {
cam->max_r -= r_scale;
}
inline int __attribute__((inline)) iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
for(int it = 0; it < ITERS; it++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + c.r;
//zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
z_i = zn_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) return it;
}
return ITERS;
}
unsigned int mandelbrot_bordertrace(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, struct window win) {
unsigned int total_iters = 0;
size_t on_pixel = 0;
int border_scanning = 0;
//these lookup tables r cheap cuz on the stm32f1, 1 memory read is 1 instruction
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X), .i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y)
};
FixedCord c = {
.i = DOUBLE_TO_FIXED((((cam.max_i - cam.min_i) * (RES_Y - win.y0)) / RES_Y) + cam.min_i),
.r = DOUBLE_TO_FIXED((((cam.max_r - cam.min_r) * win.x0) / RES_X) + cam.min_r)
};
uint64_t r0 = c.r;
for(int y = win.y0; y < win.yn; y++) {
border_scanning = 0;
c.r = r0;
for(int x = win.x0; x < win.xn; x++) {
switch(framebuffer[on_pixel] & G_MASK) {
case GCHAN_UNRENDERED:
if(border_scanning) {
framebuffer[on_pixel] = colorscheme[ITERS];
break;
}
int i = iterate(c);
total_iters += i;
framebuffer[on_pixel] = colorscheme[i];
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
bool seperated_from_start = false;
bool nei_canidate[8];
int nei_presort[8];
size_t backstack[BACKSTACK_SIZE];
size_t backstack_i = 0;
int backstack_calls = 0;
int nei_dir;
bool borders[8];
detect_borders(borders, on_pixel);
for(nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
if(borders[nei_dir]) break;
nei_i = get_neighbor_index(on_pixel, nei_dir);
if(framebuffer[nei_i] & GCHAN_EXTERNAL) break;
}
if(nei_dir >= 8) {
border_scanning = SCAN_MODE_INTERIOR;
break;
}
while(true) {
detect_borders(borders, this_index);
//step 1: check pixels around us, fill in neighbors.
bzero(nei_presort, sizeof(nei_presort));
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
bool start_is_nei = false;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(borders[nei_dir]) {
nei_presort[nei_dir] = GCHAN_EXTERNAL;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir);
gchan_info = framebuffer[nei_i] & G_MASK;
if(nei_i == on_pixel) start_is_nei = true;
if(gchan_info) nei_presort[nei_dir] = gchan_info;
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
framebuffer[nei_i] = colorscheme[i];
nei_presort[nei_dir] =
(i >= ITERS) ? GCHAN_INTERNAL : GCHAN_EXTERNAL;
framebuffer[nei_i] |= nei_presort[nei_dir];
}
}
if(!start_is_nei && !seperated_from_start && (this_index != on_pixel)) seperated_from_start = true;
if(start_is_nei && seperated_from_start) {
framebuffer[this_index] |= GCHAN_BLOCKED;
break;
}
int edge_cnt = 0;
//see what neighbors are good canidates for the next pixel in our path
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
int nei_edge_i;
if(nei_presort[nei_dir] != GCHAN_INTERNAL) {
continue;
}
for(nei_edge_i = -2; nei_edge_i <= 2; nei_edge_i++) {
int nei_edge_mod = mod((nei_dir + nei_edge_i), 8);
if((nei_presort[nei_edge_mod] == GCHAN_EXTERNAL) || borders[nei_edge_mod]) break;
}
//no edge found
if(nei_edge_i > 2) continue;
//narrow bridge scenario
if(nei_presort[mod((nei_dir + 1), 8)] & nei_presort[mod((nei_dir - 1), 8)] & GCHAN_EXTERNAL)
continue;
edge_cnt++;
nei_canidate[nei_dir] = true;
}
if(edge_cnt >= 2) backstack[backstack_i++ % BACKSTACK_SIZE] = this_index;
//now go to canidate with lowest prioraty
framebuffer[this_index] |= GCHAN_BLOCKED;
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
if(!nei_canidate[nei_dir]) continue;
backstack_calls = 0;
this_index = get_neighbor_index(this_index, nei_dir);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
goto NEXT_PIXEL;
}
if((backstack_calls++ > BACKSTACK_SIZE) || (backstack_i < 1)) break;
this_index = backstack[--backstack_i % BACKSTACK_SIZE];
c.r = DOUBLE_TO_FIXED((((on_pixel % RES_X) / (double)RES_X) * (cam.max_r - cam.min_r)) + cam.min_r);
c.i = DOUBLE_TO_FIXED((((on_pixel / (double)RES_X) / (double)RES_Y) * (cam.min_i - cam.max_i)) + cam.max_i);
NEXT_PIXEL: //TODO improve flow
for(int i = 0; i < 8; i++) nei_canidate[i] = false;
}
}
else framebuffer[on_pixel] |= GCHAN_EXTERNAL;
break;
default:
border_scanning = SCAN_MODE_NONE;
}
on_pixel++;
c.r += scale.r;
}
border_scanning = false;
c.i -= scale.i;
}
for(size_t i = 0; i < (RES_X * RES_Y); i++) framebuffer[i] &= ~G_MASK;
return total_iters;
}
//TODO look into border tracing; this is too slow. Change name
//
void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, int x0, int y0, int w, int h) {
unsigned int render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, int x0, int y0, int w, int h) {
int32_t scale_i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y);
int32_t scale_r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X);
int32_t c_i = DOUBLE_TO_FIXED((((cam.max_i - cam.min_i) * (RES_Y - y0)) / RES_Y) + cam.min_i);
@ -96,8 +346,7 @@ void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct came
int32_t c_r, z_i, z_r, zn_r, z_r_2, z_i_2;
size_t fb_index = 0;
int i;
//for(;;);
unsigned int total_iters = 0;
for(int y = y0; y < y0 + h; y++) {
c_r = c_r0;
@ -110,127 +359,107 @@ void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct came
zn_r = z_r_2 - z_i_2 + c_r;
//z_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c_i;
z_i = (FIXED_MULTIPLY(z_r, z_i) << 1) + c_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) break;
}
total_iters += i;
framebuffer[fb_index++] = colorscheme[i];
c_r += scale_r;
}
c_i -= scale_i;
}
return total_iters;
}
#define FB_SIZE_X RES_X
#define FB_SIZE_Y RES_Y/2
#define FB_SIZE_X RES_X/2
#define FB_SIZE_Y RES_Y
//TODO rename
void draw_mandelbrot(int key_pressed) {
static uint16_t framebuffer[FB_SIZE_X * FB_SIZE_Y];
uint16_t columnbuffer[8*RES_Y];
static bool bottom_buffered = true;
uint16_t columnbuffer[(size_t)(STEP_SIZE * RES_X * RES_Y)];
static bool left_buffered = true;
//program flow is awful atm becuase I was planning something different; will be improved soon.
static struct camera cam = {
.min_r = CAM_DEF_MIN_R,
.max_r = CAM_DEF_MAX_R,
.min_i = ((double)RES_Y / RES_X) * CAM_DEF_MIN_R,
.max_i = ((double)RES_Y / RES_X) * CAM_DEF_MAX_R,
};
static int view_mode = VIEW_UNINIT;
static uint16_t colorscheme[ITERS];
//we could get rid of this and do some awful bitbashing lol
//but for readability, we shant
//TODO camera moves l/r more then u/d for some reason
/**
if(key_pressed & CAM_MOVE_UP) cam_shift(&cam, 0, STEP_SIZE);
if(key_pressed & CAM_MOVE_DOWN) cam_shift(&cam, 0, -STEP_SIZE);
if(key_pressed & CAM_MOVE_RIGHT) cam_shift(&cam, -STEP_SIZE, 0);
if(key_pressed & CAM_MOVE_LEFT) cam_shift(&cam, STEP_SIZE, 0);
if(key_pressed & CAM_ZOOM_IN) cam_zoom(&cam, ZOOM_SIZE);
if(key_pressed & CAM_ZOOM_OUT) cam_zoom(&cam, -ZOOM_SIZE);
**/
//yes, I know the following is disgusting. Before I clean it, I just wanna get the general idea out,
//it's more efficient in that order
//TODO once you get your idea ironed out, clean the code and improve the flow
benchmark_start();
if(view_mode == VIEW_UNINIT) {
//TODO
view_mode = VIEW_MANDREL;
init_colorscheme_mandrel(colorscheme);
render_mandelbrot(framebuffer, colorscheme, cam, 0, 0, RES_X, RES_Y/2);
ST7735_DrawImage(0, 0, RES_X, (RES_Y / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, 0, RES_Y/2, RES_X, RES_Y/2);
ST7735_DrawImage(0, (RES_Y / 2), RES_X, (RES_Y / 2), framebuffer);
bottom_buffered = true;
render_mandelbrot(framebuffer, colorscheme, cam, 0, 0, FB_SIZE_X, RES_Y);
ST7735_DrawImage(0, 0, FB_SIZE_X, RES_Y, framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, FB_SIZE_X, 0, FB_SIZE_X, RES_Y);
ST7735_DrawImage(FB_SIZE_X, 0, FB_SIZE_X, RES_Y, framebuffer);
left_buffered = true;
}
else {
const int y_offset = STEP_SIZE * RES_Y;
const int x_offset = STEP_SIZE * RES_X;
const size_t bottom_space = RES_X * ((RES_Y/2) - y_offset) * sizeof(uint16_t);
uint16_t top_line = bottom_buffered ? (RES_Y/2) : 0;
// const size_t top_space = RES_X * ((RES_Y/2) - y_offset) * sizeof(uint16_t);
const size_t top_space = (RES_X / 2) * (RES_Y - y_offset) * sizeof(uint16_t);
uint16_t left_line = left_buffered ? (RES_X/2) : 0;
switch(key_pressed) {
case BUTTON_UP:
cam_shift(&cam, 0, STEP_SIZE);
memmove(framebuffer + (RES_X * y_offset), framebuffer, bottom_space);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, y_offset);
memmove(framebuffer + (FB_SIZE_X * y_offset), framebuffer, top_space);
render_mandelbrot(framebuffer, colorscheme, cam, left_line, 0, FB_SIZE_X, y_offset);
break;
case BUTTON_DOWN:
uint16_t bottom_line = (bottom_buffered ? RES_Y : (RES_Y/2)) - y_offset;
cam_shift(&cam, 0, -STEP_SIZE);
memmove(framebuffer, framebuffer + (RES_X * y_offset), bottom_space);
render_mandelbrot(framebuffer + (RES_X*((RES_Y/2)-y_offset)), colorscheme, cam, 0, bottom_line, RES_X, y_offset);
memmove(framebuffer, framebuffer + (FB_SIZE_X * y_offset), top_space);
render_mandelbrot(framebuffer + (FB_SIZE_X * (RES_Y - y_offset)), colorscheme, cam, left_line, (RES_Y - y_offset), FB_SIZE_X, y_offset);
break;
case BUTTON_RIGHT:
cam_shift(&cam, STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, RES_X - x_offset, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y), framebuffer + (RES_X * y) + x_offset, (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y) + (RES_X - x_offset), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
render_mandelbrot(columnbuffer, colorscheme, cam, left_line + (FB_SIZE_X - x_offset), 0, x_offset, RES_Y);
for(uint16_t y = 0; y < RES_Y; y++) {
memmove(framebuffer + (FB_SIZE_X * y), framebuffer + (FB_SIZE_X * y) + x_offset, (FB_SIZE_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (FB_SIZE_X * y) + (FB_SIZE_X - x_offset), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_LEFT:
cam_shift(&cam, -STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, 0, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y) + x_offset, framebuffer + (RES_X * y), (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
render_mandelbrot(columnbuffer, colorscheme, cam, left_line, 0, x_offset, RES_Y);
for(uint16_t y = 0; y < RES_Y; y++) {
memmove(framebuffer + (FB_SIZE_X * y) + x_offset, framebuffer + (FB_SIZE_X * y), (FB_SIZE_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (FB_SIZE_X * y), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_A:
cam_zoom(&cam, ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
render_mandelbrot(framebuffer, colorscheme, cam, left_line, 0, FB_SIZE_X, RES_Y);
break;
case BUTTON_B:
cam_zoom(&cam, -ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
render_mandelbrot(framebuffer, colorscheme, cam, left_line, 0, FB_SIZE_X, RES_Y);
break;
default:
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
render_mandelbrot(framebuffer, colorscheme, cam, left_line, 0, FB_SIZE_X, RES_Y);
}
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
ST7735_DrawImage(left_line, 0, FB_SIZE_X, RES_Y, framebuffer);
bottom_buffered = !bottom_buffered;
top_line = bottom_buffered ? (RES_Y/2) : 0;
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
left_buffered = !left_buffered;
left_line = left_buffered ? FB_SIZE_X : 0;
render_mandelbrot(framebuffer, colorscheme, cam, left_line, 0, FB_SIZE_X, RES_Y);
ST7735_DrawImage(left_line, 0, FB_SIZE_X, RES_Y, framebuffer);
}
benchmark_stop();
/**
render_mandelbrot(framebuffer, colorscheme, cam, false, key_pressed);
ST7735_DrawImage(0, 0, ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, true, key_pressed);
ST7735_DrawImage(0, (ST7735_HEIGHT / 2), ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
**/
// ST7735_DrawImage(0, 0, ST7735_WIDTH - 1, ST7735_HEIGHT - 1, (uint16_t *)0x80000000);
}

View File

@ -17,8 +17,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/main.d",
@ -48,8 +46,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_it.d",
@ -79,8 +75,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_msp.d",
@ -110,8 +104,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_gpio_ex.d",
@ -141,8 +133,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_spi.d",
@ -172,8 +162,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal.d",
@ -203,8 +191,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_rcc.d",
@ -234,8 +220,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_rcc_ex.d",
@ -265,8 +249,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_gpio.d",
@ -296,8 +278,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_dma.d",
@ -327,8 +307,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_cortex.d",
@ -358,8 +336,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_pwr.d",
@ -389,8 +365,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_flash.d",
@ -420,8 +394,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_flash_ex.d",
@ -451,8 +423,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_exti.d",
@ -482,8 +452,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/system_stm32f1xx.d",
@ -513,8 +481,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/sysmem.d",
@ -544,8 +510,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/syscalls.d",
@ -575,8 +539,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/st7735.d",
@ -606,8 +568,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/fonts.d",
@ -637,8 +597,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_tim.d",
@ -668,8 +626,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/stm32f1xx_hal_tim_ex.d",
@ -699,8 +655,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/mandelbrot.d",
@ -732,8 +686,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/startup_stm32f103xb.d",
@ -762,8 +714,6 @@
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-ggdb",
"-g3",
"-MMD",
"-MP",
"-MFbuild/benchmark.d",
@ -774,5 +724,63 @@
"build/benchmark.o"
],
"file": "Core/Src/benchmark.c"
},
{
"directory": "/home/indigo/projects/stm32_buisnesscard/program/stm32f1_buisnesscard_v1",
"arguments": [
"arm-none-eabi-gcc",
"-c",
"-mcpu=cortex-m3",
"-mthumb",
"-DSTM32F103xB",
"-DUSE_HAL_DRIVER",
"-ICore/Inc",
"-IDrivers/STM32F1xx_HAL_Driver/Inc",
"-IDrivers/CMSIS/Device/ST/STM32F1xx/Include",
"-IDrivers/CMSIS/Include",
"-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy",
"-Ofast",
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-MMD",
"-MP",
"-MFbuild/idle.d",
"-Wall",
"-Wa,-a,-ad,-alms=build/idle.lst",
"Core/Src/idle.c",
"-o",
"build/idle.o"
],
"file": "Core/Src/idle.c"
},
{
"directory": "/home/indigo/projects/stm32_buisnesscard/program/stm32f1_buisnesscard_v1",
"arguments": [
"arm-none-eabi-gcc",
"-c",
"-mcpu=cortex-m3",
"-mthumb",
"-DSTM32F103xB",
"-DUSE_HAL_DRIVER",
"-ICore/Inc",
"-IDrivers/STM32F1xx_HAL_Driver/Inc",
"-IDrivers/CMSIS/Device/ST/STM32F1xx/Include",
"-IDrivers/CMSIS/Include",
"-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy",
"-Ofast",
"-Wall",
"-fdata-sections",
"-ffunction-sections",
"-MMD",
"-MP",
"-MFbuild/gpio.d",
"-Wall",
"-Wa,-a,-ad,-alms=build/gpio.lst",
"Core/Src/gpio.c",
"-o",
"build/gpio.o"
],
"file": "Core/Src/gpio.c"
}
]

View File

@ -3,3 +3,8 @@ file build/stm32f1_buisnesscard_v1.elf
target extended localhost:3333
load
#break mandelbrot.c:430
#commands
# print cam
#end

View File

@ -18,12 +18,14 @@ Mcu.Name=STM32F103C(8-B)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PA0-WKUP
Mcu.Pin1=PA1
Mcu.Pin10=PB14
Mcu.Pin11=PA13
Mcu.Pin12=PA14
Mcu.Pin13=VP_SYS_VS_Systick
Mcu.Pin14=VP_TIM2_VS_ClockSourceINT
Mcu.Pin15=VP_TIM4_VS_ClockSourceINT
Mcu.Pin10=PB13
Mcu.Pin11=PB14
Mcu.Pin12=PB15
Mcu.Pin13=PA13
Mcu.Pin14=PA14
Mcu.Pin15=VP_SYS_VS_Systick
Mcu.Pin16=VP_TIM2_VS_ClockSourceINT
Mcu.Pin17=VP_TIM4_VS_ClockSourceINT
Mcu.Pin2=PA2
Mcu.Pin3=PA3
Mcu.Pin4=PA5
@ -31,8 +33,8 @@ Mcu.Pin5=PA7
Mcu.Pin6=PB0
Mcu.Pin7=PB1
Mcu.Pin8=PB2
Mcu.Pin9=PB13
Mcu.PinsNb=16
Mcu.Pin9=PB12
Mcu.PinsNb=18
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103C8Tx
@ -88,6 +90,10 @@ PB1.GPIOParameters=GPIO_Speed
PB1.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB1.Locked=true
PB1.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_PuPd
PB12.GPIO_PuPd=GPIO_PULLUP
PB12.Locked=true
PB12.Signal=GPXTI12
PB13.GPIOParameters=GPIO_PuPd
PB13.GPIO_PuPd=GPIO_PULLDOWN
PB13.Locked=true
@ -96,6 +102,12 @@ PB14.GPIOParameters=GPIO_PuPd
PB14.GPIO_PuPd=GPIO_PULLDOWN
PB14.Locked=true
PB14.Signal=GPXTI14
PB15.GPIOParameters=PinState,GPIO_PuPd,GPIO_ModeDefaultOutputPP
PB15.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
PB15.GPIO_PuPd=GPIO_NOPULL
PB15.Locked=true
PB15.PinState=GPIO_PIN_SET
PB15.Signal=GPIO_Output
PB2.GPIOParameters=GPIO_Speed
PB2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB2.Locked=true
@ -155,6 +167,8 @@ SH.GPXTI0.0=GPIO_EXTI0
SH.GPXTI0.ConfNb=1
SH.GPXTI1.0=GPIO_EXTI1
SH.GPXTI1.ConfNb=1
SH.GPXTI12.0=GPIO_EXTI12
SH.GPXTI12.ConfNb=1
SH.GPXTI13.0=GPIO_EXTI13
SH.GPXTI13.ConfNb=1
SH.GPXTI14.0=GPIO_EXTI14

View File

@ -1,239 +0,0 @@
#include <stdint.h>
#include <string.h>
#include "mandelbrot.h"
#include "st7735.h"
#include "benchmark.h"
#include "main.h"
#define RES_X 160
#define RES_Y 80
#define DEFAULT_CENTER_X 0
#define DEFAULT_CENTER_Y 0
#define STEP_SIZE .1
#define ZOOM_SIZE .1
#define DECIMAL_LOC 28
#define DOUBLE_SCALER (1 << DECIMAL_LOC)
#define DOUBLE_TO_FIXED(val) (int32_t)((val) * DOUBLE_SCALER)
#define FIXED_MULTIPLY(x,y) ((((uint64_t)(x))*(y)) >> DECIMAL_LOC)
#define FIXED_TO_DOUBLE(val) ((val) / (double)DOUBLE_SCALER)
#define INFTY 2
#define INFTY_SQR INFTY * INFTY
#define ITERS 255
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//TODO move to some hardware.h or somethin
//channel order: B, G, R
#define R_BITS 5
#define G_BITS 6
#define B_BITS 5
//imaginary axis set automatically
#define CAM_DEF_MIN_R -1
#define CAM_DEF_MAX_R 1
//set controls
#define CAM_MOVE_UP BUTTON_UP
#define CAM_MOVE_RIGHT BUTTON_RIGHT
#define CAM_MOVE_DOWN BUTTON_DOWN
#define CAM_MOVE_LEFT BUTTON_LEFT
#define CAM_ZOOM_IN BUTTON_A
#define CAM_ZOOM_OUT BUTTON_B
struct camera {
double min_r, min_i, max_r, max_i;
};
enum VIEW_MODES { VIEW_UNINIT, VIEW_MANDREL, VIEW_SHIP };
void init_colorscheme_mandrel(uint16_t *scheme) {
uint16_t *tc = scheme;
for(unsigned int i = 0; i < ITERS; i++) {
if((i == 0) || (i == ITERS)) *tc = 0;
else if(i < 128) *tc = (((((i - 64) << 2)+0x1f) & 0x1f) | (((((i - 128) << 1)+0x1f) & 0x1f) << (5+6)));
else *tc = (-2*(i - 128)+0x1f) & 0xff;
*tc = (*tc << 8) | (*tc >> 8); //convert to little endian
tc++;
}
}
void init_colorscheme_ship(uint16_t *scheme) {
uint16_t *tc = scheme;
for(unsigned int i = 0; i < ITERS; i++) {
if((i == 0) || (i == ITERS)) *tc = 0;
else *tc = (((i - (128)) << 1)+0x1f) << (5+6);
tc++;
}
}
void cam_shift(struct camera *cam, double step_r, double step_i) {
double i_offset = (cam->max_i - cam->min_i) * step_i;
double r_offset = (cam->max_r - cam->min_r) * step_r;
cam->min_i += i_offset;
cam->max_i += i_offset;
cam->min_r += r_offset;
cam->max_r += r_offset;
}
void cam_zoom(struct camera *cam, double zoom) {
double i_scale = (cam->max_i - cam->min_i) * zoom;
double r_scale = (cam->max_r - cam->min_r) * zoom;
cam->min_i += i_scale;
cam->max_i -= i_scale;
cam->min_r += r_scale;
cam->max_r -= r_scale;
}
//TODO look into border tracing; this is too slow. Change name
//
void render_mandelbrot(uint16_t *framebuffer, uint16_t *colorscheme, struct camera cam, int x0, int y0, int w, int h) {
int32_t scale_i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y);
int32_t scale_r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X);
int32_t c_i = DOUBLE_TO_FIXED((((cam.max_i - cam.min_i) * (RES_Y - y0)) / RES_Y) + cam.min_i);
int32_t c_r0 = DOUBLE_TO_FIXED((((cam.max_r - cam.min_r) * x0) / RES_X) + cam.min_r);
int32_t c_r, z_i, z_r, zn_r, z_r_2, z_i_2;
size_t fb_index = 0;
int i;
//for(;;);
for(int y = y0; y < y0 + h; y++) {
c_r = c_r0;
for(int x = x0; x < x0 + w; x++) {
z_i = 0;
z_r = 0;
for(i = 0; i < ITERS; i++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + c_r;
//z_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c_i;
z_i = (FIXED_MULTIPLY(z_r, z_i) << 1) + c_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) break;
}
framebuffer[fb_index++] = colorscheme[i];
c_r += scale_r;
}
c_i -= scale_i;
}
}
#define FB_SIZE_X RES_X
#define FB_SIZE_Y RES_Y/2
//TODO rename
void draw_mandelbrot(int key_pressed) {
static uint16_t framebuffer[FB_SIZE_X * FB_SIZE_Y];
uint16_t columnbuffer[8*RES_Y];
static bool bottom_buffered = true;
//program flow is awful atm becuase I was planning something different; will be improved soon.
static struct camera cam = {
.min_r = CAM_DEF_MIN_R,
.max_r = CAM_DEF_MAX_R,
.min_i = ((double)RES_Y / RES_X) * CAM_DEF_MIN_R,
.max_i = ((double)RES_Y / RES_X) * CAM_DEF_MAX_R,
};
static int view_mode = VIEW_UNINIT;
static uint16_t colorscheme[ITERS];
//we could get rid of this and do some awful bitbashing lol
//but for readability, we shant
//TODO camera moves l/r more then u/d for some reason
/**
if(key_pressed & CAM_MOVE_UP) cam_shift(&cam, 0, STEP_SIZE);
if(key_pressed & CAM_MOVE_DOWN) cam_shift(&cam, 0, -STEP_SIZE);
if(key_pressed & CAM_MOVE_RIGHT) cam_shift(&cam, -STEP_SIZE, 0);
if(key_pressed & CAM_MOVE_LEFT) cam_shift(&cam, STEP_SIZE, 0);
if(key_pressed & CAM_ZOOM_IN) cam_zoom(&cam, ZOOM_SIZE);
if(key_pressed & CAM_ZOOM_OUT) cam_zoom(&cam, -ZOOM_SIZE);
**/
//yes, I know the following is disgusting. Before I clean it, I just wanna get the general idea out,
//it's more efficient in that order
//TODO once you get your idea ironed out, clean the code and improve the flow
benchmark_start();
if(view_mode == VIEW_UNINIT) {
view_mode = VIEW_MANDREL;
init_colorscheme_mandrel(colorscheme);
render_mandelbrot(framebuffer, colorscheme, cam, 0, 0, RES_X, RES_Y/2);
ST7735_DrawImage(0, 0, RES_X, (RES_Y / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, 0, RES_Y/2, RES_X, RES_Y/2);
ST7735_DrawImage(0, (RES_Y / 2), RES_X, (RES_Y / 2), framebuffer);
bottom_buffered = true;
}
else {
uint16_t top_line = bottom_buffered ? (RES_Y/2) : 0;
switch(key_pressed) {
const int y_offset = STEP_SIZE * RES_Y;
const int x_offset = STEP_SIZE * RES_X;
const size_t lines_rendered = (RES_Y/2) - y_offset;
const size_t rendered_area_y = RES_X * lines_rendered * sizeof(uint16_t);
const uint16_t framebuffer_offset_y = framebuffer + (RES_X * y_offset);
const uint16_t columns_rendered = RES_X - x_offset;
const uint16_t
case BUTTON_UP:
cam_shift(&cam, 0, STEP_SIZE);
memmove(framebuffer_offset, framebuffer, rendered_area_y);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, y_offset);
break;
case BUTTON_DOWN:
cam_shift(&cam, 0, -STEP_SIZE);
memmove(framebuffer, framebuffer_offset_y, rendered_area_y);
render_mandelbrot(framebuffer+(RES_X*lines_rendered), colorscheme, cam, 0, bottom_buffered ? RES_Y : lines_rendered, RES_X, y_offset);
break;
case BUTTON_RIGHT:
cam_shift(&cam, STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, RES_X - x_offset, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y), framebuffer + (RES_X * y) + x_offset, (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y) + (RES_X - x_offset), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_LEFT:
cam_shift(&cam, -STEP_SIZE, 0);
render_mandelbrot(columnbuffer, colorscheme, cam, 0, top_line, x_offset, RES_Y/2);
for(uint16_t y = 0; y < RES_Y/2; y++) {
memmove(framebuffer + (RES_X * y) + x_offset, framebuffer + (RES_X * y), (RES_X - x_offset) * sizeof(*framebuffer));
memmove(framebuffer + (RES_X * y), columnbuffer + (x_offset * y), x_offset * sizeof(*framebuffer));
}
break;
case BUTTON_A:
cam_zoom(&cam, ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
break;
case BUTTON_B:
cam_zoom(&cam, -ZOOM_SIZE);
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
break;
default:
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
}
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
bottom_buffered = !bottom_buffered;
top_line = bottom_buffered ? (RES_Y/2) : 0;
render_mandelbrot(framebuffer, colorscheme, cam, 0, top_line, RES_X, RES_Y/2);
ST7735_DrawImage(0, top_line, RES_X, (RES_Y/2), framebuffer);
}
benchmark_stop();
/**
render_mandelbrot(framebuffer, colorscheme, cam, false, key_pressed);
ST7735_DrawImage(0, 0, ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
render_mandelbrot(framebuffer, colorscheme, cam, true, key_pressed);
ST7735_DrawImage(0, (ST7735_HEIGHT / 2), ST7735_WIDTH, (ST7735_HEIGHT / 2), framebuffer);
**/
// ST7735_DrawImage(0, 0, ST7735_WIDTH - 1, ST7735_HEIGHT - 1, (uint16_t *)0x80000000);
}

View File

@ -1,256 +1,256 @@
print previous_neighbors
print current_neighbors
print previous_neighbors
print previous_neighbors
print source_dir
c
print previous_neighbors
print current_bord_i
print prev_bord_i
quit
b 249
c
print visited_border
quit
c
print visted_border
print visited_border
context
context
print previous_neighbors
print bord_i
print current_bord_i
print prev_bord_i
quit
print prev_bord_i
print current_bord_i
next
print current_bord_i
next
print nei_dir
next
print nei_dir
next
print current_neighbors
next
print nei_dir
next
next
print nei_i
print current_neighbors
print current_bord_i
print get_neighbor_index(current_bord_i, nei_i)
print nei_i
quit
c
c
c
c
c
c
c
c
quit
quit
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
quit
c
c
quit
c
print current_board_i
print current_bord_i
next
print current_bord_i
print current_neighbors
next
print nei_dir
print current_neighbors
print nei_dir
next
next
print i
print nei_dir
next
print current_neighbors
next
print nei_dir
next
print i
print nei_dir
print nei_dir
print nei_dir
print get_neighbor_coord(current_bord_cord, nei_dir, scale)
print current_bord_cord
print nei_dir
quit
c
c
c
c
quit
c
quit
c
quit
c
c
c
c
c
c
c
c
c
c
c
c
c
c
c
quit
c
quit
c
quit
c
print RES_X
quit
c
print current_board_i
print current_bord_i
print current_bord_i
next
next
print nei_dir
next
print previous_neighbors
print source_dir
print source_dir
print prevbord_i
print prev_bord_i
print current_neighbors
quit
c
quit
c
quit
c
quit
c
quit
cc
c
quit
quit
quit
c
c
c
quit
quit
b BORDER_START
d 7
f 7
b BORDER_START
b main:BORDER_START
b mandelbrot_bordertrace:BORDER_START
quit
c
quit
quit
c
b 327 if current_bord_i == 2012
quit
c
print nei_dir
quit
c
c
quit
c
print current_bord_i
print prev_bord_i
c
print prev_bord_i
quit
c
next
print get_neighbor_coord
print nei_dir
next
print current_bord_cord
next
print current_bord_cord
next
print prev_bord_i
next
print current_bord_i
print prev_bord_i
next
print current_bord_i
next
print filled_neighbors
print filled_neighbors
quit
c
c
qu8it
quit
c
quit
c
print borders
quit
f 5
context
f 6
context
c
quit
quit
quit
quit
quit
f 6
context
next
f 6
advance +1
next
b 363
c
next
print on_pixel
next
print borders
next
next
quit
b 391
c
quit
quit
quit
quit
quit
quit
quit
quit
quit
qiut
quit
quit
c
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
print pixels[8613].g
f 6
print pixels[8613].g
quit
f 6
watch pixels[8613]
start
c
f 6
print iter
iterate
b iter
b iterate
d
p iterate(8613)
b this_index == 8613
watch this_index == 8613
c
start
c
info b
info
watch pixels[8613]
context
f 4
f 3
f 5
f 6
f 5
f 4
f 3
context
f 2
context
f 3
context
f 2
quit
b main.c:222
watch pixels[8613]
info
i
info b
info watch
start
info watch
watch pixels[8613]
b mandelbrot_bordertrace
c
watch pixels[8613]
c
print this_coord
next
f 1
c
quit
quit
quit
c
print pixels
print on_pixel
print this_index
print this_coord
next
print nei_i
next
print nei_i
quit
c
c
quit
c
quit
quit
quit
quit
quit
quit
quit
f 6
context
print touching_start
print start_detached
p touching_start
print pass
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
f 6
exit
start
c
exit
c
print pixels[1971].g
f 7
context
print pixels[1971].g
quit
quit
quit
quit
qiut
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
print pixels[848]
f 7
print pixels[848].g
print pixels[848]
c
print pixels[858]
f 6
f 7
print pixels[858]
quit
quit
exit
quit
quit
quit
quit
print pixels[1991].g
f 6
print pixels[1991].g
print pixels[1991].g == GCHAN_INNER_VISITED
print pixels[1991].g == GCHAN_INNER_CLOSED
print pixels[1991].g == GCHAN_INNER_VISITED
quit
quit
quit
quit
quit
quit
quit
print nei_i
print this_index
print RES_X
print nei_dir
get_neighbor_index(this_index, nei_dir)
print get_neighbor_index(this_index, nei_dir)
print this_index
pirnt on_pixel
print on_pixel
quit
c
quit
quit
quiot
quit
quit
quit
quit
quit
quit
quit
quit
quyit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quit
quyit
quit
b 394
c
print scale
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 7, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 0, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 1, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 2, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 3, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 4, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 5, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 6, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 7, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 8, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 8, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 9, (FixedCord){3355443,3355443})
print get_neighbor_coord((FixedCord){-140928622, 134217728}, 7, (FixedCord){3355443,3355443})
p sizeof(double)
c
d
c
quit
quit
b mandelbrot_bordertrace
c
next
print scale
cat camera
cat cam
print cam
print *cam
x
c
print *cam
c
c
print *cam
quit

View File

@ -1,14 +1,30 @@
/** READ BEFORE JUDING!
* Yes, I know this code is a mess. Debug code is added
* happhazardly, two cameras are used, etc.
* That's because it's a temporary program
* to create optimizations and debug rendering issues without hardware.
* None of this is going to be included in the project, and the code is thus
* not extensible or organized; it really doesn't save any effort to do so.
*
* This code is meant for my eyes only. You've been warned!
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <raylib.h>
#include <raymath.h>
#include <limits.h>
#include <complex.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#define WINDOW_SIZE_X 1600
#define WINDOW_SIZE_Y 800
#define RES_X 1600
#define RES_Y 800
#define RES_X 160
#define RES_Y 80
#define DEFAULT_CENTER_X 0
#define DEFAULT_CENTER_Y 0
#define MOUSE_BUTTON 0
@ -28,9 +44,18 @@
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//#define SHIP
#undef SHIP
//#undef SHIP
//#define COLOR_DEBUG
#ifdef SHIP
Color get_color_dbg(int i) {
if(i == ITERS) return (Color){0,0,255,255};
// if(i == 0) return (Color){255,255,255,255};
return (Color){255,0,255,255};
}
#ifdef COLOR_DEBUG
#elif SHIP
Color get_color(int i) {
if(i == ITERS) return (Color){0, 0, 0, 255};
if(i == 0) return (Color){0, 0, 0, 255};
@ -43,7 +68,9 @@ Color get_color(int i) {
}
#else
Color get_color(int i) {
if((i == ITERS) || (i == 0)) return (Color){0, 0, 0, 255};
// if((i == ITERS) || (i == 0)) return (Color){0, 0, 0, 255};
if(i == ITERS) return (Color){0,0,0,255};
if(i == 0) return (Color){0,0,1,255};
if(i < 128) {
return (Color) {
(8*(i - 128)+255) & 0xff,
@ -61,20 +88,24 @@ Color get_color(int i) {
}
#endif
//C does remainder, not modulo.
//TODO optimize for mod 8
inline int mod(int n, int d) {
int r = n % d;
return (r < 0) ? r + d : r;
}
int mod(int n, int d);
struct camera {
double min_r, min_i, max_r, max_i;
};
struct vec2_double {
double x, y;
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
struct vec2_float {
int32_t x, y;
};
static inline int iterate(int32_t r, int32_t i) {
static inline int iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
@ -82,12 +113,12 @@ static inline int iterate(int32_t r, int32_t i) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + r;
zn_r = z_r_2 - z_i_2 + c.r;
#ifdef SHIP
zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + i;
zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#else
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + i;
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#endif
z_i = zn_i;
@ -121,24 +152,579 @@ enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
//we can inline these if needed
inline bool bitarray_check(uint8_t *array, size_t i) {
return array[i/8] & (1 << (i%8));
}
inline void bitarray_set(uint8_t *array, size_t i) {
array[i/8] |= (1 << (i%8));
}
inline FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i;
if((direction > N) && (direction < S)) from_coord.r += step.r;
if((direction > E) && (direction < W)) from_coord.i -= step.i;
if(direction > S) from_coord.r -= step.r;
return from_coord;
}
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction) {
const int neighbor_index_accl[8] =
{-RES_X, -RES_X + 1, 1, RES_X + 1, RES_X, RES_X - 1, -1, -RES_X - 1};
from_pixel += neighbor_index_accl[direction];
//canidate for optimization; lots of branches. maybe inline
return from_pixel;
}
//we'll be storing info in the green channel to utalize available memory
//per pixel.
#define BACKSTACK_SIZE 32
#define GCHAN_UNRENDERED 0 //don't change; green channel zero'd on cam move
#define GCHAN_BLOCKED (1 << 7) //interior element or visiteed
#define GCHAN_INTERNAL (1 << 5) //part of set, 0x20
#define GCHAN_EXTERNAL (1 << 0) //not part of set, 0x10
#define GCHAN_INNER_VISITED (1 << 3)
#define GCHAN_INNER_CLOSED (1 << 2)
/**
void switch_pixel(coord &this_coord, const coord step, size_t this_index, int dir) {
}
**/
void debug_step(Color *pix, Texture *tex, size_t index, bool pause) {
return;
// SetTargetFPS(0);
static bool fuckin_manual_pause_iguess = false;
static Camera2D cam = {0};
if(!cam.zoom) cam.zoom = (float)GetRenderWidth()/RES_X;
static int debug_color = 0;
const float dbg_cam_step = 100;
const float dbg_cam_zoom = 1.5;
(pause || fuckin_manual_pause_iguess) ? SetTargetFPS(60) : SetTargetFPS(0);
for(;;) {
switch(GetKeyPressed()) {
case KEY_UP:
cam.offset.y += dbg_cam_step;
break;
case KEY_DOWN:
cam.offset.y -= dbg_cam_step;
break;
case KEY_RIGHT:
cam.offset.x += dbg_cam_step;
break;
case KEY_LEFT:
cam.offset.x -= dbg_cam_step;
break;
case KEY_W:
cam.zoom *= dbg_cam_zoom;
break;
case KEY_S:
cam.zoom /= dbg_cam_zoom;
break;
case KEY_SPACE:
Vector2 mouse_pos = Vector2Multiply(GetMousePosition(), (Vector2){(double)RES_X / WINDOW_SIZE_X, (double)RES_Y / WINDOW_SIZE_Y});
//mouse_pos = Vector2Divide(mouse_pos, (Vector2){cam.zoom, cam.zoom});
printf("%f, %f (%lu)\n", mouse_pos.x, mouse_pos.y, ((size_t)mouse_pos.y * RES_X) + (size_t)mouse_pos.x);
break;
case KEY_ENTER:
return;
default:
BeginDrawing();
pix[index] =
(Color) {debug_color, pix[index].g, 0, 255};
BeginDrawing();
UpdateTexture(*tex, pix);
DrawTextureEx(*tex, (Vector2)
{0 - cam.offset.x, cam.offset.y}, 0,
cam.zoom, WHITE);
EndDrawing();
if(!pause && !fuckin_manual_pause_iguess) return;
}
}
}
//only need four indecies, however we use 8 because it's more convinient.
void detect_borders(bool borders[8], size_t i) {
//if this is too slow, it's easy to do it without the modulos.
int index_mod = i % RES_X;
bzero(borders, sizeof(*borders) * 8);
if((i + RES_X) > (RES_X * RES_Y)) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(((int)i - RES_X) < 0) {
borders[NE] = GCHAN_EXTERNAL;
borders[N] = GCHAN_EXTERNAL;
borders[NW] = GCHAN_EXTERNAL;
}
if(index_mod == 0) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
else if(index_mod == (RES_X - 1)) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
borders[nei_dir] = GCHAN_EXTERNAL;
}
/**
//runs into occational percision issues
if((this_coord.i - scale.i) <= cam_bord_fixed_s) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.i + scale.i) >= cam_bord_fixed_n) {
printf("bruh\n");
nei_presort[NE] = GCHAN_EXTERNAL;
nei_presort[N] = GCHAN_EXTERNAL;
nei_presort[NW] = GCHAN_EXTERNAL;
}
if((this_coord.r - scale.r) <= cam_bord_fixed_w) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.r + scale.r) >= cam_bord_fixed_e) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
**/
}
void debug_nei_arrays(int *priority, int *presort, size_t index) {
int debug_x = index % RES_X;
int debug_y = index / RES_X;
printf("(%i, %i) %lu: pre [", debug_x, debug_y, index);
for(int nd = 0; nd < 8; nd++) printf("%i, ", presort[nd]);
printf("], pri [");
for(int nd = 0; nd < 8; nd++) printf("%i, ", priority[nd]);
printf("]\n");
}
enum {
SCAN_MODE_NONE,
SCAN_MODE_SAFE,
SCAN_MODE_INTERIOR
} scan_mode;
unsigned int mandelbrot_bordertrace(struct camera *cam, Color *pixels) {
//these lookup tables r cheap cuz on the stm32f1, 1 memory read is 1 instruction
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = {.r = 0, .i = DOUBLE_TO_FIXED(cam->max_i)};
unsigned int total_iters = 0;
size_t on_pixel = 0;
int border_scanning = 0;
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture debug_tex = LoadTextureFromImage(img);
UnloadImage(img);
// bzero(pixels, RES_X * RES_Y * sizeof(Color));
// for(size_t c = 0; c < (RES_X * RES_Y); c++) pixels[c] = (Color){0,0,0,255};
for(int y = 0; y < RES_Y; y++) {
border_scanning = 0;
for(int x = 0; x < RES_X; x++) {
c.r = DOUBLE_TO_FIXED((((on_pixel % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
c.i = DOUBLE_TO_FIXED((((on_pixel / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
/**
SetTargetFPS(0);
BeginDrawing();
UpdateTexture(debug_tex, pixels);
DrawTextureEx(debug_tex, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
**/
switch(pixels[on_pixel].g) {
case GCHAN_INTERNAL:
// printf("starting interior trace...\n");
size_t inner_pix_i = on_pixel;
int next_pix;
bool pass = false;
bool start_detached = false;
bool touching_start;
bool borders[8];
int nei_dir;
size_t nei_i;
bool trusted_nei[8];
{
//TODO
detect_borders(borders, on_pixel);
for(nei_dir = 0; nei_dir < 8; nei_dir += 2) if(borders[nei_dir]) break;
int edge_state = 0;
bool first_unrendered = false;
for(nei_dir = 0; nei_dir < 8; nei_dir += 2) {
nei_i = get_neighbor_index(inner_pix_i, nei_dir);
if((nei_dir == 0) && (pixels[nei_i].g == GCHAN_UNRENDERED)) first_unrendered = true;
if((edge_state & 1) && (pixels[nei_i].g != GCHAN_UNRENDERED)) edge_state++;
else if(!(edge_state & 1) && (pixels[nei_i].g == GCHAN_UNRENDERED)) edge_state++;
}
//tired, easier to think of success states
if(!((edge_state == 1)
|| ((edge_state == 2) && (!first_unrendered && pixels[nei_i].g != GCHAN_UNRENDERED))
|| ((edge_state == 3) && (first_unrendered && pixels[nei_i].g == GCHAN_UNRENDERED)))) break;
}
for(nei_dir = 0; nei_dir < 8; nei_dir++) {
nei_i = get_neighbor_index(inner_pix_i, nei_dir);
if(pixels[nei_i].g == GCHAN_UNRENDERED) trusted_nei[nei_dir] = true;
else trusted_nei[nei_dir] = false;
}
while(true) {
detect_borders(borders, inner_pix_i);
next_pix = -1;
touching_start = false;
//debug_step(pixels, &debug_tex, inner_pix_i, true);
for(nei_dir = 0; nei_dir < 8; nei_dir += 2) {
size_t nei_i;
size_t localized_dirs[8];
if(borders[nei_dir]) continue;
nei_i = get_neighbor_index(inner_pix_i, nei_dir);
if(nei_i == on_pixel) {
touching_start = true;
if(start_detached) {
next_pix = on_pixel;
break;
}
continue;
}
if(pixels[nei_i].g != ((pass) ? GCHAN_INNER_VISITED : GCHAN_INTERNAL)) continue;
//if((pixels[nei_i].g == GCHAN_UNRENDERED) || (pixels[nei_i].g == ((pass) ? GCHAN_INNER_CLOSED : GCHAN_INNER_VISITED))) continue;
for(int i = 0; i < 8; i++) localized_dirs[i] = mod(nei_dir + i, 8);
if(!(trusted_nei[localized_dirs[2]] || trusted_nei[localized_dirs[1]] ||
trusted_nei[localized_dirs[6]] || trusted_nei[localized_dirs[7]])) {
continue;
}
/** TODO if we have time, we can only keep track of safe borders when we get in trouble by looking at
the past pixel. This has a lot of overhead, but I did it before thinking & I'm out of resources.
**/
trusted_nei[localized_dirs[4]] = false;
trusted_nei[localized_dirs[3]] = trusted_nei[localized_dirs[2]];
trusted_nei[localized_dirs[2]] = trusted_nei[localized_dirs[1]];
trusted_nei[localized_dirs[5]] = trusted_nei[localized_dirs[6]];
trusted_nei[localized_dirs[6]] = trusted_nei[localized_dirs[7]];
{
bool front_neighbors[5];
bool local_borders[8];
detect_borders(local_borders, nei_i);
for(int nei_edge_dir = -1; nei_edge_dir <= 1; nei_edge_dir++) {
size_t nei_edge_local = mod(nei_dir + nei_edge_dir, 8);
front_neighbors[nei_edge_dir + 1] =
!(local_borders[nei_edge_local] || (pixels[get_neighbor_index(nei_i, nei_edge_local)].g != GCHAN_UNRENDERED));
}
front_neighbors[3] = trusted_nei[localized_dirs[6]];
front_neighbors[4] = trusted_nei[localized_dirs[2]];
trusted_nei[localized_dirs[7]] = (front_neighbors[0] && (front_neighbors[3] ||
(front_neighbors[1] && front_neighbors[2] && front_neighbors[4])));
trusted_nei[localized_dirs[1]] = (front_neighbors[2] && (front_neighbors[4] ||
(front_neighbors[0] && front_neighbors[1] && front_neighbors[3])));
trusted_nei[localized_dirs[0]] = (front_neighbors[1] && (trusted_nei[localized_dirs[1]] ||
trusted_nei[localized_dirs[7]]));
}
next_pix = nei_i;
break;
}
if(!start_detached && !touching_start && !(inner_pix_i == on_pixel)) start_detached = true;
else if(start_detached && touching_start) {
start_detached = false;
if(pass) {
pixels[inner_pix_i].g = GCHAN_INNER_CLOSED;
pixels[touching_start].g = GCHAN_INNER_CLOSED;
border_scanning = true;
debug_step(pixels, &debug_tex, inner_pix_i, true);
break;
}
else {
pass = true;
pixels[inner_pix_i].g = GCHAN_INNER_VISITED;
inner_pix_i = on_pixel;
continue;
}
}
pixels[inner_pix_i].g = ((pass) ? GCHAN_INNER_CLOSED : GCHAN_INNER_VISITED);
//TODO remove
if(pass) pixels[next_pix].r = 0xff;
else { pixels[next_pix].b = 0xaa; }
if(next_pix < 0) {
debug_step(pixels, &debug_tex, inner_pix_i, true);
break;
}
else {
inner_pix_i = next_pix;
}
}
break;
case GCHAN_UNRENDERED:
if(border_scanning) {
//pixels[on_pixel] = get_color(ITERS);
//printf("interior\n");
pixels[on_pixel] = (Color){0xfe,0,0xfe,0xff};
break;
}
//printf("rendering %i, %i (%lu)\n", x, y, on_pixel);
int i = iterate(c);
total_iters += i;
pixels[on_pixel] = get_color(i);
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
bool seperated_from_start = false;
int nei_priority[8];
int last_nei_priority[8];
int nei_presort[8];
size_t backstack[BACKSTACK_SIZE];
size_t backstack_i = 0;
int backstack_calls = 0;
int nei_dir;
debug_step(pixels, &debug_tex, this_index, false);
bool debug_mode = false;
bool borders[8];
detect_borders(borders, inner_pix_i);
for(nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
if(borders[nei_dir]) break;
nei_i = get_neighbor_index(on_pixel, nei_dir);
if(pixels[nei_i].g & GCHAN_EXTERNAL) break;
}
if(nei_dir >= 8) {
border_scanning = SCAN_MODE_INTERIOR;
break;
}
while(true) {
detect_borders(borders, this_index);
debug_step(pixels, &debug_tex, this_index, false);
if(debug_mode) debug_step(pixels, &debug_tex, on_pixel, debug_mode);
//step 1: check pixels around us, fill in neighbors.
bzero(nei_presort, sizeof(nei_presort));
this_coord.r = DOUBLE_TO_FIXED((((this_index % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
this_coord.i = DOUBLE_TO_FIXED((((this_index / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
// TODO replace modulos with bitwise ops
bool start_is_nei = false;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(borders[nei_dir]) {
nei_presort[nei_dir] = GCHAN_EXTERNAL;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir);
gchan_info = pixels[nei_i].g;
if(nei_i == on_pixel) start_is_nei = true;
//note that when we move this over, there will be no alpha channel.
//gchan_info will be extracted differently!!!
if(gchan_info) nei_presort[nei_dir] = gchan_info;
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
pixels[nei_i] = get_color(i);
if(i == ITERS) nei_presort[nei_dir] = GCHAN_INTERNAL;
else {
//exterior
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
pixels[nei_i].g = nei_presort[nei_dir];
}
}
if(!start_is_nei && !seperated_from_start && (this_index != on_pixel)) seperated_from_start = true;
if(start_is_nei && seperated_from_start) {
//printf("success!\n");
pixels[this_index].g = GCHAN_BLOCKED;
break;
}
//go back if we're in the interior and not an edge
int edge_cnt = 0;
//sort into prioraties
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
int nei_edge_i;
if(nei_presort[nei_dir] != GCHAN_INTERNAL) {
nei_priority[nei_dir] = -1;
continue;
}
//TODO rename nei_edge_i
//printf("%i: \n", nei_dir);
for(nei_edge_i = -2; nei_edge_i <= 2; nei_edge_i++) {
int nei_edge_mod = mod((nei_dir + nei_edge_i), 8);
if((nei_presort[nei_edge_mod] == GCHAN_EXTERNAL) || borders[nei_edge_mod]) break;
}
if(nei_edge_i > 2) {
//no edge found
nei_priority[nei_dir] = -2; //TODO test; remove interior check if nessesary
continue;
}
//narrow bridge scenario
if(nei_presort[mod((nei_dir + 1), 8)] & nei_presort[mod((nei_dir - 1), 8)] & GCHAN_EXTERNAL) {
nei_i = get_neighbor_index(this_index, nei_dir);
//pixels[nei_i] = (Color) {0xff, pixels[nei_i].g, 0x00, 0xff};
nei_priority[nei_dir] = -1;
continue;
}
edge_cnt++;
nei_priority[nei_dir] = 0;
}
if(edge_cnt >= 2) {
backstack[backstack_i++ % BACKSTACK_SIZE] = this_index;
//printf("backstack increased\n");
}
//now go to canidate with lowest prioraty
pixels[this_index].g = GCHAN_BLOCKED;
for(int priority = 0; priority <= 5; priority++) { //TODO we might not need the priority system anymore
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
if(nei_priority[nei_dir] != priority) continue;
backstack_calls = 0;
this_index = get_neighbor_index(this_index, nei_dir);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
//printf("--> (%zu, %zu)\n", this_index % RES_X, this_index / RES_X);
goto NEXT_PIXEL;
}
}
if((backstack_calls++ > BACKSTACK_SIZE) || (backstack_i < 1)) { //please don't cause issues...
//printf("cycled through backstack, questionable success...\n");
break;
}
this_index = backstack[--backstack_i % BACKSTACK_SIZE];
NEXT_PIXEL:
memcpy(last_nei_priority, nei_priority, sizeof(nei_priority));
}
debug_step(pixels, &debug_tex, this_index, true);
}
else pixels[on_pixel].g = GCHAN_EXTERNAL;
break;
case GCHAN_INNER_CLOSED:
//printf("bruh\n");
if(((x + 2) < RES_X) && (pixels[on_pixel + 1].g == GCHAN_UNRENDERED)) border_scanning = SCAN_MODE_NONE;
break;
default:
border_scanning = SCAN_MODE_NONE;
}
on_pixel++;
c.r += scale.r;
//printf("%u\n", on_pixel);
}
border_scanning = false;
}
debug_step(pixels, &debug_tex, 0, true);
for(size_t i = 0; i < (RES_X * RES_Y); i++) pixels[i].g = 0;
return total_iters;
}
unsigned int mandelbrot_unoptimized(struct camera *cam, Color *pixels) {
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = { .r = DOUBLE_TO_FIXED(cam->min_r), .i = DOUBLE_TO_FIXED(cam->max_i) };
unsigned int total_iters = 0;
size_t on_pixel = 0;
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
c.r = DOUBLE_TO_FIXED((((on_pixel % RES_X) / (double)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r);
c.i = DOUBLE_TO_FIXED((((on_pixel / (double)RES_X) / (double)RES_Y) * (cam->min_i - cam->max_i)) + cam->max_i);
total_iters += i;
pixels[((y * RES_X) + x)] = get_color(i);
on_pixel++;
// c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
int main() {
Color *pixels = malloc(RES_X * RES_Y * sizeof(Color));
struct camera cam = {
//test();
//return 0;
Color *pixels_unoptimized = malloc(RES_X * RES_Y * sizeof(Color));
Color *pixels_optimized = malloc(RES_X * RES_Y * sizeof(Color));
bool optimized = true;
//(1.514379082621093886019, 0.000033222739567139065) - (1.514381385800912305228, 0.000034374329476534746)
struct camera cam_default = {
.min_r = -1,
.max_r = 1,
// .min_i = -1,
// .max_i = 1
.max_r = 1
};
cam_default.min_i = ((double)RES_Y / RES_X) * cam_default.min_r;
cam_default.max_i = ((double)RES_Y / RES_X) * cam_default.max_r;
//done
//.min_r = 0.340060821337554164412, .min_i = -0.076399869494282027227, .max_r = 0.340671385211165078655, .max_i = -0.076094587557451340287
//done
//.min_r = 0.348347456407892719366, .min_i = -0.092130353675640097588, .max_r = 0.349033773135021985201, .max_i = -0.091787195312047098472
//has internal noise
//.min_r = 0.348416088080605645949, .min_i = -0.092130353675640097588, .max_r = 0.349102404807734911785, .max_i = -0.091787195312047098472
//needs diagnol transfer
//.min_r = 0.352126044212195454808, .min_i = -0.101818891004586714599, .max_r = 0.354169737175103083171, .max_i = -0.100797044523048578979
//works
//.min_r = 1.514379082621093886019, .min_i = 0.000033222739567139065, .max_r = 1.514381385800912305228, .max_i = 0.000034374329476534746
// unusual issue; complete rendered border
// .min_r = 0.426539347230382670517, .min_i = 0.218210183100018217939, .max_r = 0.427445609943903681582, .max_i = 0.218663314456816582076
struct camera cam = {
//.min_r = 0.348416088080605645949, .min_i = -0.092130353675640097588, .max_r = 0.349102404807734911785, .max_i = -0.091787195312047098472
.min_r = 0.348347456407892719366, .min_i = -0.092130353675640097588, .max_r = 0.349033773135021985201, .max_i = -0.091787195312047098472
};
cam.min_i = ((double)RES_Y / RES_X) * cam.min_r;
cam.max_i = ((double)RES_Y / RES_X) * cam.max_r;
InitWindow(WINDOW_SIZE_X, WINDOW_SIZE_Y, "mandelbrot fixed point test");
SetTraceLogLevel(LOG_ERROR);
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture tex = LoadTextureFromImage(img);
UnloadImage(img);
SetTargetFPS(10);
SetTargetFPS(60);
while(!WindowShouldClose()) {
switch(GetKeyPressed()) {
@ -160,50 +746,47 @@ int main() {
case KEY_S:
zoom_cam(&cam, -ZOOM_SIZE);
break;
case KEY_SPACE:
optimized = !optimized;
break;
default:
BeginDrawing();
EndDrawing();
continue;
break;
}
printf("(%.6f, %.6f) - (%.6f, %.6f)\n", cam.min_r, cam.min_i, cam.max_r, cam.max_i);
struct coords {
int x, y
};
{
int32_t scale_i = DOUBLE_TO_FIXED((cam.max_i - cam.min_i) / (double)RES_Y);
int32_t scale_r = DOUBLE_TO_FIXED((cam.max_r - cam.min_r) / (double)RES_X);
int32_t c_i = DOUBLE_TO_FIXED(cam.max_i);
int32_t c_r;
uint8_t rendered[(RES_X * RES_Y) / 8] = {0};
uint8_t edges[(RES_X * RES_Y) / 8] = {0};
int32_t directions_r[8] = {0, scale_r, scale_r, scale_r, 0, -scale_r, -scale_r, -scale_r};
int32_t directions_i[8] = {scale_i, scale_i, 0, -scale_i, -scale_i, -scale_i, 0, scale_i};
int i;
for(int y = 0; y < RES_Y; y++) {
c_r = DOUBLE_TO_FIXED(cam.min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c_r, c_i);
if(i >= ITERS) {
int start_x = x;
int start_y = y;
do {
for(int canidate_d = 0; canidate_d < NW; canidate_d++) {
printf(".min_r = %.21f, .min_i = %.21f, .max_r = %.21f, .max_i = %.21f\n", cam.min_r, cam.min_i, cam.max_r, cam.max_i);
}
} while((x != start_x) && (y != start_y));
}
pixels[((y * RES_X) + x)] = get_color(iterate(c_r, c_i));
c_r += scale_r;
}
c_i -= scale_i;
}
}
clock_t begin, end;
double time_unoptimized;
double time_optimized;
for(int i = 0; i < (RES_X * RES_Y); i++) { pixels_unoptimized[i] = (Color){0, 0, 0, 0xff}; }
for(int i = 0; i < (RES_X * RES_Y); i++) { pixels_optimized[i] = (Color){0, 0, 0, 0xff}; }
begin = clock();
unsigned int unoptimized_iters = mandelbrot_unoptimized(&cam, pixels_unoptimized);
end = clock();
time_unoptimized = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Unoptimized: %u iterations, %f seconds\n", unoptimized_iters, time_unoptimized);
begin = clock();
unsigned int optimized_iters = mandelbrot_bordertrace(&cam, pixels_optimized);
end = clock();
time_optimized = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Border tracing: %u iterations, %f seconds\n", optimized_iters, time_optimized);
printf("border tracing does %f%% of nieve approach\n", ((float)optimized_iters / unoptimized_iters) * 100);
BeginDrawing();
UpdateTexture(tex, pixels);
printf("%s\n", optimized ? "optimized mode" : "unoptimized mode");
UpdateTexture(tex, optimized ? pixels_optimized : pixels_unoptimized);
DrawTextureEx(tex, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
}
return 0;

View File

@ -0,0 +1,585 @@
/** READ BEFORE JUDING!
* Yes, I know this code is a mess. Debug code is added
* happhazardly, two cameras are used, etc.
* That's because it's a temporary program
* to create optimizations and debug rendering issues without hardware.
* None of this is going to be included in the project, and the code is thus
* not extensible or organized; it really doesn't save any effort to do so.
*
* This code is meant for my eyes only. You've been warned!
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <raylib.h>
#include <raymath.h>
#include <limits.h>
#include <complex.h>
#include <string.h>
#include <unistd.h>
#define WINDOW_SIZE_X 1600
#define WINDOW_SIZE_Y 800
#define RES_X 1600
#define RES_Y 800
#define DEFAULT_CENTER_X 0
#define DEFAULT_CENTER_Y 0
#define MOUSE_BUTTON 0
#define STEP_SIZE .1
#define ZOOM_SIZE .1
#define DECIMAL_LOC 28
#define DOUBLE_SCALER (1 << DECIMAL_LOC)
#define DOUBLE_TO_FIXED(val) (int32_t)((val) * DOUBLE_SCALER)
#define FIXED_MULTIPLY(x,y) ((((uint64_t)(x))*(y)) >> DECIMAL_LOC)
#define FIXED_TO_DOUBLE(val) ((val) / (double)DOUBLE_SCALER)
#define INFTY 2
#define INFTY_SQR INFTY * INFTY
#define ITERS 255
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//#define SHIP
//#undef SHIP
int debug_x, debug_y;
#ifdef SHIP
Color get_color(int i) {
if(i == ITERS) return (Color){0, 0, 0, 255};
if(i == 0) return (Color){0, 0, 0, 255};
return (Color) {
2*(i - 128)+255,
0,
0,
255
};
}
#else
Color get_color(int i) {
// if((i == ITERS) || (i == 0)) return (Color){0, 0, 0, 255};
if(i == ITERS) return (Color){0,0,0,255};
if(i == 0) return (Color){0,0,1,255};
if(i < 128) {
return (Color) {
(8*(i - 128)+255) & 0xff,
0,
(16*(i - 64)+255) & 0xff,
255
};
}
return (Color) {
0,
0,
((unsigned int)-2*(i - 128)+255) & 0xff,
255
};
}
#endif
//TODO remove
struct debug_info {
int32_t r, i;
int x, y;
};
__attribute__((used)) struct debug_info debug_get_coord(size_t i) {
struct debug_info ret;
ret.x = i % RES_X;
ret.y = i / RES_Y;
return ret;
}
struct camera {
double min_r, min_i, max_r, max_i;
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
static inline int iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
for(int it = 0; it < ITERS; it++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + c.r;
#ifdef SHIP
zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#else
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#endif
z_i = zn_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) return it;
}
return ITERS;
}
//blllluuuuurg, matracies and vectors in raylib are floats and we need doubles
void shift_cam(struct camera *cam, double step_r, double step_i) {
double i_offset = (cam->max_i - cam->min_i) * step_i;
double r_offset = (cam->max_r - cam->min_r) * step_r;
cam->min_i += i_offset;
cam->max_i += i_offset;
cam->min_r += r_offset;
cam->max_r += r_offset;
}
void zoom_cam(struct camera *cam, double zoom) {
double i_scale = (cam->max_i - cam->min_i) * zoom;
double r_scale = (cam->max_r - cam->min_r) * zoom;
cam->min_i += i_scale;
cam->max_i -= i_scale;
cam->min_r += r_scale;
cam->max_r -= r_scale;
}
enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
//we can inline these if needed
inline bool bitarray_check(uint8_t *array, size_t i) {
return array[i/8] & (1 << (i%8));
}
inline void bitarray_set(uint8_t *array, size_t i) {
array[i/8] |= (1 << (i%8));
}
inline FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i;
if((direction > N) && (direction < S)) from_coord.r += step.r;
if((direction > E) && (direction < W)) from_coord.i -= step.i;
if(direction > S) from_coord.r -= step.r;
return from_coord;
}
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction) {
const int neighbor_index_accl[8] =
{-RES_X, -RES_X + 1, 1, RES_X + 1, RES_X, RES_X - 1, -1, -RES_X - 1};
from_pixel += neighbor_index_accl[direction];
//canidate for optimization; lots of branches. maybe inline
return from_pixel;
}
bool bitarray_check(uint8_t *array, size_t i);
void bitarray_set(uint8_t *array, size_t i);
#define BITARRAY_SET(array, i) ((array)[(i)/8] |= (1 << ((i) % 8)))
#define BITARRAY_CLEAR(array, i) ((array)[(i)/8] &= ~(1 << ((i) % 8)))
#define BITARRAY_CHECK(array, i) ((array)[(i)/8] & (1 << ((i) % 8)))
#define PRESORT_UNSOLVED (1 << 0)
#define PRESORT_VISITED (1 << VISITED)
//#define PRESORT_INTERIOR (1 << INTERIOR) //in set, NOT an edge
//#define PRESORT_BACKTRACKED (1 << BACKTRACED)
//#define PRESORT_EXTERIOR (1 <<
//we'll be storing info in the green channel to utalize all available memory.
//the following is bitmasks to do so
#define GCHAN_RENDERED (1 << 0)
#define GCHAN_VISITED (1 << 1)
#define GCHAN_BLOCKED (1 << 2) //interior element or backtrack
#define GCHAN_EXTERNAL (1 << 3)
#define GCHAN_DEBUG (1 << 4) //extra, not nessesary
/**
void switch_pixel(coord &this_coord, const coord step, size_t this_index, int dir) {
}
**/
unsigned int mandelbrot_bordertrace(struct camera *cam, Color *pixels) {
//these lookup tables r cheap cuz on the stm32f1, 1 memory read is 1 instruction
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = {.r = 0, .i = DOUBLE_TO_FIXED(cam->max_i)};
unsigned int total_iters = 0;
size_t on_pixel = 0;
//for camera border calculations
int32_t cam_bord_fixed_n = DOUBLE_TO_FIXED(cam->min_i);
int32_t cam_bord_fixed_s = DOUBLE_TO_FIXED(cam->max_i);
int32_t cam_bord_fixed_e = DOUBLE_TO_FIXED(cam->max_r);
int32_t cam_bord_fixed_w = DOUBLE_TO_FIXED(cam->min_r);
//I know this is gross, just for debugigng!
//will clean up once I get things ironed out
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture debug_tex = LoadTextureFromImage(img);
UnloadImage(img);
Color *debug_pix = malloc(RES_X * RES_Y * sizeof(Color));
memcpy(debug_pix, pixels, RES_X * RES_Y * sizeof(Color));
static Camera2D debug_cam = {0};
debug_cam.zoom = (float)GetRenderWidth()/RES_X;
/**
//for keeping track of border only. will organize later
uint8_t set[(160*80)/8] = {0};
uint8_t unset[(160*80)/8] = {0};
**/
const Color debug_colors[] =
{ (Color) {0xff, 0x00, 0x00, 0xff},
(Color) {0xff, 0x00, 0xff, 0xff},
(Color) {0x00, 0xff, 0x00, 0xff},
(Color) {0x00, 0x00, 0xff, 0xff},
(Color) {0x6a, 0x00, 0xff, 0xff}
};
static int debug_color = 0;
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
total_iters += i;
pixels[on_pixel] = get_color(i);
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
int nei_priority[8];
int last_nei_priority[8];
int last_direction = E;
int nei_presort[8];
//only really need to zero green channel
bzero(pixels, RES_X * RES_Y * sizeof(*pixels));
//this is so fucking knarly
printf("NEW BORDER\n");
while(true) {
//step 1: check pixels around us, fill in neighbors.
bzero(nei_presort, sizeof(nei_presort));
//find if we're pushed against screen border.
//feels gross but I don't think there's a better way
if((this_coord.i - scale.i) < cam_bord_fixed_n) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.i + scale.i) > cam_bord_fixed_s) {
nei_presort[NE] = GCHAN_EXTERNAL;
nei_presort[N] = GCHAN_EXTERNAL;
nei_presort[NW] = GCHAN_EXTERNAL;
}
if((this_coord.r - scale.r) < cam_bord_fixed_w) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.r + scale.r) > cam_bord_fixed_e) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
// TODO replace modulos with something faster
bool interior = true;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(nei_presort[nei_dir] == GCHAN_EXTERNAL) {
interior = false;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir);
gchan_info = pixels[nei_i].g;
//note that when we move this over, there will be no alpha channel.
//gchan_info will be extracted differently!!!
if(gchan_info & GCHAN_RENDERED) {
gchan_info &= ~(GCHAN_RENDERED);
if(gchan_info & GCHAN_EXTERNAL) {
interior = false;
gchan_info = GCHAN_BLOCKED;
}
if(gchan_info & GCHAN_BLOCKED) gchan_info = GCHAN_BLOCKED;
nei_presort[nei_dir] = gchan_info;
}
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
pixels[nei_i] = get_color(i);
pixels[nei_i].g = GCHAN_RENDERED;
if(i == ITERS) nei_presort[nei_dir] = 0;
else {
//exterior
interior = false;
nei_presort[nei_dir] = GCHAN_BLOCKED;
pixels[nei_i].g |= GCHAN_EXTERNAL;
}
}
}
if(interior) {
printf("interior\n");
asm volatile("interior_check:");
pixels[this_index].g = GCHAN_RENDERED | GCHAN_BLOCKED;
//printf("bruh\n");
memcpy(nei_priority, last_nei_priority, sizeof(nei_priority));
nei_priority[last_direction] = -1;
this_index = get_neighbor_index(this_index, (last_direction + 4) % 8);
this_coord = get_neighbor_coord(
this_coord, (last_direction + 4) % 8, scale);
pixels[this_index].g ^= GCHAN_VISITED; //so we don't think we need to backtrack
}
else {
int blocked_cnt = 0;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
int offset_cw = (last_direction - nei_dir) % 8;
int offset_ccw = (nei_dir - last_direction) % 8;
int forward_offset;
switch(nei_presort[nei_dir]) {
case GCHAN_VISITED:
nei_priority[nei_dir] = 15;
break;
case GCHAN_BLOCKED:
case GCHAN_EXTERNAL:
nei_priority[nei_dir] = -1;
blocked_cnt++;
break;
default: //unvisited element
if((nei_presort[(nei_dir - 1) % 8] == 0) ||
(nei_presort[(nei_dir + 1) % 8] == 0)) {
nei_priority[nei_dir] = 3;
break;
}
if((nei_presort[(nei_dir - 1) % 8] == GCHAN_VISITED) ||
(nei_presort[(nei_dir + 1) % 8] == GCHAN_VISITED)) {
nei_priority[nei_dir] = 7;
break;
}
nei_priority[nei_dir] = 11;
break;
}
if(nei_priority[nei_dir] < 0) continue;
forward_offset = abs((offset_cw < offset_ccw) ?
offset_cw : offset_ccw);
if(forward_offset < 3) nei_priority[nei_dir] -= (3-forward_offset);
}
if(blocked_cnt == 8) {
for(int nd = 0; nd < 8; nd++) printf("%i, ", nei_priority[nd]);
printf("we blocked ourselves in!\n");
for(;;) sleep(10);
exit(1);
}
}
for(int priority = 0; priority < 17; priority++) {
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
if(nei_priority[nei_dir] != priority) continue;
if(nei_dir % 2) continue;
printf("(%zu, %zu): dir %i. [", this_index % RES_X, this_index / RES_X, nei_dir);
for(int nd = 0; nd < 8; nd++) printf("%i, ", nei_priority[nd]);
printf("] -> ");
// if(pixels[this_index].g & GCHAN_VISITED) {
if(priority >= 12) {
pixels[this_index].g |= GCHAN_BLOCKED;
printf("backtracking!!!\n");
}
else
pixels[this_index].g |= GCHAN_VISITED;
memcpy(last_nei_priority, nei_priority, sizeof(nei_priority));
last_direction = nei_dir;
this_index = get_neighbor_index(this_index, nei_dir);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
printf("(%zu, %zu)\n", this_index % RES_X, this_index / RES_X);
debug_x = this_index % RES_X;
debug_y = this_index / RES_X;
/**
BeginDrawing();
DrawPixel(debug_x, debug_y,
debug_colors[debug_color % (sizeof(debug_colors) / sizeof(*debug_colors))]);
EndDrawing();
*/
//FOR VISUAL DEBUGGING- read warning on line 0!
{
static bool hit_debug_pix = false;
const float dbg_cam_step = 100;
const float dbg_cam_zoom = .25;
if((debug_x == 1046) && (debug_y == 126)) hit_debug_pix = true;
if(hit_debug_pix) {
for(;;) {
switch(GetKeyPressed()) {
case KEY_UP:
debug_cam.offset.y += dbg_cam_step;
break;
case KEY_DOWN:
debug_cam.offset.y -= dbg_cam_step;
break;
case KEY_RIGHT:
debug_cam.offset.x += dbg_cam_step;
break;
case KEY_LEFT:
debug_cam.offset.x -= dbg_cam_step;
break;
case KEY_W:
debug_cam.zoom += dbg_cam_zoom;
break;
case KEY_S:
debug_cam.zoom -= dbg_cam_zoom;
break;
case KEY_ENTER:
goto switch_pixel;
default:
// BeginDrawing();
BeginDrawing();
const int dbg_clrs = 32;
uint8_t this_dbg_clr =
((debug_color++) % dbg_clrs) * (255 / dbg_clrs);
debug_pix[this_index] =
(Color) {this_dbg_clr, this_dbg_clr, this_dbg_clr, 255};
BeginDrawing();
UpdateTexture(debug_tex, debug_pix);
DrawTextureEx(debug_tex, (Vector2)
{0 - debug_cam.offset.x, debug_cam.offset.y}, 0,
debug_cam.zoom, WHITE);
EndDrawing();
// EndDrawing();
}
}
}
}
goto switch_pixel;
}
}
switch_pixel:
}
debug_color++;
}
on_pixel++;
c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
unsigned int mandelbrot_unoptimized(struct camera *cam, Color *pixels) {
FixedCord scale = { .r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X), .i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y) };
FixedCord c = { .r = 0, .i = DOUBLE_TO_FIXED(cam->max_i) };
unsigned int total_iters = 0;
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
total_iters += i;
pixels[((y * RES_X) + x)] = get_color(i);
c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
void test() {
uint8_t bitarray[(160*80)/8] = {0};
int test_i = 9;
BITARRAY_SET(bitarray, test_i);
printf("%s\n", BITARRAY_CHECK(bitarray, 9) ? "true" : "false");
}
int main() {
//test();
//return 0;
Color *pixels = malloc(RES_X * RES_Y * sizeof(Color));
struct camera cam = {
.min_r = -1,
.max_r = 1,
// .min_i = -1,
// .max_i = 1
};
cam.min_i = ((double)RES_Y / RES_X) * cam.min_r;
cam.max_i = ((double)RES_Y / RES_X) * cam.max_r;
InitWindow(WINDOW_SIZE_X, WINDOW_SIZE_Y, "mandelbrot fixed point test");
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture tex = LoadTextureFromImage(img);
Texture backdrop = LoadTextureFromImage(img);
UnloadImage(img);
SetTargetFPS(60);
while(!WindowShouldClose()) {
switch(GetKeyPressed()) {
case KEY_UP:
shift_cam(&cam, 0, STEP_SIZE);
break;
case KEY_DOWN:
shift_cam(&cam, 0, -STEP_SIZE);
break;
case KEY_RIGHT:
shift_cam(&cam, STEP_SIZE, 0);
break;
case KEY_LEFT:
shift_cam(&cam, -STEP_SIZE, 0);
break;
case KEY_W:
zoom_cam(&cam, ZOOM_SIZE);
break;
case KEY_S:
zoom_cam(&cam, -ZOOM_SIZE);
break;
default:
BeginDrawing();
EndDrawing();
continue;
break;
}
printf("(%.21f, %.21f) - (%.21f, %.21f)\n", cam.min_r, cam.min_i, cam.max_r, cam.max_i);
printf("Unoptimized: %u iterations\n", mandelbrot_unoptimized(&cam, pixels));
BeginDrawing();
UpdateTexture(backdrop, pixels);
DrawTextureEx(backdrop, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
/**
printf("Border tracing: %u iterations\n", mandelbrot_bordertrace(&cam, pixels));
BeginDrawing();
UpdateTexture(tex, pixels);
DrawTextureEx(tex, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
**/
}
return 0;
}

View File

@ -0,0 +1,561 @@
/** READ BEFORE JUDING!
* Yes, I know this code is a mess. Debug code is added
* happhazardly, two cameras are used, etc.
* That's because it's a temporary program
* to create optimizations and debug rendering issues without hardware.
* None of this is going to be included in the project, and the code is thus
* not extensible or organized; it really doesn't save any effort to do so.
*
* This code is meant for my eyes only. You've been warned!
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <raylib.h>
#include <raymath.h>
#include <limits.h>
#include <complex.h>
#include <string.h>
#include <unistd.h>
#define WINDOW_SIZE_X 1600
#define WINDOW_SIZE_Y 800
#define RES_X 1600
#define RES_Y 800
#define DEFAULT_CENTER_X 0
#define DEFAULT_CENTER_Y 0
#define MOUSE_BUTTON 0
#define STEP_SIZE .1
#define ZOOM_SIZE .1
#define DECIMAL_LOC 28
#define DOUBLE_SCALER (1 << DECIMAL_LOC)
#define DOUBLE_TO_FIXED(val) (int32_t)((val) * DOUBLE_SCALER)
#define FIXED_MULTIPLY(x,y) ((((uint64_t)(x))*(y)) >> DECIMAL_LOC)
#define FIXED_TO_DOUBLE(val) ((val) / (double)DOUBLE_SCALER)
#define INFTY 2
#define INFTY_SQR INFTY * INFTY
#define ITERS 255
#define INFTY_SQR_FIXED DOUBLE_TO_FIXED(INFTY_SQR)
//#define SHIP
//#undef SHIP
int debug_x, debug_y;
#ifdef SHIP
Color get_color(int i) {
if(i == ITERS) return (Color){0, 0, 0, 255};
if(i == 0) return (Color){0, 0, 0, 255};
return (Color) {
2*(i - 128)+255,
0,
0,
255
};
}
#else
Color get_color(int i) {
// if((i == ITERS) || (i == 0)) return (Color){0, 0, 0, 255};
if(i == ITERS) return (Color){0,0,0,255};
if(i == 0) return (Color){0,0,1,255};
if(i < 128) {
return (Color) {
(8*(i - 128)+255) & 0xff,
0,
(16*(i - 64)+255) & 0xff,
255
};
}
return (Color) {
0,
0,
((unsigned int)-2*(i - 128)+255) & 0xff,
255
};
}
#endif
//TODO remove
struct debug_info {
int32_t r, i;
int x, y;
};
__attribute__((used)) struct debug_info debug_get_coord(size_t i) {
struct debug_info ret;
ret.x = i % RES_X;
ret.y = i / RES_Y;
return ret;
}
struct camera {
double min_r, min_i, max_r, max_i;
};
typedef struct {
int32_t r; int32_t i;
} FixedCord;
static inline int iterate(FixedCord c) {
int32_t z_i = 0;
int32_t z_r = 0;
int32_t z_r_2, z_i_2, zn_r, zn_i;
for(int it = 0; it < ITERS; it++) {
z_r_2 = FIXED_MULTIPLY(z_r, z_r);
z_i_2 = FIXED_MULTIPLY(z_i, z_i);
zn_r = z_r_2 - z_i_2 + c.r;
#ifdef SHIP
zn_i = abs(FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#else
zn_i = (FIXED_MULTIPLY((DOUBLE_TO_FIXED(2)), (FIXED_MULTIPLY(z_r, z_i)))) + c.i;
#endif
z_i = zn_i;
z_r = zn_r;
if(z_i_2 + z_r_2 > INFTY_SQR_FIXED) return it;
}
return ITERS;
}
//blllluuuuurg, matracies and vectors in raylib are floats and we need doubles
void shift_cam(struct camera *cam, double step_r, double step_i) {
double i_offset = (cam->max_i - cam->min_i) * step_i;
double r_offset = (cam->max_r - cam->min_r) * step_r;
cam->min_i += i_offset;
cam->max_i += i_offset;
cam->min_r += r_offset;
cam->max_r += r_offset;
}
void zoom_cam(struct camera *cam, double zoom) {
double i_scale = (cam->max_i - cam->min_i) * zoom;
double r_scale = (cam->max_r - cam->min_r) * zoom;
cam->min_i += i_scale;
cam->max_i -= i_scale;
cam->min_r += r_scale;
cam->max_r -= r_scale;
}
enum DIRECTIONS {
N, NE, E, SE, S, SW, W, NW
};
//we can inline these if needed
inline bool bitarray_check(uint8_t *array, size_t i) {
return array[i/8] & (1 << (i%8));
}
inline void bitarray_set(uint8_t *array, size_t i) {
array[i/8] |= (1 << (i%8));
}
inline FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step) {
if((direction == NW) || (direction < E)) from_coord.i += step.i;
if((direction > N) && (direction < S)) from_coord.r += step.r;
if((direction > E) && (direction < W)) from_coord.i -= step.i;
if(direction > S) from_coord.r -= step.r;
return from_coord;
}
FixedCord get_neighbor_coord(FixedCord from_coord, int direction, FixedCord step);
size_t get_neighbor_index(size_t from_pixel, int direction) {
const int neighbor_index_accl[8] =
{-RES_X, -RES_X + 1, 1, RES_X + 1, RES_X, RES_X - 1, -1, -RES_X - 1};
from_pixel += neighbor_index_accl[direction];
//canidate for optimization; lots of branches. maybe inline
return from_pixel;
}
bool bitarray_check(uint8_t *array, size_t i);
void bitarray_set(uint8_t *array, size_t i);
#define BITARRAY_SET(array, i) ((array)[(i)/8] |= (1 << ((i) % 8)))
#define BITARRAY_CLEAR(array, i) ((array)[(i)/8] &= ~(1 << ((i) % 8)))
#define BITARRAY_CHECK(array, i) ((array)[(i)/8] & (1 << ((i) % 8)))
//we'll be storing info in the green channel to utalize available memory
//per pixel.
#define GCHAN_BLOCKED (1 << 0) //interior element or visiteed
#define GCHAN_INTERNAL (1 << 1) //part of set
#define GCHAN_EXTERNAL (1 << 2) //not part of set
#define GCHAN_DEBUG (1 << 3) //extra, not nessesary
#define BACKSTACK_SIZE 32
/**
void switch_pixel(coord &this_coord, const coord step, size_t this_index, int dir) {
}
**/
void debug_step(Color *pix, Texture *tex, size_t index) {
static Camera2D cam = {0};
if(!cam.zoom) cam.zoom = (float)GetRenderWidth()/RES_X;
static int debug_color = 0;
const Color debug_colors[] =
{ (Color) {0xff, 0x00, 0x00, 0xff},
(Color) {0xff, 0x00, 0xff, 0xff},
(Color) {0x00, 0xff, 0x00, 0xff},
(Color) {0x00, 0x00, 0xff, 0xff},
(Color) {0x6a, 0x00, 0xff, 0xff}
};
const float dbg_cam_step = 100;
const float dbg_cam_zoom = .25;
for(;;) {
switch(GetKeyPressed()) {
case KEY_UP:
cam.offset.y += dbg_cam_step;
break;
case KEY_DOWN:
cam.offset.y -= dbg_cam_step;
break;
case KEY_RIGHT:
cam.offset.x += dbg_cam_step;
break;
case KEY_LEFT:
cam.offset.x -= dbg_cam_step;
break;
case KEY_W:
cam.zoom += dbg_cam_zoom;
break;
case KEY_S:
cam.zoom -= dbg_cam_zoom;
break;
case KEY_ENTER:
return;
default:
BeginDrawing();
const int dbg_clrs = 32;
uint8_t this_dbg_clr =
((debug_color++) % dbg_clrs) * (255 / dbg_clrs);
pix[index] =
(Color) {this_dbg_clr, this_dbg_clr, this_dbg_clr, 255};
BeginDrawing();
UpdateTexture(*tex, pix);
DrawTextureEx(*tex, (Vector2)
{0 - cam.offset.x, cam.offset.y}, 0,
cam.zoom, WHITE);
EndDrawing();
}
}
}
unsigned int mandelbrot_bordertrace(struct camera *cam, Color *pixels) {
//these lookup tables r cheap cuz on the stm32f1, 1 memory read is 1 instruction
FixedCord scale = {
.r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X),
.i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y)};
FixedCord c = {.r = 0, .i = DOUBLE_TO_FIXED(cam->max_i)};
unsigned int total_iters = 0;
size_t on_pixel = 0;
//for camera border calculations
int32_t cam_bord_fixed_n = DOUBLE_TO_FIXED(cam->min_i);
int32_t cam_bord_fixed_s = DOUBLE_TO_FIXED(cam->max_i);
int32_t cam_bord_fixed_e = DOUBLE_TO_FIXED(cam->max_r);
int32_t cam_bord_fixed_w = DOUBLE_TO_FIXED(cam->min_r);
//I know this is gross, just for debugigng!
//will clean up once I get things ironed out
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture debug_tex = LoadTextureFromImage(img);
UnloadImage(img);
Color *debug_pix = malloc(RES_X * RES_Y * sizeof(Color));
memcpy(debug_pix, pixels, RES_X * RES_Y * sizeof(Color));
/**
//for keeping track of border only. will organize later
uint8_t set[(160*80)/8] = {0};
uint8_t unset[(160*80)/8] = {0};
**/
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
total_iters += i;
pixels[on_pixel] = get_color(i);
if(i == ITERS) {
FixedCord this_coord = c;
size_t this_index = on_pixel;
int nei_priority[8];
int last_nei_priority[8];
int last_direction = E;
int nei_presort[8];
size_t backstack[BACKSTACK_SIZE];
size_t backstack_i = 0;
//only really need to zero green channel
bzero(pixels, RES_X * RES_Y * sizeof(*pixels));
//this is so fucking knarly
printf("NEW BORDER\n");
while(true) {
//step 1: check pixels around us, fill in neighbors.
bzero(nei_presort, sizeof(nei_presort));
//find if we're pushed against screen border.
//feels gross but I don't think there's a better way
if((this_coord.i - scale.i) < cam_bord_fixed_n) {
for(int nei_dir = SE; nei_dir <= SW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.i + scale.i) > cam_bord_fixed_s) {
nei_presort[NE] = GCHAN_EXTERNAL;
nei_presort[N] = GCHAN_EXTERNAL;
nei_presort[NW] = GCHAN_EXTERNAL;
}
if((this_coord.r - scale.r) < cam_bord_fixed_w) {
for(int nei_dir = SW; nei_dir < NW; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
else if((this_coord.r + scale.r) > cam_bord_fixed_e) {
for(int nei_dir = NE; nei_dir < SE; nei_dir++)
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
/** now fill in neighbor info based on green channel,
* iterate if no info available.
* if this is to slow we could flatten this; it's predictable
* where there will be info
**/
// TODO replace modulos with something faster
bool interior = true;
for(int nei_dir = 0; nei_dir < 8; nei_dir++) {
size_t nei_i;
uint8_t gchan_info;
//happens if we're pushed against the screen
if(nei_presort[nei_dir] == GCHAN_EXTERNAL) {
interior = false;
nei_presort[nei_dir] = GCHAN_EXTERNAL;
continue;
}
nei_i = get_neighbor_index(this_index, nei_dir);
gchan_info = pixels[nei_i].g;
//note that when we move this over, there will be no alpha channel.
//gchan_info will be extracted differently!!!
if(gchan_info) {
if(gchan_info & GCHAN_EXTERNAL) interior = false;
nei_presort[nei_dir] = gchan_info;
}
else {
int i = iterate(get_neighbor_coord(this_coord, nei_dir, scale));
pixels[nei_i] = get_color(i);
if(i == ITERS) nei_presort[nei_dir] = GCHAN_INTERNAL;
else {
//exterior
interior = false;
nei_presort[nei_dir] = GCHAN_EXTERNAL;
}
pixels[nei_i].g = nei_presort[nei_dir];
}
}
//go back if we're in the interior and not an edge
if(interior) {
printf("interior\n");
asm volatile("interior_check:");
pixels[this_index].g = GCHAN_BLOCKED;
//printf("bruh\n");
memcpy(nei_priority, last_nei_priority, sizeof(nei_priority));
nei_priority[last_direction] = -1;
this_index = get_neighbor_index(this_index, (last_direction + 4) % 8);
this_coord = get_neighbor_coord(
this_coord, (last_direction + 4) % 8, scale);
pixels[this_index].g = GCHAN_BLOCKED; //so we don't think we need to backtrack
}
else {
int edge_cnt = 0;
//sort into prioraties
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
int nei_1 = nei_presort[(nei_dir + 1) % 8];
int nei_2 = nei_presort[(nei_dir - 1) % 8];
if((nei_presort[nei_dir] != GCHAN_INTERNAL) || ((nei_1 & nei_2) & (GCHAN_EXTERNAL | GCHAN_BLOCKED))) {
nei_priority[nei_dir] = -1;
}
else if(((nei_1 ^ nei_2) & (GCHAN_INTERNAL | GCHAN_EXTERNAL)) == (GCHAN_INTERNAL | GCHAN_EXTERNAL)) {
edge_cnt++;
nei_priority[nei_dir] = 0;
}
else if(nei_1 & nei_2 & GCHAN_INTERNAL) {
nei_priority[nei_dir] = 1;
}
else if(((nei_1 ^ nei_2) & (GCHAN_BLOCKED | GCHAN_EXTERNAL)) == (GCHAN_BLOCKED | GCHAN_EXTERNAL)) {
nei_priority[nei_dir] = 2;
}
}
if(edge_cnt >= 2) {
backstack[backstack_i] = this_index;
if(backstack_i++ > BACKSTACK_SIZE) {
printf("max backstack\n");
for(;;);
}
printf("backstack increased\n");
}
}
//now go to canidate with lowest prioraty
for(int priority = 0; priority <= 1; priority++) {
for(int nei_dir = 0; nei_dir < 8; nei_dir += 2) {
if(nei_priority[nei_dir] != priority) continue;
printf("(%zu, %zu): dir %i. [", this_index % RES_X, this_index / RES_X, nei_dir);
for(int nd = 0; nd < 8; nd++) printf("%i, ", nei_priority[nd]);
printf("] -> ");
pixels[this_index].g = GCHAN_BLOCKED;
memcpy(last_nei_priority, nei_priority, sizeof(nei_priority));
this_index = get_neighbor_index(this_index, nei_dir);
this_coord = get_neighbor_coord(this_coord, nei_dir, scale);
printf("(%zu, %zu)\n", this_index % RES_X, this_index / RES_X);
debug_x = this_index % RES_X;
debug_y = this_index / RES_X;
//FOR VISUAL DEBUGGING- read warning on line 0!
{
static bool hit_debug_pix = true;
if((debug_x == 1046) && (debug_y == 126)) hit_debug_pix = true;
if(hit_debug_pix) debug_step(debug_pix, &debug_tex, this_index);
}
goto next_pixel;
}
}
printf("checking backtrack stack\nThis pri:");
for(int nd = 0; nd < 8; nd++) printf("%i, ", nei_priority[nd]);
printf("\n");
if(--backstack_i > BACKSTACK_SIZE) {
printf("backstack depleated, no recovery\n");
for(;;);
}
printf("%lu\n", backstack_i);
this_index = backstack[backstack_i];
this_coord.r = (((this_index % RES_X) / (float)RES_X) * (cam->max_r - cam->min_r)) + cam->min_r;
this_coord.i = (((this_index / RES_X) / (float)RES_Y) * (cam->max_i - cam->min_i)) + cam->min_i;
debug_step(debug_pix, &debug_tex, this_index);
next_pixel:
}
}
on_pixel++;
c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
unsigned int mandelbrot_unoptimized(struct camera *cam, Color *pixels) {
FixedCord scale = { .r = DOUBLE_TO_FIXED((cam->max_r - cam->min_r) / (double)RES_X), .i = DOUBLE_TO_FIXED((cam->max_i - cam->min_i) / (double)RES_Y) };
FixedCord c = { .r = 0, .i = DOUBLE_TO_FIXED(cam->max_i) };
unsigned int total_iters = 0;
for(int y = 0; y < RES_Y; y++) {
c.r = DOUBLE_TO_FIXED(cam->min_r);
for(int x = 0; x < RES_X; x++) {
int i = iterate(c);
total_iters += i;
pixels[((y * RES_X) + x)] = get_color(i);
c.r += scale.r;
}
c.i -= scale.i;
}
return total_iters;
}
void test() {
uint8_t bitarray[(160*80)/8] = {0};
int test_i = 9;
BITARRAY_SET(bitarray, test_i);
printf("%s\n", BITARRAY_CHECK(bitarray, 9) ? "true" : "false");
}
int main() {
//test();
//return 0;
Color *pixels = malloc(RES_X * RES_Y * sizeof(Color));
struct camera cam = {
.min_r = -1,
.max_r = 1,
// .min_i = -1,
// .max_i = 1
};
cam.min_i = ((double)RES_Y / RES_X) * cam.min_r;
cam.max_i = ((double)RES_Y / RES_X) * cam.max_r;
InitWindow(WINDOW_SIZE_X, WINDOW_SIZE_Y, "mandelbrot fixed point test");
Image img = GenImageColor(RES_X, RES_Y, BLUE);
Texture tex = LoadTextureFromImage(img);
Texture backdrop = LoadTextureFromImage(img);
UnloadImage(img);
SetTargetFPS(60);
while(!WindowShouldClose()) {
switch(GetKeyPressed()) {
case KEY_UP:
shift_cam(&cam, 0, STEP_SIZE);
break;
case KEY_DOWN:
shift_cam(&cam, 0, -STEP_SIZE);
break;
case KEY_RIGHT:
shift_cam(&cam, STEP_SIZE, 0);
break;
case KEY_LEFT:
shift_cam(&cam, -STEP_SIZE, 0);
break;
case KEY_W:
zoom_cam(&cam, ZOOM_SIZE);
break;
case KEY_S:
zoom_cam(&cam, -ZOOM_SIZE);
break;
default:
BeginDrawing();
EndDrawing();
continue;
break;
}
printf("(%.21f, %.21f) - (%.21f, %.21f)\n", cam.min_r, cam.min_i, cam.max_r, cam.max_i);
printf("Unoptimized: %u iterations\n", mandelbrot_unoptimized(&cam, pixels));
BeginDrawing();
UpdateTexture(backdrop, pixels);
DrawTextureEx(backdrop, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
printf("Border tracing: %u iterations\n", mandelbrot_bordertrace(&cam, pixels));
BeginDrawing();
UpdateTexture(tex, pixels);
DrawTextureEx(tex, (Vector2){0,0}, 0, (float)GetRenderWidth()/RES_X, WHITE);
EndDrawing();
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More