/** * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "display/display.h" #include "engine/engine.h" #include "console/console.h" #include "display/framebuffer.h" #include "scene/scenemanager.h" #include "display/spritebatch.h" #include "display/mesh/quad.h" #include "display/screen.h" #include "ui/ui.h" display_t DISPLAY; errorret_t displayInit(void) { #if DISPLAY_SDL2 uint32_t flags = SDL_INIT_VIDEO; #if INPUT_GAMEPAD == 1 flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK; #endif if(SDL_Init(flags) != 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( "Dusk", 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_PACK_ALIGNMENT, 1); 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 quadInit(); frameBufferInitBackbuffer(); spriteBatchInit(); screenInit(); errorOk(); } errorret_t displayUpdate(void) { #if DISPLAY_SDL2 SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: { ENGINE.running = false; break; } case SDL_WINDOWEVENT: { switch(event.window.event) { case SDL_WINDOWEVENT_CLOSE: { ENGINE.running = false; break; } default: { break; } } } default: { break; } } } SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext); #endif // Reset state spriteBatchClear(); frameBufferBind(NULL); // Bind screen and render scene screenBind(); frameBufferClear( FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH, COLOR_CORNFLOWER_BLUE ); sceneManagerRender(); uiRender(); // Finish up spriteBatchFlush(); screenUnbind(); screenRender(); #if DISPLAY_SDL2 SDL_GL_SwapWindow(DISPLAY.window); #endif GLenum err; while((err = glGetError()) != GL_NO_ERROR) { consolePrint("GL Error: %d\n", err); } // For now, we just return an OK error. errorOk(); } errorret_t displayDispose(void) { spriteBatchDispose(); screenDispose(); #if 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(); }