diff --git a/Readme.PSP b/Readme.PSP new file mode 100644 index 00000000..b9a5ad3a --- /dev/null +++ b/Readme.PSP @@ -0,0 +1,41 @@ +# How to compile and run +Install latest PSPDEV toolchain, then go to src and run these commands: + +``` +mkdir build +cd build +psp-cmake .. +make +``` + +Then move the `EBOOT.PBP` file into a dir with the data/ files (WITH MUSIC!), +then finally load it into your PSP. + +## How to debug +Clean your dirs and run `psp-cmake .. -DBUILD_PRX=1` instead, then use +the debugging guide at PSPDEV's site. + +The process is like this: + +- Start `usbhostfs_pc` in a terminal at the prince.prx dir +- Start PSPLINK in your PSP, connected with a usb cable. +- Run `pspsh` in another terminal at the same prev. dir +- Run the command `debug ./prince.prx` inside pspsh +- In yet another terminal, run `psp-gdb ./prince -q`, then `target remote :10001` +- Start debugging as usual. + +You can skip the psp-gdb step, since PSPLINK lets you run the prx as is and +catch the exceptions and set breakpoints too. + +## Changes +- INI loading was disabled due to a bug that crashed the psp. Sane defaults were + provided instead (FIXED). +- PSP has to run at full speed (333mhz) in order for the game to work. +- "iconPSP.png" was provided. +- Music was replaced for ogg ones (use the smaller ones!), + so make sure to grab them into data/music (see README.md) + +## Credits +- SDLPoP and others (Github) +- PSPDEV and others (toolchain) +- striga, sharkwouter (fixing compilation for PSP) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df56218e..5bae7465 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -119,6 +119,22 @@ if(WIN32) target_link_libraries(prince mingw32 SDL2main SDL2 SDL2_image) elseif(APPLE) target_link_libraries(prince SDL2main SDL2 SDL2_image m) -else() # Linux, *BSD, etc. - target_link_libraries(prince SDL2 SDL2_image m) +elseif(PSP) # Linux, *BSD, etc. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") + include(FindPkgConfig) + pkg_search_module(SDL2 REQUIRED sdl2) + pkg_search_module(SDL2IMAGE REQUIRED SDL2_image) + target_include_directories(prince PRIVATE ${SDL2_INCLUDE_DIRS}) + target_link_libraries(prince PRIVATE + ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES} + ) + create_pbp_file( + TARGET prince + ICON_PATH ${CMAKE_SOURCE_DIR}/iconPSP.png + BACKGROUND_PATH NULL + PREVIEW_PATH NULL + TITLE prince + ) +else() + target_link_libraries(prince SDL2 SDL2_image m) endif() diff --git a/src/data.h b/src/data.h index 6d398e25..a987a39a 100644 --- a/src/data.h +++ b/src/data.h @@ -710,9 +710,15 @@ extern byte is_validate_mode; extern dword curr_tick INIT(= 0); #endif // USE_REPLAY +#ifdef __PSP__ +extern byte start_fullscreen INIT(= 1); +extern word pop_window_width INIT(= 480); +extern word pop_window_height INIT(= 272); +#else extern byte start_fullscreen INIT(= 0); extern word pop_window_width INIT(= 640); extern word pop_window_height INIT(= 400); +#endif extern byte use_custom_levelset INIT(= 0); extern char levelset_name[POP_MAX_PATH]; extern char mod_data_path[POP_MAX_PATH]; @@ -733,7 +739,11 @@ extern char gamecontrollerdb_file[POP_MAX_PATH] INIT(= ""); extern byte enable_quicksave INIT(= 1); extern byte enable_quicksave_penalty INIT(= 1); extern byte enable_replay INIT(= 1); +#ifdef __PSP__ +extern byte use_hardware_acceleration INIT(= 1); +#else extern byte use_hardware_acceleration INIT(= 2); +#endif extern byte use_correct_aspect_ratio INIT(= 0); extern byte use_integer_scaling INIT(= 0); extern byte scaling_type INIT(= 0); diff --git a/src/iconPSP.png b/src/iconPSP.png new file mode 100644 index 00000000..c52bc8e1 Binary files /dev/null and b/src/iconPSP.png differ diff --git a/src/main.c b/src/main.c index a32ee963..1ec2448f 100644 --- a/src/main.c +++ b/src/main.c @@ -26,9 +26,15 @@ static const char version[] = "\0$VER: SDLPoP " SDLPOP_VERSION " (" __AMIGADATE_ static const char stack[] = "$STACK:200000"; #endif +#ifdef __PSP__ +#include +#endif int main(int argc, char *argv[]) { + #ifdef __PSP__ + scePowerSetClockFrequency(333,333,166); + #endif g_argc = argc; g_argv = argv; pop_main(); diff --git a/src/seg006.c b/src/seg006.c index af6ca1e8..7c1cdb50 100644 --- a/src/seg006.c +++ b/src/seg006.c @@ -591,7 +591,14 @@ void play_seq() { } // fallthrough! case SEQ_JMP: // jump + #ifdef __PSP__ + word command1 = (word)*(SEQTBL_0 + Char.curr_seq); + word command2 = (word)*(SEQTBL_0 + Char.curr_seq+1); + //for some reason, this works, but normal pointer cast crashes (?) + Char.curr_seq = SDL_SwapLE16(command1 | (command2<<8)); + #else Char.curr_seq = SDL_SwapLE16(*(const word*)(SEQTBL_0 + Char.curr_seq)); + #endif break; case SEQ_UP: // up --Char.curr_row; diff --git a/src/seg009.c b/src/seg009.c index eb89a228..d5bcda9e 100644 --- a/src/seg009.c +++ b/src/seg009.c @@ -2389,7 +2389,9 @@ sound_buffer_type* convert_digi_sound(sound_buffer_type* digi_buffer) { converted_buffer->converted.length = expanded_length; byte* source = waveinfo.samples; - short* dest = converted_buffer->converted.samples; + //short* dest = converted_buffer->converted.samples; + short* dest = malloc(sizeof(short) * converted_buffer->converted.length); + converted_buffer->converted.samples = dest; for (int i = 0; i < expanded_frames; ++i) { float src_frame_float = i * freq_ratio; @@ -3371,8 +3373,8 @@ image_type* method_6_blit_img_to_scr(image_type* image,int xpos,int ypos,int bli } #ifndef USE_COMPAT_TIMER -int fps = 60; -float milliseconds_per_tick = (1000.0f / 60.0f); +int fps = BASE_FPS; +float milliseconds_per_tick = (1000.0f / (BASE_FPS*1.0f)); Uint64 timer_last_counter[NUM_TIMERS]; #endif int wait_time[NUM_TIMERS]; @@ -3845,7 +3847,7 @@ int do_wait(int timer_index) { } #ifdef USE_COMPAT_TIMER -SDL_TimerID global_timer = NULL; +SDL_TimerID global_timer = 0; #endif // seg009:78E9 void init_timer(int frequency) { @@ -3856,12 +3858,12 @@ void init_timer(int frequency) { perf_counters_per_tick = perf_frequency / fps; milliseconds_per_counter = 1000.0f / perf_frequency; #else + global_timer = SDL_AddTimer(1000/frequency, timer_callback, NULL); if (global_timer != 0) { if (!SDL_RemoveTimer(global_timer)) { sdlperror("init_timer: SDL_RemoveTimer"); } } - global_timer = SDL_AddTimer(1000/frequency, timer_callback, NULL); if (global_timer == 0) { sdlperror("init_timer: SDL_AddTimer"); quit(1); @@ -4251,6 +4253,7 @@ int has_timer_stopped(int timer_index) { #ifdef USE_REPLAY if ((replaying && skipping_replay) || is_validate_mode) return true; #endif + //PSP: overshoot always too big, 333mhz mandatory to read input! Uint64 current_counter = SDL_GetPerformanceCounter(); int ticks_elapsed = (int)((current_counter / perf_counters_per_tick) - (timer_last_counter[timer_index] / perf_counters_per_tick)); int overshoot = ticks_elapsed - wait_time[timer_index]; diff --git a/src/types.h b/src/types.h index 210407b5..35e47790 100644 --- a/src/types.h +++ b/src/types.h @@ -570,7 +570,7 @@ typedef struct ogg_type { typedef struct converted_audio_type { int length; - short samples[]; + short * samples; //FIXME: crash in PSP when using flexible arrays (??) } converted_audio_type; typedef struct sound_buffer_type { @@ -1185,7 +1185,10 @@ names_list_type listname##_list = {.type=0, .names = {&listname, COUNT(listname) #define KEY_VALUE_LIST(listname, ...) const key_value_type listname[] = __VA_ARGS__; \ names_list_type listname##_list = {.type=1, .kv_pairs= {(key_value_type*)&listname, COUNT(listname)}} +//misaligned data == CRASH!! on PSP +#ifndef __PSP__ #pragma pack(push,1) +#endif typedef struct fixes_options_type { byte enable_crouch_after_climbing; byte enable_freeze_time_during_end_music; @@ -1345,7 +1348,9 @@ typedef struct custom_options_type { byte chomper_speed; } custom_options_type; +#ifndef __PSP__ #pragma pack(pop) +#endif typedef struct directory_listing_type directory_listing_type;