Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .clang-format file and format most files #4

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -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"]
2 changes: 1 addition & 1 deletion librecomp/include/librecomp/files.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
76 changes: 36 additions & 40 deletions librecomp/include/librecomp/game.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef __RECOMP_GAME__
#define __RECOMP_GAME__

#include <vector>
#include <filesystem>
#include <vector>

#include "recomp.h"
#include "rsp.hpp"
Expand All @@ -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<uint8_t>&& 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<uint8_t>&& 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
23 changes: 13 additions & 10 deletions librecomp/include/librecomp/helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <ultramodern/ultra64.h>

template<int index, typename T>
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<T, float>) {
Expand All @@ -15,13 +15,14 @@ T _arg(uint8_t* rdram, recomp_context* ctx) {
}
else {
// static_assert in else workaround
[] <bool flag = false>() {
[]<bool flag = false>() {
static_assert(flag, "Floats in a2/a3 not supported");
}();
}
();
}
}
else if constexpr (std::is_pointer_v<T>) {
static_assert (!std::is_pointer_v<std::remove_pointer_t<T>>, "Double pointers not supported");
static_assert(!std::is_pointer_v<std::remove_pointer_t<T>>, "Double pointers not supported");
return TO_PTR(std::remove_pointer_t<T>, raw_arg);
}
else if constexpr (std::is_integral_v<T>) {
Expand All @@ -30,14 +31,15 @@ T _arg(uint8_t* rdram, recomp_context* ctx) {
}
else {
// static_assert in else workaround
[] <bool flag = false>() {
[]<bool flag = false>() {
static_assert(flag, "Unsupported type");
}();
}
();
}
}

template <typename T>
void _return(recomp_context* ctx, T val) {
template<typename T>
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<T, float>) {
ctx->f0.fl = val;
Expand All @@ -47,9 +49,10 @@ void _return(recomp_context* ctx, T val) {
}
else {
// static_assert in else workaround
[] <bool flag = false>() {
[]<bool flag = false>() {
static_assert(flag, "Unsupported type");
}();
}
();
}
}

Expand Down
14 changes: 7 additions & 7 deletions librecomp/include/librecomp/overlays.hpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
#ifndef __RECOMP_OVERLAYS_H__
#define __RECOMP_OVERLAYS_H__

#include <cstdint>
#include "sections.h"
#include <cstdint>

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);
Expand Down
49 changes: 23 additions & 26 deletions librecomp/include/librecomp/rsp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include <cstdio>

#include "rsp_vu.hpp"
#include "recomp.h"
#include "rsp_vu.hpp"
#include "ultramodern/ultra64.h"

// TODO: Move these to recomp namespace?
Expand All @@ -17,69 +17,64 @@ 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<int8_t*>(dmem + (0xFFF & (((offset) + (addr)) ^ 3))))
#define RSP_MEM_B(offset, addr) (*reinterpret_cast<int8_t *>(dmem + (0xFFF & (((offset) + (addr)) ^ 3))))

#define RSP_MEM_BU(offset, addr) \
(*reinterpret_cast<uint8_t*>(dmem + (0xFFF & (((offset) + (addr)) ^ 3))))
#define RSP_MEM_BU(offset, addr) (*reinterpret_cast<uint8_t *>(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<uint8_t*>(&out)[i ^ 3] = RSP_MEM_BU(offset + i, addr);
reinterpret_cast<uint8_t *>(&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<uint8_t*>(&val)[i ^ 3];
RSP_MEM_BU(offset + i, addr) = reinterpret_cast<uint8_t *>(&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<uint8_t*>(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr);
reinterpret_cast<uint8_t *>(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr);
}
return out;
}

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<uint8_t*>(&out)[(i + 2) ^ 3] = RSP_MEM_BU(offset + i, addr);
reinterpret_cast<uint8_t *>(&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<uint8_t*>(&val)[(i + 2) ^ 3];
RSP_MEM_BU(offset + i, addr) = reinterpret_cast<uint8_t *>(&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);
Expand All @@ -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);
Expand All @@ -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
Loading