Alibek Omarov
2 years ago
31 changed files with 575 additions and 40 deletions
After Width: | Height: | Size: 7.7 KiB |
@ -0,0 +1,125 @@ |
|||||||
|
/*
|
||||||
|
switch.c - switch backend |
||||||
|
Copyright (C) 2021-2023 fgsfds |
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify |
||||||
|
it under the terms of the GNU General Public License as published by |
||||||
|
the Free Software Foundation, either version 3 of the License, or |
||||||
|
(at your option) any later version. |
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, |
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
GNU General Public License for more details. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "platform/platform.h" |
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <switch.h> |
||||||
|
#include <solder.h> |
||||||
|
#include <SDL.h> |
||||||
|
|
||||||
|
static int nxlink_sock = -1; |
||||||
|
|
||||||
|
/* HACKHACK: force-export stuff required by the dynamic libs */ |
||||||
|
|
||||||
|
// this is required by some std::filesystem crap in libstdc++
|
||||||
|
// we don't have it defined in our libc
|
||||||
|
long pathconf( const char *path, int name ) { return -1; } |
||||||
|
|
||||||
|
// part of libunwind; required by any dynamic lib that uses C++ exceptions
|
||||||
|
extern void *_Unwind_Resume; |
||||||
|
|
||||||
|
// these are macros in our libc, so we need to wrap them
|
||||||
|
static int tolower_fn( int c ) { return tolower( c ); } |
||||||
|
static int toupper_fn( int c ) { return toupper( c ); } |
||||||
|
static int isalnum_fn( int c ) { return isalnum( c ); } |
||||||
|
static int isalpha_fn( int c ) { return isalpha( c ); } |
||||||
|
|
||||||
|
static const solder_export_t aux_exports[] = |
||||||
|
{ |
||||||
|
SOLDER_EXPORT( "tolower", tolower_fn ), |
||||||
|
SOLDER_EXPORT( "toupper", toupper_fn ), |
||||||
|
SOLDER_EXPORT( "isalnum", isalnum_fn ), |
||||||
|
SOLDER_EXPORT( "isalpha", isalpha_fn ), |
||||||
|
SOLDER_EXPORT_SYMBOL( mkdir ), |
||||||
|
SOLDER_EXPORT_SYMBOL( remove ), |
||||||
|
SOLDER_EXPORT_SYMBOL( rename ), |
||||||
|
SOLDER_EXPORT_SYMBOL( pathconf ), |
||||||
|
SOLDER_EXPORT_SYMBOL( fsync ), |
||||||
|
SOLDER_EXPORT_SYMBOL( strchrnul ), |
||||||
|
SOLDER_EXPORT_SYMBOL( stpcpy ), |
||||||
|
SOLDER_EXPORT_SYMBOL( _Unwind_Resume ), |
||||||
|
}; |
||||||
|
|
||||||
|
const solder_export_t *__solder_aux_exports = aux_exports; |
||||||
|
const size_t __solder_num_aux_exports = sizeof( aux_exports ) / sizeof( *aux_exports ); |
||||||
|
|
||||||
|
/* end of export crap */ |
||||||
|
|
||||||
|
void Platform_ShellExecute( const char *path, const char *parms ) |
||||||
|
{ |
||||||
|
Con_Reportf( S_WARN "Tried to shell execute ;%s; -- not supported\n", path ); |
||||||
|
} |
||||||
|
|
||||||
|
#if XASH_MESSAGEBOX == MSGBOX_NSWITCH |
||||||
|
void Platform_MessageBox( const char *title, const char *message, qboolean unused ) |
||||||
|
{ |
||||||
|
// TODO: maybe figure out how to show an actual messagebox or an on-screen console
|
||||||
|
// without murdering the renderer
|
||||||
|
// assume this is a fatal error
|
||||||
|
FILE *f = fopen( "fatal.log", "w" ); |
||||||
|
if ( f ) |
||||||
|
{ |
||||||
|
fprintf( f, "%s:\n%s\n", title, message ); |
||||||
|
fclose( f ); |
||||||
|
} |
||||||
|
// dump to nxlink as well
|
||||||
|
fprintf( stderr, "%s:\n%s\n", title, message ); |
||||||
|
} |
||||||
|
#endif // XASH_MESSAGEBOX == MSGBOX_NSWITCH
|
||||||
|
|
||||||
|
// this gets executed before main(), do not delete
|
||||||
|
void userAppInit( void ) |
||||||
|
{ |
||||||
|
socketInitializeDefault( ); |
||||||
|
#ifdef NSWITCH_DEBUG |
||||||
|
nxlink_sock = nxlinkStdio( ); |
||||||
|
#endif |
||||||
|
if ( solder_init( 0 ) < 0 ) |
||||||
|
{ |
||||||
|
fprintf( stderr, "solder_init() failed: %s\n", solder_dlerror() ); |
||||||
|
fflush( stderr ); |
||||||
|
exit( 1 ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// this gets executed on exit(), do not delete
|
||||||
|
void userAppExit( void ) |
||||||
|
{ |
||||||
|
solder_quit( ); |
||||||
|
if ( nxlink_sock >= 0 ) |
||||||
|
{ |
||||||
|
close( nxlink_sock ); |
||||||
|
nxlink_sock = -1; |
||||||
|
} |
||||||
|
socketExit( ); |
||||||
|
} |
||||||
|
|
||||||
|
void NSwitch_Init( void ) |
||||||
|
{ |
||||||
|
printf( "NSwitch_Init\n" ); |
||||||
|
} |
||||||
|
|
||||||
|
void NSwitch_Shutdown( void ) |
||||||
|
{ |
||||||
|
printf( "NSwitch_Shutdown\n" ); |
||||||
|
// force deinit everything SDL-related to avoid issues with changing games
|
||||||
|
if ( SDL_WasInit( 0 ) ) |
||||||
|
SDL_Quit( ); |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,20 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
. scripts/lib.sh |
||||||
|
|
||||||
|
cd "$BUILDDIR" || die |
||||||
|
|
||||||
|
rm -rf artifacts build pkgtemp |
||||||
|
|
||||||
|
mkdir -p pkgtemp/xash3d/{valve,gearbox,bshift}/{dlls,cl_dlls} || die |
||||||
|
mkdir -p artifacts/ || die |
||||||
|
|
||||||
|
echo "Running build script in Docker container..." |
||||||
|
|
||||||
|
docker run --name xash-build --rm -v `pwd`:`pwd` -w `pwd` devkitpro/devkita64:latest bash ./scripts/gha/build_nswitch_docker.sh || die |
||||||
|
|
||||||
|
echo "Packaging artifacts..." |
||||||
|
|
||||||
|
pushd pkgtemp |
||||||
|
7z a -t7z ../artifacts/xash3d-fwgs-nswitch.7z -m0=lzma2 -mx=9 -mfb=64 -md=32m -ms=on -r xash3d/ |
||||||
|
popd |
@ -0,0 +1,64 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
. scripts/lib.sh |
||||||
|
|
||||||
|
# args: branch name, gamedir name |
||||||
|
build_hlsdk() |
||||||
|
{ |
||||||
|
echo "Building HLSDK: $1 branch..." |
||||||
|
git checkout switch-$1 |
||||||
|
./waf configure -T release --nswitch || die_configure |
||||||
|
./waf build || die |
||||||
|
cp build/dlls/$1_nswitch_arm64.so ../pkgtemp/xash3d/$2/dlls/ |
||||||
|
cp build/cl_dll/client_nswitch_arm64.so ../pkgtemp/xash3d/$2/cl_dlls/ |
||||||
|
./waf clean |
||||||
|
} |
||||||
|
|
||||||
|
echo "Setting up environment..." |
||||||
|
|
||||||
|
# we can't actually download dkp-toolchain-vars even from here, so |
||||||
|
export PORTLIBS_ROOT=${DEVKITPRO}/portlibs |
||||||
|
export PATH=${DEVKITPRO}/tools/bin:${DEVKITPRO}/devkitA64/bin:$PATH |
||||||
|
export TOOL_PREFIX=aarch64-none-elf- |
||||||
|
export CC=${TOOL_PREFIX}gcc |
||||||
|
export CXX=${TOOL_PREFIX}g++ |
||||||
|
export AR=${TOOL_PREFIX}gcc-ar |
||||||
|
export RANLIB=${TOOL_PREFIX}gcc-ranlib |
||||||
|
export PORTLIBS_PREFIX=${DEVKITPRO}/portlibs/switch |
||||||
|
export PATH=$PORTLIBS_PREFIX/bin:$PATH |
||||||
|
export ARCH="-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec" |
||||||
|
export CFLAGS="${ARCH} -O2 -ffunction-sections -fdata-sections" |
||||||
|
export CXXFLAGS="${CFLAGS}" |
||||||
|
export CPPFLAGS="-D__SWITCH__ -I${PORTLIBS_PREFIX}/include -isystem ${DEVKITPRO}/libnx/include" |
||||||
|
export LDFLAGS="${ARCH} -L${PORTLIBS_PREFIX}/lib -L${DEVKITPRO}/libnx/lib" |
||||||
|
export LIBS="-lnx" |
||||||
|
|
||||||
|
# forgive me father, for I have sinned |
||||||
|
ln -s /usr/bin/python3 /usr/bin/python |
||||||
|
|
||||||
|
echo "Building libsolder..." |
||||||
|
|
||||||
|
make -C libsolder install || die |
||||||
|
|
||||||
|
echo "Building engine..." |
||||||
|
|
||||||
|
./waf configure -T release --nswitch || die_configure |
||||||
|
./waf build || die |
||||||
|
|
||||||
|
echo "Building HLSDK..." |
||||||
|
|
||||||
|
# TODO: replace with hlsdk-portable when PRs are merged |
||||||
|
pushd hlsdk-xash3d |
||||||
|
build_hlsdk hl valve |
||||||
|
build_hlsdk opfor gearbox |
||||||
|
build_hlsdk bshift bshift |
||||||
|
popd |
||||||
|
|
||||||
|
echo "Copying artifacts..." |
||||||
|
|
||||||
|
cp build/engine/xash.nro pkgtemp/xash3d/xash3d.nro |
||||||
|
cp build/filesystem/filesystem_stdio.so pkgtemp/xash3d/ |
||||||
|
cp build/ref/gl/libref_gl.so pkgtemp/xash3d/ |
||||||
|
cp build/ref/soft/libref_soft.so pkgtemp/xash3d/ |
||||||
|
cp build/3rdparty/mainui/libmenu.so pkgtemp/xash3d/ |
||||||
|
cp build/3rdparty/extras/extras.pk3 pkgtemp/xash3d/valve/ |
@ -0,0 +1,18 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
cd $GITHUB_WORKSPACE |
||||||
|
|
||||||
|
echo "Downloading devkitA64 docker container..." |
||||||
|
|
||||||
|
docker pull devkitpro/devkita64:latest || exit 1 |
||||||
|
|
||||||
|
echo "Downloading libsolder..." |
||||||
|
|
||||||
|
rm -rf libsolder |
||||||
|
git clone https://github.com/fgsfdsfgs/libsolder.git || exit 1 |
||||||
|
|
||||||
|
echo "Downloading HLSDK..." |
||||||
|
|
||||||
|
# TODO: change to FWGS/hlsdk-portable.git when changes are merged in |
||||||
|
rm -rf hlsdk-xash3d hlsdk-portable |
||||||
|
git clone --recursive https://github.com/fgsfdsfgs/hlsdk-xash3d.git || exit 1 |
@ -0,0 +1,64 @@ |
|||||||
|
# encoding: utf-8 |
||||||
|
# nswitch.py -- switch NRO task |
||||||
|
# Copyright (C) 2018 a1batross |
||||||
|
# This program is free software: you can redistribute it and/or modify |
||||||
|
# it under the terms of the GNU General Public License as published by |
||||||
|
# the Free Software Foundation, either version 3 of the License, or |
||||||
|
# (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
|
||||||
|
from waflib.Tools import ccroot |
||||||
|
from waflib import * |
||||||
|
|
||||||
|
def configure(conf): |
||||||
|
conf.find_program('elf2nro') |
||||||
|
|
||||||
|
v = conf.env |
||||||
|
|
||||||
|
v.ELF2NRO_NACP_F = ['--nacp='] |
||||||
|
v.ELF2NRO_ICON_F = ['--icon='] |
||||||
|
|
||||||
|
class elf2nro(Task.Task): |
||||||
|
color = 'RED' |
||||||
|
run_str = '${ELF2NRO} ${ELFFILE} ${TGT} ${ELF2NRO_NACP_F?NACP}${NACP} ${ELF2NRO_ICON_F?ICON}${ICON}' |
||||||
|
|
||||||
|
def keyword(self): |
||||||
|
if Logs.colors_lst['USE']: # red/blue switch colors :) |
||||||
|
return '%sConverting to NRO' % Logs.colors_lst['CYAN'] |
||||||
|
return 'Converting to NRO' |
||||||
|
|
||||||
|
@TaskGen.feature('cxxprogram') |
||||||
|
@TaskGen.after_method('apply_link') |
||||||
|
def apply_nro(self): |
||||||
|
elffile = self.link_task.outputs[0] |
||||||
|
|
||||||
|
nodes = [elffile] |
||||||
|
|
||||||
|
def add_source_file(ctx, nodes, f): |
||||||
|
if f: |
||||||
|
if isinstance(f, str): |
||||||
|
node = ctx.path.make_node(f) |
||||||
|
elif isinstance(f, Node.Node): |
||||||
|
node = f |
||||||
|
|
||||||
|
nodes += [node] |
||||||
|
return node |
||||||
|
return None |
||||||
|
|
||||||
|
nacpfile = add_source_file(self, nodes, getattr(self, 'nacp', None)) |
||||||
|
iconfile = add_source_file(self, nodes, getattr(self, 'icon', None)) |
||||||
|
self.env.ELFFILE = str(elffile) |
||||||
|
if nacpfile: self.env.NACP = str(nacpfile) |
||||||
|
if iconfile: self.env.ICON = str(iconfile) |
||||||
|
|
||||||
|
tsk = self.nro_task = self.create_task('elf2nro', nodes) |
||||||
|
self.nro_task.set_outputs(nodes[0].change_ext('.nro')) |
||||||
|
|
||||||
|
inst_to = getattr(self, 'nro_install_path', None) |
||||||
|
if inst_to: |
||||||
|
self.add_install_files(install_to=inst_to, |
||||||
|
install_from=tsk.outputs[:], chmod=Utils.O755, task=tsk) |
Loading…
Reference in new issue