diff --git a/CMakeLists.txt b/CMakeLists.txt index 668a90c..3421ba4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,27 @@ cmake_minimum_required(VERSION 3.14.5) +project(SDL_demo LANGUAGES C VERSION 1.1) -project(SDL_demo LANGUAGES C VERSION 1.0) +set(SDLCHIP_SOURCES main.c chip.c chip.h) +if(EMSCRIPTEN) + add_compile_options("SHELL:-s WASM=1") + add_compile_options("SHELL:-s USE_SDL=2") + include_directories("${EMSCRIPTEN_ROOT_PATH}/cache/wasm/include/SDL2") + if(EXISTS "${EMSCRIPTEN_ROOT_PATH}/cache/wasm/ports-builds/sdl2/libSDL2.a") + set(SDL2_LIBRARIES "${EMSCRIPTEN_ROOT_PATH}/cache/wasm/ports-builds/sdl2/libSDL2.a")#myb not necessary but it didnt work for me without it + else() + message(FATAL_ERROR "SDL2 library not found, run: embuilder build sdl2") + endif() +else() + add_subdirectory(SDL) + set(SDL2_LIBRARIES SDL2main SDL2-static) +endif() -add_executable(SDLchip main.c chip.c) +option(EMBED_TETRIS "on to embed the tetris rom" ON) +if(EMBED_TETRIS) + add_compile_definitions(EMBED_TETRIS) + list(APPEND SDLCHIP_SOURCES tetris.h) +endif() -add_subdirectory(SDL) - - -target_link_libraries(SDLchip SDL2main SDL2-static) \ No newline at end of file +add_executable(SDLchip ${SDLCHIP_SOURCES}) +target_link_libraries(SDLchip ${SDL2_LIBRARIES}) \ No newline at end of file diff --git a/file2h.py b/file2h.py index ecd6ddd..af16149 100644 --- a/file2h.py +++ b/file2h.py @@ -2,8 +2,8 @@ file_name = "tetris.ch8" newfile_name = "tetris.h" -start_string = '#define LOAD_STRING\nconst char import_string[] = {' -end_string = '};' +start_string = 'const char import_string[] = {' +end_string = '};\nconst size_t import_string_size = sizeof(import_string) / sizeof(import_string[0]);\n//this is tetris.ch8 converted using my python script into a string' oldFile = open(file_name, "rb") oldFile = oldFile.read() diff --git a/main.c b/main.c index 090cc37..d775991 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,25 @@ #include #include -#include "SDL/include/SDL.h" +#include #include "chip.h" -//#include "tetris.h"//include if you want a standalone chip8 tetris executable +#ifdef __EMSCRIPTEN__ +#include "SDL.h" +#include +EM_JS(int, getWinHeight, (), { + return window.innerHeight +}); +EM_JS(int, getWinWidth, (), { + return window.innerWidth +}); +#else +#include "SDL/include/SDL.h" +#endif + +#ifdef EMBED_TETRIS +#include "tetris.h"//include if you want a standalone chip8 tetris executable, +extern const size_t import_string_size; +extern const char import_string[import_string_size]; +#endif #define COLOR_BLACK 0,0,0,0 #define COLOR_WHITE 255,255,255,0 @@ -16,11 +33,10 @@ char paused = 0; char key[16] = {0};//an array for keystate keeping const char *filename; -#ifdef LOAD_STRING +#ifdef EMBED_TETRIS void loadString()//use for intro logo - after loading integrated or for nocart { - size_t s = sizeof(import_string) / sizeof(import_string[0]); - for (int i = 0; i < s; i++) + for (int i = 0; i < import_string_size; i++) { memory[i+512] = import_string[i]; @@ -123,7 +139,7 @@ char getEvents(char b_wait) break; case SDLK_o: init(); - #ifdef LOAD_STRING + #ifdef EMBED_TETRIS loadString(); #else loadFile(filename); @@ -218,7 +234,7 @@ void initMain() { init(); SDL_Init(SDL_INIT_VIDEO); - SDL_CreateWindowAndRenderer(640, 320, SDL_WINDOW_RESIZABLE, &win, &ren); + SDL_CreateWindowAndRenderer(640*2, 320*2, SDL_WINDOW_RESIZABLE, &win, &ren); SDL_RenderSetLogicalSize(ren, 64, 32); SDL_SetRenderDrawColor(ren, COLOR_BLACK); SDL_RenderClear(ren); @@ -227,35 +243,49 @@ void initMain() void mainloop() { - clock_t cycle_timer, sd_timer; + #ifdef __EMSCRIPTEN__//fix + if(!paused) + { + if(timerS > 0){timerS--;} + if(timerD > 0){timerD--;} + for (size_t i = 0; i < 500/60; i++) + { + fetch(); + execute(); + } + SDL_SetWindowSize(win, getWinWidth(), getWinHeight()); + displayScreen(); + } + getEvents(0); + #else + clock_t cycle_timer; cycle_timer = clock(); - sd_timer = clock(); while(1) { if(!paused) { - if (clock() - sd_timer >= CLOCKS_PER_SEC/60)//update timers + if (clock() - cycle_timer >= CLOCKS_PER_SEC/60)//update timers { if(timerS > 0){timerS--;} if(timerD > 0){timerD--;} - sd_timer = clock(); - } - if(clock() - cycle_timer >= CLOCKS_PER_SEC/clock_speed)//exec cycle - { - if(!fetch()) {break;} - execute(); - displayScreen(); cycle_timer = clock(); + for (size_t i = 0; i < 500/60; i++) + { + if(!fetch()){break;} + execute(); + } + displayScreen(); } } getEvents(0); } + #endif } int main(int argc, char const *argv[]) { - #ifndef LOAD_STRING + #ifndef EMBED_TETRIS if(argc < 2 || argc > 3) { puts("Usage:"); @@ -279,7 +309,11 @@ int main(int argc, char const *argv[]) initMain(); loadString(); #endif + #ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(mainloop, 60, 1); + #else mainloop(); + #endif quit(); return 0; } diff --git a/readme.md b/readme.md index 7911be4..765b5fc 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,13 @@ # SDLchip A simple cross-platform [chip8](https://en.wikipedia.org/wiki/CHIP-8) implementation written in c using the [SDL2](https://www.libsdl.org/) graphics library. +* now with emscripten support (desktop only) [demo pwa](jarekt.github.io/sdlchip/index.html) ## Precompiled executables * check the releases tab ## How to compile -* just use cmake :) +* just use cmake :) (tested with emscripten, gcc and visual studio) ## Controls * **hexpad mapping** diff --git a/tetris.h b/tetris.h index 6d29ede..8cccce1 100644 --- a/tetris.h +++ b/tetris.h @@ -1,3 +1,3 @@ -#define LOAD_STRING const char import_string[] = {0xa2,0xb4,0x23,0xe6,0x22,0xb6,0x70,0x1,0xd0,0x11,0x30,0x25,0x12,0x6,0x71,0xff,0xd0,0x11,0x60,0x1a,0xd0,0x11,0x60,0x25,0x31,0x0,0x12,0xe,0xc4,0x70,0x44,0x70,0x12,0x1c,0xc3,0x3,0x60,0x1e,0x61,0x3,0x22,0x5c,0xf5,0x15,0xd0,0x14,0x3f,0x1,0x12,0x3c,0xd0,0x14,0x71,0xff,0xd0,0x14,0x23,0x40,0x12,0x1c,0xe7,0xa1,0x22,0x72,0xe8,0xa1,0x22,0x84,0xe9,0xa1,0x22,0x96,0xe2,0x9e,0x12,0x50,0x66,0x0,0xf6,0x15,0xf6,0x7,0x36,0x0,0x12,0x3c,0xd0,0x14,0x71,0x1,0x12,0x2a,0xa2,0xc4,0xf4,0x1e,0x66,0x0,0x43,0x1,0x66,0x4,0x43,0x2,0x66,0x8,0x43,0x3,0x66,0xc,0xf6,0x1e,0x0,0xee,0xd0,0x14,0x70,0xff,0x23,0x34,0x3f,0x1,0x0,0xee,0xd0,0x14,0x70,0x1,0x23,0x34,0x0,0xee,0xd0,0x14,0x70,0x1,0x23,0x34,0x3f,0x1,0x0,0xee,0xd0,0x14,0x70,0xff,0x23,0x34,0x0,0xee,0xd0,0x14,0x73,0x1,0x43,0x4,0x63,0x0,0x22,0x5c,0x23,0x34,0x3f,0x1,0x0,0xee,0xd0,0x14,0x73,0xff,0x43,0xff,0x63,0x3,0x22,0x5c,0x23,0x34,0x0,0xee,0x80,0x0,0x67,0x5,0x68,0x6,0x69,0x4,0x61,0x1f,0x65,0x10,0x62,0x7,0x0,0xee,0x40,0xe0,0x0,0x0,0x40,0xc0,0x40,0x0,0x0,0xe0,0x40,0x0,0x40,0x60,0x40,0x0,0x40,0x40,0x60,0x0,0x20,0xe0,0x0,0x0,0xc0,0x40,0x40,0x0,0x0,0xe0,0x80,0x0,0x40,0x40,0xc0,0x0,0x0,0xe0,0x20,0x0,0x60,0x40,0x40,0x0,0x80,0xe0,0x0,0x0,0x40,0xc0,0x80,0x0,0xc0,0x60,0x0,0x0,0x40,0xc0,0x80,0x0,0xc0,0x60,0x0,0x0,0x80,0xc0,0x40,0x0,0x0,0x60,0xc0,0x0,0x80,0xc0,0x40,0x0,0x0,0x60,0xc0,0x0,0xc0,0xc0,0x0,0x0,0xc0,0xc0,0x0,0x0,0xc0,0xc0,0x0,0x0,0xc0,0xc0,0x0,0x0,0x40,0x40,0x40,0x40,0x0,0xf0,0x0,0x0,0x40,0x40,0x40,0x40,0x0,0xf0,0x0,0x0,0xd0,0x14,0x66,0x35,0x76,0xff,0x36,0x0,0x13,0x38,0x0,0xee,0xa2,0xb4,0x8c,0x10,0x3c,0x1e,0x7c,0x1,0x3c,0x1e,0x7c,0x1,0x3c,0x1e,0x7c,0x1,0x23,0x5e,0x4b,0xa,0x23,0x72,0x91,0xc0,0x0,0xee,0x71,0x1,0x13,0x50,0x60,0x1b,0x6b,0x0,0xd0,0x11,0x3f,0x0,0x7b,0x1,0xd0,0x11,0x70,0x1,0x30,0x25,0x13,0x62,0x0,0xee,0x60,0x1b,0xd0,0x11,0x70,0x1,0x30,0x25,0x13,0x74,0x8e,0x10,0x8d,0xe0,0x7e,0xff,0x60,0x1b,0x6b,0x0,0xd0,0xe1,0x3f,0x0,0x13,0x90,0xd0,0xe1,0x13,0x94,0xd0,0xd1,0x7b,0x1,0x70,0x1,0x30,0x25,0x13,0x86,0x4b,0x0,0x13,0xa6,0x7d,0xff,0x7e,0xff,0x3d,0x1,0x13,0x82,0x23,0xc0,0x3f,0x1,0x23,0xc0,0x7a,0x1,0x23,0xc0,0x80,0xa0,0x6d,0x7,0x80,0xd2,0x40,0x4,0x75,0xfe,0x45,0x2,0x65,0x4,0x0,0xee,0xa7,0x0,0xf2,0x55,0xa8,0x4,0xfa,0x33,0xf2,0x65,0xf0,0x29,0x6d,0x32,0x6e,0x0,0xdd,0xe5,0x7d,0x5,0xf1,0x29,0xdd,0xe5,0x7d,0x5,0xf2,0x29,0xdd,0xe5,0xa7,0x0,0xf2,0x65,0xa2,0xb4,0x0,0xee,0x6a,0x0,0x60,0x19,0x0,0xee,0x37,0x23}; +const size_t import_string_size = sizeof(import_string) / sizeof(import_string[0]); //this is tetris.ch8 converted using my python script into a string \ No newline at end of file