chip8

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.vgx.fr/chip8
Log | Files | Refs

commit f5a1325664fa0b7dda67a7273c5ec3c33654963d
parent 024662694be4fddbe0ccbdd0631a14406d9c2497
Author: Léo Villeveygoux <leo.villeveygoux@u-bordeaux.fr>
Date:   Sat,  1 Dec 2018 01:35:22 +0100

add sdl media handling

Simple, probably buggy at the moment, SDL input, graphics output, timer
handling.
Still no sound at the moment.

Diffstat:
Abuild.sh | 1+
Mchip8.c | 26++++++++++++++++++--------
Amedia-sdl.c | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amedia.h | 17+++++++++++++++++
4 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/build.sh b/build.sh @@ -0,0 +1 @@ +gcc chip8.c media-sdl.c -o chip8 $(sdl2-config --cflags --libs) diff --git a/chip8.c b/chip8.c @@ -3,6 +3,8 @@ #include <time.h> #include <unistd.h> +#include "media.h" + unsigned char RAM[0x1000]; unsigned char V[16]; @@ -147,6 +149,8 @@ void step(){ case 0x00E0: /* clear screen */ for(int i=0 ; i<256 ; i++) SCREEN[i] = 0; + clear_screen(); + send_draw(); break; case 0x00EE: /* return from a subroutine */ if(SP) @@ -257,7 +261,7 @@ void step(){ *screen_tile ^= sprite_tile; } } - /*XXX:debug*/ + /*TODO: mybe uptade just the right part*/ display(); //usleep(500000); break; @@ -335,11 +339,11 @@ void display(){ for(int y=0 ; y<32 ; y++){ for(int xc=0 ; xc<8 ; xc++){ for(int xb=7 ; xb>=0 ; xb--){ - printf("%s",SCREEN[y*8+xc]&1<<xb ? "█":" "); + draw(xc*8 + 7-xb, y, SCREEN[y*8+xc]&1<<xb ? 1:0); } } - printf("\n"); } + send_draw(); } int main(int argc, char **argv){ @@ -360,16 +364,20 @@ int main(int argc, char **argv){ fclose(rom); /*TODO: init more stuff: graphics, input, sound, timer*/ + m_init(argc, argv); /* Let's go */ for(int i=0 ; 1 ; i++){ + KEYBOARD = get_input(KEYBOARD); + if(KEYBOARD == (unsigned short)-1) + break; + step(); - /*XXX:debug*/ - /*TODO: other stuff*/ - //display(); - nanosleep(&(struct timespec){0,1000000},NULL); + + //nanosleep(&(struct timespec){0,1000000},NULL); + wait_tick(); + if(!(i%16)){ - //display(); if(DT) DT--; if(ST) @@ -378,5 +386,7 @@ int main(int argc, char **argv){ printf("i=%5d, DT=%3d \r", i, (int)DT); } + m_quit(); + return 0; } diff --git a/media-sdl.c b/media-sdl.c @@ -0,0 +1,149 @@ +#include <SDL2/SDL.h> +#include <string.h> + +#include "media.h" + +#define PIXEL_RADIUS 16 + +#define SCREEN_WIDTH (64*PIXEL_RADIUS) +#define SCREEN_HEIGHT (32*PIXEL_RADIUS) + +#define WINDOW_NAME "CHIP-8 emulator" + +#define NUM_PIXELS (SCREEN_WIDTH*SCREEN_HEIGHT) +unsigned char *pixels; + +SDL_Window *window; +SDL_Renderer *renderer; +SDL_Texture *texture; +SDL_Rect rect = {.x=0,.y=0,.w=SCREEN_WIDTH,.h=SCREEN_HEIGHT}; + +unsigned clock; + +/* +┌────┬────┬────┬────┐ +│ 1 │ 2 │ 3 │ C │ +├────┼────┼────┼────┤ +│ 4 │ 5 │ 6 │ D │ +├────┼────┼────┼────┤ +│ 7 │ 8 │ 9 │ E │ +├────┼────┼────┼────┤ +│ A │ 0 │ B │ F │ +└────┴────┴────┴────┘ +*/ + +SDL_Keycode keys[16] = { + SDLK_v, + SDLK_QUOTEDBL, SDLK_QUOTE, SDLK_LEFTPAREN, + SDLK_e, SDLK_r, SDLK_t, + SDLK_d, SDLK_f, SDLK_g, + SDLK_c, SDLK_b, + SDLK_MINUS, SDLK_y, SDLK_h, SDLK_n +}; + +int m_init(int argc, char **argv){ + (void)argc, (void)argv; + /*TODO: check every init */ + + pixels = calloc(1,NUM_PIXELS); + + SDL_Init( SDL_INIT_EVERYTHING ); + window = SDL_CreateWindow( + WINDOW_NAME, + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + SCREEN_WIDTH, SCREEN_HEIGHT, + 0); + + renderer = SDL_CreateRenderer( + window, -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + texture = SDL_CreateTexture( + renderer, + SDL_PIXELFORMAT_RGB332, SDL_TEXTUREACCESS_STREAMING, + SCREEN_WIDTH, SCREEN_HEIGHT); + + SDL_RenderClear(renderer); + + clock = SDL_GetTicks(); + + return 0; +} + +void m_quit(void){ + SDL_DestroyTexture(texture); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + + free(pixels); +} + +unsigned short get_input(unsigned short input){ + SDL_Event e; + + while(SDL_PollEvent(&e)){ + if (e.type == SDL_QUIT) { + return -1; + } + if (e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) { + for(int i=0;i<16;i++){ + if(e.key.keysym.sym == keys[i]){ + if(e.type == SDL_KEYDOWN){ + input |= 1<<i; + } else { + input &= ~(1<<i); + } + break; + } + } + } + } + + return input; +} +unsigned short wait_input(unsigned short input){ + /* TODO: better version */ + int new_input; + + while((new_input = get_input(input)) == input) + SDL_Delay(1); + + return new_input; +} + +void clear_screen(void){ + memset(pixels,0,NUM_PIXELS); +} + +void draw(int x, int y, int value){ + for(int i=0 ; i<PIXEL_RADIUS ; i++){ + for(int j=0 ; j<PIXEL_RADIUS ; j++){ + pixels[(y*PIXEL_RADIUS+i)*SCREEN_WIDTH + + x*PIXEL_RADIUS+j] = value ? 255 : 0; + } + } +} + +void send_draw(void){ + void *texture_pixels; + int pitch; /* we don't actually use this, yolo */ + SDL_LockTexture(texture, &rect, &texture_pixels, &pitch); + memcpy(texture_pixels, pixels, NUM_PIXELS); + SDL_UnlockTexture(texture); + + SDL_RenderCopy(renderer, texture, &rect, &rect); + SDL_RenderPresent(renderer); + SDL_RenderClear(renderer); +} + +void wait_tick(void){ + /* TODO: tunable frequency */ + unsigned new_clock = SDL_GetTicks(); + + if(new_clock == clock){ + SDL_Delay(1); + } + + clock = SDL_GetTicks(); +} diff --git a/media.h b/media.h @@ -0,0 +1,17 @@ +#ifndef C8_MEDIA_H +#define C8_MEDIA_H + +int m_init(int argc, char **argv); + +void m_quit(void); + +unsigned short get_input(unsigned short input); +unsigned short wait_input(unsigned short input); + +void clear_screen(void); +void draw(int x, int y, int value); +void send_draw(void); + +void wait_tick(void); + +#endif /* C8_MEDIA_H */