diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/CrocParty.iml b/.idea/CrocParty.iml new file mode 100644 index 0000000..f08604b --- /dev/null +++ b/.idea/CrocParty.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5eaf15e --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..675c11c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f9de7b7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.27) +project(CrocParty C) + +set(CMAKE_C_STANDARD 11) + +add_subdirectory(vendored/sdl EXCLUDE_FROM_ALL) +add_executable(CrocParty main.c + sdl_host.c + sdl_host.h + game.c + game.h + device.c + device.h +) +target_link_libraries(CrocParty PRIVATE SDL2::SDL2-static) diff --git a/device.c b/device.c new file mode 100644 index 0000000..d29db0c --- /dev/null +++ b/device.c @@ -0,0 +1,3 @@ +#include "device.h" + +uint32_t device_pixels[DEVICE_H][DEVICE_W]; diff --git a/device.h b/device.h new file mode 100644 index 0000000..61b7872 --- /dev/null +++ b/device.h @@ -0,0 +1,12 @@ +#ifndef CROCPARTY_DEVICE_H +#define CROCPARTY_DEVICE_H + +#include + +// 240 x 135 is also cool +#define DEVICE_W 128 +#define DEVICE_H 128 + +extern uint32_t device_pixels[DEVICE_H][DEVICE_W]; + +#endif //CROCPARTY_DEVICE_H diff --git a/game.c b/game.c new file mode 100644 index 0000000..9b9c065 --- /dev/null +++ b/game.c @@ -0,0 +1,29 @@ +#include "device.h" +#include "game.h" + +uint32_t game_frame; + +void game_init() { + game_frame = 0; +} + +void game_update() { + game_frame += 1; +} + +void game_draw() { + for (int x = 0; x < DEVICE_W; x++) { + for (int y = 0; y < DEVICE_H; y++) { + uint32_t r = (x * 255)/DEVICE_W; + uint32_t g = (y * 255)/DEVICE_H; + uint32_t b = game_frame & 0xff; + if (x % 4 == 2 && y % 4 == 2) { + r = 255 - r; + g = 255 - g; + b = 255 - b; + } + uint32_t color = r << 24 | g << 16 | b << 8; + device_pixels[y][x] = color; + } + } +} diff --git a/game.h b/game.h new file mode 100644 index 0000000..f4c7b99 --- /dev/null +++ b/game.h @@ -0,0 +1,8 @@ +#ifndef CROCPARTY_GAME_H +#define CROCPARTY_GAME_H + +void game_init(); +void game_update(); +void game_draw(); + +#endif //CROCPARTY_GAME_H diff --git a/main.c b/main.c new file mode 100644 index 0000000..7f4fdad --- /dev/null +++ b/main.c @@ -0,0 +1,9 @@ +#include "sdl_host.h" + +int main() { + // PYREX NOTE: You could, if you wanted, define another host with the same interface as sdl_host + // That would be pretty cool, right? + // + // (Such a host might be smaller and more platform-specific.) + return sdl_host_main(); +} diff --git a/sdl_host.c b/sdl_host.c new file mode 100644 index 0000000..cdb5f45 --- /dev/null +++ b/sdl_host.c @@ -0,0 +1,147 @@ +#include +#include + +#include "sdl_host.h" +#include "vendored/sdl/include/SDL.h" +#include "game.h" +#include "device.h" + +void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h); +void sdl_host_loop(); + +SDL_Window* sdl_host_window; +SDL_Renderer* sdl_host_renderer; +SDL_Texture* sdl_host_target; + +int sdl_host_main(void) { + int result = 0; + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) { + printf("could not initialize SDL! sdl error: %s\n", SDL_GetError()); + result = 1; + goto sdl_done; + } + + uint32_t window_w, window_h; + sdl_host_suggest_dimensions(&window_w, &window_h); + + // create window + sdl_host_window = SDL_CreateWindow( + "Croc Party!", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + (int) window_w, (int) window_h, + SDL_WINDOW_SHOWN + ); + + if (sdl_host_window == NULL) { + printf("could not load window! sdl error: %s\n", SDL_GetError()); + result = 1; + goto window_done; + } + + // create renderer + sdl_host_renderer = SDL_CreateRenderer(sdl_host_window, -1, 0); + if (sdl_host_renderer == NULL) { + result = 1; + goto renderer_done; + } + + // create target + sdl_host_target = SDL_CreateTexture( + sdl_host_renderer, + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_STREAMING, + DEVICE_W, DEVICE_H + ); + + if (sdl_host_target == NULL) { + printf("could not create target texture! sdl error: %s\n", SDL_GetError()); + result = 1; + goto target_done; + } + + sdl_host_loop(); + + // renderer_cleanup: + SDL_DestroyRenderer(sdl_host_renderer); + sdl_host_renderer = NULL; + renderer_done: ; + + // target_cleanup: + SDL_DestroyTexture(sdl_host_target); + sdl_host_target = NULL; + target_done: ; + + // window_cleanup: + SDL_DestroyWindow(sdl_host_window); + sdl_host_window = NULL; + window_done: ; + + // sdl_cleanup: + SDL_Quit(); + sdl_done: ; + + return result; +} + +void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h) { + SDL_DisplayMode dm; + if (SDL_GetCurrentDisplayMode(0, &dm) != 0) { + printf("could not get current display mode: %s\n", SDL_GetError()); + dm.w = 0; + dm.h = 0; + } + + for (int scalar = 5; scalar >= 1; scalar--) { + uint32_t w = DEVICE_W * scalar; + uint32_t h = DEVICE_H * scalar; + if (w <= dm.w && h <= dm.h) { + *window_w = w; + *window_h = h; + return; + } + } + + for (int scalar = 1; scalar <= 5; scalar++) { + uint32_t w = DEVICE_W / scalar; + uint32_t h = DEVICE_H / scalar; + if (w <= dm.w && h <= dm.h) { + *window_w = w; + *window_h = h; + return; + } + } + + *window_w = DEVICE_W; + *window_h = DEVICE_H; +} + +void sdl_host_loop() { + uint32_t ticks_per_frame = 1000/60; + + game_init(); + while (true) { + uint32_t frame_start = SDL_GetTicks(); + uint32_t next_frame_start = frame_start + ticks_per_frame; + + SDL_Event e; + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT) { goto quit; } + } + + // trigger game logic + game_update(); + game_draw(); + + SDL_UpdateTexture(sdl_host_target, NULL, &device_pixels, sizeof(device_pixels[0])); + SDL_RenderClear(sdl_host_renderer); + SDL_RenderCopy(sdl_host_renderer, sdl_host_target, NULL, NULL); + SDL_RenderPresent(sdl_host_renderer); + + // hold off until next frame + while (SDL_GetTicks() < next_frame_start) { + SDL_Delay(1); + } + } + quit: ; +} \ No newline at end of file diff --git a/sdl_host.h b/sdl_host.h new file mode 100644 index 0000000..4b5bec9 --- /dev/null +++ b/sdl_host.h @@ -0,0 +1,6 @@ +#ifndef CROCPARTY_SDL_HOST_H +#define CROCPARTY_SDL_HOST_H + +int sdl_host_main(void); + +#endif //CROCPARTY_SDL_HOST_H