mirror of
https://gitlab.com/octospacc/MultiSpaccSDK
synced 2025-04-26 16:38:41 +02:00
Update build system, small code updates/tests
This commit is contained in:
parent
2329a59f8f
commit
3ba1e58b75
Binary file not shown.
Before Width: | Height: | Size: 901 B |
BIN
LibMultiSpacc/Examples/CHARS.xcf
Normal file
BIN
LibMultiSpacc/Examples/CHARS.xcf
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
AppName = $(notdir $(CURDIR))
|
||||
AppAssets = ../CHARS.png
|
||||
AppAssets = ../CHARS.xcf
|
||||
AppSources = $(wildcard *.c)
|
||||
AppHeaders = $(wildcard *.h)
|
||||
SpaccSources = $(wildcard ../../LibMultiSpacc/*.c)
|
||||
@ -40,12 +40,13 @@ else ifeq ($(Target), WindowsPC)
|
||||
|
||||
else ifeq ($(Target), Windows9x)
|
||||
ExeSuffix = .exe
|
||||
Defines += -DTarget_Windows9x -DMultiSpacc_Target_PC -DMultiSpacc_Target_Windows
|
||||
Defines += -DTarget_Windows9x -DMultiSpacc_Target_Windows9x -DMultiSpacc_Target_PC -DMultiSpacc_Target_Windows
|
||||
MultiSpacc_Target = SDL12
|
||||
LdFlags += -lmingw32 -static-libgcc
|
||||
ifeq ($(Host), Windows)
|
||||
ToolsSyspath = /c/Files/Sdk/mingw32/bin
|
||||
export PATH=$$PATH:$(ToolsSyspath)
|
||||
# TODO: Find a workaround to the path hardcoding here
|
||||
export PATH=/usr/bin:/c/Files/Applications:$(ToolsSyspath)
|
||||
else
|
||||
ToolsSyspath = /opt/Sdk/mingw32/bin
|
||||
ToolsWrapper = wine
|
||||
@ -75,24 +76,28 @@ else ifeq ($(Target), NES)
|
||||
|
||||
endif
|
||||
|
||||
ConstSdlDefines = -DMultiSpacc_Target_SDLCom -DMultiSpacc_Target_SDLCommon -DMultiSpacc_Backend_SDLCommon
|
||||
ConstSdl12Defines = $(ConstSdlDefines) -DMultiSpacc_Target_SDL12 -DMultiSpacc_Backend_SDL12
|
||||
ConstSdl20Defines = $(ConstSdlDefines) -DMultiSpacc_Target_SDL20 -DMultiSpacc_Backend_SDL20
|
||||
|
||||
ifeq ($(MultiSpacc_Target), SDL12)
|
||||
Defines += -DMultiSpacc_Target_SDL12 -DMultiSpacc_Target_SDLCom -DMultiSpacc_Target_SDLCommon -DMultiSpacc_Target_SDLStandard
|
||||
Defines += $(ConstSdl12Defines) -DMultiSpacc_Target_SDLStandard
|
||||
CFlags += $(shell sdl-config --cflags)
|
||||
LdFlags += $(shell sdl-config --libs) -lSDLmain -lSDL -lSDL_image -lSDL_mixer -lSDL_ttf
|
||||
|
||||
else ifeq ($(MultiSpacc_Target), SDL20)
|
||||
Defines += -DMultiSpacc_Target_SDL20 -DMultiSpacc_Target_SDLCom -DMultiSpacc_Target_SDLCommon -DMultiSpacc_Target_SDLStandard
|
||||
Defines += $(ConstSdl20Defines) -DMultiSpacc_Target_SDLStandard
|
||||
CFlags += $(shell sdl2-config --cflags)
|
||||
LdFlags += $(shell sdl2-config --libs) -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf
|
||||
|
||||
else ifeq ($(MultiSpacc_Target), Web)
|
||||
Defines += -DMultiSpacc_Target_Web -DMultiSpacc_Target_SDL20 -DMultiSpacc_Target_SDLCom -DMultiSpacc_Target_SDLCommon -DMultiSpacc_Target_SDLWeb
|
||||
Defines += -DMultiSpacc_Target_Web $(ConstSdl20Defines) -DMultiSpacc_Target_SDLWeb
|
||||
LdFlags += -sWASM=1 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='["png"]' -sUSE_SDL_TTF=2 -sUSE_SDL_MIXER=2
|
||||
BuildProcess = Web
|
||||
|
||||
else ifeq ($(MultiSpacc_Target), Switch)
|
||||
ExeSuffix = .nro
|
||||
Defines += -DMultiSpacc_Target_Switch -DMultiSpacc_Target_SDL20 -DMultiSpacc_Target_SDLCom -DMultiSpacc_Target_SDLCommon
|
||||
Defines += -DMultiSpacc_Target_Switch $(ConstSdl20Defines)
|
||||
Libs += -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lpng -ljpeg -lwebp -lm -lz -lminizip -lbz2
|
||||
BuildProcess = Switch
|
||||
|
||||
@ -146,39 +151,55 @@ define PrepareTargetBuildDir
|
||||
for i in $(BuildDirSources)/*.c $(BuildDirSources)/*.h; do sed -i 's|#include[ \t]"./|#include "LibMultiSpacc_|g' $$i; done
|
||||
endef
|
||||
|
||||
# For C++ build systems, main() must be in a .cpp file, to be compiled by the CXX
|
||||
define TargetBuildAppToCpp
|
||||
#mv $(BuildDirSources)/$(AppName).c $(BuildDirSources)/$(AppName).cpp
|
||||
$(shell mv $(BuildDirSources)/MultiSpacc_* $(BuildDirSources)/.tmp/)
|
||||
for File in $(BuildDirSources)/*.c; do mv $${File} $${File}pp; done
|
||||
$(shell mv $(BuildDirSources)/.tmp/* $(BuildDirSources)/)
|
||||
endef
|
||||
|
||||
All all: __$(BuildProcess)__
|
||||
All all: __Assets__ __$(BuildProcess)__
|
||||
|
||||
__Assets__:
|
||||
mkdir -p ./Build/Assets
|
||||
for SrcFile in $(AppAssets); \
|
||||
do \
|
||||
SrcExt="$${SrcFile##*.}"; \
|
||||
DstName="$${SrcFile##*/}"; \
|
||||
DstName="$${DstName%.*}"; \
|
||||
if [ "$${SrcExt}" = xcf ]; then \
|
||||
magick convert "$${SrcFile}" "./Build/Assets/$${DstName}.png"; \
|
||||
mv "./Build/Assets/$${DstName}-0.png" "./Build/Assets/$${DstName}.4.png"; \
|
||||
mv "./Build/Assets/$${DstName}-1.png" "./Build/Assets/$${DstName}.png"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
# TODO: use virtual build dirs even for normals to allow linking against different libraries without recleaning
|
||||
# TODO: copy required DLLs on PC for Dist
|
||||
__Normal__: $(BuildObjects)
|
||||
$(CC) $^ $(LdFlags) $(Libs) -o $(AppName)$(ExeSuffix)
|
||||
# TODO: copy required DLLs on PC for Dist
|
||||
|
||||
# TODO: bundle JS, WASM, and assets package in HTML file for Dist
|
||||
# TODO: remove asset hardcoding from here
|
||||
__Web__:
|
||||
mkdir -p $(BuildDir)
|
||||
emcc $(BuildSources) $(CFlags) $(Defines) $(LdFlags) --preload-file $(AppAssets)@CHARS.png -o $(BuildDir)/Emscripten.js
|
||||
cp ../Emscripten.html $(BuildDir)/$(AppName).html
|
||||
# TODO: bundle JS, WASM, and assets package in HTML file for Dist
|
||||
|
||||
__Switch__:
|
||||
$(eval BuildDirSources = $(BuildDir)/source)
|
||||
$(PrepareTargetBuildDir)
|
||||
$(TargetBuildAppToCpp)
|
||||
mkdir -p $(BuildDir)/romfs/.dummy
|
||||
touch $(BuildDir)/romfs/.dummy/.dummy
|
||||
cp $(AppAssets) $(BuildDir)/romfs/
|
||||
cd $(BuildDir); make
|
||||
#mkdir -p $(BuildDir)/romfs/.dummy
|
||||
#touch $(BuildDir)/romfs/.dummy/.dummy
|
||||
mkdir -p $(BuildDir)/romfs
|
||||
cp -r ./Build/Assets $(BuildDir)/romfs/Assets
|
||||
cd $(BuildDir); make -j$$(nproc --all)
|
||||
|
||||
__3DS__ __NDS__:
|
||||
$(eval BuildDirSources = $(BuildDir)/source)
|
||||
$(PrepareTargetBuildDir)
|
||||
cd $(BuildDir); make
|
||||
cd $(BuildDir); make -j$$(nproc --all)
|
||||
|
||||
__NES__: __neslib__
|
||||
$(eval BuildDirSources = $(BuildDir))
|
||||
@ -190,10 +211,10 @@ __NES__: __neslib__
|
||||
cd $(BuildDir); sh ./Make.sh
|
||||
|
||||
__neslib__:
|
||||
cd ../../neslib; make
|
||||
cd ../../neslib; make -j$$(nproc --all)
|
||||
|
||||
Run run: All
|
||||
$(OutLauncher) $(BuildDir)/$(AppName)$(ExeSuffix)
|
||||
cd ./Build; $(OutLauncher) ../$(BuildDir)/$(AppName)$(ExeSuffix); cd ..
|
||||
|
||||
Clean clean Clear clear:
|
||||
find -L . -name "*.o" -type f -delete
|
||||
|
@ -18,14 +18,14 @@ typedef struct MainArgs {
|
||||
/*{pal:"nes",layout:"nes"}*/
|
||||
const char palette[32] = {
|
||||
0x0F, // screen
|
||||
0x11,0x30,0x27,0x00, // background 0
|
||||
0x1c,0x20,0x2c,0x00, // background 1
|
||||
0x00,0x10,0x20,0x00, // background 2
|
||||
0x06,0x16,0x26,0x00, // background 3
|
||||
0x16,0x35,0x24,0x00, // sprite 0
|
||||
0x00,0x37,0x25,0x00, // sprite 1
|
||||
0x0d,0x2d,0x3a,0x00, // sprite 2
|
||||
0x0d,0x27,0x2a, // sprite 3
|
||||
0x11,0x02,0x02,0x00, // background 0
|
||||
0x00,0x00,0x00,0x00, // background 1
|
||||
0x00,0x00,0x00,0x00, // background 2
|
||||
0x00,0x00,0x00,0x00, // background 3
|
||||
0x16,0x00,0x00,0x00, // sprite 0
|
||||
0x00,0x00,0x00,0x00, // sprite 1
|
||||
0x00,0x00,0x00,0x00, // sprite 2
|
||||
0x00,0x00,0x00, // sprite 3
|
||||
};
|
||||
|
||||
Uint32 nextTick;
|
||||
@ -34,7 +34,7 @@ bool MainLoop( void *args )
|
||||
{
|
||||
MainArgs *margs = (MainArgs*)args;
|
||||
|
||||
//SDL_FillRect(margs->Background, &rect, 0x000000);
|
||||
//SDL_FillRect(margs->background, NULL, 0x00F);
|
||||
MultiSpacc_BlitLayer( margs->background, margs->screen );
|
||||
//SDL_BlitSurface( margs->Foreground, &rect, margs->Screen, &rect );
|
||||
MultiSpacc_SetSprite( 0, margs->spriteX, margs->spriteY, 1, margs->tilesImg, margs->screen );
|
||||
@ -58,6 +58,12 @@ bool MainLoop( void *args )
|
||||
return false;
|
||||
}
|
||||
|
||||
// for( int i=0; i< margs->screen->w * margs->screen->h * margs->screen->format->BytesPerPixel; i++ )
|
||||
// {
|
||||
// NOTE: format is BGRA for 32bits
|
||||
// SDL_memset( (char*)margs->screen->pixels + i, 0xFF, 1 );
|
||||
// }
|
||||
|
||||
if( !MultiSpacc_UpdateDisplay( margs->window ) )
|
||||
{
|
||||
MultiSpacc_PrintDebug("[E] Error Updating Screen.\n");
|
||||
@ -78,11 +84,11 @@ int main( int argc, char *argv[] )
|
||||
|
||||
windowConfig.width = 320;
|
||||
windowConfig.height = 240;
|
||||
windowConfig.bits = 16;
|
||||
//windowConfig.bits = 16;
|
||||
memcpy( windowConfig.palette, palette, 32 );
|
||||
|
||||
//romfsInit();
|
||||
//chdir("romfs:/.dummy");
|
||||
//chdir("romfs:/");
|
||||
|
||||
margs.window = MultiSpacc_SetWindow( &windowConfig );
|
||||
margs.screen = MultiSpacc_GetWindowSurface( margs.window );
|
||||
@ -99,7 +105,7 @@ int main( int argc, char *argv[] )
|
||||
|
||||
// Bitmap font forked from: <https://github.com/nesdoug/01_Hello/blob/master/Alpha.chr>
|
||||
// Original copyright (c) 2018 Doug Fraker www.nesdoug.com (MIT)
|
||||
margs.tilesImg = MultiSpacc_LoadImage( "../CHARS.png", margs.screen, NULL );
|
||||
margs.tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", margs.background, NULL );
|
||||
if( margs.tilesImg == NULL )
|
||||
{
|
||||
return -1;
|
||||
|
@ -18,4 +18,12 @@ All all:
|
||||
cd ..; \
|
||||
done
|
||||
|
||||
.PHONY: All all
|
||||
Clean clean Clear clear:
|
||||
for Example in */; \
|
||||
do \
|
||||
cd $${Example}; \
|
||||
make clean; \
|
||||
cd ..; \
|
||||
done
|
||||
|
||||
.PHONY: All all Clean clean Clear clear
|
@ -1,10 +1,16 @@
|
||||
#!/dev/null
|
||||
set -e
|
||||
SdkRoot="${ProjectRoot}/../../.."
|
||||
BuildDir="$(pwd)"
|
||||
|
||||
# TODO: multiple files
|
||||
for File in ${AppAssets}
|
||||
do sh "${SdkRoot}/Tools/python3.sh" "${SdkRoot}/Tools/pilbmp2nes.py" -i "${ProjectRoot}/${File}" -o ./CHARS.chr
|
||||
for SrcFile in ../Assets/*.4.png
|
||||
do
|
||||
SrcExt="${SrcFile##*.}"
|
||||
DstName="${SrcFile##*/}"
|
||||
DstName="${DstName%%.*}"
|
||||
if [ "${SrcExt}" = png ]
|
||||
then sh "${SdkRoot}/Tools/python3.sh" "${SdkRoot}/Tools/pilbmp2nes.py" -i "${SrcFile}" -o "./${DstName}.chr"
|
||||
fi
|
||||
done
|
||||
|
||||
for File in *.c
|
||||
|
@ -284,7 +284,7 @@ int main( int argc, char *argv[] )
|
||||
|
||||
// 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( "../CHARS.png", screen, NULL );
|
||||
tilesImg = MultiSpacc_LoadImage( "./Assets/CHARS.png", screen, NULL );
|
||||
if( tilesImg == NULL )
|
||||
{
|
||||
return -1;
|
||||
|
@ -4,7 +4,9 @@ bool MultiSpacc_CheckKey( int key, char pad )
|
||||
{
|
||||
#if defined(MultiSpacc_Target_SDLCommon)
|
||||
#if defined(MultiSpacc_Target_SDL12)
|
||||
Uint8 *keys = SDL_GetKeyState(NULL);
|
||||
Uint8 *keys;
|
||||
SDL_PumpEvents();
|
||||
keys = SDL_GetKeyState(NULL);
|
||||
#elif defined(MultiSpacc_Target_SDL20)
|
||||
const Uint8 *keys;
|
||||
SDL_PumpEvents();
|
||||
|
@ -5,6 +5,19 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(MultiSpacc_Target_Switch) && defined(MultiSpacc_Target_SDLCommon)
|
||||
#define JOY_A 0
|
||||
#define JOY_B 1
|
||||
#define JOY_X 2
|
||||
#define JOY_Y 3
|
||||
#define JOY_PLUS 10
|
||||
#define JOY_MINUS 11
|
||||
#define JOY_LEFT 12
|
||||
#define JOY_UP 13
|
||||
#define JOY_RIGHT 14
|
||||
#define JOY_DOWN 15
|
||||
#endif
|
||||
|
||||
// Action1
|
||||
#if defined(MultiSpacc_Target_NES)
|
||||
#define MultiSpacc_Key_Action1 PAD_A
|
||||
@ -32,10 +45,10 @@ extern "C" {
|
||||
|
||||
// Pause
|
||||
#if defined(MultiSpacc_Target_SDLCommon) && (defined(MultiSpacc_Target_PC) || defined(MultiSpacc_Target_Web))
|
||||
// #define MultiSpacc_Key_Pause SDLK_ESCAPE
|
||||
//#define MultiSpacc_Key_Pause SDLK_ESCAPE
|
||||
#define MultiSpacc_Key_Pause SDL_SCANCODE_ESCAPE
|
||||
#elif defined(MultiSpacc_Target_SDLCommon) && defined(MultiSpacc_Target_Switch)
|
||||
#define MultiSpacc_Key_Pause 10
|
||||
#define MultiSpacc_Key_Pause JOY_PLUS
|
||||
#elif defined(MultiSpacc_Target_NDS)
|
||||
#define MultiSpacc_Key_Pause KEY_START
|
||||
#elif defined(MultiSpacc_Target_NES)
|
||||
|
@ -34,10 +34,14 @@ void MultiSpacc_PrintText( char text[], MultiSpacc_Surface *Surface, MultiSpacc_
|
||||
|
||||
void MultiSpacc_PrintDebug( const char *format, ... )
|
||||
{
|
||||
#ifdef MultiSpacc_Target_SDLCom
|
||||
#if defined(MultiSpacc_Target_SDLCommon)
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
SDL_Log( format, args );
|
||||
#if defined(MultiSpacc_Target_SDL12)
|
||||
sprintf( (char*)stderr, format, args );
|
||||
#elif defined(MultiSpacc_Target_SDL20)
|
||||
SDL_Log( format, args );
|
||||
#endif
|
||||
va_end(args);
|
||||
#endif
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ MultiSpacc_Window *MultiSpacc_SetWindow( MultiSpacc_SurfaceConfig *windowConfig
|
||||
windowConfig->height = 480;
|
||||
}
|
||||
if( windowConfig->bits <= 0 ){
|
||||
windowConfig->bits = 24;
|
||||
windowConfig->bits = 32;
|
||||
}
|
||||
|
||||
#if defined(MultiSpacc_Target_SDL12)
|
||||
|
@ -4,15 +4,28 @@ LibMultiSpacc is a library aiming to provide cross-platform abstractions for a n
|
||||
|
||||
The idea is simple: to build an universal abstraction layer on top of other existing libraries, that developers can use in their code instead of the platform-specific calls, to make it possible for an application to get build-time support for a major number of previously incompatible platforms.
|
||||
|
||||
The list of supported (or planned) backend libraries follows:
|
||||
The list of supported (or planned) platforms and backend libraries follows:
|
||||
|
||||
- Current PC platforms, modern mobile platforms and game consoles, the Web, ... via SDL 2.0 (WIP) (and 3.0?[^1])
|
||||
- Including: desktop Linux, Windows, Android, Switch, ...
|
||||
- Old PC and embedded platforms, ... via SDL 1.2 (WIP)
|
||||
- MS-DOS (?)
|
||||
- NDS (WIP)
|
||||
- Including: Windows 9x, 3DS, ...
|
||||
- MS-DOS, Windows 3.1 (Maybe?)
|
||||
- NDS via libnds (WIP)
|
||||
- GBA (Planned)
|
||||
- NES (WIP)
|
||||
- PS1/PS2 (Planned)
|
||||
- NES, via neslib (WIP)
|
||||
|
||||
SDL is used as the main cross-platform library everywhere possible as stated above, for convenience. Specific platform that require special code are handled separately via other base abstraction layers.
|
||||
|
||||
[^1]: I just discovered that SDL 3.0 exists, I'm so tired, why would they make a new major, now I have to support 3 versions... or just drop 2.0 and only support 1.2 + 3.0.
|
||||
[^1]: SDL 3.0 is the current experimental version of SDL, currently only 2.0 is considered stable. SDL 3.0 will be supported by LibMultiSpacc only if it grants any actual benefits (like better performance with equal code, or support for exclusive platforms) when it eventually becomes stable.
|
||||
|
||||
## Experimental notice
|
||||
|
||||
This project is still in an experimental phase. Tagged releases will eventually be made available with time, but currently you should avoid using the library for new projects by keeping sync with the development branch, as the API is constantly changing, and so things will break for you.
|
||||
|
||||
## Licensing
|
||||
|
||||
* The LibMultiSpacc core code is licensed under "GNU Lesser General Public License version 3 with Static Linking Exception", meaning you can use the library for any program, with any license, for any purpose, but if you modify part of the library core then you have to make that part (not necessarily your entire program) available in source code form under the original license. See [LICENSE.txt](./LICENSE.txt) for legal details.
|
||||
* The included examples for the library, both in code and media assets, will be licensed under an extremely permissive license that allows full remixing without any additional licensing/distribution requirements/obligations, but I currently don't know which would be best.
|
||||
* Any included third-party support library, or third-party borrowed media assets, fall under their own specified licenses.
|
||||
|
@ -1,25 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
#[ "$(whoami)" != root ] && {
|
||||
# echo "This script must run as root".
|
||||
# exit -1
|
||||
#}
|
||||
|
||||
mkdir -p /tmp /opt/Sdk
|
||||
|
||||
apt update
|
||||
apt install -y \
|
||||
make wine curl wget p7zip-full python3 python3-pil \
|
||||
gcc mingw-w64 cc65 emscripten \
|
||||
libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev \
|
||||
libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev \
|
||||
;
|
||||
|
||||
curl -o /tmp/mingw32.7z https://hlb0.octt.eu.org/Drive/Misc/mingw32-9.2.0.7z.sfx.exe
|
||||
7z x /tmp/mingw32.7z
|
||||
cp ./mingw32/bin/*.dll ./mingw32/libexec/gcc/mingw32/9.2.0/
|
||||
mv ./mingw32 /opt/Sdk/mingw32
|
||||
|
||||
curl -o /tmp/dkp.sh https://apt.devkitpro.org/install-devkitpro-pacman
|
||||
yes | bash /tmp/dkp.sh
|
||||
dkp-pacman -Sy nds-dev
|
||||
#!/bin/sh
|
||||
|
||||
#[ "$(whoami)" != root ] && {
|
||||
# echo "This script must run as root".
|
||||
# exit -1
|
||||
#}
|
||||
|
||||
mkdir -p /tmp /opt/Sdk
|
||||
|
||||
apt update
|
||||
apt install -y \
|
||||
make wine curl wget p7zip-full python3 python3-pil \
|
||||
gcc mingw-w64 cc65 emscripten \
|
||||
libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev \
|
||||
libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsdl2-mixer-dev \
|
||||
;
|
||||
|
||||
curl -o /tmp/mingw32.7z https://hlb0.octt.eu.org/Drive/Misc/mingw32-9.2.0.7z.sfx.exe
|
||||
7z x /tmp/mingw32.7z
|
||||
cp ./mingw32/bin/*.dll ./mingw32/libexec/gcc/mingw32/9.2.0/
|
||||
mv ./mingw32 /opt/Sdk/mingw32
|
||||
|
||||
curl -o /tmp/dkp.sh https://apt.devkitpro.org/install-devkitpro-pacman
|
||||
yes | bash /tmp/dkp.sh
|
||||
dkp-pacman -Sy nds-dev
|
||||
|
Loading…
x
Reference in New Issue
Block a user