For a game in Gameboy programming, I am using 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 struct made of two Struct Points, the top-left and the bottom right corner points.
The idea of the game is to have random-heighted blocks top-down from the ceiling and bottom-up from the floor. It is similar to the copter-classic game. In my infinite while loop, I shift all of the rectangles down 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 the rectangle.
with this code, the code should display the rectangles like this: (drew this up in paint)

But the result I get is

What is odd is that if I don't draw the bottom row at all, then the top row draws fine. The result only messes up when I draw both. This is really weird because I think that the code should be working fine, and the code is not very complicated. Is there a specific reason this is happening, and is there a way to remedy this?
Thanks.
The code that I use to draw the 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;
}
}
                Here's a debugging SSCCE  (Short, Self-Contained, Correct Example) based on your code.  There are assertions in this code that fire; it runs, but is known not to be correct.  I've renamed bottom to btm and oldBottom to oldBtm so that the names are symmetric; it makes the code layout more systematic (but is otherwise immaterial).
#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 a late 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 the size i instead of size.  This probably accounts for array overwriting issues you see.
There's a second problem though; the assertions in the loop in the middle fire:
 (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 'not negative' checks should be revised to:
            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 going negative. However, it is perfectly plausible that you should simply be checking on the bottom-right x-coordinate (instead of the top-left coordinate) using the original block. Or the wraparound may need to be more complex altogether. That's for you to decipher. But I think that the odd displays occur because you were providing negative values where you didn't intend to and weren't supposed to.
The key points to note here are:
size == 2).I had various versions of the drawRect() function before I got to the design shown, which works well on a wide screen (eg 120x65) terminal window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With