diff --git a/Makefile b/Makefile index 528d250..78dedea 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ ECHO=echo -e CFLAGS=-Wall -Werror -std=gnu99 -O0 -g -Iinclude LIBS=-lSDL2 -FILES=build/main.o build/mem.o build/stack.o build/keyboard.o build/chip8.o +FILES=build/main.o build/mem.o build/stack.o build/keyboard.o build/chip8.o \ + build/screen.o OUT=bin/chip8.out all: $(FILES) @@ -30,6 +31,10 @@ build/chip8.o: src/chip8.c @$(ECHO) "CC\t\t"$< @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) +build/screen.o: src/screen.c + @$(ECHO) "CC\t\t"$< + @$(CC) $(CFLAGS) $< -c -o $@ $(LIBS) + run: all @$(ECHO) "Runing the Chip8 compiler" @$(OUT) diff --git a/include/chip8.h b/include/chip8.h index 95cf038..fcad85b 100644 --- a/include/chip8.h +++ b/include/chip8.h @@ -5,6 +5,7 @@ #include "keyboard.h" #include "mem.h" #include "registers.h" +#include "screen.h" #include "stack.h" struct chip8 @@ -13,6 +14,7 @@ struct chip8 struct chip8_registers registers; struct chip8_stack stack; struct chip8_keyboard keyboard; + struct chip8_screen screen; }; void chip8_init (struct chip8 *chip8); diff --git a/include/config.h b/include/config.h index 602532d..e145a0f 100644 --- a/include/config.h +++ b/include/config.h @@ -5,7 +5,8 @@ #define EMULATOR_WINDOW_MULTIPLIER 10 #define CHIP8_MEMORY_SIZE 4096 -#define CHIP8_DISPLAY_WIDTH 63 + +#define CHIP8_DISPLAY_WIDTH 64 #define CHIP8_DISPLAY_HEIGHT 32 #define CHIP8_TOTAL_DATA_REGISTERS 16 diff --git a/include/screen.h b/include/screen.h new file mode 100644 index 0000000..59e285e --- /dev/null +++ b/include/screen.h @@ -0,0 +1,16 @@ +#ifndef __SCREEN_H +#define __SCREEN_H + +#include "config.h" + +struct chip8_screen +{ + _Bool pixels[CHIP8_DISPLAY_HEIGHT][CHIP8_DISPLAY_WIDTH]; +}; + +void chip8_screen_set (struct chip8_screen *screen, int x, int y); +_Bool chip8_screen_is_set (struct chip8_screen *screen, int x, int y); +_Bool chip8_screen_draw_sprite (struct chip8_screen *screen, int x, int y, + const char *sptr, int num); + +#endif diff --git a/src/main.c b/src/main.c index 218bb41..2abb732 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,8 @@ main (int argc, char **argv) { struct chip8 chip8; chip8_init (&chip8); + chip8_screen_draw_sprite (&chip8.screen, 62, 10, + (const char *)&chip8.memory.memory[0x00], 5); SDL_Init (SDL_INIT_EVERYTHING); SDL_Window *window = SDL_CreateWindow ( @@ -57,10 +59,23 @@ main (int argc, char **argv) SDL_SetRenderDrawColor (renderer, 0, 0, 0, 0); SDL_RenderClear (renderer); - SDL_SetRenderDrawColor (renderer, 255, 255, 255, 0); - SDL_Rect r = { 0, 0, 40, 40 }; - SDL_RenderFillRect (renderer, &r); + + for (int x = 0; x < CHIP8_DISPLAY_WIDTH; x++) + { + for (int y = 0; y < CHIP8_DISPLAY_HEIGHT; y++) + { + if (chip8_screen_is_set (&chip8.screen, x, y)) + { + SDL_Rect r = { 0 }; + r.x = x * EMULATOR_WINDOW_MULTIPLIER; + r.y = y * EMULATOR_WINDOW_MULTIPLIER; + r.w = EMULATOR_WINDOW_MULTIPLIER; + r.h = EMULATOR_WINDOW_MULTIPLIER; + SDL_RenderFillRect (renderer, &r); + } + } + } SDL_RenderPresent (renderer); } diff --git a/src/screen.c b/src/screen.c new file mode 100644 index 0000000..c1f3c65 --- /dev/null +++ b/src/screen.c @@ -0,0 +1,54 @@ +#include "screen.h" + +#include + +static void +chip8_screen_ensure_in_bounds (int x, int y) +{ + assert (x >= 0 && x <= CHIP8_DISPLAY_WIDTH); + assert (y >= 0 && y <= CHIP8_DISPLAY_HEIGHT); +} + +void +chip8_screen_set (struct chip8_screen *screen, int x, int y) +{ + chip8_screen_ensure_in_bounds (x, y); + screen->pixels[y][x] = 1; +} + +_Bool +chip8_screen_is_set (struct chip8_screen *screen, int x, int y) +{ + chip8_screen_ensure_in_bounds (x, y); + return screen->pixels[y][x]; +} + +_Bool +chip8_screen_draw_sprite (struct chip8_screen *screen, int x, int y, + const char *sptr, int num) +{ + _Bool sprite_hit = 0; // true if sptr overrides a set bit + + for (int ly = 0; ly < num; ly++) + { + char c = sptr[ly]; + for (int lx = 0; lx < 8; lx++) + { + if ((c & (0b10000000 >> lx)) == 0) + continue; + + if (screen->pixels[(ly + y) % CHIP8_DISPLAY_HEIGHT] + [(lx + x) % CHIP8_DISPLAY_WIDTH]) + { + sprite_hit = 1; + } + + // the % wraps it around the screen + screen->pixels[(ly + y) % CHIP8_DISPLAY_HEIGHT] + [(lx + x) % CHIP8_DISPLAY_WIDTH] + ^= 1; + } + } + + return sprite_hit; +}