/******************************************************************************************* * * raygui - custom file dialog to load image * * DEPENDENCIES: * raylib 4.0 - Windowing/input management and drawing. * raygui 3.0 - Immediate-mode GUI controls. * * COMPILATION (Windows - MinGW): * gcc -o $(NAME_PART).exe $(FILE_NAME) -I../../src -lraylib -lopengl32 -lgdi32 -std=c99 * * LICENSE: zlib/libpng * * Copyright (c) 2016-2023 Ramon Santamaria (@raysan5) * **********************************************************************************************/ #include "raylib.h" #define RAYGUI_IMPLEMENTATION #include "raygui.h" #undef RAYGUI_IMPLEMENTATION // Avoid including raygui implementation again #define GUI_FILE_DIALOG_IMPLEMENTATION #include "gui_file_dialog.h" #include "chip32_vm.h" #include int set_filename_from_memory(chip32_ctx_t *ctx, uint32_t addr, char *filename_mem) { int valid = 0; // Test if address is valid bool isRam = addr & 0x80000000; addr &= 0xFFFF; // mask the RAM/ROM bit, ensure 16-bit addressing if (isRam) { strcpy(&filename_mem[0], (const char *)&ctx->ram.mem[addr]); } else { strcpy(&filename_mem[0], (const char *)&ctx->rom.mem[addr]); } return valid; } chip32_result_t vm_load_script(chip32_ctx_t *ctx, const char *filename) { chip32_result_t run_result = VM_FINISHED; FILE *fp = fopen(filename, "rb"); if (fp != NULL) { fseek(fp, 0L, SEEK_END); long int sz = ftell(fp); fseek(fp, 0L, SEEK_SET); if (sz <= ctx->rom.size) { fread(ctx->rom.mem, sz, 1, fp); run_result = VM_OK; chip32_initialize(ctx); } fclose(fp); } return run_result; } #define MAX_PATH 260 void get_home_path(char *homedir) { #ifdef _WIN32 snprintf(homedir, MAX_PATH, "%s%s", getenv("HOMEDRIVE"), getenv("HOMEPATH")); #else snprintf(homedir, MAX_PATH, "%s", getenv("HOME")); #endif } void get_parent_dir(const char *path, char *parent) { int parentLen; char* last = strrchr(path, '/'); if (last != NULL) { parentLen = strlen(path) - strlen(last + 1); strncpy(parent, path, parentLen); } } static Music gMusic; static char root_dir[260]; static bool gMusicLoaded = false; static Texture texture = { 0 }; #define EV_BUTTON_OK 0x01 #define EV_BUTTON_LEFT 0x02 #define EV_BUTTON_RIGHT 0x04 uint8_t story_player_syscall(chip32_ctx_t *ctx, uint8_t code) { uint8_t retCode = SYSCALL_RET_OK; static char image_path[260]; static char sound_path[260]; if (code == 1) // // Execute media { printf("SYSCALL 1\n"); fflush(stdout); // UnloadTexture(*tex); // *tex = if (ctx->registers[R0] != 0) { // sound file name address is in R1 char image[100]; set_filename_from_memory(ctx, ctx->registers[R0], image); strcpy(image_path, root_dir); strcat(image_path, "images/"); strcat(image_path, image); texture = LoadTexture(image_path); } else { UnloadTexture(texture); } if (ctx->registers[R1] != 0) { // sound file name address is in R1 char sound[100]; set_filename_from_memory(ctx, ctx->registers[R1], sound); strcpy(sound_path, root_dir); strcat(sound_path, "sounds/"); strcat(sound_path, sound); gMusic = LoadMusicStream(sound_path); gMusic.looping = false; gMusicLoaded = true; if (IsMusicReady(gMusic)) { PlayMusicStream(gMusic); } } retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause } else if (code == 2) // Wait Event { printf("SYSCALL 2\n"); fflush(stdout); retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause } return retCode; } //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ int main() { // VM Stuff //--------------------------------------------------------------------------------------- uint8_t rom_data[16*1024]; uint8_t ram_data[16*1024]; chip32_ctx_t chip32_ctx; chip32_ctx.stack_size = 512; chip32_ctx.rom.mem = rom_data; chip32_ctx.rom.addr = 0; chip32_ctx.rom.size = sizeof(rom_data); chip32_ctx.ram.mem = ram_data; chip32_ctx.ram.addr = sizeof(rom_data); chip32_ctx.ram.size = sizeof(ram_data); chip32_ctx.syscall = story_player_syscall; chip32_result_t run_result = VM_FINISHED; // Directories //--------------------------------------------------------------------------------------- char homedir[MAX_PATH]; get_home_path(homedir); // Initialization //--------------------------------------------------------------------------------------- int screenWidth = 800; int screenHeight = 560; InitWindow(screenWidth, screenHeight, "OpenStoryTeller - Player"); SetExitKey(0); Font fontTtf = LoadFontEx("Inter-Regular.ttf", 14, 0, 0); GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0x133D42ff); GuiSetStyle(DEFAULT, TEXT_SIZE, 14); GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x6DBFB2ff); GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0xffffffff); GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0x2D7D85FF); GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0x6DBFB2ff); GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0xEA471Aff); GuiSetFont(fontTtf); // Custom file dialog GuiFileDialogState fileDialogState = InitGuiFileDialog(GetWorkingDirectory()); strcpy(fileDialogState.filterExt, ".c32"); strcpy(fileDialogState.dirPathText, homedir); Texture2D logoTexture = LoadTexture("logo-color2.png"); bool exitWindow = false; char fileNameToLoad[512] = { 0 }; InitAudioDevice(); UnloadMusicStream(gMusic); SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop while (!exitWindow) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- exitWindow = WindowShouldClose(); if (fileDialogState.SelectFilePressed) { if (IsFileExtension(fileDialogState.fileNameText, ".c32")) { strcpy(fileNameToLoad, TextFormat("%s/%s", fileDialogState.dirPathText, fileDialogState.fileNameText)); run_result = vm_load_script(&chip32_ctx, fileNameToLoad); get_parent_dir(fileNameToLoad, root_dir); printf("Root directory: %s\n", root_dir); } fileDialogState.SelectFilePressed = false; } // VM next instruction if (run_result == VM_OK) { run_result = chip32_step(&chip32_ctx); } if (gMusicLoaded) { UpdateMusicStream(gMusic); if (!IsMusicStreamPlaying(gMusic)) { StopMusicStream(gMusic); UnloadMusicStream(gMusic); gMusicLoaded = false; run_result = VM_OK; // continue VM execution } } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(GetColor(GuiGetStyle(DEFAULT, BACKGROUND_COLOR))); DrawTextureEx(logoTexture, (Vector2){ (float)10, (float)10 }, 0, 0.15, WHITE); // Image de l'histoire DrawRectangle(220, 25, 320, 240, WHITE); DrawTexture(texture, 220, 25, WHITE); GuiSetIconScale(3); if (GuiButton((Rectangle){ 20, 140, 60, 60 }, "#05#")) { fileDialogState.windowActive = true; } // ICON_PLAYER_PAUSE if (GuiButton((Rectangle){ 20 + 65, 140, 60, 60 }, "#132#")) { } // ICON_HOUSE if (GuiButton((Rectangle){ 20 + 2*65, 140, 60, 60 }, "#185#")) { } // ICON_ARROW_LEFT if (GuiButton((Rectangle){ 20, 205, 60, 60 }, "#114#")) { if (run_result == VM_WAIT_EVENT) { chip32_ctx.registers[R0] = EV_BUTTON_LEFT; run_result = VM_OK; } } // ICON_OK_TICK if (GuiButton((Rectangle){ 20 + 65, 205, 60, 60 }, "#112#")) { if (run_result == VM_WAIT_EVENT) { chip32_ctx.registers[R0] = EV_BUTTON_OK; run_result = VM_OK; } } // ICON_ARROW_RIGHT if (GuiButton((Rectangle){ 20 + 2*65, 205, 60, 60 }, "#115#")) { if (run_result == VM_WAIT_EVENT) { chip32_ctx.registers[R0] = EV_BUTTON_RIGHT; run_result = VM_OK; } } // raygui: controls drawing //---------------------------------------------------------------------------------- if (fileDialogState.windowActive) GuiLock(); GuiUnlock(); // GUI: Dialog Window //-------------------------------------------------------------------------------- GuiSetIconScale(1); GuiFileDialog(&fileDialogState); //-------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- UnloadTexture(logoTexture); // Unload texture UnloadTexture(texture); // Unload texture CloseAudioDevice(); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- return 0; }