From 539796531938760378e7601084cfcf59d753c5e0 Mon Sep 17 00:00:00 2001 From: Timerix Date: Fri, 29 Aug 2025 14:37:58 +0500 Subject: [PATCH] added video enable option --- .vscode/c_cpp_properties.json | 1 + .vscode/launch.json | 5 +- dependencies/tlibc | 2 +- examples/{window.tasm => video.tasm} | 2 +- project.config | 2 +- src/VM/Display/Display.c | 81 ++++++++++++++-------------- src/VM/Display/Display.h | 20 ++++--- src/VM/VM.c | 2 +- src/VM/VM.h | 2 +- src/compiler/AST.h | 4 +- src/compiler/Binary.h | 4 +- src/instructions/impl/impl_macros.h | 4 +- src/instructions/instructions.h | 2 +- src/main.c | 36 +++++++++---- src/tcpu_version.h | 3 ++ 15 files changed, 95 insertions(+), 75 deletions(-) rename examples/{window.tasm => video.tasm} (50%) create mode 100644 src/tcpu_version.h diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index bdbec87..616ccaf 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -5,6 +5,7 @@ "defines": [], "includePath": [ "dependencies/tlibc/include", + "src", "${default}" ], "cStandard": "c11" diff --git a/.vscode/launch.json b/.vscode/launch.json index 4e28cc7..4bc425a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,7 +7,10 @@ "request": "launch", "program": "${workspaceFolder}/bin/tcpu", "windows": { "program": "${workspaceFolder}/bin/tcpu.exe" }, - "args": [ "-c", "../examples/loop.tasm", "o.bin", "--debug", "-i", "o.bin" ], + "args": [ + "-c", "../examples/video.tasm", "o.bin", + "-i", "o.bin", "--debug", "--video" + ], "cwd": "${workspaceFolder}/bin", "preLaunchTask": "build_exec_dbg", "stopAtEntry": false, diff --git a/dependencies/tlibc b/dependencies/tlibc index 8eeaff4..c415e2c 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 8eeaff4245d0876f5c3308991ede7696254487f7 +Subproject commit c415e2ca8ff51f41984ace8fe796187e6ad0fa27 diff --git a/examples/window.tasm b/examples/video.tasm similarity index 50% rename from examples/window.tasm rename to examples/video.tasm index 58322f5..d8fe561 100644 --- a/examples/window.tasm +++ b/examples/video.tasm @@ -3,5 +3,5 @@ Example of graphical application */ .main: -//TODO: write code here +//TODO: add a way to access Event struct's fields exit diff --git a/project.config b/project.config index 57869a6..263ec4d 100755 --- a/project.config +++ b/project.config @@ -26,7 +26,7 @@ OBJDIR="obj" OUTDIR="bin" STATIC_LIB_FILE="lib$PROJECT.a" -INCLUDE="-I./dependencies/tlibc/include" +INCLUDE="-Isrc -Idependencies/tlibc/include" # OS-specific options case "$OS" in diff --git a/src/VM/Display/Display.c b/src/VM/Display/Display.c index 305dfe5..ac3c165 100644 --- a/src/VM/Display/Display.c +++ b/src/VM/Display/Display.c @@ -1,69 +1,70 @@ #include #include #include "Display.h" +#include "tcpu_version.h" typedef struct Display { - str name; i32 width; i32 height; SDL_Window* window; SDL_Renderer* renderer; } Display; -static SDL_InitState sdl_init_state = {0}; +static SDL_InitState _sdl_init_state = {0}; +static Display _d = {0}; +static cstr _title = "TCPU v" TCPU_VERSION_CSTR; - -bool Display_tryConstruct(Display* d, str name, i32 w, i32 h, DisplayFlags flags){ - d->name = str_copy(name); - d->width = w; - d->height = h; - d->window = NULL; - d->renderer = NULL; - - if (SDL_ShouldInit(&sdl_init_state)) { +bool Display_init(i32 w, i32 h, DisplayFlags flags){ + _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); + SDL_SetInitialized(&_sdl_init_state, sdl_initialized); if(!sdl_initialized) - return NULL; + 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 NULL; + if(!SDL_CreateWindowAndRenderer(_title, _d.width, _d.height, window_flags, &_d.window, &_d.renderer)){ + return false; } - return d; + return true; } -void Display_destroy(Display* d){ - free(d->name.data); - SDL_DestroyRenderer(d->renderer); - SDL_DestroyWindow(d->window); - free(d); +void Display_destroy(){ + SDL_DestroyRenderer(_d.renderer); + SDL_DestroyWindow(_d.window); - // if (SDL_ShouldQuit(&sdl_init_state)) { + // if (SDL_ShouldQuit(&_sdl_init_state)) { // SDL_Quit(); - // SDL_SetInitialized(&sdl_init_state, false); + // 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); +NULLABLE(cstr) Display_getError(){ + return SDL_GetError(); } -bool Display_setSize(Display* d, u32 w, u32 h){ - d->width = w; - d->height = h; - return SDL_SetWindowSize(d->window, w, h); +bool Display_setSize(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_setFullScreenMode(bool value){ + return SDL_SetWindowFullscreen(_d.window, value); } -bool Display_clear(Display* d){ - return SDL_RenderClear(d->renderer); +bool Display_setDrawingColor(ColorRGBA color){ + return SDL_SetRenderDrawColor(_d.renderer, color.r, color.g, color.b, color.a); +} + +bool Display_clear(){ + return SDL_RenderClear(_d.renderer); } #define Rect_copy(DST, SRC) {\ @@ -73,16 +74,12 @@ bool Display_clear(Display* d){ DST.h = SRC.h;\ } -bool Display_fillRect(Display* d, Rect rect) { +bool Display_fillRect(Rect rect) { SDL_FRect sdl_rect; Rect_copy(sdl_rect, rect); - return SDL_RenderFillRect(d->renderer, &sdl_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(); +bool Display_swapBuffers(){ + return SDL_RenderPresent(_d.renderer); } diff --git a/src/VM/Display/Display.h b/src/VM/Display/Display.h index fb7bb70..5d211a1 100644 --- a/src/VM/Display/Display.h +++ b/src/VM/Display/Display.h @@ -18,15 +18,13 @@ typedef enum DisplayFlags { DisplayFlags_Default = 0 } DisplayFlags; -typedef struct Display Display; - -bool Display_tryConstruct(Display* d, 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); +bool Display_init(i32 w, i32 h, DisplayFlags flags); +void Display_destroy(); NULLABLE(cstr) Display_getError(); + +bool Display_setSize(u32 w, u32 h); +bool Display_setFullScreenMode(bool value); +bool Display_setDrawingColor(ColorRGBA color); +bool Display_clear(); +bool Display_fillRect(Rect rect); +bool Display_swapBuffers(); diff --git a/src/VM/VM.c b/src/VM/VM.c index a6bd0e2..4515221 100644 --- a/src/VM/VM.c +++ b/src/VM/VM.c @@ -1,5 +1,5 @@ #include "VM.h" -#include "../instructions/instructions.h" +#include "instructions/instructions.h" void VM_construct(VM* vm){ memset(vm, 0, sizeof(VM)); diff --git a/src/VM/VM.h b/src/VM/VM.h index f5301c7..9f35ce9 100644 --- a/src/VM/VM.h +++ b/src/VM/VM.h @@ -1,7 +1,7 @@ #pragma once #include "tlibc/std.h" #include "tlibc/string/str.h" -#include "../instructions/registers.h" +#include "instructions/registers.h" typedef union Register { u64 rx; diff --git a/src/compiler/AST.h b/src/compiler/AST.h index 5a2fd17..dfe6336 100644 --- a/src/compiler/AST.h +++ b/src/compiler/AST.h @@ -1,8 +1,8 @@ #pragma once #include "tlibc/std.h" #include "tlibc/string/str.h" -#include "../instructions/instructions.h" -#include "../instructions/registers.h" +#include "instructions/instructions.h" +#include "instructions/registers.h" #include "tlibc/collections/List.h" typedef enum ArgumentType { diff --git a/src/compiler/Binary.h b/src/compiler/Binary.h index 08c12d6..7a08615 100644 --- a/src/compiler/Binary.h +++ b/src/compiler/Binary.h @@ -1,8 +1,8 @@ #pragma once #include "tlibc/std.h" #include "tlibc/string/str.h" -#include "../instructions/instructions.h" -#include "../instructions/registers.h" +#include "instructions/instructions.h" +#include "instructions/registers.h" #include "tlibc/collections/List.h" #include "tlibc/collections/HashMap.h" #include "AST.h" diff --git a/src/instructions/impl/impl_macros.h b/src/instructions/impl/impl_macros.h index a69a14d..0d1b6b9 100644 --- a/src/instructions/impl/impl_macros.h +++ b/src/instructions/impl/impl_macros.h @@ -1,6 +1,6 @@ #pragma once -#include "../instructions.h" -#include "../registers.h" +#include "instructions/instructions.h" +#include "instructions/registers.h" #define readVar(VAR) {\ if(!VM_dataRead(vm, &VAR, vm->current_pos, sizeof(VAR))) \ diff --git a/src/instructions/instructions.h b/src/instructions/instructions.h index 053c521..5d7be7e 100644 --- a/src/instructions/instructions.h +++ b/src/instructions/instructions.h @@ -1,5 +1,5 @@ #pragma once -#include "../VM/VM.h" +#include "VM/VM.h" ///@param program_pos position in vm->program next afrer opcode ///@returns number of bytes read diff --git a/src/main.c b/src/main.c index f139590..8da3196 100644 --- a/src/main.c +++ b/src/main.c @@ -1,8 +1,9 @@ #include "VM/VM.h" #include "instructions/instructions.h" -#include "tlibc/collections/List.h" #include "compiler/Compiler.h" #include "VM/Display/Display.h" +#include "tcpu_version.h" +#include "tlibc/time.h" #define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL)) @@ -23,16 +24,18 @@ i32 main(const i32 argc, cstr* argv){ cstr NULLABLE(source_file) = NULL; bool debug_log = false; + bool video_enabled = false; for(i32 argi = 1; argi < argc; argi++){ str arg_str = str_from_cstr(argv[argi]); if(arg_is("-h") || arg_is("--help")){ printf( "-h, --help Show this message.\n" - "-op, --opcodes Show list of all instructions.\n" - "-i, --image [FILE] Boot VM using image file.\n" - "-c, --compile [SOURCE_FILE] [OUT_FILE] Compile assembly source files to machine code.\n" "-d, --debug Enable debug log.\n" + "-op, --opcodes Show list of all instructions.\n" + "-c, --compile [SOURCE_FILE] [OUT_FILE] Compile assembly source files to machine code.\n" + "-i, --image [FILE] Boot VM using image file.\n" + "--video Enable VM display.\n" ); return 0; } @@ -80,6 +83,10 @@ i32 main(const i32 argc, cstr* argv){ else if(arg_is("-d") || arg_is("--debug")){ debug_log = true; } + else if(arg_is("--video")){ + video_enabled = true; + } + else { printfe("ERROR: unknown argument '%s'\n", argv[argi]); return 1; @@ -89,12 +96,24 @@ i32 main(const i32 argc, cstr* argv){ i32 exit_code = 0; if(compile){ exit_code = compileSources(source_file, out_file, debug_log); + if(exit_code != 0) + goto main_exit; } - if(exit_code == 0 && boot){ + + if(boot){ + printfe("TCPU version: " TCPU_VERSION_CSTR "\n"); + if(video_enabled){ + printfe("video enabled\n"); + if(!Display_init(1600, 900, DisplayFlags_Default)){ + printfe("DISPLAY ERROR: %s\n", Display_getError()); + return 1; + } + } exit_code = bootFromImage(image_file); } // frees global variables to supress valgrind memory leak errors +main_exit: Instruction_destroySearchStructs(); return exit_code; } @@ -123,7 +142,10 @@ i32 bootFromImage(cstr image_file){ i32 exit_code = 1; if(VM_setMemory(&vm, vm_memory, bytes_read)){ + printf("===============================================================================\n"); exit_code = VM_boot(&vm); + printf("===============================================================================\n"); + printfe("VM stopped with code %i\n", exit_code); } if(vm.state == VMState_InternalError){ if(vm.error_message){ @@ -133,10 +155,6 @@ i32 bootFromImage(cstr image_file){ else printfe("VM ERROR: unknown (error_message is null)\n"); } - if(exit_code != 0){ - printfe("program exited with code %i\n", exit_code); - } - free(vm_memory); return exit_code; } diff --git a/src/tcpu_version.h b/src/tcpu_version.h new file mode 100644 index 0000000..6ec1cc5 --- /dev/null +++ b/src/tcpu_version.h @@ -0,0 +1,3 @@ +#pragma once + +#define TCPU_VERSION_CSTR "1.0.0"