WIP Browser example; WIP init API; Partial update keys API

This commit is contained in:
OctoSpacc 2023-11-26 01:06:18 +01:00
parent 27a0d9dba1
commit 80f9b7e76a
12 changed files with 231 additions and 82 deletions

View File

@ -1,12 +1,12 @@
image: debian:latest image: debian:latest
before_script: | before_script: |
sh ./Tools/InstallBuildEnvironment.sh bash ./Tools/InstallBuildEnvironment.sh
Tests: Tests:
stage: build stage: build
script: | script: |
. .env source .env
make -j$(nproc --all) make -j$(nproc --all)
rules: rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

View File

@ -0,0 +1,133 @@
#include "../../LibMultiSpacc/MultiSpacc.h"
#include <dirent.h>
#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: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr>
// 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 );
}

View File

@ -0,0 +1 @@
include ../Common.mk

View File

@ -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
}

View File

@ -0,0 +1 @@
include ../Common.mk

View File

@ -88,6 +88,8 @@ int main( int argc, char *argv[] )
windowConfig.height = 240; windowConfig.height = 240;
memcpy( windowConfig.palette, palette, 32 ); memcpy( windowConfig.palette, palette, 32 );
MultiSpacc_InitSystem();
// TODO: integrate into LibMultiSpacc and make cross-platform to change into current directory
//romfsInit(); //romfsInit();
//chdir("romfs:/"); //chdir("romfs:/");
@ -109,6 +111,7 @@ int main( int argc, char *argv[] )
margs.tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", margs.background, NULL ); margs.tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", margs.background, NULL );
if( margs.tilesImg == NULL ) if( margs.tilesImg == NULL )
{ {
MultiSpacc_PrintDebug("[E] Error Loading tilesImg (%s).\n", TilesImgFile);
return -1; return -1;
} }

View File

@ -1,10 +1,10 @@
#include "../../LibMultiSpacc/MultiSpacc.h" #include "../../LibMultiSpacc/MultiSpacc.h"
#define AppName "Pong"
#define iabs(x) (((x) >= 0) ? (x) : -(x)) #define iabs(x) (((x) >= 0) ? (x) : -(x))
#define maxOf2(a, b) (((a + b) / 2) + (iabs(a - b) / 2)) #define maxOf2(a, b) (((a + b) / 2) + (iabs(a - b) / 2))
#define AppName "Pong"
bool paused = false; bool paused = false;
int scoreSx = 0; int scoreSx = 0;
int scoreDx = 0; int scoreDx = 0;
@ -322,6 +322,7 @@ int main( int argc, char *argv[] )
windowConfig.height = 240; windowConfig.height = 240;
memcpy( windowConfig.palette, palette, 32 ); memcpy( windowConfig.palette, palette, 32 );
MultiSpacc_InitSystem();
window = MultiSpacc_SetWindow( &windowConfig ); window = MultiSpacc_SetWindow( &windowConfig );
screen = MultiSpacc_GetWindowSurface( window ); screen = MultiSpacc_GetWindowSurface( window );
background = MultiSpacc_CreateSurface( &windowConfig ); background = MultiSpacc_CreateSurface( &windowConfig );
@ -332,13 +333,13 @@ int main( int argc, char *argv[] )
}; };
MultiSpacc_SetAppTitle( window, AppName ); MultiSpacc_SetAppTitle( window, AppName );
MultiSpacc_PrintDebug("[I] Ready!\n");
// Bitmap font forked from: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr> // Bitmap font forked from: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr>
// Original copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT) // Original copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT)
tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", screen, NULL ); tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", screen, NULL );
if( tilesImg == NULL ) if( tilesImg == NULL )
{ {
MultiSpacc_PrintDebug("[E] Error Loading tilesImg (%s).\n", TilesImgFile);
return -1; return -1;
} }
@ -347,5 +348,6 @@ int main( int argc, char *argv[] )
paddleSxY = windowConfig.height/2 - PaddleHeightPx; paddleSxY = windowConfig.height/2 - PaddleHeightPx;
paddleDxY = windowConfig.height/2 - PaddleHeightPx; paddleDxY = windowConfig.height/2 - PaddleHeightPx;
MultiSpacc_PrintDebug("[I] Ready!\n");
return MultiSpacc_SetMainLoop( FixedUpdate, RealUpdate, NULL ); return MultiSpacc_SetMainLoop( FixedUpdate, RealUpdate, NULL );
} }

View File

@ -1,60 +1,33 @@
#include "./MultiSpacc.h" #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 ) void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *keysStates )
{ {
#if defined(MultiSpacc_Target_SDLCommon) #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 #endif
if( keysStates->keysPressed == NULL )
{
keysStates->keysPressed = malloc( numkeys*sizeof(int) );
memset( (void*)keysStates->keysPressed, false, numkeys*sizeof(int) );
}
#elif defined(MultiSpacc_Target_NDS) #elif defined(MultiSpacc_Target_NDS)
scanKeys(); scanKeys();
keysStates->keysPressed = keysDown(); keysStates->keysPressed = keysDown(); //keysHeld();
keysStates->keysHeld = keysStates->keysPressed; keysStates->keysHeld = keysStates->keysPressed;
#elif defined(MultiSpacc_Target_NES) #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 ) bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates )
{ {
#if defined(MultiSpacc_Target_SDLCommon) #if defined(MultiSpacc_Target_SDLCommon)
if ( keysStates->keysHeld[key] && !keysStates->keysPressed[key] ) #if defined(MultiSpacc_Target_Switch) // WIP
{ return SDL_JoystickGetButton( keysStates->keysHeld, key );
keysStates->keysPressed[key] = true; #else
return true; if ( keysStates->keysHeld[key] && !keysStates->keysPressed[key] )
} {
else if ( !keysStates->keysHeld[key] && keysStates->keysPressed[key] ) keysStates->keysPressed[key] = true;
{ return true;
keysStates->keysPressed[key] = false; }
} else if ( !keysStates->keysHeld[key] && keysStates->keysPressed[key] )
return false; {
keysStates->keysPressed[key] = false;
}
return false;
#endif
#elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES) #elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES)
return ( keysStates->keysPressed & key ); return ( keysStates->keysPressed & key );
#endif #endif
@ -85,7 +62,11 @@ bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates )
bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates ) bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates )
{ {
#if defined(MultiSpacc_Target_SDLCommon) #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) #elif defined(MultiSpacc_Target_NDS) || defined(MultiSpacc_Target_NES)
return ( keysStates->keysHeld & key ); return ( keysStates->keysHeld & key );
#endif #endif

View File

@ -7,6 +7,7 @@ extern "C" {
#if defined(MultiSpacc_Target_SDL12) #if defined(MultiSpacc_Target_SDL12)
#define MultiSpacc_SDLK_ESCAPE SDLK_ESCAPE #define MultiSpacc_SDLK_ESCAPE SDLK_ESCAPE
#define MultiSpacc_SDLK_RETURN SDLK_RETURN
#define MultiSpacc_SDLK_TAB SDLK_TAB #define MultiSpacc_SDLK_TAB SDLK_TAB
#define MultiSpacc_SDLK_UP SDLK_UP #define MultiSpacc_SDLK_UP SDLK_UP
#define MultiSpacc_SDLK_DOWN SDLK_DOWN #define MultiSpacc_SDLK_DOWN SDLK_DOWN
@ -14,6 +15,7 @@ extern "C" {
#define MultiSpacc_SDLK_RIGHT SDLK_RIGHT #define MultiSpacc_SDLK_RIGHT SDLK_RIGHT
#elif defined(MultiSpacc_Target_SDL20) #elif defined(MultiSpacc_Target_SDL20)
#define MultiSpacc_SDLK_ESCAPE SDL_SCANCODE_ESCAPE #define MultiSpacc_SDLK_ESCAPE SDL_SCANCODE_ESCAPE
#define MultiSpacc_SDLK_RETURN SDL_SCANCODE_RETURN
#define MultiSpacc_SDLK_TAB SDL_SCANCODE_TAB #define MultiSpacc_SDLK_TAB SDL_SCANCODE_TAB
#define MultiSpacc_SDLK_UP SDL_SCANCODE_UP #define MultiSpacc_SDLK_UP SDL_SCANCODE_UP
#define MultiSpacc_SDLK_DOWN SDL_SCANCODE_DOWN #define MultiSpacc_SDLK_DOWN SDL_SCANCODE_DOWN
@ -45,7 +47,9 @@ extern "C" {
#endif #endif
// Confirm // 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 #define MultiSpacc_Key_Confirm PAD_A
#endif #endif
@ -86,7 +90,10 @@ extern "C" {
#define MultiSpacc_Key_Left MultiSpacc_SDLK_LEFT #define MultiSpacc_Key_Left MultiSpacc_SDLK_LEFT
#define MultiSpacc_Key_Right MultiSpacc_SDLK_RIGHT #define MultiSpacc_Key_Right MultiSpacc_SDLK_RIGHT
#elif defined(MultiSpacc_Target_NDS) #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) #elif defined(MultiSpacc_Target_NES)
#define MultiSpacc_Key_Up PAD_UP #define MultiSpacc_Key_Up PAD_UP
#define MultiSpacc_Key_Down PAD_DOWN #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)) #if defined(MultiSpacc_Target_SDLCommon) && (defined(MultiSpacc_Target_PC) || defined(MultiSpacc_Target_Web))
// #define MultiSpacc_Key_Action1 SPACE // #define MultiSpacc_Key_Action1 SPACE
// #define MultiSpacc_Key_Action2 SHIFT // #define MultiSpacc_Key_Action2 SHIFT
// #define MultiSpacc_Key_Confirm ENTER
// #define MultiSpacc_Key_Cancel ESC // #define MultiSpacc_Key_Cancel ESC
#endif #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 { typedef struct MultiSpacc_KeysStates {
#if defined(MultiSpacc_Target_SDLCommon) #if defined(MultiSpacc_Target_SDLCommon)
Uint8 *keysPressed; Uint8 *keysPressed;
const Uint8 *keysHeld; const Uint8 *keysHeld;
#elif defined(MultiSpacc_Target_NDS) #elif defined(MultiSpacc_Target_NDS)
int keysPressed;
int keysHeld;
#elif defined(MultiSpacc_Target_NES) #elif defined(MultiSpacc_Target_NES)
char keysPressed; char keysPressed;
char keysHeld; char keysHeld;
#endif #endif
} MultiSpacc_KeysStates; } 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 ); void MultiSpacc_PollButtons( char pad, MultiSpacc_KeysStates *keysStates );
bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates ); bool MultiSpacc_CheckKeyPress( int key, MultiSpacc_KeysStates *keysStates );
bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates ); bool MultiSpacc_CheckKeyHold( int key, MultiSpacc_KeysStates *keysStates );

View File

@ -1,5 +1,13 @@
#include "./MultiSpacc.h" #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 ) MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window )
{ {
#if defined(MultiSpacc_Target_SDL12) #if defined(MultiSpacc_Target_SDL12)

View File

@ -45,7 +45,6 @@ extern "C" {
#endif #endif
#ifdef MultiSpacc_Target_SDLCommon #ifdef MultiSpacc_Target_SDLCommon
#define MultiSpacc_Init SDL_Init
#define MultiSpacc_Surface SDL_Surface #define MultiSpacc_Surface SDL_Surface
#define MultiSpacc_GetTicks SDL_GetTicks #define MultiSpacc_GetTicks SDL_GetTicks
#endif #endif
@ -137,7 +136,13 @@ typedef struct MultiSpacc_MainLoopHandlerArgs {
#define MultiSpacc_StaticScreenSizeNull true #define MultiSpacc_StaticScreenSizeNull true
#endif #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_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *windowConfig );
MultiSpacc_Surface *MultiSpacc_GetWindowSurface( MultiSpacc_Window *Window ); 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 ); 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_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 ); MultiSpacc_Surface *MultiSpacc_LoadImage( char FilePath[], MultiSpacc_Surface *Screen, Uint32 *ColorKey );
int MultiSpacc_SetColorKey( MultiSpacc_Surface *Surface, bool Flag, Uint32 Key ); int MultiSpacc_SetColorKey( MultiSpacc_Surface *Surface, bool Flag, Uint32 Key );

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/bash
#[ "$(whoami)" != root ] && { #[ "$(whoami)" != root ] && {
# echo "This script must run as root". echo "This script must probably run as root".
# exit -1 # exit -1
#} #}
@ -35,4 +35,4 @@ export DEVKITARM=/opt/devkitpro/devkitARM
export DEVKITPPC=/opt/devkitpro/devkitPPC export DEVKITPPC=/opt/devkitpro/devkitPPC
[EOF] [EOF]
. .env source .env