Archived

This topic is now archived and is closed to further replies.

tppramod

Sprites background in array clash on recall

Recommended Posts

This is an extract from my main game program. For the matter of simplicity i have created a sample program. There are two sprites namely Sprite_Red and Sprite_Yellow. 'Sprite_Red' moves over a Yellow Stick and 'Sprite_Yellow' moves over a Red Stick from top to bottom and vice versa, without disturbing the background. Things are OK as long as I enable only one Sprite lets say 'Sprite_Red' or `Sprite_Yellow'. On enabling both the sprites, the background image of both the sprites in the array clashes. Both the sprites are using different array for storing their respective backgrounds. i don't know why the arrays are clashing even though i am using different arrays. in no way i am able to understand what is wrong in my program. I am using Turbo C 3.0 DOS compiler. Pls. compile this and see the sample first. The main functions are: 1. Backg_Image_Capture() - Capture the background for both sprites. 2. DrawSprites() - Draws both sprites. 3. EraseSprites() - Erases both sprites using the background captured. I have commented `Sprite_Yellow' portions in the above three functions by default so that `Sprite_Red' works. I am listing below the full source code. pls. help as early as possible because i cannot go ahead unless i fix this bug.vishnu100 #include <stdlib.h> #include <conio.h> #include <alloc.h> #include <memory.h> #include <dos.h> #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 200 #define SCREEN_SEGMENT 0xA000 #define IMAGE_WIDTH 14 #define IMAGE_HEIGHT 14 #define INPUT_STATUS 0x03da #define VRETRACE 0x08 #define NUM_GHOSTS 1 char Sprite_Red[] = { 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,12,12,12,12,12, }; char Sprite_Yellow[] = { 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14, }; //for storing the backgrounds. char Sprite_Red_Backg_Array[196]; char Sprite_Yellow_Backg_Array[196]; typedef unsigned char byte; byte *On_Screen=(byte *)MK_FP(0xA000,0); int Sprite_Red_X=126, Sprite_Red_Y=0, Sprite_Yellow_X=226, Sprite_Yellow_Y=0, ydir= 1; //---------------------------- Screen Codes Begins -------------------------- void EnterMode13H(void) {union REGS regs;regs.x.ax = 0x0013;int86(0x10, ®s, ®s);} void LeaveMode13H(void) {union REGS regs;regs.x.ax = 0x0003;int86(0x10, ®s, ®s);} //------------------------------------------------------------------------------------------ //------------------------- Plot-Read Pixels Begins ------------------------- void PlotPixel (unsigned int x, unsigned int y, unsigned char c) { if ((x < 320) && (y < 200)) { on_Screen[(y << 8) + (y << 6) + x] = c; } } unsigned char ReadPixel(unsigned int x, unsigned int y) { if((x < 320) && (y < 200)) { return (On_Screen[(y << 8) + (y << 6) + x]); } else { return(0); } } //------------------------------------------------------------------------------------------ //------------------------- Vertical Retrace Begins ------------------------- void wait_for_retrace(void) { while ((inp(INPUT_STATUS) & VRETRACE)) {}; while (!(inp(INPUT_STATUS) & VRETRACE)) {}; } //------------------------------------------------------------------------------------------ //--------------------------- DrawLine Begins -------------------------------- void DrawLine(int x, int y, int x1, int y1, unsigned char c) { int i, dx=0, dy=0, length; if (x==x1) { length = (y1-y); dy=1; } else { length = (x1-x); dx=1; } for (i=0; i<=(length); i++) { PlotPixel(x,y,c);x = x+dx; y = y+dy; } } //------------------------------------------------------------------------------------------ //------------------------------- IMAGE CAPTURE BEGINS ---------------------------------- Backg_Image_Capture() { int h, w, c; // sprite X, Y values - you can skip this if (Sprite_Red_Y == 186) {ydir=-1;} if (Sprite_Yellow_Y == 186) {ydir=-1;} if (Sprite_Red_Y == 1) {ydir=1;} if (Sprite_Yellow_Y == 1) {ydir=1;} Sprite_Red_Y = Sprite_Red_Y + ydir; Sprite_Yellow_Y = Sprite_Yellow_Y + ydir; //-------------------------- SPRITE RED BACKGROUND CAPTURE ------------------------------- c=0; for (h=0; h<= IMAGE_HEIGHT; h++) { for (w=0; w<= IMAGE_WIDTH; w++) { Sprite_Red_Backg_Array[c++] = ReadPixel(Sprite_Red_X+w, Sprite_Red_Y+h); } } //------------------------ SPRITE YELLOW BACKGROUND CAPTURE ------------------------------- /* c=0; for (h=0; h<= IMAGE_HEIGHT; h++) { for (w=0; w<= IMAGE_WIDTH; w++) { Sprite_Yellow_Backg_Array[c++] = ReadPixel(Sprite_Yellow_X+w, Sprite_Yellow_Y+h); } } */ } //--------------------------------- CAPTURE ENDS ------------------------------- //------------------------- Draw Sprites Begins ----------------------------- void DrawSprites() { int h, w; char far *Sprite_Red_RowPtr; char far *Sprite_Red_BufferPtr; char far *Sprite_Red_ImagePtr; char far *Sprite_Yellow_RowPtr; char far *Sprite_Yellow_BufferPtr; char far *Sprite_Yellow_ImagePtr; //--------------------------- DRAW SPRITE_RED ------------------------------- Sprite_Red_RowPtr = on_Screen+(Sprite_Red_Y * SCREEN_WIDTH) + Sprite_Red_X; Sprite_Red_ImagePtr = Sprite_Red; for (h = 0; h < IMAGE_HEIGHT; h++) { for (w=0, Sprite_Red_BufferPtr = Sprite_Red_RowPtr; w < IMAGE_WIDTH; w++) { *Sprite_Red_BufferPtr++ = *Sprite_Red_ImagePtr++; } Sprite_Red_RowPtr += SCREEN_WIDTH; } //------------------------------------------------------------------------------------------ //--------------------------- DRAW SPRITE_YELLOW ------------------------------- /* Sprite_Yellow_RowPtr = on_Screen+(Sprite_Yellow_Y * SCREEN_WIDTH) + Sprite_Yellow_X; Sprite_Yellow_ImagePtr = Sprite_Yellow; for (h = 0; h < IMAGE_HEIGHT; h++) { for (w=0, Sprite_Yellow_BufferPtr = Sprite_Yellow_RowPtr; w < IMAGE_WIDTH; w++) { *Sprite_Yellow_BufferPtr++ = *Sprite_Yellow_ImagePtr++; } Sprite_Yellow_RowPtr += SCREEN_WIDTH; } */ //------------------------------------------------------------------------------------------ } //----------------------- Erase Sprites Begins ----------------------------- void EraseSprites() { int h, w, c; char far *Sprite_Red_RowPtr; char far *Sprite_Red_BufferPtr; char far *Sprite_Yellow_RowPtr; char far *Sprite_Yellow_BufferPtr; Sprite_Red_RowPtr = on_Screen+(Sprite_Red_Y * SCREEN_WIDTH) + Sprite_Red_X; Sprite_Yellow_RowPtr = on_Screen+(Sprite_Yellow_Y * SCREEN_WIDTH) + Sprite_Yellow_X; //------------------------- ERASE SPRITE_RED --------------------------------------- c=0; for (h = 0; h <= IMAGE_HEIGHT; h++) { for (w=0, Sprite_Red_BufferPtr = Sprite_Red_RowPtr; w <= IMAGE_WIDTH; w++) { *Sprite_Red_BufferPtr++ = Sprite_Red_Backg_Array[c++]; } Sprite_Red_RowPtr += SCREEN_WIDTH; } //------------------------- ERASE SPRITE_YELLOW --------------------------------------- /* c=0; for (h = 0; h <= IMAGE_HEIGHT; h++) { for (w=0, Sprite_Yellow_BufferPtr = Sprite_Yellow_RowPtr; w <= IMAGE_WIDTH; w++) { *Sprite_Yellow_BufferPtr++ = Sprite_Yellow_Backg_Array[c++]; } Sprite_Yellow_RowPtr += SCREEN_WIDTH; } */ } //------------------------------------------------------------------------------------------ //--------------------------- Draw Red & Yellow Stics -------------------------------- DrawSticks() { int i, rsx=130, ysx=230; for (i = 0; i <= 5; i++) { DrawLine(rsx,1,rsx,199,14); rsx++; } for (i = 0; i <= 5; i++) { DrawLine(ysx,1,ysx,199,12); ysx++; } } //------------------------------------------------------------------------------------------ void main() { EnterMode13H(); DrawSticks(); do { Backg_Image_Capture(); DrawSprites(); wait_for_retrace(); //getch(); EraseSprites(); } while (!kbhit()); getch(); LeaveMode13H(); } [edited by - tppramod on March 30, 2004 3:58:39 AM] [edited by - tppramod on March 30, 2004 4:00:08 AM]

Share this post


Link to post
Share on other sites
It an off by one error.

Look for all instances of
for (h=0; h<= IMAGE_HEIGHT; h++)
for (w=0; w<= IMAGE_WIDTH; w++)

and replace with

for (h=0; h< IMAGE_HEIGHT; h++)
for (w=0; w< IMAGE_WIDTH; w++)

These errors are in your EraseSprites and Backg_Image_Capture functions. Good Luck.


Share this post


Link to post
Share on other sites
Hi! Jack Sotac,

thanks for the fast reply. i have not yet changed the lines and tried as per your suggestion because i remember once i had changed in this way, but then the sprites were not redering correctly. i think changing '=' won't work because as i mentioned in the first para that if i enable only one sprite (i.e. red or yellow) it works very fine i.e. it captures, draws and erases correctly. had this been the error then how it is functioning properly when it runs individually. but only on enabling both, 'sprite_red' is using the background of 'sprite_yellow' for erasing thats my problem. I request you to please `COMPILE THE PROGRAM AND SEE THE ANIMATION' then you will have the clear idea what i am trying to explain. pls. note that `sprite_yellow' is disabled by default. In my original post the include section has got some junck characters, which i have corrected thereafter.

Thanks & Regards,


T. P. Pramod Kumar
New Delhi
INDIA

[edited by Tiffany]
Deleted some excessive spacing.

[edited by - tiffany_smith on March 31, 2004 11:01:30 AM]

Share this post


Link to post
Share on other sites
tppramod,

I read your post carefully, compiled and ran your program before reponding to your post. I ran it again with both sprite enable and using my corrections. It worked perfectly.

What you are doing is overflowing your arrays for storing the background. That is you are writing to memory that was never allocated to you. Sometimes this is harmless and other times cause crashes or glitches that are hard to pinpoint.

It probably ran OK with only one sprite enabled because the memory overruns just goes into the unused background memory for the other sprite. Try commenting out the unused background buffer and see what happens.

Best Wishes




Share this post


Link to post
Share on other sites
Jack Sotac,

thanks a tonn...... for the great help Jack!!!!. when u said that u have already tested the code and working fine, i am really got exicted. i am at my workplace so i am not able to see the result now. could u pls. clear one thing more. as u said it was an array overflow but then if i look logically, the initial value of `c'' is = 0 and is incremented by 1, after that the background is stored in the array using the loop. After the first updation, when the loop begins again, (value of c is set to 0 again) it overwrites the array only on the same location i.e. from `0''. then how does the array overflow?. updation is being done on the same memory location again & again. I don''t know if this is the correct method of array usage.


Also please tell if the program is now ok or still is there any problem with the array usage i.e. `array overflow''. is there any simply way to test if the usage of array is perfect.

Thanks & Regards,

pramod

Share this post


Link to post
Share on other sites
Lets take your original yellow sprite capture code.
Lets pretend for this example that IMAGE_HEIGHT is 2 and IMAGE_WIDTH is 2.
This means the size of Sprite_Yellow_Backg_Array would be 4.
Sprite_Yellow_Backg_Array[0] <- GOOD (1st element)
Sprite_Yellow_Backg_Array[1] <- GOOD (2nd element)
Sprite_Yellow_Backg_Array[2] <- GOOD (3rd element)
Sprite_Yellow_Backg_Array[3] <- GOOD (4th element)
Sprite_Yellow_Backg_Array[4] <- BAD (5th element is out of bounds)

So if c >= 4 then we have overrun the array.
...psuedo definitions
#define IMAGE_WIDTH 2
#define IMAGE_HEIGHT 2
char Sprite_Yellow_Backg_Array[4];

Here is a simplified version of the function to store the background.

c=0;
for (h=0; h<= 2; h++)//this will loop h=0,h=1,h=2,at h=3 it will break the loop
{
for (w=0; w<= 2; w++)//this will loop w=0,w=1,w=2,at w=3 it will break
{
array[c] = readpixel(..);
c++;
}
}
If we go through the loop and keep track of the variables we get this table.
h:0 w:0 c:0
h:0 w:1 c:1
h:0 w:2 c:2
h:1 w:0 c:3
h:1 w:1 c:4
h:1 w:2 c:5
h:2 w:0 c:6
h:2 w:1 c:7
h:2 w:2 c:8
At the end we get c=8. This means we have tried to access more than double the amount of memory we had in Sprite_Yellow_Backg_Array. This is VERY bad because we might have
overwritten something important.

Now we use our corrected version
c=0;
for (h=0; h< 2; h++)//this will loop h=0,h=1,at h=2 it will break the loop
{
for (w=0; w< 2; w++)//this will loop w=0,w=1,at w=2 it will break
{
c++;
}
}
h:0 w:0 c:0
h:0 w:1 c:1
h:1 w:0 c:2
h:1 w:1 c:3
At the end we get c=3 which is still within bounds of our memory.

NOTE:
The current value of ''c'' is used then afterwards incremented. Look-up preincrement and postincrement operators.

c++; //Changes value after the expression is evaluated
++c;//Changes value before the expression is evaluated

So if c is initialized to zero then
Sprite_Yellow_Backg_Array[c++] = ReadPixel(...);
it is like you wrote
Sprite_Yellow_Backg_Array[c] = ReadPixel(...);
c=c+1;
NOT
c=c+1
Sprite_Yellow_Backg_Array[c] = ReadPixel(...);
Remember, C/C++ arrays start at 0


Hope this helps.Have a good day.

Share this post


Link to post
Share on other sites
Really great! i really appreciate you for the time spent by you for clearing my doubts. Very nice explanations. Now i am very much clear about where i was making the mistake. I have made the changes in my main program and is working fantastic. Thank you very much once again.

Best Wishes,

T. P. Pramod Kumar

Share this post


Link to post
Share on other sites