diff --git a/CMakeLists.txt b/CMakeLists.txt index 0564579..4d9576e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,13 +51,23 @@ add_executable(${DUSK_TARGET_NAME}) # Add tools add_subdirectory(tools) +# Add libraries +if(DUSK_TARGET_SYSTEM STREQUAL "linux") + find_package(SDL2 REQUIRED) + find_package(OpenGL REQUIRED) + target_link_libraries(${DUSK_TARGET_NAME} PRIVATE + SDL2::SDL2 + OpenGL::GL + GL + ) +endif() + # Add code add_subdirectory(src) # Include generated headers -target_include_directories(${DUSK_TARGET_NAME} - PUBLIC - ${DUSK_GENERATED_HEADERS_DIR} +target_include_directories(${DUSK_TARGET_NAME} PUBLIC + ${DUSK_GENERATED_HEADERS_DIR} ) # Postbuild, create PBP file for PSP. diff --git a/src/console/console.c b/src/console/console.c index 8cf8a3d..675517a 100644 --- a/src/console/console.c +++ b/src/console/console.c @@ -28,8 +28,6 @@ void consoleInit() { consolePrint(" = Dawn Console = "); #if DUSK_CONSOLE_POSIX - - threadInit(&CONSOLE.thread, consoleInputThread); threadMutexInit(&CONSOLE.execMutex); threadStartRequest(&CONSOLE.thread); @@ -77,7 +75,9 @@ void consolePrint(const char_t *message, ...) { } void consoleExec(const char_t *line) { - threadMutexLock(&CONSOLE.execMutex); + #if DUSK_CONSOLE_POSIX + threadMutexLock(&CONSOLE.execMutex); + #endif assertNotNull(line, "line must not be NULL"); assertTrue( @@ -279,59 +279,28 @@ void consoleExec(const char_t *line) { } } - threadMutexUnlock(&CONSOLE.execMutex); + #if DUSK_CONSOLE_POSIX + threadMutexUnlock(&CONSOLE.execMutex); + #endif } -// May move these later void consoleUpdate() { #if DUSK_CONSOLE_POSIX + threadMutexLock(&CONSOLE.execMutex); #endif - threadMutexLock(&CONSOLE.execMutex); for(uint32_t i = 0; i < CONSOLE.execBufferCount; i++) { consolecmdexec_t *exec = &CONSOLE.execBuffer[i]; assertNotNull(exec->cmd, "Command execution has no command."); exec->cmd->function(exec); } - threadMutexUnlock(&CONSOLE.execMutex); - - // #if DUSK_KEYBOARD_SUPPORT == 1 - // uint8_t key; - // while((key = inputKeyboardPop()) != 0) { - // printf("Key pressed: %c\n", key); - // switch(key) { - // case 0: - // break; - - // case INPUT_KEY_ENTER: - // consoleExec(CONSOLE.inputBuffer); - // CONSOLE.inputIndex = 0; - // CONSOLE.inputBuffer[0] = '\0'; - // break; - - // case INPUT_KEY_BACKSPACE: - // if(CONSOLE.inputIndex > 0) { - // CONSOLE.inputIndex--; - // CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0'; - // } - // break; - - // default: - // if( - // key >= INPUT_KEY_ASCII_START && key <= INPUT_KEY_ASCII_END && - // CONSOLE.inputIndex < CONSOLE_LINE_MAX - 1 - // ) { - // CONSOLE.inputBuffer[CONSOLE.inputIndex++] = key; - // CONSOLE.inputBuffer[CONSOLE.inputIndex] = '\0'; - // } - // break; - - // } - // } - // #endif // Clear the exec buffer CONSOLE.execBufferCount = 0; + + #if DUSK_CONSOLE_POSIX + threadMutexUnlock(&CONSOLE.execMutex); + #endif } void consoleDispose(void) { @@ -343,7 +312,6 @@ void consoleDispose(void) { consolePrint(" = Console shutting down = "); } - #if DUSK_CONSOLE_POSIX void consoleInputThread(thread_t *thread) { assertNotNull(thread, "Thread cannot be NULL."); diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index 46c5dbd..de672e7 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -6,5 +6,12 @@ # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE - render.c -) \ No newline at end of file + display.c +) + +if(DUSK_TARGET_SYSTEM STREQUAL "linux") + target_compile_definitions(${DUSK_TARGET_NAME} + PRIVATE + DUSK_DISPLAY_SDL2=1 + ) +endif() \ No newline at end of file diff --git a/src/display/display.c b/src/display/display.c new file mode 100644 index 0000000..e19842d --- /dev/null +++ b/src/display/display.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "display/display.h" +#include "console/console.h" + +display_t DISPLAY; + +errorret_t displayInit(void) { + #if DUSK_DISPLAY_SDL2 + if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) != 0) { + errorThrow("SDL Failed to Initialize: %s", SDL_GetError()); + } + + // Set OpenGL attributes (Needs to be done now or later?) + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // Create window with OpenGL flag. + DISPLAY.window = SDL_CreateWindow( + "DuskSDL2", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + DISPLAY_WINDOW_WIDTH_DEFAULT, + DISPLAY_WINDOW_HEIGHT_DEFAULT, + SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | + SDL_WINDOW_OPENGL + ); + if(!DISPLAY.window) { + errorThrow("SDL_CreateWindow failed: %s", SDL_GetError()); + } + + // Create OpenGL context + DISPLAY.glContext = SDL_GL_CreateContext(DISPLAY.window); + if(!DISPLAY.glContext) { + errorThrow("SDL_GL_CreateContext failed: %s", SDL_GetError()); + } + + SDL_GL_SetSwapInterval(1); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING);// PSP defaults this on? + glShadeModel(GL_SMOOTH); // Fixes color on PSP? + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glEnableClientState(GL_COLOR_ARRAY);// To confirm: every frame on PSP? + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + #endif + + // For now, we just return an OK error. + errorOk(); +} + +errorret_t displayUpdate(void) { + #if DUSK_DISPLAY_SDL2 + SDL_Event event; + while(SDL_PollEvent(&event)) { + switch(event.type) { + case SDL_QUIT: + consoleExec("quit"); + break; + + default: + break; + } + } + + SDL_GL_SwapWindow(DISPLAY.window); + #endif + + // For now, we just return an OK error. + errorOk(); +} + +errorret_t displayDispose(void) { + #if DUSK_DISPLAY_SDL2 + if(DISPLAY.glContext) { + SDL_GL_DeleteContext(DISPLAY.glContext); + DISPLAY.glContext = NULL; + } + if(DISPLAY.window) { + SDL_DestroyWindow(DISPLAY.window); + DISPLAY.window = NULL; + } + SDL_Quit(); + #endif + + // For now, we just return an OK error. + errorOk(); +} \ No newline at end of file diff --git a/src/display/display.h b/src/display/display.h new file mode 100644 index 0000000..6da90b7 --- /dev/null +++ b/src/display/display.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "error/error.h" + +#if DUSK_DISPLAY_SDL2 + #include + #define GL_GLEXT_PROTOTYPES + #include + #include +#endif + +#ifndef DISPLAY_WIDTH + #define DISPLAY_WIDTH 320 +#endif +#ifndef DISPLAY_HEIGHT + #define DISPLAY_HEIGHT 240 +#endif + +#ifndef DISPLAY_WINDOW_WIDTH_DEFAULT + #define DISPLAY_WINDOW_WIDTH_DEFAULT DISPLAY_WIDTH +#endif +#ifndef DISPLAY_WINDOW_HEIGHT_DEFAULT + #define DISPLAY_WINDOW_HEIGHT_DEFAULT DISPLAY_HEIGHT +#endif + +typedef struct { + #if DUSK_DISPLAY_SDL2 + SDL_Window *window; + SDL_GLContext glContext; + #endif +} display_t; + +extern display_t DISPLAY; + +/** + * Initializes the display system. + */ +errorret_t displayInit(void); + +/** + * Tells the display system to actually draw the frame. + */ +errorret_t displayUpdate(void); + +/** + * Disposes of the display system. + */ +errorret_t displayDispose(void); \ No newline at end of file diff --git a/src/display/render.c b/src/display/render.c deleted file mode 100644 index 9331e01..0000000 --- a/src/display/render.c +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "display/render.h" \ No newline at end of file diff --git a/src/display/render.h b/src/display/render.h deleted file mode 100644 index 2039247..0000000 --- a/src/display/render.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "error/error.h" - -#ifndef RENDER_WIDTH - #define RENDER_WIDTH 320 -#endif -#ifndef RENDER_HEIGHT - #define RENDER_HEIGHT 240 -#endif - -/** - * Initializes the rendering system. - */ -errorret_t renderInit(void); - -/** - * Tells the rendering system to actually draw the frame. - */ -errorret_t renderDraw(void); - -/** - * Disposes of the rendering system. - */ -errorret_t renderDispose(void); \ No newline at end of file diff --git a/src/engine/engine.c b/src/engine/engine.c index 124c5e7..c56b110 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -9,23 +9,33 @@ #include "util/memory.h" #include "time/time.h" #include "console/console.h" +#include "display/display.h" engine_t ENGINE; -void engineInit(void) { +errorret_t engineInit(void) { memoryZero(&ENGINE, sizeof(engine_t)); ENGINE.running = true; // Init systems. Order is important. timeInit(); consoleInit(); + errorChain(displayInit()); + + errorOk(); } -void engineUpdate(void) { +errorret_t engineUpdate(void) { timeUpdate(); consoleUpdate(); + errorChain(displayUpdate()); + + errorOk(); } -void engineDispose(void) { +errorret_t engineDispose(void) { + errorChain(displayDispose()); consoleDispose(); + + errorOk(); } \ No newline at end of file diff --git a/src/engine/engine.h b/src/engine/engine.h index f4b1e37..29f9052 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -6,7 +6,7 @@ */ #pragma once -#include "dusk.h" +#include "error/error.h" typedef struct { bool_t running; @@ -17,14 +17,14 @@ extern engine_t ENGINE; /** * Initializes the engine. */ -void engineInit(void); +errorret_t engineInit(void); /** * Updates the engine. */ -void engineUpdate(void); +errorret_t engineUpdate(void); /** * Shuts down the engine. */ -void engineDispose(void); \ No newline at end of file +errorret_t engineDispose(void); \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1cb46b5..8e0bae0 100644 --- a/src/main.c +++ b/src/main.c @@ -8,10 +8,27 @@ #include "engine/engine.h" int main(int argc, char **argv) { - engineInit(); + errorret_t ret; + ret = engineInit(); + + if(ret.code != ERROR_OK) { + errorCatch(errorPrint(ret)); + return ret.code; + } + do { - engineUpdate(); + ret = engineUpdate(); + if(ret.code != ERROR_OK) { + errorCatch(errorPrint(ret)); + return ret.code; + } } while(ENGINE.running); - engineDispose(); + + ret = engineDispose(); + if(ret.code != ERROR_OK) { + errorCatch(errorPrint(ret)); + return ret.code; + } + return 0; } \ No newline at end of file