From 88192cb3f34fcfbadda89a455760e3bde01d943b Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 11:17:20 +0200 Subject: [PATCH 01/22] switch: first commit --- .gitignore | 4 ++ CMakeLists.switch | 144 +++++++++++++++++++++++++++++++++++++ engine/source/globals.h | 5 ++ engine/source/ramlib/ram.c | 5 +- 4 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 CMakeLists.switch diff --git a/.gitignore b/.gitignore index c1190ff56..699284713 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ tools/bin/.wget-hsts tools/win-sdk/* tools/psp-sdk/* tools/devkitpro/* +# switch port +.idea +cmake-build* +CMakeLists.txt \ No newline at end of file diff --git a/CMakeLists.switch b/CMakeLists.switch new file mode 100644 index 000000000..bbc4f7632 --- /dev/null +++ b/CMakeLists.switch @@ -0,0 +1,144 @@ +cmake_minimum_required(VERSION 3.1) +#set(CMAKE_VERBOSE_MAKEFILE ON) + +option(PLATFORM_LINUX "Linux platform target" OFF) +option(PLATFORM_SWITCH "Nintendo Switch platform target" OFF) + +option(BUILD_GFX "Build with GFX support" ON) +option(BUILD_VORBIS "Build with BUILD_VORBIS support" ON) + +if (PLATFORM_LINUX) + set(CMAKE_SYSTEM_NAME "Linux") +elseif (PLATFORM_SWITCH) + set(CMAKE_SYSTEM_NAME "Generic") + set(DEVKITPRO $ENV{DEVKITPRO}) + set(CMAKE_SYSTEM_PROCESSOR "armv8-a") + set(CMAKE_C_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc") + set(CMAKE_CXX_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++") + set(CMAKE_ASM_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-as") + set(CMAKE_AR "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ar" CACHE STRING "") + set(CMAKE_RANLIB "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ranlib" CACHE STRING "") + set(CMAKE_C_FLAGS "-g -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -ftls-model=local-exec -fPIC -I${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include" CACHE STRING "C flags") + set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions" CACHE STRING "C++ flags") + set(PKG_CONFIG_EXECUTABLE ${DEVKITPRO}/portlibs/switch/bin/aarch64-none-elf-pkg-config) + set(CMAKE_FIND_ROOT_PATH ${DEVKITPRO} ${DEVKITPRO}/devkitA64 ${DEVKITPRO}/libnx ${DEVKITPRO}/portlibs/switch) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available") +endif () + +project(OpenBOR) + +############## +# COMMON +############## + +include(FindPkgConfig) +pkg_search_module(SDL2 REQUIRED sdl2) +pkg_search_module(VPX REQUIRED vpx) +pkg_search_module(PNG REQUIRED libpng) +pkg_search_module(ZLIB REQUIRED zlib) + +set(BOR_INC + engine + engine/sdl + engine/source + engine/source/adpcmlib + engine/source/gamelib + engine/source/openborscript + engine/source/pnglib + engine/source/preprocessorlib + engine/source/ramlib + engine/source/randlib + engine/source/scriptlib + engine/source/webmlib + engine/source/webmlib/halloc + engine/source/webmlib/nestegg + ${SDL2_INCLUDE_DIRS} + ${VPX_INCLUDE_DIRS} + ${PNG_INCLUDE_DIRS} + ${ZLIB_INCLUDE_DIRS} + ) + +file(GLOB BOR_SRC + engine/*.c + engine/sdl/*.c + engine/source/*.c + engine/source/adpcmlib/*.c + engine/source/gamelib/*.c + engine/source/openborscript/*.c + engine/source/pnglib/*.c + engine/source/preprocessorlib/*.c + engine/source/ramlib/*.c + engine/source/randlib/*.c + engine/source/scriptlib/*.c + engine/source/webmlib/*.c + engine/source/webmlib/halloc/*.c + engine/source/webmlib/nestegg/*.c + ) + +set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2) + +set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) + +##################### +# OPTIONS +##################### +if (BUILD_GFX) + list(APPEND BOR_INC engine/source/gfxlib) + file(GLOB GFX_SRC engine/source/gfxlib/*.c) + list(APPEND BOR_SRC ${GFX_SRC}) +endif () +if (BUILD_VORBIS) + pkg_search_module(VORBIS REQUIRED vorbis) + pkg_search_module(VORBISFILE REQUIRED vorbisfile) + pkg_search_module(OGG REQUIRED ogg) + list(APPEND BOR_INC ${VORBIS_INCLUDE_DIRS} ${VORBISFILE_INCLUDE_DIRS} ${OGG_INCLUDE_DIRS}) + list(APPEND BOR_CFLAGS -DOV_EXCLUDE_STATIC_CALLBACKS) + list(APPEND BOR_LDFLAGS ${VORBIS_LIBRARIES} ${VORBISFILE_LIBRARIES} ${OGG_LIBRARIES} m) +endif () + +##################### +# PLATORM SPECIFIC +##################### +if (PLATFORM_SWITCH) + ##################### + # SWITCH PLATORM + ##################### + # Ryujinx doesn't like original png decoding code.. replace that + # list(REMOVE_ITEM BOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/engine/source/pnglib/pngdec.c) + #list(APPEND BOR_INC engine/switch) + #file(GLOB SWITCH_SRC engine/switch/*.c) + #list(APPEND BOR_SRC ${SWITCH_SRC}) + list(APPEND BOR_CFLAGS -D__SWITCH__) + list(APPEND BOR_LDFLAGS + -L${DEVKITPRO}/libnx/lib + -L${DEVKITPRO}/portlibs/switch/lib + -specs=${DEVKITPRO}/libnx/switch.specs + stdc++) +elseif (PLATFORM_LINUX) + ##################### + # LINUX PLATORM + ##################### + list(APPEND BOR_CFLAGS -D__LINUX__) +endif () + +##################### +# OpenBOR executable +##################### +add_executable(${CMAKE_PROJECT_NAME}.elf ${BOR_SRC}) +target_include_directories(${CMAKE_PROJECT_NAME}.elf PRIVATE ${BOR_INC}) +target_compile_options(${CMAKE_PROJECT_NAME}.elf PRIVATE ${BOR_CFLAGS}) +target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${BOR_LDFLAGS}) + +##################### +# SWITCH target +##################### +if (PLATFORM_SWITCH) + add_custom_target(${CMAKE_PROJECT_NAME}.nro + DEPENDS ${CMAKE_PROJECT_NAME}.elf + COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste, rsn8887" "1.1" ${CMAKE_PROJECT_NAME}.nacp + COMMAND elf2nro ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.nro --icon=${CMAKE_SOURCE_DIR}/engine/resources/switch_icon.jpg --nacp=${CMAKE_PROJECT_NAME}.nacp) +endif () diff --git a/engine/source/globals.h b/engine/source/globals.h index ca80c1f30..a8d000cca 100644 --- a/engine/source/globals.h +++ b/engine/source/globals.h @@ -65,6 +65,11 @@ #define strnicmp strncasecmp #endif +#if defined(__LINUX__) || defined(__SWITCH__) +#define stricmp strcasecmp +#define strnicmp strncasecmp +#endif + #include "packfile.h" ///////////////////////////////////////////////////////////////////////////// diff --git a/engine/source/ramlib/ram.c b/engine/source/ramlib/ram.c index 96e93a85f..9df914711 100644 --- a/engine/source/ramlib/ram.c +++ b/engine/source/ramlib/ram.c @@ -179,12 +179,15 @@ void setSystemRam() #elif VITA systemRam = 0x0f000000; elfOffset = 0x00000000; +#elif __SWITCH__ + systemRam = (u64) 2048 * 1024 * 1024; + elfOffset = 0x00000000; #else elfOffset = 0x00000000; stackSize = 0x00000000; systemRam = getFreeRam(BYTES); #endif -#if !(defined(WIN) || defined(LINUX) || defined(DARWIN) || defined(SYMBIAN) || defined(VITA)) +#if !(defined(WIN) || defined(LINUX) || defined(DARWIN) || defined(SYMBIAN) || defined(VITA) || defined(__SWITCH__)) stackSize = (int)&_end - (int)&_start + ((int)&_start - elfOffset); #endif getRamStatus(BYTES); From ada8a29e3c3f6a79eaeda910770411f8887482dd Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 12:58:41 +0200 Subject: [PATCH 02/22] switch: minor cleanup --- CMakeLists.switch | 21 ++++++++++++--------- engine/source/globals.h | 11 ++++++++++- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CMakeLists.switch b/CMakeLists.switch index bbc4f7632..d8f835438 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -#set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_VERBOSE_MAKEFILE ON) option(PLATFORM_LINUX "Linux platform target" OFF) option(PLATFORM_SWITCH "Nintendo Switch platform target" OFF) @@ -79,10 +79,18 @@ file(GLOB BOR_SRC engine/source/webmlib/nestegg/*.c ) -set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2) - +set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -D__CMAKE__) set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) +############## +# VERSION.SH +############## +ADD_CUSTOM_COMMAND( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/engine/version.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/engine + COMMAND bash version.sh) +list(APPEND BOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/engine/version.h) + ##################### # OPTIONS ##################### @@ -107,11 +115,6 @@ if (PLATFORM_SWITCH) ##################### # SWITCH PLATORM ##################### - # Ryujinx doesn't like original png decoding code.. replace that - # list(REMOVE_ITEM BOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/engine/source/pnglib/pngdec.c) - #list(APPEND BOR_INC engine/switch) - #file(GLOB SWITCH_SRC engine/switch/*.c) - #list(APPEND BOR_SRC ${SWITCH_SRC}) list(APPEND BOR_CFLAGS -D__SWITCH__) list(APPEND BOR_LDFLAGS -L${DEVKITPRO}/libnx/lib @@ -122,7 +125,7 @@ elseif (PLATFORM_LINUX) ##################### # LINUX PLATORM ##################### - list(APPEND BOR_CFLAGS -D__LINUX__) + list(APPEND BOR_CFLAGS -D__LINUX__ -DLINUX) endif () ##################### diff --git a/engine/source/globals.h b/engine/source/globals.h index a8d000cca..60b63ef28 100644 --- a/engine/source/globals.h +++ b/engine/source/globals.h @@ -65,7 +65,7 @@ #define strnicmp strncasecmp #endif -#if defined(__LINUX__) || defined(__SWITCH__) +#ifdef __SWITCH__ #define stricmp strcasecmp #define strnicmp strncasecmp #endif @@ -74,6 +74,14 @@ ///////////////////////////////////////////////////////////////////////////// +#ifdef __CMAKE__ +#ifdef NDEBUG +#define printf writeToLogFile +#undef assert +#define assert(x) exitIfFalse((x)?1:0, #x, __func__, __FILE__, __LINE__) +#define sysassert(x) abortIfFalse((x)?1:0, #x, __func__, __FILE__, __LINE__) +#endif +#else #ifndef PP_TEST #define printf writeToLogFile @@ -82,6 +90,7 @@ #define assert(x) exitIfFalse((x)?1:0, #x, __func__, __FILE__, __LINE__) #define sysassert(x) abortIfFalse((x)?1:0, #x, __func__, __FILE__, __LINE__) #endif +#endif ///////////////////////////////////////////////////////////////////////////// From 95f1401f7d5df213e0e1087b41eb4deb0c3ddbd6 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 13:17:16 +0200 Subject: [PATCH 03/22] switch: enable opengl, increase available ram, add icon --- CMakeLists.switch | 4 ++-- engine/resources/switch_icon.jpg | Bin 0 -> 45897 bytes engine/source/ramlib/ram.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 engine/resources/switch_icon.jpg diff --git a/CMakeLists.switch b/CMakeLists.switch index d8f835438..f609b27a0 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -79,7 +79,7 @@ file(GLOB BOR_SRC engine/source/webmlib/nestegg/*.c ) -set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -D__CMAKE__) +set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DOPENGL -DLOADGL -D__CMAKE__) set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) ############## @@ -142,6 +142,6 @@ target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${BOR_LDFLAGS}) if (PLATFORM_SWITCH) add_custom_target(${CMAKE_PROJECT_NAME}.nro DEPENDS ${CMAKE_PROJECT_NAME}.elf - COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste, rsn8887" "1.1" ${CMAKE_PROJECT_NAME}.nacp + COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste" "3.0.7087" ${CMAKE_PROJECT_NAME}.nacp COMMAND elf2nro ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.nro --icon=${CMAKE_SOURCE_DIR}/engine/resources/switch_icon.jpg --nacp=${CMAKE_PROJECT_NAME}.nacp) endif () diff --git a/engine/resources/switch_icon.jpg b/engine/resources/switch_icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fc4207e8ce9ac7bed7afe41e3b9f6f4b7709a963 GIT binary patch literal 45897 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ⅈ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 Date: Sun, 3 May 2020 13:44:04 +0200 Subject: [PATCH 04/22] switch: use 720p by default, add nxlink debug --- CMakeLists.switch | 4 ++-- engine/openbor.c | 3 +++ engine/sdl/sdlport.c | 14 ++++++++++++++ engine/sdl/video.c | 5 +++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CMakeLists.switch b/CMakeLists.switch index f609b27a0..eb53e7a01 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -79,7 +79,7 @@ file(GLOB BOR_SRC engine/source/webmlib/nestegg/*.c ) -set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DOPENGL -DLOADGL -D__CMAKE__) +set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DWEBM -DOPENGL -DLOADGL -D__CMAKE__) set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) ############## @@ -115,7 +115,7 @@ if (PLATFORM_SWITCH) ##################### # SWITCH PLATORM ##################### - list(APPEND BOR_CFLAGS -D__SWITCH__) + list(APPEND BOR_CFLAGS -D__SWITCH__ -DNXLINK) list(APPEND BOR_LDFLAGS -L${DEVKITPRO}/libnx/lib -L${DEVKITPRO}/portlibs/switch/lib diff --git a/engine/openbor.c b/engine/openbor.c index 44eb88b93..0d04cfe7e 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -37870,6 +37870,9 @@ void init_videomodes(int log) #elif VITA tryfile("data/videovita.txt"); tryfile("data/video169.txt"); +#elif __SWITCH__ + tryfile("data/videoswitch.txt"); + tryfile("data/video169.txt"); #endif #undef tryfile diff --git a/engine/sdl/sdlport.c b/engine/sdl/sdlport.c index a820fefc3..0a0b2c296 100644 --- a/engine/sdl/sdlport.c +++ b/engine/sdl/sdlport.c @@ -20,6 +20,9 @@ #include #elif WIN #undef main +#elif defined(__SWITCH__) && defined(NXLINK) +#include +static int nxlink_sock = -1; #endif char packfile[MAX_FILENAME_LEN] = {"bor.pak"}; @@ -64,6 +67,12 @@ void borExit(int reset) SDL_Quit(); // call this instead of atexit(SDL_Quit); It's best practice! #endif +#if defined(__SWITCH__) && defined(NXLINK) + if (nxlink_sock != -1) + close(nxlink_sock); + socketExit(); +#endif + exit(reset); } @@ -101,6 +110,11 @@ int main(int argc, char *argv[]) } #endif +#if defined(__SWITCH__) && defined(NXLINK) + socketInitializeDefault(); + nxlink_sock = nxlinkStdio(); +#endif + setSystemRam(); initSDL(); diff --git a/engine/sdl/video.c b/engine/sdl/video.c index c5c592cd1..7eab37060 100644 --- a/engine/sdl/video.c +++ b/engine/sdl/video.c @@ -64,10 +64,15 @@ void initSDL() } #endif +#ifdef __SWITCH__ + nativeWidth = 1280; + nativeHeight = 720; +#else SDL_GetCurrentDisplayMode(0, &video_info); nativeWidth = video_info.w; nativeHeight = video_info.h; printf("debug:nativeWidth, nativeHeight, bpp, Hz %d, %d, %d, %d\n", nativeWidth, nativeHeight, SDL_BITSPERPIXEL(video_info.format), video_info.refresh_rate); +#endif } void video_set_window_title(const char* title) From a95ff67edcda44943e4958afbf55144a452c0379 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 18:20:36 +0200 Subject: [PATCH 05/22] switch: fix default inputs --- engine/sdl/control.h | 61 +++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/engine/sdl/control.h b/engine/sdl/control.h index 9450fdb4f..e8ebb2484 100644 --- a/engine/sdl/control.h +++ b/engine/sdl/control.h @@ -47,6 +47,21 @@ #define CONTROL_DEFAULT1_START (JOY_LIST_FIRST + 11) #define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 12) #define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 15) +#elif __SWITCH__ + #define CONTROL_ESC (JOY_LIST_FIRST + 11) + 1 // MINUS + #define CONTROL_DEFAULT1_START (JOY_LIST_FIRST + 10) + 1 // PLUS + #define CONTROL_DEFAULT1_UP (JOY_LIST_FIRST + 13) + 1 // DUP + #define CONTROL_DEFAULT1_DOWN (JOY_LIST_FIRST + 15) + 1 // DDOWN + #define CONTROL_DEFAULT1_LEFT (JOY_LIST_FIRST + 12) + 1 // DLEFT + #define CONTROL_DEFAULT1_RIGHT (JOY_LIST_FIRST + 14) + 1 // DRIGHT + #define CONTROL_DEFAULT1_FIRE1 (JOY_LIST_FIRST + 0) + 1 // A + #define CONTROL_DEFAULT1_FIRE2 (JOY_LIST_FIRST + 1) + 1 // B + #define CONTROL_DEFAULT1_FIRE3 (JOY_LIST_FIRST + 2) + 1 // X + #define CONTROL_DEFAULT1_FIRE4 (JOY_LIST_FIRST + 3) + 1 // Y + #define CONTROL_DEFAULT1_FIRE5 (JOY_LIST_FIRST + 8) + 1 // ZL + #define CONTROL_DEFAULT1_FIRE6 (JOY_LIST_FIRST + 9) + 1 // ZR + #define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 5) + 1 // RSTICK + #define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 11) + 1 // MINUS #else #ifdef SDL2 #define CONTROL_ESC SDL_SCANCODE_ESCAPE @@ -138,8 +153,8 @@ typedef struct{ u64 keyflags, newkeyflags; int kb_break; }s_playercontrols; - -void open_joystick(int i); + +void open_joystick(int i); void close_joystick(int i); void control_exit(); void control_init(int joy_enable); @@ -148,36 +163,36 @@ int control_getjoyenabled(); void control_setkey(s_playercontrols * pcontrols, unsigned int flag, int key); int control_scankey(); - -void set_default_joystick_keynames(int i); -void reset_joystick_map(int i); -char* get_joystick_name(const char* name); + +void set_default_joystick_keynames(int i); +void reset_joystick_map(int i); +char* get_joystick_name(const char* name); char *control_getkeyname(unsigned int keycode); void control_update(s_playercontrols ** playercontrols, int numplayers); void control_rumble(int port, int ratio, int msec); -int keyboard_getlastkey(); - -#ifdef ANDROID -#define MAX_POINTERS 30 +int keyboard_getlastkey(); + +#ifdef ANDROID +#define MAX_POINTERS 30 typedef enum -{ +{ TOUCH_STATUS_UP, TOUCH_STATUS_DOWN -} touch_status; - -typedef struct TouchStatus { +} touch_status; + +typedef struct TouchStatus { float px[MAX_POINTERS]; float py[MAX_POINTERS]; - SDL_FingerID pid[MAX_POINTERS]; - touch_status pstatus[MAX_POINTERS]; -} TouchStatus; - -int is_touchpad_vibration_enabled(); -void control_update_android_touch(TouchStatus *touch_info, int maxp, Uint8* keystate, Uint8* keystate_def); + SDL_FingerID pid[MAX_POINTERS]; + touch_status pstatus[MAX_POINTERS]; +} TouchStatus; + +int is_touchpad_vibration_enabled(); +void control_update_android_touch(TouchStatus *touch_info, int maxp, Uint8* keystate, Uint8* keystate_def); int is_touch_area(float x, float y); -#endif - - +#endif + + #endif From a2ee4926314d02a0712973943803fb830b1dc7dd Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 20:48:48 +0200 Subject: [PATCH 06/22] sdl/menu: fix getPreview crash on 32 bits previews --- engine/sdl/menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/sdl/menu.c b/engine/sdl/menu.c index c42e93953..30242b0c8 100644 --- a/engine/sdl/menu.c +++ b/engine/sdl/menu.c @@ -279,8 +279,8 @@ static s_screen *getPreview(char *filename) else { scalescreen(scale, title); + memcpy(scale->palette, title->palette, PAL_BYTES); } - memcpy(scale->palette, title->palette, PAL_BYTES); // ScreenShots within Menu will be saved as "Menu" strncpy(packfile,"Menu.xxx",MAX_FILENAME_LEN); From d081601ad6b87693e97679eb40f73bc835f70933 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 21:16:15 +0200 Subject: [PATCH 07/22] switch: define joystick button names --- engine/sdl/joysticks.c | 75 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/engine/sdl/joysticks.c b/engine/sdl/joysticks.c index 1556d2b2c..ef547ac59 100644 --- a/engine/sdl/joysticks.c +++ b/engine/sdl/joysticks.c @@ -224,6 +224,80 @@ const u64 JoystickBits[JOY_MAX_INPUTS + 1] = { 0x8000000000000000 // Button 60 }; +#ifdef __SWITCH__ +const char *JoystickButtonNames[JOY_NAME_SIZE] = { + "...", +#define BUTTON_NAMES(x) \ + "A", \ + "B", \ + "X", \ + "Y", \ + "LS", \ + "RS", \ + "L", \ + "R", \ + "ZL", \ + "ZR", \ + "+", \ + "-", \ + "LEFT", \ + "UP", \ + "RIGHT", \ + "DOWN", \ + "SL_LEFT", \ + "SL_UP", \ + "SL_RIGHT", \ + "SL_DOWN", \ + "SR_LEFT", \ + "SR_UP", \ + "SR_RIGHT", \ + "SR_DOWN", \ + "Button 25", \ + "Button 26", \ + "Button 27", \ + "Button 28", \ + "Button 29", \ + "Button 30", \ + "Button 31", \ + "Button 32", \ + "Button 33", \ + "Button 34", \ + "Button 35", \ + "Button 36", \ + "Button 37", \ + "Button 38", \ + "Button 39", \ + "Button 40", \ + "Button 41", \ + "Button 42", \ + "Button 43", \ + "Button 44", \ + "Button 45", \ + "Button 46", \ + "Button 47", \ + "Button 48", \ + "Button 49", \ + "Button 50", \ + "Button 51", \ + "Button 52", \ + "Button 53", \ + "Button 54", \ + "Button 55", \ + "Button 56", \ + "Button 57", \ + "Button 58", \ + "Button 59", \ + "Button 60", \ + "Button 61", \ + "Button 62", \ + "Button 63", \ + "Button 64", + BUTTON_NAMES("P1") + BUTTON_NAMES("P2") + BUTTON_NAMES("P3") + BUTTON_NAMES("P4") +}; +#else const char* JoystickButtonNames[JOY_NAME_SIZE] = { "...", #define BUTTON_NAMES(x) \ @@ -296,6 +370,7 @@ const char* JoystickButtonNames[JOY_NAME_SIZE] = { BUTTON_NAMES("P3") BUTTON_NAMES("P4") }; +#endif const char* JoystickAxisNames[JOY_NAME_SIZE] = { "...", From 25d1042326725a6ca0cbb0dabda114cfd823b339 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 21:31:13 +0200 Subject: [PATCH 08/22] switch: use wide screen setting in menu --- engine/sdl/menu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/sdl/menu.c b/engine/sdl/menu.c index 30242b0c8..13b6c7ce6 100644 --- a/engine/sdl/menu.c +++ b/engine/sdl/menu.c @@ -58,7 +58,11 @@ static s_screen* logscreen; #define LOG_SCREEN_END (isWide ? 26 : 23) static int bpp = 32; +#ifdef __SWITCH__ +static int isWide = 1; +#else static int isWide = 0; +#endif static int isFull = 0; static int dListTotal; static int dListCurrentPosition; From 5acc50254d1984416d42da43ea8a8f97a57fff9b Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 21:35:12 +0200 Subject: [PATCH 09/22] switch: invert x/y and l/r buttons --- engine/sdl/control.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/sdl/control.h b/engine/sdl/control.h index e8ebb2484..6b7d977a4 100644 --- a/engine/sdl/control.h +++ b/engine/sdl/control.h @@ -56,10 +56,10 @@ #define CONTROL_DEFAULT1_RIGHT (JOY_LIST_FIRST + 14) + 1 // DRIGHT #define CONTROL_DEFAULT1_FIRE1 (JOY_LIST_FIRST + 0) + 1 // A #define CONTROL_DEFAULT1_FIRE2 (JOY_LIST_FIRST + 1) + 1 // B - #define CONTROL_DEFAULT1_FIRE3 (JOY_LIST_FIRST + 2) + 1 // X - #define CONTROL_DEFAULT1_FIRE4 (JOY_LIST_FIRST + 3) + 1 // Y - #define CONTROL_DEFAULT1_FIRE5 (JOY_LIST_FIRST + 8) + 1 // ZL - #define CONTROL_DEFAULT1_FIRE6 (JOY_LIST_FIRST + 9) + 1 // ZR + #define CONTROL_DEFAULT1_FIRE3 (JOY_LIST_FIRST + 8) + 1 // X + #define CONTROL_DEFAULT1_FIRE4 (JOY_LIST_FIRST + 9) + 1 // Y + #define CONTROL_DEFAULT1_FIRE5 (JOY_LIST_FIRST + 2) + 1 // ZL + #define CONTROL_DEFAULT1_FIRE6 (JOY_LIST_FIRST + 3) + 1 // ZR #define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 5) + 1 // RSTICK #define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 11) + 1 // MINUS #else From 4f57d275a6861ada2c243b5c0600fe4dab929e07 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Sun, 3 May 2020 21:55:28 +0200 Subject: [PATCH 10/22] switch: prevent joystick disabling --- CMakeLists.switch | 2 +- engine/openbor.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.switch b/CMakeLists.switch index eb53e7a01..60a03e7ca 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -set(CMAKE_VERBOSE_MAKEFILE ON) +#set(CMAKE_VERBOSE_MAKEFILE ON) option(PLATFORM_LINUX "Linux platform target" OFF) option(PLATFORM_SWITCH "Nintendo Switch platform target" OFF) diff --git a/engine/openbor.c b/engine/openbor.c index 0d04cfe7e..b34d42af6 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -38467,7 +38467,9 @@ void menu_options_input() switch(selector) { case 0: +#ifndef __SWITCH__ control_usejoy((savedata.usejoy ^= 1)); +#endif break; case 1: keyboard_setup(0); From e9817bbe42a3a8264ab616390e92a133cf753497 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Mon, 4 May 2020 20:08:53 +0200 Subject: [PATCH 11/22] switch: do not try to load 32 bits previews (too slow) --- engine/sdl/menu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/engine/sdl/menu.c b/engine/sdl/menu.c index 13b6c7ce6..42c639087 100644 --- a/engine/sdl/menu.c +++ b/engine/sdl/menu.c @@ -269,8 +269,12 @@ static s_screen *getPreview(char *filename) // Grab current path and filename getBasePath(packfile, filename, 1); // Create & Load & Scale Image - if(!loadscreen("data/bgs/title", packfile, NULL, PIXEL_x8, &title) && - !loadscreen32("data/bgs/title", packfile, &title)) + if(!loadscreen("data/bgs/title", packfile, NULL, PIXEL_x8, &title) + #ifdef __SWITCH__ + ) + #else + && !loadscreen32("data/bgs/title", packfile, &title)) + #endif { return NULL; } From b0c3f204dca74efc8a64132903ab90c73b27f9ad Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Mon, 4 May 2020 20:30:26 +0200 Subject: [PATCH 12/22] switch: use 2x hw scaling by default, disable fullscreen --- engine/openbor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/openbor.c b/engine/openbor.c index b34d42af6..0ec32af01 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -2558,6 +2558,8 @@ void clearsettings() savedata.hwfilter = 1; #ifdef ANDROID savedata.hwscale = 0.0; + #elif __SWITCH__ + savedata.hwscale = 2.0f; #else savedata.hwscale = 1.0; #endif @@ -39477,7 +39479,9 @@ void menu_options_video() #if SDL #if !defined(GP2X) && !defined(OPENDINGUX) +#ifndef __SWITCH__ video_fullscreen_flip(); +#endif break; case 4: savedata.usegl = !savedata.usegl; From a9585c2a0dcfed914d9a3b12e7047ffab3cc55f3 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Tue, 5 May 2020 14:45:10 +0200 Subject: [PATCH 13/22] switch: refactor inputs, add single joycons mode option --- engine/openbor.c | 18 +- engine/sdl/control.c | 604 +++++++++++++++++++----------------- engine/sdl/control.h | 19 +- engine/sdl/control_switch.h | 71 +++++ engine/sdl/joysticks.c | 54 ++-- engine/source/savedata.h | 3 + 6 files changed, 437 insertions(+), 332 deletions(-) create mode 100644 engine/sdl/control_switch.h diff --git a/engine/openbor.c b/engine/openbor.c index 0ec32af01..fad274ffc 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -2560,6 +2560,7 @@ void clearsettings() savedata.hwscale = 0.0; #elif __SWITCH__ savedata.hwscale = 2.0f; + savedata.single_joycon_mode = 1; #else savedata.hwscale = 1.0; #endif @@ -38362,7 +38363,11 @@ void keyboard_setup(int player) void menu_options_input() { int quit = 0; + #if __SWITCH__ + int selector = 0; // 0 + #else int selector = 1; // 0 + #endif int x_pos = -6; #if ANDROID int OPTIONS_NUM = 6; @@ -38395,6 +38400,11 @@ void menu_options_input() { _menutext((selector == 0), -4, -2, Tr("Nunchuk Analog Disabled")); } + #elif __SWITCH__ + if(savedata.single_joycon_mode) + _menutext((selector == 0), x_pos, -2, Tr("Single Joycon Mode Enabled")); + else + _menutext((selector == 0), x_pos, -2, Tr("Single Joycon Mode Disabled")); #else if(savedata.usejoy) { @@ -38469,7 +38479,13 @@ void menu_options_input() switch(selector) { case 0: -#ifndef __SWITCH__ +#ifdef __SWITCH__ + savedata.single_joycon_mode ^= 1; + if(savedata.single_joycon_mode) + SDL_SetHint("SDL_HINT_SINGLE_JOYCONS_MODE", "1"); + else + SDL_SetHint("SDL_HINT_SINGLE_JOYCONS_MODE", "0"); +#else control_usejoy((savedata.usejoy ^= 1)); #endif break; diff --git a/engine/sdl/control.c b/engine/sdl/control.c index 9e353bc73..cbd8a0d9e 100644 --- a/engine/sdl/control.c +++ b/engine/sdl/control.c @@ -6,7 +6,7 @@ * Copyright (c) 2004 - 2014 OpenBOR Team */ -// Generic control stuff (keyboard+joystick) +// Generic control stuff (keyboard+joystick) #include "video.h" #include "globals.h" @@ -14,15 +14,19 @@ #include "stristr.h" #include "sblaster.h" #include "joysticks.h" -#include "openbor.h" - +#include "openbor.h" + #define T_AXIS 7000 #ifdef ANDROID #include "jniutils.h" #endif -SDL_Joystick *joystick[JOY_LIST_TOTAL]; // SDL struct for joysticks +#ifdef __SWITCH__ +#include +#endif + +SDL_Joystick *joystick[JOY_LIST_TOTAL]; // SDL struct for joysticks SDL_Haptic *joystick_haptic[JOY_LIST_TOTAL]; // SDL haptic for joysticks static int usejoy; // To be or Not to be used? static int numjoy; // Number of Joy(s) found @@ -30,13 +34,13 @@ static int lastkey; // Last keyboard key Pressed static int lastjoy; // Last joystick button/axis/hat input int sdl_game_started = 0; - -extern int default_keys[MAX_BTN_NUM]; -extern s_playercontrols default_control; + +extern int default_keys[MAX_BTN_NUM]; +extern s_playercontrols default_control; #ifdef ANDROID extern int nativeWidth; -extern int nativeHeight; +extern int nativeHeight; static TouchStatus touch_info; #endif @@ -80,7 +84,7 @@ void getPads(Uint8* keystate, Uint8* keystate_def) { touch_info.pid[i] = ev.tfinger.fingerId; touch_info.px[i] = ev.tfinger.x*nativeWidth; - touch_info.py[i] = ev.tfinger.y*nativeHeight; + touch_info.py[i] = ev.tfinger.y*nativeHeight; touch_info.pstatus[i] = TOUCH_STATUS_DOWN; // migration for White Dragon's vibration logic from SDLActivity.java @@ -101,7 +105,7 @@ void getPads(Uint8* keystate, Uint8* keystate_def) for(i=0; i= 8 && ev.jbutton.button <= 18) joysticks[i].Buttons &= ~(JoystickBits[ev.jbutton.button - 3]); - } - /*else - { - // add key flag from event - #ifdef ANDROID - joysticks[i].Buttons &= 0x00 << ev.jbutton.button; - #endif + } + /*else + { + // add key flag from event + #ifdef ANDROID + joysticks[i].Buttons &= 0x00 << ev.jbutton.button; + #endif }*/ } } @@ -188,11 +192,11 @@ void getPads(Uint8* keystate, Uint8* keystate_def) if (SDL_JoystickInstanceID(joystick[i]) == ev.jbutton.which) { //printf("Button down: controller %i, button %i\n", i, ev.jbutton.button); - lastjoy = 1 + i * JOY_MAX_INPUTS + ev.jbutton.button; - - // add key flag from event - /*#ifdef ANDROID - joysticks[i].Buttons |= 0x01 << ev.jbutton.button; + lastjoy = 1 + i * JOY_MAX_INPUTS + ev.jbutton.button; + + // add key flag from event + /*#ifdef ANDROID + joysticks[i].Buttons |= 0x01 << ev.jbutton.button; #endif*/ } } @@ -209,20 +213,21 @@ void getPads(Uint8* keystate, Uint8* keystate_def) if(ev.jhat.value & SDL_HAT_RIGHT && !(x & SDL_HAT_RIGHT)) lastjoy = hatfirst + 1; if(ev.jhat.value & SDL_HAT_DOWN && !(x & SDL_HAT_DOWN)) lastjoy = hatfirst + 2; if(ev.jhat.value & SDL_HAT_LEFT && !(x & SDL_HAT_LEFT)) lastjoy = hatfirst + 3; - //if(lastjoy) fprintf(stderr, "SDL_JOYHATMOTION - Joystick %i Hat %i (Index %i)\n", i, ev.jhat.hat, lastjoy); - - // add key flag from event (0x01 0x02 0x04 0x08) - #ifdef ANDROID - if(ev.jhat.value & SDL_HAT_UP) joysticks[i].Hats |= SDL_HAT_UP << (ev.jhat.hat*4); - if(ev.jhat.value & SDL_HAT_RIGHT) joysticks[i].Hats |= SDL_HAT_RIGHT << (ev.jhat.hat*4); - if(ev.jhat.value & SDL_HAT_DOWN) joysticks[i].Hats |= SDL_HAT_DOWN << (ev.jhat.hat*4); - if(ev.jhat.value & SDL_HAT_LEFT) joysticks[i].Hats |= SDL_HAT_LEFT << (ev.jhat.hat*4); + //if(lastjoy) fprintf(stderr, "SDL_JOYHATMOTION - Joystick %i Hat %i (Index %i)\n", i, ev.jhat.hat, lastjoy); + + // add key flag from event (0x01 0x02 0x04 0x08) + #ifdef ANDROID + if(ev.jhat.value & SDL_HAT_UP) joysticks[i].Hats |= SDL_HAT_UP << (ev.jhat.hat*4); + if(ev.jhat.value & SDL_HAT_RIGHT) joysticks[i].Hats |= SDL_HAT_RIGHT << (ev.jhat.hat*4); + if(ev.jhat.value & SDL_HAT_DOWN) joysticks[i].Hats |= SDL_HAT_DOWN << (ev.jhat.hat*4); + if(ev.jhat.value & SDL_HAT_LEFT) joysticks[i].Hats |= SDL_HAT_LEFT << (ev.jhat.hat*4); #endif } } break; case SDL_JOYAXISMOTION: +#ifndef __SWITCH__ for(i=0; i> (2*ev.jaxis.axis)) & 0x03; // previous state of axis if(ev.jaxis.value < -1*T_AXIS && !(x & 0x01)) lastjoy = axisfirst; if(ev.jaxis.value > T_AXIS && !(x & 0x02)) lastjoy = axisfirst + 1; - //if(lastjoy) fprintf(stderr, "SDL_JOYAXISMOTION - Joystick %i Axis %i = Position %i (Index %i)\n", i, ev.jaxis.axis, ev.jaxis.value, lastjoy); - - // add key flag from event - #ifdef ANDROID + //if(lastjoy) fprintf(stderr, "SDL_JOYAXISMOTION - Joystick %i Axis %i = Position %i (Index %i)\n", i, ev.jaxis.axis, ev.jaxis.value, lastjoy); + + // add key flag from event + #ifdef ANDROID if(ev.jaxis.value < -1*T_AXIS) { joysticks[i].Axes |= 0x01 << (ev.jaxis.axis*2); } - if(ev.jaxis.value > T_AXIS) { joysticks[i].Axes |= 0x02 << (ev.jaxis.axis*2); } + if(ev.jaxis.value > T_AXIS) { joysticks[i].Axes |= 0x02 << (ev.jaxis.axis*2); } #endif } } - break; - - // PLUG AND PLAY - case SDL_JOYDEVICEADDED: - if (ev.jdevice.which < JOY_LIST_TOTAL) - { - int i = ev.jdevice.which; - char buffer[MAX_BUFFER_LEN]; - char joy_name[MAX_BUFFER_LEN]; - open_joystick(i); - //get_time_string(buffer, MAX_BUFFER_LEN, (time_t)ev.jdevice.timestamp, TIMESTAMP_PATTERN); - get_now_string(buffer, MAX_BUFFER_LEN, TIMESTAMP_PATTERN); - numjoy = SDL_NumJoysticks(); - strcpy(joy_name,get_joystick_name(joysticks[i].Name)); - printf("Joystick: \"%s\" connected at port: %d at %s\n",joy_name,i,buffer); - } - break; - - case SDL_JOYDEVICEREMOVED: - if (ev.jdevice.which < JOY_LIST_TOTAL) - { - int i = ev.jdevice.which; - if(joystick[i]) - { - char buffer[MAX_BUFFER_LEN]; - char joy_name[MAX_BUFFER_LEN]; - get_now_string(buffer, MAX_BUFFER_LEN, TIMESTAMP_PATTERN); - close_joystick(i); - numjoy = SDL_NumJoysticks(); - strcpy(joy_name,get_joystick_name(joysticks[i].Name)); - printf("Joystick: \"%s\" disconnected from port: %d at %s\n",joy_name,i,buffer); - } - } - break; - - default: +#endif + break; + + // PLUG AND PLAY + case SDL_JOYDEVICEADDED: + if (ev.jdevice.which < JOY_LIST_TOTAL) + { + int i = ev.jdevice.which; + char buffer[MAX_BUFFER_LEN]; + char joy_name[MAX_BUFFER_LEN]; + open_joystick(i); + //get_time_string(buffer, MAX_BUFFER_LEN, (time_t)ev.jdevice.timestamp, TIMESTAMP_PATTERN); + get_now_string(buffer, MAX_BUFFER_LEN, TIMESTAMP_PATTERN); + numjoy = SDL_NumJoysticks(); + strcpy(joy_name,get_joystick_name(joysticks[i].Name)); + printf("Joystick: \"%s\" connected at port: %d at %s\n",joy_name,i,buffer); + } + break; + + case SDL_JOYDEVICEREMOVED: + if (ev.jdevice.which < JOY_LIST_TOTAL) + { + int i = ev.jdevice.which; + if(joystick[i]) + { + char buffer[MAX_BUFFER_LEN]; + char joy_name[MAX_BUFFER_LEN]; + get_now_string(buffer, MAX_BUFFER_LEN, TIMESTAMP_PATTERN); + close_joystick(i); + numjoy = SDL_NumJoysticks(); + strcpy(joy_name,get_joystick_name(joysticks[i].Name)); + printf("Joystick: \"%s\" disconnected from port: %d at %s\n",joy_name,i,buffer); + } + } + break; + + default: break; } @@ -288,15 +294,27 @@ void getPads(Uint8* keystate, Uint8* keystate_def) for(i = 0; i < JOY_LIST_TOTAL; i++) { // reset state - joysticks[i].Axes = joysticks[i].Hats = joysticks[i].Buttons = 0; + joysticks[i].Axes = joysticks[i].Hats = joysticks[i].Buttons = 0; if (joystick[i] == NULL) continue; // check buttons - for(j = 0; j < joysticks[i].NumButtons; j++) - { - joysticks[i].Buttons |= SDL_JoystickGetButton(joystick[i], j) << j; + for(j = 0; j < joysticks[i].NumButtons; j++) + { +#ifdef __SWITCH__ + // we want "plus" or "minus" button to send start in single joycon mode + if(j == 10 || j == 11) + { + joysticks[i].Buttons |= SDL_JoystickGetButton(joystick[i], j) << 10; + continue; + } + // skip "plus and minus" combo key (?!) + else if(j == 34) + continue; +#endif + joysticks[i].Buttons |= SDL_JoystickGetButton(joystick[i], j) << j; } +#ifndef __SWITCH__ // check axes for(j = 0; j < joysticks[i].NumAxes; j++) { @@ -304,17 +322,18 @@ void getPads(Uint8* keystate, Uint8* keystate_def) if(axis < -1*T_AXIS) { joysticks[i].Axes |= 0x01 << (j*2); } if(axis > T_AXIS) { joysticks[i].Axes |= 0x02 << (j*2); } } +#endif // check hats - for(j = 0; j < joysticks[i].NumHats; j++) - { - //joysticks[i].Hats |= SDL_JoystickGetHat(joystick[i], j) << (j*4); - - Uint8 hat_value = SDL_JoystickGetHat(joystick[i], j); - if(hat_value & SDL_HAT_UP) joysticks[i].Hats |= SDL_HAT_UP << (j*4); - if(hat_value & SDL_HAT_RIGHT) joysticks[i].Hats |= SDL_HAT_RIGHT << (j*4); - if(hat_value & SDL_HAT_DOWN) joysticks[i].Hats |= SDL_HAT_DOWN << (j*4); - if(hat_value & SDL_HAT_LEFT) joysticks[i].Hats |= SDL_HAT_LEFT << (j*4); + for(j = 0; j < joysticks[i].NumHats; j++) + { + //joysticks[i].Hats |= SDL_JoystickGetHat(joystick[i], j) << (j*4); + + Uint8 hat_value = SDL_JoystickGetHat(joystick[i], j); + if(hat_value & SDL_HAT_UP) joysticks[i].Hats |= SDL_HAT_UP << (j*4); + if(hat_value & SDL_HAT_RIGHT) joysticks[i].Hats |= SDL_HAT_RIGHT << (j*4); + if(hat_value & SDL_HAT_DOWN) joysticks[i].Hats |= SDL_HAT_DOWN << (j*4); + if(hat_value & SDL_HAT_LEFT) joysticks[i].Hats |= SDL_HAT_LEFT << (j*4); } // combine axis, hat, and button state into a single value @@ -336,19 +355,19 @@ static int flag_to_index(u64 flag) while(!((bit< JOY_LIST_TOTAL) numjoy = JOY_LIST_TOTAL; // avoid overflow bug + } + } + + if (numjoy > JOY_LIST_TOTAL) numjoy = JOY_LIST_TOTAL; // avoid overflow bug for(i = 0; i < numjoy; i++) { - open_joystick(i); - + open_joystick(i); + if(scan != 2) - { + { // print JOY_MAX_INPUTS (32) spaces for alignment - if(numjoy == 1) - { + if(numjoy == 1) + { printf("%s - %d axes, %d buttons, %d hat(s)\n", - get_joystick_name(joysticks[i].Name), joysticks[i].NumAxes, joysticks[i].NumButtons, joysticks[i].NumHats); + get_joystick_name(joysticks[i].Name), joysticks[i].NumAxes, joysticks[i].NumButtons, joysticks[i].NumHats); } else if(numjoy > 1) { @@ -399,56 +418,56 @@ void joystick_scan(int scan) } } } - -/* -Open a single joystick + +/* +Open a single joystick */ void open_joystick(int i) -{ - int j; +{ + int j; - if ( ( joystick[i] = SDL_JoystickOpen(i) ) == NULL ) - { - printf("\nWarning: Unable to initialize joystick in port: %d! SDL Error: %s\n", i, SDL_GetError()); - return; + if ( ( joystick[i] = SDL_JoystickOpen(i) ) == NULL ) + { + printf("\nWarning: Unable to initialize joystick in port: %d! SDL Error: %s\n", i, SDL_GetError()); + return; } joysticks[i].NumHats = SDL_JoystickNumHats(joystick[i]); joysticks[i].NumAxes = SDL_JoystickNumAxes(joystick[i]); joysticks[i].NumButtons = SDL_JoystickNumButtons(joystick[i]); - + strcpy(joysticks[i].Name, SDL_JoystickName(i)); - - joystick_haptic[i] = SDL_HapticOpenFromJoystick(joystick[i]); - if (joystick_haptic[i] != NULL) - { - //Get initialize rumble - if( SDL_HapticRumbleInit( joystick_haptic[i] ) < 0 ) - { - printf("\nWarning: Unable to initialize rumble for joystick: %s in port: %d! SDL Error: %s\n", joysticks[i].Name, i, SDL_GetError()); - } - } + + joystick_haptic[i] = SDL_HapticOpenFromJoystick(joystick[i]); + if (joystick_haptic[i] != NULL) + { + //Get initialize rumble + if( SDL_HapticRumbleInit( joystick_haptic[i] ) < 0 ) + { + printf("\nWarning: Unable to initialize rumble for joystick: %s in port: %d! SDL Error: %s\n", joysticks[i].Name, i, SDL_GetError()); + } + } #if GP2X joysticks[i].Type = JOY_TYPE_GAMEPARK; for(j = 0; j < JOY_MAX_INPUTS + 1; j++) { - if(j) joysticks[i].KeyName[j] = GameparkKeyName[j + i * JOY_MAX_INPUTS]; + if(j) joysticks[i].KeyName[j] = GameparkKeyName[j + i * JOY_MAX_INPUTS]; else joysticks[i].KeyName[j] = GameparkKeyName[j]; } #else //SDL_JoystickEventState(SDL_IGNORE); // disable joystick events for(j = 1; j < JOY_MAX_INPUTS + 1; j++) - { + { strcpy(joysticks[i].KeyName[j], PC_GetJoystickKeyName(i, j)); } - #endif - + #endif + return; -} - -void reset_joystick_map(int i) -{ - memset(joysticks[i].Name,0,sizeof(joysticks[i].Name)); +} + +void reset_joystick_map(int i) +{ + memset(joysticks[i].Name,0,sizeof(joysticks[i].Name)); memset(joysticks[i].KeyName,0,sizeof(joysticks[i].KeyName)); joysticks[i].Type = 0; joysticks[i].NumHats = 0; @@ -457,8 +476,8 @@ void reset_joystick_map(int i) joysticks[i].Hats = 0; joysticks[i].Axes = 0; joysticks[i].Buttons = 0; - joysticks[i].Data = 0; - set_default_joystick_keynames(i); + joysticks[i].Data = 0; + set_default_joystick_keynames(i); } /* @@ -468,24 +487,24 @@ destroy all SDL Joystick data. void control_exit() { int i; - for(i = 0; i < numjoy; i++) + for(i = 0; i < numjoy; i++) { close_joystick(i); - } + } usejoy = 0; } - -/* -Reset single joystick + +/* +Reset single joystick */ void close_joystick(int i) { - if(joystick[i] != NULL) SDL_JoystickClose(joystick[i]); - if(joystick_haptic[i] != NULL) SDL_HapticClose(joystick_haptic[i]); - joystick[i] = NULL; - joystick_haptic[i] = NULL; + if(joystick[i] != NULL) SDL_JoystickClose(joystick[i]); + if(joystick_haptic[i] != NULL) SDL_HapticClose(joystick_haptic[i]); + joystick[i] = NULL; + joystick_haptic[i] = NULL; reset_joystick_map(i); -} +} /* Create default values for joysticks if enabled. @@ -493,41 +512,48 @@ Then scan for joysticks and update their data. */ void control_init(int joy_enable) { - int i; + int i; #ifdef GP2X usejoy = joy_enable ? joy_enable : 1; #else usejoy = joy_enable; -#endif +#endif + +#ifdef __SWITCH__ + if(savedata.single_joycon_mode) + SDL_SetHint("SDL_HINT_SINGLE_JOYCONS_MODE", "1"); + else + SDL_SetHint("SDL_HINT_SINGLE_JOYCONS_MODE", "0"); +#endif //memset(joysticks, 0, sizeof(s_joysticks) * JOY_LIST_TOTAL); for(i = 0; i < JOY_LIST_TOTAL; i++) - { - joystick[i] = NULL; - joystick_haptic[i] = NULL; + { + joystick[i] = NULL; + joystick_haptic[i] = NULL; reset_joystick_map(i); } - joystick_scan(usejoy); + joystick_scan(usejoy); #ifdef ANDROID - for(i = 0; i < MAX_POINTERS; i++) - { - touch_info.pstatus[i] = TOUCH_STATUS_UP; + for(i = 0; i < MAX_POINTERS; i++) + { + touch_info.pstatus[i] = TOUCH_STATUS_UP; } #endif -} - -void set_default_joystick_keynames(int i) -{ - int j; +} + +void set_default_joystick_keynames(int i) +{ + int j; for(j = 0; j < JOY_MAX_INPUTS + 1; j++) - { - if(j) strcpy(joysticks[i].KeyName[j], JoystickKeyName[j + i * JOY_MAX_INPUTS]); + { + if(j) strcpy(joysticks[i].KeyName[j], JoystickKeyName[j + i * JOY_MAX_INPUTS]); else strcpy(joysticks[i].KeyName[j], JoystickKeyName[j]); - } + } } - + char *control_getkeyname(unsigned int keycode) { int i; @@ -535,7 +561,7 @@ char *control_getkeyname(unsigned int keycode) { if((keycode >= (JOY_LIST_FIRST + 1 + (i * JOY_MAX_INPUTS))) && (keycode <= JOY_LIST_FIRST + JOY_MAX_INPUTS + (i * JOY_MAX_INPUTS))) return (char*)joysticks[i].KeyName[keycode - (JOY_LIST_FIRST + (i * JOY_MAX_INPUTS))]; - } + } if(keycode > SDLK_FIRST && keycode < SDLK_LAST) return JOY_GetKeyName(keycode); @@ -551,12 +577,12 @@ int control_usejoy(int enable) { usejoy = enable; return 0; -} - -#if ANDROID -/* -Get if touchscreen vibration is active -*/ +} + +#if ANDROID +/* +Get if touchscreen vibration is active +*/ int is_touchpad_vibration_enabled() { return savedata.is_touchpad_vibration_enabled; @@ -595,9 +621,9 @@ void control_update_android_touch(TouchStatus *touch_info, int maxp, Uint8* keys int i, j; float tx, ty, tr; float r[MAXTOUCHB]; - float dirx, diry, circlea, circleb, tan; + float dirx, diry, circlea, circleb, tan; - memset(touchstates, 0, sizeof(touchstates)); + memset(touchstates, 0, sizeof(touchstates)); for(j=0; j=-tana && tan<=tana) + if(tan>=-tana && tan<=tana) { touchstates[SDID_MOVELEFT] = 1; - } - else if(tan<-tanb) + } + else if(tan<-tanb) { touchstates[SDID_MOVEDOWN] = 1; - } - else if(tan>tanb) + } + else if(tan>tanb) { touchstates[SDID_MOVEUP] = 1; - } - else if(ty<0) + } + else if(ty<0) { touchstates[SDID_MOVEUP] = touchstates[SDID_MOVELEFT] = 1; - } - else + } + else { - touchstates[SDID_MOVELEFT] = touchstates[SDID_MOVEDOWN] = 1; + touchstates[SDID_MOVELEFT] = touchstates[SDID_MOVEDOWN] = 1; } } else if(tx>0) { tan = ty/tx; - if(tan>=-tana && tan<=tana) + if(tan>=-tana && tan<=tana) { touchstates[SDID_MOVERIGHT] = 1; - } - else if(tan<-tanb) + } + else if(tan<-tanb) { touchstates[SDID_MOVEUP] = 1; - } - else if(tan>tanb) + } + else if(tan>tanb) { touchstates[SDID_MOVEDOWN] = 1; - } - else if(ty<0) + } + else if(ty<0) { touchstates[SDID_MOVEUP] = touchstates[SDID_MOVERIGHT] = 1; - } - else + } + else { - touchstates[SDID_MOVERIGHT] = touchstates[SDID_MOVEDOWN] = 1; + touchstates[SDID_MOVERIGHT] = touchstates[SDID_MOVEDOWN] = 1; } } else { - if(ty>0) - { + if(ty>0) + { touchstates[SDID_MOVEDOWN] = 1; - } - else - { - touchstates[SDID_MOVEUP] = 1; + } + else + { + touchstates[SDID_MOVEUP] = 1; } } } @@ -689,35 +715,35 @@ void control_update_android_touch(TouchStatus *touch_info, int maxp, Uint8* keys tx = touch_info->px[i]-bx[j]; ty = touch_info->py[i]-by[j]; tr = tx*tx + ty*ty; - if(tr<=r[j]) - { - touchstates[j] = 1; + if(tr<=r[j]) + { + touchstates[j] = 1; } } - } - #undef tana - #undef tanb + } + #undef tana + #undef tanb - hide_t = timer_gettick() + 5000; + hide_t = timer_gettick() + 5000; //map to current user settings extern s_savedata savedata; #define pc(x) savedata.keys[0][x] - keystate[pc(SDID_MOVEUP)] = touchstates[SDID_MOVEUP]; - keystate[pc(SDID_MOVEDOWN)] = touchstates[SDID_MOVEDOWN]; + keystate[pc(SDID_MOVEUP)] = touchstates[SDID_MOVEUP]; + keystate[pc(SDID_MOVEDOWN)] = touchstates[SDID_MOVEDOWN]; keystate[pc(SDID_MOVELEFT)] = touchstates[SDID_MOVELEFT]; keystate[pc(SDID_MOVERIGHT)] = touchstates[SDID_MOVERIGHT]; keystate[pc(SDID_ATTACK)] = touchstates[SDID_ATTACK]; - keystate[pc(SDID_ATTACK2)] = touchstates[SDID_ATTACK2]; + keystate[pc(SDID_ATTACK2)] = touchstates[SDID_ATTACK2]; keystate[pc(SDID_ATTACK3)] = touchstates[SDID_ATTACK3]; - keystate[pc(SDID_ATTACK4)] = touchstates[SDID_ATTACK4]; + keystate[pc(SDID_ATTACK4)] = touchstates[SDID_ATTACK4]; keystate[pc(SDID_JUMP)] = touchstates[SDID_JUMP]; keystate[pc(SDID_SPECIAL)] = touchstates[SDID_SPECIAL]; keystate[pc(SDID_START)] = touchstates[SDID_START]; - keystate[pc(SDID_SCREENSHOT)] = touchstates[SDID_SCREENSHOT]; - #undef pc - - //use default value for touch key mapping + keystate[pc(SDID_SCREENSHOT)] = touchstates[SDID_SCREENSHOT]; + #undef pc + + //use default value for touch key mapping keystate_def[default_keys[SDID_MOVEUP]] = touchstates[SDID_MOVEUP]; keystate_def[default_keys[SDID_MOVEDOWN]] = touchstates[SDID_MOVEDOWN]; keystate_def[default_keys[SDID_MOVELEFT]] = touchstates[SDID_MOVELEFT]; @@ -729,19 +755,19 @@ void control_update_android_touch(TouchStatus *touch_info, int maxp, Uint8* keys keystate_def[default_keys[SDID_JUMP]] = touchstates[SDID_JUMP]; keystate_def[default_keys[SDID_SPECIAL]] = touchstates[SDID_SPECIAL]; keystate_def[default_keys[SDID_START]] = touchstates[SDID_START]; - keystate_def[default_keys[SDID_SCREENSHOT]] = touchstates[SDID_SCREENSHOT]; - - keystate[CONTROL_ESC] = keystate_def[CONTROL_ESC] = touchstates[SDID_ESC]; - + keystate_def[default_keys[SDID_SCREENSHOT]] = touchstates[SDID_SCREENSHOT]; + + keystate[CONTROL_ESC] = keystate_def[CONTROL_ESC] = touchstates[SDID_ESC]; + return; -} - +} + int is_touch_area(float x, float y) { int j; float tx, ty, tr; float r[MAXTOUCHB]; - float dirx, diry, circlea, circleb, tan; + float dirx, diry, circlea, circleb, tan; for(j=0; j=-tana && tan<=tana) + if(tan>=-tana && tan<=tana) { return 1; - } - else if(tan<-tanb) + } + else if(tan<-tanb) { return 1; - } - else if(tan>tanb) + } + else if(tan>tanb) { return 1; - } - else if(ty<0) + } + else if(ty<0) { return 1; - } - else + } + else { - return 1; + return 1; } } else if(tx>0) { tan = ty/tx; - if(tan>=-tana && tan<=tana) + if(tan>=-tana && tan<=tana) { return 1; - } - else if(tan<-tanb) + } + else if(tan<-tanb) { return 1; - } - else if(tan>tanb) + } + else if(tan>tanb) { return 1; - } - else if(ty<0) + } + else if(ty<0) { return 1; - } - else + } + else { - return 1; + return 1; } } else { - if(ty>0) - { + if(ty>0) + { + return 1; + } + else + { return 1; - } - else - { - return 1; } } } @@ -830,15 +856,15 @@ int is_touch_area(float x, float y) tx = x-bx[j]; ty = y-by[j]; tr = tx*tx + ty*ty; - if(tr<=r[j]) - { - return 1; + if(tr<=r[j]) + { + return 1; } - } - #undef tana - #undef tanb - - return 0; + } + #undef tana + #undef tanb + + return 0; } #endif @@ -881,7 +907,7 @@ int control_scankey() } ready = (!k || !j); return 0; -} +} void control_update(s_playercontrols ** playercontrols, int numplayers) { @@ -890,10 +916,10 @@ void control_update(s_playercontrols ** playercontrols, int numplayers) int player; int t; s_playercontrols * pcontrols; - Uint8* keystate = (Uint8*)SDL_GetKeyState(NULL); // Here retrieve keyboard state - Uint8* keystate_def = (Uint8*)SDL_GetKeyState(NULL); // Here retrieve keyboard state for default + Uint8* keystate = (Uint8*)SDL_GetKeyState(NULL); // Here retrieve keyboard state + Uint8* keystate_def = (Uint8*)SDL_GetKeyState(NULL); // Here retrieve keyboard state for default - getPads(keystate,keystate_def); + getPads(keystate,keystate_def); for(player = 0; player < numplayers; player++){ @@ -904,22 +930,22 @@ void control_update(s_playercontrols ** playercontrols, int numplayers) for(i = 0; i < JOY_MAX_INPUTS; i++) { t = pcontrols->settings[i]; - if(t >= SDLK_FIRST && t < SDLK_LAST){ + if(t >= SDLK_FIRST && t < SDLK_LAST){ if(keystate[t]) k |= (1<= SDLK_FIRST && t < SDLK_LAST){ + if(t >= SDLK_FIRST && t < SDLK_LAST){ if(keystate_def[t]) k |= (1<kb_break = 0; pcontrols->newkeyflags = k & (~pcontrols->keyflags); - pcontrols->keyflags = k; - + pcontrols->keyflags = k; + //if (player <= 0) debug_printf("hats: %d, axes: %d, data: %d",joysticks[0].Hats,joysticks[0].Axes,joysticks[0].Data); } } void control_rumble(int port, int ratio, int msec) -{ - #if SDL - if (joystick[port] != NULL && joystick_haptic[port] != NULL) { - if(SDL_HapticRumblePlay(joystick_haptic[port], ratio, msec) != 0) - { - //printf( "Warning: Unable to play rumble! %s\n", SDL_GetError() ); - } - } +{ + #if SDL + if (joystick[port] != NULL && joystick_haptic[port] != NULL) { + if(SDL_HapticRumblePlay(joystick_haptic[port], ratio, msec) != 0) + { + //printf( "Warning: Unable to play rumble! %s\n", SDL_GetError() ); + } + } #endif } diff --git a/engine/sdl/control.h b/engine/sdl/control.h index 6b7d977a4..dc061866e 100644 --- a/engine/sdl/control.h +++ b/engine/sdl/control.h @@ -17,6 +17,9 @@ #endif #include "joysticks.h" +#ifdef __SWITCH__ +#include "control_switch.h" +#else #ifdef OPENDINGUX #define CONTROL_ESC OPENDINGUX_BUTTON_SELECT #define CONTROL_DEFAULT1_START OPENDINGUX_BUTTON_START @@ -47,21 +50,6 @@ #define CONTROL_DEFAULT1_START (JOY_LIST_FIRST + 11) #define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 12) #define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 15) -#elif __SWITCH__ - #define CONTROL_ESC (JOY_LIST_FIRST + 11) + 1 // MINUS - #define CONTROL_DEFAULT1_START (JOY_LIST_FIRST + 10) + 1 // PLUS - #define CONTROL_DEFAULT1_UP (JOY_LIST_FIRST + 13) + 1 // DUP - #define CONTROL_DEFAULT1_DOWN (JOY_LIST_FIRST + 15) + 1 // DDOWN - #define CONTROL_DEFAULT1_LEFT (JOY_LIST_FIRST + 12) + 1 // DLEFT - #define CONTROL_DEFAULT1_RIGHT (JOY_LIST_FIRST + 14) + 1 // DRIGHT - #define CONTROL_DEFAULT1_FIRE1 (JOY_LIST_FIRST + 0) + 1 // A - #define CONTROL_DEFAULT1_FIRE2 (JOY_LIST_FIRST + 1) + 1 // B - #define CONTROL_DEFAULT1_FIRE3 (JOY_LIST_FIRST + 8) + 1 // X - #define CONTROL_DEFAULT1_FIRE4 (JOY_LIST_FIRST + 9) + 1 // Y - #define CONTROL_DEFAULT1_FIRE5 (JOY_LIST_FIRST + 2) + 1 // ZL - #define CONTROL_DEFAULT1_FIRE6 (JOY_LIST_FIRST + 3) + 1 // ZR - #define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 5) + 1 // RSTICK - #define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 11) + 1 // MINUS #else #ifdef SDL2 #define CONTROL_ESC SDL_SCANCODE_ESCAPE @@ -137,6 +125,7 @@ #define CONTROL_DEFAULT4_START ((JOY_LIST_FIRST + 11) + (JOY_MAX_INPUTS * 3)) #define CONTROL_DEFAULT4_SCREENSHOT ((JOY_LIST_FIRST + 12) + (JOY_MAX_INPUTS * 3)) #define CONTROL_DEFAULT4_ESC ((JOY_LIST_FIRST + 15) + (JOY_MAX_INPUTS * 3)) +#endif // __SWITCH__ #define JOYBUTTON(index, btn) (1 + i * JOY_MAX_INPUTS + btn) #define JOYAXIS(index, axis, dir) (JOYBUTTON(index, joysticks[index].NumButtons) + 2 * axis + dir) diff --git a/engine/sdl/control_switch.h b/engine/sdl/control_switch.h new file mode 100644 index 000000000..ba0d3b962 --- /dev/null +++ b/engine/sdl/control_switch.h @@ -0,0 +1,71 @@ +/* + * OpenBOR - http://www.chronocrash.com + * ----------------------------------------------------------------------- + * All rights reserved, see LICENSE in OpenBOR root for details. + * + * Copyright (c) 2004 - 2014 OpenBOR Team + */ + +#ifndef CONTROL_SWITCH_H +#define CONTROL_SWITCH_H + +#include "joysticks.h" + +#define CONTROL_ESC (JOY_LIST_FIRST + 4) + 1 // LSTICK +#define CONTROL_DEFAULT1_UP (JOY_LIST_FIRST + 28) + 1 // UP (DIGITAL OR ANALOG) +#define CONTROL_DEFAULT1_RIGHT (JOY_LIST_FIRST + 31) + 1 // RIGHT (DIGITAL OR ANALOG) +#define CONTROL_DEFAULT1_DOWN (JOY_LIST_FIRST + 29) + 1 // DOWN (DIGITAL OR ANALOG) +#define CONTROL_DEFAULT1_LEFT (JOY_LIST_FIRST + 30) + 1 // LEFT (DIGITAL OR ANALOG) +#define CONTROL_DEFAULT1_FIRE1 (JOY_LIST_FIRST + 0) + 1 // A +#define CONTROL_DEFAULT1_FIRE2 (JOY_LIST_FIRST + 1) + 1 // B +#define CONTROL_DEFAULT1_FIRE3 (JOY_LIST_FIRST + 6) + 1 // L +#define CONTROL_DEFAULT1_FIRE4 (JOY_LIST_FIRST + 7) + 1 // R +#define CONTROL_DEFAULT1_FIRE5 (JOY_LIST_FIRST + 2) + 1 // X +#define CONTROL_DEFAULT1_FIRE6 (JOY_LIST_FIRST + 3) + 1 // Y +#define CONTROL_DEFAULT1_START (JOY_LIST_FIRST + 10) + 1 // PLUS (OR MINUS) +#define CONTROL_DEFAULT1_SCREENSHOT (JOY_LIST_FIRST + 5) + 1 // RSTICK +#define CONTROL_DEFAULT1_ESC (JOY_LIST_FIRST + 4) + 1 // MINUS + +#define CONTROL_DEFAULT2_UP (CONTROL_DEFAULT1_UP + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_RIGHT (CONTROL_DEFAULT1_RIGHT + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_DOWN (CONTROL_DEFAULT1_DOWN + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_LEFT (CONTROL_DEFAULT1_LEFT + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE1 (CONTROL_DEFAULT1_FIRE1 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE2 (CONTROL_DEFAULT1_FIRE2 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE3 (CONTROL_DEFAULT1_FIRE3 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE4 (CONTROL_DEFAULT1_FIRE4 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE5 (CONTROL_DEFAULT1_FIRE5 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_FIRE6 (CONTROL_DEFAULT1_FIRE6 + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_START (CONTROL_DEFAULT1_START + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_SCREENSHOT (CONTROL_DEFAULT1_SCREENSHOT + JOY_MAX_INPUTS) +#define CONTROL_DEFAULT2_ESC (CONTROL_DEFAULT1_ESC + JOY_MAX_INPUTS) + +#define CONTROL_DEFAULT3_UP (CONTROL_DEFAULT1_UP + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_RIGHT (CONTROL_DEFAULT1_RIGHT + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_DOWN (CONTROL_DEFAULT1_DOWN + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_LEFT (CONTROL_DEFAULT1_LEFT + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE1 (CONTROL_DEFAULT1_FIRE1 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE2 (CONTROL_DEFAULT1_FIRE2 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE3 (CONTROL_DEFAULT1_FIRE3 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE4 (CONTROL_DEFAULT1_FIRE4 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE5 (CONTROL_DEFAULT1_FIRE5 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_FIRE6 (CONTROL_DEFAULT1_FIRE6 + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_START (CONTROL_DEFAULT1_START + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_SCREENSHOT (CONTROL_DEFAULT1_SCREENSHOT + (JOY_MAX_INPUTS * 2)) +#define CONTROL_DEFAULT3_ESC (CONTROL_DEFAULT1_ESC + (JOY_MAX_INPUTS * 2)) + +#define CONTROL_DEFAULT4_UP (CONTROL_DEFAULT1_UP + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_RIGHT (CONTROL_DEFAULT1_RIGHT + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_DOWN (CONTROL_DEFAULT1_DOWN + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_LEFT (CONTROL_DEFAULT1_LEFT + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE1 (CONTROL_DEFAULT1_FIRE1 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE2 (CONTROL_DEFAULT1_FIRE2 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE3 (CONTROL_DEFAULT1_FIRE3 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE4 (CONTROL_DEFAULT1_FIRE4 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE5 (CONTROL_DEFAULT1_FIRE5 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_FIRE6 (CONTROL_DEFAULT1_FIRE6 + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_START (CONTROL_DEFAULT1_START + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_SCREENSHOT (CONTROL_DEFAULT1_SCREENSHOT + (JOY_MAX_INPUTS * 3)) +#define CONTROL_DEFAULT4_ESC (CONTROL_DEFAULT1_ESC + (JOY_MAX_INPUTS * 3)) + +#endif // CONTROL_SWITCH_H \ No newline at end of file diff --git a/engine/sdl/joysticks.c b/engine/sdl/joysticks.c index ef547ac59..ea49c30d4 100644 --- a/engine/sdl/joysticks.c +++ b/engine/sdl/joysticks.c @@ -232,37 +232,37 @@ const char *JoystickButtonNames[JOY_NAME_SIZE] = { "B", \ "X", \ "Y", \ - "LS", \ - "RS", \ + "LSTICK", \ + "RSTICK", \ "L", \ "R", \ "ZL", \ "ZR", \ - "+", \ - "-", \ - "LEFT", \ - "UP", \ - "RIGHT", \ - "DOWN", \ - "SL_LEFT", \ - "SL_UP", \ - "SL_RIGHT", \ - "SL_DOWN", \ - "SR_LEFT", \ - "SR_UP", \ - "SR_RIGHT", \ - "SR_DOWN", \ - "Button 25", \ - "Button 26", \ - "Button 27", \ - "Button 28", \ - "Button 29", \ - "Button 30", \ - "Button 31", \ - "Button 32", \ - "Button 33", \ - "Button 34", \ - "Button 35", \ + "PLUS", \ + "MINUS", \ + "DLEFT", \ + "DUP", \ + "DRIGHT", \ + "DDOWN", \ + "LSTICK_LEFT", \ + "LSTICK_UP", \ + "LSTICK_RIGHT", \ + "LSTICK_DOWN", \ + "RSTICK_LEFT", \ + "RSTICK_UP", \ + "RSTICK_RIGHT", \ + "RSTICK_DOWN", \ + "SL_LEFT", \ + "SR_LEFT", \ + "SL_RIGHT", \ + "SR_RIGHT", \ + "UP", \ + "DOWN", \ + "LEFT", \ + "RIGHT", \ + "SL", \ + "SR", \ + "PLUS_OR_MINUS", \ "Button 36", \ "Button 37", \ "Button 38", \ diff --git a/engine/source/savedata.h b/engine/source/savedata.h index 9700f3202..6890ec917 100644 --- a/engine/source/savedata.h +++ b/engine/source/savedata.h @@ -49,6 +49,9 @@ typedef struct #if ANDROID int is_touchpad_vibration_enabled; #endif +#if __SWITCH__ + int single_joycon_mode; +#endif } s_savedata; extern s_savedata savedata; From 7913b9bd91ba1efd60eef2d52d0a108d3675ae67 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Wed, 6 May 2020 08:51:22 +0200 Subject: [PATCH 14/22] switch: update cmakelist --- CMakeLists.switch | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.switch b/CMakeLists.switch index 60a03e7ca..2fdb15676 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -115,7 +115,10 @@ if (PLATFORM_SWITCH) ##################### # SWITCH PLATORM ##################### - list(APPEND BOR_CFLAGS -D__SWITCH__ -DNXLINK) + if (CMAKE_BUILD_TYPE STREQUAL "Debug") + list(APPEND BOR_CFLAGS -DNXLINK) + endif () + list(APPEND BOR_CFLAGS -D__SWITCH__) list(APPEND BOR_LDFLAGS -L${DEVKITPRO}/libnx/lib -L${DEVKITPRO}/portlibs/switch/lib From 865852bc187dd3a7e7528a998347a37c7e036fdd Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Wed, 6 May 2020 08:59:07 +0200 Subject: [PATCH 15/22] switch: update cmakelist --- CMakeLists.switch | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CMakeLists.switch b/CMakeLists.switch index 2fdb15676..01f2ff7b9 100644 --- a/CMakeLists.switch +++ b/CMakeLists.switch @@ -31,6 +31,8 @@ endif () project(OpenBOR) +set(OPENBOR_VERSION "3.0.7087") + ############## # COMMON ############## @@ -145,6 +147,13 @@ target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${BOR_LDFLAGS}) if (PLATFORM_SWITCH) add_custom_target(${CMAKE_PROJECT_NAME}.nro DEPENDS ${CMAKE_PROJECT_NAME}.elf - COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste" "3.0.7087" ${CMAKE_PROJECT_NAME}.nacp + COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste" "${OPENBOR_VERSION}" ${CMAKE_PROJECT_NAME}.nacp COMMAND elf2nro ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.nro --icon=${CMAKE_SOURCE_DIR}/engine/resources/switch_icon.jpg --nacp=${CMAKE_PROJECT_NAME}.nacp) + add_custom_target(${PROJECT_NAME}_switch_release + DEPENDS ${PROJECT_NAME}.nro + COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-${OPENBOR_VERSION}_switch.zip + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/release/${PROJECT_NAME} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.nro ${CMAKE_BINARY_DIR}/release/${PROJECT_NAME}/ + COMMAND cd ${CMAKE_BINARY_DIR}/release && zip -r ../${PROJECT_NAME}-${OPENBOR_VERSION}_switch.zip ${PROJECT_NAME} + ) endif () From 267f94e7b541eafe6980ad35d1a9ddba7daf5b46 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Thu, 7 May 2020 09:48:31 +0200 Subject: [PATCH 16/22] switch: don't load sdl gl library (since it's not needed, and not unloaded by openbor...) --- engine/sdl/video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/sdl/video.c b/engine/sdl/video.c index 7eab37060..71dc3a30a 100644 --- a/engine/sdl/video.c +++ b/engine/sdl/video.c @@ -57,7 +57,7 @@ void initSDL() SDL_ShowCursor(SDL_DISABLE); //atexit(SDL_Quit); //White Dragon: use SDL_Quit() into sdlport.c it's best practice! -#ifdef LOADGL +#if defined(LOADGL) && !defined(__SWITCH__) if(SDL_GL_LoadLibrary(NULL) < 0) { printf("Warning: couldn't load OpenGL library (%s)\n", SDL_GetError()); From 62ae0764dc61ea7cc20c14da9d2c00ba84955a2c Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Thu, 7 May 2020 10:34:27 +0200 Subject: [PATCH 17/22] sdl/haptic: try joystick rumble if no haptic --- engine/openbor.c | 4 ++++ engine/sdl/control.c | 13 ++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/engine/openbor.c b/engine/openbor.c index fad274ffc..c3292ea6b 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -2419,7 +2419,11 @@ void execute_pdie_script(int index) void clearbuttons(int player) { +#ifdef __SWITCH__ + savedata.joyrumble[player] = 1; +#else savedata.joyrumble[player] = 0; +#endif if (player == 0) { diff --git a/engine/sdl/control.c b/engine/sdl/control.c index cbd8a0d9e..78a6e5032 100644 --- a/engine/sdl/control.c +++ b/engine/sdl/control.c @@ -975,10 +975,17 @@ void control_update(s_playercontrols ** playercontrols, int numplayers) void control_rumble(int port, int ratio, int msec) { #if SDL - if (joystick[port] != NULL && joystick_haptic[port] != NULL) { - if(SDL_HapticRumblePlay(joystick_haptic[port], ratio, msec) != 0) + if (joystick[port] != NULL) + { + if(joystick_haptic[port] != NULL) + { + SDL_HapticRumblePlay(joystick_haptic[port], ratio, msec); + } + else { - //printf( "Warning: Unable to play rumble! %s\n", SDL_GetError() ); + // try joystick rumble + int freq = msec ? 30000 : 0; + SDL_JoystickRumble(joystick[port], freq, freq, msec); } } #endif From f79c0b3bb1f2a33e5a2c452ac007031ac550fe92 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Fri, 25 Jun 2021 12:01:33 +0200 Subject: [PATCH 18/22] cmake: add cmake support (linux and switch) globals.h: define stricmp/strnicmp if not defined --- .gitignore | 3 +- CMakeLists.switch => CMakeLists.txt | 72 ++++++++++------------------- engine/sdl/video.c | 2 +- engine/source/globals.h | 8 ++++ 4 files changed, 35 insertions(+), 50 deletions(-) rename CMakeLists.switch => CMakeLists.txt (57%) diff --git a/.gitignore b/.gitignore index 699284713..d5f4a9b05 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,4 @@ tools/psp-sdk/* tools/devkitpro/* # switch port .idea -cmake-build* -CMakeLists.txt \ No newline at end of file +cmake-build* \ No newline at end of file diff --git a/CMakeLists.switch b/CMakeLists.txt similarity index 57% rename from CMakeLists.switch rename to CMakeLists.txt index 01f2ff7b9..52cd52fcb 100644 --- a/CMakeLists.switch +++ b/CMakeLists.txt @@ -1,44 +1,21 @@ cmake_minimum_required(VERSION 3.1) #set(CMAKE_VERBOSE_MAKEFILE ON) -option(PLATFORM_LINUX "Linux platform target" OFF) -option(PLATFORM_SWITCH "Nintendo Switch platform target" OFF) +project(OpenBOR) +set(OPENBOR_VERSION "3.0.7141") +##################### +# OPTIONS +##################### option(BUILD_GFX "Build with GFX support" ON) option(BUILD_VORBIS "Build with BUILD_VORBIS support" ON) -if (PLATFORM_LINUX) - set(CMAKE_SYSTEM_NAME "Linux") -elseif (PLATFORM_SWITCH) - set(CMAKE_SYSTEM_NAME "Generic") - set(DEVKITPRO $ENV{DEVKITPRO}) - set(CMAKE_SYSTEM_PROCESSOR "armv8-a") - set(CMAKE_C_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc") - set(CMAKE_CXX_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++") - set(CMAKE_ASM_COMPILER "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-as") - set(CMAKE_AR "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ar" CACHE STRING "") - set(CMAKE_RANLIB "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-gcc-ranlib" CACHE STRING "") - set(CMAKE_C_FLAGS "-g -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -ftls-model=local-exec -fPIC -I${DEVKITPRO}/libnx/include -I${DEVKITPRO}/portlibs/switch/include" CACHE STRING "C flags") - set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions" CACHE STRING "C++ flags") - set(PKG_CONFIG_EXECUTABLE ${DEVKITPRO}/portlibs/switch/bin/aarch64-none-elf-pkg-config) - set(CMAKE_FIND_ROOT_PATH ${DEVKITPRO} ${DEVKITPRO}/devkitA64 ${DEVKITPRO}/libnx ${DEVKITPRO}/portlibs/switch) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "Shared libs not available") -endif () - -project(OpenBOR) - -set(OPENBOR_VERSION "3.0.7087") - ############## # COMMON ############## - include(FindPkgConfig) pkg_search_module(SDL2 REQUIRED sdl2) +pkg_search_module(SDL2_GFX REQUIRED SDL2_gfx) pkg_search_module(VPX REQUIRED vpx) pkg_search_module(PNG REQUIRED libpng) pkg_search_module(ZLIB REQUIRED zlib) @@ -59,6 +36,7 @@ set(BOR_INC engine/source/webmlib/halloc engine/source/webmlib/nestegg ${SDL2_INCLUDE_DIRS} + ${SDL2_GFX_INCLUDE_DIRS} ${VPX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} @@ -82,7 +60,7 @@ file(GLOB BOR_SRC ) set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DWEBM -DOPENGL -DLOADGL -D__CMAKE__) -set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) +set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${SDL2_GFX_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) ############## # VERSION.SH @@ -113,20 +91,15 @@ endif () ##################### # PLATORM SPECIFIC ##################### -if (PLATFORM_SWITCH) +if (NINTENDO_SWITCH) ##################### # SWITCH PLATORM ##################### if (CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND BOR_CFLAGS -DNXLINK) endif () - list(APPEND BOR_CFLAGS -D__SWITCH__) - list(APPEND BOR_LDFLAGS - -L${DEVKITPRO}/libnx/lib - -L${DEVKITPRO}/portlibs/switch/lib - -specs=${DEVKITPRO}/libnx/switch.specs - stdc++) -elseif (PLATFORM_LINUX) + list(APPEND BOR_LDFLAGS stdc++) +else () ##################### # LINUX PLATORM ##################### @@ -136,19 +109,24 @@ endif () ##################### # OpenBOR executable ##################### -add_executable(${CMAKE_PROJECT_NAME}.elf ${BOR_SRC}) -target_include_directories(${CMAKE_PROJECT_NAME}.elf PRIVATE ${BOR_INC}) -target_compile_options(${CMAKE_PROJECT_NAME}.elf PRIVATE ${BOR_CFLAGS}) -target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${BOR_LDFLAGS}) +add_executable(${CMAKE_PROJECT_NAME} ${BOR_SRC}) +target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${BOR_INC}) +target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE ${BOR_CFLAGS}) +target_link_libraries(${CMAKE_PROJECT_NAME} ${BOR_LDFLAGS}) ##################### # SWITCH target ##################### -if (PLATFORM_SWITCH) - add_custom_target(${CMAKE_PROJECT_NAME}.nro - DEPENDS ${CMAKE_PROJECT_NAME}.elf - COMMAND ${DEVKITPRO}/tools/bin/nacptool --create "${CMAKE_PROJECT_NAME}" "cpasjuste" "${OPENBOR_VERSION}" ${CMAKE_PROJECT_NAME}.nacp - COMMAND elf2nro ${CMAKE_PROJECT_NAME}.elf ${CMAKE_PROJECT_NAME}.nro --icon=${CMAKE_SOURCE_DIR}/engine/resources/switch_icon.jpg --nacp=${CMAKE_PROJECT_NAME}.nacp) +if (NINTENDO_SWITCH) + nx_generate_nacp(${CMAKE_PROJECT_NAME}.nacp + NAME "${CMAKE_PROJECT_NAME}" + AUTHOR "cpasjuste" + VERSION "${OPENBOR_VERSION}" + ) + nx_create_nro(${CMAKE_PROJECT_NAME} + NACP ${CMAKE_PROJECT_NAME}.nacp + ICON "${CMAKE_SOURCE_DIR}/engine/resources/switch_icon.jpg" + ) add_custom_target(${PROJECT_NAME}_switch_release DEPENDS ${PROJECT_NAME}.nro COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-${OPENBOR_VERSION}_switch.zip diff --git a/engine/sdl/video.c b/engine/sdl/video.c index 422e5b96c..ce531bf8a 100644 --- a/engine/sdl/video.c +++ b/engine/sdl/video.c @@ -71,8 +71,8 @@ void initSDL() SDL_GetCurrentDisplayMode(0, &video_info); nativeWidth = video_info.w; nativeHeight = video_info.h; -#endif printf("debug:nativeWidth, nativeHeight, bpp, Hz %d, %d, %d, %d\n", nativeWidth, nativeHeight, SDL_BITSPERPIXEL(video_info.format), video_info.refresh_rate); +#endif SDL_initFramerate(&framerate_manager); SDL_setFramerate(&framerate_manager, 200); //Kratus (29-04-21) Reversed the FPS limit to reduce CPU usage } diff --git a/engine/source/globals.h b/engine/source/globals.h index e9366196e..f7d0fa62c 100644 --- a/engine/source/globals.h +++ b/engine/source/globals.h @@ -70,6 +70,14 @@ #define strnicmp strncasecmp #endif +#ifndef stricmp +#define stricmp strcasecmp +#endif + +#ifndef strnicmp +#define strnicmp strncasecmp +#endif + #include "packfile.h" ///////////////////////////////////////////////////////////////////////////// From 9889a5e73b5987c246be2fc3bd6b6c8e8f4dc624 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Fri, 25 Jun 2021 12:06:25 +0200 Subject: [PATCH 19/22] switch: minor cleanup --- CMakeLists.txt | 2 +- engine/sdl/sdlport.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52cd52fcb..e8fb209e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ if (NINTENDO_SWITCH) # SWITCH PLATORM ##################### if (CMAKE_BUILD_TYPE STREQUAL "Debug") - list(APPEND BOR_CFLAGS -DNXLINK) + list(APPEND BOR_CFLAGS -D__NXLINK__) endif () list(APPEND BOR_LDFLAGS stdc++) else () diff --git a/engine/sdl/sdlport.c b/engine/sdl/sdlport.c index d650277c7..c4822f873 100644 --- a/engine/sdl/sdlport.c +++ b/engine/sdl/sdlport.c @@ -20,9 +20,9 @@ #include #elif WIN #undef main -#elif defined(__SWITCH__) && defined(NXLINK) +#elif defined(__SWITCH__) && defined(__NXLINK__) #include -static int nxlink_sock = -1; +int nx_sock = -1; #endif char packfile[MAX_FILENAME_LEN] = {"bor.pak"}; @@ -67,9 +67,9 @@ void borExit(int reset) SDL_Quit(); // call this instead of atexit(SDL_Quit); It's best practice! #endif -#if defined(__SWITCH__) && defined(NXLINK) - if (nxlink_sock != -1) - close(nxlink_sock); +#if defined(__SWITCH__) && defined(__NXLINK__) + if (nx_sock != -1) + close(nx_sock); socketExit(); #endif @@ -110,9 +110,9 @@ int main(int argc, char *argv[]) } #endif -#if defined(__SWITCH__) && defined(NXLINK) +#if defined(__SWITCH__) && defined(__NXLINK__) socketInitializeDefault(); - nxlink_sock = nxlinkStdio(); + nx_sock = nxlinkStdio(); #endif setSystemRam(); From 7a93eaf0e128a132c69591dad8dc081855db41c6 Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Mon, 7 Mar 2022 12:43:08 +0100 Subject: [PATCH 20/22] common: remove sdl2_gfx deps --- CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8fb209e2..7522b2601 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1) #set(CMAKE_VERBOSE_MAKEFILE ON) project(OpenBOR) -set(OPENBOR_VERSION "3.0.7141") +set(OPENBOR_VERSION "3.0.7162") ##################### # OPTIONS @@ -15,7 +15,6 @@ option(BUILD_VORBIS "Build with BUILD_VORBIS support" ON) ############## include(FindPkgConfig) pkg_search_module(SDL2 REQUIRED sdl2) -pkg_search_module(SDL2_GFX REQUIRED SDL2_gfx) pkg_search_module(VPX REQUIRED vpx) pkg_search_module(PNG REQUIRED libpng) pkg_search_module(ZLIB REQUIRED zlib) @@ -36,7 +35,6 @@ set(BOR_INC engine/source/webmlib/halloc engine/source/webmlib/nestegg ${SDL2_INCLUDE_DIRS} - ${SDL2_GFX_INCLUDE_DIRS} ${VPX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} @@ -60,7 +58,7 @@ file(GLOB BOR_SRC ) set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DWEBM -DOPENGL -DLOADGL -D__CMAKE__) -set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${SDL2_GFX_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) +set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) ############## # VERSION.SH From 3acca5a58bf999e9f8d9731cc21c24bc7dbc6f8a Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Mon, 7 Mar 2022 15:17:47 +0100 Subject: [PATCH 21/22] ps4: first commit --- CMakeLists.txt | 15 +- engine/openbor.c | 7 +- engine/openbor.h | 3 +- engine/openborscript.c | 2360 +++++++++-------- .../resources/ps4/sce_module/libSceFios2.prx | Bin 0 -> 3200 bytes engine/resources/ps4/sce_module/libc.prx | Bin 0 -> 3424 bytes engine/resources/ps4/sce_sys/about/right.sprx | Bin 0 -> 28800 bytes engine/resources/ps4/sce_sys/icon0.png | Bin 0 -> 110311 bytes engine/sdl/menu.c | 2 +- engine/sdl/video.c | 5 +- engine/source/ramlib/ram.c | 4 +- engine/source/utils.c | 9 +- 12 files changed, 1212 insertions(+), 1193 deletions(-) create mode 100644 engine/resources/ps4/sce_module/libSceFios2.prx create mode 100644 engine/resources/ps4/sce_module/libc.prx create mode 100644 engine/resources/ps4/sce_sys/about/right.sprx create mode 100644 engine/resources/ps4/sce_sys/icon0.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 7522b2601..df7dd2eae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ file(GLOB BOR_SRC engine/source/webmlib/nestegg/*.c ) -set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DWEBM -DOPENGL -DLOADGL -D__CMAKE__) +set(BOR_CFLAGS -g -Wall -fsigned-char -fomit-frame-pointer -DSDL -DSDL2 -DWEBM -D__CMAKE__) set(BOR_LDFLAGS ${SDL2_LIBRARIES} ${VPX_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} m) ############## @@ -90,18 +90,17 @@ endif () # PLATORM SPECIFIC ##################### if (NINTENDO_SWITCH) - ##################### - # SWITCH PLATORM - ##################### if (CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND BOR_CFLAGS -D__NXLINK__) endif () + list(APPEND BOR_CFLAGS -DOPENGL -DLOADGL) list(APPEND BOR_LDFLAGS stdc++) +elseif (PS4) + list(APPEND BOR_CFLAGS -D__CLANG_MAX_ALIGN_T_DEFINED) + add_self(${PROJECT_NAME}) + add_pkg(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/engine/resources/ps4 "OPEN00001" "OpenBor @ cpasjuste" "03.71") else () - ##################### - # LINUX PLATORM - ##################### - list(APPEND BOR_CFLAGS -D__LINUX__ -DLINUX) + list(APPEND BOR_CFLAGS -D__LINUX__ -DLINUX -DOPENGL -DLOADGL) endif () ##################### diff --git a/engine/openbor.c b/engine/openbor.c index 9cc752100..84a54fdea 100644 --- a/engine/openbor.c +++ b/engine/openbor.c @@ -2457,6 +2457,8 @@ void clearsettings() savedata.hwscale = 0.0; #elif __SWITCH__ savedata.hwscale = 2.0f; + #elif __PS4__ + savedata.hwscale = 2.0f; #else savedata.hwscale = 1.0; #endif @@ -37835,6 +37837,9 @@ void init_videomodes(int log) #elif __SWITCH__ tryfile("data/videoswitch.txt"); tryfile("data/video169.txt"); +#elif __PS4__ + tryfile("data/videops4.txt"); + tryfile("data/video169.txt"); #endif #undef tryfile @@ -39494,7 +39499,7 @@ void menu_options_video() #if SDL #if !defined(GP2X) && !defined(OPENDINGUX) -#ifndef __SWITCH__ +#if !defined(__SWITCH__) && !defined(__PS4__) video_fullscreen_flip(); #endif break; diff --git a/engine/openbor.h b/engine/openbor.h index a19fafbe5..06a5d37c0 100644 --- a/engine/openbor.h +++ b/engine/openbor.h @@ -358,7 +358,8 @@ typedef enum PORTING_WINDOWS, PORTING_WIZ, PORTING_XBOX, - PORTING_VITA + PORTING_VITA, + PORTING_PS4 } e_porting; // Caskey, Damon V. diff --git a/engine/openborscript.c b/engine/openborscript.c index 9b4be67f9..c437d84f4 100644 --- a/engine/openborscript.c +++ b/engine/openborscript.c @@ -45,81 +45,81 @@ static s_drawmethod drawmethod; int max_indexed_vars = 0; int max_entity_vars = 0; int max_script_vars = 0; -int no_nested_script = 0; - -extern int ent_count; -extern int ent_max; -extern int gameOver; -extern int selectScreen; -extern int titleScreen; -extern int hallOfFame; -extern int showComplete; -extern char *currentScene; -extern int enginecreditsScreen; -extern int menuScreen; -extern int optionsMenu; -extern int controloptionsMenu; -extern int videooptionsMenu; -extern int soundoptionsMenu; -extern int systemoptionsMenu; -extern int startgameMenu; -extern int newgameMenu; -extern int loadgameMenu; -extern int num_difficulties; -extern u32 _time; -extern int goto_mainmenu_flag; -extern int _pause; -extern int timeleft; -extern int gfx_x_offset; -extern int gfx_y_offset; -extern int gfx_y_offset_adj; -extern s_lasthit lasthit; -extern int current_set; -extern int current_level; -extern int current_stage; -extern int timevar; -extern float bgtravelled; -extern float vbgtravelled; -extern int traveltime; -extern int texttime; -extern int timetoshow; -extern int is_total_timeover; -extern int showgo; -extern float advancex; -extern float advancey; -extern float scrolldx; -extern float scrolldy; -extern float scrollminz; -extern float scrollmaxz; -extern float blockade; -extern float scrollminx; -extern float scrollmaxx; -extern s_videomodes videomodes; -extern int panel_height; -extern char branch_name[MAX_NAME_LEN + 1]; -extern s_set_entry *levelsets; -extern unsigned int models_loaded; -//extern unsigned int models_cached; -extern int viewportx; -extern int viewporty; -extern int viewportw; -extern int viewporth; -extern int nosave; -extern int nopause; -extern int nofadeout; -extern int noscreenshot; -extern int nojoin; -extern s_screen *vscreen; -extern entity *smartbomber; -extern entity *textbox; -extern s_screen *background; -extern int skiptoset; -extern s_slow_motion slowmotion; -extern int shadowcolor; -extern int shadowalpha; -extern int shadowopacity; -extern s_axis_plane_vertical_int light; -extern int max_attack_types; +int no_nested_script = 0; + +extern int ent_count; +extern int ent_max; +extern int gameOver; +extern int selectScreen; +extern int titleScreen; +extern int hallOfFame; +extern int showComplete; +extern char *currentScene; +extern int enginecreditsScreen; +extern int menuScreen; +extern int optionsMenu; +extern int controloptionsMenu; +extern int videooptionsMenu; +extern int soundoptionsMenu; +extern int systemoptionsMenu; +extern int startgameMenu; +extern int newgameMenu; +extern int loadgameMenu; +extern int num_difficulties; +extern u32 _time; +extern int goto_mainmenu_flag; +extern int _pause; +extern int timeleft; +extern int gfx_x_offset; +extern int gfx_y_offset; +extern int gfx_y_offset_adj; +extern s_lasthit lasthit; +extern int current_set; +extern int current_level; +extern int current_stage; +extern int timevar; +extern float bgtravelled; +extern float vbgtravelled; +extern int traveltime; +extern int texttime; +extern int timetoshow; +extern int is_total_timeover; +extern int showgo; +extern float advancex; +extern float advancey; +extern float scrolldx; +extern float scrolldy; +extern float scrollminz; +extern float scrollmaxz; +extern float blockade; +extern float scrollminx; +extern float scrollmaxx; +extern s_videomodes videomodes; +extern int panel_height; +extern char branch_name[MAX_NAME_LEN + 1]; +extern s_set_entry *levelsets; +extern unsigned int models_loaded; +//extern unsigned int models_cached; +extern int viewportx; +extern int viewporty; +extern int viewportw; +extern int viewporth; +extern int nosave; +extern int nopause; +extern int nofadeout; +extern int noscreenshot; +extern int nojoin; +extern s_screen *vscreen; +extern entity *smartbomber; +extern entity *textbox; +extern s_screen *background; +extern int skiptoset; +extern s_slow_motion slowmotion; +extern int shadowcolor; +extern int shadowalpha; +extern int shadowopacity; +extern s_axis_plane_vertical_int light; +extern int max_attack_types; extern int max_animations; static void clear_named_var_list(List *list, int level) @@ -684,12 +684,12 @@ static s_collision_attack attack; HRESULT system_isempty(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) { if(paramCount != 1) - { + { *pretvar = NULL; return E_FAIL; } - ScriptVariant_ChangeType(*pretvar, VT_INTEGER); + ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)( (varlist[0])->vt == VT_EMPTY ); @@ -923,7 +923,7 @@ HRESULT system_typeof(ScriptVariant **varlist , ScriptVariant **pretvar, int par static const char *svlist[] = { "background", - "blockade", + "blockade", "bossescount", "branchname", "cheats", @@ -1000,7 +1000,7 @@ static const char *svlist[] = "nosave", "noscreenshot", "noshowcomplete", - "numbasemaps", + "numbasemaps", "numbosses", "numholes", "numlayers", @@ -2031,7 +2031,7 @@ enum entityproperty_enum _ep_attackthrottletime, _ep_autokill, _ep_base, - _ep_bbox, + _ep_bbox, _ep_bind, _ep_blink, _ep_blockback, @@ -2041,7 +2041,7 @@ enum entityproperty_enum _ep_bounce, _ep_bound, _ep_candamage, - _ep_chargerate, + _ep_chargerate, _ep_collidedentity, _ep_colourmap, _ep_colourtable, @@ -2055,14 +2055,14 @@ enum entityproperty_enum _ep_defense, _ep_destx, _ep_destz, - _ep_detect, + _ep_detect, _ep_die_on_landing, _ep_direction, _ep_dropframe, - _ep_edelay, - _ep_edge, + _ep_edelay, + _ep_edge, _ep_edgerange, - _ep_energycost, + _ep_energycost, _ep_entitypushing, _ep_escapecount, _ep_escapehits, @@ -2110,8 +2110,8 @@ enum entityproperty_enum _ep_maxhealth, _ep_maxjugglepoints, _ep_maxmp, - _ep_model, - _ep_movex, + _ep_model, + _ep_movex, _ep_movez, _ep_mp, _ep_mpdroprate, @@ -2143,10 +2143,10 @@ enum entityproperty_enum _ep_path, _ep_pathfindstep, _ep_playerindex, - _ep_position, + _ep_position, _ep_prevanimationid, _ep_projectile, - _ep_projectilehit, + _ep_projectilehit, _ep_pushingfactor, _ep_range, _ep_releasetime, @@ -2234,7 +2234,7 @@ static const char *eplist[] = "attackthrottletime", "autokill", "base", - "bbox", + "bbox", "binding", "blink", "blockback", @@ -2244,7 +2244,7 @@ static const char *eplist[] = "bounce", "bound", "candamage", - "chargerate", + "chargerate", "collidedentity", "colourmap", "colourtable", @@ -2258,14 +2258,14 @@ static const char *eplist[] = "defense", "destx", "destz", - "detect", + "detect", "die_on_landing", "direction", "dropframe", - "edelay", - "edge", + "edelay", + "edge", "edgerange", - "energycost", + "energycost", "entitypushing", "escapecount", "escapehits", @@ -2313,8 +2313,8 @@ static const char *eplist[] = "maxhealth", "maxjugglepoints", "maxmp", - "model", - "movex", + "model", + "movex", "movez", "mp", "mpdroprate", @@ -2346,10 +2346,10 @@ static const char *eplist[] = "path", "pathfindstep", "playerindex", - "position", + "position", "prevanimationid", "projectile", - "projectilehit", + "projectilehit", "pushingfactor", "range", "releasetime", @@ -2418,7 +2418,7 @@ enum aiflag_enum _ep_aiflag_blocking, _ep_aiflag_charging, _ep_aiflag_dead, - _ep_aiflag_drop, + _ep_aiflag_drop, _ep_aiflag_ducking, _ep_aiflag_falling, _ep_aiflag_frozen, @@ -2430,7 +2430,7 @@ enum aiflag_enum _ep_aiflag_invincible, _ep_aiflag_jumpid, _ep_aiflag_jumping, - _ep_aiflag_projectile, + _ep_aiflag_projectile, _ep_aiflag_rising, _ep_aiflag_running, _ep_aiflag_toexplode, @@ -2450,7 +2450,7 @@ static const char *eplist_aiflag[] = "blocking", "charging", "dead", - "drop", + "drop", "ducking", "falling", "frozen", @@ -2462,22 +2462,22 @@ static const char *eplist_aiflag[] = "invincible", "jumpid", "jumping", - "projectile", + "projectile", "rising", "running", "toexplode", "turning", "walking", "walkmode", -}; - +}; + enum edgerange_enum { _ep_edgerange_x, _ep_edgerange_z, _ep_edgerange_the_end, -}; - +}; + static const char *eplist_edgerange[] = { "x", @@ -2683,8 +2683,8 @@ enum _prop_summonframe_enum _PROP_SUMMONFRAME_Y, _PROP_SUMMONFRAME_Z, _PROP_SUMMONFRAME_THE_END -}; - +}; + enum _prop_starvelocity_enum { _PROP_STARVELOCITY_1, @@ -3102,7 +3102,7 @@ int mapstrings_entityproperty(ScriptVariant **varlist, int paramCount) MAPSTRINGS(varlist[2], eplist_aiflag, _ep_aiflag_the_end, _is_not_a_known_subproperty_of_, eps); break; - } + } // map subproperties of edgerange property case _ep_edgerange: { @@ -3345,7 +3345,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret break; case _ep_aiflag_blocking: (*pretvar)->lVal = (LONG)ent->blocking; - break; + break; case _ep_aiflag_ducking: (*pretvar)->lVal = (LONG)ent->ducking; break; @@ -3357,7 +3357,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret break; case _ep_aiflag_inpain: (*pretvar)->lVal = (LONG)ent->inpain; - break; + break; case _ep_aiflag_rising: (*pretvar)->lVal = (LONG)ent->rising; break; @@ -3476,7 +3476,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)ent->animnum; break; - } + } case _ep_prevanimationid: { ScriptVariant_ChangeType(*pretvar, VT_INTEGER); @@ -3605,7 +3605,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret ScriptVariant_ChangeType(*pretvar, VT_PTR); (*pretvar)->ptrVal = (VOID *)ent->binding.ent; break; - } + } case _ep_bind: { ScriptVariant_ChangeType(*pretvar, VT_PTR); @@ -3641,12 +3641,12 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)ent->combotime; break; - } - case _ep_collidedentity: - { - ScriptVariant_ChangeType(*pretvar, VT_PTR); - (*pretvar)->ptrVal = (VOID *)&ent->collided_entity; - break; + } + case _ep_collidedentity: + { + ScriptVariant_ChangeType(*pretvar, VT_PTR); + (*pretvar)->ptrVal = (VOID *)&ent->collided_entity; + break; } case _ep_hostile: { @@ -3680,9 +3680,9 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret } case _ep_damage_on_landing: { - ScriptVariant_ChangeType(*pretvar, VT_INTEGER); - (*pretvar)->lVal = (LONG)ent->damage_on_landing.attack_force; - + ScriptVariant_ChangeType(*pretvar, VT_INTEGER); + (*pretvar)->lVal = (LONG)ent->damage_on_landing.attack_force; + break; } @@ -3783,7 +3783,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)ent->modeldata.stealth.detect; break; - } + } case _ep_die_on_landing: { ScriptVariant_ChangeType(*pretvar, VT_INTEGER); @@ -3843,7 +3843,7 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret break; } case _ep_edelay_factor: - { + { ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edelay.factor; break; @@ -3873,41 +3873,41 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret return E_FAIL; } break; - } + } case _ep_edge: { ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)ent->edge; break; - } + } case _ep_edgerange: - { - if(paramCount < 3) - { - break; - } - arg = varlist[2]; - if(arg->vt != VT_INTEGER) - { - printf("You must give a string name for edgerange.\n"); - return E_FAIL; - } - ltemp = arg->lVal; - - ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); - switch(ltemp) - { - case _ep_edgerange_x: - (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.x; - break; - case _ep_edgerange_z: - (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.z; - break; - default: - ScriptVariant_Clear(*pretvar); - return E_FAIL; - } - break; + { + if(paramCount < 3) + { + break; + } + arg = varlist[2]; + if(arg->vt != VT_INTEGER) + { + printf("You must give a string name for edgerange.\n"); + return E_FAIL; + } + ltemp = arg->lVal; + + ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); + switch(ltemp) + { + case _ep_edgerange_x: + (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.x; + break; + case _ep_edgerange_z: + (*pretvar)->dblVal = (DOUBLE)ent->modeldata.edgerange.z; + break; + default: + ScriptVariant_Clear(*pretvar); + return E_FAIL; + } + break; } case _ep_energycost: { @@ -4355,12 +4355,12 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret { break; } - - // entity must have a land frame set. - if(!ent->modeldata.animation[i]->landframe) - { - break; - } + + // entity must have a land frame set. + if(!ent->modeldata.animation[i]->landframe) + { + break; + } switch(ltemp) { @@ -4580,25 +4580,25 @@ HRESULT openbor_getentityproperty(ScriptVariant **varlist , ScriptVariant **pret ScriptVariant_ChangeType(*pretvar, VT_STR); (*pretvar)->strVal = StrCache_CreateNewFrom(ent->model->name); break; - } + } case _ep_movex: { ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); (*pretvar)->dblVal = (DOUBLE)ent->movex; break; - } + } case _ep_movez: { ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); (*pretvar)->dblVal = (DOUBLE)ent->movex; break; - } + } case _ep_entitypushing: { ScriptVariant_ChangeType(*pretvar, VT_INTEGER); (*pretvar)->lVal = (LONG)ent->modeldata.entitypushing; break; - } + } case _ep_pushingfactor: { ScriptVariant_ChangeType(*pretvar, VT_DECIMAL); @@ -5476,7 +5476,7 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p break; case _ep_aiflag_blocking: ent->blocking = (LONG)ltemp; - break; + break; case _ep_aiflag_ducking: ent->ducking = (LONG)ltemp; break; @@ -5488,7 +5488,7 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p break; case _ep_aiflag_inpain: ent->inpain = (LONG)ltemp; - break; + break; case _ep_aiflag_rising: ent->rising = (LONG)ltemp; break; @@ -5720,7 +5720,7 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p ent->combotime = (LONG)ltemp; } break; - } + } case _ep_collidedentity: { ent->collided_entity = (entity *)varlist[2]->ptrVal; @@ -5865,7 +5865,7 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p } break; - } + } case _ep_edge: { if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], <emp))) @@ -5873,38 +5873,38 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p ent->edge = (LONG)ltemp; } break; - } + } case _ep_edgerange: - { - if(varlist[2]->vt != VT_INTEGER) - { - if(varlist[2]->vt != VT_STR) - { - printf("You must give a string value for edgerange name.\n"); - } - goto changeentityproperty_error; - } - if(paramCount < 4) - { - break; - } - - if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp))) - { - switch(varlist[2]->lVal) - { - case _ep_edgerange_x: - ent->modeldata.edgerange.x = (DOUBLE)dbltemp; - break; - case _ep_edgerange_z: - ent->modeldata.edgerange.z = (DOUBLE)dbltemp; - break; - default: - printf("Unknown edgerange.\n"); - goto changeentityproperty_error; - } - } - break; + { + if(varlist[2]->vt != VT_INTEGER) + { + if(varlist[2]->vt != VT_STR) + { + printf("You must give a string value for edgerange name.\n"); + } + goto changeentityproperty_error; + } + if(paramCount < 4) + { + break; + } + + if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[3], &dbltemp))) + { + switch(varlist[2]->lVal) + { + case _ep_edgerange_x: + ent->modeldata.edgerange.x = (DOUBLE)dbltemp; + break; + case _ep_edgerange_z: + ent->modeldata.edgerange.z = (DOUBLE)dbltemp; + break; + default: + printf("Unknown edgerange.\n"); + goto changeentityproperty_error; + } + } + break; } case _ep_energycost: { @@ -6396,38 +6396,38 @@ HRESULT openbor_changeentityproperty(ScriptVariant **varlist , ScriptVariant **p } } break; - } - case _ep_movex: - { - if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) - { - ent->movex = (DOUBLE)dbltemp; - } - break; - } - case _ep_movez: - { - if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) - { - ent->movez = (DOUBLE)dbltemp; - } - break; - } - case _ep_entitypushing: - { - if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], <emp))) - { - ent->modeldata.entitypushing = (LONG)ltemp; - } - break; - } - case _ep_pushingfactor: - { - if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) - { - ent->modeldata.pushingfactor = (DOUBLE)dbltemp; - } - break; + } + case _ep_movex: + { + if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) + { + ent->movex = (DOUBLE)dbltemp; + } + break; + } + case _ep_movez: + { + if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) + { + ent->movez = (DOUBLE)dbltemp; + } + break; + } + case _ep_entitypushing: + { + if(SUCCEEDED(ScriptVariant_IntegerValue(varlist[2], <emp))) + { + ent->modeldata.entitypushing = (LONG)ltemp; + } + break; + } + case _ep_pushingfactor: + { + if(SUCCEEDED(ScriptVariant_DecimalValue(varlist[2], &dbltemp))) + { + ent->modeldata.pushingfactor = (DOUBLE)dbltemp; + } + break; } case _ep_mp: { @@ -7679,8 +7679,8 @@ HRESULT openbor_getplayerproperty(ScriptVariant **varlist , ScriptVariant **pret (*pretvar)->lVal = (LONG)(model_cache[cacheindex].model->maps_loaded + 1); break; - } - default: + } + default: { //printf("Property name '%s' is not supported by function getplayerproperty.\n", propname); *pretvar = NULL; @@ -8037,893 +8037,895 @@ HRESULT openbor_changeplayerproperty(ScriptVariant **varlist , ScriptVariant **p ScriptVariant_ToString(arg, buffer); printf("Function changeplayerproperty receives an invalid value: %s.\n", buffer); return E_FAIL; -} - -//this method is used by script engine, we move it here -// it will get a system property, put it in the ScriptVariant -// if failed return 0, otherwise return 1 -int getsyspropertybyindex(ScriptVariant *var, int index) -{ - if(!var) - { - return 0; - } - - switch(index) - { - case _sv_count_enemies: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = count_ents(TYPE_ENEMY); - break; - case _sv_count_players: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = count_ents(TYPE_PLAYER); - break; - case _sv_count_npcs: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = count_ents(TYPE_NPC); - break; - case _sv_count_entities: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = ent_count; - break; - case _sv_drawmethod_default: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = (void *)&plainmethod; - break; - case _sv_ent_max: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = ent_max; - break; - case _sv_in_level: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = (level != NULL); - break; - case _sv_in_gameoverscreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = gameOver; - break; - case _sv_in_menuscreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - if(selectScreen || titleScreen || hallOfFame || gameOver || showComplete || currentScene || level || enginecreditsScreen) - { - var->lVal = 0; - } - else - { - var->lVal = menuScreen; - } - break; - case _sv_in_enginecreditsscreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = enginecreditsScreen; - break; - case _sv_in_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = optionsMenu; - break; - case _sv_in_system_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = systemoptionsMenu; - break; - case _sv_in_cheat_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = (optionsMenu && is_cheat_actived()) ? 1:0; - break; - case _sv_cheats: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = is_cheat_actived(); - break; - case _sv_in_control_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = controloptionsMenu; - break; - case _sv_in_sound_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = soundoptionsMenu; - break; - case _sv_in_video_options: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = videooptionsMenu; - break; - case _sv_in_start_game: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = startgameMenu; - break; - case _sv_in_new_game: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = newgameMenu; - break; - case _sv_in_load_game: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = loadgameMenu; - break; - case _sv_sets_count: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = num_difficulties; - break; - case _sv_in_showcomplete: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = showComplete; - break; - case _sv_in_titlescreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = titleScreen; - break; - case _sv_in_halloffamescreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = (hallOfFame); - break; - case _sv_sample_play_id: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = sample_play_id; - break; - case _sv_effectvol: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = savedata.effectvol; - break; - case _sv_elapsed_time: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = _time; - break; - case _sv_game_speed: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = GAME_SPEED; - break; - case _sv_game_paused: - case _sv_pause: - ScriptVariant_ChangeType(var, VT_INTEGER); - if( !(goto_mainmenu_flag&1) ) var->lVal = (_pause); - else var->lVal = 0; - break; - case _sv_game_time: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = timeleft; - break; - case _sv_porting: - { - e_porting porting; - - #if ANDROID - porting = PORTING_ANDROID; - #elif DARWIN - porting = PORTING_DARWIN; - #elif DC - porting = PORTING_DREAMCAST; - #elif GPX2 - porting = PORTING_GPX2; - #elif LINUX - porting = PORTING_LINUX; - #elif OPENDINGUX - porting = PORTING_OPENDINGUX; - #elif PSP - porting = PORTING_PSP; - #elif WII - porting = PORTING_WII; - #elif WIN - porting = PORTING_WINDOWS; - #elif WIZ - porting = PORTING_WIZ; - #elif XBOX - porting = PORTING_XBOX; - #elif VITA - porting = PORTING_VITA; - #else - porting = PORTING_UNKNOWN; - #endif - - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = porting; - break; - } - case _sv_gfx_x_offset: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = gfx_x_offset; - break; - case _sv_gfx_y_offset: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = gfx_y_offset; - break; - case _sv_gfx_y_offset_adj: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = gfx_y_offset_adj; - break; - case _sv_in_selectscreen: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = selectScreen; - break; - case _sv_lasthit_attack: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = lasthit.attack; - break; - case _sv_lasthit_attacker: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = lasthit.attacker; - break; - case _sv_lasthit_target: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = lasthit.target; - break; - - case _sv_lasthita: - case _sv_lasthity: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = lasthit.position.y; - break; - case _sv_lasthitc: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = lasthit.confirm; - break; - case _sv_lasthitt: - ScriptVariant_ChangeType(var, VT_INTEGER); - - if(lasthit.attack) - { - var->lVal = lasthit.attack->attack_type; - } - - break; - case _sv_lasthitx: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = lasthit.position.x; - break; - case _sv_lasthitz: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = lasthit.position.z; - break; - case _sv_xpos: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = advancex; - break; - case _sv_ypos: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = advancey; - break; - case _sv_hresolution: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = videomodes.hRes; - break; - case _sv_vresolution: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = videomodes.vRes; - break; - case _sv_current_scene: - if(currentScene) - { - ScriptVariant_ChangeType(var, VT_STR); - var->strVal = StrCache_CreateNewFrom(currentScene); - } - else - { - ScriptVariant_Clear(var); - } - break; - case _sv_current_set: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = current_set; - break; - case _sv_current_level: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = current_level; - break; - case _sv_current_palette: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = current_palette; - break; - case _sv_current_stage: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = current_stage; - break; - case _sv_levelwidth: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->width; - break; - case _sv_levelheight: - if(!level) - { - return 0; - } - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = panel_height; - break; - case _sv_branchname: - ScriptVariant_ChangeType(var, VT_STR); - var->strVal = StrCache_CreateNewFrom(branch_name); - break; - case _sv_current_branch: - if(level != NULL && levelsets && levelsets[current_set].levelorder && levelsets[current_set].levelorder[current_level].branchname) - { - ScriptVariant_ChangeType(var, VT_STR); - var->strVal = StrCache_CreateNewFrom(levelsets[current_set].levelorder[current_level].branchname); - } - else - { - ScriptVariant_Clear(var); - } - break; - case _sv_pakname: - { - char tempstr[MAX_BUFFER_LEN]; - getPakName(tempstr, -1); - ScriptVariant_ChangeType(var, VT_STR); - var->strVal = StrCache_CreateNewFrom(tempstr); - break; - } - case _sv_bossescount: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->bossescount; - break; - case _sv_maxsoundchannels: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = maxchannels(); - break; - case _sv_maxentityvars: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = max_entity_vars; - break; - case _sv_maxindexedvars: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = max_indexed_vars; - break; - case _sv_maxplayers: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = levelsets[current_set].maxplayers; - break; - case _sv_maxscriptvars: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = max_script_vars; - break; - case _sv_models_cached: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = models_cached; - break; - case _sv_models_loaded: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = models_loaded; - break; - case _sv_musicvol: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = savedata.musicvol; - break; - case _sv_nofadeout: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = nofadeout; - break; - case _sv_nojoin: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = nojoin; - break; - case _sv_nopause: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = nopause; - break; - case _sv_nosave: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = nosave; - break; - case _sv_noscreenshot: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = noscreenshot; - break; - case _sv_noshowcomplete: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = levelsets[current_set].noshowcomplete; - break; - case _sv_numbasemaps: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numbasemaps; - break; - case _sv_numbosses: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numbosses; - break; - case _sv_numholes: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numholes; - break; - case _sv_numlayers: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numlayers; - break; - case _sv_numpalettes: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numpalettes; - break; - case _sv_numwalls: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level->numwalls; - break; - case _sv_pixelformat: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = pixelformat; - break; - case _sv_player: - case _sv_player1: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = player; - break; - case _sv_player2: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = player + 1; - break; - case _sv_player3: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = player + 2; - break; - case _sv_player4: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = player + 3; - break; - case _sv_player_max_z: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = PLAYER_MAX_Z; - break; - case _sv_player_min_z: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = PLAYER_MIN_Z; - break; - case _sv_lightx: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = light.x; - break; - case _sv_lightz: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = light.y; - break; - case _sv_self: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = self; - break; - case _sv_shadowalpha: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = shadowalpha; - break; - case _sv_shadowcolor: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = shadowcolor; - break; - case _sv_shadowopacity: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = shadowopacity; - break; - case _sv_skiptoset: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = skiptoset; - break; - case _sv_slowmotion: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = slowmotion.toggle; - break; - case _sv_slowmotion_duration: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = slowmotion.duration; - break; - case _sv_soundvol: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = savedata.soundvol; - break; - case _sv_totalram: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = getSystemRam(KBYTES); - break; - case _sv_freeram: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = getFreeRam(KBYTES); - break; - case _sv_usedram: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = getUsedRam(KBYTES); - break; - case _sv_textbox: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = textbox; - break; - case _sv_background: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = background; - break; - case _sv_vscreen: - ScriptVariant_ChangeType(var, VT_PTR); - var->ptrVal = vscreen; - break; - case _sv_viewportx: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = viewportx; - break; - case _sv_viewporty: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = viewporty; - break; - case _sv_viewportw: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = viewportw; - break; - case _sv_viewporth: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = viewporth; - break; - case _sv_scrollminx: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = scrollminx; - break; - case _sv_scrollmaxx: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = scrollmaxx; - break; - case _sv_scrollminz: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = scrollminz; - break; - case _sv_scrollmaxz: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = scrollmaxz; - break; - case _sv_blockade: - ScriptVariant_ChangeType(var, VT_DECIMAL); - var->dblVal = blockade; - break; - case _sv_waiting: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = level ? level->waiting : 0; - case _sv_maxattacktypes: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = max_attack_types; - break; - case _sv_maxanimations: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = max_animations; - break; - case _sv_ticks: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = timer_gettick(); - break; - case _sv_nogameover: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = levelsets[current_set].noshowgameover; // or s_set_entry *set = levelsets + current_set; - break; - case _sv_nohof: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = levelsets[current_set].noshowhof; - break; - case _sv_fps: - ScriptVariant_ChangeType(var, VT_INTEGER); - var->lVal = getFPS(); - break; - default: - // We use indices now, but players/modders don't need to be exposed - // to that implementation detail, so we write "name" and not "index". - printf("Unknown system property name.\n"); - return 0; - } - return 1; -} - -// change a system variant, used by script -int changesyspropertybyindex(int index, ScriptVariant *value) -{ - //char* tempstr = NULL; - LONG ltemp; - DOUBLE dbltemp; - - switch(index) - { - case _sv_elapsed_time: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - _time = (LONG)ltemp; - } - break; - case _sv_current_stage: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - current_stage = (LONG)ltemp; - } - break; - case _sv_current_set: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - current_set = (LONG)ltemp; - } - break; - case _sv_current_level: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - current_level = (LONG)ltemp; - } - break; - case _sv_game_time: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - timeleft = (LONG)ltemp; - } - break; - case _sv_gfx_x_offset: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - gfx_x_offset = (LONG)ltemp; - } - break; - case _sv_gfx_y_offset: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - gfx_y_offset = (LONG)ltemp; - } - break; - case _sv_gfx_y_offset_adj: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - gfx_y_offset_adj = (LONG)ltemp; - } - break; - case _sv_levelpos: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - level->pos = (LONG)ltemp; - } - break; - case _sv_xpos: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - advancex = (float)dbltemp; - } - break; - case _sv_ypos: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - advancey = (DOUBLE)dbltemp; - } - break; - case _sv_scrollminz: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - scrollminz = (DOUBLE)dbltemp; - } - break; - case _sv_scrollmaxz: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - scrollmaxz = (DOUBLE)dbltemp; - } - break; - case _sv_scrollminx: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - scrollminx = (DOUBLE)dbltemp; - } - break; - case _sv_scrollmaxx: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - scrollmaxx = (DOUBLE)dbltemp; - } - break; - case _sv_blockade: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - blockade = (DOUBLE)dbltemp; - } - break; - case _sv_shadowcolor: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - shadowcolor = (LONG)ltemp; - } - break; - case _sv_shadowalpha: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - shadowalpha = (LONG)ltemp; - } - break; - case _sv_shadowopacity: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - shadowopacity = (LONG)ltemp; - } - break; - case _sv_skiptoset: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - skiptoset = (LONG)ltemp; - } - break; - case _sv_slowmotion: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - slowmotion.toggle = (unsigned)ltemp; - } - break; - case _sv_slowmotion_duration: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - slowmotion.duration = (unsigned)ltemp; - } - break; - case _sv_lasthit_attack: - - lasthit.attack = (s_collision_attack*)value->ptrVal; - break; - - case _sv_lasthit_attacker: - - lasthit.attacker = (entity*)value->ptrVal; - break; - - case _sv_lasthit_target: - - lasthit.target = (entity*)value->ptrVal; - break; - - case _sv_lasthita: - case _sv_lasthity: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - lasthit.position.y = (DOUBLE)dbltemp; - } - break; - case _sv_lasthitx: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - lasthit.position.x = (DOUBLE)dbltemp; - } - break; - case _sv_lasthitz: - if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) - { - lasthit.position.z = (DOUBLE)dbltemp; - } - break; - case _sv_lasthitc: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - lasthit.confirm = (LONG)ltemp; - } - break; - case _sv_lasthitt: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - lasthit.attack->attack_type = (LONG)ltemp; - } - break; - case _sv_smartbomber: - smartbomber = (entity *)value->ptrVal; - break; - case _sv_textbox: - textbox = (entity *)value->ptrVal; - break; - case _sv_background: - background = (s_screen *)value->ptrVal; - break; - case _sv_bossescount: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - level->bossescount = (LONG)ltemp; - } - break; - case _sv_vscreen: - vscreen = (s_screen *)value->ptrVal; - break; - case _sv_nofadeout: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - nofadeout = (LONG)ltemp; - } - break; - case _sv_nojoin: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - nojoin = (LONG)ltemp; - } - break; - case _sv_nopause: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - nopause = (LONG)ltemp; - } - break; - case _sv_nosave: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - nosave = (LONG)ltemp; - } - break; - case _sv_noscreenshot: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - noscreenshot = (LONG)ltemp; - } - break; - case _sv_noshowcomplete: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - levelsets[current_set].noshowcomplete = (LONG)ltemp; - } - break; - case _sv_numbosses: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - level->numbosses = (LONG)ltemp; - } - break; - case _sv_viewportx: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - viewportx = (LONG)ltemp; - } - break; - case _sv_viewporty: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - viewporty = (LONG)ltemp; - } - break; - case _sv_viewportw: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - viewportw = (LONG)ltemp; - } - break; - case _sv_viewporth: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - viewporth = (LONG)ltemp; - } - break; - case _sv_waiting: - if(!level) - { - break; - } - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - level->waiting = (LONG)ltemp; - } - break; - case _sv_nogameover: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - levelsets[current_set].noshowgameover = (LONG)ltemp; - } - break; - case _sv_nohof: - if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) - { - levelsets[current_set].noshowhof = (LONG)ltemp; - } - break; - default: - return 0; - } - - return 1; +} + +//this method is used by script engine, we move it here +// it will get a system property, put it in the ScriptVariant +// if failed return 0, otherwise return 1 +int getsyspropertybyindex(ScriptVariant *var, int index) +{ + if(!var) + { + return 0; + } + + switch(index) + { + case _sv_count_enemies: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = count_ents(TYPE_ENEMY); + break; + case _sv_count_players: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = count_ents(TYPE_PLAYER); + break; + case _sv_count_npcs: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = count_ents(TYPE_NPC); + break; + case _sv_count_entities: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = ent_count; + break; + case _sv_drawmethod_default: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = (void *)&plainmethod; + break; + case _sv_ent_max: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = ent_max; + break; + case _sv_in_level: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = (level != NULL); + break; + case _sv_in_gameoverscreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = gameOver; + break; + case _sv_in_menuscreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + if(selectScreen || titleScreen || hallOfFame || gameOver || showComplete || currentScene || level || enginecreditsScreen) + { + var->lVal = 0; + } + else + { + var->lVal = menuScreen; + } + break; + case _sv_in_enginecreditsscreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = enginecreditsScreen; + break; + case _sv_in_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = optionsMenu; + break; + case _sv_in_system_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = systemoptionsMenu; + break; + case _sv_in_cheat_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = (optionsMenu && is_cheat_actived()) ? 1:0; + break; + case _sv_cheats: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = is_cheat_actived(); + break; + case _sv_in_control_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = controloptionsMenu; + break; + case _sv_in_sound_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = soundoptionsMenu; + break; + case _sv_in_video_options: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = videooptionsMenu; + break; + case _sv_in_start_game: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = startgameMenu; + break; + case _sv_in_new_game: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = newgameMenu; + break; + case _sv_in_load_game: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = loadgameMenu; + break; + case _sv_sets_count: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = num_difficulties; + break; + case _sv_in_showcomplete: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = showComplete; + break; + case _sv_in_titlescreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = titleScreen; + break; + case _sv_in_halloffamescreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = (hallOfFame); + break; + case _sv_sample_play_id: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = sample_play_id; + break; + case _sv_effectvol: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = savedata.effectvol; + break; + case _sv_elapsed_time: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = _time; + break; + case _sv_game_speed: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = GAME_SPEED; + break; + case _sv_game_paused: + case _sv_pause: + ScriptVariant_ChangeType(var, VT_INTEGER); + if( !(goto_mainmenu_flag&1) ) var->lVal = (_pause); + else var->lVal = 0; + break; + case _sv_game_time: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = timeleft; + break; + case _sv_porting: + { + e_porting porting; + + #if ANDROID + porting = PORTING_ANDROID; + #elif DARWIN + porting = PORTING_DARWIN; + #elif DC + porting = PORTING_DREAMCAST; + #elif GPX2 + porting = PORTING_GPX2; + #elif LINUX + porting = PORTING_LINUX; + #elif OPENDINGUX + porting = PORTING_OPENDINGUX; + #elif PSP + porting = PORTING_PSP; + #elif WII + porting = PORTING_WII; + #elif WIN + porting = PORTING_WINDOWS; + #elif WIZ + porting = PORTING_WIZ; + #elif XBOX + porting = PORTING_XBOX; + #elif VITA + porting = PORTING_VITA; + #elif __PS4__ + porting = PORTING_PS4; + #else + porting = PORTING_UNKNOWN; + #endif + + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = porting; + break; + } + case _sv_gfx_x_offset: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = gfx_x_offset; + break; + case _sv_gfx_y_offset: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = gfx_y_offset; + break; + case _sv_gfx_y_offset_adj: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = gfx_y_offset_adj; + break; + case _sv_in_selectscreen: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = selectScreen; + break; + case _sv_lasthit_attack: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = lasthit.attack; + break; + case _sv_lasthit_attacker: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = lasthit.attacker; + break; + case _sv_lasthit_target: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = lasthit.target; + break; + + case _sv_lasthita: + case _sv_lasthity: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = lasthit.position.y; + break; + case _sv_lasthitc: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = lasthit.confirm; + break; + case _sv_lasthitt: + ScriptVariant_ChangeType(var, VT_INTEGER); + + if(lasthit.attack) + { + var->lVal = lasthit.attack->attack_type; + } + + break; + case _sv_lasthitx: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = lasthit.position.x; + break; + case _sv_lasthitz: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = lasthit.position.z; + break; + case _sv_xpos: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = advancex; + break; + case _sv_ypos: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = advancey; + break; + case _sv_hresolution: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = videomodes.hRes; + break; + case _sv_vresolution: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = videomodes.vRes; + break; + case _sv_current_scene: + if(currentScene) + { + ScriptVariant_ChangeType(var, VT_STR); + var->strVal = StrCache_CreateNewFrom(currentScene); + } + else + { + ScriptVariant_Clear(var); + } + break; + case _sv_current_set: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = current_set; + break; + case _sv_current_level: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = current_level; + break; + case _sv_current_palette: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = current_palette; + break; + case _sv_current_stage: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = current_stage; + break; + case _sv_levelwidth: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->width; + break; + case _sv_levelheight: + if(!level) + { + return 0; + } + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = panel_height; + break; + case _sv_branchname: + ScriptVariant_ChangeType(var, VT_STR); + var->strVal = StrCache_CreateNewFrom(branch_name); + break; + case _sv_current_branch: + if(level != NULL && levelsets && levelsets[current_set].levelorder && levelsets[current_set].levelorder[current_level].branchname) + { + ScriptVariant_ChangeType(var, VT_STR); + var->strVal = StrCache_CreateNewFrom(levelsets[current_set].levelorder[current_level].branchname); + } + else + { + ScriptVariant_Clear(var); + } + break; + case _sv_pakname: + { + char tempstr[MAX_BUFFER_LEN]; + getPakName(tempstr, -1); + ScriptVariant_ChangeType(var, VT_STR); + var->strVal = StrCache_CreateNewFrom(tempstr); + break; + } + case _sv_bossescount: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->bossescount; + break; + case _sv_maxsoundchannels: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = maxchannels(); + break; + case _sv_maxentityvars: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = max_entity_vars; + break; + case _sv_maxindexedvars: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = max_indexed_vars; + break; + case _sv_maxplayers: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = levelsets[current_set].maxplayers; + break; + case _sv_maxscriptvars: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = max_script_vars; + break; + case _sv_models_cached: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = models_cached; + break; + case _sv_models_loaded: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = models_loaded; + break; + case _sv_musicvol: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = savedata.musicvol; + break; + case _sv_nofadeout: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = nofadeout; + break; + case _sv_nojoin: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = nojoin; + break; + case _sv_nopause: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = nopause; + break; + case _sv_nosave: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = nosave; + break; + case _sv_noscreenshot: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = noscreenshot; + break; + case _sv_noshowcomplete: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = levelsets[current_set].noshowcomplete; + break; + case _sv_numbasemaps: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numbasemaps; + break; + case _sv_numbosses: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numbosses; + break; + case _sv_numholes: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numholes; + break; + case _sv_numlayers: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numlayers; + break; + case _sv_numpalettes: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numpalettes; + break; + case _sv_numwalls: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level->numwalls; + break; + case _sv_pixelformat: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = pixelformat; + break; + case _sv_player: + case _sv_player1: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = player; + break; + case _sv_player2: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = player + 1; + break; + case _sv_player3: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = player + 2; + break; + case _sv_player4: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = player + 3; + break; + case _sv_player_max_z: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = PLAYER_MAX_Z; + break; + case _sv_player_min_z: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = PLAYER_MIN_Z; + break; + case _sv_lightx: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = light.x; + break; + case _sv_lightz: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = light.y; + break; + case _sv_self: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = self; + break; + case _sv_shadowalpha: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = shadowalpha; + break; + case _sv_shadowcolor: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = shadowcolor; + break; + case _sv_shadowopacity: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = shadowopacity; + break; + case _sv_skiptoset: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = skiptoset; + break; + case _sv_slowmotion: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = slowmotion.toggle; + break; + case _sv_slowmotion_duration: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = slowmotion.duration; + break; + case _sv_soundvol: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = savedata.soundvol; + break; + case _sv_totalram: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = getSystemRam(KBYTES); + break; + case _sv_freeram: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = getFreeRam(KBYTES); + break; + case _sv_usedram: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = getUsedRam(KBYTES); + break; + case _sv_textbox: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = textbox; + break; + case _sv_background: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = background; + break; + case _sv_vscreen: + ScriptVariant_ChangeType(var, VT_PTR); + var->ptrVal = vscreen; + break; + case _sv_viewportx: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = viewportx; + break; + case _sv_viewporty: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = viewporty; + break; + case _sv_viewportw: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = viewportw; + break; + case _sv_viewporth: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = viewporth; + break; + case _sv_scrollminx: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = scrollminx; + break; + case _sv_scrollmaxx: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = scrollmaxx; + break; + case _sv_scrollminz: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = scrollminz; + break; + case _sv_scrollmaxz: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = scrollmaxz; + break; + case _sv_blockade: + ScriptVariant_ChangeType(var, VT_DECIMAL); + var->dblVal = blockade; + break; + case _sv_waiting: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = level ? level->waiting : 0; + case _sv_maxattacktypes: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = max_attack_types; + break; + case _sv_maxanimations: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = max_animations; + break; + case _sv_ticks: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = timer_gettick(); + break; + case _sv_nogameover: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = levelsets[current_set].noshowgameover; // or s_set_entry *set = levelsets + current_set; + break; + case _sv_nohof: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = levelsets[current_set].noshowhof; + break; + case _sv_fps: + ScriptVariant_ChangeType(var, VT_INTEGER); + var->lVal = getFPS(); + break; + default: + // We use indices now, but players/modders don't need to be exposed + // to that implementation detail, so we write "name" and not "index". + printf("Unknown system property name.\n"); + return 0; + } + return 1; +} + +// change a system variant, used by script +int changesyspropertybyindex(int index, ScriptVariant *value) +{ + //char* tempstr = NULL; + LONG ltemp; + DOUBLE dbltemp; + + switch(index) + { + case _sv_elapsed_time: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + _time = (LONG)ltemp; + } + break; + case _sv_current_stage: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + current_stage = (LONG)ltemp; + } + break; + case _sv_current_set: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + current_set = (LONG)ltemp; + } + break; + case _sv_current_level: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + current_level = (LONG)ltemp; + } + break; + case _sv_game_time: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + timeleft = (LONG)ltemp; + } + break; + case _sv_gfx_x_offset: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + gfx_x_offset = (LONG)ltemp; + } + break; + case _sv_gfx_y_offset: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + gfx_y_offset = (LONG)ltemp; + } + break; + case _sv_gfx_y_offset_adj: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + gfx_y_offset_adj = (LONG)ltemp; + } + break; + case _sv_levelpos: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + level->pos = (LONG)ltemp; + } + break; + case _sv_xpos: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + advancex = (float)dbltemp; + } + break; + case _sv_ypos: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + advancey = (DOUBLE)dbltemp; + } + break; + case _sv_scrollminz: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + scrollminz = (DOUBLE)dbltemp; + } + break; + case _sv_scrollmaxz: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + scrollmaxz = (DOUBLE)dbltemp; + } + break; + case _sv_scrollminx: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + scrollminx = (DOUBLE)dbltemp; + } + break; + case _sv_scrollmaxx: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + scrollmaxx = (DOUBLE)dbltemp; + } + break; + case _sv_blockade: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + blockade = (DOUBLE)dbltemp; + } + break; + case _sv_shadowcolor: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + shadowcolor = (LONG)ltemp; + } + break; + case _sv_shadowalpha: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + shadowalpha = (LONG)ltemp; + } + break; + case _sv_shadowopacity: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + shadowopacity = (LONG)ltemp; + } + break; + case _sv_skiptoset: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + skiptoset = (LONG)ltemp; + } + break; + case _sv_slowmotion: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + slowmotion.toggle = (unsigned)ltemp; + } + break; + case _sv_slowmotion_duration: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + slowmotion.duration = (unsigned)ltemp; + } + break; + case _sv_lasthit_attack: + + lasthit.attack = (s_collision_attack*)value->ptrVal; + break; + + case _sv_lasthit_attacker: + + lasthit.attacker = (entity*)value->ptrVal; + break; + + case _sv_lasthit_target: + + lasthit.target = (entity*)value->ptrVal; + break; + + case _sv_lasthita: + case _sv_lasthity: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + lasthit.position.y = (DOUBLE)dbltemp; + } + break; + case _sv_lasthitx: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + lasthit.position.x = (DOUBLE)dbltemp; + } + break; + case _sv_lasthitz: + if(SUCCEEDED(ScriptVariant_DecimalValue(value, &dbltemp))) + { + lasthit.position.z = (DOUBLE)dbltemp; + } + break; + case _sv_lasthitc: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + lasthit.confirm = (LONG)ltemp; + } + break; + case _sv_lasthitt: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + lasthit.attack->attack_type = (LONG)ltemp; + } + break; + case _sv_smartbomber: + smartbomber = (entity *)value->ptrVal; + break; + case _sv_textbox: + textbox = (entity *)value->ptrVal; + break; + case _sv_background: + background = (s_screen *)value->ptrVal; + break; + case _sv_bossescount: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + level->bossescount = (LONG)ltemp; + } + break; + case _sv_vscreen: + vscreen = (s_screen *)value->ptrVal; + break; + case _sv_nofadeout: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + nofadeout = (LONG)ltemp; + } + break; + case _sv_nojoin: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + nojoin = (LONG)ltemp; + } + break; + case _sv_nopause: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + nopause = (LONG)ltemp; + } + break; + case _sv_nosave: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + nosave = (LONG)ltemp; + } + break; + case _sv_noscreenshot: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + noscreenshot = (LONG)ltemp; + } + break; + case _sv_noshowcomplete: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + levelsets[current_set].noshowcomplete = (LONG)ltemp; + } + break; + case _sv_numbosses: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + level->numbosses = (LONG)ltemp; + } + break; + case _sv_viewportx: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + viewportx = (LONG)ltemp; + } + break; + case _sv_viewporty: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + viewporty = (LONG)ltemp; + } + break; + case _sv_viewportw: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + viewportw = (LONG)ltemp; + } + break; + case _sv_viewporth: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + viewporth = (LONG)ltemp; + } + break; + case _sv_waiting: + if(!level) + { + break; + } + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + level->waiting = (LONG)ltemp; + } + break; + case _sv_nogameover: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + levelsets[current_set].noshowgameover = (LONG)ltemp; + } + break; + case _sv_nohof: + if(SUCCEEDED(ScriptVariant_IntegerValue(value, <emp))) + { + levelsets[current_set].noshowhof = (LONG)ltemp; + } + break; + default: + return 0; + } + + return 1; } //checkhole(x,z,a), return 1 if there's hole here @@ -9011,14 +9013,14 @@ HRESULT openbor_checkholeindex(ScriptVariant **varlist , ScriptVariant **pretvar } return S_OK; -} - +} + //checkbase(x,z,y,entity), return base of terrain. -1 if there is a wall and no platform. entity param is optional. -HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) -{ +HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) +{ ScriptVariant *arg = NULL; - DOUBLE x, z, y; - entity *ent = NULL; + DOUBLE x, z, y; + entity *ent = NULL; float base = -1.0f; if(paramCount < 3) @@ -9040,8 +9042,8 @@ HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int if(FAILED(ScriptVariant_DecimalValue(arg, &z))) { return S_OK; - } - + } + arg = varlist[2]; if(FAILED(ScriptVariant_DecimalValue(arg, &y))) { @@ -9051,12 +9053,12 @@ HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int if (paramCount > 3) { arg = varlist[3]; - /*if(arg->vt != VT_PTR && arg->vt != VT_EMPTY) - { - printf("Function checkbase must have a valid entity handle or NULL().\n"); - *pretvar = NULL; - return E_FAIL; - }*/ + /*if(arg->vt != VT_PTR && arg->vt != VT_EMPTY) + { + printf("Function checkbase must have a valid entity handle or NULL().\n"); + *pretvar = NULL; + return E_FAIL; + }*/ ent = (entity *)arg->ptrVal; //retrieve the entity } @@ -9064,7 +9066,7 @@ HRESULT openbor_checkbase(ScriptVariant **varlist , ScriptVariant **pretvar, int { (*pretvar)->dblVal = (DOUBLE)base; } - return S_OK; + return S_OK; } //checkwall(x,z), return wall height, or 0 | accept checkwall_index(x,z,y) too @@ -10035,15 +10037,15 @@ HRESULT openbor_damageentity(ScriptVariant **varlist , ScriptVariant **pretvar, de_error: *pretvar = NULL; return E_FAIL; -} - +} + //getcomputeddamage(defender, attacker, force, drop, type), it returns the real damage. Minimum 3 params (defender, attacker, force) -HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) -{ +HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) +{ entity *defender = NULL; - entity *attacker = NULL; - entity *temp = NULL; - LONG force, drop, type; + entity *attacker = NULL; + entity *temp = NULL; + LONG force, drop, type; s_collision_attack atk; if(paramCount < 3) @@ -10053,8 +10055,8 @@ HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pret } ScriptVariant_ChangeType(*pretvar, VT_INTEGER); - (*pretvar)->lVal = (LONG)0; - + (*pretvar)->lVal = (LONG)0; + force = (LONG)0; drop = (LONG)0; type = (LONG)ATK_NORMAL; @@ -10075,8 +10077,8 @@ HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pret { printf("Wrong force value.\n"); goto gcd_error; - } - + } + if(paramCount >= 4) { if(FAILED(ScriptVariant_IntegerValue((varlist[3]), &drop))) @@ -10092,8 +10094,8 @@ HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pret printf("Wrong type value.\n"); goto gcd_error; } - } - + } + atk = emptyattack; atk.attack_force = force; atk.attack_drop = drop; @@ -10103,18 +10105,18 @@ HRESULT openbor_getcomputeddamage(ScriptVariant **varlist , ScriptVariant **pret atk.dropv.x = (float)DEFAULT_ATK_DROPV_X; atk.dropv.z = (float)DEFAULT_ATK_DROPV_Z; } - atk.attack_type = type; - + atk.attack_type = type; + temp = self; - self = defender; - (*pretvar)->lVal = (LONG)calculate_force_damage(attacker, &atk); + self = defender; + (*pretvar)->lVal = (LONG)calculate_force_damage(attacker, &atk); self = temp; return S_OK; gcd_error: *pretvar = NULL; - return E_FAIL; + return E_FAIL; } //killentity(entity) @@ -10757,7 +10759,7 @@ HRESULT openbor_spawn(ScriptVariant **varlist , ScriptVariant **pretvar, int par if(spawnentry.boss && level) { - level->bossescount++; + level->bossescount++; level->numbosses++; } @@ -10865,20 +10867,20 @@ HRESULT openbor_projectile(ScriptVariant **varlist , ScriptVariant **pretvar, in // PType if(paramCount >= 6 && SUCCEEDED(ScriptVariant_IntegerValue(varlist[5], <emp))) - { - - // Backwards compatibility for modules made before bitwise update - // of projectile_prime and expect base vs. floor and moving - // behavior to both be tied to a single 0 or 1 value. - if((LONG)ltemp) - { - projectile_prime |= PROJECTILE_PRIME_BASE_FLOOR; - projectile_prime |= PROJECTILE_PRIME_LAUNCH_STATIONARY; - } - else - { - projectile_prime |= PROJECTILE_PRIME_BASE_Y; - projectile_prime |= PROJECTILE_PRIME_LAUNCH_MOVING; + { + + // Backwards compatibility for modules made before bitwise update + // of projectile_prime and expect base vs. floor and moving + // behavior to both be tied to a single 0 or 1 value. + if((LONG)ltemp) + { + projectile_prime |= PROJECTILE_PRIME_BASE_FLOOR; + projectile_prime |= PROJECTILE_PRIME_LAUNCH_STATIONARY; + } + else + { + projectile_prime |= PROJECTILE_PRIME_BASE_Y; + projectile_prime |= PROJECTILE_PRIME_LAUNCH_MOVING; } } @@ -11293,7 +11295,7 @@ HRESULT openbor_pausesamples(ScriptVariant **varlist , ScriptVariant **pretvar, //pausesample(toggle,channel) HRESULT openbor_pausesample(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) { - int pause = 0; + int pause = 0; LONG channel = 0; if(paramCount < 2) { @@ -13881,9 +13883,9 @@ HRESULT openbor_executeanimation(ScriptVariant **varlist , ScriptVariant **pretv e->idling = IDLING_NONE; e->drop = 0; e->falling = 0; - e->inpain = 0; - e->rising = RISING_NONE; - e->edge = EDGE_NONE; + e->inpain = 0; + e->rising = RISING_NONE; + e->edge = EDGE_NONE; e->ducking = DUCK_NONE; e->inbackpain = 0; e->blocking = 0; @@ -13945,8 +13947,8 @@ HRESULT openbor_performattack(ScriptVariant **varlist , ScriptVariant **pretvar, e->idling = IDLING_NONE; e->drop = 0; e->falling = 0; - e->inpain = 0; - e->rising = RISING_NONE; + e->inpain = 0; + e->rising = RISING_NONE; e->edge = EDGE_NONE; e->inbackpain = 0; e->blocking = 0; @@ -14009,9 +14011,9 @@ HRESULT openbor_setidle(ScriptVariant **varlist , ScriptVariant **pretvar, int p e->idling = 1; e->drop = 0; e->falling = 0; - e->inpain = 0; - e->rising = RISING_NONE; - e->edge = EDGE_NONE; + e->inpain = 0; + e->rising = RISING_NONE; + e->edge = EDGE_NONE; e->ducking = DUCK_NONE; e->inbackpain = 0; e->blocking = 0; @@ -15155,8 +15157,8 @@ HRESULT openbor_finishlevel(ScriptVariant **varlist , ScriptVariant **pretvar, i *pretvar = NULL; level->force_finishlevel = 1; return S_OK; -} - +} + //gameover() HRESULT openbor_gameover(ScriptVariant **varlist , ScriptVariant **pretvar, int paramCount) { diff --git a/engine/resources/ps4/sce_module/libSceFios2.prx b/engine/resources/ps4/sce_module/libSceFios2.prx new file mode 100644 index 0000000000000000000000000000000000000000..1f83bdc8f1fd0ddf6a56f0d5faa1d914e35095fa GIT binary patch literal 3200 zcmeHKOHUI~6h5~d1riJ|i3my>h>DMb4^RxC16qUxEtG{ZAt6vkQ?0Z>Ns1eB;m(Ee z7odrI;?j*(F&bAaS-Q~Zl7$;L;<@LZ)5i@3W8#KzlbLV6^PR`sb7wlY;o6?Vpj5R| z0IU90|6)1ND1|0M2dW5{N{l^V00f;DW5}?+#=4*bXUMWtYJ>pmf=){%Su(8Gu`cMq z2wA=qjps~dCQ#x89he~@z&d;9-G7pFmvz@~@(4Z*4fXq!Viln7_a(qqWrxdG%WtzL zaG?{*@LUBIM{A4h;1;6HPy7Y-z3tVm8GXXBNarj{oS?+{ zq+X`bU*g4Ike356j_SD|InIK0ZkC|L>BoiUXZaVS((~bOsVN<|;u_Bt4iMbWTrjT& z^>h6LJ6Is=EoSpn3j237Zx3|J{o9#Nyc!QCBaI8MXBJ*wi@%FC)tnl5@~eL6N7d)& zT`#)7^W$iT?eg6Y?2rx=doy;(^#1cS+TyWEFYQI!;!{B{e!F!p(P}=pT=)Gp^>z2< zsJDE@o;72w(Wo~Rn~V-lr@Yzei8$5+wBAGF5s}|r^&kQ&U8x$%OG=+&B5gl}M{;9h zL+8yOs=?p&iS1*EU-8J-x4K^2O8g5=zGrWK)^yW+9}VYyGPX|;9uD0INBRawg9G8~ zp}t7yCdcHulAKNJ9@(8^vuWKX4s7a=CFagT`h5G?Rc~_s&X~zW)>d3_=pAkE7)jh3 zxEpP6?rrXc`-!RfxHmqRN+fgF6SJx9rvjUOYhoBzjZa8`<7Mp@kc*8ag2zSdI!^C{ zBwp_ubUnM-M{pm4W@ur@9_9gU#L>ZA*6jlGXGVsL%$J#8W}ar=WyQBKmwNc}Ps1&IwL3=j}1nN@B)Fi%WlOtYAMxy1%2y6>i#vpC;~u8rH99j>iG! yk`L?W;?d(EbF;x!`u<3#e7L(S)O~>SARSZFz&PSz=KGjaeFgg8LxDfLW#JE)-l}c@ literal 0 HcmV?d00001 diff --git a/engine/resources/ps4/sce_module/libc.prx b/engine/resources/ps4/sce_module/libc.prx new file mode 100644 index 0000000000000000000000000000000000000000..e49b25d011281d52131a34d5a18106dd49605919 GIT binary patch literal 3424 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

~h>;ty=RCdbi z>{tsza)pX{Ds_jjuP+NgFgVtdlCFraph4~?N8J?9`ioMvmnhWnyQm)Do~i4qTX@Fm z<0)sZ=8Jbk%go3iS7Z-t3h~4n`croW@2mZl;~r|D3f(t}>*=x2+sC6acu<bKvPIsm!0fg{f8us zX}1iFr8oCOx1i9a`nJPvRY?BDwdE1H3(WWo?hY7gvr387Yd(4bhjFmf-D3^;2cai^ z+$2Gt{Ue?q*VW(!eSt*mJmQ?Y2&h3KZh?+kHJ*gyr2I7s9zYYsm_F5iOXJdR-s-S= z4e|L^Ag?4!g1Vo!j~kBOTK<`3xj*@B1UikWF%sO9KdOQ6y;7Xl5|7+coKp_AJ6$zd z|Mj{iwE6;R71Tvg1ZCC%meF~|zJFYTx+PY~(KGJeK6oYmfBwdld{RVw)P|^bJVhfk zRTP6XDFa_T4U;Ds&sh+JkYd^BEE4lWEwZX4J$e(9F66oIG z(d>L>j76KE$eu26RMssb=;WNMLrgE%r*L5Eeoj}p zJ19sB^BW2$ju#x-M53<7^Kblxr+PrxXHc!U-4#R7I1MhIdvED_oj!p>K*jDN^@Ut| zlif@ID(9$z$^j_%9iSzSCn$O5vDt{&nK?1OPSPyX6e8o~naa3f_O1x}XQdPBay zdufb9JRwqrsmW8YrD@@AFYuLU%6SlJfaXG^2jSo51^BX3*ZAveYdAKzvfD(nF* z{(INr^07SEa~|7v=lRjrNyeHt;L|TFz=btAhU@yece%a)3in+vM?!Rl>i`s;tPSD> ziD_*_Dpnk6SI-QoZ9qa!1-NJ_0-(iSmna|J!@6-Ft*+$B3*^2ZYmx%`EzkYpuH!30KS4uv9Dk@D~TXhy`*`b{D=d9gusIoYJe z&g6&rOG{Rho~qO7niR0L}RA4zzVaRl>vv9^HN$>x6CQsS`2#U5!Wq;T^u*q^oJn{THw&A2`#XCd}3 zrNY?Z;LDE318S;3tJ1AkAZUtH&9!{?Y34_F{97@(7+~c1uIGEklZo*+e1Aw!2kgS3 zkeuBEVCpSQ|AsFU1r+aV4b|U?>)};p=)asyIUb!85?I>p_8-Z0aZ_e6>4!TF_tgE1 z;5Hut%oq zJ!}3I_rMQ=%sv5BT7>B*sKZ{URs*nsHOGOO_|z8!(c3DLwWK;Fz>lVR zJ`7Le)jO_PPZ1~WquUkT{FGi#&BG7G%9N$@fBEP)6sPu_-t<}ouSUssaJ%A_%hD{* zuYaqATZ1iCzz!rua5V?}B&+2+zA*_N)U)Z%+D8w!og8ITltlTVe?`E@>6p*8xoqkn zgU`+~vuq!p`NO2N)U8Tlc31zt-@N=MJ68*8cACiyAUZvKN|?900e?-7-EwAK3o|Q} z_aLV)@R|gLWu_&i@{Oarzphe$dLTF9xKivN%v7TmA0P68{4FQQF;PDCLNO}5BnPcd>QqG&{pRY!j58QCo#>Zt% zP*qHdG!*;*xp(Om<{({Q2;$u*C<6aXtG&n(GifQQ;Lgt0+P5dz2S@HXNin~qNn5jxK>8N zO~g~nj^w*`>#I)NXiexzHW|jNdxkrV+svFi-CcjE~ zZ36UY)B-Hoo5KYk4SyS&Q!$I$6jq?WQXvdY7o<~#Gd(@$pID_&7{tMU7N^HPh=KlN zAx!MeaZUZY3XCu4qom0SGC?JW00Wl+e+Z-};Wp6Wg(%E~daiFUOHa>TpFERT|MtC( z>wR~99Tx*(`cH-!_$5~mjoCC=0GWvhW--F;?t7UoxMJ7B^puac&IxQW;(P~8nC7nn z2cfPU@*8nOVtU^*59ozyKs&^&!AC*9c>{>6ov`xRSLJOdU3nm3xiu8Dr=pIHxTH-? z*q_QK6_gXHVo1_$W7!(_ZzFpOv+6=EAE@5G`c~{^v-!oU!9wy-Ff~Wo_2RjDd`Jy6 z^A?DvC*JLKj zQQNL*y6LO9())WeXlRv8@a1aP-^scxMd!~384o}mvd>0+XxVQ#emjJ^IVc99!y0kB z@G$Nc`r_)L=>mkpo#w)m7Ll-0UKBMVq6LW{D8022JAz19>a(jdf-~L=j1)7%(SCm^JWs1;WCbQLYm06*EOz}ywb9Y@ZxJZ1sOMe_apFN>Ea2sk7Y;$ z%E=69iWH0!StvJ8U^lc!oK@S|4V+FvXq-8I;K^xWp2P=NoVU+1^KX9U0!e$S7i+G5 z*#pjT1Kr*tM;XuMjGcA8>0E6y2Qf=1f6EK{B6qZ(^y8nDmll z(4&m4WT!?4lcTITvHAxFtWtBQMoCa#;|-oURFdMLxejJRn37Cyphq&F>_9E zQ~Sw{r_!8H9XK-_rpPP$9yo`mbBl6NeDl))AA-*2$}+;!40{+x_Zh0)cKl zbG5)qT(Lo%YFB)zq*&u$sn>L8bq?mi+n-;sf?~zl<$gFUJ(RQVl4Ct==rm%~B?hu$ zB6&5NKzf(3foT9(+PmYgzoi9WCwbT&=5)`!$2_KpkUvM15-D@Vs`BM8250=K_vZ?# zPsY64v77LPeW-HI_{~&7Y?W$(PP{XBbq4#J8U@!PUUvikW<9MbD~D*FK-Az66L$sF zbWJwbt9?_yf8Nb-?vL`d%*T~nHdD`nsL@(f50yzi3WgT5cAdzVyCw@@-w9%O+=5eXb@UtqoNl~ z-vpkfY7yyQ!eBvtVUnCP=(9K0kH0{VFYf_2?tdgL45t`iouGRn&)%dkweDK}!^MW2 zHNaNZ=$LhgAdX({>UnN9O0$3axo`{^))*cRhD?4a8)n8hE~co2@V**%kuY_Jn`+Wz zvRt>V<1=H}Zz=2P|J~`c-IT4T7^}VEA{#X&8tF3xqBJy`>)@WhLWo=lR84hZT_Dzp zkrX-)jbsDpT%D<9-YSjO^u(9eskq>y%)d{Q1yANMN~7h!I_`KhbrhviegN42+(^AHsl>OleLF#+uss8}SKq1_>V^t^CM>1Z_ruXGMmrD=SI(k@9 zpaII@J!M(GYYpJi#{pm`zBHMIi+`?~KR zBer}eF7wg!3XsF6<3cw&g4b#3Q&Pdt_p(2x-;}F9|Co=Lpn9>P`wl?@^35hN1(-gN zR&_XqEWYOuTDv*Af(;K}b&R>oPvoK`z4Y_dBi6py;1(yt<1Eu>Bo8X@n3Si#GhqGX zj$NpMsz{GiDCPNRoG@hLI~~LSg8SxNJryBSDk5WTQW!Qx=BLXQd>;>-DLAK>w-k23 zr6Rvr(76swV}Buf8okBLPi#Uu&hMix!KV#3q1Ce7wFH1l(=XII3J<=EQ?y~KkNX`^6H&G3k=A0BU0i$Rb{B$pTCH@_3m4=Kxh!pu>)-aOWO%Dwxi=| zVk+rIn(fBH?dj%?Q2#=f_)qNmsrM>5Uuy2oUD}j!^pyPcTuk2)cbU4`kp9Lfa`VO| zLpxO1oEERCLHtR9@{KxZrRuss|AK+FRk~#*VTFyb>}C;L9V_m7_TEEsG4-jwH)rLv zZ^4BU3m14O17k9btJvvy8<1Ulk5`*OyLvn>)K8mV)$f6mK!HNF)fKOuR`Z}R+>s(1 zmVtDvuUj>@v`b99aH|3rcJJh4vF`O&V7JeX)2j$Afg0e`(nh7#N23d$XztGO;>mx2 zsLdyZH<@n*x&|E2`9-o=!lKcnU9nR$6gUu<1qms4p#3{hsc+B5A&A_s#{{+YtrXoq zvs*Ho{w1oqM4!G2^=QAjyn!#M064HfNfgwj8$1?BYXCz$30dVN`xr4ESSF=%j$&^5 zRw5*=thsNtHPkb7R(py4WfW2M86&$~!*u-eu{nF4%;}||D#kuuDdNchl=A#H4-yuB zf&JX<@(c-imY|J{=TO}NgoR!lli#+X{l%1px<^&Pdh>mky{H|1XRnHsvmXnmXI#6+lAZdL zu;)hSs)MD0M{>R5^H}*?Hhyi{D6BN6o6hq?FEnCCtw3b=>=PW^A{$$di<*=dBCSqZ zq^G+jt6BGbAYWu8_D=agn)uLJ_ivWtm)*D_f@6F6hv>oQ1YEdwj)ru8-j@^YJUp%^ zymcy!O=Io$C{9}}CR0ebCLGq*6Y=}99n-6-cy+vqGd)i$$a%>61FAN|SP7^Z`bbb^ z!HM1$e)$lBQMm@0=?djVn0)YMcf0Yd(@aDC<8iJ*PEO+LiIc9`X-QVk>-1t>kX_((~i@{{hIC5*Y@U_ z5|(4-m)7fK$Zc*=-7BH>7yRFS%1Dr`&p=@X8f){qx-K)Yf@VZ zdc5Lbpd-{L#Wa^Ob(W2=8t<}^r}RpA04zYfDDP_e^)KtS*!sOHxo?wo&mToNasi=p zr!WRCFd{v`P2{z9{=2RYnN;5Cw72l4vSlFi=eCsGwPZv za-BG9LZOW4|Fr;xJKj3CWw9}-DeN&J>I7q=Y=hp@92T7?`g-bW_XStBrO>5ij=sAR z=a^8Vac#LTXc!qVrzxLjg8w^xz_ST7ZOyN1|ii=u_eYh2S0nmzVr;Q2z`AoPX%s6hT(a|-9)tjHaySoCl9BHC{3EVEQyEK=nHwN z9yC!FiPe~C2yJlhh?%&!hDGlgNs_I^mP(VYY?e`(z;ZZU63Y=hdlB4^EFxF9O>>Eg z3*n;ZeifBa9G;4bk}C2-Ho<%FQ2JeXQ7t^(t>+=41tJ1QyaTY3*fZNJU$)&)P1X`L z^CL3gU#w7l=+Y=`uSUFn1zqn`UJ3QO=m^7Q?l}7O1&#qtht*gAs5+a6>%ch1Z^y!RI8?S_O2O4ZXK@lh+tlt#Zc(_YO0>BvdE|4dfM#Qgym7hn z1QnV_K&^TC^tgjt|`AJB=kGFB|0sqp)U(LYR4_afOst~!~j zy%H(%eM11(amY9qP=_`A=zSSfe;T$oIF_StZEoE;I&%{6T(tWc=RC;$MXjK__Vl)` zwB(h}dUIzslglacLoF;bLHAXt)tB=<7Hp6$U`}xKHq;c>tRv{wEtqZ(HT>gqL$_31 zwRod{USiv%m6oZ3D%bv)ZpJFfI@Ex(eNn(~$Ad?I$HiB;Tku|W=MJT1!I`9|&3@cU zm$PRpBoz`hsXY!-y@}UtvCn576avY8@8;3_DPL+ zA8_-J&$I8&P9EH+8PJzpz%s$eKrsO9v~SsYnb(MF3Z)LoPi<$uUc~;szZ0rX($RHk zHSxZq@EXj6%_JT9zJ$EJ(Jbp&%M z%>Vd@_Hs^L9@!Ewo*dEE8>kwcC8-`c=&;3Oqm^19h29~$l>dsTc~lGhxQ1R#@Ko_o z{4Ve?ocrSrdyEnD=crnJQEQjy)uMg>_(;@GohlDmsRP!YOETQx)|i>MKsM z-al2yKmq(pzn1GMq>>KFiU>aP?36vD*%^YXi$#(Qf6|WxE!Q2QR`bi};2*B#aY->P zMI*d#6gkb1|H^NZliXya5z>6t1DBh`uGbdGli568L#ZQqN^wU~!7)o4UX!YHCCVxS zMCY=LUgO>|=ax)z%UhQCAnX65>8shEaA*4s#N&h{XU1ZPyaq>>+Rt1fl4Y-1J_BIfM1`G*I$}DlwhBpl(uthnCk)0 z7b3O_NE}gW`1Er(kc7fa+LJLbH3}MmMg6UC>=vt}CQ~C?XLK)o(8jIb`nOyL+W|vj zF*~q@B&_i=&(C-`8ljvv)(oKup;%{xx=VhDY+-O* zxM(oJT-qU_V3RY8Xk~gjw)lV(>2(R7U}ADC&Z3#JzwpT-Vn1TeWCp#kDdD{AJFdtc zv*Wkt<7g=7q>c>*3A~x_wN`xesY<2kf9LR6gCXxJtmv@lFzP$gE9b+dgp1D7Yl%TX zVfG#Tt?%W!v2N%M`)s-T#&m>^kq*y2@aq22o&+npT~M;jGroH1wDIJ*N<}Dj%xnyA zpWmB@b1RlVblkPFSzc<6yk?0CY5En12l_V?+@|3ZBw7c|BrJCe+N!_C^RHp~ytgJ; zU%6GUBwk@gbe#bRuBd(^KVv)C>^0{-(HgEV_C9xWWF>%2)AxjuEDMRA;Dso`QJSE) zgqNH3#!70uf~0RFS|M@@ss<>f)Ga+l78GH5*4oZGY}RY*HA|}ek|f*1qlRtm+9ZBG zlit|4o{3ML*j6o%M7N0FCC@;TbIkgYDW|6%~|CUESt3Xj; zJu~_5l>7V?Co8Tmp;AA0Z6pIX>$m4qUdnKHb_t0PIJzGVQy~W9-ty!fp)}XOf

5 z6Fy54KE*p5C%SdQX89`%;u);X8kU~~@yU7AKTglcE$vV~aa_F?PVxc@53ITINYstQ zM6nbcA4*ikfNHM%N~Ba-?hz&Xs#h)kxfy{pqUDOVrgWU3F)=)3^vaIi@Y;3p9k_ZE z@zTGRDmM!tuQRa4#Ks4<=aIah5|xj;-3bFA4|%^e^+!-a*ytm{-iRj(JyX$`lGM%9 zb7O&_tF*^(5-9Od^pF@ozSObMnV{N1i(Kj2j)yMc&9QH~srd)Y`Gfy_;*^uW>eG9=vyDCz`8gWdQfVklFuNlH35mY*8Tm-&nRtmSv1KQm`@Be9V5o>vJ z7~JmMeb6+iY+Ch17%y<(S!= z%qaEe|2=$}l5#?g*31O~6^S6q$_e@8a+RAB6n7Gl z*saGs_6>;aBam+-@?Kg=bvP8czoUY1JOXD1SmGAJUwyy)DB7>+XC`h=`xlLJr$i|c zf!C=pJ@kssRZ6-`d}cl6*Nj>Ri;o7&LP>uqQv9kgpk|Cb*@*z$ z%-A6Ku5^dWry#b(^mM}sRVVQ-7iDlv$dJ*sNPcAJ6Ek;aWKCDx z$ewi0yxUj%%8}_TLgep?mC7l+gm+@F1&{L*vs5Mb}`f2Gt6rpT3dmgZFz8FyO0cP~Rlb zV!F_bEVvxe_YIcv4fg)RoHh)`kH#*)aSi)GvIKD_$Q@~LF{xIqI44pWR4dSYJ`7Yc z$MUalVYs?YrxZZ(7Pf!B(PtSc~Fjs7O+(Dv%8*4!7@?g?4MJC%G;pcnP z^(yiEvzhvYy}0K&oKAl9>C}>^p}Q|VKOn-Qh|=>#O(6j+by(xGO;?C+WdubJNdiAH z)3_&j%pW{ZHPJ^6f&`!qZqRA{`xo4XMOJ^Hb@rWfMP`*SR|obHev;mj;^?zL->R^! zHXS3UB;>WdRC1ha1Zdx&N&p{gp>)oxCOctnRb=hqAv79G@KeH|Ck}W8R&3 zlg;L*2DbIM_=C&^hRRU?=~DSmR@B8*0M?iC?hzVhc@4z2uD&}2v>UTd#?ANOSdedx(0EI z?xh6YHElrhCgnDU*tY&sEBE8eHy|O^MDX=F0FVuHoHuu6)KYu_uB9)yixLycr!rUM zH#>4|s{Ea)7Y(G4GKqgGwdkB;tY!CJ0InGq>Kg&(ihy`LfDZG9Rpu9lk)fz*TuZ)V zEClr($7r36uv4_!#Afz+cwgXQ(YF#WO+Y;`S>f0IdX{i(gLYZ?%|wF!G+$~2;ZzRj%< z!CJqcw5~n2-Grj9PwB%T#fO*}iSaF`btMiLuwnXEl}^A1sn!tnJ&IS;2eI3#gJsyf z3M_sT&^-9_(Y)^0$B%akspu~Fgt51rlq%T#O<2wYB2wD0aCs(L+DNthXCxeGiH0AM zd}{`qh1P&sOF$#hX3uthiSdJvZTsF`p%8H2zTKXvZp}7D3W>_NXwo9XnZo;f6M>#@ zW|WC@56yk!2V>l|&^>u+dOQvA9OW(F8QC;S&ItPPM!RXA>w=qhn$An_LlKB_6=m z_f6U*Nk&1&$A{Vx_fj(Fo84lSX(upo1=J7+yNbvgP5lE%^Z`Sx{O zgI--jUJ}9mc|Hm$sm+AW5{-I>KRd^zGPk84+(?xC)rwFqzY!+XJOk=8!B38De>bjV zfS#4c%FGbvEu(=cgq5q|5JJfR(jUec)z+bws zdb94h9<2IxeQF=7UY{1@LfHS<%nI7_a_V?0RrJ3R$O~MSF z*bkve#rphDS!B_&U@gi$(#zgbwAoDN%KrcswLO4LMo(K<@u`JdKywu&R3RNngZM&g7lg`w(1-7GR7vi$^29J(zt6NF!uY+m%>dY(8a=^vk>V`*eY0 zksOWTlRg0`)(A?68gzeqg8%v*(>pG6Ldc7#yjQrN@3qPv@c>FGHbu$Whp{k!pb~Be zn2Wim><;1`fl>1jktl{8l4o41pa_gQ^6>8+b>M~7{vEu=os~yWEdg;&!5KdHQ5a&} zSycvm!#3N1CXin9p1`S{1V&>&P-1^P32ozR0nO(!6ySSEIb;wA)nn}@IJED2_*+PW_gT_2k0^<^)IaM9~_fbO9!G74%)ysvysDci}YHJ;k5HdV7`} zuV>5Uu5AMx%~o&mk@^pH^>hE~O=$cU_Jaw=-LoJ>T|f2-k?@;M!<`0D5elafZiK#c z%sbhT{Ja29tfUYFK%Wy9jkL3VGOs+)r+schXExnVNdzY@Bal-NAdg^GOVM$M=|+{R zSldNxKnjiVVz|}zi1C8!QLEW6GQ9#Z9%1--T?RA6-W{7g&iGgT&-Skn6P!yhWbdni zXO;tYmKo+zmu^^5r9QhqIsor(j0e-5K&LDT_{R9GjX^dZZbmW;0h!O(7aHprI1|7? z`U!u6pQCmC^a3%<6CkGqFjBPv@cazSK??}%)AD;3$!a9Z$yOgf#>!mf)irpkPBzcp zD2Y}U$eO6bxyYSw`tTE%;TnSa?sFTK;5vzL(Bp?laaI(HY=rL^&WJ+)L5zp35N%NZ1y6Rb z1POYeL*=CMZT$kVAHHK&PWkazy#c(`_W?e}nvbb;FBr?YYOrb|l-W7eT5-gm_*82Q z`|5<|(nyD(K6KfvP5?8=#;PYhSI=&+{E}a&KwjhCj>c;h^J@(3n+ZZLmF-m zfy4j2jk!bk5n>6PJEM=l+JG-&fN1XCEJ9|e-B0y*wDg!+x0uD0f-u4`3VkqCN|M}6 z#WIn0FG5E{*N*c&a1FyL8op|ZpT`YQCrYX$M9S0`4nN+n|5IQZdR3n_koiR2M%*7Z z{342C!;j(NM|tGrHoD_VB;hxqM0bWEpFoq{UJA^XCba5^uQ!k*4MVDeb>4!o4MNN( zV6x7~FFN~AoXwEm218}PU@E5(&%nKx$;+8*6`aN#k(fR-mppcRP#Q8%t*gr;Q)NuI z_I8olBT%uZf6neOiS!%lTqqf@sQSy2ak^goRx=s#p}*#od$@qK+GGE84yrI?vLqG5 zO$krd^|`Po>id<78w;EMcB*!;pB7eh;SyAECSEcN^SugTaKPXm7X@Y#k;(py^QsR; zBOo%azlXZC`5VdS24i*)Ep*%RbG-G-g?pr)|6=;}YUl{Uj6(Ns$gO4H?Jt!8K@Sf` zA1aeaCg9;L{<>7!ftXs35{~CVbc!$5n#2QNI%?$zF~95HTeT_(8eG;mRuP{e@~=lS z^*njQN^REXxk`AgbXvjj>|-5~zWVffa9W>`Mz*lqmi z^Wn~E=n`A`%ESQ$H6>n&$@8VOsdV&?{&-{L9|C)3CtoOIVC&aoGCF~+l2U#-V44q? zCIn~BC(XwjfQeiuvH-j4Hx?0#g>XWd_g+kbA zIsnK%MB}Nhlj7H3&ElJH#O}R3ke^82vO97dgoi-4L+nViHXd$7Fey^)fc+hRQINJ= zi+;(f6oRvO}PgdRPr%zMRn|M2$Kzd()$=wZsaqx zw*W97E!iT#`vbqgxQ?_@D*3{q;Z#>x%ti1MT~R0yjy|r$P%dHRRyFJs!3VI} z%@B@XwadcoX!p!}+z~@l#8t2JwE@L>cP+z|LN+FzLq* z@qDM0v5^x(`TSRkeS2Lh^6Oh`gSv|Uw4(8{f8d6CSw;UH@(t>$*Hh(RdWRUU1pKi* z?3|-Ju=x@_B1q!+)+5m)nzH+OE;h$ef+k`VDB{r$w1r?i&+lLo+t+n9`%%#te|$JP z@WZ50lDhpmO7f!&Gy1)&e{B>LSE4BHbcj@W>x5mgOABe~tecl_ixw%}{%*v9Prx z7@WcU)%~fh)xry%SBZSi$5KY`dW!yxS^=_&?vd=}cvFRJB*&(hDD#%RMldM;cWU zAEPWTE@&pX3#sP>9yAezfA|Wn_(f-UYG~!JOkKZPfdc|OX7vqUVlOwL-Y=F0yr>eb z2kV8m8mE7^OEIIf7(zE-axAW4<$y8ZUS|geW$?N zn}yd@vC9r7jW1ZwE)u$)TJ3Qo1)euNCG~zhW<_9iG`5g4B>X%u?uwKe0He&$0k{P^ zMJW05b4=ON!TU*c2!B0PS^}%3bc=j)`s_v3MZP-s+^iC2p`^7j8{5Uzmg2&Dhu7}pq|6R6!#k?ew!@hcrxBQ6MzX$Jq&J9 z3-e&f&1@2EAGGinDu)#1R~l3}wT5rMEh#oQXaDZ8H1C3u_O#-U4iVNfiv$!yEd{qO zk((MXAvl-0*0}b;!jQc_J#S>oH!>3cmMho8;LZ7SuMOA<+Z;&3Z zS-(yt@#1aE^79h767#AV!{EK6C{ERDTkh8Cwyf+>Fz{#BErL@ z>g=fh&jkPtKO=nj6VSloN|7hg_{SF4!NG%G3Y!gs`*^-)wj zr}d}G=B3K+|F8FG6bd-gZSDO2y)2VGJ-aV)y7ZUF?tLyVrC-R>1Xi;UdfJa!r^I{L zFSnV~x0MK%`(t17%muW-(bf0(^l1-9z^pk)7-7Da7LpCyUE=PAQ82zKe z&&~ezGv>BOuYX^iodnO`TGCt%kT=({Nj4{VCG5|B#4&feKF7mj7dD@NPCyraV9C2f z*;h*?$(v?UL`Ro{>ydm6bNp$`{W88cr?v3SQd+q-$nxTGTag2;HGPs^I0ZI%H07N2p($n75|IqPgRWg zQ#H`LFLsi5hbpDZ*n0h>JG4jo z0;NRF{5`Z^0i8oprchQo*zri{l z!rS18XAXL0s@1f2=DuPRGY;T*2Zr5QBc#zhBk!dK@Src4sT|3(&BnoL&IsumL4CK3qwel50Om8W>b*`#Z}MH3hM zE7dt#`SQQ)r2S|f(+j<^C-i)EMEbl_590EZ#&R~i%1|%e!wtQFuO?7H&=1bSILNQz z4=z5zABxV+L{5XH8V?S}h!jbj5&PL_a2m%stM`tF4nXy`r*GODQ&S8BQ9x?qKtBC2 zac5lvdve9p#5vJV2Q;at252z(r|d~#OutSdE;__$dtC4Gp*M4KZ_tMB1!c%(`vyk4HsZvDHbGciU!lzPo z#mi$URqJG_AGucG8b%uzk=aK|tE2&lei;UD{HN~p6i<(JMndcyrzUXlNjhgcSaVH5 zm`VBp-C^T$>YpU-y{d{aWyiYzvP~F`d<(?oyz`4;>8h7_Vhw{+YI#)5&LV`5I-dYP zzIWQZ@z*SZ)JpeAHjLp24%RLN-Au20DAeiEI!uHZ%W-H6G{@lG;bH-wP6$Xm7kjBB$`O0D z``zBr`m8Aj_4951Qks=+^3AT0gA3&yKV?r$sJFlVdw-{@C}A0yGGB5`h3}zJ0~?hX z-Xm%aJMJ%reHLE~AG@l8s6U&R( z!9@x?x;)6>9kE7?am*)ZiP}1;CL>)YXw2vKPffg+jnkx4MNB*9qTJrNX8H=e%PZtq& zaawA{g;biN8Ebx;Q8NY!a|`7R_-V*X53;@(&_cDkY0qhz{tx93xNN%x)t`WM?yjc) z>MY@|$fOidFYsZ$8_al&1RIwFmzeVI`^yB>?$^ba3<=g}+lhDFYU_2#LNHS|wR*E5 z%jc!>$?qy!drPV=K;RLl43P4HS5&y45sMvn8uVIc?63mD?E}>#tBqJmarq}{8h*w zjuK##9dU@IUqVn(@m*ptcK_9_-=lj!``fk&Xr5oPz@amy>g6Q;LVx==ddU z#Vo*E06FV;>csi z14a%}>b-9iLuQGsod`PlslR8FYDui-6O2LwKH6?CZg$Tp^#{bc_m#Q@S zr4sT+eAU!ro&5SJdnD*{R#xyAou^NEHitGtzCIb&^Lx{vpFkEy`~zV4*)`hBrHJZA z$Y&+_m6ofD4tp=<4<I=iHtu@7IYunVr~U*BJ&SI3!&S7nJYk(d!D~s zKasgCnUHL%d(F!1f~W$sSDsaZC$d+!?wZLz(_H4xAR=if^G!H3{b_cL5JoiCyeFTE z^e`D;gOT_Ca;M4|QcTl2{o3P@-Fs%?mX=h-ca+|4fJ){INxxo`f6h1Lqhejcxcpm2 z%U=SU&A)T9|2>H&>_bM_y5;?o_Y4HhHS%0jEno9)H*D*~4d!sV1)8jlX5%qA5jROH z84X#5*R}2TY)h5~X@YvnsG@%)@aKQ)X?e^cd*zSG@V}UT)TcG}gDGm>?io#rm0e;h!Yyh1i(0-9v zfnL;f06J843wU@=V}s#-AlVy>_gx^lKrax7UKp^REr=cee48#)+f*P$(TT2MpRloH zh&sG{ABJ)KRRbZU1*HI@xDCp2tR04<86!WkcwLu}=UN6@;iY{#oVD38PoAQs!+~$V zM3x-d2p*J{SkDoX`VOoAk^Az3uW}V(dSDFQ3i)VgTXVfR&;Ot^s=v-CWo?j zR9lxvtg31pl`$aWU03WU_8L}lSyb#okXkfDY2{QhqgF(p;H@EY@LMd|`W|TQ&UL(6 zNFiGB6Q&R$n|Fu(d=mC(AJae;sK<|tKz}O0`>38SMsic1XDIdWG=H&~&@&Y6pd+n_ z{*EKoEC;kvYJmII-Hq;osy7>Dm1Q#a`Rx~--@i7{FmQef$F&6-v%mpNN^tTfIBbRM zHS&8b#y9UquD8FPbw>o3lYWjYB+naX6)3HpC$%Z3i6Jy6UvJ@9+QM8#p=1ASyp$;K zUN0-zrVvt&E_O(cJ|I@0TH`N2k`m4|HJ#H|*VW$0E0a$t>TXN@FvX6)KcdgYdcXRB zc%j{( z2W-RZDiXhIxHPfBFZBdHCxzwGKJ(2|RdVZm&;1wA*8qy;q>!=5Gqvzq*=wp#^HR5F zBtEtuAKJo#-S7MZ&-XV26xh0E=@@2@h{qxbw=)3UG=MtOYv|2Ht8szwz!2Cmp!P{Y zSHusIs+OYkhu6oY%#+gBg^~J^&M3i4)M_Mz4TX+l?DmO5trLM-2*geVkw96_(bN_&pn&4&M*=zPszmRrFK!vHeI9SMW{fN zLy+P7Z+RG1D{s@l&+jj0IyamE8_IY_MEeorh6gAS!xnhEjPgqsL-+BKACa-ymyt6rIkTJTIn$| zu4N?%)}n12FD-dI-}I0g{-s@h@If^g&ir0Y z?U}Fif6p9Z^56L06MpZnw#IpE(?-@LeP0BRgggP)|w=@%MKucVI0=nV@bUl7Nv zs4+~X{3afwa{Lf!pmF6a>G|&Hj@|(ccJL8Dk95w?S=XdL)lH3jG(Nxs{G!W$M?*5W z&a(OBYY5X3kLcP)Th0N*A)r&<7@0!a=bVOtl3~!2$O`2ZxFt)d1+KN8X|^^#&UyJ# zzIk8`Ur$x%{)`YjIVwE#+5|nzjv`jY0xr7*k9GulLU(e1AJ>mnTIo#xk^SpPg$S4o zQBcE7yk^;RC~XaX%SRpY_{H@^hZlw;DStyq|9EvddjEz0hqw5fgR~Wy>?PipLw_1d z@eDWDX|%&M^_psMTVvv7A4Sb$EPy?C>(G5L8%EribbPa6A$1|e*wn~)BHBc@b}D+| zgB2fx1mk@4qR(w>13Ot2}V;^zt^Fh2eeOVtq5$#$E8-s-D)0#v)nnEB`vNSsb;e;%Ck_ zA4Offtfn5ZEFQ~W)|fu7e*n8M%(ULh)}z$6fF+=$Y%~DoRR5t&bmI5F?A<(#C0OIO z_JMX8cWRDJ>wis-js-${+36uAdaeJtXk;sVrTqHWh}tzg@~xd7;etaQ^Oz`nbj2`8 z81iT0^Ql5AxqqycU-$1~Db8(!c}3Bz&8ey`Eli>*+G!tyuf%uR%G>ujqEeQPUz ze~-8~t_=QfcC^U|~GIr`mwSBC8N^#Lsd;uFPcXVgtT=*K(y{+ou)DucJtK1z;2G&ji+L1o$ z+7Bwie4c=uMs>EB=uxt`?&ngp7#S6w-54=x6J9*?W>>&o31j!tqte+5g6-_)nXefSr0#9v0Fx2E|?C&#%EO=ifzta#GD|ZRdeuWXT##rI3Fl~yi z_wew=n*g^loF7R6;K1g6vHb5;%hTp=Rez$~EsU-eS`6Pc%0D))c$0IL+2P$hRgGq1 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 literal 0 HcmV?d00001 diff --git a/engine/sdl/menu.c b/engine/sdl/menu.c index fb79f02ea..82129b4c3 100644 --- a/engine/sdl/menu.c +++ b/engine/sdl/menu.c @@ -58,7 +58,7 @@ static s_screen* logscreen; #define LOG_SCREEN_END (isWide ? 26 : 23) static int bpp = 32; -#ifdef __SWITCH__ +#if defined(__SWITCH__) || defined(__PS4__) static int isWide = 1; #else static int isWide = 0; diff --git a/engine/sdl/video.c b/engine/sdl/video.c index 1578de340..abb3b80dc 100644 --- a/engine/sdl/video.c +++ b/engine/sdl/video.c @@ -55,7 +55,7 @@ void initSDL() SDL_ShowCursor(SDL_DISABLE); //atexit(SDL_Quit); //White Dragon: use SDL_Quit() into sdlport.c it's best practice! -#if defined(LOADGL) && !defined(__SWITCH__) +#if defined(LOADGL) && !defined(__SWITCH__) && !defined(__PS4__) if(SDL_GL_LoadLibrary(NULL) < 0) { printf("Warning: couldn't load OpenGL library (%s)\n", SDL_GetError()); @@ -65,6 +65,9 @@ void initSDL() #ifdef __SWITCH__ nativeWidth = 1280; nativeHeight = 720; +#elif __PS4__ + nativeWidth = 1920; + nativeHeight = 1080; #else SDL_GetCurrentDisplayMode(0, &video_info); nativeWidth = video_info.w; diff --git a/engine/source/ramlib/ram.c b/engine/source/ramlib/ram.c index 818b116d5..84b1428ed 100644 --- a/engine/source/ramlib/ram.c +++ b/engine/source/ramlib/ram.c @@ -115,6 +115,8 @@ u64 getFreeRam(int byte_size) return (atoi(result) * 1024) / byte_size; #elif SYMBIAN return GetFreeAmount(); +#elif __PS4__ + return 1024 * 1024 * 1024; #else struct mallinfo mi = mallinfo(); #ifdef _INCLUDE_MALLOC_H_ @@ -187,7 +189,7 @@ void setSystemRam() stackSize = 0x00000000; systemRam = getFreeRam(BYTES); #endif -#if !(defined(WIN) || defined(LINUX) || defined(DARWIN) || defined(SYMBIAN) || defined(VITA) || defined(__SWITCH__)) +#if !(defined(WIN) || defined(LINUX) || defined(DARWIN) || defined(SYMBIAN) || defined(VITA) || defined(__SWITCH__)) && !defined(__PS4__) stackSize = (int)&_end - (int)&_start + ((int)&_start - elfOffset); #endif getRamStatus(BYTES); diff --git a/engine/source/utils.c b/engine/source/utils.c index f9e071e69..5eba88164 100644 --- a/engine/source/utils.c +++ b/engine/source/utils.c @@ -94,6 +94,13 @@ typedef void DIR; #define READ_LOGFILE(type) type ? fopen(Alog, "rt") : fopen(Aslog, "rt") #define COPY_ROOT_PATH(buf, name) strncpy(buf, rootDir, strlen(rootDir)); strncat(buf, name, strlen(name)); strncat(buf, "/", 1); #define COPY_PAKS_PATH(buf, name) strncpy(buf, paksDir, strlen(paksDir)); strncat(buf, "/", 1); strncat(buf, name, strlen(name)); +#elif __PS4__ +#define CHECK_LOGFILE(type) type ? fileExists("/data/OpenBOR/Logs/OpenBorLog.txt") : fileExists("/data/OpenBOR/Logs/ScriptLog.txt") +#define OPEN_LOGFILE(type) type ? fopen("/data/OpenBOR/Logs/OpenBorLog.txt", "wt") : fopen("/data/OpenBOR/Logs/ScriptLog.txt", "wt") +#define APPEND_LOGFILE(type) type ? fopen("/data/OpenBOR/Logs/OpenBorLog.txt", "at") : fopen("/data/OpenBOR/Logs/ScriptLog.txt", "at") +#define READ_LOGFILE(type) type ? fopen("/data/OpenBOR/Logs/OpenBorLog.txt", "rt") : fopen("/data/OpenBOR/Logs/ScriptLog.txt", "rt") +#define COPY_ROOT_PATH(buf, name) strcpy(buf, "/data/OpenBOR/"); strcat(buf, name); strcat(buf, "/"); +#define COPY_PAKS_PATH(buf, name) strcpy(buf, "/data/OpenBOR/Paks/"); strcat(buf, name); #else #define CHECK_LOGFILE(type) type ? fileExists("./Logs/OpenBorLog.txt") : fileExists("./Logs/ScriptLog.txt") #define OPEN_LOGFILE(type) type ? fopen("./Logs/OpenBorLog.txt", "wt") : fopen("./Logs/ScriptLog.txt", "wt") @@ -303,7 +310,7 @@ void *checkAlloc(void *ptr, size_t size, const char *func, const char *file, int "\n* Shutting Down *\n\n"); writeToLogFile("Out of memory!\n"); writeToLogFile("Allocation of size %i failed in function '%s' at %s:%i.\n", size, func, file, line); -#ifndef WIN +#if !defined(WIN) && !defined(__PS4__) writeToLogFile("Memory usage at exit: %u\n", mallinfo().arena); #endif borExit(2); From 463ea2fae593f359d4cad8c4efcc6eae1e8df20b Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Mon, 7 Mar 2022 15:36:47 +0100 Subject: [PATCH 22/22] ps4: change pkg title --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df7dd2eae..22f18b295 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,7 +98,7 @@ if (NINTENDO_SWITCH) elseif (PS4) list(APPEND BOR_CFLAGS -D__CLANG_MAX_ALIGN_T_DEFINED) add_self(${PROJECT_NAME}) - add_pkg(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/engine/resources/ps4 "OPEN00001" "OpenBor @ cpasjuste" "03.71") + add_pkg(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/engine/resources/ps4 "OBOR00001" "OpenBor @ cpasjuste" "03.71") else () list(APPEND BOR_CFLAGS -D__LINUX__ -DLINUX -DOPENGL -DLOADGL) endif ()