From 78af003371b6b651e1d9b005702e3d22cee951c7 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Mon, 17 Aug 2020 19:51:43 +0930 Subject: implement pixel XORing and wrapping sprites are properly XOR'd to the display, setting the 0xF register as appropriate. sprites also wrap on the bottom and irght side of the screen. because you can't access negative video memory, wrpaping top to bottom and left to right isn't implemented --- chip8.c | 30 +++++++++++++++++------------- chip8.h | 2 +- main.c | 13 +++++++++++-- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/chip8.c b/chip8.c index db2efd2..3a2f43d 100644 --- a/chip8.c +++ b/chip8.c @@ -79,10 +79,17 @@ chip8_init() { memory[0x0 + i] = chip8_fontset[i]; } + + uint8_t sinv[] = {0xBA, 0x7C, 0xD6, 0xFE, 0x54, 0xAA}; + // temp + for (uint8_t i = 0; i < 6; i++) + { + memory[0x200+i] = sinv[i]; + } } void -chip8_draw_sprite(int startx, int starty, uint8_t mem, uint8_t size) +chip8_draw_sprite(int startx, int starty, uint16_t mem, uint8_t size) { /* * draw sprite located at loc of height size at startx,starty @@ -90,7 +97,7 @@ chip8_draw_sprite(int startx, int starty, uint8_t mem, uint8_t size) uint8_t byte = 0; uint8_t mask = 0x1; - uint8_t destbit = 0x0; + V[0xF] = 0; /* set collision register to 0 */ for (uint8_t byteoffset = 0; byteoffset < size; byteoffset++) { /* loop through each byte from mem to mem+size */ @@ -98,21 +105,18 @@ chip8_draw_sprite(int startx, int starty, uint8_t mem, uint8_t size) int bit = 0; for (mask = 0x80; mask != 0; mask >>= 1) { - if (byte&mask) - { - destbit = 1; - video[WIDTH*starty+(startx+bit)] = 0xFFFFFF; - } - else + if (byte & mask) { - destbit = 0; - video[WIDTH*starty+(startx+bit)] = 0x0; + uint32_t pixel = WIDTH*(starty%HEIGHT)+((startx%WIDTH)+bit); + if (video[pixel] != 0) + { + /* if the video bit is already set, we need to set the collision register */ + V[0xF] = 1; + } + video[pixel] ^= 0xFFFFFF; } - printf("%d", destbit); bit++; } starty++; - puts(""); } - puts("---"); } diff --git a/chip8.h b/chip8.h index 6018d40..3aaa8a8 100644 --- a/chip8.h +++ b/chip8.h @@ -17,6 +17,6 @@ int load_rom(); void chip8_init(); -void chip8_draw_sprite(int startx, int starty, uint8_t mem, uint8_t size); +void chip8_draw_sprite(int startx, int starty, uint16_t mem, uint8_t size); #endif diff --git a/main.c b/main.c index d549b25..ce86053 100644 --- a/main.c +++ b/main.c @@ -12,7 +12,7 @@ * http://www.emulator101.com/chip-8-sprites.html */ -#define VIDEO_SCALE 10 +#define VIDEO_SCALE 5 SDL_Window *window; SDL_Renderer *renderer; @@ -109,6 +109,7 @@ int main(int argc, char *argv[]) uint32_t frame_time; int do_quit = 0; + chip8_draw_sprite(0, 0, 0xD*5, 0x5); chip8_draw_sprite(5, 0, 0xE*5, 0x5); chip8_draw_sprite(10, 0, 0xA*5, 0x5); @@ -127,13 +128,21 @@ int main(int argc, char *argv[]) chip8_draw_sprite(30, 9, 0xE*5, 0x5); chip8_draw_sprite(35, 9, 0xf*5, 0x5); + chip8_draw_sprite(0, 20, 0x200, 0x6); + chip8_draw_sprite(8, 20, 0x200, 0x6); + chip8_draw_sprite(16, 20, 0x200, 0x6); + chip8_draw_sprite(18, 20, 0x200, 0x6); + + chip8_draw_sprite(61, 25, 0x200, 0x6); + chip8_draw_sprite(50, 30, 0x200, 0x6); while(!do_quit) { frame_start = SDL_GetTicks(); // logic - update_video(); + if (draw_flag) + update_video(); frame_time = SDL_GetTicks() - frame_start; if (frame_delay > frame_time) -- cgit v1.2.3