summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-04-16 17:09:54 +0200
committerBad Diode <bd@badd10de.dev>2021-04-16 17:09:54 +0200
commit0cd630609ea14432751cf015467af181340c61ca (patch)
tree79a57f05c7dca4ac972d02e4be9a276b298854bf
parent21aaf2e5f1720f9b6d227d29859b035c3367e9d7 (diff)
downloadgba-experiments-0cd630609ea14432751cf015467af181340c61ca.tar.gz
gba-experiments-0cd630609ea14432751cf015467af181340c61ca.zip
Update draw_line to fix offset error
-rw-r--r--src/main.c42
1 files changed, 16 insertions, 26 deletions
diff --git a/src/main.c b/src/main.c
index b86a830..6dcbf64 100644
--- a/src/main.c
+++ b/src/main.c
@@ -102,17 +102,15 @@ put_text(int x, int y, Color clr, char *msg) {
102// Bresenham's line drawing algorithm using exclusively integer arithmetic. 102// Bresenham's line drawing algorithm using exclusively integer arithmetic.
103static void 103static void
104draw_line(int x0, int y0, int x1, int y1, Color clr) { 104draw_line(int x0, int y0, int x1, int y1, Color clr) {
105 // The line length in color units.
106 int pitch = SCREEN_WIDTH;
107
108 // Pointer to the initial position of the screen buffer where we will start 105 // Pointer to the initial position of the screen buffer where we will start
109 // writing our data. We need to multiply by 2 because in mode 3 we have 106 // writing our data.
110 // 2 bytes per pixel. 107 vu16 *destination = (u16*)(SCREEN_BUFFER + y0 * SCREEN_WIDTH + x0);
111 vu16 *destination = (u16*)(SCREEN_BUFFER + y0 * pitch * 2 + x0 * 2);
112 108
113 // Adjust the step direction and calculate deltas. 109 // Adjust the step direction and calculate deltas.
114 int x_step; 110 int x_step;
111 int y_step;
115 int dx; 112 int dx;
113 int dy;
116 if (x0 > x1) { 114 if (x0 > x1) {
117 x_step = -1; 115 x_step = -1;
118 dx = x0 - x1; 116 dx = x0 - x1;
@@ -120,20 +118,14 @@ draw_line(int x0, int y0, int x1, int y1, Color clr) {
120 x_step = 1; 118 x_step = 1;
121 dx = x1 - x0; 119 dx = x1 - x0;
122 } 120 }
123 int y_step;
124 int dy;
125 if (y0 > y1) { 121 if (y0 > y1) {
126 y_step = -pitch; 122 y_step = -SCREEN_WIDTH;
127 dy = y0 - y1; 123 dy = y0 - y1;
128 } else { 124 } else {
129 y_step = +pitch; 125 y_step = +SCREEN_WIDTH;
130 dy = y1 - y0; 126 dy = y1 - y0;
131 } 127 }
132 128
133 // Precalculate 2 * deltas for x and y.
134 int ddx = dx + dx;
135 int ddy = dy + dy;
136
137 if(dy == 0) { 129 if(dy == 0) {
138 // Horizontal line. 130 // Horizontal line.
139 for(int i = 0; i <= dx; i++) { 131 for(int i = 0; i <= dx; i++) {
@@ -146,27 +138,27 @@ draw_line(int x0, int y0, int x1, int y1, Color clr) {
146 } 138 }
147 } else if (dx >= dy){ 139 } else if (dx >= dy){
148 // Positive slope. 140 // Positive slope.
149 int diff = ddy - dx; 141 int diff = 2 * dy - dx;
150 for (int i = 0; i <= dx; ++i) { 142 for (int i = 0; i <= dx; ++i) {
151 *destination = clr; 143 *destination = clr;
152 if (diff >= 0) { 144 if (diff >= 0) {
153 destination += y_step; 145 destination += y_step;
154 diff -= ddx; 146 diff -= 2 * dx;
155 } 147 }
156 destination += x_step; 148 destination += x_step;
157 diff += ddy; 149 diff += 2 * dy;
158 } 150 }
159 } else { 151 } else {
160 // Negative slope. 152 // Negative slope.
161 int diff = ddx - dy; 153 int diff = 2 * dx - dy;
162 for (int i = 0; i <= dy; ++i) { 154 for (int i = 0; i <= dy; ++i) {
163 *destination = clr; 155 *destination = clr;
164 if (diff >= 0) { 156 if (diff >= 0) {
165 destination += x_step; 157 destination += x_step;
166 diff -= ddy; 158 diff -= 2 * dy;
167 } 159 }
168 destination += y_step; 160 destination += y_step;
169 diff += ddx; 161 diff += 2 * dx;
170 } 162 }
171 } 163 }
172} 164}
@@ -316,10 +308,10 @@ int main(void) {
316 draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY); 308 draw_fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, COLOR_GREY);
317 309
318 int side = 60; 310 int side = 60;
319 int x = 88;
320 int y = 70;
321 int line = 35; 311 int line = 35;
322 int height = sqrt(side * side - (side / 2) * (side / 2)); 312 int height = side * 0.5;
313 int x = SCREEN_WIDTH / 2 - height / 2;
314 int y = SCREEN_HEIGHT / 2;
323 315
324 // Draw red triangle. 316 // Draw red triangle.
325 draw_line(x + height - 1, y - side / 2, x, y - 1, COLOR_RED); 317 draw_line(x + height - 1, y - side / 2, x, y - 1, COLOR_RED);
@@ -335,8 +327,6 @@ int main(void) {
335 // Draw white line at triangle tip. 327 // Draw white line at triangle tip.
336 draw_line(x + height, y - side / 2, x + height, y + side / 2, COLOR_WHITE); 328 draw_line(x + height, y - side / 2, x + height, y + side / 2, COLOR_WHITE);
337 draw_line(x + height + 1, y - side / 2, x + height + 1, y + side / 2, COLOR_WHITE); 329 draw_line(x + height + 1, y - side / 2, x + height + 1, y + side / 2, COLOR_WHITE);
338 draw_line(x + height + 2, y - side / 2, x + height + 2, y + side / 2, COLOR_WHITE);
339 // draw_line(x + height + 3, y - side / 2, x + height + 3, y + side / 2, COLOR_WHITE);
340 330
341 // Double triangle line. 331 // Double triangle line.
342 draw_line(x - 1, y - side / 2, x - 1, y + side / 2, COLOR_WHITE); 332 draw_line(x - 1, y - side / 2, x - 1, y + side / 2, COLOR_WHITE);
@@ -349,7 +339,7 @@ int main(void) {
349 draw_line(x - line, y + 1, x, y + 1, COLOR_WHITE); 339 draw_line(x - line, y + 1, x, y + 1, COLOR_WHITE);
350 draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE); 340 draw_line(x + height, y + 1, x + height + line, y + 1, COLOR_WHITE);
351 341
352 put_text(77, 125, COLOR_RED, "0xbadd10de"); 342 put_text(SCREEN_WIDTH / 2 - 8 * 10 / 2, 125, COLOR_RED, "0xbadd10de");
353 343
354 int frame_counter = 0; 344 int frame_counter = 0;
355 while(true) { 345 while(true) {