mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp
synced 2026-05-22 22:44:34 -04:00
Migrate to N64ModernRuntime (#354)
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
#ifndef __OVL_PATCHES_HPP__
|
||||
#define __OVL_PATCHES_HPP__
|
||||
|
||||
namespace zelda64 {
|
||||
void register_overlays();
|
||||
void register_patches();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,327 +0,0 @@
|
||||
#ifndef __RECOMP_H__
|
||||
#define __RECOMP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#if 0 // treat GPRs as 32-bit, should be better codegen
|
||||
typedef uint32_t gpr;
|
||||
|
||||
#define SIGNED(val) \
|
||||
((int32_t)(val))
|
||||
#else
|
||||
typedef uint64_t gpr;
|
||||
|
||||
#define SIGNED(val) \
|
||||
((int64_t)(val))
|
||||
#endif
|
||||
|
||||
#define ADD32(a, b) \
|
||||
((gpr)(int32_t)((a) + (b)))
|
||||
|
||||
#define SUB32(a, b) \
|
||||
((gpr)(int32_t)((a) - (b)))
|
||||
|
||||
#define MEM_W(offset, reg) \
|
||||
(*(int32_t*)(rdram + ((((reg) + (offset))) - 0xFFFFFFFF80000000)))
|
||||
//(*(int32_t*)(rdram + ((((reg) + (offset))) & 0x3FFFFFF)))
|
||||
|
||||
#define MEM_H(offset, reg) \
|
||||
(*(int16_t*)(rdram + ((((reg) + (offset)) ^ 2) - 0xFFFFFFFF80000000)))
|
||||
//(*(int16_t*)(rdram + ((((reg) + (offset)) ^ 2) & 0x3FFFFFF)))
|
||||
|
||||
#define MEM_B(offset, reg) \
|
||||
(*(int8_t*)(rdram + ((((reg) + (offset)) ^ 3) - 0xFFFFFFFF80000000)))
|
||||
//(*(int8_t*)(rdram + ((((reg) + (offset)) ^ 3) & 0x3FFFFFF)))
|
||||
|
||||
#define MEM_HU(offset, reg) \
|
||||
(*(uint16_t*)(rdram + ((((reg) + (offset)) ^ 2) - 0xFFFFFFFF80000000)))
|
||||
//(*(uint16_t*)(rdram + ((((reg) + (offset)) ^ 2) & 0x3FFFFFF)))
|
||||
|
||||
#define MEM_BU(offset, reg) \
|
||||
(*(uint8_t*)(rdram + ((((reg) + (offset)) ^ 3) - 0xFFFFFFFF80000000)))
|
||||
//(*(uint8_t*)(rdram + ((((reg) + (offset)) ^ 3) & 0x3FFFFFF)))
|
||||
|
||||
#define SD(val, offset, reg) { \
|
||||
*(uint32_t*)(rdram + ((((reg) + (offset) + 4)) - 0xFFFFFFFF80000000)) = (uint32_t)((gpr)(val) >> 0); \
|
||||
*(uint32_t*)(rdram + ((((reg) + (offset) + 0)) - 0xFFFFFFFF80000000)) = (uint32_t)((gpr)(val) >> 32); \
|
||||
}
|
||||
|
||||
//#define SD(val, offset, reg) { \
|
||||
// *(uint32_t*)(rdram + ((((reg) + (offset) + 4)) & 0x3FFFFFF)) = (uint32_t)((val) >> 32); \
|
||||
// *(uint32_t*)(rdram + ((((reg) + (offset) + 0)) & 0x3FFFFFF)) = (uint32_t)((val) >> 0); \
|
||||
//}
|
||||
|
||||
static inline uint64_t load_doubleword(uint8_t* rdram, gpr reg, gpr offset) {
|
||||
uint64_t ret = 0;
|
||||
uint64_t lo = (uint64_t)(uint32_t)MEM_W(reg, offset + 4);
|
||||
uint64_t hi = (uint64_t)(uint32_t)MEM_W(reg, offset + 0);
|
||||
ret = (lo << 0) | (hi << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define LD(offset, reg) \
|
||||
load_doubleword(rdram, offset, reg)
|
||||
|
||||
static inline gpr do_lwl(uint8_t* rdram, gpr initial_value, gpr offset, gpr reg) {
|
||||
// Calculate the overall address
|
||||
gpr address = (offset + reg);
|
||||
|
||||
// Load the aligned word
|
||||
gpr word_address = address & ~0x3;
|
||||
uint32_t loaded_value = MEM_W(0, word_address);
|
||||
|
||||
// Mask the existing value and shift the loaded value appropriately
|
||||
gpr misalignment = address & 0x3;
|
||||
gpr masked_value = initial_value & ~(0xFFFFFFFFu << (misalignment * 8));
|
||||
loaded_value <<= (misalignment * 8);
|
||||
|
||||
// Cast to int32_t to sign extend first
|
||||
return (gpr)(int32_t)(masked_value | loaded_value);
|
||||
}
|
||||
|
||||
static inline gpr do_lwr(uint8_t* rdram, gpr initial_value, gpr offset, gpr reg) {
|
||||
// Calculate the overall address
|
||||
gpr address = (offset + reg);
|
||||
|
||||
// Load the aligned word
|
||||
gpr word_address = address & ~0x3;
|
||||
uint32_t loaded_value = MEM_W(0, word_address);
|
||||
|
||||
// Mask the existing value and shift the loaded value appropriately
|
||||
gpr misalignment = address & 0x3;
|
||||
gpr masked_value = initial_value & ~(0xFFFFFFFFu >> (24 - misalignment * 8));
|
||||
loaded_value >>= (24 - misalignment * 8);
|
||||
|
||||
// Cast to int32_t to sign extend first
|
||||
return (gpr)(int32_t)(masked_value | loaded_value);
|
||||
}
|
||||
|
||||
static inline void do_swl(uint8_t* rdram, gpr offset, gpr reg, gpr val) {
|
||||
// Calculate the overall address
|
||||
gpr address = (offset + reg);
|
||||
|
||||
// Get the initial value of the aligned word
|
||||
gpr word_address = address & ~0x3;
|
||||
uint32_t initial_value = MEM_W(0, word_address);
|
||||
|
||||
// Mask the initial value and shift the input value appropriately
|
||||
gpr misalignment = address & 0x3;
|
||||
uint32_t masked_initial_value = initial_value & ~(0xFFFFFFFFu >> (misalignment * 8));
|
||||
uint32_t shifted_input_value = ((uint32_t)val) >> (misalignment * 8);
|
||||
MEM_W(0, word_address) = masked_initial_value | shifted_input_value;
|
||||
}
|
||||
|
||||
static inline void do_swr(uint8_t* rdram, gpr offset, gpr reg, gpr val) {
|
||||
// Calculate the overall address
|
||||
gpr address = (offset + reg);
|
||||
|
||||
// Get the initial value of the aligned word
|
||||
gpr word_address = address & ~0x3;
|
||||
uint32_t initial_value = MEM_W(0, word_address);
|
||||
|
||||
// Mask the initial value and shift the input value appropriately
|
||||
gpr misalignment = address & 0x3;
|
||||
uint32_t masked_initial_value = initial_value & ~(0xFFFFFFFFu << (24 - misalignment * 8));
|
||||
uint32_t shifted_input_value = ((uint32_t)val) << (24 - misalignment * 8);
|
||||
MEM_W(0, word_address) = masked_initial_value | shifted_input_value;
|
||||
}
|
||||
|
||||
#define S32(val) \
|
||||
((int32_t)(val))
|
||||
|
||||
#define U32(val) \
|
||||
((uint32_t)(val))
|
||||
|
||||
#define S64(val) \
|
||||
((int64_t)(val))
|
||||
|
||||
#define U64(val) \
|
||||
((uint64_t)(val))
|
||||
|
||||
#define MUL_S(val1, val2) \
|
||||
((val1) * (val2))
|
||||
|
||||
#define MUL_D(val1, val2) \
|
||||
((val1) * (val2))
|
||||
|
||||
#define DIV_S(val1, val2) \
|
||||
((val1) / (val2))
|
||||
|
||||
#define DIV_D(val1, val2) \
|
||||
((val1) / (val2))
|
||||
|
||||
#define CVT_S_W(val) \
|
||||
((float)((int32_t)(val)))
|
||||
|
||||
#define CVT_D_W(val) \
|
||||
((double)((int32_t)(val)))
|
||||
|
||||
#define CVT_D_S(val) \
|
||||
((double)(val))
|
||||
|
||||
#define CVT_S_D(val) \
|
||||
((float)(val))
|
||||
|
||||
#define TRUNC_W_S(val) \
|
||||
((int32_t)(val))
|
||||
|
||||
#define TRUNC_W_D(val) \
|
||||
((int32_t)(val))
|
||||
|
||||
#define TRUNC_L_S(val) \
|
||||
((int64_t)(val))
|
||||
|
||||
#define TRUNC_L_D(val) \
|
||||
((int64_t)(val))
|
||||
|
||||
#define DEFAULT_ROUNDING_MODE 0
|
||||
|
||||
static inline int32_t do_cvt_w_s(float val, unsigned int rounding_mode) {
|
||||
switch (rounding_mode) {
|
||||
case 0: // round to nearest value
|
||||
return (int32_t)lroundf(val);
|
||||
case 1: // round to zero (truncate)
|
||||
return (int32_t)val;
|
||||
case 2: // round to positive infinity (ceil)
|
||||
return (int32_t)ceilf(val);
|
||||
case 3: // round to negative infinity (floor)
|
||||
return (int32_t)floorf(val);
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CVT_W_S(val) \
|
||||
do_cvt_w_s(val, rounding_mode)
|
||||
|
||||
static inline int32_t do_cvt_w_d(double val, unsigned int rounding_mode) {
|
||||
switch (rounding_mode) {
|
||||
case 0: // round to nearest value
|
||||
return (int32_t)lround(val);
|
||||
case 1: // round to zero (truncate)
|
||||
return (int32_t)val;
|
||||
case 2: // round to positive infinity (ceil)
|
||||
return (int32_t)ceil(val);
|
||||
case 3: // round to negative infinity (floor)
|
||||
return (int32_t)floor(val);
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CVT_W_D(val) \
|
||||
do_cvt_w_d(val, rounding_mode)
|
||||
|
||||
#define NAN_CHECK(val) \
|
||||
assert(val == val)
|
||||
|
||||
//#define NAN_CHECK(val)
|
||||
|
||||
typedef union {
|
||||
double d;
|
||||
struct {
|
||||
float fl;
|
||||
float fh;
|
||||
};
|
||||
struct {
|
||||
uint32_t u32l;
|
||||
uint32_t u32h;
|
||||
};
|
||||
uint64_t u64;
|
||||
} fpr;
|
||||
|
||||
typedef struct {
|
||||
gpr r0, r1, r2, r3, r4, r5, r6, r7,
|
||||
r8, r9, r10, r11, r12, r13, r14, r15,
|
||||
r16, r17, r18, r19, r20, r21, r22, r23,
|
||||
r24, r25, r26, r27, r28, r29, r30, r31;
|
||||
fpr f0, f1, f2, f3, f4, f5, f6, f7,
|
||||
f8, f9, f10, f11, f12, f13, f14, f15,
|
||||
f16, f17, f18, f19, f20, f21, f22, f23,
|
||||
f24, f25, f26, f27, f28, f29, f30, f31;
|
||||
uint64_t hi, lo;
|
||||
uint32_t* f_odd;
|
||||
uint32_t status_reg;
|
||||
uint8_t mips3_float_mode;
|
||||
} recomp_context;
|
||||
|
||||
// Checks if the target is an even float register or that mips3 float mode is enabled
|
||||
#define CHECK_FR(ctx, idx) \
|
||||
assert(((idx) & 1) == 0 || (ctx)->mips3_float_mode)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cop0_status_write(recomp_context* ctx, gpr value);
|
||||
gpr cop0_status_read(recomp_context* ctx);
|
||||
void switch_error(const char* func, uint32_t vram, uint32_t jtbl);
|
||||
void do_break(uint32_t vram);
|
||||
|
||||
typedef void (recomp_func_t)(uint8_t* rdram, recomp_context* ctx);
|
||||
|
||||
recomp_func_t* get_function(int32_t vram);
|
||||
|
||||
#define LOOKUP_FUNC(val) \
|
||||
get_function((int32_t)(val))
|
||||
|
||||
extern int32_t section_addresses[];
|
||||
|
||||
#define LO16(x) \
|
||||
((x) & 0xFFFF)
|
||||
|
||||
#define HI16(x) \
|
||||
(((x) >> 16) + (((x) >> 15) & 1))
|
||||
|
||||
#define RELOC_HI16(section_index, offset) \
|
||||
HI16(section_addresses[section_index] + (offset))
|
||||
|
||||
#define RELOC_LO16(section_index, offset) \
|
||||
LO16(section_addresses[section_index] + (offset))
|
||||
|
||||
// For Banjo-Tooie
|
||||
void recomp_syscall_handler(uint8_t* rdram, recomp_context* ctx, int32_t instruction_vram);
|
||||
|
||||
// For the Mario Party games (not working)
|
||||
//// This has to be in this file so it can be inlined
|
||||
//struct jmp_buf_storage {
|
||||
// jmp_buf buffer;
|
||||
//};
|
||||
//
|
||||
//struct RecompJmpBuf {
|
||||
// int32_t owner;
|
||||
// struct jmp_buf_storage* storage;
|
||||
// uint64_t magic;
|
||||
//};
|
||||
//
|
||||
//// Randomly generated constant
|
||||
//#define SETJMP_MAGIC 0xe17afdfa939a437bu
|
||||
//
|
||||
//int32_t osGetThreadEx(void);
|
||||
//
|
||||
//#define setjmp_recomp(rdram, ctx) { \
|
||||
// struct RecompJmpBuf* buf = (struct RecompJmpBuf*)(&rdram[(uint64_t)ctx->r4 - 0xFFFFFFFF80000000]); \
|
||||
// \
|
||||
// /* Check if this jump buffer was previously set up */ \
|
||||
// if (buf->magic == SETJMP_MAGIC) { \
|
||||
// /* If so, free the old jmp_buf */ \
|
||||
// free(buf->storage); \
|
||||
// } \
|
||||
// \
|
||||
// buf->magic = SETJMP_MAGIC; \
|
||||
// buf->owner = osGetThreadEx(); \
|
||||
// buf->storage = (struct jmp_buf_storage*)calloc(1, sizeof(struct jmp_buf_storage)); \
|
||||
// ctx->r2 = setjmp(buf->storage->buffer); \
|
||||
//}
|
||||
|
||||
void pause_self(uint8_t *rdram);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef __RECOMP_CONFIG_H__
|
||||
#define __RECOMP_CONFIG_H__
|
||||
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
#include "../ultramodern/config.hpp"
|
||||
|
||||
namespace recomp {
|
||||
constexpr std::u8string_view program_id = u8"Zelda64Recompiled";
|
||||
constexpr std::u8string_view mm_game_id = u8"mm.n64.us.1.0";
|
||||
constexpr std::string_view program_name = "Zelda 64: Recompiled";
|
||||
|
||||
void load_config();
|
||||
void save_config();
|
||||
|
||||
void reset_input_bindings();
|
||||
void reset_cont_input_bindings();
|
||||
void reset_kb_input_bindings();
|
||||
|
||||
std::filesystem::path get_app_folder_path();
|
||||
|
||||
bool get_debug_mode_enabled();
|
||||
void set_debug_mode_enabled(bool enabled);
|
||||
|
||||
enum class AutosaveMode {
|
||||
On,
|
||||
Off,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
enum class AnalogCamMode {
|
||||
On,
|
||||
Off,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::AutosaveMode, {
|
||||
{recomp::AutosaveMode::On, "On"},
|
||||
{recomp::AutosaveMode::Off, "Off"}
|
||||
});
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::AnalogCamMode, {
|
||||
{recomp::AnalogCamMode::On, "On"},
|
||||
{recomp::AnalogCamMode::Off, "Off"}
|
||||
});
|
||||
|
||||
AutosaveMode get_autosave_mode();
|
||||
void set_autosave_mode(AutosaveMode mode);
|
||||
|
||||
AnalogCamMode get_analog_cam_mode();
|
||||
void set_analog_cam_mode(AnalogCamMode mode);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef __RECOMP_GAME__
|
||||
#define __RECOMP_GAME__
|
||||
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
#include "recomp.h"
|
||||
#include "../ultramodern/ultramodern.hpp"
|
||||
#include "rt64_layer.h"
|
||||
|
||||
namespace recomp {
|
||||
enum class Game {
|
||||
OoT,
|
||||
MM,
|
||||
None,
|
||||
Quit
|
||||
};
|
||||
enum class RomValidationError {
|
||||
Good,
|
||||
FailedToOpen,
|
||||
NotARom,
|
||||
IncorrectRom,
|
||||
NotYet,
|
||||
IncorrectVersion,
|
||||
OtherError
|
||||
};
|
||||
void check_all_stored_roms();
|
||||
bool load_stored_rom(Game game);
|
||||
RomValidationError select_rom(const std::filesystem::path& rom_path, Game game);
|
||||
bool is_rom_valid(Game game);
|
||||
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);
|
||||
void start(ultramodern::WindowHandle window_handle, const ultramodern::audio_callbacks_t& audio_callbacks, const ultramodern::input_callbacks_t& input_callbacks, const ultramodern::gfx_callbacks_t& gfx_callbacks);
|
||||
void start_game(Game game);
|
||||
void message_box(const char* message);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef __RECOMP_HELPERS__
|
||||
#define __RECOMP_HELPERS__
|
||||
|
||||
#include "recomp.h"
|
||||
#include "../ultramodern/ultra64.h"
|
||||
|
||||
template<int index, typename T>
|
||||
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>) {
|
||||
if constexpr (index < 2) {
|
||||
static_assert(index != 1, "Floats in arg 1 not supported");
|
||||
return ctx->f12.fl;
|
||||
}
|
||||
else {
|
||||
// static_assert in else workaround
|
||||
[] <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");
|
||||
return TO_PTR(std::remove_pointer_t<T>, raw_arg);
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>) {
|
||||
static_assert(sizeof(T) <= 4, "64-bit args not supported");
|
||||
return static_cast<T>(raw_arg);
|
||||
}
|
||||
else {
|
||||
// static_assert in else workaround
|
||||
[] <bool flag = false>() {
|
||||
static_assert(flag, "Unsupported type");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void _return(recomp_context* ctx, T val) {
|
||||
static_assert(sizeof(T) <= 4 && "Only 32-bit value returns supported currently");
|
||||
if (std::is_same_v<T, float>) {
|
||||
ctx->f0.fl = val;
|
||||
}
|
||||
else if (std::is_integral_v<T> && sizeof(T) <= 4) {
|
||||
ctx->r2 = int32_t(val);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+1
-41
@@ -14,6 +14,7 @@
|
||||
namespace recomp {
|
||||
// x-macros to build input enums and arrays.
|
||||
// First parameter is the enum name, second parameter is the bit field for the input (or 0 if there is no associated one), third is the readable name.
|
||||
// TODO refactor this to allow projects to rename these, or get rid of the readable name and leave that up to individual projects to map.
|
||||
#define DEFINE_N64_BUTTON_INPUTS() \
|
||||
DEFINE_INPUT(A, 0x8000, "Action") \
|
||||
DEFINE_INPUT(B, 0x4000, "Attack/Cancel") \
|
||||
@@ -168,20 +169,6 @@ namespace recomp {
|
||||
void apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out);
|
||||
void set_right_analog_suppressed(bool suppressed);
|
||||
|
||||
enum class TargetingMode {
|
||||
Switch,
|
||||
Hold,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::TargetingMode, {
|
||||
{recomp::TargetingMode::Switch, "Switch"},
|
||||
{recomp::TargetingMode::Hold, "Hold"}
|
||||
});
|
||||
|
||||
TargetingMode get_targeting_mode();
|
||||
void set_targeting_mode(TargetingMode mode);
|
||||
|
||||
enum class BackgroundInputMode {
|
||||
On,
|
||||
Off,
|
||||
@@ -196,35 +183,8 @@ namespace recomp {
|
||||
BackgroundInputMode get_background_input_mode();
|
||||
void set_background_input_mode(BackgroundInputMode mode);
|
||||
|
||||
enum class CameraInvertMode {
|
||||
InvertNone,
|
||||
InvertX,
|
||||
InvertY,
|
||||
InvertBoth,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::CameraInvertMode, {
|
||||
{recomp::CameraInvertMode::InvertNone, "InvertNone"},
|
||||
{recomp::CameraInvertMode::InvertX, "InvertX"},
|
||||
{recomp::CameraInvertMode::InvertY, "InvertY"},
|
||||
{recomp::CameraInvertMode::InvertBoth, "InvertBoth"}
|
||||
});
|
||||
|
||||
CameraInvertMode get_camera_invert_mode();
|
||||
void set_camera_invert_mode(CameraInvertMode mode);
|
||||
|
||||
CameraInvertMode get_analog_camera_invert_mode();
|
||||
void set_analog_camera_invert_mode(CameraInvertMode mode);
|
||||
|
||||
bool game_input_disabled();
|
||||
bool all_input_disabled();
|
||||
|
||||
// TODO move these
|
||||
void quicksave_save();
|
||||
void quicksave_load();
|
||||
|
||||
void open_quit_game_prompt();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef __RECOMP_OVERLAYS_H__
|
||||
#define __RECOMP_OVERLAYS_H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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);
|
||||
void init_overlays();
|
||||
|
||||
#endif
|
||||
+3
-1
@@ -14,7 +14,7 @@ namespace Rml {
|
||||
class Event;
|
||||
}
|
||||
|
||||
namespace recomp {
|
||||
namespace recompui {
|
||||
class UiEventListenerInstancer;
|
||||
|
||||
class MenuController {
|
||||
@@ -118,6 +118,8 @@ namespace recomp {
|
||||
bool get_cont_active(void);
|
||||
void set_cont_active(bool active);
|
||||
void activate_mouse();
|
||||
|
||||
void message_box(const char* msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#ifndef __RSP_H__
|
||||
#define __RSP_H__
|
||||
|
||||
#include "rsp_vu.h"
|
||||
#include "recomp.h"
|
||||
#include <cstdio>
|
||||
|
||||
enum class RspExitReason {
|
||||
Invalid,
|
||||
Broke,
|
||||
ImemOverrun,
|
||||
UnhandledJumpTarget,
|
||||
Unsupported
|
||||
};
|
||||
|
||||
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_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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
#define RSP_ADD32(a, b) \
|
||||
((int32_t)((a) + (b)))
|
||||
|
||||
#define RSP_SUB32(a, b) \
|
||||
((int32_t)((a) - (b)))
|
||||
|
||||
#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) {
|
||||
rd_len += 1; // Read length is inclusive
|
||||
dram_addr &= 0xFFFFF8;
|
||||
assert(dmem_addr + rd_len <= 0x1000);
|
||||
for (uint32_t i = 0; i < rd_len; i++) {
|
||||
RSP_MEM_B(i, dmem_addr) = MEM_B(0, (int64_t)(int32_t)(dram_addr + i + 0x80000000));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
for (uint32_t i = 0; i < wr_len; i++) {
|
||||
MEM_B(0, (int64_t)(int32_t)(dram_addr + i + 0x80000000)) = RSP_MEM_B(i, dmem_addr);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,203 +0,0 @@
|
||||
// This file is modified from the Ares N64 emulator core. Ares can
|
||||
// be found at https://github.com/ares-emulator/ares. The original license
|
||||
// for this portion of Ares is as follows:
|
||||
// ----------------------------------------------------------------------
|
||||
// ares
|
||||
//
|
||||
// Copyright(c) 2004 - 2021 ares team, Near et al
|
||||
//
|
||||
// Permission to use, copy, modify, and /or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright noticeand this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS.IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
// ----------------------------------------------------------------------
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#define ARCHITECTURE_SUPPORTS_SSE4_1 1
|
||||
#include <nmmintrin.h>
|
||||
using v128 = __m128i;
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define ARCHITECTURE_SUPPORTS_SSE4_1 1
|
||||
#include "sse2neon.h"
|
||||
using v128 = __m128i;
|
||||
#endif
|
||||
|
||||
namespace Accuracy {
|
||||
namespace RSP {
|
||||
#if ARCHITECTURE_SUPPORTS_SSE4_1
|
||||
constexpr bool SISD = false;
|
||||
constexpr bool SIMD = true;
|
||||
#else
|
||||
constexpr bool SISD = true;
|
||||
constexpr bool SIMD = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
using u8 = uint8_t;
|
||||
using s8 = int8_t;
|
||||
using u16 = uint16_t;
|
||||
using s16 = int16_t;
|
||||
using u32 = uint32_t;
|
||||
using s32 = int32_t;
|
||||
using u64 = uint64_t;
|
||||
using s64 = int64_t;
|
||||
using uint128_t = uint64_t[2];
|
||||
|
||||
template<u32 bits> inline auto sclamp(s64 x) -> s64 {
|
||||
enum : s64 { b = 1ull << (bits - 1), m = b - 1 };
|
||||
return (x > m) ? m : (x < -b) ? -b : x;
|
||||
}
|
||||
|
||||
template<u32 bits> inline auto sclip(s64 x) -> s64 {
|
||||
enum : u64 { b = 1ull << (bits - 1), m = b * 2 - 1 };
|
||||
return ((x & m) ^ b) - b;
|
||||
}
|
||||
|
||||
struct RSP {
|
||||
using r32 = uint32_t;
|
||||
using cr32 = const r32;
|
||||
|
||||
union r128 {
|
||||
struct { uint64_t u128[2]; };
|
||||
#if ARCHITECTURE_SUPPORTS_SSE4_1
|
||||
struct { __m128i v128; };
|
||||
|
||||
operator __m128i() const { return v128; }
|
||||
auto operator=(__m128i value) { v128 = value; }
|
||||
#endif
|
||||
|
||||
auto byte(u32 index) -> uint8_t& { return ((uint8_t*)&u128)[15 - index]; }
|
||||
auto byte(u32 index) const -> uint8_t { return ((uint8_t*)&u128)[15 - index]; }
|
||||
|
||||
auto element(u32 index) -> uint16_t& { return ((uint16_t*)&u128)[7 - index]; }
|
||||
auto element(u32 index) const -> uint16_t { return ((uint16_t*)&u128)[7 - index]; }
|
||||
|
||||
auto u8(u32 index) -> uint8_t& { return ((uint8_t*)&u128)[15 - index]; }
|
||||
auto u8(u32 index) const -> uint8_t { return ((uint8_t*)&u128)[15 - index]; }
|
||||
|
||||
auto s16(u32 index) -> int16_t& { return ((int16_t*)&u128)[7 - index]; }
|
||||
auto s16(u32 index) const -> int16_t { return ((int16_t*)&u128)[7 - index]; }
|
||||
|
||||
auto u16(u32 index) -> uint16_t& { return ((uint16_t*)&u128)[7 - index]; }
|
||||
auto u16(u32 index) const -> uint16_t { return ((uint16_t*)&u128)[7 - index]; }
|
||||
|
||||
//VCx registers
|
||||
auto get(u32 index) const -> bool { return u16(index) != 0; }
|
||||
auto set(u32 index, bool value) -> bool { return u16(index) = 0 - value, value; }
|
||||
|
||||
//vu-registers.cpp
|
||||
inline auto operator()(u32 index) const -> r128;
|
||||
};
|
||||
using cr128 = const r128;
|
||||
|
||||
struct VU {
|
||||
r128 r[32];
|
||||
r128 acch, accm, accl;
|
||||
r128 vcoh, vcol; //16-bit little endian
|
||||
r128 vcch, vccl; //16-bit little endian
|
||||
r128 vce; // 8-bit little endian
|
||||
s16 divin;
|
||||
s16 divout;
|
||||
bool divdp;
|
||||
} vpu;
|
||||
|
||||
static constexpr r128 zero{0};
|
||||
static constexpr r128 invert{(uint64_t)-1, (uint64_t)-1};
|
||||
|
||||
inline auto accumulatorGet(u32 index) const -> u64;
|
||||
inline auto accumulatorSet(u32 index, u64 value) -> void;
|
||||
inline auto accumulatorSaturate(u32 index, bool slice, u16 negative, u16 positive) const -> u16;
|
||||
|
||||
inline auto CFC2(r32& rt, u8 rd) -> void;
|
||||
inline auto CTC2(cr32& rt, u8 rd) -> void;
|
||||
template<u8 e> inline auto LBV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LDV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LFV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LHV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LLV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LPV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LQV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LRV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LSV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LTV(u8 vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LUV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto LWV(r128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto MFC2(r32& rt, cr128& vs) -> void;
|
||||
template<u8 e> inline auto MTC2(cr32& rt, r128& vs) -> void;
|
||||
template<u8 e> inline auto SBV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SDV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SFV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SHV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SLV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SPV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SQV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SRV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SSV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto STV(u8 vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SUV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto SWV(cr128& vt, cr32& rs, s8 imm) -> void;
|
||||
template<u8 e> inline auto VABS(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VADD(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VADDC(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VAND(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VCH(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VCL(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VCR(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VEQ(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VGE(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VLT(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<bool U, u8 e>
|
||||
inline auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMACF(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<0, e>(vd, vs, vt); }
|
||||
template<u8 e> inline auto VMACU(r128& vd, cr128& vs, cr128& vt) -> void { VMACF<1, e>(vd, vs, vt); }
|
||||
inline auto VMACQ(r128& vd) -> void;
|
||||
template<u8 e> inline auto VMADH(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMADL(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMADM(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMADN(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMOV(r128& vd, u8 de, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMRG(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMUDH(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMUDL(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMUDM(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMUDN(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<bool U, u8 e>
|
||||
inline auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VMULF(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<0, e>(rd, vs, vt); }
|
||||
template<u8 e> inline auto VMULU(r128& rd, cr128& vs, cr128& vt) -> void { VMULF<1, e>(rd, vs, vt); }
|
||||
template<u8 e> inline auto VMULQ(r128& rd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VNAND(r128& rd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VNE(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
inline auto VNOP() -> void;
|
||||
template<u8 e> inline auto VNOR(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VNXOR(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VOR(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<bool L, u8 e>
|
||||
inline auto VRCP(r128& vd, u8 de, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VRCP(r128& vd, u8 de, cr128& vt) -> void { VRCP<0, e>(vd, de, vt); }
|
||||
template<u8 e> inline auto VRCPL(r128& vd, u8 de, cr128& vt) -> void { VRCP<1, e>(vd, de, vt); }
|
||||
template<u8 e> inline auto VRCPH(r128& vd, u8 de, cr128& vt) -> void;
|
||||
template<bool D, u8 e>
|
||||
inline auto VRND(r128& vd, u8 vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VRNDN(r128& vd, u8 vs, cr128& vt) -> void { VRND<0, e>(vd, vs, vt); }
|
||||
template<u8 e> inline auto VRNDP(r128& vd, u8 vs, cr128& vt) -> void { VRND<1, e>(vd, vs, vt); }
|
||||
template<bool L, u8 e>
|
||||
inline auto VRSQ(r128& vd, u8 de, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VRSQ(r128& vd, u8 de, cr128& vt) -> void { VRSQ<0, e>(vd, de, vt); }
|
||||
template<u8 e> inline auto VRSQL(r128& vd, u8 de, cr128& vt) -> void { VRSQ<1, e>(vd, de, vt); }
|
||||
template<u8 e> inline auto VRSQH(r128& vd, u8 de, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VSAR(r128& vd, cr128& vs) -> void;
|
||||
template<u8 e> inline auto VSUB(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VSUBC(r128& vd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VXOR(r128& rd, cr128& vs, cr128& vt) -> void;
|
||||
template<u8 e> inline auto VZERO(r128& rd, cr128& vs, cr128& vt) -> void;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
||||
#ifndef __RT64_LAYER_H__
|
||||
#define __RT64_LAYER_H__
|
||||
|
||||
#include "../ultramodern/ultramodern.hpp"
|
||||
#include "../ultramodern/config.hpp"
|
||||
|
||||
namespace RT64 {
|
||||
struct Application;
|
||||
}
|
||||
|
||||
namespace ultramodern {
|
||||
enum class RT64SetupResult {
|
||||
Success,
|
||||
DynamicLibrariesNotFound,
|
||||
InvalidGraphicsAPI,
|
||||
GraphicsAPINotFound,
|
||||
GraphicsDeviceNotFound
|
||||
};
|
||||
|
||||
struct WindowHandle;
|
||||
struct RT64Context {
|
||||
public:
|
||||
~RT64Context();
|
||||
RT64Context(uint8_t* rdram, WindowHandle window_handle, bool developer_mode);
|
||||
bool valid() { return static_cast<bool>(app); }
|
||||
RT64SetupResult get_setup_result() { return setup_result; }
|
||||
|
||||
void update_config(const GraphicsConfig& old_config, const GraphicsConfig& new_config);
|
||||
void enable_instant_present();
|
||||
void send_dl(const OSTask* task);
|
||||
void update_screen(uint32_t vi_origin);
|
||||
void shutdown();
|
||||
void set_dummy_vi();
|
||||
uint32_t get_display_framerate();
|
||||
float get_resolution_scale();
|
||||
void load_shader_cache(std::span<const char> cache_binary);
|
||||
private:
|
||||
RT64SetupResult setup_result;
|
||||
std::unique_ptr<RT64::Application> app;
|
||||
};
|
||||
|
||||
RT64::UserConfiguration::Antialiasing RT64MaxMSAA();
|
||||
bool RT64SamplePositionsSupported();
|
||||
bool RT64HighPrecisionFBEnabled();
|
||||
}
|
||||
|
||||
void set_rt64_hooks();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#ifndef __SECTIONS_H__
|
||||
#define __SECTIONS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "recomp.h"
|
||||
|
||||
#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
typedef struct {
|
||||
recomp_func_t* func;
|
||||
uint32_t offset;
|
||||
} FuncEntry;
|
||||
|
||||
typedef struct {
|
||||
uint32_t rom_addr;
|
||||
uint32_t ram_addr;
|
||||
uint32_t size;
|
||||
FuncEntry *funcs;
|
||||
size_t num_funcs;
|
||||
size_t index;
|
||||
} SectionTableEntry;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef __ZELDA_CONFIG_H__
|
||||
#define __ZELDA_CONFIG_H__
|
||||
|
||||
#include <filesystem>
|
||||
#include <string_view>
|
||||
#include "ultramodern/config.hpp"
|
||||
|
||||
namespace zelda64 {
|
||||
constexpr std::u8string_view program_id = u8"Zelda64Recompiled";
|
||||
constexpr std::string_view program_name = "Zelda 64: Recompiled";
|
||||
|
||||
// TODO: Move loading configs to the runtime once we have a way to allow per-project customization.
|
||||
void load_config();
|
||||
void save_config();
|
||||
|
||||
void reset_input_bindings();
|
||||
void reset_cont_input_bindings();
|
||||
void reset_kb_input_bindings();
|
||||
|
||||
std::filesystem::path get_app_folder_path();
|
||||
|
||||
bool get_debug_mode_enabled();
|
||||
void set_debug_mode_enabled(bool enabled);
|
||||
|
||||
enum class AutosaveMode {
|
||||
On,
|
||||
Off,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AutosaveMode, {
|
||||
{zelda64::AutosaveMode::On, "On"},
|
||||
{zelda64::AutosaveMode::Off, "Off"}
|
||||
});
|
||||
|
||||
enum class TargetingMode {
|
||||
Switch,
|
||||
Hold,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::TargetingMode, {
|
||||
{zelda64::TargetingMode::Switch, "Switch"},
|
||||
{zelda64::TargetingMode::Hold, "Hold"}
|
||||
});
|
||||
|
||||
TargetingMode get_targeting_mode();
|
||||
void set_targeting_mode(TargetingMode mode);
|
||||
|
||||
enum class CameraInvertMode {
|
||||
InvertNone,
|
||||
InvertX,
|
||||
InvertY,
|
||||
InvertBoth,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::CameraInvertMode, {
|
||||
{zelda64::CameraInvertMode::InvertNone, "InvertNone"},
|
||||
{zelda64::CameraInvertMode::InvertX, "InvertX"},
|
||||
{zelda64::CameraInvertMode::InvertY, "InvertY"},
|
||||
{zelda64::CameraInvertMode::InvertBoth, "InvertBoth"}
|
||||
});
|
||||
|
||||
CameraInvertMode get_camera_invert_mode();
|
||||
void set_camera_invert_mode(CameraInvertMode mode);
|
||||
|
||||
CameraInvertMode get_analog_camera_invert_mode();
|
||||
void set_analog_camera_invert_mode(CameraInvertMode mode);
|
||||
|
||||
enum class AnalogCamMode {
|
||||
On,
|
||||
Off,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AnalogCamMode, {
|
||||
{zelda64::AnalogCamMode::On, "On"},
|
||||
{zelda64::AnalogCamMode::Off, "Off"}
|
||||
});
|
||||
|
||||
AutosaveMode get_autosave_mode();
|
||||
void set_autosave_mode(AutosaveMode mode);
|
||||
|
||||
AnalogCamMode get_analog_cam_mode();
|
||||
void set_analog_cam_mode(AnalogCamMode mode);
|
||||
|
||||
void open_quit_game_prompt();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef __RECOMP_DEBUG_H__
|
||||
#define __RECOMP_DEBUG_H__
|
||||
#ifndef __ZELDA_DEBUG_H__
|
||||
#define __ZELDA_DEBUG_H__
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace recomp {
|
||||
namespace zelda64 {
|
||||
struct SceneWarps {
|
||||
int index;
|
||||
std::string name;
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef __ZELDA_GAME_H__
|
||||
#define __ZELDA_GAME_H__
|
||||
|
||||
namespace zelda64 {
|
||||
void quicksave_save();
|
||||
void quicksave_load();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __RECOMP_SOUND_H__
|
||||
#define __RECOMP_SOUND_H__
|
||||
#ifndef __ZELDA_SOUND_H__
|
||||
#define __ZELDA_SOUND_H__
|
||||
|
||||
namespace recomp {
|
||||
namespace zelda64 {
|
||||
void reset_sound_settings();
|
||||
void set_main_volume(int volume);
|
||||
int get_main_volume();
|
||||
Reference in New Issue
Block a user