diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1574fd1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,60 @@ +IndentWidth: 4 +Language: Cpp +UseTab: Never +ColumnLimit: 140 +ReferenceAlignment: Left +PointerAlignment: Right +SpaceAfterCStyleCast: false +Cpp11BracedListStyle: false +SpaceBeforeCpp11BracedList: false + +# Cases inside switches are indented one level +IndentCaseLabels: true + +# Do not indent access modifiers (public, protected, private) +AccessModifierOffset: -4 + +AlignAfterOpenBracket: AlwaysBreak + +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortEnumsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: false +AllowShortLoopsOnASingleLine: false + +# Otherwise it would align escaped newlines to the column limit +AlignEscapedNewlines: Left + +AlignTrailingComments: true +SortIncludes: true + +BreakBeforeBraces: Custom +BraceWrapping: + AfterControlStatement: Never + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeElse: true + +# Adds a comment at the end of the namespace with its name +FixNamespaceComments: true +# Indent namespace's content +NamespaceIndentation: All + +# Aligns preprocessor directives +IndentPPDirectives: AfterHash + +# No space between template and < +SpaceAfterTemplateKeyword: false +# Newline after template +AlwaysBreakTemplateDeclarations: Yes + +# Make the indentation of lambdas nicer +LambdaBodyIndentation: Signature + +# Tags these macros as types +TypenameMacros: ["PTR"] diff --git a/librecomp/include/librecomp/files.hpp b/librecomp/include/librecomp/files.hpp index 63e3e9d..46eaa5c 100644 --- a/librecomp/include/librecomp/files.hpp +++ b/librecomp/include/librecomp/files.hpp @@ -9,6 +9,6 @@ namespace recomp { std::ifstream open_input_backup_file(const std::filesystem::path& filepath, std::ios_base::openmode mode = std::ios_base::in); std::ofstream open_output_file_with_backup(const std::filesystem::path& filepath, std::ios_base::openmode mode = std::ios_base::out); bool finalize_output_file_with_backup(const std::filesystem::path& filepath); -}; +}; // namespace recomp #endif diff --git a/librecomp/include/librecomp/game.hpp b/librecomp/include/librecomp/game.hpp index 0e108a9..8e1b233 100644 --- a/librecomp/include/librecomp/game.hpp +++ b/librecomp/include/librecomp/game.hpp @@ -1,8 +1,8 @@ #ifndef __RECOMP_GAME__ #define __RECOMP_GAME__ -#include #include +#include #include "recomp.h" #include "rsp.hpp" @@ -17,50 +17,46 @@ namespace recomp { bool is_enabled; gpr entrypoint_address; - void (*entrypoint)(uint8_t* rdram, recomp_context* context); + void (*entrypoint)(uint8_t *rdram, recomp_context *context); std::u8string stored_filename() const; }; - enum class RomValidationError { - Good, - FailedToOpen, - NotARom, - IncorrectRom, - NotYet, - IncorrectVersion, - OtherError - }; - void register_config_path(std::filesystem::path path); - bool register_game(const recomp::GameEntry& entry); - void check_all_stored_roms(); - bool load_stored_rom(std::u8string& game_id); - RomValidationError select_rom(const std::filesystem::path& rom_path, std::u8string& game_id); - bool is_rom_valid(std::u8string& game_id); - bool is_rom_loaded(); - void set_rom_contents(std::vector&& new_rom); - void do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr, size_t num_bytes); - void do_rom_pio(uint8_t* rdram, gpr ram_address, uint32_t physical_addr); - - /** - * The following arguments contain mandatory callbacks that need to be registered (i.e., can't be `nullptr`): - * - `rsp_callbacks` - * - `renderer_callbacks` - * - * It must be called only once and it must be called before `ultramodern::preinit`. - */ + enum class RomValidationError { + Good, + FailedToOpen, + NotARom, + IncorrectRom, + NotYet, + IncorrectVersion, + OtherError + }; + void register_config_path(std::filesystem::path path); + bool register_game(const recomp::GameEntry& entry); + void check_all_stored_roms(); + bool load_stored_rom(std::u8string& game_id); + RomValidationError select_rom(const std::filesystem::path& rom_path, std::u8string& game_id); + bool is_rom_valid(std::u8string& game_id); + bool is_rom_loaded(); + void set_rom_contents(std::vector&& new_rom); + void do_rom_read(uint8_t *rdram, gpr ram_address, uint32_t physical_addr, size_t num_bytes); + void do_rom_pio(uint8_t *rdram, gpr ram_address, uint32_t physical_addr); + + /** + * The following arguments contain mandatory callbacks that need to be registered (i.e., can't be `nullptr`): + * - `rsp_callbacks` + * - `renderer_callbacks` + * + * It must be called only once and it must be called before `ultramodern::preinit`. + */ void start( - ultramodern::renderer::WindowHandle window_handle, - const recomp::rsp::callbacks_t& rsp_callbacks, - const ultramodern::renderer::callbacks_t& renderer_callbacks, - const ultramodern::audio_callbacks_t& audio_callbacks, - const ultramodern::input::callbacks_t& input_callbacks, - const ultramodern::gfx_callbacks_t& gfx_callbacks, + ultramodern::renderer::WindowHandle window_handle, const recomp::rsp::callbacks_t& rsp_callbacks, + const ultramodern::renderer::callbacks_t& renderer_callbacks, const ultramodern::audio_callbacks_t& audio_callbacks, + const ultramodern::input::callbacks_t& input_callbacks, const ultramodern::gfx_callbacks_t& gfx_callbacks, const ultramodern::events::callbacks_t& events_callbacks, - const ultramodern::error_handling::callbacks_t& error_handling_callbacks_ - ); + const ultramodern::error_handling::callbacks_t& error_handling_callbacks_); - void start_game(const std::u8string& game_id); - std::u8string current_game_id(); -} + void start_game(const std::u8string& game_id); + std::u8string current_game_id(); +} // namespace recomp #endif diff --git a/librecomp/include/librecomp/helpers.hpp b/librecomp/include/librecomp/helpers.hpp index 9f02367..5d732c2 100644 --- a/librecomp/include/librecomp/helpers.hpp +++ b/librecomp/include/librecomp/helpers.hpp @@ -5,7 +5,7 @@ #include template -T _arg(uint8_t* rdram, recomp_context* ctx) { +T _arg(uint8_t *rdram, recomp_context *ctx) { static_assert(index < 4, "Only args 0 through 3 supported"); gpr raw_arg = (&ctx->r4)[index]; if constexpr (std::is_same_v) { @@ -15,13 +15,14 @@ T _arg(uint8_t* rdram, recomp_context* ctx) { } else { // static_assert in else workaround - [] () { + []() { static_assert(flag, "Floats in a2/a3 not supported"); - }(); + } + (); } } else if constexpr (std::is_pointer_v) { - static_assert (!std::is_pointer_v>, "Double pointers not supported"); + static_assert(!std::is_pointer_v>, "Double pointers not supported"); return TO_PTR(std::remove_pointer_t, raw_arg); } else if constexpr (std::is_integral_v) { @@ -30,14 +31,15 @@ T _arg(uint8_t* rdram, recomp_context* ctx) { } else { // static_assert in else workaround - [] () { + []() { static_assert(flag, "Unsupported type"); - }(); + } + (); } } -template -void _return(recomp_context* ctx, T val) { +template +void _return(recomp_context *ctx, T val) { static_assert(sizeof(T) <= 4 && "Only 32-bit value returns supported currently"); if constexpr (std::is_same_v) { ctx->f0.fl = val; @@ -47,9 +49,10 @@ void _return(recomp_context* ctx, T val) { } else { // static_assert in else workaround - [] () { + []() { static_assert(flag, "Unsupported type"); - }(); + } + (); } } diff --git a/librecomp/include/librecomp/overlays.hpp b/librecomp/include/librecomp/overlays.hpp index d66ae47..215a37a 100644 --- a/librecomp/include/librecomp/overlays.hpp +++ b/librecomp/include/librecomp/overlays.hpp @@ -1,30 +1,30 @@ #ifndef __RECOMP_OVERLAYS_H__ #define __RECOMP_OVERLAYS_H__ -#include #include "sections.h" +#include namespace recomp { namespace overlays { struct overlay_section_table_data_t { - SectionTableEntry* code_sections; + SectionTableEntry *code_sections; size_t num_code_sections; size_t total_num_sections; }; struct overlays_by_index_t { - int* table; + int *table; size_t len; }; void register_overlays(const overlay_section_table_data_t& sections, const overlays_by_index_t& overlays); - void register_patches(const char* patch_data, std::size_t patch_size, SectionTableEntry* code_sections); - void read_patch_data(uint8_t* rdram, gpr patch_data_address); + void register_patches(const char *patch_data, std::size_t patch_size, SectionTableEntry *code_sections); + void read_patch_data(uint8_t *rdram, gpr patch_data_address); void init_overlays(); - } -}; + } // namespace overlays +}; // namespace recomp extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size); extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); diff --git a/librecomp/include/librecomp/rsp.hpp b/librecomp/include/librecomp/rsp.hpp index 1bc91e4..427e734 100644 --- a/librecomp/include/librecomp/rsp.hpp +++ b/librecomp/include/librecomp/rsp.hpp @@ -3,8 +3,8 @@ #include -#include "rsp_vu.hpp" #include "recomp.h" +#include "rsp_vu.hpp" #include "ultramodern/ultra64.h" // TODO: Move these to recomp namespace? @@ -17,36 +17,34 @@ enum class RspExitReason { Unsupported }; -using RspUcodeFunc = RspExitReason(uint8_t* rdram); +using RspUcodeFunc = RspExitReason(uint8_t *rdram); extern uint8_t dmem[]; extern uint16_t rspReciprocals[512]; extern uint16_t rspInverseSquareRoots[512]; -#define RSP_MEM_B(offset, addr) \ - (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) +#define RSP_MEM_B(offset, addr) (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) -#define RSP_MEM_BU(offset, addr) \ - (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) +#define RSP_MEM_BU(offset, addr) (*reinterpret_cast(dmem + (0xFFF & (((offset) + (addr)) ^ 3)))) static inline uint32_t RSP_MEM_W_LOAD(uint32_t offset, uint32_t addr) { uint32_t out; for (int i = 0; i < 4; i++) { - reinterpret_cast(&out)[i ^ 3] = RSP_MEM_BU(offset + i, addr); + reinterpret_cast(&out)[i ^ 3] = RSP_MEM_BU(offset + i, addr); } return out; } static inline void RSP_MEM_W_STORE(uint32_t offset, uint32_t addr, uint32_t val) { for (int i = 0; i < 4; i++) { - RSP_MEM_BU(offset + i, addr) = reinterpret_cast(&val)[i ^ 3]; + RSP_MEM_BU(offset + i, addr) = reinterpret_cast(&val)[i ^ 3]; } } static inline uint32_t RSP_MEM_HU_LOAD(uint32_t offset, uint32_t addr) { uint16_t out; for (int i = 0; i < 2; i++) { - reinterpret_cast(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr); + reinterpret_cast(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr); } return out; } @@ -54,32 +52,29 @@ static inline uint32_t RSP_MEM_HU_LOAD(uint32_t offset, uint32_t addr) { static inline uint32_t RSP_MEM_H_LOAD(uint32_t offset, uint32_t addr) { int16_t out; for (int i = 0; i < 2; i++) { - reinterpret_cast(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr); + reinterpret_cast(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr); } return out; } static inline void RSP_MEM_H_STORE(uint32_t offset, uint32_t addr, uint32_t val) { for (int i = 0; i < 2; i++) { - RSP_MEM_BU(offset + i, addr) = reinterpret_cast(&val)[(i + 2) ^ 3]; + RSP_MEM_BU(offset + i, addr) = reinterpret_cast(&val)[(i + 2) ^ 3]; } } -#define RSP_ADD32(a, b) \ - ((int32_t)((a) + (b))) +#define RSP_ADD32(a, b) ((int32_t)((a) + (b))) -#define RSP_SUB32(a, b) \ - ((int32_t)((a) - (b))) +#define RSP_SUB32(a, b) ((int32_t)((a) - (b))) -#define RSP_SIGNED(val) \ - ((int32_t)(val)) +#define RSP_SIGNED(val) ((int32_t)(val)) #define SET_DMA_DMEM(dmem_addr) dma_dmem_address = (dmem_addr) #define SET_DMA_DRAM(dram_addr) dma_dram_address = (dram_addr) #define DO_DMA_READ(rd_len) dma_rdram_to_dmem(rdram, dma_dmem_address, dma_dram_address, (rd_len)) #define DO_DMA_WRITE(wr_len) dma_dmem_to_rdram(rdram, dma_dmem_address, dma_dram_address, (wr_len)) -static inline void dma_rdram_to_dmem(uint8_t* rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t rd_len) { +static inline void dma_rdram_to_dmem(uint8_t *rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t rd_len) { rd_len += 1; // Read length is inclusive dram_addr &= 0xFFFFF8; assert(dmem_addr + rd_len <= 0x1000); @@ -88,7 +83,7 @@ static inline void dma_rdram_to_dmem(uint8_t* rdram, uint32_t dmem_addr, uint32_ } } -static inline void dma_dmem_to_rdram(uint8_t* rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t wr_len) { +static inline void dma_dmem_to_rdram(uint8_t *rdram, uint32_t dmem_addr, uint32_t dram_addr, uint32_t wr_len) { wr_len += 1; // Write length is inclusive dram_addr &= 0xFFFFF8; assert(dmem_addr + wr_len <= 0x1000); @@ -100,24 +95,26 @@ static inline void dma_dmem_to_rdram(uint8_t* rdram, uint32_t dmem_addr, uint32_ namespace recomp { namespace rsp { struct callbacks_t { - using get_rsp_microcode_t = RspUcodeFunc*(const OSTask* task); + using get_rsp_microcode_t = RspUcodeFunc *(const OSTask *task); /** * Return a function pointer to the corresponding RSP microcode function for the given `task_type`. * - * The full OSTask (`task` parameter) is passed in case the `task_type` number is not enough information to distinguish out the exact microcode function. + * The full OSTask (`task` parameter) is passed in case the `task_type` number is not enough information to distinguish out the + * exact microcode function. * - * This function is allowed to return `nullptr` if no microcode matches the specified task. In this case a message will be printed to stderr and the program will exit. + * This function is allowed to return `nullptr` if no microcode matches the specified task. In this case a message will be + * printed to stderr and the program will exit. */ - get_rsp_microcode_t* get_rsp_microcode; + get_rsp_microcode_t *get_rsp_microcode; }; void set_callbacks(const callbacks_t& callbacks); void constants_init(); - bool run_task(uint8_t* rdram, const OSTask* task); - } -} + bool run_task(uint8_t *rdram, const OSTask *task); + } // namespace rsp +} // namespace recomp #endif diff --git a/librecomp/include/librecomp/sections.h b/librecomp/include/librecomp/sections.h index 1d1b228..c25eb6c 100644 --- a/librecomp/include/librecomp/sections.h +++ b/librecomp/include/librecomp/sections.h @@ -2,12 +2,13 @@ #define __SECTIONS_H__ #include + #include "recomp.h" #define ARRLEN(x) (sizeof(x) / sizeof((x)[0])) typedef struct { - recomp_func_t* func; + recomp_func_t *func; uint32_t offset; } FuncEntry; diff --git a/librecomp/src/ai.cpp b/librecomp/src/ai.cpp index 0195f2b..b59db77 100644 --- a/librecomp/src/ai.cpp +++ b/librecomp/src/ai.cpp @@ -6,24 +6,24 @@ #define VI_NTSC_CLOCK 48681812 -extern "C" void osAiSetFrequency_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osAiSetFrequency_recomp(uint8_t *rdram, recomp_context *ctx) { uint32_t freq = ctx->r4; // This makes actual audio frequency more accurate to console, but may not be desirable - //uint32_t dacRate = (uint32_t)(((float)VI_NTSC_CLOCK / freq) + 0.5f); - //freq = VI_NTSC_CLOCK / dacRate; + // uint32_t dacRate = (uint32_t)(((float)VI_NTSC_CLOCK / freq) + 0.5f); + // freq = VI_NTSC_CLOCK / dacRate; ctx->r2 = freq; ultramodern::set_audio_frequency(freq); } -extern "C" void osAiSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osAiSetNextBuffer_recomp(uint8_t *rdram, recomp_context *ctx) { ultramodern::queue_audio_buffer(rdram, ctx->r4, ctx->r5); ctx->r2 = 0; } -extern "C" void osAiGetLength_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osAiGetLength_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = ultramodern::get_remaining_audio_bytes(); } -extern "C" void osAiGetStatus_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osAiGetStatus_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0x00000000; // Pretend the audio DMAs finish instantly } diff --git a/librecomp/src/cont.cpp b/librecomp/src/cont.cpp index 8e15c83..02a40cb 100644 --- a/librecomp/src/cont.cpp +++ b/librecomp/src/cont.cpp @@ -4,15 +4,15 @@ #define MAXCONTROLLERS 4 -extern "C" void recomp_set_current_frame_poll_id(uint8_t* rdram, recomp_context* ctx) { +extern "C" void recomp_set_current_frame_poll_id(uint8_t *rdram, recomp_context *ctx) { // TODO reimplement the system for tagging polls with IDs to handle games with multithreaded input polling. } -extern "C" void recomp_measure_latency(uint8_t* rdram, recomp_context* ctx) { +extern "C" void recomp_measure_latency(uint8_t *rdram, recomp_context *ctx) { ultramodern::measure_input_latency(); } -extern "C" void osContInit_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osContInit_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSMesgQueue) mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx); PTR(u8) bitpattern = _arg<1, PTR(u8)>(rdram, ctx); PTR(OSContStatus) data = _arg<2, PTR(OSContStatus)>(rdram, ctx); @@ -22,7 +22,7 @@ extern "C" void osContInit_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void osContReset_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osContReset_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSMesgQueue) mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx); PTR(OSContStatus) data = _arg<1, PTR(OSContStatus)>(rdram, ctx); @@ -31,7 +31,7 @@ extern "C" void osContReset_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void osContStartReadData_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osContStartReadData_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSMesgQueue) mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx); s32 ret = osContStartReadData(PASS_RDRAM mq); @@ -39,7 +39,7 @@ extern "C" void osContStartReadData_recomp(uint8_t* rdram, recomp_context* ctx) _return(ctx, ret); } -extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osContGetReadData_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSContPad) data = _arg<0, PTR(OSContPad)>(rdram, ctx); OSContPad dummy_data[MAXCONTROLLERS]; @@ -54,7 +54,7 @@ extern "C" void osContGetReadData_recomp(uint8_t* rdram, recomp_context* ctx) { } } -extern "C" void osContStartQuery_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osContStartQuery_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSMesgQueue) mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx); s32 ret = osContStartQuery(PASS_RDRAM mq); @@ -62,13 +62,13 @@ extern "C" void osContStartQuery_recomp(uint8_t * rdram, recomp_context * ctx) { _return(ctx, ret); } -extern "C" void osContGetQuery_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osContGetQuery_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSContStatus) data = _arg<0, PTR(OSContStatus)>(rdram, ctx); osContGetQuery(PASS_RDRAM data); } -extern "C" void osContSetCh_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osContSetCh_recomp(uint8_t *rdram, recomp_context *ctx) { u8 ch = _arg<0, u8>(rdram, ctx); s32 ret = osContSetCh(PASS_RDRAM ch); @@ -76,7 +76,7 @@ extern "C" void osContSetCh_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void __osMotorAccess_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void __osMotorAccess_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSPfs) pfs = _arg<0, PTR(OSPfs)>(rdram, ctx); s32 flag = _arg<1, s32>(rdram, ctx); @@ -85,7 +85,7 @@ extern "C" void __osMotorAccess_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void osMotorInit_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osMotorInit_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSMesgQueue) mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx); PTR(OSPfs) pfs = _arg<1, PTR(OSPfs)>(rdram, ctx); int channel = _arg<2, s32>(rdram, ctx); @@ -95,7 +95,7 @@ extern "C" void osMotorInit_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void osMotorStart_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osMotorStart_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSPfs) pfs = _arg<0, PTR(OSPfs)>(rdram, ctx); s32 ret = osMotorStart(PASS_RDRAM pfs); @@ -103,7 +103,7 @@ extern "C" void osMotorStart_recomp(uint8_t* rdram, recomp_context* ctx) { _return(ctx, ret); } -extern "C" void osMotorStop_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osMotorStop_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(OSPfs) pfs = _arg<0, PTR(OSPfs)>(rdram, ctx); s32 ret = osMotorStop(PASS_RDRAM pfs); diff --git a/librecomp/src/dp.cpp b/librecomp/src/dp.cpp index 3098778..f7c9bc0 100644 --- a/librecomp/src/dp.cpp +++ b/librecomp/src/dp.cpp @@ -29,15 +29,15 @@ constexpr void update_bit(uint32_t& state, uint32_t flags, RDPStatusBit bit) { uint32_t rdp_state = 1 << (int)RDPStatusBit::BufferReady; -extern "C" void osDpSetNextBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osDpSetNextBuffer_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osDpGetStatus_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osDpGetStatus_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = rdp_state; } -extern "C" void osDpSetStatus_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osDpSetStatus_recomp(uint8_t *rdram, recomp_context *ctx) { update_bit(rdp_state, ctx->r4, RDPStatusBit::XbusDmem); update_bit(rdp_state, ctx->r4, RDPStatusBit::Freeze); update_bit(rdp_state, ctx->r4, RDPStatusBit::Flush); diff --git a/librecomp/src/eep.cpp b/librecomp/src/eep.cpp index ee73929..616398a 100644 --- a/librecomp/src/eep.cpp +++ b/librecomp/src/eep.cpp @@ -11,15 +11,15 @@ constexpr int eep4_block_count = eep4_size / eeprom_block_size; constexpr int eep16_size = 16384; constexpr int eep16_block_count = eep16_size / eeprom_block_size; -extern "C" void osEepromProbe_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osEepromProbe_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0x02; // EEP16K } -extern "C" void osEepromWrite_recomp(uint8_t* rdram, recomp_context* ctx) { - assert(false);// ctx->r2 = 8; // CONT_NO_RESPONSE_ERROR +extern "C" void osEepromWrite_recomp(uint8_t *rdram, recomp_context *ctx) { + assert(false); // ctx->r2 = 8; // CONT_NO_RESPONSE_ERROR } -extern "C" void osEepromLongWrite_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osEepromLongWrite_recomp(uint8_t *rdram, recomp_context *ctx) { uint8_t eep_address = ctx->r5; gpr buffer = ctx->r6; int32_t nbytes = ctx->r7; @@ -32,11 +32,11 @@ extern "C" void osEepromLongWrite_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = 0; } -extern "C" void osEepromRead_recomp(uint8_t* rdram, recomp_context* ctx) { - assert(false);// ctx->r2 = 8; // CONT_NO_RESPONSE_ERROR +extern "C" void osEepromRead_recomp(uint8_t *rdram, recomp_context *ctx) { + assert(false); // ctx->r2 = 8; // CONT_NO_RESPONSE_ERROR } -extern "C" void osEepromLongRead_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osEepromLongRead_recomp(uint8_t *rdram, recomp_context *ctx) { uint8_t eep_address = ctx->r5; gpr buffer = ctx->r6; int32_t nbytes = ctx->r7; diff --git a/librecomp/src/files.cpp b/librecomp/src/files.cpp index af6f18d..017e24e 100644 --- a/librecomp/src/files.cpp +++ b/librecomp/src/files.cpp @@ -4,13 +4,13 @@ constexpr std::u8string_view backup_suffix = u8".bak"; constexpr std::u8string_view temp_suffix = u8".temp"; std::ifstream recomp::open_input_backup_file(const std::filesystem::path& filepath, std::ios_base::openmode mode) { - std::filesystem::path backup_path{filepath}; + std::filesystem::path backup_path{ filepath }; backup_path += backup_suffix; - return std::ifstream{backup_path, mode}; + return std::ifstream{ backup_path, mode }; } std::ifstream recomp::open_input_file_with_backup(const std::filesystem::path& filepath, std::ios_base::openmode mode) { - std::ifstream ret{filepath, mode}; + std::ifstream ret{ filepath, mode }; // Check if the file failed to open and open the corresponding backup file instead if so. if (!ret.good()) { @@ -21,7 +21,7 @@ std::ifstream recomp::open_input_file_with_backup(const std::filesystem::path& f } std::ofstream recomp::open_output_file_with_backup(const std::filesystem::path& filepath, std::ios_base::openmode mode) { - std::filesystem::path temp_path{filepath}; + std::filesystem::path temp_path{ filepath }; temp_path += temp_suffix; std::ofstream temp_file_out{ temp_path, mode }; @@ -29,10 +29,10 @@ std::ofstream recomp::open_output_file_with_backup(const std::filesystem::path& } bool recomp::finalize_output_file_with_backup(const std::filesystem::path& filepath) { - std::filesystem::path backup_path{filepath}; + std::filesystem::path backup_path{ filepath }; backup_path += backup_suffix; - std::filesystem::path temp_path{filepath}; + std::filesystem::path temp_path{ filepath }; temp_path += temp_suffix; std::error_code ec; diff --git a/librecomp/src/flash.cpp b/librecomp/src/flash.cpp index 43407e8..9e4a227 100644 --- a/librecomp/src/flash.cpp +++ b/librecomp/src/flash.cpp @@ -1,7 +1,9 @@ #include #include + #include #include + #include "recomp.h" // TODO move this out into ultramodern code @@ -13,24 +15,24 @@ constexpr uint32_t page_count = flash_size / page_size; constexpr uint32_t sector_size = page_size * pages_per_sector; constexpr uint32_t sector_count = flash_size / sector_size; -void save_write_ptr(const void* in, uint32_t offset, uint32_t count); +void save_write_ptr(const void *in, uint32_t offset, uint32_t count); void save_write(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t count); void save_read(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t count); void save_clear(uint32_t start, uint32_t size, char value); std::array write_buffer; -extern "C" void osFlashInit_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashInit_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = ultramodern::flash_handle; } -extern "C" void osFlashReadStatus_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashReadStatus_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(u8) flash_status = ctx->r4; MEM_B(0, flash_status) = 0; } -extern "C" void osFlashReadId_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashReadId_recomp(uint8_t *rdram, recomp_context *ctx) { PTR(u32) flash_type = ctx->r4; PTR(u32) flash_maker = ctx->r5; @@ -39,24 +41,23 @@ extern "C" void osFlashReadId_recomp(uint8_t * rdram, recomp_context * ctx) { MEM_W(0, flash_maker) = 0x00C2001E; } -extern "C" void osFlashClearStatus_recomp(uint8_t * rdram, recomp_context * ctx) { - +extern "C" void osFlashClearStatus_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void osFlashAllErase_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashAllErase_recomp(uint8_t *rdram, recomp_context *ctx) { save_clear(0, ultramodern::save_size, 0xFF); ctx->r2 = 0; } -extern "C" void osFlashAllEraseThrough_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashAllEraseThrough_recomp(uint8_t *rdram, recomp_context *ctx) { save_clear(0, ultramodern::save_size, 0xFF); ctx->r2 = 0; } // This function is named sector but really means page. -extern "C" void osFlashSectorErase_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashSectorErase_recomp(uint8_t *rdram, recomp_context *ctx) { uint32_t page_num = (uint32_t)ctx->r4; // Prevent out of bounds erase @@ -71,7 +72,7 @@ extern "C" void osFlashSectorErase_recomp(uint8_t * rdram, recomp_context * ctx) } // Same naming issue as above. -extern "C" void osFlashSectorEraseThrough_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashSectorEraseThrough_recomp(uint8_t *rdram, recomp_context *ctx) { uint32_t page_num = (uint32_t)ctx->r4; // Prevent out of bounds erase @@ -85,17 +86,17 @@ extern "C" void osFlashSectorEraseThrough_recomp(uint8_t * rdram, recomp_context ctx->r2 = 0; } -extern "C" void osFlashCheckEraseEnd_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashCheckEraseEnd_recomp(uint8_t *rdram, recomp_context *ctx) { // All erases are blocking in this implementation, so this should always return OK. ctx->r2 = 0; // FLASH_STATUS_ERASE_OK } -extern "C" void osFlashWriteBuffer_recomp(uint8_t * rdram, recomp_context * ctx) { - OSIoMesg* mb = TO_PTR(OSIoMesg, ctx->r4); +extern "C" void osFlashWriteBuffer_recomp(uint8_t *rdram, recomp_context *ctx) { + OSIoMesg *mb = TO_PTR(OSIoMesg, ctx->r4); int32_t pri = ctx->r5; PTR(void) dramAddr = ctx->r6; PTR(OSMesgQueue) mq = ctx->r7; - + // Copy the input data into the write buffer for (size_t i = 0; i < page_size; i++) { write_buffer[i] = MEM_B(i, dramAddr); @@ -107,7 +108,7 @@ extern "C" void osFlashWriteBuffer_recomp(uint8_t * rdram, recomp_context * ctx) ctx->r2 = 0; } -extern "C" void osFlashWriteArray_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashWriteArray_recomp(uint8_t *rdram, recomp_context *ctx) { uint32_t page_num = ctx->r4; // Copy the write buffer into the save file @@ -116,8 +117,8 @@ extern "C" void osFlashWriteArray_recomp(uint8_t * rdram, recomp_context * ctx) ctx->r2 = 0; } -extern "C" void osFlashReadArray_recomp(uint8_t * rdram, recomp_context * ctx) { - OSIoMesg* mb = TO_PTR(OSIoMesg, ctx->r4); +extern "C" void osFlashReadArray_recomp(uint8_t *rdram, recomp_context *ctx) { + OSIoMesg *mb = TO_PTR(OSIoMesg, ctx->r4); int32_t pri = ctx->r5; uint32_t page_num = ctx->r6; PTR(void) dramAddr = ctx->r7; @@ -136,6 +137,6 @@ extern "C" void osFlashReadArray_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void osFlashChange_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osFlashChange_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } diff --git a/librecomp/src/math_routines.cpp b/librecomp/src/math_routines.cpp index 2bd21ce..bf2dd33 100644 --- a/librecomp/src/math_routines.cpp +++ b/librecomp/src/math_routines.cpp @@ -1,10 +1,11 @@ #include + #include "recomp.h" // TODO remove these by implementing the necessary instructions and control flow handling in the recompiler. // This has already been partially completed. -extern "C" void __udivdi3_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __udivdi3_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a / b; @@ -13,7 +14,7 @@ extern "C" void __udivdi3_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __divdi3_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __divdi3_recomp(uint8_t *rdram, recomp_context *ctx) { int64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); int64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); int64_t ret = a / b; @@ -22,7 +23,7 @@ extern "C" void __divdi3_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __umoddi3_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __umoddi3_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a % b; @@ -31,7 +32,7 @@ extern "C" void __umoddi3_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_div_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ull_div_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a / b; @@ -40,7 +41,7 @@ extern "C" void __ull_div_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ll_div_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ll_div_recomp(uint8_t *rdram, recomp_context *ctx) { int64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); int64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); int64_t ret = a / b; @@ -49,7 +50,7 @@ extern "C" void __ll_div_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ll_mul_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ll_mul_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a * b; @@ -58,7 +59,7 @@ extern "C" void __ll_mul_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_rem_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ull_rem_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); uint64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu); uint64_t ret = a % b; @@ -67,14 +68,14 @@ extern "C" void __ull_rem_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r3 = (int32_t)(ret >> 0); } -extern "C" void __ull_to_d_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ull_to_d_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); double ret = (double)a; ctx->f0.d = ret; } -extern "C" void __ull_to_f_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __ull_to_f_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu); float ret = (float)a; diff --git a/librecomp/src/overlays.cpp b/librecomp/src/overlays.cpp index 9abd751..d8c395c 100644 --- a/librecomp/src/overlays.cpp +++ b/librecomp/src/overlays.cpp @@ -7,14 +7,14 @@ #include "ultramodern/ultramodern.hpp" -#include "recomp.h" #include "overlays.hpp" +#include "recomp.h" #include "sections.h" -static recomp::overlays::overlay_section_table_data_t sections_info {}; -static recomp::overlays::overlays_by_index_t overlays_info {}; +static recomp::overlays::overlay_section_table_data_t sections_info{}; +static recomp::overlays::overlays_by_index_t overlays_info{}; -static SectionTableEntry* patch_code_sections = nullptr; +static SectionTableEntry *patch_code_sections = nullptr; static std::vector patch_data; void recomp::overlays::register_overlays(const overlay_section_table_data_t& sections, const overlays_by_index_t& overlays) { @@ -22,7 +22,7 @@ void recomp::overlays::register_overlays(const overlay_section_table_data_t& sec overlays_info = overlays; } -void recomp::overlays::register_patches(const char* patch, std::size_t size, SectionTableEntry* sections) { +void recomp::overlays::register_patches(const char *patch, std::size_t size, SectionTableEntry *sections) { patch_code_sections = sections; patch_data.resize(size); @@ -44,7 +44,7 @@ struct LoadedSection { }; std::vector loaded_sections{}; -std::unordered_map func_map{}; +std::unordered_map func_map{}; void load_overlay(size_t section_table_index, int32_t ram) { const SectionTableEntry& section = sections_info.code_sections[section_table_index]; @@ -73,29 +73,29 @@ static void load_patch_functions() { load_special_overlay(patch_code_sections[0], patch_code_sections[0].ram_addr); } -void recomp::overlays::read_patch_data(uint8_t* rdram, gpr patch_data_address) { +void recomp::overlays::read_patch_data(uint8_t *rdram, gpr patch_data_address) { for (size_t i = 0; i < patch_data.size(); i++) { MEM_B(i, patch_data_address) = patch_data[i]; } } extern "C" { -int32_t* section_addresses = nullptr; +int32_t *section_addresses = nullptr; } extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size) { // Search for the first section that's included in the loaded rom range // Sections were sorted by `init_overlays` so we can use the bounds functions - auto lower = std::lower_bound(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], rom, + auto lower = std::lower_bound( + §ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], rom, [](const SectionTableEntry& entry, uint32_t addr) { return entry.rom_addr < addr; - } - ); - auto upper = std::upper_bound(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], (uint32_t)(rom + size), + }); + auto upper = std::upper_bound( + §ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], (uint32_t)(rom + size), [](uint32_t addr, const SectionTableEntry& entry) { return addr < entry.size + entry.rom_addr; - } - ); + }); // Load the overlays that were found for (auto it = lower; it != upper; ++it) { load_overlay(std::distance(§ions_info.code_sections[0], it), it->rom_addr - rom + ram_addr); @@ -106,7 +106,9 @@ extern "C" void unload_overlay_by_id(uint32_t id) { uint32_t section_table_index = overlays_info.table[id]; const SectionTableEntry& section = sections_info.code_sections[section_table_index]; - auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { return s.section_table_index == section_table_index; }); + auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { + return s.section_table_index == section_table_index; + }); if (find_it != loaded_sections.end()) { // Determine where each function was loaded to and remove that entry from the function map @@ -144,11 +146,12 @@ extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) { if (ram_addr < (it->loaded_ram_addr + section.size) && (ram_addr + size) >= it->loaded_ram_addr) { // Check if the section isn't entirely in the loaded region if (ram_addr > it->loaded_ram_addr || (ram_addr + size) < (it->loaded_ram_addr + section.size)) { - fprintf(stderr, + fprintf( + stderr, "Cannot partially unload section\n" " rom: 0x%08X size: 0x%08X loaded_addr: 0x%08X\n" " unloaded_ram: 0x%08X unloaded_size : 0x%08X\n", - section.rom_addr, section.size, it->loaded_ram_addr, ram_addr, size); + section.rom_addr, section.size, it->loaded_ram_addr, ram_addr, size); assert(false); std::exit(EXIT_FAILURE); } @@ -177,16 +180,16 @@ void recomp::overlays::init_overlays() { } // Sort the executable sections by rom address - std::sort(§ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], + std::sort( + §ions_info.code_sections[0], §ions_info.code_sections[sections_info.num_code_sections], [](const SectionTableEntry& a, const SectionTableEntry& b) { return a.rom_addr < b.rom_addr; - } - ); + }); load_patch_functions(); } -extern "C" recomp_func_t * get_function(int32_t addr) { +extern "C" recomp_func_t *get_function(int32_t addr) { auto func_find = func_map.find(addr); if (func_find == func_map.end()) { fprintf(stderr, "Failed to find function at 0x%08X\n", addr); @@ -195,4 +198,3 @@ extern "C" recomp_func_t * get_function(int32_t addr) { } return func_find->second; } - diff --git a/librecomp/src/pak.cpp b/librecomp/src/pak.cpp index 92e0f10..aff72b6 100644 --- a/librecomp/src/pak.cpp +++ b/librecomp/src/pak.cpp @@ -2,34 +2,34 @@ #include #include -extern "C" void osPfsInitPak_recomp(uint8_t * rdram, recomp_context* ctx) { +extern "C" void osPfsInitPak_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFreeBlocks_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsFreeBlocks_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsAllocateFile_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsAllocateFile_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsDeleteFile_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsDeleteFile_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFileState_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsFileState_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsFindFile_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsFindFile_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsReadWriteFile_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsReadWriteFile_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } -extern "C" void osPfsChecker_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osPfsChecker_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 1; // PFS_ERR_NOPACK } diff --git a/librecomp/src/pi.cpp b/librecomp/src/pi.cpp index 65a896f..7009775 100644 --- a/librecomp/src/pi.cpp +++ b/librecomp/src/pi.cpp @@ -1,15 +1,17 @@ -#include -#include #include #include -#include +#include +#include #include -#include "recomp.h" -#include "game.hpp" -#include "files.hpp" +#include + #include #include +#include "files.hpp" +#include "game.hpp" +#include "recomp.h" + static std::vector rom; bool recomp::is_rom_loaded() { @@ -35,14 +37,14 @@ constexpr uint32_t phys_to_k1(uint32_t addr) { return addr | 0xA0000000; } -extern "C" void __osPiGetAccess_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void __osPiGetAccess_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void __osPiRelAccess_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void __osPiRelAccess_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ultramodern::cart_handle); +extern "C" void osCartRomInit_recomp(uint8_t *rdram, recomp_context *ctx) { + OSPiHandle *handle = TO_PTR(OSPiHandle, ultramodern::cart_handle); handle->type = 0; // cart handle->baseAddress = phys_to_k1(rom_base); handle->domain = 0; @@ -50,8 +52,8 @@ extern "C" void osCartRomInit_recomp(uint8_t* rdram, recomp_context* ctx) { ctx->r2 = (gpr)ultramodern::cart_handle; } -extern "C" void osDriveRomInit_recomp(uint8_t * rdram, recomp_context * ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ultramodern::drive_handle); +extern "C" void osDriveRomInit_recomp(uint8_t *rdram, recomp_context *ctx) { + OSPiHandle *handle = TO_PTR(OSPiHandle, ultramodern::drive_handle); handle->type = 1; // bulk handle->baseAddress = phys_to_k1(drive_base); handle->domain = 0; @@ -59,28 +61,28 @@ extern "C" void osDriveRomInit_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = (gpr)ultramodern::drive_handle; } -extern "C" void osCreatePiManager_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osCreatePiManager_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -void recomp::do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t physical_addr, size_t num_bytes) { +void recomp::do_rom_read(uint8_t *rdram, gpr ram_address, uint32_t physical_addr, size_t num_bytes) { // TODO use word copies when possible // TODO handle misaligned DMA assert((physical_addr & 0x1) == 0 && "Only PI DMA from aligned ROM addresses is currently supported"); assert((ram_address & 0x7) == 0 && "Only PI DMA to aligned RDRAM addresses is currently supported"); assert((num_bytes & 0x1) == 0 && "Only PI DMA with aligned sizes is currently supported"); - uint8_t* rom_addr = rom.data() + physical_addr - rom_base; + uint8_t *rom_addr = rom.data() + physical_addr - rom_base; for (size_t i = 0; i < num_bytes; i++) { MEM_B(i, ram_address) = *rom_addr; rom_addr++; } } -void recomp::do_rom_pio(uint8_t* rdram, gpr ram_address, uint32_t physical_addr) { +void recomp::do_rom_pio(uint8_t *rdram, gpr ram_address, uint32_t physical_addr) { assert((physical_addr & 0x3) == 0 && "PIO not 4-byte aligned in device, currently unsupported"); assert((ram_address & 0x3) == 0 && "PIO not 4-byte aligned in RDRAM, currently unsupported"); - uint8_t* rom_addr = rom.data() + physical_addr - rom_base; + uint8_t *rom_addr = rom.data() + physical_addr - rom_base; MEM_B(0, ram_address) = *rom_addr++; MEM_B(1, ram_address) = *rom_addr++; MEM_B(2, ram_address) = *rom_addr++; @@ -99,7 +101,7 @@ const std::u8string save_folder = u8"saves"; extern std::filesystem::path config_path; std::filesystem::path get_save_file_path() { - return config_path / save_folder / (std::u8string{recomp::current_game_id()} + u8".bin"); + return config_path / save_folder / (std::u8string{ recomp::current_game_id() } + u8".bin"); } void update_save_file() { @@ -119,7 +121,8 @@ void update_save_file() { saving_failed = !recomp::finalize_output_file_with_backup(get_save_file_path()); } if (saving_failed) { - ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions and whether the save folder has been moved to Dropbox or similar, as this can cause issues."); + ultramodern::error_handling::message_box("Failed to write to the save file. Check your file permissions and whether the save " + "folder has been moved to Dropbox or similar, as this can cause issues."); } } @@ -148,18 +151,18 @@ void saving_thread_func(RDRAM_ARG1) { } } -void save_write_ptr(const void* in, uint32_t offset, uint32_t count) { +void save_write_ptr(const void *in, uint32_t offset, uint32_t count) { { - std::lock_guard lock { save_context.save_buffer_mutex }; + std::lock_guard lock{ save_context.save_buffer_mutex }; memcpy(&save_context.save_buffer[offset], in, count); } - + save_context.write_sempahore.signal(); } void save_write(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t count) { { - std::lock_guard lock { save_context.save_buffer_mutex }; + std::lock_guard lock{ save_context.save_buffer_mutex }; for (uint32_t i = 0; i < count; i++) { save_context.save_buffer[offset + i] = MEM_B(i, rdram_address); } @@ -169,7 +172,7 @@ void save_write(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t cou } void save_read(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t count) { - std::lock_guard lock { save_context.save_buffer_mutex }; + std::lock_guard lock{ save_context.save_buffer_mutex }; for (size_t i = 0; i < count; i++) { MEM_B(i, rdram_address) = save_context.save_buffer[offset + i]; } @@ -177,7 +180,7 @@ void save_read(RDRAM_ARG PTR(void) rdram_address, uint32_t offset, uint32_t coun void save_clear(uint32_t start, uint32_t size, char value) { { - std::lock_guard lock { save_context.save_buffer_mutex }; + std::lock_guard lock{ save_context.save_buffer_mutex }; std::fill_n(save_context.save_buffer.begin() + start, size, value); } @@ -200,7 +203,7 @@ void ultramodern::init_saving(RDRAM_ARG1) { save_context.save_buffer.fill(0); } - save_context.saving_thread = std::thread{saving_thread_func, PASS_RDRAM}; + save_context.saving_thread = std::thread{ saving_thread_func, PASS_RDRAM }; } void ultramodern::join_saving_thread() { @@ -217,32 +220,37 @@ void do_dma(RDRAM_ARG PTR(OSMesgQueue) mq, gpr rdram_address, uint32_t physical_ // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); - } else if (physical_addr >= sram_base) { + } + else if (physical_addr >= sram_base) { // read sram save_read(rdram, rdram_address, physical_addr - sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); - } else { + } + else { fprintf(stderr, "[WARN] PI DMA read from unknown region, phys address 0x%08X\n", physical_addr); } - } else { + } + else { if (physical_addr >= rom_base) { // write cart rom throw std::runtime_error("ROM DMA write unimplemented"); - } else if (physical_addr >= sram_base) { + } + else if (physical_addr >= sram_base) { // write sram save_write(rdram, rdram_address, physical_addr - sram_base, size); // Send a message to the mq to indicate that the transfer completed osSendMesg(rdram, mq, 0, OS_MESG_NOBLOCK); - } else { + } + else { fprintf(stderr, "[WARN] PI DMA write to unknown region, phys address 0x%08X\n", physical_addr); } } } -extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) { +extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context *ctx) { uint32_t mb = ctx->r4; uint32_t pri = ctx->r5; uint32_t direction = ctx->r6; @@ -259,9 +267,9 @@ extern "C" void osPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) { ctx->r2 = 0; } -extern "C" void osEPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4); - OSIoMesg* mb = TO_PTR(OSIoMesg, ctx->r5); +extern "C" void osEPiStartDma_recomp(RDRAM_ARG recomp_context *ctx) { + OSPiHandle *handle = TO_PTR(OSPiHandle, ctx->r4); + OSIoMesg *mb = TO_PTR(OSIoMesg, ctx->r5); uint32_t direction = ctx->r6; uint32_t devAddr = handle->baseAddress | mb->devAddr; gpr dramAddr = mb->dramAddr; @@ -276,8 +284,8 @@ extern "C" void osEPiStartDma_recomp(RDRAM_ARG recomp_context* ctx) { ctx->r2 = 0; } -extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context * ctx) { - OSPiHandle* handle = TO_PTR(OSPiHandle, ctx->r4); +extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context *ctx) { + OSPiHandle *handle = TO_PTR(OSPiHandle, ctx->r4); uint32_t devAddr = handle->baseAddress | ctx->r5; gpr dramAddr = ctx->r6; uint32_t physical_addr = k1_to_phys(devAddr); @@ -285,7 +293,8 @@ extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context * ctx) { if (physical_addr > rom_base) { // cart rom recomp::do_rom_pio(PASS_RDRAM dramAddr, physical_addr); - } else { + } + else { // sram assert(false && "SRAM ReadIo unimplemented"); } @@ -293,10 +302,10 @@ extern "C" void osEPiReadIo_recomp(RDRAM_ARG recomp_context * ctx) { ctx->r2 = 0; } -extern "C" void osPiGetStatus_recomp(RDRAM_ARG recomp_context * ctx) { +extern "C" void osPiGetStatus_recomp(RDRAM_ARG recomp_context *ctx) { ctx->r2 = 0; } -extern "C" void osPiRawStartDma_recomp(RDRAM_ARG recomp_context * ctx) { +extern "C" void osPiRawStartDma_recomp(RDRAM_ARG recomp_context *ctx) { ctx->r2 = 0; } diff --git a/librecomp/src/print.cpp b/librecomp/src/print.cpp index 944e9fe..2c1c451 100644 --- a/librecomp/src/print.cpp +++ b/librecomp/src/print.cpp @@ -2,34 +2,35 @@ #include #include -#include "recomp.h" + #include "euc-jp.hpp" +#include "recomp.h" -extern "C" void __checkHardware_msp_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __checkHardware_msp_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0; } -extern "C" void __checkHardware_kmc_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __checkHardware_kmc_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0; } -extern "C" void __checkHardware_isv_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __checkHardware_isv_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0; } -extern "C" void __osInitialize_msp_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osInitialize_msp_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void __osInitialize_kmc_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osInitialize_kmc_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void __osInitialize_isv_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osInitialize_isv_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void isPrintfInit_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void isPrintfInit_recomp(uint8_t *rdram, recomp_context *ctx) { } -extern "C" void __osRdbSend_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osRdbSend_recomp(uint8_t *rdram, recomp_context *ctx) { gpr buf = ctx->r4; size_t size = ctx->r5; u32 type = (u32)ctx->r6; @@ -45,16 +46,16 @@ extern "C" void __osRdbSend_recomp(uint8_t * rdram, recomp_context * ctx) { ctx->r2 = size; } -extern "C" void is_proutSyncPrintf_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void is_proutSyncPrintf_recomp(uint8_t *rdram, recomp_context *ctx) { // Buffering to speed up print performance static std::vector print_buffer; gpr buf = ctx->r5; size_t size = ctx->r6; - //for (size_t i = 0; i < size; i++) { - // // Add the new character to the buffer - // char cur_char = MEM_B(i, buf); + // for (size_t i = 0; i < size; i++) { + // // Add the new character to the buffer + // char cur_char = MEM_B(i, buf); // // If the new character is a newline, flush the buffer // if (cur_char == '\n') { @@ -66,7 +67,7 @@ extern "C" void is_proutSyncPrintf_recomp(uint8_t * rdram, recomp_context * ctx) // } //} - //fwrite(to_print.get(), size, 1, stdout); + // fwrite(to_print.get(), size, 1, stdout); ctx->r2 = 1; } diff --git a/librecomp/src/recomp.cpp b/librecomp/src/recomp.cpp index ce50a81..056ba5a 100644 --- a/librecomp/src/recomp.cpp +++ b/librecomp/src/recomp.cpp @@ -1,22 +1,24 @@ +#include +#include #include #include #include -#include -#include -#include -#include #include #include -#include +#include #include -#include +#include +#include +#include -#include "recomp.h" -#include "overlays.hpp" -#include "game.hpp" #include "xxHash/xxh3.h" -#include "ultramodern/ultramodern.hpp" + #include "ultramodern/error_handling.hpp" +#include "ultramodern/ultramodern.hpp" + +#include "game.hpp" +#include "overlays.hpp" +#include "recomp.h" #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { @@ -40,7 +42,7 @@ std::mutex current_game_mutex; // Global variables std::filesystem::path config_path; -std::unordered_map game_roms {}; +std::unordered_map game_roms{}; std::u8string recomp::GameEntry::stored_filename() const { return game_id + u8".z64"; @@ -64,14 +66,14 @@ bool check_hash(const std::vector& rom_data, uint64_t expected_hash) { static std::vector read_file(const std::filesystem::path& path) { std::vector ret; - std::ifstream file{ path, std::ios::binary}; + std::ifstream file{ path, std::ios::binary }; if (file.good()) { file.seekg(0, std::ios::end); ret.resize(file.tellg()); file.seekg(0, std::ios::beg); - file.read(reinterpret_cast(ret.data()), ret.size()); + file.read(reinterpret_cast(ret.data()), ret.size()); } return ret; @@ -84,7 +86,7 @@ bool write_file(const std::filesystem::path& path, const std::vector& d return false; } - out_file.write(reinterpret_cast(data.data()), data.size()); + out_file.write(reinterpret_cast(data.data()), data.size()); return true; } @@ -108,7 +110,7 @@ bool recomp::is_rom_valid(std::u8string& game_id) { } void recomp::check_all_stored_roms() { - for (const auto& cur_rom_entry: game_roms) { + for (const auto& cur_rom_entry : game_roms) { if (check_stored_rom(cur_rom_entry.second)) { valid_game_roms.insert(cur_rom_entry.first); } @@ -121,7 +123,7 @@ bool recomp::load_stored_rom(std::u8string& game_id) { if (find_it == game_roms.end()) { return false; } - + std::vector stored_rom_data = read_file(config_path / find_it->second.stored_filename()); if (!check_hash(stored_rom_data, find_it->second.rom_hash)) { @@ -134,7 +136,7 @@ bool recomp::load_stored_rom(std::u8string& game_id) { return true; } -const std::array first_rom_bytes { 0x80, 0x37, 0x12, 0x40 }; +const std::array first_rom_bytes{ 0x80, 0x37, 0x12, 0x40 }; enum class ByteswapType { NotByteswapped, @@ -149,25 +151,22 @@ ByteswapType check_rom_start(const std::vector& rom_data) { } auto check_match = [&](uint8_t index0, uint8_t index1, uint8_t index2, uint8_t index3) { - return - rom_data[0] == first_rom_bytes[index0] && - rom_data[1] == first_rom_bytes[index1] && - rom_data[2] == first_rom_bytes[index2] && - rom_data[3] == first_rom_bytes[index3]; + return rom_data[0] == first_rom_bytes[index0] && rom_data[1] == first_rom_bytes[index1] && rom_data[2] == first_rom_bytes[index2] && + rom_data[3] == first_rom_bytes[index3]; }; // Check if the ROM is already in the correct byte order. - if (check_match(0,1,2,3)) { + if (check_match(0, 1, 2, 3)) { return ByteswapType::NotByteswapped; } // Check if the ROM has been byteswapped in groups of 4 bytes. - if (check_match(3,2,1,0)) { + if (check_match(3, 2, 1, 0)) { return ByteswapType::Byteswapped4; } // Check if the ROM has been byteswapped in groups of 2 bytes. - if (check_match(1,0,3,2)) { + if (check_match(1, 0, 3, 2)) { return ByteswapType::Byteswapped2; } @@ -223,12 +222,13 @@ recomp::RomValidationError recomp::select_rom(const std::filesystem::path& rom_p } if (!check_hash(rom_data, game_entry.rom_hash)) { - const std::string_view name{ reinterpret_cast(rom_data.data()) + 0x20, game_entry.internal_name.size()}; + const std::string_view name{ reinterpret_cast(rom_data.data()) + 0x20, game_entry.internal_name.size() }; if (name == game_entry.internal_name) { return recomp::RomValidationError::IncorrectVersion; } else { - if (game_entry.is_enabled && std::string_view{ reinterpret_cast(rom_data.data()) + 0x20, 19 } == game_entry.internal_name) { + if (game_entry.is_enabled && + std::string_view{ reinterpret_cast(rom_data.data()) + 0x20, 19 } == game_entry.internal_name) { return recomp::RomValidationError::NotYet; } else { @@ -238,11 +238,11 @@ recomp::RomValidationError recomp::select_rom(const std::filesystem::path& rom_p } write_file(config_path / game_entry.stored_filename(), rom_data); - + return recomp::RomValidationError::Good; } -extern "C" void osGetMemSize_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osGetMemSize_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 8 * 1024 * 1024; } @@ -250,7 +250,7 @@ enum class StatusReg { FR = 0x04000000, }; -extern "C" void cop0_status_write(recomp_context* ctx, gpr value) { +extern "C" void cop0_status_write(recomp_context *ctx, gpr value) { uint32_t old_sr = ctx->status_reg; uint32_t new_sr = (uint32_t)value; uint32_t changed = old_sr ^ new_sr; @@ -280,16 +280,16 @@ extern "C" void cop0_status_write(recomp_context* ctx, gpr value) { assert(false); exit(EXIT_FAILURE); } - + // Update the status register in the context ctx->status_reg = new_sr; } -extern "C" gpr cop0_status_read(recomp_context* ctx) { +extern "C" gpr cop0_status_read(recomp_context *ctx) { return (gpr)(int32_t)ctx->status_reg; } -extern "C" void switch_error(const char* func, uint32_t vram, uint32_t jtbl) { +extern "C" void switch_error(const char *func, uint32_t vram, uint32_t jtbl) { printf("Switch-case out of bounds in %s at 0x%08X for jump table at 0x%08X\n", func, vram, jtbl); assert(false); exit(EXIT_FAILURE); @@ -301,17 +301,17 @@ extern "C" void do_break(uint32_t vram) { exit(EXIT_FAILURE); } -void run_thread_function(uint8_t* rdram, uint64_t addr, uint64_t sp, uint64_t arg) { +void run_thread_function(uint8_t *rdram, uint64_t addr, uint64_t sp, uint64_t arg) { recomp_context ctx{}; ctx.r29 = sp; ctx.r4 = arg; ctx.mips3_float_mode = 0; ctx.f_odd = &ctx.f0.u32h; - recomp_func_t* func = get_function(addr); + recomp_func_t *func = get_function(addr); func(rdram, &ctx); } -void init(uint8_t* rdram, recomp_context* ctx, gpr entrypoint) { +void init(uint8_t *rdram, recomp_context *ctx, gpr entrypoint) { // Initialize the overlays recomp::overlays::init_overlays(); @@ -337,9 +337,9 @@ void init(uint8_t* rdram, recomp_context* ctx, gpr entrypoint) { constexpr int32_t osVersion = 0x80000314; constexpr int32_t osMemSize = 0x80000318; constexpr int32_t osAppNMIBuffer = 0x8000031c; - MEM_W(osTvType, 0) = 1; // NTSC - MEM_W(osRomBase, 0) = 0xB0000000u; // standard rom base - MEM_W(osResetType, 0) = 0; // cold reset + MEM_W(osTvType, 0) = 1; // NTSC + MEM_W(osRomBase, 0) = 0xB0000000u; // standard rom base + MEM_W(osResetType, 0) = 0; // cold reset MEM_W(osMemSize, 0) = 8 * 1024 * 1024; // 8MB } @@ -374,25 +374,22 @@ void ultramodern::quit() { } void recomp::start( - ultramodern::renderer::WindowHandle window_handle, - const recomp::rsp::callbacks_t& rsp_callbacks, - const ultramodern::renderer::callbacks_t& renderer_callbacks, - const ultramodern::audio_callbacks_t& audio_callbacks, - const ultramodern::input::callbacks_t& input_callbacks, - const ultramodern::gfx_callbacks_t& gfx_callbacks_, - const ultramodern::events::callbacks_t& events_callbacks, - const ultramodern::error_handling::callbacks_t& error_handling_callbacks_ -) { + ultramodern::renderer::WindowHandle window_handle, const recomp::rsp::callbacks_t& rsp_callbacks, + const ultramodern::renderer::callbacks_t& renderer_callbacks, const ultramodern::audio_callbacks_t& audio_callbacks, + const ultramodern::input::callbacks_t& input_callbacks, const ultramodern::gfx_callbacks_t& gfx_callbacks_, + const ultramodern::events::callbacks_t& events_callbacks, const ultramodern::error_handling::callbacks_t& error_handling_callbacks_) { recomp::check_all_stored_roms(); recomp::rsp::set_callbacks(rsp_callbacks); - static const ultramodern::rsp::callbacks_t ultramodern_rsp_callbacks { + static const ultramodern::rsp::callbacks_t ultramodern_rsp_callbacks{ .init = recomp::rsp::constants_init, .run_task = recomp::rsp::run_task, }; - ultramodern::set_callbacks(ultramodern_rsp_callbacks, renderer_callbacks, audio_callbacks, input_callbacks, gfx_callbacks_, events_callbacks, error_handling_callbacks_); + ultramodern::set_callbacks( + ultramodern_rsp_callbacks, renderer_callbacks, audio_callbacks, input_callbacks, gfx_callbacks_, events_callbacks, + error_handling_callbacks_); ultramodern::gfx_callbacks_t gfx_callbacks = gfx_callbacks_; @@ -415,20 +412,20 @@ void recomp::start( std::unique_ptr rdram_buffer = std::make_unique(ultramodern::rdram_size); std::memset(rdram_buffer.get(), 0, ultramodern::rdram_size); - std::thread game_thread{[](ultramodern::renderer::WindowHandle window_handle, uint8_t* rdram) { - debug_printf("[Recomp] Starting\n"); + std::thread game_thread{ + [](ultramodern::renderer::WindowHandle window_handle, uint8_t *rdram) { + debug_printf("[Recomp] Starting\n"); - ultramodern::set_native_thread_name("Game Start Thread"); + ultramodern::set_native_thread_name("Game Start Thread"); - ultramodern::preinit(rdram, window_handle); + ultramodern::preinit(rdram, window_handle); - game_status.wait(GameStatus::None); - recomp_context context{}; + game_status.wait(GameStatus::None); + recomp_context context{}; - switch (game_status.load()) { - // TODO refactor this to allow a project to specify what entrypoint function to run for a give game. - case GameStatus::Running: - { + switch (game_status.load()) { + // TODO refactor this to allow a project to specify what entrypoint function to run for a give game. + case GameStatus::Running: { if (!recomp::load_stored_rom(current_game.value())) { ultramodern::error_handling::message_box("Error opening stored ROM! Please restart this program."); } @@ -443,20 +440,21 @@ void recomp::start( try { game_entry.entrypoint(rdram, &context); } catch (ultramodern::thread_terminated& terminated) { - } - } - break; + } break; - case GameStatus::Quit: - break; + case GameStatus::Quit: + break; - case GameStatus::None: - break; - } + case GameStatus::None: + break; + } - debug_printf("[Recomp] Quitting\n"); - }, window_handle, rdram_buffer.get()}; + debug_printf("[Recomp] Quitting\n"); + }, + window_handle, + rdram_buffer.get(), + }; while (!exited) { ultramodern::sleep_milliseconds(1); diff --git a/librecomp/src/rsp.cpp b/librecomp/src/rsp.cpp index 50bf73b..e7f4dcc 100644 --- a/librecomp/src/rsp.cpp +++ b/librecomp/src/rsp.cpp @@ -1,10 +1,10 @@ #include -#include #include +#include #include "rsp.hpp" -static recomp::rsp::callbacks_t rsp_callbacks {}; +static recomp::rsp::callbacks_t rsp_callbacks{}; void recomp::rsp::set_callbacks(const callbacks_t& callbacks) { rsp_callbacks = callbacks; @@ -26,16 +26,17 @@ void recomp::rsp::constants_init() { for (u16 index = 0; index < 512; index++) { u64 a = (index + 512) >> ((index % 2 == 1) ? 1 : 0); u64 b = 1 << 17; - //find the largest b where b < 1.0 / sqrt(a) - while (a * (b + 1) * (b + 1) < (u64(1) << 44)) b++; + // find the largest b where b < 1.0 / sqrt(a) + while (a * (b + 1) * (b + 1) < (u64(1) << 44)) + b++; rspInverseSquareRoots[index] = u16(b >> 1); } } // Runs a recompiled RSP microcode -bool recomp::rsp::run_task(uint8_t* rdram, const OSTask* task) { +bool recomp::rsp::run_task(uint8_t *rdram, const OSTask *task) { assert(rsp_callbacks.get_rsp_microcode != nullptr); - RspUcodeFunc* ucode_func = rsp_callbacks.get_rsp_microcode(task); + RspUcodeFunc *ucode_func = rsp_callbacks.get_rsp_microcode(task); if (ucode_func == nullptr) { fprintf(stderr, "No registered RSP ucode for %" PRIu32 " (returned `nullptr`)\n", task->t.type); diff --git a/librecomp/src/sp.cpp b/librecomp/src/sp.cpp index ae0f44f..1cc6f2f 100644 --- a/librecomp/src/sp.cpp +++ b/librecomp/src/sp.cpp @@ -1,21 +1,24 @@ #include #include + #include + #include "recomp.h" -extern "C" void osSpTaskLoad_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSpTaskLoad_recomp(uint8_t *rdram, recomp_context *ctx) { // Nothing to do here } bool dump_frame = false; -extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) { - //printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4); - OSTask* task = TO_PTR(OSTask, ctx->r4); +extern "C" void osSpTaskStartGo_recomp(uint8_t *rdram, recomp_context *ctx) { + // printf("[sp] osSpTaskStartGo(0x%08X)\n", (uint32_t)ctx->r4); + OSTask *task = TO_PTR(OSTask, ctx->r4); if (task->t.type == M_GFXTASK) { - //printf("[sp] Gfx task: %08X\n", (uint32_t)ctx->r4); - } else if (task->t.type == M_AUDTASK) { - //printf("[sp] Audio task: %08X\n", (uint32_t)ctx->r4); + // printf("[sp] Gfx task: %08X\n", (uint32_t)ctx->r4); + } + else if (task->t.type == M_AUDTASK) { + // printf("[sp] Audio task: %08X\n", (uint32_t)ctx->r4); } // For debugging if (dump_frame) { @@ -24,7 +27,7 @@ extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) { std::unique_ptr ram_unswapped = std::make_unique(ram_size); snprintf(addr_str, sizeof(addr_str) - 1, "%08X", task->t.data_ptr); addr_str[sizeof(addr_str) - 1] = '\0'; - std::ofstream dump_file{ "ramdump" + std::string{ addr_str } + ".bin", std::ios::binary}; + std::ofstream dump_file{ "ramdump" + std::string{ addr_str } + ".bin", std::ios::binary }; for (size_t i = 0; i < ram_size; i++) { ram_unswapped[i] = rdram[i ^ 3]; @@ -36,15 +39,15 @@ extern "C" void osSpTaskStartGo_recomp(uint8_t* rdram, recomp_context* ctx) { ultramodern::submit_rsp_task(rdram, ctx->r4); } -extern "C" void osSpTaskYield_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSpTaskYield_recomp(uint8_t *rdram, recomp_context *ctx) { // Ignore yield requests (acts as if the task completed before it received the yield request) } -extern "C" void osSpTaskYielded_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSpTaskYielded_recomp(uint8_t *rdram, recomp_context *ctx) { // Task yield requests are ignored, so always return 0 as tasks will never be yielded ctx->r2 = 0; } -extern "C" void __osSpSetPc_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void __osSpSetPc_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } diff --git a/librecomp/src/ultra_stubs.cpp b/librecomp/src/ultra_stubs.cpp index 9dd263b..2ba9641 100644 --- a/librecomp/src/ultra_stubs.cpp +++ b/librecomp/src/ultra_stubs.cpp @@ -1,45 +1,45 @@ #include #include + #include "recomp.h" // None of these functions need to be reimplemented, so stub them out -extern "C" void osUnmapTLBAll_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osUnmapTLBAll_recomp(uint8_t *rdram, recomp_context *ctx) { // TODO this will need to be implemented in the future for any games that actually use the TLB } -extern "C" void osVoiceInit_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceInit_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 11; // CONT_ERR_DEVICE } -extern "C" void osVoiceSetWord_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceSetWord_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceCheckWord_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceCheckWord_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceStopReadData_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceStopReadData_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceMaskDictionary_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceMaskDictionary_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceStartReadData_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceStartReadData_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceControlGain_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceControlGain_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceGetReadData_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceGetReadData_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } -extern "C" void osVoiceClearDictionary_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVoiceClearDictionary_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); } - diff --git a/librecomp/src/ultra_translation.cpp b/librecomp/src/ultra_translation.cpp index 24ea0bd..e68306f 100644 --- a/librecomp/src/ultra_translation.cpp +++ b/librecomp/src/ultra_translation.cpp @@ -1,132 +1,135 @@ #include + #include #include + #include "recomp.h" -extern "C" void osInitialize_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osInitialize_recomp(uint8_t *rdram, recomp_context *ctx) { osInitialize(); } -extern "C" void __osInitialize_common_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osInitialize_common_recomp(uint8_t *rdram, recomp_context *ctx) { osInitialize(); } -extern "C" void osCreateThread_recomp(uint8_t* rdram, recomp_context* ctx) { - osCreateThread(rdram, (int32_t)ctx->r4, (OSId)ctx->r5, (int32_t)ctx->r6, (int32_t)ctx->r7, - (int32_t)MEM_W(0x10, ctx->r29), (OSPri)MEM_W(0x14, ctx->r29)); +extern "C" void osCreateThread_recomp(uint8_t *rdram, recomp_context *ctx) { + osCreateThread( + rdram, (int32_t)ctx->r4, (OSId)ctx->r5, (int32_t)ctx->r6, (int32_t)ctx->r7, (int32_t)MEM_W(0x10, ctx->r29), + (OSPri)MEM_W(0x14, ctx->r29)); } -extern "C" void osStartThread_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osStartThread_recomp(uint8_t *rdram, recomp_context *ctx) { osStartThread(rdram, (int32_t)ctx->r4); } -extern "C" void osStopThread_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osStopThread_recomp(uint8_t *rdram, recomp_context *ctx) { osStopThread(rdram, (int32_t)ctx->r4); } -extern "C" void osDestroyThread_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osDestroyThread_recomp(uint8_t *rdram, recomp_context *ctx) { osDestroyThread(rdram, (int32_t)ctx->r4); } -extern "C" void osYieldThread_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osYieldThread_recomp(uint8_t *rdram, recomp_context *ctx) { assert(false); // osYieldThread(rdram); } -extern "C" void osSetThreadPri_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSetThreadPri_recomp(uint8_t *rdram, recomp_context *ctx) { osSetThreadPri(rdram, (int32_t)ctx->r4, (OSPri)ctx->r5); } -extern "C" void osGetThreadPri_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osGetThreadPri_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osGetThreadPri(rdram, (int32_t)ctx->r4); } -extern "C" void osGetThreadId_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osGetThreadId_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osGetThreadId(rdram, (int32_t)ctx->r4); } -extern "C" void osCreateMesgQueue_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osCreateMesgQueue_recomp(uint8_t *rdram, recomp_context *ctx) { osCreateMesgQueue(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6); } -extern "C" void osRecvMesg_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osRecvMesg_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osRecvMesg(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6); } -extern "C" void osSendMesg_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSendMesg_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osSendMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6); } -extern "C" void osJamMesg_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osJamMesg_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osJamMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6); } -extern "C" void osSetEventMesg_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osSetEventMesg_recomp(uint8_t *rdram, recomp_context *ctx) { osSetEventMesg(rdram, (OSEvent)ctx->r4, (int32_t)ctx->r5, (OSMesg)ctx->r6); } -extern "C" void osViSetEvent_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osViSetEvent_recomp(uint8_t *rdram, recomp_context *ctx) { osViSetEvent(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (u32)ctx->r6); } -extern "C" void osGetCount_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osGetCount_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osGetCount(); } -extern "C" void osGetTime_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osGetTime_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t total_count = osGetTime(); ctx->r2 = (int32_t)(total_count >> 32); ctx->r3 = (int32_t)(total_count >> 0); } -extern "C" void osSetTimer_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osSetTimer_recomp(uint8_t *rdram, recomp_context *ctx) { uint64_t countdown = ((uint64_t)(ctx->r6) << 32) | ((ctx->r7) & 0xFFFFFFFFu); uint64_t interval = load_doubleword(rdram, ctx->r29, 0x10); ctx->r2 = osSetTimer(rdram, (int32_t)ctx->r4, countdown, interval, (int32_t)MEM_W(0x18, ctx->r29), (OSMesg)MEM_W(0x1C, ctx->r29)); } -extern "C" void osStopTimer_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osStopTimer_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osStopTimer(rdram, (int32_t)ctx->r4); } -extern "C" void osVirtualToPhysical_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osVirtualToPhysical_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = osVirtualToPhysical((int32_t)ctx->r4); } -extern "C" void osInvalDCache_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osInvalDCache_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void osInvalICache_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osInvalICache_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void osWritebackDCache_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osWritebackDCache_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void osWritebackDCacheAll_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osWritebackDCacheAll_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void osSetIntMask_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void osSetIntMask_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void __osDisableInt_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osDisableInt_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void __osRestoreInt_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osRestoreInt_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void __osSetFpcCsr_recomp(uint8_t * rdram, recomp_context * ctx) { +extern "C" void __osSetFpcCsr_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = 0; } // For the Mario Party games (not working) -//extern "C" void longjmp_recomp(uint8_t * rdram, recomp_context * ctx) { +// extern "C" void longjmp_recomp(uint8_t * rdram, recomp_context * ctx) { // RecompJmpBuf* buf = TO_PTR(RecompJmpBuf, ctx->r4); // // // Check if this is a buffer that was set up with setjmp @@ -153,11 +156,11 @@ extern "C" void __osSetFpcCsr_recomp(uint8_t * rdram, recomp_context * ctx) { //} // //#undef setjmp_recomp -//extern "C" void setjmp_recomp(uint8_t * rdram, recomp_context * ctx) { +// extern "C" void setjmp_recomp(uint8_t * rdram, recomp_context * ctx) { // fprintf(stderr, "Program called setjmp_recomp\n"); // std::quick_exit(EXIT_FAILURE); //} // -//extern "C" int32_t osGetThreadEx(void) { +// extern "C" int32_t osGetThreadEx(void) { // return ultramodern::this_thread(); //} diff --git a/librecomp/src/vi.cpp b/librecomp/src/vi.cpp index e38152f..2f78231 100644 --- a/librecomp/src/vi.cpp +++ b/librecomp/src/vi.cpp @@ -1,45 +1,46 @@ #include + #include "recomp.h" -extern "C" void osViSetYScale_recomp(uint8_t* rdram, recomp_context * ctx) { +extern "C" void osViSetYScale_recomp(uint8_t *rdram, recomp_context *ctx) { osViSetYScale(ctx->f12.fl); } -extern "C" void osViSetXScale_recomp(uint8_t* rdram, recomp_context * ctx) { +extern "C" void osViSetXScale_recomp(uint8_t *rdram, recomp_context *ctx) { osViSetXScale(ctx->f12.fl); } -extern "C" void osCreateViManager_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osCreateViManager_recomp(uint8_t *rdram, recomp_context *ctx) { ; } -extern "C" void osViBlack_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViBlack_recomp(uint8_t *rdram, recomp_context *ctx) { osViBlack((uint32_t)ctx->r4); } -extern "C" void osViSetSpecialFeatures_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViSetSpecialFeatures_recomp(uint8_t *rdram, recomp_context *ctx) { osViSetSpecialFeatures((uint32_t)ctx->r4); } -extern "C" void osViGetCurrentFramebuffer_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViGetCurrentFramebuffer_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = (gpr)(int32_t)osViGetCurrentFramebuffer(); } -extern "C" void osViGetNextFramebuffer_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViGetNextFramebuffer_recomp(uint8_t *rdram, recomp_context *ctx) { ctx->r2 = (gpr)(int32_t)osViGetNextFramebuffer(); } -extern "C" void osViSwapBuffer_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViSwapBuffer_recomp(uint8_t *rdram, recomp_context *ctx) { osViSwapBuffer(rdram, (int32_t)ctx->r4); } -extern "C" void osViSetMode_recomp(uint8_t* rdram, recomp_context* ctx) { +extern "C" void osViSetMode_recomp(uint8_t *rdram, recomp_context *ctx) { osViSetMode(rdram, (int32_t)ctx->r4); } extern uint64_t total_vis; -extern "C" void wait_one_frame(uint8_t* rdram, recomp_context* ctx) { +extern "C" void wait_one_frame(uint8_t *rdram, recomp_context *ctx) { uint64_t cur_vis = total_vis; while (cur_vis == total_vis) { std::this_thread::yield(); diff --git a/ultramodern/include/ultramodern/config.hpp b/ultramodern/include/ultramodern/config.hpp index 29c1fe9..bccc31f 100644 --- a/ultramodern/include/ultramodern/config.hpp +++ b/ultramodern/include/ultramodern/config.hpp @@ -1,8 +1,8 @@ #ifndef __CONFIG_HPP__ #define __CONFIG_HPP__ -#include #include +#include #include "json/json.hpp" @@ -81,6 +81,7 @@ namespace ultramodern { const GraphicsConfig& get_graphics_config(); void set_graphics_config(const GraphicsConfig& new_config); + // clang-format off NLOHMANN_JSON_SERIALIZE_ENUM(ultramodern::renderer::Resolution, { {ultramodern::renderer::Resolution::Original, "Original"}, {ultramodern::renderer::Resolution::Original2x, "Original2x"}, @@ -128,7 +129,8 @@ namespace ultramodern { {ultramodern::renderer::HighPrecisionFramebuffer::On, "On"}, {ultramodern::renderer::HighPrecisionFramebuffer::Off, "Off"}, }); - } -} + // clang-format on + } // namespace renderer +} // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/error_handling.hpp b/ultramodern/include/ultramodern/error_handling.hpp index 303e6b7..8da12c0 100644 --- a/ultramodern/include/ultramodern/error_handling.hpp +++ b/ultramodern/include/ultramodern/error_handling.hpp @@ -8,7 +8,7 @@ namespace ultramodern { namespace error_handling { struct callbacks_t { - using message_box_t = void(const char* msg); + using message_box_t = void(const char *msg); /** * Show an OS dialog with the given `msg`. @@ -20,10 +20,10 @@ namespace ultramodern { void set_callbacks(const callbacks_t& callbacks); - void message_box(const char* msg); + void message_box(const char *msg); - [[noreturn]] void quick_exit(const char* filename, int line, const char *func, int exit_status = EXIT_FAILURE); - } -} + [[noreturn]] void quick_exit(const char *filename, int line, const char *func, int exit_status = EXIT_FAILURE); + } // namespace error_handling +} // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/events.hpp b/ultramodern/include/ultramodern/events.hpp index dbb2ea5..b08d350 100644 --- a/ultramodern/include/ultramodern/events.hpp +++ b/ultramodern/include/ultramodern/events.hpp @@ -10,16 +10,16 @@ namespace ultramodern { /** * Called in each VI. */ - vi_callback_t* vi_callback; + vi_callback_t *vi_callback; /** * Called before entering the gfx main loop. */ - gfx_init_callback_t* gfx_init_callback; + gfx_init_callback_t *gfx_init_callback; }; void set_callbacks(const callbacks_t& callbacks); - } -} + } // namespace events +} // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/input.hpp b/ultramodern/include/ultramodern/input.hpp index 1dab1b8..d938a28 100644 --- a/ultramodern/include/ultramodern/input.hpp +++ b/ultramodern/include/ultramodern/input.hpp @@ -26,11 +26,11 @@ namespace ultramodern { struct callbacks_t { using poll_input_t = void(void); - using get_input_t = bool(int controller_num, uint16_t* buttons, float* x, float* y); + using get_input_t = bool(int controller_num, uint16_t *buttons, float *x, float *y); using set_rumble_t = void(int controller_num, bool rumble); using get_connected_device_info_t = connected_device_info_t(int controller_num); - poll_input_t* poll_input; + poll_input_t *poll_input; /** * Requests the state of the pressed buttons and the analog stick for the given `controller_num`. @@ -39,25 +39,25 @@ namespace ultramodern { * * Returns `true` if was able to fetch the specified data, `false` otherwise and the parameter arguments are left untouched. */ - get_input_t* get_input; + get_input_t *get_input; /** * Turns on or off rumbling for the specified controller. * * `controller_num` is zero-indexed, meaning 0 corresponds to the first controller. */ - set_rumble_t* set_rumble; + set_rumble_t *set_rumble; /** * Returns the connected device info for the given `controller_num` (as in, the controller port of the console). * * `controller_num` is zero-indexed, meaning 0 corresponds to the first controller. */ - get_connected_device_info_t* get_connected_device_info; + get_connected_device_info_t *get_connected_device_info; }; void set_callbacks(const callbacks_t& callbacks); - } -} + } // namespace input +} // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/renderer_context.hpp b/ultramodern/include/ultramodern/renderer_context.hpp index 0b5d333..2351cc6 100644 --- a/ultramodern/include/ultramodern/renderer_context.hpp +++ b/ultramodern/include/ultramodern/renderer_context.hpp @@ -7,21 +7,21 @@ #include #if defined(_WIN32) -# define WIN32_LEAN_AND_MEAN -# include +# define WIN32_LEAN_AND_MEAN +# include #elif defined(__ANDROID__) -# include "android/native_window.h" +# include "android/native_window.h" #elif defined(__linux__) -# include "X11/Xlib.h" -# undef None -# undef Status -# undef LockMask -# undef Always -# undef Success +# include "X11/Xlib.h" +# undef None +# undef Status +# undef LockMask +# undef Always +# undef Success #endif -#include "ultra64.h" #include "config.hpp" +#include "ultra64.h" namespace ultramodern { namespace renderer { @@ -34,17 +34,17 @@ namespace ultramodern { auto operator<=>(const WindowHandle&) const = default; }; #elif defined(__ANDROID__) - using WindowHandle = ANativeWindow*; + using WindowHandle = ANativeWindow *; #elif defined(__linux__) struct WindowHandle { - Display* display; + Display *display; Window window; auto operator<=>(const WindowHandle&) const = default; }; #elif defined(__APPLE__) struct WindowHandle { - void* window; - void* view; + void *window; + void *view; auto operator<=>(const WindowHandle&) const = default; }; #endif @@ -58,28 +58,31 @@ namespace ultramodern { }; class RendererContext { - public: - virtual ~RendererContext() = default; - - virtual bool valid() = 0; - virtual SetupResult get_setup_result() const { return setup_result; } - - virtual bool update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config) = 0; - - virtual void enable_instant_present() = 0; - virtual void send_dl(const OSTask* task) = 0; - virtual void update_screen(uint32_t vi_origin) = 0; - virtual void shutdown() = 0; - virtual uint32_t get_display_framerate() const = 0; - virtual float get_resolution_scale() const = 0; - virtual void load_shader_cache(std::span cache_binary) = 0; - - protected: - SetupResult setup_result; + public: + virtual ~RendererContext() = default; + + virtual bool valid() = 0; + virtual SetupResult get_setup_result() const { + return setup_result; + } + + virtual bool update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config) = 0; + + virtual void enable_instant_present() = 0; + virtual void send_dl(const OSTask *task) = 0; + virtual void update_screen(uint32_t vi_origin) = 0; + virtual void shutdown() = 0; + virtual uint32_t get_display_framerate() const = 0; + virtual float get_resolution_scale() const = 0; + virtual void load_shader_cache(std::span cache_binary) = 0; + + protected: + SetupResult setup_result; }; struct callbacks_t { - using create_render_context_t = std::unique_ptr(uint8_t* rdram, WindowHandle window_handle, bool developer_mode); + using create_render_context_t = + std::unique_ptr(uint8_t *rdram, WindowHandle window_handle, bool developer_mode); using get_graphics_api_name_t = std::string(const GraphicsConfig& config); /** @@ -97,10 +100,10 @@ namespace ultramodern { void set_callbacks(const callbacks_t& callbacks); - std::unique_ptr create_render_context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode); + std::unique_ptr create_render_context(uint8_t *rdram, WindowHandle window_handle, bool developer_mode); std::string get_graphics_api_name(const GraphicsConfig& config); - } -} + } // namespace renderer +} // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/rsp.hpp b/ultramodern/include/ultramodern/rsp.hpp index be1a85c..e3c4c3b 100644 --- a/ultramodern/include/ultramodern/rsp.hpp +++ b/ultramodern/include/ultramodern/rsp.hpp @@ -13,23 +13,23 @@ namespace ultramodern { namespace rsp { struct callbacks_t { using init_t = void(); - using run_microcode_t = bool(RDRAM_ARG const OSTask* task); + using run_microcode_t = bool(RDRAM_ARG const OSTask *task); - init_t* init; + init_t *init; /** * Executes the given RSP task. * * Returns true if task was executed successfully. */ - run_microcode_t* run_task; + run_microcode_t *run_task; }; void set_callbacks(const callbacks_t& callbacks); void init(); - bool run_task(RDRAM_ARG const OSTask* task); - }; + bool run_task(RDRAM_ARG const OSTask *task); + }; // namespace rsp } // namespace ultramodern #endif diff --git a/ultramodern/include/ultramodern/ultra64.h b/ultramodern/include/ultramodern/ultra64.h index ef9a86a..f746e61 100644 --- a/ultramodern/include/ultramodern/ultra64.h +++ b/ultramodern/include/ultramodern/ultra64.h @@ -4,11 +4,11 @@ #include #ifdef __GNUC__ -#define UNUSED __attribute__((unused)) -#define ALIGNED(x) __attribute__((aligned(x))) +# define UNUSED __attribute__((unused)) +# define ALIGNED(x) __attribute__((aligned(x))) #else -#define UNUSED -#define ALIGNED(x) +# define UNUSED +# define ALIGNED(x) #endif typedef int64_t s64; @@ -23,60 +23,60 @@ typedef uint8_t u8; // TODO allow a compile-time flag to be set to switch between recomp mode and // fully native mode. #if 0 // For native compilation -# define PTR(x) x* -# define RDRAM_ARG -# define RDRAM_ARG1 -# define PASS_RDRAM -# define PASS_RDRAM1 -# define TO_PTR(type, var) var -# define GET_MEMBER(type, addr, member) (&addr->member) -# ifdef __cplusplus -# define NULLPTR nullptr -# endif +# define PTR(x) x * +# define RDRAM_ARG +# define RDRAM_ARG1 +# define PASS_RDRAM +# define PASS_RDRAM1 +# define TO_PTR(type, var) var +# define GET_MEMBER(type, addr, member) (&addr->member) +# ifdef __cplusplus +# define NULLPTR nullptr +# endif #else -# define PTR(x) int32_t -# define RDRAM_ARG uint8_t *rdram, -# define RDRAM_ARG1 uint8_t *rdram -# define PASS_RDRAM rdram, -# define PASS_RDRAM1 rdram -# define TO_PTR(type, var) ((type*)(&rdram[(uint64_t)var - 0xFFFFFFFF80000000])) -# define GET_MEMBER(type, addr, member) (addr + (intptr_t)&(((type*)nullptr)->member)) -# ifdef __cplusplus -# define NULLPTR (PTR(void))0 -# endif +# define PTR(x) int32_t +# define RDRAM_ARG uint8_t *rdram, +# define RDRAM_ARG1 uint8_t *rdram +# define PASS_RDRAM rdram, +# define PASS_RDRAM1 rdram +# define TO_PTR(type, var) ((type *)(&rdram[(uint64_t)var - 0xFFFFFFFF80000000])) +# define GET_MEMBER(type, addr, member) (addr + (intptr_t) & (((type *)nullptr)->member)) +# ifdef __cplusplus +# define NULLPTR (PTR(void))0 +# endif #endif #ifndef NULL -#define NULL (PTR(void) 0) +# define NULL (PTR(void) 0) #endif -#define OS_MESG_NOBLOCK 0 -#define OS_MESG_BLOCK 1 +#define OS_MESG_NOBLOCK 0 +#define OS_MESG_BLOCK 1 typedef s32 OSPri; typedef s32 OSId; -typedef u64 OSTime; - -#define OS_EVENT_SW1 0 /* CPU SW1 interrupt */ -#define OS_EVENT_SW2 1 /* CPU SW2 interrupt */ -#define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */ -#define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */ -#define OS_EVENT_SP 4 /* SP task done interrupt */ -#define OS_EVENT_SI 5 /* SI (controller) interrupt */ -#define OS_EVENT_AI 6 /* AI interrupt */ -#define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */ -#define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */ -#define OS_EVENT_DP 9 /* DP full sync interrupt */ -#define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */ -#define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */ -#define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */ -#define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */ -#define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */ - -#define M_GFXTASK 1 -#define M_AUDTASK 2 -#define M_VIDTASK 3 +typedef u64 OSTime; + +#define OS_EVENT_SW1 0 /* CPU SW1 interrupt */ +#define OS_EVENT_SW2 1 /* CPU SW2 interrupt */ +#define OS_EVENT_CART 2 /* Cartridge interrupt: used by rmon */ +#define OS_EVENT_COUNTER 3 /* Counter int: used by VI/Timer Mgr */ +#define OS_EVENT_SP 4 /* SP task done interrupt */ +#define OS_EVENT_SI 5 /* SI (controller) interrupt */ +#define OS_EVENT_AI 6 /* AI interrupt */ +#define OS_EVENT_VI 7 /* VI interrupt: used by VI/Timer Mgr */ +#define OS_EVENT_PI 8 /* PI interrupt: used by PI Manager */ +#define OS_EVENT_DP 9 /* DP full sync interrupt */ +#define OS_EVENT_CPU_BREAK 10 /* CPU breakpoint: used by rmon */ +#define OS_EVENT_SP_BREAK 11 /* SP breakpoint: used by rmon */ +#define OS_EVENT_FAULT 12 /* CPU fault event: used by rmon */ +#define OS_EVENT_THREADSTATUS 13 /* CPU thread status: used by rmon */ +#define OS_EVENT_PRENMI 14 /* Pre NMI interrupt */ + +#define M_GFXTASK 1 +#define M_AUDTASK 2 +#define M_VIDTASK 3 #define M_NJPEGTASK 4 ///////////// @@ -103,7 +103,7 @@ typedef struct OSThread_t { uint16_t state; OSId id; int32_t pad3; - UltraThreadContext* context; // An actual pointer regardless of platform + UltraThreadContext *context; // An actual pointer regardless of platform int32_t sp; } OSThread; @@ -112,7 +112,7 @@ typedef PTR(void) OSMesg; typedef struct OSMesgQueue { PTR(OSThread) blocked_on_recv; /* Linked list of threads blocked on receiving from this queue */ - PTR(OSThread) blocked_on_send; /* Linked list of threads blocked on sending to this queue */ + PTR(OSThread) blocked_on_send; /* Linked list of threads blocked on sending to this queue */ s32 validCount; /* Number of messages in the queue */ s32 first; /* Index of the first message in the ring buffer */ s32 msgCount; /* Size of message buffer */ @@ -122,29 +122,29 @@ typedef struct OSMesgQueue { // RSP typedef struct { - u32 type; - u32 flags; + u32 type; + u32 flags; PTR(u64) ucode_boot; - u32 ucode_boot_size; + u32 ucode_boot_size; PTR(u64) ucode; - u32 ucode_size; + u32 ucode_size; PTR(u64) ucode_data; - u32 ucode_data_size; + u32 ucode_data_size; PTR(u64) dram_stack; - u32 dram_stack_size; + u32 dram_stack_size; PTR(u64) output_buff; PTR(u64) output_buff_size; PTR(u64) data_ptr; - u32 data_size; + u32 data_size; PTR(u64) yield_data_ptr; - u32 yield_data_size; + u32 yield_data_size; } OSTask_s; typedef union { @@ -163,55 +163,55 @@ struct OSIoMesgHdr { }; struct OSIoMesg { - OSIoMesgHdr hdr; /* Message header */ - PTR(void) dramAddr; /* RDRAM buffer address (DMA) */ - u32 devAddr; /* Device buffer address (DMA) */ - u32 size; /* DMA transfer size in bytes */ - u32 piHandle; /* PI device handle */ + OSIoMesgHdr hdr; /* Message header */ + PTR(void) dramAddr; /* RDRAM buffer address (DMA) */ + u32 devAddr; /* Device buffer address (DMA) */ + u32 size; /* DMA transfer size in bytes */ + u32 piHandle; /* PI device handle */ }; struct OSPiHandle { - PTR(OSPiHandle_s) unused; /* point to next handle on the table */ + PTR(OSPiHandle_s) unused; /* point to next handle on the table */ // These four members reversed due to endianness - u8 relDuration; /* domain release duration */ - u8 pageSize; /* domain page size */ - u8 latency; /* domain latency */ - u8 type; /* DEVICE_TYPE_BULK for disk */ + u8 relDuration; /* domain release duration */ + u8 pageSize; /* domain page size */ + u8 latency; /* domain latency */ + u8 type; /* DEVICE_TYPE_BULK for disk */ // These three members reversed due to endianness - u16 padding; /* struct alignment padding */ - u8 domain; /* which domain */ - u8 pulse; /* domain pulse width */ - u32 baseAddress; /* Domain address */ - u32 speed; /* for roms only */ + u16 padding; /* struct alignment padding */ + u8 domain; /* which domain */ + u8 pulse; /* domain pulse width */ + u32 baseAddress; /* Domain address */ + u32 speed; /* for roms only */ /* The following are "private" elements" */ - u32 transferInfo[18]; /* for disk only */ + u32 transferInfo[18]; /* for disk only */ }; typedef struct { - u32 ctrl; - u32 width; - u32 burst; - u32 vSync; - u32 hSync; - u32 leap; - u32 hStart; - u32 xScale; - u32 vCurrent; + u32 ctrl; + u32 width; + u32 burst; + u32 vSync; + u32 hSync; + u32 leap; + u32 hStart; + u32 xScale; + u32 vCurrent; } OSViCommonRegs; typedef struct { - u32 origin; - u32 yScale; - u32 vStart; - u32 vBurst; - u32 vIntr; + u32 origin; + u32 yScale; + u32 vStart; + u32 vBurst; + u32 vIntr; } OSViFieldRegs; typedef struct { u8 padding[3]; u8 type; OSViCommonRegs comRegs; - OSViFieldRegs fldRegs[2]; + OSViFieldRegs fldRegs[2]; } OSViMode; /* @@ -221,13 +221,13 @@ typedef struct { int status; PTR(OSMesgQueue) queue; int channel; - u8 id[32]; // TODO: funky endianness here + u8 id[32]; // TODO: funky endianness here u8 label[32]; // TODO: funky endianness here int version; int dir_size; - int inode_table; /* block location */ - int minode_table; /* mirrioring inode_table */ - int dir_table; /* block location */ + int inode_table; /* block location */ + int minode_table; /* mirrioring inode_table */ + int dir_table; /* block location */ int inode_start_page; /* page # */ // Padding and reversed members due to endianness u8 padding[2]; @@ -235,14 +235,13 @@ typedef struct { u8 banks; } OSPfs; - // Controller typedef struct { // These three members reversed due to endianness u8 err_no; - u8 status; /* Controller status */ - u16 type; /* Controller Type */ + u8 status; /* Controller status */ + u16 type; /* Controller Type */ } OSContStatus; typedef struct { @@ -252,7 +251,6 @@ typedef struct { u8 err_no; } OSContPad; - /////////////// // Functions // /////////////// @@ -263,7 +261,7 @@ extern "C" { void osInitialize(void); -typedef void (thread_func_t)(PTR(void)); +typedef void(thread_func_t)(PTR(void)); void osCreateThread(RDRAM_ARG PTR(OSThread) t, OSId id, PTR(thread_func_t) entry, PTR(void) arg, PTR(void) sp, OSPri p); void osStartThread(RDRAM_ARG PTR(OSThread) t); diff --git a/ultramodern/include/ultramodern/ultramodern.hpp b/ultramodern/include/ultramodern/ultramodern.hpp index 8dbccdc..e87b05c 100644 --- a/ultramodern/include/ultramodern/ultramodern.hpp +++ b/ultramodern/include/ultramodern/ultramodern.hpp @@ -1,10 +1,10 @@ #ifndef __ultramodern_HPP__ #define __ultramodern_HPP__ -#include #include -#include #include +#include +#include #undef MOODYCAMEL_DELETE_FUNCTION #define MOODYCAMEL_DELETE_FUNCTION = delete @@ -14,8 +14,8 @@ #include "ultramodern/error_handling.hpp" #include "ultramodern/events.hpp" #include "ultramodern/input.hpp" -#include "ultramodern/rsp.hpp" #include "ultramodern/renderer_context.hpp" +#include "ultramodern/rsp.hpp" struct UltraThreadContext { std::thread host_thread; @@ -25,127 +25,122 @@ struct UltraThreadContext { namespace ultramodern { -// We need a place in rdram to hold the PI handles, so pick an address in extended rdram -constexpr uint32_t rdram_size = 1024 * 1024 * 16; // 16MB to give extra room for anything custom -constexpr int32_t cart_handle = 0x80800000; -constexpr int32_t drive_handle = (int32_t)(cart_handle + sizeof(OSPiHandle)); -constexpr int32_t flash_handle = (int32_t)(drive_handle + sizeof(OSPiHandle)); -constexpr uint32_t save_size = 1024 * 1024 / 8; // Maximum save size, 1Mbit for flash - -// Initialization. -void preinit(RDRAM_ARG renderer::WindowHandle window_handle); -void init_saving(RDRAM_ARG1); -void init_events(RDRAM_ARG renderer::WindowHandle window_handle); -void init_timers(RDRAM_ARG1); -void init_thread_cleanup(); - -// Thread queues. -constexpr PTR(PTR(OSThread)) running_queue = (PTR(PTR(OSThread)))-1; - -void thread_queue_insert(RDRAM_ARG PTR(PTR(OSThread)) queue, PTR(OSThread) toadd); -PTR(OSThread) thread_queue_pop(RDRAM_ARG PTR(PTR(OSThread)) queue); -bool thread_queue_remove(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(OSThread) t_); -bool thread_queue_empty(RDRAM_ARG PTR(PTR(OSThread)) queue); -PTR(OSThread) thread_queue_peek(RDRAM_ARG PTR(PTR(OSThread)) queue); - -// Message queues. -void wait_for_external_message(RDRAM_ARG1); -void wait_for_external_message_timed(RDRAM_ARG1, u32 millis); - -// Thread scheduling. -void check_running_queue(RDRAM_ARG1); -void run_next_thread_and_wait(RDRAM_ARG1); -void resume_thread_and_wait(RDRAM_ARG OSThread* t); -void schedule_running_thread(RDRAM_ARG PTR(OSThread) t); -void cleanup_thread(UltraThreadContext* thread_context); -uint32_t permanent_thread_count(); -uint32_t temporary_thread_count(); -struct thread_terminated : std::exception {}; - -enum class ThreadPriority { - Low, - Normal, - High, - VeryHigh, - Critical -}; - -void set_native_thread_name(const std::string& name); -void set_native_thread_priority(ThreadPriority pri); -PTR(OSThread) this_thread(); -void set_main_thread(); -bool is_game_thread(); -void submit_rsp_task(RDRAM_ARG PTR(OSTask) task); -void send_si_message(RDRAM_ARG1); -uint32_t get_speed_multiplier(); - -// Time -std::chrono::high_resolution_clock::time_point get_start(); -std::chrono::high_resolution_clock::duration time_since_start(); -void measure_input_latency(); -void sleep_milliseconds(uint32_t millis); -void sleep_until(const std::chrono::high_resolution_clock::time_point& time_point); - -// Graphics -uint32_t get_target_framerate(uint32_t original); -uint32_t get_display_refresh_rate(); -float get_resolution_scale(); -void load_shader_cache(std::span cache_data); -void trigger_config_action(); - -// Audio -void init_audio(); -void set_audio_frequency(uint32_t freq); -void queue_audio_buffer(RDRAM_ARG PTR(s16) audio_data, uint32_t byte_count); -uint32_t get_remaining_audio_bytes(); - -struct audio_callbacks_t { - using queue_samples_t = void(int16_t*, size_t); - using get_samples_remaining_t = size_t(); - using set_frequency_t = void(uint32_t); - queue_samples_t* queue_samples; - get_samples_remaining_t* get_frames_remaining; - set_frequency_t* set_frequency; -}; - -// TODO: Most of the members of this struct are not used by ultramodern. Should we move them to librecomp instead? -struct gfx_callbacks_t { - using gfx_data_t = void*; - using create_gfx_t = gfx_data_t(); - using create_window_t = renderer::WindowHandle(gfx_data_t); - using update_gfx_t = void(gfx_data_t); - - create_gfx_t* create_gfx; - create_window_t* create_window; - update_gfx_t* update_gfx; -}; - -bool is_game_started(); -void quit(); -void join_event_threads(); -void join_thread_cleaner_thread(); -void join_saving_thread(); - -void set_audio_callbacks(const audio_callbacks_t& callbacks); - -/** - * Register all the callbacks used by `ultramodern`, most of them being optional. - * - * The following arguments contain mandatory callbacks that need to be registered (i.e., can't be `nullptr`): - * - `rsp_callbacks` - * - `renderer_callbacks` - * - * It must be called only once and it must be called before `ultramodern::preinit`. - */ -void set_callbacks( - const rsp::callbacks_t& rsp_callbacks, - const renderer::callbacks_t& renderer_callbacks, - const audio_callbacks_t& audio_callbacks, - const input::callbacks_t& input_callbacks, - const gfx_callbacks_t& gfx_callbacks, - const events::callbacks_t& events_callbacks, - const error_handling::callbacks_t& error_handling_callbacks -); + // We need a place in rdram to hold the PI handles, so pick an address in extended rdram + constexpr uint32_t rdram_size = 1024 * 1024 * 16; // 16MB to give extra room for anything custom + constexpr int32_t cart_handle = 0x80800000; + constexpr int32_t drive_handle = (int32_t)(cart_handle + sizeof(OSPiHandle)); + constexpr int32_t flash_handle = (int32_t)(drive_handle + sizeof(OSPiHandle)); + constexpr uint32_t save_size = 1024 * 1024 / 8; // Maximum save size, 1Mbit for flash + + // Initialization. + void preinit(RDRAM_ARG renderer::WindowHandle window_handle); + void init_saving(RDRAM_ARG1); + void init_events(RDRAM_ARG renderer::WindowHandle window_handle); + void init_timers(RDRAM_ARG1); + void init_thread_cleanup(); + + // Thread queues. + constexpr PTR(PTR(OSThread)) running_queue = (PTR(PTR(OSThread)))-1; + + void thread_queue_insert(RDRAM_ARG PTR(PTR(OSThread)) queue, PTR(OSThread) toadd); + PTR(OSThread) thread_queue_pop(RDRAM_ARG PTR(PTR(OSThread)) queue); + bool thread_queue_remove(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(OSThread) t_); + bool thread_queue_empty(RDRAM_ARG PTR(PTR(OSThread)) queue); + PTR(OSThread) thread_queue_peek(RDRAM_ARG PTR(PTR(OSThread)) queue); + + // Message queues. + void wait_for_external_message(RDRAM_ARG1); + void wait_for_external_message_timed(RDRAM_ARG1, u32 millis); + + // Thread scheduling. + void check_running_queue(RDRAM_ARG1); + void run_next_thread_and_wait(RDRAM_ARG1); + void resume_thread_and_wait(RDRAM_ARG OSThread *t); + void schedule_running_thread(RDRAM_ARG PTR(OSThread) t); + void cleanup_thread(UltraThreadContext *thread_context); + uint32_t permanent_thread_count(); + uint32_t temporary_thread_count(); + struct thread_terminated : std::exception {}; + + enum class ThreadPriority { + Low, + Normal, + High, + VeryHigh, + Critical + }; + + void set_native_thread_name(const std::string& name); + void set_native_thread_priority(ThreadPriority pri); + PTR(OSThread) this_thread(); + void set_main_thread(); + bool is_game_thread(); + void submit_rsp_task(RDRAM_ARG PTR(OSTask) task); + void send_si_message(RDRAM_ARG1); + uint32_t get_speed_multiplier(); + + // Time + std::chrono::high_resolution_clock::time_point get_start(); + std::chrono::high_resolution_clock::duration time_since_start(); + void measure_input_latency(); + void sleep_milliseconds(uint32_t millis); + void sleep_until(const std::chrono::high_resolution_clock::time_point& time_point); + + // Graphics + uint32_t get_target_framerate(uint32_t original); + uint32_t get_display_refresh_rate(); + float get_resolution_scale(); + void load_shader_cache(std::span cache_data); + void trigger_config_action(); + + // Audio + void init_audio(); + void set_audio_frequency(uint32_t freq); + void queue_audio_buffer(RDRAM_ARG PTR(s16) audio_data, uint32_t byte_count); + uint32_t get_remaining_audio_bytes(); + + struct audio_callbacks_t { + using queue_samples_t = void(int16_t *, size_t); + using get_samples_remaining_t = size_t(); + using set_frequency_t = void(uint32_t); + queue_samples_t *queue_samples; + get_samples_remaining_t *get_frames_remaining; + set_frequency_t *set_frequency; + }; + + // TODO: Most of the members of this struct are not used by ultramodern. Should we move them to librecomp instead? + struct gfx_callbacks_t { + using gfx_data_t = void *; + using create_gfx_t = gfx_data_t(); + using create_window_t = renderer::WindowHandle(gfx_data_t); + using update_gfx_t = void(gfx_data_t); + + create_gfx_t *create_gfx; + create_window_t *create_window; + update_gfx_t *update_gfx; + }; + + bool is_game_started(); + void quit(); + void join_event_threads(); + void join_thread_cleaner_thread(); + void join_saving_thread(); + + void set_audio_callbacks(const audio_callbacks_t& callbacks); + + /** + * Register all the callbacks used by `ultramodern`, most of them being optional. + * + * The following arguments contain mandatory callbacks that need to be registered (i.e., can't be `nullptr`): + * - `rsp_callbacks` + * - `renderer_callbacks` + * + * It must be called only once and it must be called before `ultramodern::preinit`. + */ + void set_callbacks( + const rsp::callbacks_t& rsp_callbacks, const renderer::callbacks_t& renderer_callbacks, const audio_callbacks_t& audio_callbacks, + const input::callbacks_t& input_callbacks, const gfx_callbacks_t& gfx_callbacks, const events::callbacks_t& events_callbacks, + const error_handling::callbacks_t& error_handling_callbacks); } // namespace ultramodern #define MIN(a, b) ((a) < (b) ? (a) : (b)) diff --git a/ultramodern/src/audio.cpp b/ultramodern/src/audio.cpp index 82c4206..ac47641 100644 --- a/ultramodern/src/audio.cpp +++ b/ultramodern/src/audio.cpp @@ -36,7 +36,7 @@ void ultramodern::queue_audio_buffer(RDRAM_ARG PTR(int16_t) audio_data_, uint32_ } // For SDL2 -//uint32_t buffer_offset_frames = 1; +// uint32_t buffer_offset_frames = 1; // For Godot float buffer_offset_frames = 0.5f; @@ -52,16 +52,16 @@ uint32_t ultramodern::get_remaining_audio_bytes() { else { buffered_byte_count = 100; } - // Adjust the reported count to be some number of refreshes in the future, which helps ensure that - // there are enough samples even if the audio thread experiences a small amount of lag. This prevents - // audio popping on games that use the buffered audio byte count to determine how many samples - // to generate. - uint32_t samples_per_vi = (sample_rate / 60); - if (buffered_byte_count > static_cast(buffer_offset_frames * sizeof(int16_t) * samples_per_vi)) { - buffered_byte_count -= static_cast(buffer_offset_frames * sizeof(int16_t) * samples_per_vi); - } - else { - buffered_byte_count = 0; - } - return buffered_byte_count; + // Adjust the reported count to be some number of refreshes in the future, which helps ensure that + // there are enough samples even if the audio thread experiences a small amount of lag. This prevents + // audio popping on games that use the buffered audio byte count to determine how many samples + // to generate. + uint32_t samples_per_vi = (sample_rate / 60); + if (buffered_byte_count > static_cast(buffer_offset_frames * sizeof(int16_t) * samples_per_vi)) { + buffered_byte_count -= static_cast(buffer_offset_frames * sizeof(int16_t) * samples_per_vi); + } + else { + buffered_byte_count = 0; + } + return buffered_byte_count; } diff --git a/ultramodern/src/error_handling.cpp b/ultramodern/src/error_handling.cpp index 9be5acd..8b95a37 100644 --- a/ultramodern/src/error_handling.cpp +++ b/ultramodern/src/error_handling.cpp @@ -8,7 +8,7 @@ void ultramodern::error_handling::set_callbacks(const ultramodern::error_handlin error_handling_callbacks = callbacks; } -void ultramodern::error_handling::message_box(const char* msg) { +void ultramodern::error_handling::message_box(const char *msg) { // We print the message to stderr since the user may not have provided a message_box callback fprintf(stderr, "%s\n", msg); @@ -18,7 +18,7 @@ void ultramodern::error_handling::message_box(const char* msg) { } } -void ultramodern::error_handling::quick_exit(const char* filename, int line, const char *func, int exit_status) { +void ultramodern::error_handling::quick_exit(const char *filename, int line, const char *func, int exit_status) { fprintf(stderr, "Exiting with exit status '%i'. Function %s, at file %s:%i, ", exit_status, func, filename, line); #ifdef __APPLE__ diff --git a/ultramodern/src/events.cpp b/ultramodern/src/events.cpp index 3131610..e89e5ee 100644 --- a/ultramodern/src/events.cpp +++ b/ultramodern/src/events.cpp @@ -1,21 +1,21 @@ -#include #include #include #include -#include -#include -#include +#include #include #include -#include +#include +#include +#include +#include #include "blockingconcurrentqueue.h" #include "ultramodern/ultra64.h" #include "ultramodern/ultramodern.hpp" -#include "ultramodern/rsp.hpp" #include "ultramodern/renderer_context.hpp" +#include "ultramodern/rsp.hpp" static ultramodern::events::callbacks_t events_callbacks{}; @@ -31,8 +31,7 @@ struct SwapBuffersAction { uint32_t origin; }; -struct UpdateConfigAction { -}; +struct UpdateConfigAction {}; struct LoadShaderCacheAction { std::span data; @@ -69,14 +68,14 @@ static struct { } si; // The same message queue may be used for multiple events, so share a mutex for all of them std::mutex message_mutex; - uint8_t* rdram; + uint8_t *rdram; moodycamel::BlockingConcurrentQueue action_queue{}; - moodycamel::BlockingConcurrentQueue sp_task_queue{}; - moodycamel::ConcurrentQueue deleted_threads{}; + moodycamel::BlockingConcurrentQueue sp_task_queue{}; + moodycamel::ConcurrentQueue deleted_threads{}; } events_context{}; extern "C" void osSetEventMesg(RDRAM_ARG OSEvent event_id, PTR(OSMesgQueue) mq_, OSMesg msg) { - OSMesgQueue* mq = TO_PTR(OSMesgQueue, mq_); + OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); std::lock_guard lock{ events_context.message_mutex }; switch (event_id) { @@ -107,7 +106,6 @@ extern "C" void osViSetEvent(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, u32 ret uint64_t total_vis = 0; - extern std::atomic_bool exited; void set_dummy_vi(); @@ -124,15 +122,16 @@ void vi_thread_func() { while (!exited) { // Determine the next VI time (more accurate than adding 16ms each VI interrupt) auto next = ultramodern::get_start() + (total_vis * 1000000us) / (60 * ultramodern::get_speed_multiplier()); - //if (next > std::chrono::high_resolution_clock::now()) { - // printf("Sleeping for %" PRIu64 " us to get from %" PRIu64 " us to %" PRIu64 " us \n", - // (next - std::chrono::high_resolution_clock::now()) / 1us, - // (std::chrono::high_resolution_clock::now() - events_context.start) / 1us, - // (next - events_context.start) / 1us); - //} else { - // printf("No need to sleep\n"); - //} - // Detect if there's more than a second to wait and wait a fixed amount instead for the next VI if so, as that usually means the system clock went back in time. + // if (next > std::chrono::high_resolution_clock::now()) { + // printf("Sleeping for %" PRIu64 " us to get from %" PRIu64 " us to %" PRIu64 " us \n", + // (next - std::chrono::high_resolution_clock::now()) / 1us, + // (std::chrono::high_resolution_clock::now() - events_context.start) / 1us, + // (next - events_context.start) / 1us); + // } else { + // printf("No need to sleep\n"); + // } + // Detect if there's more than a second to wait and wait a fixed amount instead for the next VI if so, as that usually means the + // system clock went back in time. if (std::chrono::floor(next - std::chrono::high_resolution_clock::now()) > 1s) { // printf("Skipping the next VI wait\n"); next = std::chrono::high_resolution_clock::now(); @@ -141,7 +140,7 @@ void vi_thread_func() { // Calculate how many VIs have passed uint64_t new_total_vis = (ultramodern::time_since_start() * (60 * ultramodern::get_speed_multiplier()) / 1000ms) + 1; if (new_total_vis > total_vis + 1) { - //printf("Skipped % " PRId64 " frames in VI interupt thread!\n", new_total_vis - total_vis - 1); + // printf("Skipped % " PRId64 " frames in VI interupt thread!\n", new_total_vis - total_vis - 1); } total_vis = new_total_vis; @@ -149,14 +148,14 @@ void vi_thread_func() { { std::lock_guard lock{ events_context.message_mutex }; - uint8_t* rdram = events_context.rdram; + uint8_t *rdram = events_context.rdram; if (remaining_retraces == 0) { remaining_retraces = events_context.vi.retrace_count; if (ultramodern::is_game_started()) { if (events_context.vi.mq != NULLPTR) { if (osSendMesg(PASS_RDRAM events_context.vi.mq, events_context.vi.msg, OS_MESG_NOBLOCK) == -1) { - //printf("Game skipped a VI frame!\n"); + // printf("Game skipped a VI frame!\n"); } } } @@ -174,7 +173,7 @@ void vi_thread_func() { } if (events_context.ai.mq != NULLPTR) { if (osSendMesg(PASS_RDRAM events_context.ai.mq, events_context.ai.msg, OS_MESG_NOBLOCK) == -1) { - //printf("Game skipped a AI frame!\n"); + // printf("Game skipped a AI frame!\n"); } } } @@ -186,18 +185,18 @@ void vi_thread_func() { } void sp_complete() { - uint8_t* rdram = events_context.rdram; + uint8_t *rdram = events_context.rdram; std::lock_guard lock{ events_context.message_mutex }; osSendMesg(PASS_RDRAM events_context.sp.mq, events_context.sp.msg, OS_MESG_NOBLOCK); } void dp_complete() { - uint8_t* rdram = events_context.rdram; + uint8_t *rdram = events_context.rdram; std::lock_guard lock{ events_context.message_mutex }; osSendMesg(PASS_RDRAM events_context.dp.mq, events_context.dp.msg, OS_MESG_NOBLOCK); } -void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready) { +void task_thread_func(uint8_t *rdram, moodycamel::LightweightSemaphore *thread_ready) { ultramodern::set_native_thread_name("SP Task Thread"); ultramodern::set_native_thread_priority(ultramodern::ThreadPriority::Normal); @@ -206,7 +205,7 @@ void task_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_r while (true) { // Wait until an RSP task has been sent - OSTask* task; + OSTask *task; events_context.sp_task_queue.wait_dequeue(task); if (task == nullptr) { @@ -249,7 +248,7 @@ float ultramodern::get_resolution_scale() { } void ultramodern::load_shader_cache(std::span cache_data) { - events_context.action_queue.enqueue(LoadShaderCacheAction{cache_data}); + events_context.action_queue.enqueue(LoadShaderCacheAction{ cache_data }); } void ultramodern::trigger_config_action() { @@ -258,7 +257,7 @@ void ultramodern::trigger_config_action() { std::atomic renderer_setup_result = ultramodern::renderer::SetupResult::Success; -void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_ready, ultramodern::renderer::WindowHandle window_handle) { +void gfx_thread_func(uint8_t *rdram, moodycamel::LightweightSemaphore *thread_ready, ultramodern::renderer::WindowHandle window_handle) { bool enabled_instant_present = false; using namespace std::chrono_literals; @@ -267,7 +266,8 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re auto old_config = ultramodern::renderer::get_graphics_config(); - auto renderer_context = ultramodern::renderer::create_render_context(rdram, window_handle, ultramodern::renderer::get_graphics_config().developer_mode); + auto renderer_context = + ultramodern::renderer::create_render_context(rdram, window_handle, ultramodern::renderer::get_graphics_config().developer_mode); if (!renderer_context->valid()) { renderer_setup_result.store(renderer_context->get_setup_result()); @@ -290,7 +290,7 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re Action action; if (events_context.action_queue.wait_dequeue_timed(action, 1ms)) { // Determine the action type and act on it - if (const auto* task_action = std::get_if(&action)) { + if (const auto *task_action = std::get_if(&action)) { // Turn on instant present if the game has been started and it hasn't been turned on yet. if (ultramodern::is_game_started() && !enabled_instant_present) { renderer_context->enable_instant_present(); @@ -307,21 +307,22 @@ void gfx_thread_func(uint8_t* rdram, moodycamel::LightweightSemaphore* thread_re renderer_context->send_dl(&task_action->task); auto renderer_end = std::chrono::high_resolution_clock::now(); dp_complete(); - // printf("Renderer ProcessDList time: %d us\n", static_cast(std::chrono::duration_cast(renderer_end - renderer_start).count())); + // printf("Renderer ProcessDList time: %d us\n", + // static_cast(std::chrono::duration_cast(renderer_end - renderer_start).count())); } - else if (const auto* swap_action = std::get_if(&action)) { + else if (const auto *swap_action = std::get_if(&action)) { events_context.vi.current_buffer = events_context.vi.next_buffer; renderer_context->update_screen(swap_action->origin); display_refresh_rate = renderer_context->get_display_framerate(); resolution_scale = renderer_context->get_resolution_scale(); } - else if (const auto* config_action = std::get_if(&action)) { + else if (const auto *config_action = std::get_if(&action)) { auto new_config = ultramodern::renderer::get_graphics_config(); if (renderer_context->update_config(old_config, new_config)) { old_config = new_config; } } - else if (const auto* load_shader_cache_action = std::get_if(&action)) { + else if (const auto *load_shader_cache_action = std::get_if(&action)) { renderer_context->load_shader_cache(load_shader_cache_action->data); } } @@ -368,7 +369,8 @@ void set_dummy_vi() { extern "C" void osViSwapBuffer(RDRAM_ARG PTR(void) frameBufPtr) { if (vi_black) { VI_H_START_REG = 0; - } else { + } + else { VI_H_START_REG = hstart; } events_context.vi.next_buffer = frameBufPtr; @@ -376,7 +378,7 @@ extern "C" void osViSwapBuffer(RDRAM_ARG PTR(void) frameBufPtr) { } extern "C" void osViSetMode(RDRAM_ARG PTR(OSViMode) mode_) { - OSViMode* mode = TO_PTR(OSViMode, mode_); + OSViMode *mode = TO_PTR(OSViMode, mode_); VI_STATUS_REG = mode->comRegs.ctrl; VI_WIDTH_REG = mode->comRegs.width; // burst @@ -395,29 +397,29 @@ extern "C" void osViSetMode(RDRAM_ARG PTR(OSViMode) mode_) { VI_INTR_REG = mode->fldRegs[0].vIntr; } -#define VI_CTRL_TYPE_16 0x00002 -#define VI_CTRL_TYPE_32 0x00003 -#define VI_CTRL_GAMMA_DITHER_ON 0x00004 -#define VI_CTRL_GAMMA_ON 0x00008 -#define VI_CTRL_DIVOT_ON 0x00010 -#define VI_CTRL_SERRATE_ON 0x00040 -#define VI_CTRL_ANTIALIAS_MASK 0x00300 -#define VI_CTRL_ANTIALIAS_MODE_1 0x00100 -#define VI_CTRL_ANTIALIAS_MODE_2 0x00200 -#define VI_CTRL_ANTIALIAS_MODE_3 0x00300 -#define VI_CTRL_PIXEL_ADV_MASK 0x01000 -#define VI_CTRL_PIXEL_ADV_1 0x01000 -#define VI_CTRL_PIXEL_ADV_2 0x02000 -#define VI_CTRL_PIXEL_ADV_3 0x03000 -#define VI_CTRL_DITHER_FILTER_ON 0x10000 - -#define OS_VI_GAMMA_ON 0x0001 -#define OS_VI_GAMMA_OFF 0x0002 -#define OS_VI_GAMMA_DITHER_ON 0x0004 -#define OS_VI_GAMMA_DITHER_OFF 0x0008 -#define OS_VI_DIVOT_ON 0x0010 -#define OS_VI_DIVOT_OFF 0x0020 -#define OS_VI_DITHER_FILTER_ON 0x0040 +#define VI_CTRL_TYPE_16 0x00002 +#define VI_CTRL_TYPE_32 0x00003 +#define VI_CTRL_GAMMA_DITHER_ON 0x00004 +#define VI_CTRL_GAMMA_ON 0x00008 +#define VI_CTRL_DIVOT_ON 0x00010 +#define VI_CTRL_SERRATE_ON 0x00040 +#define VI_CTRL_ANTIALIAS_MASK 0x00300 +#define VI_CTRL_ANTIALIAS_MODE_1 0x00100 +#define VI_CTRL_ANTIALIAS_MODE_2 0x00200 +#define VI_CTRL_ANTIALIAS_MODE_3 0x00300 +#define VI_CTRL_PIXEL_ADV_MASK 0x01000 +#define VI_CTRL_PIXEL_ADV_1 0x01000 +#define VI_CTRL_PIXEL_ADV_2 0x02000 +#define VI_CTRL_PIXEL_ADV_3 0x03000 +#define VI_CTRL_DITHER_FILTER_ON 0x10000 + +#define OS_VI_GAMMA_ON 0x0001 +#define OS_VI_GAMMA_OFF 0x0002 +#define OS_VI_GAMMA_DITHER_ON 0x0004 +#define OS_VI_GAMMA_DITHER_OFF 0x0008 +#define OS_VI_DIVOT_ON 0x0010 +#define OS_VI_DIVOT_OFF 0x0020 +#define OS_VI_DITHER_FILTER_ON 0x0040 #define OS_VI_DITHER_FILTER_OFF 0x0080 extern "C" void osViSetSpecialFeatures(uint32_t func) { @@ -452,7 +454,7 @@ extern "C" void osViSetSpecialFeatures(uint32_t func) { if ((func & OS_VI_DITHER_FILTER_OFF) != 0) { VI_STATUS_REG &= ~VI_CTRL_DITHER_FILTER_ON; - //VI_STATUS_REG |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK; + // VI_STATUS_REG |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK; } } @@ -481,7 +483,7 @@ extern "C" PTR(void) osViGetCurrentFramebuffer() { } void ultramodern::submit_rsp_task(RDRAM_ARG PTR(OSTask) task_) { - OSTask* task = TO_PTR(OSTask, task_); + OSTask *task = TO_PTR(OSTask, task_); // Send gfx tasks to the graphics action queue if (task->t.type == M_GFXTASK) { @@ -525,10 +527,14 @@ void ultramodern::init_events(RDRAM_ARG ultramodern::renderer::WindowHandle wind show_renderer_error("Failed to load dynamic libraries. Make sure the DLLs are next to the recomp executable."); break; case ultramodern::renderer::SetupResult::InvalidGraphicsAPI: - show_renderer_error(ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + " is not supported on this platform. Please select a different graphics API."); + show_renderer_error( + ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + + " is not supported on this platform. Please select a different graphics API."); break; case ultramodern::renderer::SetupResult::GraphicsAPINotFound: - show_renderer_error("Unable to initialize " + ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + "." + driver_os_suffix); + show_renderer_error( + "Unable to initialize " + ultramodern::renderer::get_graphics_api_name(ultramodern::renderer::get_graphics_config()) + + "." + driver_os_suffix); break; case ultramodern::renderer::SetupResult::GraphicsDeviceNotFound: show_renderer_error("Unable to find compatible graphics device." + driver_os_suffix); diff --git a/ultramodern/src/input.cpp b/ultramodern/src/input.cpp index cf77096..fccf5c6 100644 --- a/ultramodern/src/input.cpp +++ b/ultramodern/src/input.cpp @@ -4,7 +4,7 @@ #include "ultramodern/ultra64.h" #include "ultramodern/ultramodern.hpp" -static ultramodern::input::callbacks_t input_callbacks {}; +static ultramodern::input::callbacks_t input_callbacks{}; void ultramodern::input::set_callbacks(const callbacks_t& callbacks) { input_callbacks = callbacks; @@ -27,8 +27,8 @@ void ultramodern::measure_input_latency() { #define CONT_NO_RESPONSE_ERROR 0x8 #define CONT_TYPE_NORMAL 0x0005 -#define CONT_TYPE_MOUSE 0x0002 -#define CONT_TYPE_VOICE 0x0100 +#define CONT_TYPE_MOUSE 0x0002 +#define CONT_TYPE_VOICE 0x0100 static int max_controllers = 0; @@ -36,11 +36,11 @@ static int max_controllers = 0; static u16 get_controller_type(ultramodern::input::Device device_type) { switch (device_type) { - case ultramodern::input::Device::None: - return 0; + case ultramodern::input::Device::None: + return 0; - case ultramodern::input::Device::Controller: - return CONT_TYPE_NORMAL; + case ultramodern::input::Device::Controller: + return CONT_TYPE_NORMAL; #if 0 case ultramodern::input::Device::Mouse: @@ -54,7 +54,7 @@ static u16 get_controller_type(ultramodern::input::Device device_type) { return 0; } -static void __osContGetInitData(u8* pattern, OSContStatus *data) { +static void __osContGetInitData(u8 *pattern, OSContStatus *data) { *pattern = 0x00; for (int controller = 0; controller < max_controllers; controller++) { @@ -144,8 +144,9 @@ extern "C" void osContGetReadData(OSContPad *data) { data[controller].stick_x = (int8_t)(127 * x); data[controller].stick_y = (int8_t)(127 * y); data[controller].err_no = 0; - } else { - data[controller].err_no = CONT_NO_RESPONSE_ERROR; // CHNL_ERR_NORESP >> 4 + } + else { + data[controller].err_no = CONT_NO_RESPONSE_ERROR; // CHNL_ERR_NORESP >> 4 } } } diff --git a/ultramodern/src/mesgqueue.cpp b/ultramodern/src/mesgqueue.cpp index 6f38e02..49a01a5 100644 --- a/ultramodern/src/mesgqueue.cpp +++ b/ultramodern/src/mesgqueue.cpp @@ -11,10 +11,10 @@ struct QueuedMessage { bool jam; }; -static moodycamel::BlockingConcurrentQueue external_messages {}; +static moodycamel::BlockingConcurrentQueue external_messages{}; void enqueue_external_message(PTR(OSMesgQueue) mq, OSMesg msg, bool jam) { - external_messages.enqueue({mq, msg, jam}); + external_messages.enqueue({ mq, msg, jam }); } bool do_send(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, bool jam, bool block); @@ -34,7 +34,7 @@ void ultramodern::wait_for_external_message(RDRAM_ARG1) { void ultramodern::wait_for_external_message_timed(RDRAM_ARG1, u32 millis) { QueuedMessage to_send; - if (external_messages.wait_dequeue_timed(to_send, std::chrono::milliseconds{millis})) { + if (external_messages.wait_dequeue_timed(to_send, std::chrono::milliseconds{ millis })) { do_send(PASS_RDRAM to_send.mq, to_send.mesg, to_send.jam, false); } } @@ -57,12 +57,12 @@ s32 MQ_IS_EMPTY(OSMesgQueue *mq) { return mq->validCount == 0; } -s32 MQ_IS_FULL(OSMesgQueue* mq) { +s32 MQ_IS_FULL(OSMesgQueue *mq) { return MQ_GET_COUNT(mq) >= mq->msgCount; } bool do_send(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, bool jam, bool block) { - OSMesgQueue* mq = TO_PTR(OSMesgQueue, mq_); + OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); if (!block) { // If non-blocking, fail if the queue is full. if (MQ_IS_FULL(mq)) { @@ -77,7 +77,7 @@ bool do_send(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, bool jam, bool block) { ultramodern::run_next_thread_and_wait(PASS_RDRAM1); } } - + if (jam) { // Jams insert at the head of the message queue's buffer. mq->first = (mq->first + mq->msgCount - 1) % mq->msgCount; @@ -96,18 +96,19 @@ bool do_send(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, bool jam, bool block) { if (!ultramodern::thread_queue_empty(PASS_RDRAM blocked_queue)) { ultramodern::schedule_running_thread(PASS_RDRAM ultramodern::thread_queue_pop(PASS_RDRAM blocked_queue)); } - + return true; } bool do_recv(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, bool block) { - OSMesgQueue* mq = TO_PTR(OSMesgQueue, mq_); + OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); if (!block) { // If non-blocking, fail if the queue is empty if (MQ_IS_EMPTY(mq)) { return false; } - } else { + } + else { // Otherwise, yield this thread in a loop until the queue is no longer full while (MQ_IS_EMPTY(mq)) { debug_printf("[Message Queue] Thread %d is blocked on receive\n", TO_PTR(OSThread, ultramodern::this_thread())->id); @@ -119,7 +120,7 @@ bool do_recv(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, bool block) { if (msg_ != NULLPTR) { *TO_PTR(OSMesg, msg_) = TO_PTR(OSMesg, mq->msg)[mq->first]; } - + mq->first = (mq->first + 1) % mq->msgCount; mq->validCount--; @@ -135,19 +136,19 @@ bool do_recv(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, bool block) { extern "C" s32 osSendMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) { OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); bool jam = false; - + // Don't directly send to the message queue if this isn't a game thread to avoid contention. if (!ultramodern::is_game_thread()) { enqueue_external_message(mq_, msg, jam); return 0; } - + // Handle any messages that have been received from an external thread. dequeue_external_messages(PASS_RDRAM1); // Try to send the message. bool sent = do_send(PASS_RDRAM mq_, msg, jam, flags == OS_MESG_BLOCK); - + // Check the queue to see if this thread should swap execution to another. ultramodern::check_running_queue(PASS_RDRAM1); @@ -157,19 +158,19 @@ extern "C" s32 osSendMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) { OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); bool jam = true; - + // Don't directly send to the message queue if this isn't a game thread to avoid contention. if (!ultramodern::is_game_thread()) { enqueue_external_message(mq_, msg, jam); return 0; } - + // Handle any messages that have been received from an external thread. dequeue_external_messages(PASS_RDRAM1); // Try to send the message. bool sent = do_send(PASS_RDRAM mq_, msg, jam, flags == OS_MESG_BLOCK); - + // Check the queue to see if this thread should swap execution to another. ultramodern::check_running_queue(PASS_RDRAM1); @@ -178,15 +179,15 @@ extern "C" s32 osJamMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, OSMesg msg, s32 flags) extern "C" s32 osRecvMesg(RDRAM_ARG PTR(OSMesgQueue) mq_, PTR(OSMesg) msg_, s32 flags) { OSMesgQueue *mq = TO_PTR(OSMesgQueue, mq_); - + assert(ultramodern::is_game_thread() && "RecvMesg not allowed outside of game threads."); - + // Handle any messages that have been received from an external thread. dequeue_external_messages(PASS_RDRAM1); // Try to receive a message. bool received = do_recv(PASS_RDRAM mq_, msg_, flags == OS_MESG_BLOCK); - + // Check the queue to see if this thread should swap execution to another. ultramodern::check_running_queue(PASS_RDRAM1); diff --git a/ultramodern/src/misc_ultra.cpp b/ultramodern/src/misc_ultra.cpp index 31fb226..dc44eb5 100644 --- a/ultramodern/src/misc_ultra.cpp +++ b/ultramodern/src/misc_ultra.cpp @@ -1,10 +1,10 @@ #include "ultramodern/ultra64.h" -#define K0BASE 0x80000000 -#define K1BASE 0xA0000000 -#define K2BASE 0xC0000000 -#define IS_KSEG0(x) ((u32)(x) >= K0BASE && (u32)(x) < K1BASE) -#define IS_KSEG1(x) ((u32)(x) >= K1BASE && (u32)(x) < K2BASE) +#define K0BASE 0x80000000 +#define K1BASE 0xA0000000 +#define K2BASE 0xC0000000 +#define IS_KSEG0(x) ((u32)(x) >= K0BASE && (u32)(x) < K1BASE) +#define IS_KSEG1(x) ((u32)(x) >= K1BASE && (u32)(x) < K2BASE) #define K0_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) #define K1_TO_PHYS(x) ((u32)(x)&0x1FFFFFFF) @@ -12,11 +12,12 @@ u32 osVirtualToPhysical(PTR(void) addr) { uintptr_t addr_val = (uintptr_t)addr; if (IS_KSEG0(addr_val)) { return K0_TO_PHYS(addr_val); - } else if (IS_KSEG1(addr_val)) { + } + else if (IS_KSEG1(addr_val)) { return K1_TO_PHYS(addr_val); - } else { + } + else { // TODO handle TLB mappings return (u32)addr_val; } } - diff --git a/ultramodern/src/port_main.c b/ultramodern/src/port_main.c index 968b4d3..a433a58 100644 --- a/ultramodern/src/port_main.c +++ b/ultramodern/src/port_main.c @@ -1,10 +1,10 @@ #if 0 -#include -#include -#include "ultra64.h" +# include "ultra64.h" +# include +# include -#define THREAD_STACK_SIZE 0x1000 +# define THREAD_STACK_SIZE 0x1000 u8 idle_stack[THREAD_STACK_SIZE] ALIGNED(16); u8 main_stack[THREAD_STACK_SIZE] ALIGNED(16); diff --git a/ultramodern/src/renderer_context.cpp b/ultramodern/src/renderer_context.cpp index 7fc5d26..8279eeb 100644 --- a/ultramodern/src/renderer_context.cpp +++ b/ultramodern/src/renderer_context.cpp @@ -10,8 +10,8 @@ void ultramodern::renderer::set_callbacks(const callbacks_t& callbacks) { render_callbacks = callbacks; } - -std::unique_ptr ultramodern::renderer::create_render_context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode) { +std::unique_ptr +ultramodern::renderer::create_render_context(uint8_t *rdram, WindowHandle window_handle, bool developer_mode) { if (render_callbacks.create_render_context == nullptr) { error_handling::message_box("[Error] The mandatory render callback `create_render_context` was not registered"); ULTRAMODERN_QUICK_EXIT(); @@ -27,7 +27,6 @@ std::string ultramodern::renderer::get_graphics_api_name(const GraphicsConfig& c return config.get_graphics_api_name(); } - static ultramodern::renderer::GraphicsConfig graphic_config{}; static std::mutex graphic_config_mutex; diff --git a/ultramodern/src/rsp.cpp b/ultramodern/src/rsp.cpp index 1594304..fea9454 100644 --- a/ultramodern/src/rsp.cpp +++ b/ultramodern/src/rsp.cpp @@ -3,7 +3,7 @@ #include "ultramodern/rsp.hpp" -static ultramodern::rsp::callbacks_t rsp_callbacks {}; +static ultramodern::rsp::callbacks_t rsp_callbacks{}; void ultramodern::rsp::set_callbacks(const callbacks_t& callbacks) { rsp_callbacks = callbacks; @@ -15,7 +15,7 @@ void ultramodern::rsp::init() { } } -bool ultramodern::rsp::run_task(RDRAM_ARG const OSTask* task) { +bool ultramodern::rsp::run_task(RDRAM_ARG const OSTask *task) { assert(rsp_callbacks.run_task != nullptr); return rsp_callbacks.run_task(PASS_RDRAM task); diff --git a/ultramodern/src/scheduling.cpp b/ultramodern/src/scheduling.cpp index a22f747..fe44e00 100644 --- a/ultramodern/src/scheduling.cpp +++ b/ultramodern/src/scheduling.cpp @@ -19,8 +19,8 @@ void ultramodern::check_running_queue(RDRAM_ARG1) { // Check if there are any threads in the running queue. if (!thread_queue_empty(PASS_RDRAM running_queue)) { // Check if the highest priority thread in the queue is higher priority than the current thread. - OSThread* next_thread = TO_PTR(OSThread, ultramodern::thread_queue_peek(PASS_RDRAM running_queue)); - OSThread* self = TO_PTR(OSThread, ultramodern::this_thread()); + OSThread *next_thread = TO_PTR(OSThread, ultramodern::thread_queue_peek(PASS_RDRAM running_queue)); + OSThread *self = TO_PTR(OSThread, ultramodern::this_thread()); if (next_thread->priority > self->priority) { ultramodern::thread_queue_pop(PASS_RDRAM running_queue); // Swap to the higher priority thread. diff --git a/ultramodern/src/task_win32.cpp b/ultramodern/src/task_win32.cpp index bacbf01..5a1e718 100644 --- a/ultramodern/src/task_win32.cpp +++ b/ultramodern/src/task_win32.cpp @@ -1,9 +1,9 @@ #ifdef _WIN32 -#include +# include -#include "ultramodern/ultra64.h" -#include "ultramodern/ultramodern.hpp" +# include "ultramodern/ultra64.h" +# include "ultramodern/ultramodern.hpp" extern "C" unsigned int sleep(unsigned int seconds) { Sleep(seconds * 1000); diff --git a/ultramodern/src/threadqueue.cpp b/ultramodern/src/threadqueue.cpp index 22ab3bc..4b56a91 100644 --- a/ultramodern/src/threadqueue.cpp +++ b/ultramodern/src/threadqueue.cpp @@ -4,7 +4,7 @@ static PTR(OSThread) running_queue_impl = NULLPTR; -static PTR(OSThread)* queue_to_ptr(RDRAM_ARG PTR(PTR(OSThread)) queue) { +static PTR(OSThread) *queue_to_ptr(RDRAM_ARG PTR(PTR(OSThread)) queue) { if (queue == ultramodern::running_queue) { return &running_queue_impl; } @@ -12,8 +12,8 @@ static PTR(OSThread)* queue_to_ptr(RDRAM_ARG PTR(PTR(OSThread)) queue) { } void ultramodern::thread_queue_insert(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(OSThread) toadd_) { - PTR(OSThread)* cur = queue_to_ptr(PASS_RDRAM queue_); - OSThread* toadd = TO_PTR(OSThread, toadd_); + PTR(OSThread) *cur = queue_to_ptr(PASS_RDRAM queue_); + OSThread *toadd = TO_PTR(OSThread, toadd_); debug_printf("[Thread Queue] Inserting thread %d into queue 0x%08X\n", toadd->id, (uintptr_t)queue_); while (*cur && TO_PTR(OSThread, *cur)->priority > toadd->priority) { cur = &TO_PTR(OSThread, *cur)->next; @@ -32,7 +32,7 @@ void ultramodern::thread_queue_insert(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(O } PTR(OSThread) ultramodern::thread_queue_pop(RDRAM_ARG PTR(PTR(OSThread)) queue_) { - PTR(OSThread)* queue = queue_to_ptr(PASS_RDRAM queue_); + PTR(OSThread) *queue = queue_to_ptr(PASS_RDRAM queue_); PTR(OSThread) ret = *queue; *queue = TO_PTR(OSThread, ret)->next; TO_PTR(OSThread, ret)->queue = NULLPTR; @@ -45,7 +45,7 @@ bool ultramodern::thread_queue_remove(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(O PTR(PTR(OSThread)) cur = queue_; while (cur != NULLPTR) { - PTR(OSThread)* cur_ptr = queue_to_ptr(PASS_RDRAM queue_); + PTR(OSThread) *cur_ptr = queue_to_ptr(PASS_RDRAM queue_); if (*cur_ptr == t_) { return true; } @@ -56,11 +56,11 @@ bool ultramodern::thread_queue_remove(RDRAM_ARG PTR(PTR(OSThread)) queue_, PTR(O } bool ultramodern::thread_queue_empty(RDRAM_ARG PTR(PTR(OSThread)) queue_) { - PTR(OSThread)* queue = queue_to_ptr(PASS_RDRAM queue_); + PTR(OSThread) *queue = queue_to_ptr(PASS_RDRAM queue_); return *queue == NULLPTR; } PTR(OSThread) ultramodern::thread_queue_peek(RDRAM_ARG PTR(PTR(OSThread)) queue_) { - PTR(OSThread)* queue = queue_to_ptr(PASS_RDRAM queue_); + PTR(OSThread) *queue = queue_to_ptr(PASS_RDRAM queue_); return *queue; } diff --git a/ultramodern/src/threads.cpp b/ultramodern/src/threads.cpp index adb898a..d2a200a 100644 --- a/ultramodern/src/threads.cpp +++ b/ultramodern/src/threads.cpp @@ -1,15 +1,15 @@ -#include -#include #include +#include #include +#include +#include "blockingconcurrentqueue.h" #include "ultramodern/ultra64.h" #include "ultramodern/ultramodern.hpp" -#include "blockingconcurrentqueue.h" // Native APIs only used to set thread names for easier debugging #ifdef _WIN32 -#include +# include #endif extern "C" void bootproc(); @@ -37,20 +37,17 @@ int main(int argc, char** argv) { #endif #if 1 -void run_thread_function(uint8_t* rdram, uint64_t addr, uint64_t sp, uint64_t arg); +void run_thread_function(uint8_t *rdram, uint64_t addr, uint64_t sp, uint64_t arg); #else -#define run_thread_function(func, sp, arg) func(arg) +# define run_thread_function(func, sp, arg) func(arg) #endif #if defined(_WIN32) void ultramodern::set_native_thread_name(const std::string& name) { - std::wstring wname{name.begin(), name.end()}; + std::wstring wname{ name.begin(), name.end() }; HRESULT r; - r = SetThreadDescription( - GetCurrentThread(), - wname.c_str() - ); + r = SetThreadDescription(GetCurrentThread(), wname.c_str()); } void ultramodern::set_native_thread_priority(ThreadPriority pri) { @@ -116,13 +113,14 @@ void ultramodern::set_native_thread_name(const std::string& name) { pthread_setname_np(name.c_str()); } -void ultramodern::set_native_thread_priority(ThreadPriority pri) {} +void ultramodern::set_native_thread_priority(ThreadPriority pri) { +} #endif std::atomic_int temporary_threads = 0; std::atomic_int permanent_threads = 0; -void wait_for_resumed(RDRAM_ARG UltraThreadContext* thread_context) { +void wait_for_resumed(RDRAM_ARG UltraThreadContext *thread_context) { TO_PTR(OSThread, ultramodern::this_thread())->context->running.wait(); // If this thread's context was replaced by another thread or deleted, destroy it again from its own context. // This will trigger thread cleanup instead. @@ -131,7 +129,7 @@ void wait_for_resumed(RDRAM_ARG UltraThreadContext* thread_context) { } } -void resume_thread(OSThread* t) { +void resume_thread(OSThread *t) { debug_printf("[Thread] Resuming execution of thread %d\n", t->id); t->context->running.signal(); } @@ -141,24 +139,24 @@ void run_next_thread(RDRAM_ARG1) { throw std::runtime_error("No threads left to run!\n"); } - OSThread* to_run = TO_PTR(OSThread, ultramodern::thread_queue_pop(PASS_RDRAM ultramodern::running_queue)); + OSThread *to_run = TO_PTR(OSThread, ultramodern::thread_queue_pop(PASS_RDRAM ultramodern::running_queue)); debug_printf("[Scheduling] Resuming execution of thread %d\n", to_run->id); to_run->context->running.signal(); } void ultramodern::run_next_thread_and_wait(RDRAM_ARG1) { - UltraThreadContext* cur_context = TO_PTR(OSThread, thread_self)->context; + UltraThreadContext *cur_context = TO_PTR(OSThread, thread_self)->context; run_next_thread(PASS_RDRAM1); wait_for_resumed(PASS_RDRAM cur_context); } void ultramodern::resume_thread_and_wait(RDRAM_ARG OSThread *t) { - UltraThreadContext* cur_context = TO_PTR(OSThread, thread_self)->context; + UltraThreadContext *cur_context = TO_PTR(OSThread, thread_self)->context; resume_thread(t); wait_for_resumed(PASS_RDRAM cur_context); } -static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entrypoint, PTR(void) arg, UltraThreadContext* thread_context) { +static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entrypoint, PTR(void) arg, UltraThreadContext *thread_context) { OSThread *self = TO_PTR(OSThread, self_); debug_printf("[Thread] Thread created: %d\n", self->id); thread_self = self_; @@ -183,7 +181,7 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry // Wait until the thread is marked as running. wait_for_resumed(PASS_RDRAM thread_context); - + // Make sure the thread wasn't replaced or destroyed before it was started. if (self->context == thread_context) { debug_printf("[Thread] Thread started: %d\n", self->id); @@ -206,7 +204,7 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry // Dispose of this thread now that it's completed or terminated. ultramodern::cleanup_thread(thread_context); - + // TODO fix these being hardcoded (this is only used for quicksaving) if ((self->id == 2 && self->priority == 5) || self->id == 13) { // slowly, flashrom temporary_threads.fetch_sub(1); @@ -222,7 +220,7 @@ uint32_t ultramodern::temporary_thread_count() { } extern "C" void osStartThread(RDRAM_ARG PTR(OSThread) t_) { - OSThread* t = TO_PTR(OSThread, t_); + OSThread *t = TO_PTR(OSThread, t_); debug_printf("[os] Start Thread %d\n", t->id); // Wait until the thread is initialized to indicate that it's ready to be started. @@ -239,14 +237,14 @@ extern "C" void osStartThread(RDRAM_ARG PTR(OSThread) t_) { else { t->state = OSThreadState::QUEUED; resume_thread(t); - //throw ultramodern::thread_terminated{}; + // throw ultramodern::thread_terminated{}; } } extern "C" void osCreateThread(RDRAM_ARG PTR(OSThread) t_, OSId id, PTR(thread_func_t) entrypoint, PTR(void) arg, PTR(void) sp, OSPri pri) { debug_printf("[os] Create Thread %d\n", id); OSThread *t = TO_PTR(OSThread, t_); - + t->next = NULLPTR; t->queue = NULLPTR; t->priority = pri; @@ -257,7 +255,7 @@ extern "C" void osCreateThread(RDRAM_ARG PTR(OSThread) t_, OSId id, PTR(thread_f // Spawn a new thread, which will immediately pause itself and wait until it's been started. // Pass the context as an argument to the thread function to ensure that it can't get cleared before the thread captures its value. t->context = new UltraThreadContext{}; - t->context->host_thread = std::thread{_thread_func, PASS_RDRAM t_, entrypoint, arg, t->context}; + t->context->host_thread = std::thread{ _thread_func, PASS_RDRAM t_, entrypoint, arg, t->context }; } extern "C" void osStopThread(RDRAM_ARG PTR(OSThread) t_) { @@ -268,17 +266,17 @@ extern "C" void osDestroyThread(RDRAM_ARG PTR(OSThread) t_) { if (t_ == NULLPTR) { t_ = thread_self; } - OSThread* t = TO_PTR(OSThread, t_); + OSThread *t = TO_PTR(OSThread, t_); // Check if the thread is destroying itself (arg is null or thread_self) if (t_ == thread_self) { throw ultramodern::thread_terminated{}; } - // Otherwise if the thread isn't stopped, remove it from its currrent queue., + // Otherwise if the thread isn't stopped, remove it from its currrent queue., if (t->state != OSThreadState::STOPPED) { ultramodern::thread_queue_remove(PASS_RDRAM t->queue, t_); } // Check if the thread has already been destroyed to prevent destroying it again. - UltraThreadContext* cur_context = t->context; + UltraThreadContext *cur_context = t->context; if (cur_context != nullptr) { // Mark the target thread as destroyed and resume it. When it starts it'll check this and terminate itself instead of resuming. t->context = nullptr; @@ -290,7 +288,7 @@ extern "C" void osSetThreadPri(RDRAM_ARG PTR(OSThread) t_, OSPri pri) { if (t_ == NULLPTR) { t_ = thread_self; } - OSThread* t = TO_PTR(OSThread, t_); + OSThread *t = TO_PTR(OSThread, t_); if (t->priority != pri) { t->priority = pri; @@ -323,13 +321,13 @@ PTR(OSThread) ultramodern::this_thread() { } static std::thread thread_cleaner_thread; -static moodycamel::BlockingConcurrentQueue deleted_threads{}; +static moodycamel::BlockingConcurrentQueue deleted_threads{}; extern std::atomic_bool exited; void thread_cleaner_func() { using namespace std::chrono_literals; while (!exited) { - UltraThreadContext* to_delete; + UltraThreadContext *to_delete; if (deleted_threads.wait_dequeue_timed(to_delete, 10ms)) { debug_printf("[Cleanup] Deleting thread context %p\n", to_delete); @@ -340,7 +338,7 @@ void thread_cleaner_func() { } void ultramodern::init_thread_cleanup() { - thread_cleaner_thread = std::thread{thread_cleaner_func}; + thread_cleaner_thread = std::thread{ thread_cleaner_func }; } void ultramodern::cleanup_thread(UltraThreadContext *cur_context) { diff --git a/ultramodern/src/timer.cpp b/ultramodern/src/timer.cpp index 1b4e9ae..5822f18 100644 --- a/ultramodern/src/timer.cpp +++ b/ultramodern/src/timer.cpp @@ -1,14 +1,14 @@ +#include "blockingconcurrentqueue.h" +#include #include #include -#include -#include "blockingconcurrentqueue.h" #include "ultramodern/ultra64.h" #include "ultramodern/ultramodern.hpp" #ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include "Windows.h" +# define WIN32_LEAN_AND_MEAN +# include "Windows.h" #endif // Start time for the program @@ -70,8 +70,8 @@ void timer_thread(RDRAM_ARG1) { // Lambda comparator function to keep the set ordered auto timer_sort = [PASS_RDRAM1](PTR(OSTimer) a_, PTR(OSTimer) b_) { - OSTimer* a = TO_PTR(OSTimer, a_); - OSTimer* b = TO_PTR(OSTimer, b_); + OSTimer *a = TO_PTR(OSTimer, a_); + OSTimer *b = TO_PTR(OSTimer, b_); // Order by timestamp if the timers have different timestamps if (a->timestamp != b->timestamp) { @@ -83,14 +83,15 @@ void timer_thread(RDRAM_ARG1) { }; // Ordered set of timers that are currently active - std::set active_timers{timer_sort}; - + std::set active_timers{ timer_sort }; + // Lambda to process a timer action to handle adding and removing timers auto process_timer_action = [&](const Action& action) { // Determine the action type and act on it - if (const auto* add_action = std::get_if(&action)) { + if (const auto *add_action = std::get_if(&action)) { active_timers.insert(add_action->timer); - } else if (const auto* remove_action = std::get_if(&action)) { + } + else if (const auto *remove_action = std::get_if(&action)) { active_timers.erase(remove_action->timer); } }; @@ -110,7 +111,7 @@ void timer_thread(RDRAM_ARG1) { // Get the timer that's closest to running out PTR(OSTimer) cur_timer_ = *active_timers.begin(); - OSTimer* cur_timer = TO_PTR(OSTimer, cur_timer_); + OSTimer *cur_timer = TO_PTR(OSTimer, cur_timer_); // Remove the timer from the queue (it may get readded if waiting is interrupted) active_timers.erase(cur_timer_); @@ -120,7 +121,7 @@ void timer_thread(RDRAM_ARG1) { // Wait for either the duration to complete or a new action to come through if (wait_duration.count() >= 0 && timer_context.action_queue.wait_dequeue_timed(cur_action, wait_duration)) { - // Timer was interrupted by a new action + // Timer was interrupted by a new action // Add the current timer back to the queue (done first in case the action is to remove this timer) active_timers.insert(cur_timer_); // Process the new action @@ -169,13 +170,14 @@ extern "C" OSTime osGetTime() { } extern "C" int osSetTimer(RDRAM_ARG PTR(OSTimer) t_, OSTime countdown, OSTime interval, PTR(OSMesgQueue) mq, OSMesg msg) { - OSTimer* t = TO_PTR(OSTimer, t_); + OSTimer *t = TO_PTR(OSTimer, t_); // Determine the time when this timer will trigger off if (countdown == 0) { // Set the timestamp based on the interval t->timestamp = interval + time_now(); - } else { + } + else { t->timestamp = countdown + time_now(); } t->interval = interval; @@ -214,7 +216,7 @@ void ultramodern::sleep_until(const std::chrono::high_resolution_clock::time_poi #else void ultramodern::sleep_milliseconds(uint32_t millis) { - std::this_thread::sleep_for(std::chrono::milliseconds{millis}); + std::this_thread::sleep_for(std::chrono::milliseconds{ millis }); } void ultramodern::sleep_until(const std::chrono::high_resolution_clock::time_point& time_point) { diff --git a/ultramodern/src/ultrainit.cpp b/ultramodern/src/ultrainit.cpp index fe11115..0ace967 100644 --- a/ultramodern/src/ultrainit.cpp +++ b/ultramodern/src/ultrainit.cpp @@ -2,14 +2,9 @@ #include "ultramodern/ultramodern.hpp" void ultramodern::set_callbacks( - const rsp::callbacks_t& rsp_callbacks, - const renderer::callbacks_t& renderer_callbacks, - const audio_callbacks_t& audio_callbacks, - const input::callbacks_t& input_callbacks, - const gfx_callbacks_t& gfx_callbacks, - const events::callbacks_t& thread_callbacks, - const error_handling::callbacks_t& error_handling_callbacks -) { + const rsp::callbacks_t& rsp_callbacks, const renderer::callbacks_t& renderer_callbacks, const audio_callbacks_t& audio_callbacks, + const input::callbacks_t& input_callbacks, const gfx_callbacks_t& gfx_callbacks, const events::callbacks_t& thread_callbacks, + const error_handling::callbacks_t& error_handling_callbacks) { ultramodern::rsp::set_callbacks(rsp_callbacks); ultramodern::renderer::set_callbacks(renderer_callbacks); ultramodern::set_audio_callbacks(audio_callbacks);