diff options
| author | John "Lameguy" Wilbert Villamor <lameguy64@gmail.com> | 2022-10-19 17:57:06 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-19 17:57:06 +0800 |
| commit | e08a3d9366f8ca14a76b3dd569dac1fb9f569748 (patch) | |
| tree | 33654513b0b184c27f8035dbc405640fcbeb44ab /examples | |
| parent | c4a2533d21dfd05cde841ea48c67b05e0e6a853f (diff) | |
| parent | 9b2ffc6078a850b7d354855cca7622090b41f30c (diff) | |
| download | psn00bsdk-e08a3d9366f8ca14a76b3dd569dac1fb9f569748.tar.gz | |
Merge pull request #59 from spicyjpeg/psxmdec
IRQ handler fix, .STR playback example, multiple library builds (v0.21)
Diffstat (limited to 'examples')
45 files changed, 670 insertions, 196 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 15212c8..2fbc4d9 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK examples build script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( PSn00bSDK-examples diff --git a/examples/README.md b/examples/README.md index 82d7698..ade94b0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -24,7 +24,8 @@ Additional information may be found in the source code of each example. | [`io/pads`](./io/pads) | Demonstrates reading controllers via low-level access | EXE | 3 | | [`io/system573`](./io/system573) | Konami System 573 (PS1-based arcade board) example | CD | | | [`lowlevel/cartrom`](./lowlevel/cartrom) | ROM firmware for cheat devices written using GNU GAS | ROM | 4 | -| [`mdec/mdecimage`](./mdec/mdecimage) | Displays a (raw) MDEC format image using libpsxpress | EXE | | +| [`mdec/mdecimage`](./mdec/mdecimage) | Displays a (raw) MDEC format image | EXE | | +| [`mdec/strvideo`](./mdec/strvideo) | Plays a .STR video file using the MDEC | CD | 1 | | [`sound/spustream`](./sound/spustream) | Custom (non XA) CD-ROM audio streaming using the SPU | CD | | | [`sound/vagsample`](./sound/vagsample) | Demonstrates playing VAG sound files using the SPU | EXE | | | [`system/childexec`](./system/childexec) | Loading a child program and returning to parent | EXE | | @@ -35,9 +36,9 @@ Additional information may be found in the source code of each example. Notes: -1. `cdrom/cdxa` does not come with an example XA audio file. In order to run - this example you'll have to provide your own file and build the CD image - manually. +1. `cdrom/cdxa` and `mdec/strvideo` do not come with example files. In order + to run these examples you'll have to provide your own files and build the CD + image manually. 2. `demos/n00bdemo` suffers from flickering on real hardware, especially when masking/stencil buffering is used. 3. `io/pads` seems to work on real hardware, but fails to automatically enable @@ -48,7 +49,7 @@ Notes: ## Building the examples -The instructions below assume that PSn00bSDK, CMake 3.20+ and a GCC toolchain +The instructions below assume that PSn00bSDK, CMake 3.21+ and a GCC toolchain are already installed. Refer to the [installation guide](../doc/installation.md) for details. @@ -84,4 +85,4 @@ are for rebuilding the examples *after* the SDK has been installed. CD images for each example. ----------------------------------------- -_Last updated on 2022-08-11 by spicyjpeg_ +_Last updated on 2022-10-16 by spicyjpeg_ diff --git a/examples/beginner/cppdemo/CMakeLists.txt b/examples/beginner/cppdemo/CMakeLists.txt index c43d4a1..11a35ed 100644 --- a/examples/beginner/cppdemo/CMakeLists.txt +++ b/examples/beginner/cppdemo/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( cppdemo @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.cpp) -psn00bsdk_add_executable(cppdemo STATIC ${_sources}) +psn00bsdk_add_executable(cppdemo GPREL ${_sources}) #psn00bsdk_add_cd_image(cppdemo_iso cppdemo iso.xml DEPENDS cppdemo) install(FILES ${PROJECT_BINARY_DIR}/cppdemo.exe TYPE BIN) diff --git a/examples/beginner/hello/CMakeLists.txt b/examples/beginner/hello/CMakeLists.txt index d8297c5..98ab43b 100644 --- a/examples/beginner/hello/CMakeLists.txt +++ b/examples/beginner/hello/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( hello @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(hello STATIC ${_sources}) +psn00bsdk_add_executable(hello GPREL ${_sources}) #psn00bsdk_add_cd_image(hello_iso hello iso.xml DEPENDS hello) install(FILES ${PROJECT_BINARY_DIR}/hello.exe TYPE BIN) diff --git a/examples/cdrom/cdbrowse/CMakeLists.txt b/examples/cdrom/cdbrowse/CMakeLists.txt index c2e93fc..0cc091f 100644 --- a/examples/cdrom/cdbrowse/CMakeLists.txt +++ b/examples/cdrom/cdbrowse/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( cdbrowse @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(cdbrowse STATIC ${_sources}) +psn00bsdk_add_executable(cdbrowse GPREL ${_sources}) psn00bsdk_add_cd_image(cdbrowse_iso cdbrowse iso.xml DEPENDS cdbrowse) psn00bsdk_target_incbin(cdbrowse PRIVATE ball16c ball16c.tim) diff --git a/examples/cdrom/cdbrowse/iso.xml b/examples/cdrom/cdbrowse/iso.xml index 5ffca18..771b0e9 100644 --- a/examples/cdrom/cdbrowse/iso.xml +++ b/examples/cdrom/cdbrowse/iso.xml @@ -17,7 +17,6 @@ <directory_tree> <file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" /> <file name="CDBROWSE.EXE" type="data" source="cdbrowse.exe" /> - <file name="CDBROWSE.MAP" type="data" source="cdbrowse.map" /> <dir name="DIRA"> <dir name="DIRAA"> diff --git a/examples/cdrom/cdxa/CMakeLists.txt b/examples/cdrom/cdxa/CMakeLists.txt index 70ef77c..fd2f653 100644 --- a/examples/cdrom/cdxa/CMakeLists.txt +++ b/examples/cdrom/cdxa/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( cdxa @@ -13,7 +13,7 @@ project( # TODO: add rules to actually generate a valid .XA file file(GLOB _sources *.c) -psn00bsdk_add_executable(cdxa STATIC ${_sources}) +psn00bsdk_add_executable(cdxa GPREL ${_sources}) #psn00bsdk_add_cd_image(cdxa_iso cdxa iso.xml DEPENDS cdxa) psn00bsdk_target_incbin(cdxa PRIVATE ball16c ball16c.tim) diff --git a/examples/cdrom/cdxa/iso.xml b/examples/cdrom/cdxa/iso.xml index b98a16f..6715f94 100644 --- a/examples/cdrom/cdxa/iso.xml +++ b/examples/cdrom/cdxa/iso.xml @@ -17,7 +17,6 @@ <directory_tree> <file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" /> <file name="CDXA.EXE" type="data" source="cdxa.exe" /> - <file name="CDXA.MAP" type="data" source="cdxa.map" /> <!-- CD-XA file, you'll have to provide your own to make this example work --> <file name="XASAMPLE.XA" type="mixed" source="${PROJECT_SOURCE_DIR}/xasample.xa"/> diff --git a/examples/cdrom/cdxa/main.c b/examples/cdrom/cdxa/main.c index 4921658..93cf01a 100644 --- a/examples/cdrom/cdxa/main.c +++ b/examples/cdrom/cdxa/main.c @@ -349,7 +349,9 @@ int main(int argc, const char* argv[]) xa_loc = file.pos; /* Hook XA callback function to CdReadyCallback (for auto stop/loop */ + EnterCriticalSection(); CdReadyCallback(xa_callback); + ExitCriticalSection(); /* Set CD mode for XA streaming (2x speed, send XA to SPU, enable filter */ i = CdlModeSpeed|CdlModeRT|CdlModeSF; diff --git a/examples/demos/n00bdemo/CMakeLists.txt b/examples/demos/n00bdemo/CMakeLists.txt index a54c198..f7811b0 100644 --- a/examples/demos/n00bdemo/CMakeLists.txt +++ b/examples/demos/n00bdemo/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( n00bdemo @@ -28,7 +28,7 @@ add_custom_command( ) file(GLOB _sources *.s *.c) -psn00bsdk_add_executable(n00bdemo STATIC ${_sources}) +psn00bsdk_add_executable(n00bdemo GPREL ${_sources}) #psn00bsdk_add_cd_image(n00bdemo_iso n00bdemo iso.xml DEPENDS n00bdemo) target_include_directories(n00bdemo PRIVATE ${PROJECT_SOURCE_DIR}) diff --git a/examples/graphics/balls/CMakeLists.txt b/examples/graphics/balls/CMakeLists.txt index deee473..03c2720 100644 --- a/examples/graphics/balls/CMakeLists.txt +++ b/examples/graphics/balls/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( balls @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(balls STATIC ${_sources}) +psn00bsdk_add_executable(balls GPREL ${_sources}) #psn00bsdk_add_cd_image(balls_iso balls iso.xml DEPENDS balls) psn00bsdk_target_incbin(balls PRIVATE ball16c ball16c.tim) diff --git a/examples/graphics/billboard/CMakeLists.txt b/examples/graphics/billboard/CMakeLists.txt index 4fc668d..5288896 100644 --- a/examples/graphics/billboard/CMakeLists.txt +++ b/examples/graphics/billboard/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( billboard @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(billboard STATIC ${_sources}) +psn00bsdk_add_executable(billboard GPREL ${_sources}) #psn00bsdk_add_cd_image(billboard_iso billboard iso.xml DEPENDS billboard) psn00bsdk_target_incbin(billboard PRIVATE tim_image texture64.tim) diff --git a/examples/graphics/fpscam/CMakeLists.txt b/examples/graphics/fpscam/CMakeLists.txt index cb0c086..2c21296 100644 --- a/examples/graphics/fpscam/CMakeLists.txt +++ b/examples/graphics/fpscam/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( fpscam @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(fpscam STATIC ${_sources}) +psn00bsdk_add_executable(fpscam GPREL ${_sources}) #psn00bsdk_add_cd_image(fpscam_iso fpscam iso.xml DEPENDS fpscam) install(FILES ${PROJECT_BINARY_DIR}/fpscam.exe TYPE BIN) diff --git a/examples/graphics/gte/CMakeLists.txt b/examples/graphics/gte/CMakeLists.txt index 90d897b..e9ab4f3 100644 --- a/examples/graphics/gte/CMakeLists.txt +++ b/examples/graphics/gte/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( gte @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(gte STATIC ${_sources}) +psn00bsdk_add_executable(gte GPREL ${_sources}) #psn00bsdk_add_cd_image(gte_iso gte iso.xml DEPENDS gte) psn00bsdk_target_incbin(gte PRIVATE tim_texture texture.tim) diff --git a/examples/graphics/hdtv/CMakeLists.txt b/examples/graphics/hdtv/CMakeLists.txt index 804b096..78411f5 100644 --- a/examples/graphics/hdtv/CMakeLists.txt +++ b/examples/graphics/hdtv/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( hdtv @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(hdtv STATIC ${_sources}) +psn00bsdk_add_executable(hdtv GPREL ${_sources}) #psn00bsdk_add_cd_image(hdtv_iso hdtv iso.xml DEPENDS hdtv) install(FILES ${PROJECT_BINARY_DIR}/hdtv.exe TYPE BIN) diff --git a/examples/graphics/render2tex/CMakeLists.txt b/examples/graphics/render2tex/CMakeLists.txt index a97cf02..1ef36e0 100644 --- a/examples/graphics/render2tex/CMakeLists.txt +++ b/examples/graphics/render2tex/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( render2tex @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(render2tex STATIC ${_sources}) +psn00bsdk_add_executable(render2tex GPREL ${_sources}) #psn00bsdk_add_cd_image(render2tex_iso render2tex iso.xml DEPENDS render2tex) psn00bsdk_target_incbin(render2tex PRIVATE tim_blendpattern blendpattern-16c.tim) diff --git a/examples/graphics/rgb24/CMakeLists.txt b/examples/graphics/rgb24/CMakeLists.txt index 9565b8b..de81db0 100644 --- a/examples/graphics/rgb24/CMakeLists.txt +++ b/examples/graphics/rgb24/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( rgb24 @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(rgb24 STATIC ${_sources}) +psn00bsdk_add_executable(rgb24 GPREL ${_sources}) #psn00bsdk_add_cd_image(rgb24_iso rgb24 iso.xml DEPENDS rgb24) psn00bsdk_target_incbin(rgb24 PRIVATE tim_image bunpattern.tim) diff --git a/examples/graphics/tilesasm/CMakeLists.txt b/examples/graphics/tilesasm/CMakeLists.txt index 5b8de96..21ceafc 100644 --- a/examples/graphics/tilesasm/CMakeLists.txt +++ b/examples/graphics/tilesasm/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( tilesasm @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.s *.c) -psn00bsdk_add_executable(tilesasm STATIC ${_sources}) +psn00bsdk_add_executable(tilesasm GPREL ${_sources}) #psn00bsdk_add_cd_image(tilesasm_iso tilesasm iso.xml DEPENDS tilesasm) psn00bsdk_target_incbin(tilesasm PRIVATE tim_tileset tiles_256.tim) diff --git a/examples/io/pads/CMakeLists.txt b/examples/io/pads/CMakeLists.txt index cf5f817..618b696 100644 --- a/examples/io/pads/CMakeLists.txt +++ b/examples/io/pads/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( pads @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c *.s) -psn00bsdk_add_executable(pads STATIC ${_sources}) +psn00bsdk_add_executable(pads GPREL ${_sources}) #psn00bsdk_add_cd_image(pads_iso pads iso.xml DEPENDS pads) install(FILES ${PROJECT_BINARY_DIR}/pads.exe TYPE BIN) diff --git a/examples/io/pads/main.c b/examples/io/pads/main.c index 17bf331..29bb527 100644 --- a/examples/io/pads/main.c +++ b/examples/io/pads/main.c @@ -62,17 +62,17 @@ static const char *const PAD_TYPEIDS[] = { #define BGCOLOR_B 0 typedef struct { - DISPENV disp; - DRAWENV draw; -} DB; + DISPENV disp; + DRAWENV draw; +} Framebuffer; typedef struct { - DB db[2]; - uint32_t db_active; -} CONTEXT; + Framebuffer db[2]; + int db_active; +} RenderContext; -void init_context(CONTEXT *ctx) { - DB *db; +void init_context(RenderContext *ctx) { + Framebuffer *db; ResetGraph(0); ctx->db_active = 0; @@ -99,8 +99,8 @@ void init_context(CONTEXT *ctx) { FntOpen(8, 16, 304, 208, 2, 512); } -void display(CONTEXT *ctx) { - DB *db; +void display(RenderContext *ctx) { + Framebuffer *db; DrawSync(0); VSync(0); @@ -227,7 +227,7 @@ void poll_cb(uint32_t port, const volatile uint8_t *buff, size_t rx_len) { /* Main */ -static CONTEXT ctx; +static RenderContext ctx; int main(int argc, const char* argv[]) { init_context(&ctx); diff --git a/examples/io/pads/spi.c b/examples/io/pads/spi.c index 133782c..292e682 100644 --- a/examples/io/pads/spi.c +++ b/examples/io/pads/spi.c @@ -46,9 +46,9 @@ typedef struct _SPI_Context { SPI_Callback callback; } SPI_Context; -static volatile SPI_Context _context; -static volatile SPI_Request volatile *_current_req; -static volatile SPI_Callback _default_cb; +static volatile SPI_Context _context; +static volatile SPI_Request *_current_req; +static volatile SPI_Callback _default_cb; /* Request queue management */ diff --git a/examples/io/system573/CMakeLists.txt b/examples/io/system573/CMakeLists.txt index 2a362e8..34b0d69 100644 --- a/examples/io/system573/CMakeLists.txt +++ b/examples/io/system573/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( system573 @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c *.s) -psn00bsdk_add_executable(system573 STATIC ${_sources}) +psn00bsdk_add_executable(system573 GPREL ${_sources}) psn00bsdk_add_cd_image(system573_iso system573 iso.xml DEPENDS system573) install( diff --git a/examples/io/system573/iso.xml b/examples/io/system573/iso.xml index 0bb84d5..2226089 100644 --- a/examples/io/system573/iso.xml +++ b/examples/io/system573/iso.xml @@ -30,8 +30,6 @@ --> <!--<file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" />--> <file name="PSX.EXE" type="data" source="system573.exe" /> - <file name="PSX.MAP" type="data" source="system573.map" /> - <file name="QSY.DXD" type="data" source="system573.exe" /> <file name="SSW.BXF" type="data" source="system573.exe" /> <file name="TSV.AXG" type="data" source="system573.exe" /> diff --git a/examples/io/system573/main.c b/examples/io/system573/main.c index 3404ee4..39ddb64 100644 --- a/examples/io/system573/main.c +++ b/examples/io/system573/main.c @@ -83,17 +83,17 @@ const char *const IO_BOARD_TYPES[] = { #define BGCOLOR_B 0 typedef struct { - DISPENV disp; - DRAWENV draw; -} DB; + DISPENV disp; + DRAWENV draw; +} Framebuffer; typedef struct { - DB db[2]; - uint32_t db_active; -} CONTEXT; + Framebuffer db[2]; + int db_active; +} RenderContext; -void init_context(CONTEXT *ctx) { - DB *db; +void init_context(RenderContext *ctx) { + Framebuffer *db; ResetGraph(0); ctx->db_active = 0; @@ -120,8 +120,8 @@ void init_context(CONTEXT *ctx) { FntOpen(8, 16, 304, 208, 2, 512); } -void display(CONTEXT *ctx) { - DB *db; +void display(RenderContext *ctx) { + Framebuffer *db; DrawSync(0); VSync(0); @@ -135,7 +135,7 @@ void display(CONTEXT *ctx) { /* Main */ -static CONTEXT ctx; +static RenderContext ctx; #define SHOW_STATUS(...) { FntPrint(-1, __VA_ARGS__); FntFlush(-1); display(&ctx); } #define SHOW_ERROR(...) { SHOW_STATUS(__VA_ARGS__); while (1) __asm__("nop"); } diff --git a/examples/lowlevel/cartrom/CMakeLists.txt b/examples/lowlevel/cartrom/CMakeLists.txt index 7d5e86e..6a94d9f 100644 --- a/examples/lowlevel/cartrom/CMakeLists.txt +++ b/examples/lowlevel/cartrom/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( cartrom @@ -17,9 +17,13 @@ file(GLOB _sources *.c *.s) # executable has to be created manually and converted into raw binary format # (for testing on emulators or flashing to a cheat cartridge). add_executable (cartrom ${_sources}) -target_link_libraries(cartrom psn00bsdk_static_exe) -set_target_properties(cartrom PROPERTIES PREFIX "" SUFFIX ".elf") target_link_options (cartrom PRIVATE -T${PROJECT_SOURCE_DIR}/rom.ld) +set_target_properties( + cartrom PROPERTIES + PREFIX "" + SUFFIX ".elf" + PSN00BSDK_TARGET_TYPE EXECUTABLE_NOGPREL +) target_include_directories(cartrom PRIVATE ${PROJECT_SOURCE_DIR}) diff --git a/examples/mdec/mdecimage/CMakeLists.txt b/examples/mdec/mdecimage/CMakeLists.txt index b76adb4..b3d8ae1 100644 --- a/examples/mdec/mdecimage/CMakeLists.txt +++ b/examples/mdec/mdecimage/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( mdecimage @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(mdecimage STATIC ${_sources}) +psn00bsdk_add_executable(mdecimage GPREL ${_sources}) #psn00bsdk_add_cd_image(mdecimage_iso mdecimage iso.xml DEPENDS mdecimage) psn00bsdk_target_incbin(mdecimage PRIVATE mdec_image image.bin) diff --git a/examples/mdec/strvideo/CMakeLists.txt b/examples/mdec/strvideo/CMakeLists.txt new file mode 100644 index 0000000..d41556b --- /dev/null +++ b/examples/mdec/strvideo/CMakeLists.txt @@ -0,0 +1,24 @@ +# PSn00bSDK example CMake script +# (C) 2021 spicyjpeg - MPL licensed + +cmake_minimum_required(VERSION 3.21) + +project( + strvideo + LANGUAGES C + VERSION 1.0.0 + DESCRIPTION "PSn00bSDK .STR video playback example" + HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" +) + +file(GLOB _sources *.c) +psn00bsdk_add_executable(strvideo GPREL ${_sources}) +#psn00bsdk_add_cd_image(strvideo_iso strvideo iso.xml DEPENDS strvideo) + +install( + FILES + #${PROJECT_BINARY_DIR}/strvideo.bin + #${PROJECT_BINARY_DIR}/strvideo.cue + ${PROJECT_BINARY_DIR}/strvideo.exe + TYPE BIN +) diff --git a/examples/graphics/tilesasm/iso.xml b/examples/mdec/strvideo/iso.xml index 477c636..65e0ff5 100644 --- a/examples/graphics/tilesasm/iso.xml +++ b/examples/mdec/strvideo/iso.xml @@ -1,11 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- - This file is processed by CMake and used by mkpsxiso to build the CD image. - - NOTE: all paths are relative to the build directory; if you want to include - a file from the source tree, you'll have to prepend its path with - ${PROJECT_SOURCE_DIR}. ---> <iso_project image_name="${CD_IMAGE_NAME}.bin" cue_sheet="${CD_IMAGE_NAME}.cue" @@ -13,8 +6,8 @@ <track type="data"> <identifiers system ="PLAYSTATION" - volume ="PSN00BSDK_TEMPLATE" - volume_set ="PSN00BSDK_TEMPLATE" + volume ="STRVIDEO" + volume_set ="STRVIDEO" publisher ="MEIDOTEK" data_preparer ="PSN00BSDK ${PSN00BSDK_VERSION}" application ="PLAYSTATION" @@ -23,8 +16,9 @@ <directory_tree> <file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" /> - <file name="TEMPLATE.EXE" type="data" source="template.exe" /> - <file name="TEMPLATE.MAP" type="data" source="template.map" /> + <file name="STRVIDEO.EXE" type="data" source="strvideo.exe" /> + + <file name="VIDEO.STR" type="mixed" source="${PROJECT_SOURCE_DIR}/video.str"/> <dummy sectors="1024"/> </directory_tree> diff --git a/examples/mdec/strvideo/main.c b/examples/mdec/strvideo/main.c new file mode 100644 index 0000000..842bbb8 --- /dev/null +++ b/examples/mdec/strvideo/main.c @@ -0,0 +1,439 @@ +/* + * PSn00bSDK .STR FMV playback example + * (C) 2022 spicyjpeg - MPL licensed + * + * This example demonstrates playback of full-motion video in the standard .STR + * format, using the MDEC for frame decoding and XA for audio. Decoded frames + * are transferred directly to the main framebuffer in this example, but could + * also be output to another VRAM location and used as a background or texture + * for a 2D or 3D scene. + * + * Playing video files requires setting up a fairly complex pipeline, involving + * several buffers and components working in parallel: + * + * - .STR sectors are read continuously from the CD and each frame, usually + * spanning multiple sectors, is reassembled (demuxed) into a buffer in + * memory. In this example the task is performed by cd_sector_handler(). The + * CD drive handles XA-ADPCM sectors automatically, so no CPU intervention is + * necessary to play the audio track interleaved with the video. + * - Once a full frame has been demuxed, the bitstream data is parsed and + * decompressed by the CPU (using DecDCTvlc()) to an array of run-length + * codes to be fed to the MDEC. This is done in the main loop. + * - At the same time the last frame decompressed is read from RAM by the MDEC, + * which decodes it and outputs one 16-pixel-wide vertical slice at a time. + * - When a slice is ready, it is uploaded by mdec_dma_handler() to the current + * framebuffer in VRAM while the MDEC is decoding the next slice. + * A text overlay is drawn on top of the framebuffer using the GPU after the + * entire frame has been decoded. + * + * Since pretty much all buffers used are going to be read and written at the + * same time, double buffering is required for all of them. Every part of the + * pipeline must also run in lockstep with each other to prevent frame + * corruption, hence several functions and flag variables are used to stall the + * main loop until a frame is available for decoding and the MDEC is ready. + * Playback is stopped when a sector with the end-of-file flag set in the XA + * subheader (added at the end of the file by most .STR encoders) is + * encountered; in order to access the subheader, this example requests 2340 + * bytes of data for each sector (rather than the usual 2048) from the drive. + * + * Note that PSn00bSDK's bitstream decoding API only supports version 1 and 2 + * bitstreams currently, so make sure your .STR files are encoded as v2 and not + * v3. + */ + +#include <stdint.h> +#include <string.h> +#include <psxetc.h> +#include <psxapi.h> +#include <psxgpu.h> +#include <psxgte.h> +#include <psxspu.h> +#include <psxcd.h> +#include <psxpress.h> +#include <hwregs_c.h> + +// Uncomment to display the video in 24bpp mode. Note that the GPU does not +// support 24bpp rendering, so the text overlay is only enabled in 16bpp mode. +//#define DISP_24BPP + +/* Display/GPU context utilities */ + +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +#define BGCOLOR_R 0 +#define BGCOLOR_G 0 +#define BGCOLOR_B 0 + +typedef struct { + DISPENV disp; + DRAWENV draw; +} Framebuffer; + +typedef struct { + Framebuffer db[2]; + int db_active; +} RenderContext; + +void init_context(RenderContext *ctx) { + Framebuffer *db; + + ResetGraph(0); + ctx->db_active = 0; + + db = &(ctx->db[0]); + SetDefDispEnv(&(db->disp), 0, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + db = &(ctx->db[1]); + SetDefDispEnv(&(db->disp), 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&(db->draw), 0, 0, SCREEN_XRES, SCREEN_YRES); + setRGB0(&(db->draw), BGCOLOR_R, BGCOLOR_G, BGCOLOR_B); + db->draw.isbg = 1; + db->draw.dtd = 1; + + PutDrawEnv(&(db->draw)); + //PutDispEnv(&(db->disp)); + + // Create a text stream at the top of the screen. + FntLoad(960, 0); + FntOpen(4, 12, 312, 16, 2, 256); +} + +void display(RenderContext *ctx, int sync) { + Framebuffer *db; + ctx->db_active ^= 1; + + DrawSync(0); + if (sync) + VSync(0); + + db = &(ctx->db[ctx->db_active]); + PutDrawEnv(&(db->draw)); + PutDispEnv(&(db->disp)); + SetDispMask(1); +} + +/* CD and MDEC interrupt handlers */ + +#ifdef DISP_24BPP +#define BLOCK_SIZE 24 +#else +#define BLOCK_SIZE 16 +#define DRAW_OVERLAY +#endif + +#define VRAM_X_COORD(x) ((x) * BLOCK_SIZE / 16) + +// All non-audio sectors in .STR files begin with this 32-byte header, which +// contains metadata about the sector and is followed by a chunk of frame +// bitstream data. +// https://problemkaputt.de/psx-spx.htm#cdromfilevideostrstreamingandbspicturecompressionsony +typedef struct { + uint16_t magic; // Always 0x0160 + uint16_t type; // 0x8001 for MDEC + uint16_t sector_id; // Chunk number (0 = first chunk of this frame) + uint16_t sector_count; // Total number of chunks for this frame + uint32_t frame_id; // Frame number + uint32_t bs_length; // Total length of this frame in bytes + + uint16_t width, height; + uint8_t bs_header[8]; + uint32_t _reserved; +} STR_Header; + +// https://problemkaputt.de/psx-spx.htm#cdromxasubheaderfilechannelinterleave +typedef struct { + uint8_t file, channel; + uint8_t submode, coding_info; +} XA_Header; + +// https://problemkaputt.de/psx-spx.htm#cdromsectorencoding +typedef struct { + CdlLOC pos; + XA_Header xa_header[2]; + STR_Header str_header; + uint8_t data[2016]; + uint32_t edc; + uint8_t ecc[276]; +} STR_Sector; + +typedef struct { + uint16_t width, height; + uint32_t bs_data[0x2000]; // Bitstream data read from the disc + uint32_t mdec_data[0x8000]; // Decompressed data to be fed to the MDEC +} StreamBuffer; + +typedef struct { + StreamBuffer frames[2]; + uint32_t slices[2][BLOCK_SIZE * SCREEN_YRES / 2]; + + int frame_id, sector_count; + int dropped_frames; + RECT slice_pos; + int frame_width; + + volatile int8_t sector_pending, frame_ready; + volatile int8_t cur_frame, cur_slice; +} StreamContext; + +StreamContext str_ctx; + +// This buffer is used by cd_sector_handler() as a temporary area for sectors +// read from the CD. Due to DMA limitations it can't be allocated on the stack +// (especially not in the interrupt callbacks' stack, whose size is very +// limited). +STR_Sector sector_buffer; + +void cd_sector_handler(void) { + // Fetch the .STR header of the sector that has been read and check if the + // end-of-file bit is set in the XA header. + CdGetSector(§or_buffer, sizeof(STR_Sector) / 4); + + if ( + (sector_buffer.xa_header[0].submode & (1 << 7)) || + (sector_buffer.xa_header[1].submode & (1 << 7)) + ) { + CdControlF(CdlPause, 0); + str_ctx.frame_ready = -1; + return; + } + + STR_Header *header = §or_buffer.str_header; + StreamBuffer *frame = &str_ctx.frames[str_ctx.cur_frame]; + + // Ignore any non-MDEC sectors that might be present in the stream. + if (header->type != 0x8001) + return; + + // If this sector is actually part of a new frame, validate the sectors + // that have been read so far and flip the bitstream data buffers. + if (header->frame_id != str_ctx.frame_id) { + // Do not set the ready flag if any sector has been missed. + if (str_ctx.sector_count) + str_ctx.dropped_frames++; + else + str_ctx.frame_ready = 1; + + str_ctx.frame_id = header->frame_id; + str_ctx.sector_count = header->sector_count; + str_ctx.cur_frame ^= 1; + + frame = &str_ctx.frames[str_ctx.cur_frame]; + + // Initialize the next frame. Dimensions must be rounded up to the + // nearest multiple of 16 as the MDEC operates on 16x16 pixel blocks. + frame->width = (header->width + 15) & 0xfff0; + frame->height = (header->height + 15) & 0xfff0; + } + + // Append the payload contained in this sector to the current buffer. + memcpy( + &(frame->bs_data[2016 / 4 * header->sector_id]), + sector_buffer.data, + 2016 + ); + str_ctx.sector_count--; +} + +void mdec_dma_handler(void) { + // Handle any sectors that were not processed by cd_event_handler() (see + // below) while a DMA transfer from the MDEC was in progress. As the MDEC + // has just finished decoding a slice, they can be safely handled now. + if (str_ctx.sector_pending) { + cd_sector_handler(); + str_ctx.sector_pending = 0; + } + + // Upload the decoded slice to VRAM and start decoding the next slice (into + // another buffer) if any. + LoadImage(&str_ctx.slice_pos, str_ctx.slices[str_ctx.cur_slice]); + + str_ctx.cur_slice ^= 1; + str_ctx.slice_pos.x += BLOCK_SIZE; + + if (str_ctx.slice_pos.x < str_ctx.frame_width) + DecDCTout( + str_ctx.slices[str_ctx.cur_slice], + BLOCK_SIZE * str_ctx.slice_pos.h / 2 + ); +} + +void cd_event_handler(int event, uint8_t *payload) { + // Ignore all events other than a sector being ready. + if (event != CdlDataReady) + return; + + // Only handle sectors immediately if the MDEC is not decoding a frame, + // otherwise defer handling to mdec_dma_handler(). This is a workaround for + // a hardware conflict between the DMA channels used for the CD drive and + // MDEC output, which shall not run simultaneously. + if (DecDCTinSync(1)) + str_ctx.sector_pending = 1; + else + cd_sector_handler(); +} + +/* Stream helpers */ + +void init_stream(void) { + EnterCriticalSection(); + DMACallback(1, &mdec_dma_handler); + CdReadyCallback(&cd_event_handler); + ExitCriticalSection(); + + // Set the maximum amount of data DecDCTvlc() can output and copy the + // lookup table used for decompression to the scratchpad area. This is + // optional but makes the decompressor slightly faster. See the libpsxpress + // documentation for more details. + DecDCTvlcSize(0x8000); + DecDCTvlcCopyTable((DECDCTTAB *) 0x1f800000); + + str_ctx.dropped_frames = 0; + str_ctx.cur_frame = 0; + str_ctx.cur_slice = 0; +} + +StreamBuffer *get_next_frame(void) { + while (!str_ctx.frame_ready) + __asm__ volatile(""); + + if (str_ctx.frame_ready < 0) + return 0; + + str_ctx.frame_ready = 0; + return &str_ctx.frames[str_ctx.cur_frame ^ 1]; +} + +void start_stream(CdlFILE *file) { + str_ctx.frame_id = -1; + str_ctx.sector_pending = 0; + str_ctx.frame_ready = 0; + + CdSync(0, 0); + + // Configure the CD drive to read 2340-byte sectors at 2x speed and to + // play any XA-ADPCM sectors that might be interleaved with the video data. + uint8_t mode = CdlModeSize | CdlModeRT | CdlModeSpeed; + CdControl(CdlSetmode, (const uint8_t *) &mode, 0); + + // Start reading in real-time mode (i.e. without retrying in case of read + // errors) and wait for the first frame to be buffered. + CdControl(CdlReadS, &(file->pos), 0); + + get_next_frame(); +} + +/* Main */ + +static RenderContext ctx; + +#define SHOW_STATUS(...) { FntPrint(-1, __VA_ARGS__); FntFlush(-1); display(&ctx, 1); } +#define SHOW_ERROR(...) { SHOW_STATUS(__VA_ARGS__); while (1) __asm__("nop"); } + +int main(int argc, const char* argv[]) { + init_context(&ctx); + + SHOW_STATUS("INITIALIZING\n"); + SpuInit(); + CdInit(); + InitGeom(); // Required for PSn00bSDK's DecDCTvlc() + DecDCTReset(0); + + SHOW_STATUS("OPENING VIDEO FILE\n"); + + CdlFILE file; + if (!CdSearchFile(&file, "\\VIDEO.STR")) + SHOW_ERROR("FAILED TO FIND VIDEO.STR\n"); + + init_stream(); + start_stream(&file); + + // Disable framebuffer clearing to get rid of flickering during playback. + display(&ctx, 1); + ctx.db[0].draw.isbg = 0; + ctx.db[1].draw.isbg = 0; +#ifdef DISP_24BPP + ctx.db[0].disp.isrgb24 = 1; + ctx.db[1].disp.isrgb24 = 1; +#endif + + int decode_errors = 0; + + while (1) { + // Wait for a full frame to be read from the disc and decompress the + // bitstream into the format expected by the MDEC. If the video has + // ended, restart playback from the beginning. + StreamBuffer *frame = get_next_frame(); + if (!frame) { + start_stream(&file); + continue; + } + +#ifdef DRAW_OVERLAY + // Measure CPU usage of the decompressor using the hblank counter. + int total_time = TIMER_VALUE(1) + 1; + TIMER_VALUE(1) = 0; +#endif + + if (DecDCTvlc(frame->bs_data, frame->mdec_data)) { + decode_errors++; + continue; + } + +#ifdef DRAW_OVERLAY + int cpu_usage = TIMER_VALUE(1) * 100 / total_time; +#endif + + // Wait for the MDEC to finish decoding the previous frame, then flip + // the framebuffers to display it and prepare the buffer for the next + // frame. + // NOTE: you should *not* call VSync(0) during playback, as the refresh + // rate of the GPU is not synced to the video's frame rate. If you want + // to minimize screen tearing, consider triple buffering instead (i.e. + // always keep 2 fully decoded frames in VRAM and use VSyncCallback() + // to register a function that displays the next decoded frame whenever + // vblank occurs). + DecDCTinSync(0); + DecDCToutSync(0); + +#ifdef DRAW_OVERLAY + FntPrint(-1, "FRAME:%5d READ ERRORS: %5d\n", str_ctx.frame_id, str_ctx.dropped_frames); + FntPrint(-1, "CPU: %5d%% DECODE ERRORS:%5d\n", cpu_usage, decode_errors); + FntFlush(-1); +#endif + display(&ctx, 0); + + // Feed the newly decompressed frame to the MDEC. The MDEC will not + // actually start decoding it until an output buffer is also configured + // by calling DecDCTout() (see below). +#ifdef DISP_24BPP + DecDCTin(frame->mdec_data, DECDCT_MODE_24BPP); +#else + DecDCTin(frame->mdec_data, DECDCT_MODE_16BPP); +#endif + + // Place the frame at the center of the currently active framebuffer + // and start decoding the first slice. Decoded slices will be uploaded + // to VRAM in the background by mdec_dma_handler(). + RECT *fb_clip = &(ctx.db[ctx.db_active].draw.clip); + int x_offset = (fb_clip->w - frame->width) / 2; + int y_offset = (fb_clip->h - frame->height) / 2; + + str_ctx.slice_pos.x = VRAM_X_COORD(fb_clip->x + x_offset); + str_ctx.slice_pos.y = fb_clip->y + y_offset; + str_ctx.slice_pos.w = BLOCK_SIZE; + str_ctx.slice_pos.h = frame->height; + str_ctx.frame_width = VRAM_X_COORD(frame->width); + + DecDCTout( + str_ctx.slices[str_ctx.cur_slice], + BLOCK_SIZE * str_ctx.slice_pos.h / 2 + ); + } + + return 0; +} diff --git a/examples/graphics/tilesasm/system.cnf b/examples/mdec/strvideo/system.cnf index e221726..d199117 100644 --- a/examples/graphics/tilesasm/system.cnf +++ b/examples/mdec/strvideo/system.cnf @@ -1,4 +1,4 @@ -BOOT=cdrom:\template.exe;1 +BOOT=cdrom:\strvideo.exe;1 TCB=4 EVENT=10 STACK=801FFFF0 diff --git a/examples/sound/spustream/CMakeLists.txt b/examples/sound/spustream/CMakeLists.txt index 397796a..63d113b 100644 --- a/examples/sound/spustream/CMakeLists.txt +++ b/examples/sound/spustream/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( spustream @@ -13,7 +13,7 @@ project( # TODO: add rules to actually generate a valid STREAM.BIN file file(GLOB _sources *.c) -psn00bsdk_add_executable(spustream STATIC ${_sources}) +psn00bsdk_add_executable(spustream GPREL ${_sources}) psn00bsdk_add_cd_image(spustream_iso spustream iso.xml DEPENDS spustream) install( diff --git a/examples/sound/spustream/iso.xml b/examples/sound/spustream/iso.xml index 3807046..050d673 100644 --- a/examples/sound/spustream/iso.xml +++ b/examples/sound/spustream/iso.xml @@ -17,7 +17,6 @@ <directory_tree> <file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" /> <file name="SPUSTRM.EXE" type="data" source="spustream.exe" /> - <file name="SPUSTRM.MAP" type="data" source="spustream.map" /> <file name="STREAM.BIN" type="data" source="${PROJECT_SOURCE_DIR}/stream.bin" /> diff --git a/examples/sound/spustream/main.c b/examples/sound/spustream/main.c index 6179179..1fee883 100644 --- a/examples/sound/spustream/main.c +++ b/examples/sound/spustream/main.c @@ -117,17 +117,17 @@ #define BGCOLOR_B 0 typedef struct { - DISPENV disp; - DRAWENV draw; -} DB; + DISPENV disp; + DRAWENV draw; +} Framebuffer; typedef struct { - DB db[2]; - int db_active; -} CONTEXT; + Framebuffer db[2]; + int db_active; +} RenderContext; -void init_context(CONTEXT *ctx) { - DB *db; +void init_context(RenderContext *ctx) { + Framebuffer *db; ResetGraph(0); ctx->db_active = 0; @@ -154,8 +154,8 @@ void init_context(CONTEXT *ctx) { FntOpen(8, 16, 304, 208, 2, 512); } -void display(CONTEXT *ctx) { - DB *db; +void display(RenderContext *ctx) { + Framebuffer *db; DrawSync(0); VSync(0); @@ -181,16 +181,14 @@ void display(CONTEXT *ctx) { #define CHUNK_SIZE (BUFFER_SIZE * NUM_CHANNELS) typedef struct { - uint32_t lba; - uint32_t length; - uint32_t pos; + int lba, length; - uint32_t spu_addr; - uint32_t spu_pos; - uint32_t db_active; + volatile int pos; + volatile int spu_addr, spu_pos; + volatile int db_active; } StreamContext; -static volatile StreamContext str_ctx; +static StreamContext str_ctx; // This buffer is used by cd_event_handler() as a temporary area for sectors // read from the CD and uploaded to SPU RAM. Due to DMA limitations it can't be @@ -316,10 +314,10 @@ void init_stream(CdlFILE *file) { } void start_stream(void) { - SPU_KEY_OFF = CHANNEL_MASK; + uint32_t addr = BUFFER_START_ADDR + CHUNK_SIZE * str_ctx.db_active; for (int i = 0; i < NUM_CHANNELS; i++) { - SPU_CH_ADDR(i) = SPU_RAM_ADDR(BUFFER_START_ADDR + BUFFER_SIZE * i); + SPU_CH_ADDR(i) = SPU_RAM_ADDR(addr + BUFFER_SIZE * i); SPU_CH_FREQ(i) = SAMPLE_RATE; SPU_CH_ADSR(i) = 0x1fee80ff; } @@ -336,9 +334,21 @@ void start_stream(void) { spu_irq_handler(); } +// This is basically a variant of reset_spu_channels() that only resets the +// channels used to play the stream, to (again) prevent them from triggering +// the SPU IRQ while the stream is paused. +void stop_stream(void) { + SPU_KEY_OFF = CHANNEL_MASK; + + for (int i = 0; i < NUM_CHANNELS; i++) + SPU_CH_ADDR(i) = SPU_RAM_ADDR(DUMMY_BLOCK_ADDR); + + SPU_KEY_ON = CHANNEL_MASK; +} + /* Main */ -static CONTEXT ctx; +static RenderContext ctx; #define SHOW_STATUS(...) { FntPrint(-1, __VA_ARGS__); FntFlush(-1); display(&ctx); } #define SHOW_ERROR(...) { SHOW_STATUS(__VA_ARGS__); while (1) __asm__("nop"); } @@ -351,7 +361,13 @@ int main(int argc, const char* argv[]) { CdInit(); reset_spu_channels(); - SHOW_STATUS("LOCATING STREAM FILE\n"); + // Set up controller polling. + uint8_t pad_buff[2][34]; + InitPAD(pad_buff[0], 34, pad_buff[1], 34); + StartPAD(); + ChangeClearPAD(0); + + SHOW_STATUS("OPENING STREAM FILE\n"); CdlFILE file; if (!CdSearchFile(&file, "\\STREAM.BIN")) @@ -361,28 +377,27 @@ int main(int argc, const char* argv[]) { init_stream(&file); start_stream(); - // Set up controller polling. - uint8_t pad_buff[2][34]; - InitPAD(pad_buff[0], 34, pad_buff[1], 34); - StartPAD(); - ChangeClearPAD(0); + int paused = 0; uint16_t sample_rate = SAMPLE_RATE; uint16_t last_buttons = 0xffff; while (1) { - FntPrint(-1, "PLAYING SPU STREAM\n"); + FntPrint(-1, "PLAYING SPU STREAM\n\n"); + + FntPrint(-1, "BUFFER: %d\nSTATUS: ", str_ctx.db_active); if (str_ctx.spu_pos >= CHUNK_SIZE) - FntPrint(-1, "STATUS: IDLE\n\n"); - else if (!str_ctx.spu_pos) - FntPrint(-1, "STATUS: SEEKING\n\n"); + FntPrint(-1, "IDLE\n\n"); + else if (str_ctx.spu_pos) + FntPrint(-1, "BUFFERING\n\n"); else - FntPrint(-1, "STATUS: BUFFERING\n\n"); + FntPrint(-1, "SEEKING\n\n"); - FntPrint(-1, "POSITION=%5d/%5d\n", str_ctx.pos, str_ctx.length); - FntPrint(-1, "BUFFERED=%5d/%5d\n", str_ctx.spu_pos, CHUNK_SIZE); - FntPrint(-1, "SMP RATE=%5d HZ\n\n", (sample_rate * 44100) >> 12); + FntPrint(-1, "POSITION: %5d/%5d\n", str_ctx.pos, str_ctx.length); + FntPrint(-1, "BUFFERED: %5d/%5d\n", str_ctx.spu_pos, CHUNK_SIZE); + FntPrint(-1, "SMP RATE: %5d HZ\n\n", (sample_rate * 44100) >> 12); + FntPrint(-1, "[START] %s\n", paused ? "RESUME" : "PAUSE"); FntPrint(-1, "[LEFT/RIGHT] SEEK\n"); FntPrint(-1, "[O] RESET POSITION\n"); FntPrint(-1, "[UP/DOWN] CHANGE SAMPLE RATE\n"); @@ -399,6 +414,14 @@ int main(int argc, const char* argv[]) { if ((pad->type != 4) && (pad->type != 5) && (pad->type != 7)) continue; + if ((last_buttons & PAD_START) && !(pad->btn & PAD_START)) { + paused ^= 1; + if (paused) + stop_stream(); + else + start_stream(); + } + // Seeking by an arbitrary number of sectors isn't a problem as // spu_irq_handler() always realigns the counter. if (!(pad->btn & PAD_LEFT)) diff --git a/examples/sound/vagsample/CMakeLists.txt b/examples/sound/vagsample/CMakeLists.txt index c9849ae..7d06afd 100644 --- a/examples/sound/vagsample/CMakeLists.txt +++ b/examples/sound/vagsample/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( vagsample @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(vagsample STATIC ${_sources}) +psn00bsdk_add_executable(vagsample GPREL ${_sources}) #psn00bsdk_add_cd_image(vagsample_iso vagsample iso.xml DEPENDS vagsample) psn00bsdk_target_incbin(vagsample PRIVATE proyt proyt.vag) diff --git a/examples/system/childexec/CMakeLists.txt b/examples/system/childexec/CMakeLists.txt index 7e91589..e542d2a 100644 --- a/examples/system/childexec/CMakeLists.txt +++ b/examples/system/childexec/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( childexec @@ -13,14 +13,14 @@ project( file(GLOB _sources *.c) file(GLOB _child_sources child/*.c) -psn00bsdk_add_executable(parent STATIC ${_sources}) -psn00bsdk_add_executable(child STATIC ${_child_sources}) -#psn00bsdk_add_cd_image(childexec_iso childexec iso.xml DEPENDS parent) +psn00bsdk_add_executable(childexec GPREL ${_sources}) +psn00bsdk_add_executable(childexec_child GPREL ${_child_sources}) +#psn00bsdk_add_cd_image(childexec_iso childexec iso.xml DEPENDS childexec) -psn00bsdk_target_incbin(parent PRIVATE ball16c ball16c.tim) +psn00bsdk_target_incbin(childexec PRIVATE ball16c ball16c.tim) psn00bsdk_target_incbin( - parent PRIVATE child_exe - ${PROJECT_BINARY_DIR}/child.exe + childexec PRIVATE child_exe + ${PROJECT_BINARY_DIR}/childexec_child.exe ) # Relocate the child executable to a non-default address to prevent it from @@ -28,9 +28,9 @@ psn00bsdk_target_incbin( # NOTE: child executables are not position-independent and can't be relocated # at runtime. If you need your code to be relocatable (e.g. to load it into a # dynamically-allocated buffer), consider using a DLL instead. -target_link_options(child PRIVATE -Ttext=0x80030000) +target_link_options(childexec_child PRIVATE -Ttext=0x80030000) # Make sure the child executable is built before the parent. -add_dependencies(parent child) +add_dependencies(childexec childexec_child) -install(FILES ${PROJECT_BINARY_DIR}/parent.exe TYPE BIN) +install(FILES ${PROJECT_BINARY_DIR}/childexec.exe TYPE BIN) diff --git a/examples/system/childexec/child/child.c b/examples/system/childexec/child/child.c index bd17440..dcfbfaf 100644 --- a/examples/system/childexec/child/child.c +++ b/examples/system/childexec/child/child.c @@ -98,8 +98,8 @@ MATRIX light_mtx = { char pad_buff[2][34]; /* Function declarations */ -void init(); -void display(); +void init(void); +void display(void); /* Main function */ @@ -245,7 +245,7 @@ int main(int argc, const char *argv[]) { } -void init() { +void init(void) { /* Reset the GPU, also installs a VSync event handler */ ResetGraph( 0 ); @@ -300,7 +300,7 @@ void init() { } -void display() { +void display(void) { /* Wait for GPU to finish drawing and vertical retrace */ DrawSync( 0 ); diff --git a/examples/system/childexec/parent.c b/examples/system/childexec/parent.c index 3e7d218..83d964c 100644 --- a/examples/system/childexec/parent.c +++ b/examples/system/childexec/parent.c @@ -67,12 +67,12 @@ extern const uint32_t ball16c[]; TIM_IMAGE tim; -void run_child(); +void run_child(void); char pad_buff[2][34]; -void init() { +void init(void) { int i; @@ -270,10 +270,7 @@ typedef struct { // Child program address extern char child_exe[]; -// Manually defined as its not defined in psxapi by default -void SetDefaultExitFromException(); - -void run_child() { +void run_child(void) { // Arguments for the child program char *args[] = @@ -289,29 +286,23 @@ void run_child() { // Copy child executable to its intended adddress memcpy((void*)exe->param.t_addr, child_exe+2048, exe->param.t_size); - // Enter critical section to prepare for program execution - EnterCriticalSection(); + // Prepare for program execution and disable interrupts + //EnterCriticalSection(); + StopCallback(); // Stop pads, enable auto acknowledge StopPAD(); ChangeClearPAD(1); ChangeClearRCnt(3, 1); - - // Set default exception handler just in case - //SetDefaultExitFromException(); - - // Last three function calls could be relegated to - // a StopCallback() function in the future. - + // Execute child printf("Child exec!\n"); Exec(&exe->param, 3, args); // Restore interrupts for this PS-EXE - EnterCriticalSection(); RestartCallback(); - ExitCriticalSection(); - + //ExitCriticalSection(); + // Re-init and re-enable pads InitPAD(pad_buff[0], 34, pad_buff[1], 34); StartPAD(); diff --git a/examples/system/console/CMakeLists.txt b/examples/system/console/CMakeLists.txt index eeb8e62..c6fa573 100644 --- a/examples/system/console/CMakeLists.txt +++ b/examples/system/console/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( console @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(console STATIC ${_sources}) +psn00bsdk_add_executable(console GPREL ${_sources}) #psn00bsdk_add_cd_image(console_iso console iso.xml DEPENDS console) psn00bsdk_target_incbin(console PRIVATE ball16c ball16c.tim) diff --git a/examples/system/dynlink/CMakeLists.txt b/examples/system/dynlink/CMakeLists.txt index f5f4ea8..e750fd1 100644 --- a/examples/system/dynlink/CMakeLists.txt +++ b/examples/system/dynlink/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( dynlink @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(dynlink_main DYNAMIC ${_sources}) +psn00bsdk_add_executable(dynlink_main NOGPREL ${_sources}) psn00bsdk_add_library (dynlink_cube SHARED library/cube.c) psn00bsdk_add_library (dynlink_balls SHARED library/balls.c) psn00bsdk_add_cd_image( diff --git a/examples/system/dynlink/library/balls.c b/examples/system/dynlink/library/balls.c index c537167..457ec4e 100644 --- a/examples/system/dynlink/library/balls.c +++ b/examples/system/dynlink/library/balls.c @@ -21,7 +21,7 @@ typedef struct { int16_t x, y; int16_t xdir, ydir; uint8_t r, g, b, p; -} BALL_TYPE; +} Ball; #define MAX_BALLS 512 @@ -35,12 +35,13 @@ typedef struct { // initialize variables or hardware. static uint32_t frame = 0; -static BALL_TYPE balls[MAX_BALLS]; +static Ball balls[MAX_BALLS]; static TIM_IMAGE ball_tim; -void init(CONTEXT *ctx) { - GetTimInfo(ball16c, &ball_tim); +void init(RenderContext *ctx) { + Framebuffer *db = &(ctx->db[ctx->db_active]); + GetTimInfo(ball16c, &ball_tim); LoadImage(ball_tim.prect, ball_tim.paddr); if (ball_tim.mode & 8) LoadImage(ball_tim.crect, ball_tim.caddr); @@ -48,10 +49,10 @@ void init(CONTEXT *ctx) { // Initialize the balls by giving them a random initial position, velocity // and color. for (uint32_t i = 0; i < MAX_BALLS; i++) { - BALL_TYPE *b = &(balls[i]); + Ball *b = &(balls[i]); - b->x = rand() % (ctx->xres - 16); - b->y = rand() % (ctx->yres - 16); + b->x = rand() % (db->draw.clip.w - 16); + b->y = rand() % (db->draw.clip.h - 16); b->xdir = ((rand() & 1) ? 1 : -1) * ((rand() % 3) + 1); b->ydir = ((rand() & 1) ? 1 : -1) * ((rand() % 3) + 1); b->r = rand() & 0xff; @@ -60,12 +61,12 @@ void init(CONTEXT *ctx) { } } -void render(CONTEXT *ctx, uint16_t buttons) { - DB *db = &(ctx->db[ctx->db_active]); - SPRT_16 *sprt = (SPRT_16 *) ctx->db_nextpri; +void render(RenderContext *ctx, uint16_t buttons) { + Framebuffer *db = &(ctx->db[ctx->db_active]); + SPRT_16 *sprt = (SPRT_16 *) ctx->db_nextpri; for (uint32_t i = 0; i < MAX_BALLS; i++) { - BALL_TYPE *b = &(balls[i]); + Ball *b = &(balls[i]); setSprt16(sprt); @@ -85,12 +86,12 @@ void render(CONTEXT *ctx, uint16_t buttons) { if ( (b->x < 0) || - ((b->x + 16) > ctx->xres) + ((b->x + 16) > db->draw.clip.w) ) b->xdir *= -1; if ( (b->y < 0) || - ((b->y + 16) > ctx->yres) + ((b->y + 16) > db->draw.clip.h) ) b->ydir *= -1; } diff --git a/examples/system/dynlink/library/cube.c b/examples/system/dynlink/library/cube.c index 84fe552..22a805f 100644 --- a/examples/system/dynlink/library/cube.c +++ b/examples/system/dynlink/library/cube.c @@ -81,16 +81,18 @@ static SVECTOR rot = { 0 }; static VECTOR pos = { 0, 0, 400 }; static MATRIX mtx, lmtx; -void init(CONTEXT *ctx) { +void init(RenderContext *ctx) { + Framebuffer *db = &(ctx->db[ctx->db_active]); + InitGeom(); - gte_SetGeomOffset(ctx->xres / 2, ctx->yres / 2); - gte_SetGeomScreen(ctx->xres / 2); + gte_SetGeomOffset(db->draw.clip.w / 2, db->draw.clip.h / 2); + gte_SetGeomScreen(db->draw.clip.w / 2); gte_SetBackColor(63, 63, 63); gte_SetColorMatrix(&color_mtx); } -void render(CONTEXT *ctx, uint16_t buttons) { +void render(RenderContext *ctx, uint16_t buttons) { RotMatrix(&rot, &mtx); TransMatrix(&mtx, &pos); MulMatrix0(&light_mtx, &mtx, &lmtx); @@ -104,8 +106,8 @@ void render(CONTEXT *ctx, uint16_t buttons) { rot.vx += step; rot.vz += step; - DB *db = &(ctx->db[ctx->db_active]); - POLY_F4 *pol4 = (POLY_F4 *) ctx->db_nextpri; + Framebuffer *db = &(ctx->db[ctx->db_active]); + POLY_F4 *pol4 = (POLY_F4 *) ctx->db_nextpri; for (uint32_t i = 0; i < CUBE_FACES; i++) { int32_t p; diff --git a/examples/system/dynlink/library/dll_common.h b/examples/system/dynlink/library/dll_common.h index 315a993..6606bda 100644 --- a/examples/system/dynlink/library/dll_common.h +++ b/examples/system/dynlink/library/dll_common.h @@ -19,13 +19,12 @@ typedef struct { DRAWENV draw; uint32_t ot[OT_LEN]; uint8_t p[PACKET_LEN]; -} DB; +} Framebuffer; typedef struct { - uint16_t xres, yres; - DB db[2]; - uint32_t db_active; - uint8_t *db_nextpri; -} CONTEXT; + Framebuffer db[2]; + int db_active; + uint8_t *db_nextpri; +} RenderContext; #endif diff --git a/examples/system/dynlink/main.c b/examples/system/dynlink/main.c index fff7aa5..fcce5b1 100644 --- a/examples/system/dynlink/main.c +++ b/examples/system/dynlink/main.c @@ -83,12 +83,10 @@ static const char *const DLL_FILENAMES[] = { #define BGCOLOR_G 24 #define BGCOLOR_B 0 -void init_context(CONTEXT *ctx) { - DB *db; +void init_context(RenderContext *ctx) { + Framebuffer *db; ResetGraph(0); - ctx->xres = SCREEN_XRES; - ctx->yres = SCREEN_YRES; ctx->db_active = 0; db = &(ctx->db[0]); @@ -121,8 +119,8 @@ void init_context(CONTEXT *ctx) { FntOpen(4, 12, 312, 32, 2, 256); } -void display(CONTEXT *ctx) { - DB *db; +void display(RenderContext *ctx) { + Framebuffer *db; DrawSync(0); VSync(0); @@ -185,13 +183,14 @@ void *custom_resolver(DLL *dll, const char *name) { // and the pointers returned by DL_GetDLLSymbol() should be saved and reused as // much as possible. typedef struct { - void (*init)(CONTEXT *); - void (*render)(CONTEXT *, uint16_t buttons); + void (*init)(RenderContext *); + void (*render)(RenderContext *, uint16_t buttons); } DLL_API; static DLL *dll = 0; static DLL_API dll_api; -static CONTEXT ctx; + +static RenderContext ctx; /* Main */ diff --git a/examples/system/timer/CMakeLists.txt b/examples/system/timer/CMakeLists.txt index 328e07e..30efbf3 100644 --- a/examples/system/timer/CMakeLists.txt +++ b/examples/system/timer/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( timer @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(timer STATIC ${_sources}) +psn00bsdk_add_executable(timer GPREL ${_sources}) #psn00bsdk_add_cd_image(timer_iso timer iso.xml DEPENDS timer) install(FILES ${PROJECT_BINARY_DIR}/timer.exe TYPE BIN) diff --git a/examples/system/tty/CMakeLists.txt b/examples/system/tty/CMakeLists.txt index 0664502..75ce689 100644 --- a/examples/system/tty/CMakeLists.txt +++ b/examples/system/tty/CMakeLists.txt @@ -1,7 +1,7 @@ # PSn00bSDK example CMake script # (C) 2021 spicyjpeg - MPL licensed -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.21) project( tty @@ -12,7 +12,7 @@ project( ) file(GLOB _sources *.c) -psn00bsdk_add_executable(tty STATIC ${_sources}) +psn00bsdk_add_executable(tty GPREL ${_sources}) #psn00bsdk_add_cd_image(tty_iso tty iso.xml DEPENDS tty) install(FILES ${PROJECT_BINARY_DIR}/tty.exe TYPE BIN) |
