test render loop

This commit is contained in:
Timerix 2025-03-09 18:35:56 +05:00
parent 0291279f1a
commit 4de066b6c1
7 changed files with 205 additions and 12 deletions

View File

@ -58,7 +58,7 @@ case "$TASK" in
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code # -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -67,7 +67,7 @@ case "$TASK" in
build_exec_dbg) build_exec_dbg)
C_ARGS="-O0 -g3" C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -76,7 +76,7 @@ case "$TASK" in
build_shared_lib) build_shared_lib)
C_ARGS="-O2 -fpic -flto -shared" C_ARGS="-O2 -fpic -flto -shared"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -85,7 +85,7 @@ case "$TASK" in
build_shared_lib_dbg) build_shared_lib_dbg)
C_ARGS="-O0 -g3 -fpic -shared" C_ARGS="-O0 -g3 -fpic -shared"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS -Wl,-soname,$SHARED_LIB_FILE"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -126,7 +126,7 @@ case "$TASK" in
# -fprofile-prefix-path sets path where profiling info about objects will be saved # -fprofile-prefix-path sets path where profiling info about objects will be saved
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/profile.sh TASK_SCRIPT=cbuild/default_tasks/profile.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -139,7 +139,7 @@ case "$TASK" in
# -pg adds code to executable, that generates file containing function call info (gmon.out) # -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/gprof.sh TASK_SCRIPT=cbuild/default_tasks/gprof.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -153,7 +153,7 @@ case "$TASK" in
# -pg adds code to executable, that generates file containing function call info (gmon.out) # -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin" C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/callgrind.sh TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@ -163,7 +163,7 @@ case "$TASK" in
OUTDIR="$OUTDIR/sanitize" OUTDIR="$OUTDIR/sanitize"
C_ARGS="-O0 -g3 -fsanitize=undefined,address" C_ARGS="-O0 -g3 -fsanitize=undefined,address"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/exec.sh TASK_SCRIPT=cbuild/default_tasks/exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=

90
src/VM/Display/Display.c Normal file
View File

@ -0,0 +1,90 @@
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include "Display.h"
typedef struct Display {
str name;
i32 width;
i32 height;
SDL_Window* window;
SDL_Renderer* renderer;
} Display;
static SDL_InitState sdl_init_state = {0};
Display* Display_create(str name, i32 w, i32 h, DisplayFlags flags){
Display* d = malloc(sizeof(Display));
d->name = str_copy(name);
d->width = w;
d->height = h;
d->window = NULL;
d->renderer = NULL;
if (SDL_ShouldInit(&sdl_init_state)) {
bool sdl_initialized = SDL_Init(SDL_INIT_VIDEO);
SDL_SetInitialized(&sdl_init_state, sdl_initialized);
if(!sdl_initialized)
return false;
}
SDL_WindowFlags window_flags = SDL_WINDOW_ALWAYS_ON_TOP;
if(!SDL_CreateWindowAndRenderer(d->name.data, d->width, d->height, window_flags, &d->window, &d->renderer)){
return false;
}
return d;
}
void Display_destroy(Display* d){
free(d->name.data);
SDL_DestroyRenderer(d->renderer);
SDL_DestroyWindow(d->window);
free(d);
// if (SDL_ShouldQuit(&sdl_init_state)) {
// SDL_Quit();
// SDL_SetInitialized(&sdl_init_state, false);
// }
}
bool Display_setName(Display* d, str name){
d->name = str_copy(name);
return SDL_SetWindowTitle(d->window, name.data);
}
bool Display_setSize(Display* d, u32 w, u32 h){
d->width = w;
d->height = h;
return SDL_SetWindowSize(d->window, w, h);
}
bool Display_setDrawingColor(Display* d, ColorRGBA color){
return SDL_SetRenderDrawColor(d->renderer, color.r, color.g, color.b, color.a);
}
bool Display_clear(Display* d){
return SDL_RenderClear(d->renderer);
}
#define Rect_copy(DST, SRC) {\
DST.x = SRC.x;\
DST.y = SRC.y;\
DST.w = SRC.w;\
DST.h = SRC.h;\
}
bool Display_fillRect(Display* d, Rect rect) {
SDL_FRect sdl_rect;
Rect_copy(sdl_rect, rect);
return SDL_RenderFillRect(d->renderer, &sdl_rect);
}
bool Display_swapBuffers(Display* d){
return SDL_RenderPresent(d->renderer);
}
NULLABLE(cstr) Display_getError(){
return SDL_GetError();
}

32
src/VM/Display/Display.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include "../../std.h"
#include "../../string/str.h"
typedef struct Rect {
i32 x, y;
i32 w, h;
} Rect;
#define Rect_create(X, Y, W, H) ((Rect){ .x = X, .y = Y, .w = W, .h = H})
typedef struct ColorRGBA {
u8 r, g, b, a;
} ColorRGBA;
#define ColorRGBA_create(R, G, B, A) ((ColorRGBA){ .r = R, .g = G, .b = B, .a = A })
typedef enum DisplayFlags {
DisplayFlags_Default = 0
} DisplayFlags;
typedef struct Display Display;
Display* Display_create(str name, i32 w, i32 h, DisplayFlags flags);
void Display_destroy(Display* d);
bool Display_setName(Display* d, str name);
bool Display_setSize(Display* d, u32 w, u32 h);
bool Display_setDrawingColor(Display* d, ColorRGBA color);
bool Display_clear(Display* d);
bool Display_fillRect(Display* d, Rect rect);
bool Display_swapBuffers(Display* d);
NULLABLE(cstr) Display_getError();

18
src/VM/time.c Normal file
View File

@ -0,0 +1,18 @@
#include <SDL3/SDL_timer.h>
#include "time.h"
void time_sleepMS(u32 ms){
SDL_Delay(ms);
}
void time_sleepNS(u64 ns){
SDL_DelayNS(ns);
}
u64 time_getMonotonicMS(){
SDL_GetTicks();
}
u64 time_getMonotonicNS(){
SDL_GetTicksNS();
}

8
src/VM/time.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include "../std.h"
void time_sleepMS(u32 ms);
void time_sleepNS(u64 ns);
u64 time_getMonotonicMS();
u64 time_getMonotonicNS();

View File

@ -2,13 +2,61 @@
#include "instructions/instructions.h" #include "instructions/instructions.h"
#include "collections/List.h" #include "collections/List.h"
#include "compiler/Compiler.h" #include "compiler/Compiler.h"
#include "VM/Display/Display.h"
#include <SDL3/SDL.h>
#define arg_is(STR) (strcmp(argv[argi], STR) == 0) #define arg_is(STR) (strcmp(argv[argi], STR) == 0)
i32 compileSources(cstr source_file, cstr out_file, bool debug_log); i32 compileSources(cstr source_file, cstr out_file, bool debug_log);
i32 bootFromImage(cstr image_file); i32 bootFromImage(cstr image_file);
#define assert_sdl(EXPR) if(!(EXPR)) { printf("assert failed: %s\nSDL_Error: %s\n", #EXPR, SDL_GetError()); return false; }
bool test_display(){
Display* display = Display_create(STR("le display"), 1600, 900, DisplayFlags_Default);
assert_sdl(display != NULL);
i64 fps = 60;
i64 nsec_per_frame = 1e9 / fps;
for(u32 i = 0; i < 600; i++){
static i64 last_frame_time = 0;
i64 current_frame_time = SDL_GetTicksNS();
i64 delta_time = current_frame_time - last_frame_time;
last_frame_time = current_frame_time;
SDL_Event event;
while(SDL_PollEvent(&event)) {
if(event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED){
printfe("event WINDOW_CLOSE");
return 0;
}
if(event.type == SDL_EVENT_QUIT){
printfe("event QUIT");
return 0;
}
}
assert_sdl(Display_setDrawingColor(display, ColorRGBA_create(200, 200, 200, 255)));
assert_sdl(Display_clear(display));
assert_sdl(Display_setDrawingColor(display, ColorRGBA_create(240, 40, 40, 255)));
assert_sdl(Display_fillRect(display, Rect_create(i, i, 64, 64)));
assert_sdl(Display_swapBuffers(display));
i64 time_ellapsed = SDL_GetTicksNS() - last_frame_time;
i64 delay = nsec_per_frame - time_ellapsed;
if (delay > 0) {
SDL_DelayNS(delay);
}
}
Display_destroy(display);
return true;
}
i32 main(const i32 argc, cstr* argv){ i32 main(const i32 argc, cstr* argv){
test_display();
return 0;
if(argc < 2){ if(argc < 2){
printfe("ERROR: no arguments provided. Use --help to know more.\n"); printfe("ERROR: no arguments provided. Use --help to know more.\n");
return 1; return 1;

View File

@ -8,6 +8,7 @@
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
typedef int8_t i8; typedef int8_t i8;
typedef uint8_t u8; typedef uint8_t u8;
@ -20,10 +21,6 @@ typedef uint64_t u64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
typedef u8 bool;
#define true 1
#define false 0
typedef const char* cstr; typedef const char* cstr;
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)