Using Two Arrays in C / Gameboy Programming

For a game in Gameboy programming, I use four arrays called top , oldTop , bottom and oldBottom :

 struct Point { int x, y; }; struct Rect { struct Point xx, yy; }; Rect top[size], oldTop[size]; Rect bottom[size], oldBottom[i]; 

where Rect is a structure consisting of two Struct points, upper left and lower corner points.

The idea of ​​the game is to have chaotic blocks from top to bottom from the ceiling and from bottom to top from the floor. It looks like a classic game. In my infinite while loop, I shift all the rectangles by one pixel using the following code

 while (1) { for (int i = 0; i < size; i++) { //in Struct Rect, xx is the top-left corner point, and yy is the bottom right top[i].xx.x--; top[i].yy.x--; bottom[i].xx.x--; bottom[i].yy.x--; if (top[i].xx.x < 0) { top[i].xx.x += 240; top[i].yy.x += 240; } if (bottom[i].xx.x < 0) { bottom[i].xx.x += 240; bottom[i].yy.x += 240; } } for (int i = 0; i < size; i++) { drawRect(oldTop[i], colorBlack); drawRect(oldBottom[i], colorBlack); } /*call delay function that wait for Vertical Blank*/ for(int i = 0; i < size; i++) { drawRect(top[i], colorGreen); drawRect(bottom[i], colorGreen); oldTop[i] = top[i]; oldBottom[i] = bottom[i]; } } 

The drawRect method uses DMA to draw a rectangle.

with this code, the code should display the rectangles as follows: (painted it in paint) enter image description here

But the result I get

enter image description here

Odd is that if I don't draw the bottom line at all, the top line draws fine. The result only gets confused when I draw both. This is really strange, because I think the code should work fine, and the code is not very complicated. Is there a specific reason this is happening, and is there a way to fix this?

Thanks.

The code I use to draw a rectangle looks like this:

 void drawRect(int row, int col, int width, int height){ int i; for (i=0; i<height; i++) { DMA[3].src = &color; DMA[3].dst = videoBuffer + (row+r)*240 + col); DMA[3].cnt = DMA_ON | DMA_FIXED_SOURCE | width; } } 
+4
source share
1 answer

Here's the debugging SSCCE ( Short, Self-Contained, Correct Example ) based on your code. There are statements in this code that work; It works, but, as you know, is not correct. I renamed bottom to btm and oldBottom to oldBtm so that the names are symmetric; this makes the code layout more systematic (but otherwise not inconsequential).

 #include <assert.h> #include <stdio.h> typedef struct Point { int x, y; } Point; typedef struct Rect { struct Point xx, yy; } Rect; enum { size = 2 }; typedef enum { colourGreen = 0, colourBlack = 1 } Colour; /*ARGSUSED*/ static void drawRect(Rect r, Colour c) { printf(" (%3d)(%3d)", r.xx.x, r.yy.x); } int main(void) { Rect top[size], oldTop[size]; Rect btm[size], oldBtm[size]; int counter = 0; for (int i = 0; i < size; i++) { top[i].xx.x = 240 - 4 * i; top[i].xx.y = 0 + 10 + i; top[i].yy.x = 240 - 14 * i; top[i].yy.y = 0 + 20 + i; btm[i].xx.x = 0 + 72 * i; btm[i].xx.y = 0 + 10 * i; btm[i].yy.x = 0 + 12 * i; btm[i].yy.y = 0 + 20 * i; oldTop[i] = top[i]; oldBtm[i] = btm[i]; } while (1) { if (counter++ > 480) // Limit amount of output! break; for (int i = 0; i < size; i++) { //in Struct Rect, xx is the top-left corner point, and yy is the bottom right top[i].xx.x--; top[i].yy.x--; btm[i].xx.x--; btm[i].yy.x--; if (top[i].xx.x < 0) { top[i].xx.x += 240; top[i].yy.x += 240; } if (btm[i].xx.x < 0) { btm[i].xx.x += 240; btm[i].yy.x += 240; } } for (int i = 0; i < size; i++) { assert(top[i].xx.x >= 0 && top[i].yy.x >= 0); assert(btm[i].xx.x >= 0 && btm[i].yy.x >= 0); } for (int i = 0; i < size; i++) { drawRect(oldTop[i], colourBlack); drawRect(oldBtm[i], colourBlack); } /*call delay function that wait for Vertical Blank*/ for(int i = 0; i < size; i++) { drawRect(top[i], colourGreen); drawRect(btm[i], colourGreen); oldTop[i] = top[i]; oldBtm[i] = btm[i]; } putchar('\n'); } return(0); } 

As noted in the last comment, one big difference between this and your code is that oldBottom in your code is declared as:

 Rect top[size], oldTop[size]; Rect bottom[size], oldBottom[i]; 

using size i instead of size . This probably causes problems with rewriting the arrays you see.

However, there is a second problem; statements in the medium fire loop:

  (240)(240) ( 0)( 0) (236)(226) ( 72)( 12) (239)(239) (239)(239) (235)(225) ( 71)( 11) (239)(239) (239)(239) (235)(225) ( 71)( 11) (238)(238) (238)(238) (234)(224) ( 70)( 10) (238)(238) (238)(238) (234)(224) ( 70)( 10) (237)(237) (237)(237) (233)(223) ( 69)( 9) (237)(237) (237)(237) (233)(223) ( 69)( 9) (236)(236) (236)(236) (232)(222) ( 68)( 8) (236)(236) (236)(236) (232)(222) ( 68)( 8) (235)(235) (235)(235) (231)(221) ( 67)( 7) (235)(235) (235)(235) (231)(221) ( 67)( 7) (234)(234) (234)(234) (230)(220) ( 66)( 6) (234)(234) (234)(234) (230)(220) ( 66)( 6) (233)(233) (233)(233) (229)(219) ( 65)( 5) (233)(233) (233)(233) (229)(219) ( 65)( 5) (232)(232) (232)(232) (228)(218) ( 64)( 4) (232)(232) (232)(232) (228)(218) ( 64)( 4) (231)(231) (231)(231) (227)(217) ( 63)( 3) (231)(231) (231)(231) (227)(217) ( 63)( 3) (230)(230) (230)(230) (226)(216) ( 62)( 2) (230)(230) (230)(230) (226)(216) ( 62)( 2) (229)(229) (229)(229) (225)(215) ( 61)( 1) (229)(229) (229)(229) (225)(215) ( 61)( 1) (228)(228) (228)(228) (224)(214) ( 60)( 0) Assertion failed: (btm[i].xx.x >= 0 && btm[i].yy.x >= 0), function main, file video.c, line 63. 

I think your "negative" checks should be reviewed:

  if (top[i].xx.x < 0) top[i].xx.x += 240; if (top[i].yy.x < 0) top[i].yy.x += 240; if (btm[i].xx.x < 0) btm[i].xx.x += 240; if (btm[i].yy.x < 0) btm[i].yy.x += 240; 

This stops anything negative. However, it is entirely plausible that you should just check the lower right x coordinate (instead of the left left coordinate) using the source block. Or a more complicated flow may be required. This is for you to decrypt. But I think that the odd displays are due to the fact that you provide negative values ​​where you did not intend and should not.

The key points here are:

  • When you are debugging an algorithm, you do not need to use the usual display mechanisms.
  • When you are debugging, reduce the size of the loops where you can ( size == 2 ).
  • Printing only the relevant information (here x-coordinates) helped to reduce the output.
  • Putting counter code to limit the amount of output is simplified.
  • If everything goes wrong, find patterns in what happens wrong before.

I had various versions of the drawRect() function before I got to the shown design, which works well on a widescreen (e.g. 120x65) terminal window.

+2
source

All Articles