What's new

CHIP8 DrawSprite

Kevin19

New member
I have been trying to figure this routine out for more than 40minutes now
But i still do not get how it works

void DrawSprite(int rx,int ry,int s)
{
int countery,counterx;
char pixel;
for(countery=0;countery<s;countery++)
{
pixel=memory[I+countery];
for(counterx=0;counterx<8;counterx++)
{
if((pixel&(0x80>>counterx))!=0)
{
if(screen[rx+(ry*64)]==1)
{
V[0xF]=1;
}
screen[rx+(ry*64)]^=1;
}
}
}
}
Why is there a need to go through the same loop 8 times if any number is going to be the same anyway NUM&0x80=80 or 0
Is not it highly CPU consuming
 

RipNLa

New member
Kevin19 said:
I have been trying to figure this routine out for more than 40minutes now
But i still do not get how it works

void DrawSprite(int rx,int ry,int s)
{
int countery,counterx;
char pixel;
for(countery=0;countery<s;countery++)
{
pixel=memory[I+countery];
for(counterx=0;counterx<8;counterx++)
{
if((pixel&(0x80>>counterx))!=0)
{
if(screen[rx+(ry*64)]==1)
{
V[0xF]=1;
}
screen[rx+(ry*64)]^=1;
}
}
}
}
Why is there a need to go through the same loop 8 times if any number is going to be the same anyway NUM&0x80=80 or 0
Is not it highly CPU consuming

Its because, it is not being & with just 0x80 each iteration. 0x80 is being right shifted each time BEFORE the & (notice the order of precedence, parenthesis).

Basically, 0x80 is 10000000 in binary right?
So
(0x80 >> 0) = (10000000) & pixel
(0x80 >> 1) = (01000000) & pixel
(0x80 >> 2) = (00100000) & pixel
(0x80 >> 3) = (00010000) & pixel
(0x80 >> 4) = (00001000) & pixel
(0x80 >> 5) = (00000100) & pixel
(0x80 >> 6) = (00000010) & pixel
(0x80 >> 7) = (00000001) & pixel

So each iteration of the outer loop, the variable pixel gets one byte (8 binary bits) of memory, that represents a graphic. You then check EACH BIT OF THAT BYTE with this piece of code to see if we need to draw on the screen or not.

If the byte you pulled was 11001111, you wouldnt want to do anything with the 00 because another graphic might be drawn there on that screen location already.
 
OP
K

Kevin19

New member
I still do not see the purpose of this process I think it is overly redundant and could be optimized With a single check whether the number is resulting in zero or not
 

RipNLa

New member
Kevin19 said:
I still do not see the purpose of this process I think it is overly redundant and could be optimized With a single check whether the number is resulting in zero or not

Hmm..I'm not sure what you mean, but do you understand that one "number" contains 8 separate values?

Imagine your PIXEL is integer 213 on one iteration, so that means in binary it is 11010101. That means, that starting at location x,y you have to draw THOSE 8 pixels from that ONE value. Remember, that PIXEL is updated every outside loop iteration to go through each ROW of the sprite youre drawing.

I think your confusion comes from your using the name PIXEL for the variable, when it should really be called something like RowOfSprite since it contains many pixels, not just one.
 
Last edited:
OP
K

Kevin19

New member
I understand I have practiced assembler for over 2 years Do trust me i understand what it means

And yes i have been lost in confusion I was being too hasty and have neglected to see the part where it increases the positions

and the single check thing WELL i simply suggested that maybe instead all of this loop you could use boolean
 

aprentice

Moderator
Kevin19 said:
I understand I have practiced assembler for over 2 years Do trust me i understand what it means

And yes i have been lost in confusion I was being too hasty and have neglected to see the part where it increases the positions

and the single check thing WELL i simply suggested that maybe instead all of this loop you could use boolean

I seriously doubt you have coded in asm for 2 years, if you have, you would understand bit management. Every byte is composed of 8 bits. Every bit tells the chip8 emu where to draw the pixel and where to not draw the pixel. You can think of it as a matrix. I can't explain it more simpler than this :p

summary
--------
0 = no pixel
1 = pixel
 
OP
K

Kevin19

New member
Are you kidding me now I hope you are It definitely Seems like you are

I am sorry if It looks like I am taking offense to it

But i am a serious person And I do not like when i am being mocked
 
OP
K

Kevin19

New member
I decided to forgive you For making Fun of my negligence And Throwing it back at me 10 times more than i deserved it

So i have been working all day and coded the whole instructions Did not use assembly yet for optimization Not that i think any would be required after all it is only a 40 instruction emulator

Of course it would be fun To experience and enrich my knowledge

anyway Now that all is done It seems so dull and inanimate I think Thanks to my carelessness again I have omitted something

I know I should not be asking and trying to figure it out myself but really I have coded this thing all day and i am really tired to the bone
 
OP
K

Kevin19

New member
Am i missing something here Because How ridiculous and newbie it may sound It only draws That image

Now i have been checking and compared all the opcodes to other peoples codes And everything seems adequate SO to speak

These are the last opcodes which the little debugger I have coded issue

[2FC] F129 FONT V1
[2FE] 6337 MOV V3,37
[300] 6400 MOV V4,0
[302] D345 DRYS 345
[304] 7305 ADD V3,5
[306] F229 FONT V2
[308] D345 DRYS 345

And there it also seems to get stuck almost at the end of the binary file

[THE END] - Just right before it excutes d345
0xD3, 0x45, 0x00, 0xEE, 0xE0, 0x00, 0x80, 0x00, 0xFC, 0x00,0xAA,0x00, 0x00, 0x00, 0x00, 0x00
[/THE END]

I have only coded the instructions the sprite drawer which i had to revise as well and a function to load THE romFile and the font table

void main()
{
debug();
LoadTable(FontTable);
loadROM();
while(keyCheck()!=27)
CPU();
}

I know this may look like one big joke to you But no I am very serious And tired

So i will go to sleep now and hope i will be able to solve this in the morning or someone will be able to solve it for me

THANK YOU
 
Last edited:

manboy

New member
Kevin19 said:
Am i missing something here Because How ridiculous and newbie it may sound It only draws That image

Now i have been checking and compared all the opcodes to other peoples codes And everything seems adequate SO to speak

These are the last opcodes which the little debugger I have coded issue

[2FC] F129 FONT V1
[2FE] 6337 MOV V3,37
[300] 6400 MOV V4,0
[302] D345 DRYS 345
[304] 7305 ADD V3,5
[306] F229 FONT V2
[308] D345 DRYS 345

And there it also seems to get stuck almost at the end of the binary file

[THE END] - Just right before it excutes d345
0xD3, 0x45, 0x00, 0xEE, 0xE0, 0x00, 0x80, 0x00, 0xFC, 0x00,0xAA,0x00, 0x00, 0x00, 0x00, 0x00
[/THE END]

I have only coded the instructions the sprite drawer which i had to revise as well and a function to load THE romFile and the font table

void main()
{
debug();
LoadTable(FontTable);
loadROM();
while(keyCheck()!=27)
CPU();
}

I know this may look like one big joke to you But no I am very serious And tired

So i will go to sleep now and hope i will be able to solve this in the morning or someone will be able to solve it for me

THANK YOU

Try contacting Refraction for help. He knows a lot about the chip8 :bouncy:
 
OP
K

Kevin19

New member
Good morning everyone
Hello manboy
That is ok I just woke up and everything looks more clear in the morning
The problem originated from hastiness to get to see results I thought i could have it done in one day

The problem was In the RTS calling Instead of juxtaposing the whole byte To see if it matches the case I only juxtaposed the lower nibble Which created this conflict and i also seem to have made one of the stupidest most foolish mistakes in the whole history of programming I have defined the stack as 8bits instead of 16

Now it seems to loop through the subroutine infinitely

And another uncanny thing is happening it appears that if i do not position the stack array in a certain way it creates another conflict But it is all fixed now except for the iterative LOOP

of course
 
OP
K

Kevin19

New member
HAHAHAHA
I am unsure of the reason which led you to say that But i will take it you were laughing at the fact that Unlike all of you bill gates butlickers

I did not use Visual c++

or any of those neoteric 21 century means such as directx and opengl The simplicity of using them so simple Why use something so primitive and outdated You probably think to yourself HAHAHAHA

"Children of the future"

anyway I have just finished the GFX implementation
I used mod 13 which is about 320*200 with a direct pointer to the screen buffer which gives it pretty much a smooth sail I wish I could post you some pictures to see my newbiness But it does not seem to let me printscreen it

So i will just append the file to this message of course I would not recommend anyone to see it because It is one of the most disastrous things I have ever coded

But first impression and first demo
 
OP
K

Kevin19

New member
I just finished coding the input function and when i run it
It seems to get stuck during the game if you keep pushing it as a matter of fact All the game seems to get stuck

According to the debug file it seems to get stuck at address

[2CE] A30E MVI 30E
[2D0] 7EFF ADD V14,FF
[2D2] 80E0 MOV V0,VE
[2D4] 8004 ADD V0,V0
[2D6] 6100 MOV V1,0
[2D8] D011 DRYS 11
[2DE] 3E00 SKEQ V14,0
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE

case 0xE000:
if((opcode&0xFF)==0x9E)
{
if(input(V[(opcode&0xF00)>>8])==V[(opcode&0xF00)>>8])
{
PC=PC+4;
}
else
{
PC=PC+2;
}
}
if((opcode&0xFF)==0xA1)
{
if(input(V[(opcode&0xF00)>>8])!=V[(opcode&0xF00)>>8])
{
PC=PC+4;
}
else
{
PC=PC+2;
}

}
int input(int key)
{
switch(key)
{
case 4 : if(keyCheck()=='a')return 4; break;
case 6 : if(keyCheck()=='d')return 6; break;
default : return 0; break;
}
}

I also attached the file to this message
 

aprentice

Moderator
Kevin19 said:
I just finished coding the input function and when i run it
It seems to get stuck during the game if you keep pushing it as a matter of fact All the game seems to get stuck

According to the debug file it seems to get stuck at address

[2CE] A30E MVI 30E
[2D0] 7EFF ADD V14,FF
[2D2] 80E0 MOV V0,VE
[2D4] 8004 ADD V0,V0
[2D6] 6100 MOV V1,0
[2D8] D011 DRYS 11
[2DE] 3E00 SKEQ V14,0
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE
[2DE] 12DE JMP 2DE

Its not stuck, have you bothered to read the output?

[2DE] 3E00 SKEQ V14,0 <- skip next instruction if register 14 is equal to 0
otherwise execute the instruction, and since the instruction jumps to itself, it means that the rom was meant to end there, think of it as a "game over" or "execution complete".
 

smcd

Active member
Actually Kevin19, I was referring to your breaking the standard set forth by ANSI/ISO commitees regarding both C and C++, they define main() as a function that returns a value of type int, not a void function. :p
 
OP
K

Kevin19

New member
Yes i thought it was a gameover myself at first because it had no other place to jump But then this little gameover address came before the game was over

It still gets stuck in the middle of the game
I am having problems establishing the correct input system
I have already tried approximately 8 different approaches which none of them seemed to work properly


and sethmcdoogle Yes little rebellious me

When you get caught up between the rush of finishing something and fatigue
of the night
You forget who and where you came from

after all this rant
I would like to thank you all for helping me whether you did or not Thank you anyway for even replying
 
OP
K

Kevin19

New member
Ok it seems to get stuck with and without any input just like that random sometimes after 10 seconds and sometimes after 40seconds
 

zenogais

New member
Kevin19 said:
HAHAHAHA
I am unsure of the reason which led you to say that But i will take it you were laughing at the fact that Unlike all of you bill gates butlickers

I did not use Visual c++

or any of those neoteric 21 century means such as directx and opengl The simplicity of using them so simple Why use something so primitive and outdated You probably think to yourself HAHAHAHA

"Children of the future"

anyway I have just finished the GFX implementation
I used mod 13 which is about 320*200 with a direct pointer to the screen buffer which gives it pretty much a smooth sail I wish I could post you some pictures to see my newbiness But it does not seem to let me printscreen it

So i will just append the file to this message of course I would not recommend anyone to see it because It is one of the most disastrous things I have ever coded

But first impression and first demo

No, as was stated, we were referring to the fact that void main() an ancient and deprecated way of defining the program entry point. Also, in my Chip8 emulator I use neither DirectX or OpenGL.
 

Top