From 80f9b7e76a2e4ff8e42bdcb562b09e3f4504d18c Mon Sep 17 00:00:00 2001 From: OctoSpacc Date: Sun, 26 Nov 2023 01:06:18 +0100 Subject: [PATCH] WIP Browser example; WIP init API; Partial update keys API --- .gitlab-ci.yml | 4 +- LibMultiSpacc/Examples/Browser/Browser.c | 133 ++++++++++++++++++ LibMultiSpacc/Examples/Browser/Makefile | 1 + LibMultiSpacc/Examples/Clock/Clock.c | 18 +++ LibMultiSpacc/Examples/Clock/Makefile | 1 + .../Examples/HelloWorld/HelloWorld.c | 3 + LibMultiSpacc/Examples/Pong/Pong.c | 8 +- LibMultiSpacc/LibMultiSpacc/Keys.c | 95 +++++-------- LibMultiSpacc/LibMultiSpacc/Keys.h | 26 ++-- LibMultiSpacc/LibMultiSpacc/MultiSpacc.c | 8 ++ LibMultiSpacc/LibMultiSpacc/MultiSpacc.h | 10 +- Tools/InstallBuildEnvironment.sh | 6 +- 12 files changed, 231 insertions(+), 82 deletions(-) create mode 100644 LibMultiSpacc/Examples/Browser/Browser.c create mode 100644 LibMultiSpacc/Examples/Browser/Makefile create mode 100644 LibMultiSpacc/Examples/Clock/Clock.c create mode 100644 LibMultiSpacc/Examples/Clock/Makefile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8e8ee37..1dc8a9e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,12 @@ image: debian:latest before_script: | - sh ./Tools/InstallBuildEnvironment.sh + bash ./Tools/InstallBuildEnvironment.sh Tests: stage: build script: | - . .env + source .env make -j$(nproc --all) rules: - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH diff --git a/LibMultiSpacc/Examples/Browser/Browser.c b/LibMultiSpacc/Examples/Browser/Browser.c new file mode 100644 index 0000000..0e2f1ca --- /dev/null +++ b/LibMultiSpacc/Examples/Browser/Browser.c @@ -0,0 +1,133 @@ +#include "../../LibMultiSpacc/MultiSpacc.h" +#include + +#define AppName "Browser" +#define TilesImgFile "./Assets/CHARS.png" + +#define TileSize 8 +#define ScreenTilesH (windowConfig.width / TileSize) + +MultiSpacc_KeysStates buttonsStates; +MultiSpacc_SurfaceConfig windowConfig = {0}; +MultiSpacc_Window *window; +MultiSpacc_Surface *screen; +MultiSpacc_Surface *tilesImg; + +struct dirent *de; +DIR *dr; + +bool TryReadDirectory( char path[] ) +{ + int i = 0; + char previousPath[1024]; + char workingPath[1024]; + char displayPath[ScreenTilesH+1]; + + memset( displayPath, 0, ScreenTilesH+1 ); + + if( dr != NULL ){ + closedir(dr); + } + + if( (dr = opendir(path)) != NULL ){ + strcpy( previousPath, path ); + } + else{ + dr = opendir(previousPath); + } + + if( strlen(getcwd( workingPath, sizeof(workingPath) )) > ScreenTilesH ) + { + strncpy( displayPath, "...", 3 ); + i = 3; + } + + // TODO: fix bug, if path is too short we have parts of it to the right + while( workingPath[i] ) + { + if( strlen(workingPath) - ScreenTilesH <= i-3 ) + { + strcat( displayPath, &workingPath[i] ); + } + ++i; + } + + SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) ); + MultiSpacc_PrintText( displayPath, screen, &windowConfig, 0, 0, tilesImg ); + + return true; +} + +bool RealUpdate( void *args, double deltaTime ) +{ + int entriesCount = 0; + + MultiSpacc_PollButtons( 0, &buttonsStates ); + + // TODO: show cursor, allow moving it in list and to select entries + if( MultiSpacc_CheckKeyPress( MultiSpacc_Key_Confirm, &buttonsStates ) ) + { + chdir(".."); + TryReadDirectory("."); + } + else if( MultiSpacc_CheckKeyPress( MultiSpacc_Key_Up, &buttonsStates ) ) + { + + } + else if( MultiSpacc_CheckKeyPress( MultiSpacc_Key_Down, &buttonsStates ) ) + { + + } + // TODO: listen for OS terminate signal + else if( MultiSpacc_CheckKeyPress( MultiSpacc_Key_Pause, &buttonsStates ) ) + { + return false; + } + + de = readdir(dr); // "delete" first entry (".", meaning current directory) from list + while ( (de = readdir(dr)) != NULL ) + { + MultiSpacc_PrintText( de->d_name, screen, &windowConfig, 2, 2+i, tilesImg ); + ++i; + } + // TODO: handle directories with more entries than screen height + + if( !MultiSpacc_UpdateDisplay(window) ) + { + MultiSpacc_PrintDebug("[E] Error Updating Screen.\n"); + return false; + } + + return true; +} + +int main( int argc, char *argv[] ) +{ + if( !MultiSpacc_InitSystem() ) + { + MultiSpacc_PrintDebug("[E] Error Initializing System Core.\n"); + return -1; + } + + window = MultiSpacc_SetWindow( &windowConfig ); + screen = MultiSpacc_GetWindowSurface( window ); + if( window == NULL || screen == NULL ) + { + MultiSpacc_PrintDebug("[E] Error Initializing Video System.\n"); + return -1; + }; + + // Bitmap font forked from: + // Original copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT) + tilesImg = MultiSpacc_LoadImage( TilesImgFile, screen, NULL ); + if( tilesImg == NULL ) + { + MultiSpacc_PrintDebug("[E] Error Loading tilesImg (%s).\n", TilesImgFile); + return -1; + } + + TryReadDirectory("."); + MultiSpacc_SetAppTitle( window, AppName ); + MultiSpacc_PrintDebug("[I] Ready!\n"); + return MultiSpacc_SetMainLoop( NULL, RealUpdate, NULL ); +} diff --git a/LibMultiSpacc/Examples/Browser/Makefile b/LibMultiSpacc/Examples/Browser/Makefile new file mode 100644 index 0000000..636699b --- /dev/null +++ b/LibMultiSpacc/Examples/Browser/Makefile @@ -0,0 +1 @@ +include ../Common.mk \ No newline at end of file diff --git a/LibMultiSpacc/Examples/Clock/Clock.c b/LibMultiSpacc/Examples/Clock/Clock.c new file mode 100644 index 0000000..bda1f66 --- /dev/null +++ b/LibMultiSpacc/Examples/Clock/Clock.c @@ -0,0 +1,18 @@ +#include "../../LibMultiSpacc/MultiSpacc.h" + +#define AppName "Clock" + + + +int main( int argc, char *argv[] ) +{ + // ... do setup things + + if( !MultiSpacc_SystemClockAvailable ) + { + // ... make the user set time in-app + } + + // ... retrieve system time by common API or keep a clock manually + // ... display and update a clock +} diff --git a/LibMultiSpacc/Examples/Clock/Makefile b/LibMultiSpacc/Examples/Clock/Makefile new file mode 100644 index 0000000..636699b --- /dev/null +++ b/LibMultiSpacc/Examples/Clock/Makefile @@ -0,0 +1 @@ +include ../Common.mk \ No newline at end of file diff --git a/LibMultiSpacc/Examples/HelloWorld/HelloWorld.c b/LibMultiSpacc/Examples/HelloWorld/HelloWorld.c index 4b319e0..544ad29 100644 --- a/LibMultiSpacc/Examples/HelloWorld/HelloWorld.c +++ b/LibMultiSpacc/Examples/HelloWorld/HelloWorld.c @@ -88,6 +88,8 @@ int main( int argc, char *argv[] ) windowConfig.height = 240; memcpy( windowConfig.palette, palette, 32 ); + MultiSpacc_InitSystem(); + // TODO: integrate into LibMultiSpacc and make cross-platform to change into current directory //romfsInit(); //chdir("romfs:/"); @@ -109,6 +111,7 @@ int main( int argc, char *argv[] ) margs.tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", margs.background, NULL ); if( margs.tilesImg == NULL ) { + MultiSpacc_PrintDebug("[E] Error Loading tilesImg (%s).\n", TilesImgFile); return -1; } diff --git a/LibMultiSpacc/Examples/Pong/Pong.c b/LibMultiSpacc/Examples/Pong/Pong.c index 2baf13e..a1dc565 100644 --- a/LibMultiSpacc/Examples/Pong/Pong.c +++ b/LibMultiSpacc/Examples/Pong/Pong.c @@ -1,10 +1,10 @@ #include "../../LibMultiSpacc/MultiSpacc.h" +#define AppName "Pong" + #define iabs(x) (((x) >= 0) ? (x) : -(x)) #define maxOf2(a, b) (((a + b) / 2) + (iabs(a - b) / 2)) -#define AppName "Pong" - bool paused = false; int scoreSx = 0; int scoreDx = 0; @@ -322,6 +322,7 @@ int main( int argc, char *argv[] ) windowConfig.height = 240; memcpy( windowConfig.palette, palette, 32 ); + MultiSpacc_InitSystem(); window = MultiSpacc_SetWindow( &windowConfig ); screen = MultiSpacc_GetWindowSurface( window ); background = MultiSpacc_CreateSurface( &windowConfig ); @@ -332,13 +333,13 @@ int main( int argc, char *argv[] ) }; MultiSpacc_SetAppTitle( window, AppName ); - MultiSpacc_PrintDebug("[I] Ready!\n"); // Bitmap font forked from: // Original copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT) tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", screen, NULL ); if( tilesImg == NULL ) { + MultiSpacc_PrintDebug("[E] Error Loading tilesImg (%s).\n", TilesImgFile); return -1; } @@ -347,5 +348,6 @@ int main( int argc, char *argv[] ) paddleSxY = windowConfig.height/2 - PaddleHeightPx; paddleDxY = windowConfig.height/2 - PaddleHeightPx; + MultiSpacc_PrintDebug("[I] Ready!\n"); return MultiSpacc_SetMainLoop( FixedUpdate, RealUpdate, NULL ); } diff --git a/LibMultiSpacc/LibMultiSpacc/Keys.c b/LibMultiSpacc/LibMultiSpacc/Keys.c index 15a6d7a..74996ed 100644 --- a/LibMultiSpacc/LibMultiSpacc/Keys.c +++ b/LibMultiSpacc/LibMultiSpacc/Keys.c @@ -1,60 +1,33 @@ #include "./MultiSpacc.h" -// TODO: Handle actual presses in SDL -// void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *buttonsPressed, MultiSpacc_KeysStates *buttonsHeld ) -// { - // #if defined(MultiSpacc_Target_SDLCommon) - // SDL_PumpEvents(); - // #if defined(MultiSpacc_Target_SDL12) - // buttonsPressed->keysStates = SDL_GetKeyState(NULL); - // #elif defined(MultiSpacc_Target_SDL20) - // buttonsPressed->keysStates = SDL_GetKeyboardState(NULL); - // #endif - // buttonsHeld->keysStates = buttonsPressed->keysStates; - - // #elif defined(MultiSpacc_Target_NDS) - // scanKeys(); - // buttonsPressed->keysStates = keysDown(); - // buttonsHeld->keysStates = buttonsPressed->keysStates; - - // #elif defined(MultiSpacc_Target_NES) - // buttonsPressed->keysStates = pad_trigger(pad); - // buttonsHeld->keysStates = pad_state(pad); - - // #endif -// } - -// bool MultiSpacc_CheckButtonState( int button, MultiSpacc_KeysStates *buttonsStates ) -// { - // #if defined(MultiSpacc_Target_SDLCommon) - // return buttonsStates->keysStates[button]; - // #elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES) - // return ( buttonsStates->keysStates & button ); - // #endif -// } - void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *keysStates ) { #if defined(MultiSpacc_Target_SDLCommon) - int numkeys; + #if defined(MultiSpacc_Target_Switch) // WIP + keysStates->keysHeld = SDL_JoystickOpen(pad); - SDL_PumpEvents(); + #else + int numkeys; + + SDL_PumpEvents(); + + #if defined(MultiSpacc_Target_SDL12) + keysStates->keysHeld = SDL_GetKeyState(&numkeys); + #elif defined(MultiSpacc_Target_SDL20) + keysStates->keysHeld = SDL_GetKeyboardState(&numkeys); + #endif + + if( keysStates->keysPressed == NULL ) + { + keysStates->keysPressed = malloc( numkeys*sizeof(int) ); + memset( (void*)keysStates->keysPressed, false, numkeys*sizeof(int) ); + } - #if defined(MultiSpacc_Target_SDL12) - keysStates->keysHeld = SDL_GetKeyState(&numkeys); - #elif defined(MultiSpacc_Target_SDL20) - keysStates->keysHeld = SDL_GetKeyboardState(&numkeys); #endif - if( keysStates->keysPressed == NULL ) - { - keysStates->keysPressed = malloc( numkeys*sizeof(int) ); - memset( (void*)keysStates->keysPressed, false, numkeys*sizeof(int) ); - } - #elif defined(MultiSpacc_Target_NDS) scanKeys(); - keysStates->keysPressed = keysDown(); + keysStates->keysPressed = keysDown(); //keysHeld(); keysStates->keysHeld = keysStates->keysPressed; #elif defined(MultiSpacc_Target_NES) @@ -67,16 +40,20 @@ void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *keysStates ) bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates ) { #if defined(MultiSpacc_Target_SDLCommon) - if ( keysStates->keysHeld[key] && !keysStates->keysPressed[key] ) - { - keysStates->keysPressed[key] = true; - return true; - } - else if ( !keysStates->keysHeld[key] && keysStates->keysPressed[key] ) - { - keysStates->keysPressed[key] = false; - } - return false; + #if defined(MultiSpacc_Target_Switch) // WIP + return SDL_JoystickGetButton( keysStates->keysHeld, key ); + #else + if ( keysStates->keysHeld[key] && !keysStates->keysPressed[key] ) + { + keysStates->keysPressed[key] = true; + return true; + } + else if ( !keysStates->keysHeld[key] && keysStates->keysPressed[key] ) + { + keysStates->keysPressed[key] = false; + } + return false; + #endif #elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES) return ( keysStates->keysPressed & key ); #endif @@ -85,7 +62,11 @@ bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates ) bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates ) { #if defined(MultiSpacc_Target_SDLCommon) - return keysStates->keysHeld[key]; + #if defined(MultiSpacc_Target_Switch) + return SDL_JoystickGetButton( keysStates->keysHeld, key ); + #else + return keysStates->keysHeld[key]; + #endif #elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES) return ( keysStates->keysHeld & key ); #endif diff --git a/LibMultiSpacc/LibMultiSpacc/Keys.h b/LibMultiSpacc/LibMultiSpacc/Keys.h index b002430..1c3d1f8 100644 --- a/LibMultiSpacc/LibMultiSpacc/Keys.h +++ b/LibMultiSpacc/LibMultiSpacc/Keys.h @@ -7,6 +7,7 @@ extern "C" { #if defined(MultiSpacc_Target_SDL12) #define MultiSpacc_SDLK_ESCAPE SDLK_ESCAPE + #define MultiSpacc_SDLK_RETURN SDLK_RETURN #define MultiSpacc_SDLK_TAB SDLK_TAB #define MultiSpacc_SDLK_UP SDLK_UP #define MultiSpacc_SDLK_DOWN SDLK_DOWN @@ -14,6 +15,7 @@ extern "C" { #define MultiSpacc_SDLK_RIGHT SDLK_RIGHT #elif defined(MultiSpacc_Target_SDL20) #define MultiSpacc_SDLK_ESCAPE SDL_SCANCODE_ESCAPE + #define MultiSpacc_SDLK_RETURN SDL_SCANCODE_RETURN #define MultiSpacc_SDLK_TAB SDL_SCANCODE_TAB #define MultiSpacc_SDLK_UP SDL_SCANCODE_UP #define MultiSpacc_SDLK_DOWN SDL_SCANCODE_DOWN @@ -45,7 +47,9 @@ extern "C" { #endif // Confirm -#if defined(MultiSpacc_Target_NES) +#if defined(MultiSpacc_Target_SDLCommon) && (defined(MultiSpacc_Target_PC) || defined(MultiSpacc_Target_Web)) + #define MultiSpacc_Key_Confirm MultiSpacc_SDLK_RETURN +#elif defined(MultiSpacc_Target_NES) #define MultiSpacc_Key_Confirm PAD_A #endif @@ -86,7 +90,10 @@ extern "C" { #define MultiSpacc_Key_Left MultiSpacc_SDLK_LEFT #define MultiSpacc_Key_Right MultiSpacc_SDLK_RIGHT #elif defined(MultiSpacc_Target_NDS) - // ... + #define MultiSpacc_Key_Up KEY_UP + #define MultiSpacc_Key_Down KEY_DOWN + #define MultiSpacc_Key_Left KEY_LEFT + #define MultiSpacc_Key_Right KEY_RIGHT #elif defined(MultiSpacc_Target_NES) #define MultiSpacc_Key_Up PAD_UP #define MultiSpacc_Key_Down PAD_DOWN @@ -97,33 +104,22 @@ extern "C" { #if defined(MultiSpacc_Target_SDLCommon) && (defined(MultiSpacc_Target_PC) || defined(MultiSpacc_Target_Web)) // #define MultiSpacc_Key_Action1 SPACE // #define MultiSpacc_Key_Action2 SHIFT - // #define MultiSpacc_Key_Confirm ENTER // #define MultiSpacc_Key_Cancel ESC #endif -// typedef struct MultiSpacc_KeysStates { - // #if defined(MultiSpacc_Target_SDLCommon) - // const Uint8 *keysStates; - // #elif defined(MultiSpacc_Target_NDS) - // int keysStates; - // #elif defined(MultiSpacc_Target_NES) - // char keysStates; - // #endif -// } MultiSpacc_KeysStates; - typedef struct MultiSpacc_KeysStates { #if defined(MultiSpacc_Target_SDLCommon) Uint8 *keysPressed; const Uint8 *keysHeld; #elif defined(MultiSpacc_Target_NDS) + int keysPressed; + int keysHeld; #elif defined(MultiSpacc_Target_NES) char keysPressed; char keysHeld; #endif } MultiSpacc_KeysStates; -//void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *buttonsPressed, MultiSpacc_KeysStates *buttonsHeld ); -//bool MultiSpacc_CheckButtonState( int button, MultiSpacc_KeysStates *buttonsStates ); void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *keysStates ); bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates ); bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates ); diff --git a/LibMultiSpacc/LibMultiSpacc/MultiSpacc.c b/LibMultiSpacc/LibMultiSpacc/MultiSpacc.c index 9b76bfb..2f8ab15 100644 --- a/LibMultiSpacc/LibMultiSpacc/MultiSpacc.c +++ b/LibMultiSpacc/LibMultiSpacc/MultiSpacc.c @@ -1,5 +1,13 @@ #include "./MultiSpacc.h" +bool MultiSpacc_InitSystem(void) +{ + #if defined(MultiSpacc_Target_SDLCommon) + SDL_Init(SDL_INIT_EVERYTHING); + #endif + return true; +} + MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window ) { #if defined(MultiSpacc_Target_SDL12) diff --git a/LibMultiSpacc/LibMultiSpacc/MultiSpacc.h b/LibMultiSpacc/LibMultiSpacc/MultiSpacc.h index f1cec2e..b96a60c 100644 --- a/LibMultiSpacc/LibMultiSpacc/MultiSpacc.h +++ b/LibMultiSpacc/LibMultiSpacc/MultiSpacc.h @@ -45,7 +45,6 @@ extern "C" { #endif #ifdef MultiSpacc_Target_SDLCommon - #define MultiSpacc_Init SDL_Init #define MultiSpacc_Surface SDL_Surface #define MultiSpacc_GetTicks SDL_GetTicks #endif @@ -137,7 +136,13 @@ typedef struct MultiSpacc_MainLoopHandlerArgs { #define MultiSpacc_StaticScreenSizeNull true #endif -bool MultiSpacc_MainLoopHandler( MultiSpacc_MainLoopHandlerArgs *handlerArgs ); +#if defined(MultiSpacc_Target_NES) + #define MultiSpacc_SystemClockAvailable false +#else + #define MultiSpacc_SystemClockAvailable true +#endif + +bool MultiSpacc_InitSystem(void); MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *windowConfig ); MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window ); @@ -146,6 +151,7 @@ void MultiSpacc_SetAppTitle( MultiSpacc_Window *Window, const char Title[] ); void MultiSpacc_SetAppIcon( MultiSpacc_Window *Window, MultiSpacc_Surface *Icon ); bool MultiSpacc_SetMainLoop( bool functionFixedUpdate( void *args ), bool functionRealUpdate( void *args, double deltaTime ), void *args ); +bool MultiSpacc_MainLoopHandler( MultiSpacc_MainLoopHandlerArgs *handlerArgs ); MultiSpacc_Surface *MultiSpacc_LoadImage( char FilePath[], MultiSpacc_Surface *Screen, Uint32 *ColorKey ); int MultiSpacc_SetColorKey( MultiSpacc_Surface *Surface, bool Flag, Uint32 Key ); diff --git a/Tools/InstallBuildEnvironment.sh b/Tools/InstallBuildEnvironment.sh index 44289d1..80c6422 100644 --- a/Tools/InstallBuildEnvironment.sh +++ b/Tools/InstallBuildEnvironment.sh @@ -1,7 +1,7 @@ -#!/bin/sh +#!/bin/bash #[ "$(whoami)" != root ] && { -# echo "This script must run as root". + echo "This script must probably run as root". # exit -1 #} @@ -35,4 +35,4 @@ export DEVKITARM=/opt/devkitpro/devkitARM export DEVKITPPC=/opt/devkitpro/devkitPPC [EOF] -. .env +source .env