diff --git a/Makefile b/Makefile index fd105d5..2f4123c 100644 --- a/Makefile +++ b/Makefile @@ -10,4 +10,7 @@ build: $(SRC) run: build $(OUT) +clean: + rm $(OUT) + .PHONY: build run \ No newline at end of file diff --git a/build/main b/build/main deleted file mode 100755 index 14b1fc6..0000000 Binary files a/build/main and /dev/null differ diff --git a/src/main.c b/src/main.c index e0845de..355cfae 100644 --- a/src/main.c +++ b/src/main.c @@ -10,22 +10,38 @@ uint32_t framebuffer[WIDTH * HEIGHT]; +// alter a pixel at an imaginary x & y coordinates void put_pixel(unsigned int x, unsigned int y, uint32_t color) { + if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { + fprintf(stderr, "CRITICAL: attempted buffer overflow in put_pixel\n" + "at x = %d, y = %d", x, y); + return; + } + framebuffer[WIDTH * y + x] = color; } -int main() { - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - fprintf(stderr, "SDL_Init failed! %s\n", SDL_GetError()); - return EXIT_FAILURE; +// fill the entire framebuffer with a given color +void clear_framebuffer(uint32_t color) { + for (int i = 0; i < WIDTH * HEIGHT; i++) { + framebuffer[i] = color; } +} +int main() { SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; SDL_Event event; bool is_running = true; + const double target_frame = 1.0 / 60.0; + + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + fprintf(stderr, "SDL_Init failed! %s\n", SDL_GetError()); + return EXIT_FAILURE; + } + window = SDL_CreateWindow( "SDL Framebuffer", 0, 0, WIDTH, HEIGHT, 0 @@ -57,24 +73,51 @@ int main() { return EXIT_FAILURE; } - for (int i = 0; i < 20; i++) { - for (int j = 0; j < 20; j++) { - put_pixel(i, j, 0x00FF00); - } - } + bool left = true; while (is_running) { + uint64_t start = SDL_GetPerformanceCounter(); + while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { is_running = false; } } + // draw alternating green squares + if (left) { + clear_framebuffer(0x000000); + for (int i = 0; i < 20; i++) { + for (int j = 0; j < 20; j++) { + put_pixel(i, j, 0x00FF00); + } + } + left = false; + } else { + clear_framebuffer(0x000000); + for (int i = 20; i < 40; i++) { + for (int j = 20; j < 40; j++) { + put_pixel(i, j, 0x00FFFF); + } + } + left = true; + } + SDL_Delay(100); + SDL_UpdateTexture(texture, NULL, framebuffer, WIDTH * sizeof(uint32_t)); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); + + uint64_t end = SDL_GetPerformanceCounter(); + + double elapsed = (double)(end - start) / (double)SDL_GetPerformanceFrequency(); + + // cap the framerate at '1.0/target_frame' fps + if (elapsed < target_frame) { + SDL_Delay((target_frame - elapsed) * 1000); + } } SDL_DestroyTexture(texture);