diff --git a/.idea/scopes/Chisel_8.xml b/.idea/scopes/Chisel_8.xml index 2359fca..eaa88ea 100644 --- a/.idea/scopes/Chisel_8.xml +++ b/.idea/scopes/Chisel_8.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/README.md b/README.md index a059e86..d72da9d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# ![ICON](pictures/icon.png) chisel8 +

+title +

+ Compact Hexadecimal Interpretive Programming – 8-bit (Chip-8 Interpreter), written in C with use of the [Raylib](https://github.com/raysan5/raylib) and [Raygui](https://github.com/raysan5/raygui) libraries. Special thanks to everyone in the [EmuDev Discord Server](https://discord.com/invite/7nuaqZ2) that helped out with fixing some issues and handling undefined behaviour, as well as the test ROMS from [Timendus's Chip8 test suite](https://github.com/Timendus/chip8-test-suite). @@ -6,11 +9,12 @@ the test ROMS from [Timendus's Chip8 test suite](https://github.com/Timendus/chi ### Pictures
Menu +settings IBM LOGO Chip-8 TTS LOGO corax+ flags -settings +quirks
--- @@ -21,15 +25,10 @@ Currently, all opcodes are implemented and all of them except for a few work as - [X] MacOS, Linux and Windows platform support. (See: [raylib: supported platforms](https://www.raylib.com/#supported-platforms)) - [X] Loading of .ch8 ROM files - [X] Supports all opcodes for the original [Chip-8](https://emu.gulrak.net/reference/opcodes/) system -- [X] Settings.txt to change background and pixel color values as well as the display scaling +- [X] Settings to change background and pixel color values as well as the beep volume - [X] Chip-8 Audio emulation (it's just a beep...) - [X] Correct keypad input - [X] Settings panel to change color, display scale and debug/FPS info in the application -- [ ] Loading previous ROM files for quick access via "Load ROM" -- [ ] Custom Font support (via external binary file or other means) - - -**Scrapped**: ~~External Debug window to show RAM contents, fetched/executed opcodes etc.~~ ``` Please report any bugs via GitHub on the issue page. Thank you! @@ -63,11 +62,15 @@ You will now need to provide the ANGLE dylibs in `external/angle-lib/`: ``` File tree: -root/ +chisel8/ |-- external/ |-- angle-lib/ |-- libEGL.dylib |-- libGLESv2.dylib + + |-- raylib-stable/ + |-- raygui-stable/ + ... ``` Without these libraries, ANGLE won't be able to be loaded & compiled against. If both of these are in their respective directory, you can continue as follows: diff --git a/include/core/emu_core.h b/include/core/emu_core.h index 78656e8..96bc936 100644 --- a/include/core/emu_core.h +++ b/include/core/emu_core.h @@ -31,5 +31,6 @@ #include "core/emu_definition.h" #include "gui/options_window.h" +int32_t undefined(int32_t instruct); int32_t fetch(emu *chip8); int32_t decode_exec(emu *chip, options_config *config); \ No newline at end of file diff --git a/include/core/emu_definition.h b/include/core/emu_definition.h index 74b68ba..7f04651 100644 --- a/include/core/emu_definition.h +++ b/include/core/emu_definition.h @@ -35,7 +35,7 @@ #define DISPLAY_WIDTH 64 #define DISPLAY_HEIGHT 32 #define REFRESH_RATE 60 -#define CLOCK_RATE 700 +#define CLOCK_RATE 600 // FONT static uint8_t FONT[FONT_SIZE] = { diff --git a/include/gui/options_window.h b/include/gui/options_window.h index 30db366..fdbe544 100644 --- a/include/gui/options_window.h +++ b/include/gui/options_window.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include #include #include @@ -45,6 +46,8 @@ typedef struct Options_config{ typedef struct Interface_scaling{ int32_t window_width; int32_t window_height; + int32_t emu_width; + int32_t emu_height; float button_width; float button_height; @@ -53,7 +56,5 @@ typedef struct Interface_scaling{ int32_t font_size; } ui_scale; -void create_config(options_config *config); void load_settings(options_config *config); -int32_t write_settings(options_config *config); int32_t options_window(options_config *config, ui_scale *scale); \ No newline at end of file diff --git a/pictures/icon.png b/pictures/icon.png index ec07b10..f13f03a 100644 Binary files a/pictures/icon.png and b/pictures/icon.png differ diff --git a/pictures/menu.png b/pictures/menu.png index 82c8f6f..b3a438e 100644 Binary files a/pictures/menu.png and b/pictures/menu.png differ diff --git a/pictures/quirks.png b/pictures/quirks.png new file mode 100644 index 0000000..5dfda49 Binary files /dev/null and b/pictures/quirks.png differ diff --git a/pictures/settings.png b/pictures/settings.png index 107738e..ddb5ffa 100644 Binary files a/pictures/settings.png and b/pictures/settings.png differ diff --git a/pictures/title.png b/pictures/title.png new file mode 100644 index 0000000..c4bdab2 Binary files /dev/null and b/pictures/title.png differ diff --git a/pictures/title.xcf b/pictures/title.xcf new file mode 100644 index 0000000..df7351e Binary files /dev/null and b/pictures/title.xcf differ diff --git a/src/core/emu_core.c b/src/core/emu_core.c index a5fdfe4..28086b1 100644 --- a/src/core/emu_core.c +++ b/src/core/emu_core.c @@ -26,8 +26,8 @@ #include "core/emu_core.h" -int32_t undefined(void) { // Handles undefined behaviour - TraceLog(LOG_ERROR, "EMU_CORE -> COULD NOT DECODE INSTRUCTION!"); +int32_t undefined(int32_t opcode) { // Handles undefined behaviour + TraceLog(LOG_ERROR, "EMU_CORE -> COULD NOT DECODE INSTRUCTION %04x!", opcode); return -1; } @@ -36,7 +36,7 @@ int32_t fetch(emu *chip8) { // Fetches instruction chip8->opcode <<= 8; chip8->opcode += chip8->ram[chip8->pc++]; if (chip8->opcode == 0x0000) { - return undefined(); + return undefined(0x000); } return 0; } @@ -65,7 +65,7 @@ int32_t decode_exec(emu *chip8, options_config *config) { chip8->i_stack -= 1; } else { - return undefined(); + return undefined(chip8->opcode); } break; @@ -92,13 +92,13 @@ int32_t decode_exec(emu *chip8, options_config *config) { break; case (0x5): - if (chip8->reg[X] == chip8->reg[Y]) { + if (chip8->reg[X] == chip8->reg[Y] && N1 == 0) { chip8->pc += 2; } break; case (0x9): - if (chip8->reg[X] != chip8->reg[Y]) { + if (chip8->reg[X] != chip8->reg[Y] && N1 == 0) { chip8->pc += 2; } break; @@ -184,7 +184,7 @@ int32_t decode_exec(emu *chip8, options_config *config) { break; default: - return undefined(); + return undefined(chip8->opcode); } break; @@ -205,17 +205,15 @@ int32_t decode_exec(emu *chip8, options_config *config) { if (N2 == 0x9e) { if (chip8->key == chip8->reg[X]) { chip8->pc += 2; - chip8->key = -1; } } else if (N2 == 0xa1) { if (chip8->key != chip8->reg[X]) { chip8->pc += 2; - chip8->key = -1; } } else { - return undefined(); + return undefined(chip8->opcode); } break; @@ -245,10 +243,10 @@ int32_t decode_exec(emu *chip8, options_config *config) { break; case (0x0a): - if (chip8->key != -1) { - chip8->reg[X] = chip8->key; - } else { + if (chip8->key == -1) { chip8->pc -= 2; + } else { + chip8->reg[X] = chip8->key; } break; @@ -276,7 +274,7 @@ int32_t decode_exec(emu *chip8, options_config *config) { break; default: - return undefined(); + return undefined(chip8->opcode); } break; @@ -315,7 +313,7 @@ int32_t decode_exec(emu *chip8, options_config *config) { break; default: - return undefined(); + return undefined(0x0000); } return 0; } \ No newline at end of file diff --git a/src/core/emu_main.c b/src/core/emu_main.c index 6f67e58..bbadcf5 100644 --- a/src/core/emu_main.c +++ b/src/core/emu_main.c @@ -70,8 +70,6 @@ void check_input(emu *chip8) { // I'm sorry, I tried it with a switch but chip8->key = 0xb; } else if (IsKeyDown(KEY_V)) { chip8->key = 0xf; - } else { - chip8->key = -1; } } @@ -152,12 +150,27 @@ int32_t emu_main(options_config *config, ui_scale *scale) { BeginDrawing(); ClearBackground(BLACK); + if (IsKeyPressed(KEY_F11)) { + if (!IsWindowFullscreen()) { + SetWindowSize(GetMonitorWidth(GetCurrentMonitor()), GetMonitorHeight(GetCurrentMonitor())); + ToggleFullscreen(); + } else { + ToggleFullscreen(); + SetWindowSize(scale->window_width, scale->window_height); + } + } + if (IsWindowResized()) { // Magic to enable dynamic scaling config->display_scaling = (uint32_t) fminf(GetScreenWidth() / (float) DISPLAY_WIDTH, GetScreenHeight() / (float) DISPLAY_HEIGHT); - scale->window_width = DISPLAY_WIDTH * config->display_scaling; - scale->window_height = DISPLAY_HEIGHT * config->display_scaling; + if (!IsWindowFullscreen()) { + scale->window_width = GetScreenWidth(); + scale->window_height = GetScreenHeight(); + } + + scale->emu_width = DISPLAY_WIDTH * config->display_scaling; + scale->emu_height = DISPLAY_HEIGHT * config->display_scaling; scale->button_width = (float) (GetScreenWidth() / 4.8); scale->button_height = (float) ((float) GetScreenHeight() / 16); @@ -172,33 +185,36 @@ int32_t emu_main(options_config *config, ui_scale *scale) { // Draw Pixels from virtual Texture DrawTexturePro(chip8.display, (Rectangle) {0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT}, - (Rectangle) {(GetScreenWidth() - scale->window_width) / 2, - (GetScreenHeight() - scale->window_height) / 2, scale->window_width, - scale->window_height}, (Vector2) {0, 0}, 0, WHITE); + (Rectangle) {(GetScreenWidth() - scale->emu_width) / 2, + (GetScreenHeight() - scale->emu_height) / 2, + scale->emu_width, + scale->emu_height}, (Vector2) {0, 0}, 0, WHITE); - DrawRectangleLines(((GetScreenWidth() - scale->window_width) / 2) - 1, - (((GetScreenHeight() - scale->window_height) / 2)) - 1, scale->window_width + 2, - scale->window_height + 2, DARKGRAY); + DrawRectangleLines(((GetScreenWidth() - scale->emu_width) / 2) - 1, + (((GetScreenHeight() - scale->emu_height) / 2)) - 1, + scale->emu_width + 2, + scale->emu_height + 2, DARKGRAY); if (config->show_fps) { - DrawText(TextFormat("%dhz", GetFPS() + 1), (int32_t) config->display_scaling, + DrawText(TextFormat("%dhz", GetFPS()), (int32_t) config->display_scaling, (int32_t) config->display_scaling / 2, (int32_t) (scale->font_size / 1.8), DARKGREEN); } + check_input(&chip8); for (int32_t i = 0; i < (int32_t) (CLOCK_RATE / REFRESH_RATE); ++i) { - check_input(&chip8); if (!undefined && fetch(&chip8) == -1) { undefined = true; - TraceLog(LOG_INFO, "EMU_MAIN -> Pausing emulation!"); + TraceLog(LOG_WARNING, "EMU_MAIN -> Stopping further cycles!"); continue; } if (!undefined && decode_exec(&chip8, config) == -1) { undefined = true; - TraceLog(LOG_INFO, "EMU_MAIN -> Pausing emulation!"); + TraceLog(LOG_WARNING, "EMU_MAIN -> Stopping further cycles!"); continue; } } + chip8.key = -1; if (chip8.delay > 0) { chip8.delay -= REFRESH_RATE; diff --git a/src/gui/main_window.c b/src/gui/main_window.c index c69161d..01cce0d 100644 --- a/src/gui/main_window.c +++ b/src/gui/main_window.c @@ -35,17 +35,18 @@ #include "gui/main_window.h" void main_window(options_config *config) { - ui_scale scale; - // Show debug info? - if (config->show_debug == true) { + if (config->show_debug == true) { // Show debug info? SetTraceLogLevel(LOG_INFO); } else { - SetTraceLogLevel(LOG_ERROR); + SetTraceLogLevel(LOG_WARNING); } + ui_scale scale; scale.window_width = DISPLAY_WIDTH * config->display_scaling; scale.window_height = DISPLAY_HEIGHT * config->display_scaling; + scale.emu_width = DISPLAY_WIDTH * config->display_scaling; + scale.emu_height = DISPLAY_HEIGHT * config->display_scaling; SetConfigFlags(FLAG_WINDOW_RESIZABLE); @@ -57,108 +58,102 @@ void main_window(options_config *config) { scale.font_size = (GetScreenHeight() / (int32_t) config->display_scaling); GuiLoadStyleDark(); + GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 1023); // Set window box colour, no idea what the value is, but it works - enum menu_state_counter { - normal, options, init - }; - uint32_t menu_state = normal; + bool is_options = false; SetTargetFPS(REFRESH_RATE); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(BLACK); + //---------------------------------------------------------------------------------- + // WINDOW EVENTS + //---------------------------------------------------------------------------------- + + if (IsKeyPressed(KEY_F11)) { + if (!IsWindowFullscreen()) { + SetWindowSize(GetMonitorWidth(GetCurrentMonitor()), GetMonitorHeight(GetCurrentMonitor())); + ToggleFullscreen(); + } else { + ToggleFullscreen(); + SetWindowSize(scale.window_width, scale.window_height); + } + } + if (IsWindowResized()) { // Magic to enable dynamic scaling config->display_scaling = (uint32_t) fminf(GetScreenWidth() / (float) DISPLAY_WIDTH, GetScreenHeight() / (float) DISPLAY_HEIGHT); - scale.window_width = DISPLAY_WIDTH * config->display_scaling; - scale.window_height = DISPLAY_HEIGHT * config->display_scaling; + if (!IsWindowFullscreen()) { + scale.window_width = GetScreenWidth(); + scale.window_height = GetScreenHeight(); + } + + scale.emu_width = DISPLAY_WIDTH * config->display_scaling; + scale.emu_height = DISPLAY_HEIGHT * config->display_scaling; scale.button_width = (float) (GetScreenWidth() / 4.8); scale.button_height = (float) ((float) GetScreenHeight() / 16); scale.button_x = (float) ((float) GetScreenWidth() / 2 - (GetScreenWidth() / 9.6)); - scale.font_size = (scale.window_width / scale.window_height) * (int32_t) config->display_scaling; + scale.font_size = (scale.emu_width / scale.emu_height) * (int32_t) config->display_scaling; GuiSetStyle(DEFAULT, TEXT_SIZE, (int32_t) (scale.font_size / 1.8)); GuiSetIconScale((int32_t) (scale.font_size / 1.8) / 16); } - if (IsFileDropped() && menu_state != options) { // Initialize Emulation + if (IsFileDropped()) { // Initialize Emulation EndDrawing(); if (emu_main(config, &scale) == -2) { break; } - menu_state = normal; - } else { - UnloadDroppedFiles(LoadDroppedFiles()); } - SetWindowTitle(WINDOW_TITLE VERSION); - switch (menu_state) { - /*-------------------------------------------------------------------------------------------------------------*/ - case (normal): - DrawText("Chisel8 Emulator", GetScreenWidth() / 2 - (scale.font_size * 4), (GetScreenHeight() / 12), - scale.font_size, RAYWHITE); - - if (GuiButton((Rectangle) {scale.button_x, GetScreenHeight() / 2 - GetScreenHeight() / 6 - 10, - scale.button_width, scale.button_height}, - GuiIconText(ICON_ROM, "Load ROM"))) { - menu_state = init; - } - - if (GuiButton((Rectangle) {scale.button_x, GetScreenHeight() / 2 - GetScreenHeight() / 16, - scale.button_width, scale.button_height}, - GuiIconText(ICON_GEAR, "Settings"))) { - menu_state = options; - } - - if (GuiButton((Rectangle) {GetScreenWidth() - scale.button_height * 1.5, - GetScreenHeight() - scale.button_height * 1.5, - scale.button_height, scale.button_height}, - GuiIconText(ICON_INFO, ""))) { - OpenURL("https://github.com/npxtune/chisel8"); - } - - if (GuiButton((Rectangle) {scale.button_x, GetScreenHeight() - (GetScreenHeight() / 6), - scale.button_width, scale.button_height}, - GuiIconText(ICON_EXIT, "Quit"))) { - EndDrawing(); - CloseWindow(); - return; - } - break; - - /*-------------------------------------------------------------------------------------------------------------*/ - - case (options): - menu_state = options_window(config, &scale); - break; - - /*-------------------------------------------------------------------------------------------------------------*/ - - case (init): - SetExitKey(KEY_NULL); - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, 0.2f)); - DrawText("Please drag a ROM file into the window", - GetScreenWidth() / 2 - (scale.font_size * 10) + (scale.font_size / 2), - (GetScreenHeight() / 2) - scale.font_size * 1.5, scale.font_size, RAYWHITE); - - if (GuiButton((Rectangle) {scale.button_x, GetScreenHeight() - (GetScreenHeight() / 8), - scale.button_width, scale.button_height}, - GuiIconText(ICON_REREDO_FILL, "Return")) || IsKeyPressed(KEY_ESCAPE)) { - menu_state = normal; - SetExitKey(KEY_ESCAPE); - break; - } - if (IsFileDropped()) { // Initialize Emulation - EndDrawing(); - if (emu_main(config, &scale) == -2) { break; } - menu_state = normal; - break; - } - break; - - /*-------------------------------------------------------------------------------------------------------------*/ + //---------------------------------------------------------------------------------- + // RENDER LOGIC + //---------------------------------------------------------------------------------- + + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, 0.2f)); + DrawText("Please drag a ROM file into the window", + GetScreenWidth() / 2 - (scale.font_size * 10) + (scale.font_size / 2), + (GetScreenHeight() / 2) - scale.font_size, scale.font_size, RAYWHITE); + + if (GuiButton((Rectangle) {GetScreenWidth() - scale.button_height * 4.5, + GetScreenHeight() - scale.button_height * 1.5, + scale.button_height, scale.button_height}, + GuiIconText(ICON_INFO, ""))) { + OpenURL("https://github.com/npxtune/chisel8"); + } + + if (GuiButton((Rectangle) {GetScreenWidth() - scale.button_height * 3, + GetScreenHeight() - scale.button_height * 1.5, + scale.button_height, scale.button_height}, + GuiIconText(ICON_GEAR, "")) || IsKeyPressed(KEY_S)) { + if (is_options) { + is_options = false; + } else { + is_options = true; + } + } + + if (GuiButton((Rectangle) {GetScreenWidth() - scale.button_height * 1.5, + GetScreenHeight() - scale.button_height * 1.5, + scale.button_height, scale.button_height}, + GuiIconText(ICON_EXIT, ""))) { + EndDrawing(); + CloseWindow(); + return; + } + + if (is_options) { + SetExitKey(KEY_NULL); + if (GuiWindowBox((Rectangle) {(GetScreenWidth() / 5) / 2, (GetScreenHeight() / 5) / 2, + GetScreenWidth() - GetScreenWidth() / 5, + GetScreenHeight() - GetScreenHeight() / 4.5}, "")) { + is_options = false; + } + options_window(config, &scale) != 0 ? is_options = false : 0; + } else { + SetExitKey(KEY_ESCAPE); } EndDrawing(); } diff --git a/src/gui/options_window.c b/src/gui/options_window.c index a194805..312b1a4 100644 --- a/src/gui/options_window.c +++ b/src/gui/options_window.c @@ -27,233 +27,98 @@ #include "gui/options_window.h" #include "raygui.h" -// DEFAULT SETTINGS VALUES - -#define color_0 " 0, 0, 0, 1; # Background color\n" // Default color is BLACK -#define color_1 "255,255,255, 1; # Pixel color\n" // Default color is WHITE -#define scaling "15; # Display scaling, Chip8 Display -> 32x64 Pixels\n" -#define debug "false; # Show debugging info in terminal\n" -#define fps "false; # Show Frames per Second in the top left\n" -#define audio "0.50; # Set the volume of the Chip-8's beep\n" - -#define items 6 // How many options are configurable? - -enum menu_state_counter { - main, theme, miscellaneous -}; -uint32_t menu_state = main; - -void create_config(options_config *config) { - FILE *file = fopen("./chisel8-settings.txt", "w"); - - fwrite(color_0, strlen(color_0), 1, file); - fwrite(color_1, strlen(color_1), 1, file); - fwrite(scaling, strlen(scaling), 1, file); - fwrite(debug, strlen(debug), 1, file); - fwrite(fps, strlen(fps), 1, file); - fwrite(audio, strlen(audio), 1, file); +bool is_theme = true, is_misc = false; +void load_settings(options_config *config) { config->background_color = BLACK; config->pixel_color = WHITE; config->display_scaling = 15; config->show_debug = false; config->show_fps = false; - config->volume = 0.50f; - - fclose(file); + config->volume = 0.25f; } -void load_settings(options_config *config) { - FILE *file = fopen("./chisel8-settings.txt", "r"); - if (file != NULL) { - // READ OPTIONS - char line[100]; - int32_t temp; - for (int32_t i = 0; i < items; ++i) { - fgets(line, 100, file); - uint16_t color[4] = {0, 0, 0, 0}; - uint32_t counter = 0; +int32_t options_window(options_config *config, ui_scale *scale) { + SetExitKey(KEY_NULL); + +// if (fileDialogState.windowActive) GuiLock(); + + // AUDIO VOLUME SLIDER + GuiSliderBar((Rectangle) {scale->button_x - scale->button_width / 1.45, + GetScreenHeight() - (GetScreenHeight() / 1.3), scale->button_width * 2.5, + scale->button_height / 1.5}, + GuiIconText(ICON_AUDIO, "Volume "), + TextFormat("%d %%", (int32_t) (config->volume * 100)), &config->volume, 0, 1); + + if (GuiButton((Rectangle) {scale->button_x / 3, + GetScreenHeight() - (GetScreenHeight() / 1.7), + scale->button_height * 1.5, scale->button_height * 1.5}, + GuiIconText(ICON_BRUSH_PAINTER, ""))) { + // COLOR MENU + is_theme = true, is_misc = false; + } - // Skip line if it is not a value - if (line[0] == '#' || line[0] == '\n' || line[0] == EOF) { - i -= 1; - continue; - } + if (GuiButton((Rectangle) {scale->button_x / 3, + GetScreenHeight() - (GetScreenHeight() / 2.2), + scale->button_height * 1.5, scale->button_height * 1.5}, + GuiIconText(ICON_GEAR_EX, ""))) { + // OTHER SETTINGS + is_misc = true, is_theme = false; + } - switch (i) { - case 0: - for (int32_t j = 0; line[j] != ';'; ++j) { - if (isdigit(line[j]) && color[counter] > 0) { - color[counter] = (color[counter] * 10) + line[j] - '0'; - } else if (isdigit(line[j])) { - color[counter] = line[j] - '0'; - } - if (line[j] == ',') { - counter++; - } - } - config->background_color = (Color) {color[0], color[1], color[2], color[3] * 255}; - break; +// if (GuiButton((Rectangle) {scale->button_x / 3, +// GetScreenHeight() - (GetScreenHeight() / 3.1), +// scale->button_height * 1.5, scale->button_height * 1.5}, +// GuiIconText(ICON_FILE_SAVE_CLASSIC, ""))) { +// // save settings? +// } - case 1: - for (int32_t j = 0; line[j] != ';'; ++j) { - if (isdigit(line[j]) && color[counter] > 0) { - color[counter] = (color[counter] * 10) + line[j] - '0'; - } else if (isdigit(line[j])) { - color[counter] = line[j] - '0'; - } - if (line[j] == ',') { - counter++; - } - } - config->pixel_color = (Color) {color[0], color[1], color[2], color[3] * 255}; - break; + if (is_theme) { + DrawText("Background Color:", scale->button_x - (scale->font_size * 4) + (scale->font_size / 2), + GetScreenHeight() / 2 - scale->font_size * 2, scale->font_size / 1.5, WHITE); - case 2: - for (int32_t j = 0; line[j] != ';'; ++j) { - if (isdigit(line[j]) && color[0] > 0) { - color[0] = (color[0] * 10) + line[j] - '0'; - } else if (isdigit(line[j])) { - color[0] = line[j] - '0'; - } - } - config->display_scaling = color[0]; - break; + GuiColorPicker((Rectangle) {scale->button_x - scale->button_width / 2, GetScreenHeight() / 2.2, + scale->button_width / 1.5, scale->button_width / 1.5}, "BG Color", + &config->background_color); - case 3: - for (temp = 0; line[temp] != ';'; ++temp) {} - if (strncmp(&line[0], "true", sizeof(line[temp])) == 0) { - config->show_debug = true; - } else { - config->show_debug = false; - } - break; + DrawText("Pixel Color:", scale->button_x * 1.85 - (scale->font_size * 4) + (scale->font_size / 2), + GetScreenHeight() / 2 - scale->font_size * 2, scale->font_size / 1.5, WHITE); - case 4: - for (temp = 0; line[temp] != ';'; ++temp) {} - if (strncmp(&line[0], "true", sizeof(line[temp])) == 0) { - config->show_fps = true; - } else { - config->show_fps = false; - } - break; + GuiColorPicker((Rectangle) {scale->button_x + scale->button_width, GetScreenHeight() / 2.2, + scale->button_width / 1.5, scale->button_width / 1.5}, "FG Color", + &config->pixel_color); + } - case 5: - for (temp = 0; line[temp] != ';'; ++temp) {} - if (strncmp(&line[0], "0.", sizeof(line[temp])) == 0) { - config->volume = (float) (line[2] - '0') / 10 + (float) (line[3] - '0') / 100; - } else { - config->volume = 1.0f; - } - break; + if (is_misc) { + GuiCheckBox((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 1.7), + scale->button_width / 8, scale->button_width / 8}, "Show Debug info", + &config->show_debug); + + GuiCheckBox((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 2.2), + scale->button_width / 8, scale->button_width / 8}, "Show FPS", &config->show_fps); + + // CUSTOM FONT LOADING? +// if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 3.2), +// scale->button_width, scale->button_width / 8}, "Custom FONT binary")) { +// ClearWindowState(FLAG_WINDOW_RESIZABLE); +// fileDialogState = InitGuiWindowFileDialog(GetWorkingDirectory()); +// fileDialogState.windowActive = true; +// config->is_dialog = true; +// } +// +// GuiUnlock(); +// GuiWindowFileDialog(&fileDialogState); - default: - fclose(file); - return; - } + if (config->show_debug == true) { + SetTraceLogLevel(LOG_INFO); + } else { + SetTraceLogLevel(LOG_WARNING); } - } else { - // CREATE OPTIONS - create_config(config); } - fclose(file); -} - -int32_t write_settings(options_config *config) { - // TODO - return 0; -} - -float temp; - -int32_t options_window(options_config *config, ui_scale *scale) { - switch (menu_state) { - - /*-------------------------------------------------------------------------------------------------------------*/ - - case main: - SetExitKey(KEY_NULL); - - DrawText("Settings", GetScreenWidth() / 2 - (scale->font_size * 2), (GetScreenHeight() / 12), - scale->font_size, RAYWHITE); - - // AUDIO VOLUME SLIDER - GuiSliderBar((Rectangle) {scale->button_x - scale->button_width / 1.45, - GetScreenHeight() - (GetScreenHeight() / 1.3), scale->button_width * 2.5, - scale->button_height / 1.5}, - GuiIconText(ICON_AUDIO, "Volume "), - TextFormat("%d %%", (int32_t) (config->volume * 100)), &config->volume, 0, 1); - - if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 1.7), - scale->button_width, scale->button_height}, - GuiIconText(ICON_BRUSH_PAINTER, "Change color theme"))) { - // COLOR MENU - menu_state = theme; - } - - if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 2.2), - scale->button_width, scale->button_height}, - GuiIconText(ICON_GEAR_EX, "Miscellaneous"))) { - // OTHER SETTINGS - menu_state = miscellaneous; - } - - if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 8), - scale->button_width, scale->button_height}, - GuiIconText(ICON_REREDO_FILL, "Return")) || IsKeyPressed(KEY_ESCAPE)) { - SetExitKey(KEY_ESCAPE); - return 0; - } - break; - - /*-------------------------------------------------------------------------------------------------------------*/ - - case theme: - DrawText("Color Theme", GetScreenWidth() / 2 - (scale->font_size * 2) - 50, (GetScreenHeight() / 12), - scale->font_size, RAYWHITE); - - DrawText("Background Color:", 115, 175 - 40, scale->font_size / 1.5, WHITE); - GuiColorPicker((Rectangle) {100, 175, 200, 200}, "BG Color", &config->background_color); - - DrawText("Pixel Color:", 645, 175 - 40, scale->font_size / 1.5, WHITE); - GuiColorPicker((Rectangle) {600, 175, 200, 200}, "FG Color", &config->pixel_color); - - if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 8), - scale->button_width, scale->button_height}, - GuiIconText(ICON_REREDO_FILL, "Return")) || IsKeyPressed(KEY_ESCAPE)) { - menu_state = main; - } - break; - - /*-------------------------------------------------------------------------------------------------------------*/ - - case miscellaneous: - DrawText("Miscellaneous", GetScreenWidth() / 2 - (scale->font_size * 2) - 50, (GetScreenHeight() / 12), - scale->font_size, RAYWHITE); - - GuiCheckBox((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 1.7), - scale->button_width / 8, scale->button_width / 8}, "Show Debug info", - &config->show_debug); - - GuiCheckBox((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 2.2), - scale->button_width / 8, scale->button_width / 8}, "Show FPS", &config->show_fps); - - - if (GuiButton((Rectangle) {scale->button_x, GetScreenHeight() - (GetScreenHeight() / 8), - scale->button_width, scale->button_height}, - GuiIconText(ICON_REREDO_FILL, "Return")) || IsKeyPressed(KEY_ESCAPE)) { - menu_state = main; - } - - if (config->show_debug == true) { - SetTraceLogLevel(LOG_INFO); - } else { - SetTraceLogLevel(LOG_ERROR); - } - break; - - /*-------------------------------------------------------------------------------------------------------------*/ + if (IsKeyPressed(KEY_ESCAPE)) { + SetExitKey(KEY_ESCAPE); + return -1; } - return 1; + return 0; } \ No newline at end of file