Restructure
This commit is contained in:
@@ -4,8 +4,8 @@ project(gadolinium)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
file(GLOB_RECURSE CORE_SOURCES n64/*.cpp)
|
||||
file(GLOB_RECURSE CORE_HEADERS n64/*.hpp)
|
||||
file(GLOB_RECURSE CORE_SOURCES backend/*.cpp)
|
||||
file(GLOB_RECURSE CORE_HEADERS backend/*.hpp)
|
||||
file(GLOB_RECURSE FRONTEND_SOURCES frontend/*.cpp)
|
||||
file(GLOB_RECURSE FRONTEND_HEADERS frontend/*.hpp)
|
||||
|
||||
@@ -30,20 +30,20 @@ add_executable(gadolinium
|
||||
${FRONTEND_HEADERS}
|
||||
main.cpp
|
||||
common.hpp
|
||||
util.hpp
|
||||
n64/Scheduler.cpp
|
||||
n64/Scheduler.hpp)
|
||||
backend/Scheduler.cpp
|
||||
backend/Scheduler.hpp)
|
||||
|
||||
target_include_directories(gadolinium PRIVATE
|
||||
.
|
||||
n64
|
||||
n64/core
|
||||
n64/core/interpreter/
|
||||
n64/core/registers
|
||||
n64/core/mmio
|
||||
n64/core/rsp
|
||||
backend
|
||||
backend/core
|
||||
backend/core/interpreter/
|
||||
backend/core/registers
|
||||
backend/core/mmio
|
||||
backend/core/rsp
|
||||
frontend
|
||||
frontend/imgui
|
||||
utils
|
||||
../external
|
||||
../external/xbyak
|
||||
../external/imgui/imgui
|
||||
|
||||
42
src/Discord.hpp
Normal file
42
src/Discord.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include <discord_rpc.h>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
namespace util {
|
||||
enum State {
|
||||
Idling,
|
||||
Playing,
|
||||
Paused
|
||||
};
|
||||
|
||||
inline void UpdateRPC(State state, const std::string& game = "") {
|
||||
DiscordRichPresence presence{};
|
||||
std::string textState, textDetails;
|
||||
|
||||
switch(state) {
|
||||
case Idling:
|
||||
textDetails = "Idling";
|
||||
break;
|
||||
case Playing:
|
||||
textDetails = "In-game";
|
||||
textState = "Playing \"" + game + "\"";
|
||||
break;
|
||||
case Paused:
|
||||
textDetails = "In-game";
|
||||
textState = "Playing \"" + game + "\" (Paused)";
|
||||
break;
|
||||
}
|
||||
|
||||
presence.details = textDetails.c_str();
|
||||
presence.state = textState.c_str();
|
||||
presence.startTimestamp = time(nullptr);
|
||||
presence.largeImageText = "Gadolinium";
|
||||
presence.largeImageKey = "logo";
|
||||
Discord_UpdatePresence(&presence);
|
||||
}
|
||||
|
||||
inline void ClearRPC() {
|
||||
Discord_ClearPresence();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <ParallelRDPWrapper.hpp>
|
||||
#include <Window.hpp>
|
||||
#include <algorithm>
|
||||
#include "m64.hpp"
|
||||
#include <MupenMovie.hpp>
|
||||
#include <Scheduler.hpp>
|
||||
|
||||
namespace n64 {
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <m64.hpp>
|
||||
#include <util.hpp>
|
||||
#include <MupenMovie.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
struct TASMovieHeader {
|
||||
u8 signature[4];
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <Audio.hpp>
|
||||
#include <SDL_audio.h>
|
||||
#include <util.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
#define AUDIO_SAMPLE_RATE 44100
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include <common.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void PushSample(float, float, float, float);
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void Interpreter::Reset() {
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <n64/core/MMIO.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <core/MMIO.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
|
||||
namespace n64 {
|
||||
30
src/backend/core/MMIO.hpp
Normal file
30
src/backend/core/MMIO.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <core/mmio/VI.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/mmio/AI.hpp>
|
||||
#include <core/mmio/PI.hpp>
|
||||
#include <core/mmio/RI.hpp>
|
||||
#include <core/mmio/SI.hpp>
|
||||
#include <core/RSP.hpp>
|
||||
#include <core/RDP.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct Mem;
|
||||
struct Registers;
|
||||
|
||||
struct MMIO {
|
||||
MMIO();
|
||||
void Reset();
|
||||
VI vi;
|
||||
MI mi;
|
||||
AI ai;
|
||||
PI pi;
|
||||
RI ri;
|
||||
SI si;
|
||||
RSP rsp;
|
||||
RDP rdp;
|
||||
|
||||
u32 Read(u32);
|
||||
void Write(Mem&, Registers&, u32, u32);
|
||||
};
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
#include <fstream>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <core/registers/Cop0.hpp>
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
#include <File.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Mem::Mem() {
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <n64/memory_regions.hpp>
|
||||
#include <n64/core/MMIO.hpp>
|
||||
#include <MemoryRegions.hpp>
|
||||
#include <core/MMIO.hpp>
|
||||
#include <vector>
|
||||
#include <util.hpp>
|
||||
#include <MemoryHelpers.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct Registers;
|
||||
37
src/backend/core/RCP.hpp
Normal file
37
src/backend/core/RCP.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
|
||||
static constexpr u16 rcpRom[] = {
|
||||
0xffff, 0xff00, 0xfe01, 0xfd04, 0xfc07, 0xfb0c, 0xfa11, 0xf918, 0xf81f, 0xf727, 0xf631, 0xf53b, 0xf446, 0xf352, 0xf25f, 0xf16d,
|
||||
0xf07c, 0xef8b, 0xee9c, 0xedae, 0xecc0, 0xebd3, 0xeae8, 0xe9fd, 0xe913, 0xe829, 0xe741, 0xe65a, 0xe573, 0xe48d, 0xe3a9, 0xe2c5,
|
||||
0xe1e1, 0xe0ff, 0xe01e, 0xdf3d, 0xde5d, 0xdd7e, 0xdca0, 0xdbc2, 0xdae6, 0xda0a, 0xd92f, 0xd854, 0xd77b, 0xd6a2, 0xd5ca, 0xd4f3,
|
||||
0xd41d, 0xd347, 0xd272, 0xd19e, 0xd0cb, 0xcff8, 0xcf26, 0xce55, 0xcd85, 0xccb5, 0xcbe6, 0xcb18, 0xca4b, 0xc97e, 0xc8b2, 0xc7e7,
|
||||
0xc71c, 0xc652, 0xc589, 0xc4c0, 0xc3f8, 0xc331, 0xc26b, 0xc1a5, 0xc0e0, 0xc01c, 0xbf58, 0xbe95, 0xbdd2, 0xbd10, 0xbc4f, 0xbb8f,
|
||||
0xbacf, 0xba10, 0xb951, 0xb894, 0xb7d6, 0xb71a, 0xb65e, 0xb5a2, 0xb4e8, 0xb42e, 0xb374, 0xb2bb, 0xb203, 0xb14b, 0xb094, 0xafde,
|
||||
0xaf28, 0xae73, 0xadbe, 0xad0a, 0xac57, 0xaba4, 0xaaf1, 0xaa40, 0xa98e, 0xa8de, 0xa82e, 0xa77e, 0xa6d0, 0xa621, 0xa574, 0xa4c6,
|
||||
0xa41a, 0xa36e, 0xa2c2, 0xa217, 0xa16d, 0xa0c3, 0xa01a, 0x9f71, 0x9ec8, 0x9e21, 0x9d79, 0x9cd3, 0x9c2d, 0x9b87, 0x9ae2, 0x9a3d,
|
||||
0x9999, 0x98f6, 0x9852, 0x97b0, 0x970e, 0x966c, 0x95cb, 0x952b, 0x948b, 0x93eb, 0x934c, 0x92ad, 0x920f, 0x9172, 0x90d4, 0x9038,
|
||||
0x8f9c, 0x8f00, 0x8e65, 0x8dca, 0x8d30, 0x8c96, 0x8bfc, 0x8b64, 0x8acb, 0x8a33, 0x899c, 0x8904, 0x886e, 0x87d8, 0x8742, 0x86ad,
|
||||
0x8618, 0x8583, 0x84f0, 0x845c, 0x83c9, 0x8336, 0x82a4, 0x8212, 0x8181, 0x80f0, 0x8060, 0x7fd0, 0x7f40, 0x7eb1, 0x7e22, 0x7d93,
|
||||
0x7d05, 0x7c78, 0x7beb, 0x7b5e, 0x7ad2, 0x7a46, 0x79ba, 0x792f, 0x78a4, 0x781a, 0x7790, 0x7706, 0x767d, 0x75f5, 0x756c, 0x74e4,
|
||||
0x745d, 0x73d5, 0x734f, 0x72c8, 0x7242, 0x71bc, 0x7137, 0x70b2, 0x702e, 0x6fa9, 0x6f26, 0x6ea2, 0x6e1f, 0x6d9c, 0x6d1a, 0x6c98,
|
||||
0x6c16, 0x6b95, 0x6b14, 0x6a94, 0x6a13, 0x6993, 0x6914, 0x6895, 0x6816, 0x6798, 0x6719, 0x669c, 0x661e, 0x65a1, 0x6524, 0x64a8,
|
||||
0x642c, 0x63b0, 0x6335, 0x62ba, 0x623f, 0x61c5, 0x614b, 0x60d1, 0x6058, 0x5fdf, 0x5f66, 0x5eed, 0x5e75, 0x5dfd, 0x5d86, 0x5d0f,
|
||||
0x5c98, 0x5c22, 0x5bab, 0x5b35, 0x5ac0, 0x5a4b, 0x59d6, 0x5961, 0x58ed, 0x5879, 0x5805, 0x5791, 0x571e, 0x56ac, 0x5639, 0x55c7,
|
||||
0x5555, 0x54e3, 0x5472, 0x5401, 0x5390, 0x5320, 0x52af, 0x5240, 0x51d0, 0x5161, 0x50f2, 0x5083, 0x5015, 0x4fa6, 0x4f38, 0x4ecb,
|
||||
0x4e5e, 0x4df1, 0x4d84, 0x4d17, 0x4cab, 0x4c3f, 0x4bd3, 0x4b68, 0x4afd, 0x4a92, 0x4a27, 0x49bd, 0x4953, 0x48e9, 0x4880, 0x4817,
|
||||
0x47ae, 0x4745, 0x46dc, 0x4674, 0x460c, 0x45a5, 0x453d, 0x44d6, 0x446f, 0x4408, 0x43a2, 0x433c, 0x42d6, 0x4270, 0x420b, 0x41a6,
|
||||
0x4141, 0x40dc, 0x4078, 0x4014, 0x3fb0, 0x3f4c, 0x3ee8, 0x3e85, 0x3e22, 0x3dc0, 0x3d5d, 0x3cfb, 0x3c99, 0x3c37, 0x3bd6, 0x3b74,
|
||||
0x3b13, 0x3ab2, 0x3a52, 0x39f1, 0x3991, 0x3931, 0x38d2, 0x3872, 0x3813, 0x37b4, 0x3755, 0x36f7, 0x3698, 0x363a, 0x35dc, 0x357f,
|
||||
0x3521, 0x34c4, 0x3467, 0x340a, 0x33ae, 0x3351, 0x32f5, 0x3299, 0x323e, 0x31e2, 0x3187, 0x312c, 0x30d1, 0x3076, 0x301c, 0x2fc2,
|
||||
0x2f68, 0x2f0e, 0x2eb4, 0x2e5b, 0x2e02, 0x2da9, 0x2d50, 0x2cf8, 0x2c9f, 0x2c47, 0x2bef, 0x2b97, 0x2b40, 0x2ae8, 0x2a91, 0x2a3a,
|
||||
0x29e4, 0x298d, 0x2937, 0x28e0, 0x288b, 0x2835, 0x27df, 0x278a, 0x2735, 0x26e0, 0x268b, 0x2636, 0x25e2, 0x258d, 0x2539, 0x24e5,
|
||||
0x2492, 0x243e, 0x23eb, 0x2398, 0x2345, 0x22f2, 0x22a0, 0x224d, 0x21fb, 0x21a9, 0x2157, 0x2105, 0x20b4, 0x2063, 0x2012, 0x1fc1,
|
||||
0x1f70, 0x1f1f, 0x1ecf, 0x1e7f, 0x1e2e, 0x1ddf, 0x1d8f, 0x1d3f, 0x1cf0, 0x1ca1, 0x1c52, 0x1c03, 0x1bb4, 0x1b66, 0x1b17, 0x1ac9,
|
||||
0x1a7b, 0x1a2d, 0x19e0, 0x1992, 0x1945, 0x18f8, 0x18ab, 0x185e, 0x1811, 0x17c4, 0x1778, 0x172c, 0x16e0, 0x1694, 0x1648, 0x15fd,
|
||||
0x15b1, 0x1566, 0x151b, 0x14d0, 0x1485, 0x143b, 0x13f0, 0x13a6, 0x135c, 0x1312, 0x12c8, 0x127f, 0x1235, 0x11ec, 0x11a3, 0x1159,
|
||||
0x1111, 0x10c8, 0x107f, 0x1037, 0x0fef, 0x0fa6, 0x0f5e, 0x0f17, 0x0ecf, 0x0e87, 0x0e40, 0x0df9, 0x0db2, 0x0d6b, 0x0d24, 0x0cdd,
|
||||
0x0c97, 0x0c50, 0x0c0a, 0x0bc4, 0x0b7e, 0x0b38, 0x0af2, 0x0aad, 0x0a68, 0x0a22, 0x09dd, 0x0998, 0x0953, 0x090f, 0x08ca, 0x0886,
|
||||
0x0842, 0x07fd, 0x07b9, 0x0776, 0x0732, 0x06ee, 0x06ab, 0x0668, 0x0624, 0x05e1, 0x059e, 0x055c, 0x0519, 0x04d6, 0x0494, 0x0452,
|
||||
0x0410, 0x03ce, 0x038c, 0x034a, 0x0309, 0x02c7, 0x0286, 0x0245, 0x0204, 0x01c3, 0x0182, 0x0141, 0x0101, 0x00c0, 0x0080, 0x0040
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <n64/core/RDP.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/RSP.hpp>
|
||||
#include <core/RDP.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/RSP.hpp>
|
||||
#include <parallel-rdp/ParallelRDPWrapper.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
|
||||
namespace n64 {
|
||||
RDP::RDP() {
|
||||
@@ -80,4 +80,4 @@ struct RDP {
|
||||
RunCommand(mi, regs, rsp);
|
||||
}
|
||||
};
|
||||
} // n64
|
||||
} // backend
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <n64/core/RSP.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <n64/core/registers/Registers.hpp>
|
||||
#include <core/RSP.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
|
||||
namespace n64 {
|
||||
RSP::RSP() {
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <n64/core/RDP.hpp>
|
||||
#include <n64/memory_regions.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/RDP.hpp>
|
||||
#include <MemoryRegions.hpp>
|
||||
#include <Interrupt.hpp>
|
||||
|
||||
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
||||
37
src/backend/core/RSQ.hpp
Normal file
37
src/backend/core/RSQ.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
|
||||
static constexpr u16 rsqRom[] = {
|
||||
0xffff, 0xff00, 0xfe02, 0xfd06, 0xfc0b, 0xfb12, 0xfa1a, 0xf923, 0xf82e, 0xf73b, 0xf648, 0xf557, 0xf467, 0xf379, 0xf28c, 0xf1a0,
|
||||
0xf0b6, 0xefcd, 0xeee5, 0xedff, 0xed19, 0xec35, 0xeb52, 0xea71, 0xe990, 0xe8b1, 0xe7d3, 0xe6f6, 0xe61b, 0xe540, 0xe467, 0xe38e,
|
||||
0xe2b7, 0xe1e1, 0xe10d, 0xe039, 0xdf66, 0xde94, 0xddc4, 0xdcf4, 0xdc26, 0xdb59, 0xda8c, 0xd9c1, 0xd8f7, 0xd82d, 0xd765, 0xd69e,
|
||||
0xd5d7, 0xd512, 0xd44e, 0xd38a, 0xd2c8, 0xd206, 0xd146, 0xd086, 0xcfc7, 0xcf0a, 0xce4d, 0xcd91, 0xccd6, 0xcc1b, 0xcb62, 0xcaa9,
|
||||
0xc9f2, 0xc93b, 0xc885, 0xc7d0, 0xc71c, 0xc669, 0xc5b6, 0xc504, 0xc453, 0xc3a3, 0xc2f4, 0xc245, 0xc198, 0xc0eb, 0xc03f, 0xbf93,
|
||||
0xbee9, 0xbe3f, 0xbd96, 0xbced, 0xbc46, 0xbb9f, 0xbaf8, 0xba53, 0xb9ae, 0xb90a, 0xb867, 0xb7c5, 0xb723, 0xb681, 0xb5e1, 0xb541,
|
||||
0xb4a2, 0xb404, 0xb366, 0xb2c9, 0xb22c, 0xb191, 0xb0f5, 0xb05b, 0xafc1, 0xaf28, 0xae8f, 0xadf7, 0xad60, 0xacc9, 0xac33, 0xab9e,
|
||||
0xab09, 0xaa75, 0xa9e1, 0xa94e, 0xa8bc, 0xa82a, 0xa799, 0xa708, 0xa678, 0xa5e8, 0xa559, 0xa4cb, 0xa43d, 0xa3b0, 0xa323, 0xa297,
|
||||
0xa20b, 0xa180, 0xa0f6, 0xa06c, 0x9fe2, 0x9f59, 0x9ed1, 0x9e49, 0x9dc2, 0x9d3b, 0x9cb4, 0x9c2f, 0x9ba9, 0x9b25, 0x9aa0, 0x9a1c,
|
||||
0x9999, 0x9916, 0x9894, 0x9812, 0x9791, 0x9710, 0x968f, 0x960f, 0x9590, 0x9511, 0x9492, 0x9414, 0x9397, 0x931a, 0x929d, 0x9221,
|
||||
0x91a5, 0x9129, 0x90af, 0x9034, 0x8fba, 0x8f40, 0x8ec7, 0x8e4f, 0x8dd6, 0x8d5e, 0x8ce7, 0x8c70, 0x8bf9, 0x8b83, 0x8b0d, 0x8a98,
|
||||
0x8a23, 0x89ae, 0x893a, 0x88c6, 0x8853, 0x87e0, 0x876d, 0x86fb, 0x8689, 0x8618, 0x85a7, 0x8536, 0x84c6, 0x8456, 0x83e7, 0x8377,
|
||||
0x8309, 0x829a, 0x822c, 0x81bf, 0x8151, 0x80e4, 0x8078, 0x800c, 0x7fa0, 0x7f34, 0x7ec9, 0x7e5e, 0x7df4, 0x7d8a, 0x7d20, 0x7cb6,
|
||||
0x7c4d, 0x7be5, 0x7b7c, 0x7b14, 0x7aac, 0x7a45, 0x79de, 0x7977, 0x7911, 0x78ab, 0x7845, 0x77df, 0x777a, 0x7715, 0x76b1, 0x764d,
|
||||
0x75e9, 0x7585, 0x7522, 0x74bf, 0x745d, 0x73fa, 0x7398, 0x7337, 0x72d5, 0x7274, 0x7213, 0x71b3, 0x7152, 0x70f2, 0x7093, 0x7033,
|
||||
0x6fd4, 0x6f76, 0x6f17, 0x6eb9, 0x6e5b, 0x6dfd, 0x6da0, 0x6d43, 0x6ce6, 0x6c8a, 0x6c2d, 0x6bd1, 0x6b76, 0x6b1a, 0x6abf, 0x6a64,
|
||||
0x6a09, 0x6955, 0x68a1, 0x67ef, 0x673e, 0x668d, 0x65de, 0x6530, 0x6482, 0x63d6, 0x632b, 0x6280, 0x61d7, 0x612e, 0x6087, 0x5fe0,
|
||||
0x5f3a, 0x5e95, 0x5df1, 0x5d4e, 0x5cac, 0x5c0b, 0x5b6b, 0x5acb, 0x5a2c, 0x598f, 0x58f2, 0x5855, 0x57ba, 0x5720, 0x5686, 0x55ed,
|
||||
0x5555, 0x54be, 0x5427, 0x5391, 0x52fc, 0x5268, 0x51d5, 0x5142, 0x50b0, 0x501f, 0x4f8e, 0x4efe, 0x4e6f, 0x4de1, 0x4d53, 0x4cc6,
|
||||
0x4c3a, 0x4baf, 0x4b24, 0x4a9a, 0x4a10, 0x4987, 0x48ff, 0x4878, 0x47f1, 0x476b, 0x46e5, 0x4660, 0x45dc, 0x4558, 0x44d5, 0x4453,
|
||||
0x43d1, 0x434f, 0x42cf, 0x424f, 0x41cf, 0x4151, 0x40d2, 0x4055, 0x3fd8, 0x3f5b, 0x3edf, 0x3e64, 0x3de9, 0x3d6e, 0x3cf5, 0x3c7c,
|
||||
0x3c03, 0x3b8b, 0x3b13, 0x3a9c, 0x3a26, 0x39b0, 0x393a, 0x38c5, 0x3851, 0x37dd, 0x3769, 0x36f6, 0x3684, 0x3612, 0x35a0, 0x352f,
|
||||
0x34bf, 0x344f, 0x33df, 0x3370, 0x3302, 0x3293, 0x3226, 0x31b9, 0x314c, 0x30df, 0x3074, 0x3008, 0x2f9d, 0x2f33, 0x2ec8, 0x2e5f,
|
||||
0x2df6, 0x2d8d, 0x2d24, 0x2cbc, 0x2c55, 0x2bee, 0x2b87, 0x2b21, 0x2abb, 0x2a55, 0x29f0, 0x298b, 0x2927, 0x28c3, 0x2860, 0x27fd,
|
||||
0x279a, 0x2738, 0x26d6, 0x2674, 0x2613, 0x25b2, 0x2552, 0x24f2, 0x2492, 0x2432, 0x23d3, 0x2375, 0x2317, 0x22b9, 0x225b, 0x21fe,
|
||||
0x21a1, 0x2145, 0x20e8, 0x208d, 0x2031, 0x1fd6, 0x1f7b, 0x1f21, 0x1ec7, 0x1e6d, 0x1e13, 0x1dba, 0x1d61, 0x1d09, 0x1cb1, 0x1c59,
|
||||
0x1c01, 0x1baa, 0x1b53, 0x1afc, 0x1aa6, 0x1a50, 0x19fa, 0x19a5, 0x1950, 0x18fb, 0x18a7, 0x1853, 0x17ff, 0x17ab, 0x1758, 0x1705,
|
||||
0x16b2, 0x1660, 0x160d, 0x15bc, 0x156a, 0x1519, 0x14c8, 0x1477, 0x1426, 0x13d6, 0x1386, 0x1337, 0x12e7, 0x1298, 0x1249, 0x11fb,
|
||||
0x11ac, 0x115e, 0x1111, 0x10c3, 0x1076, 0x1029, 0x0fdc, 0x0f8f, 0x0f43, 0x0ef7, 0x0eab, 0x0e60, 0x0e15, 0x0dca, 0x0d7f, 0x0d34,
|
||||
0x0cea, 0x0ca0, 0x0c56, 0x0c0c, 0x0bc3, 0x0b7a, 0x0b31, 0x0ae8, 0x0aa0, 0x0a58, 0x0a10, 0x09c8, 0x0981, 0x0939, 0x08f2, 0x08ab,
|
||||
0x0865, 0x081e, 0x07d8, 0x0792, 0x074d, 0x0707, 0x06c2, 0x067d, 0x0638, 0x05f3, 0x05af, 0x056a, 0x0526, 0x04e2, 0x049f, 0x045b,
|
||||
0x0418, 0x03d5, 0x0392, 0x0350, 0x030d, 0x02cb, 0x0289, 0x0247, 0x0206, 0x01c4, 0x0183, 0x0142, 0x0101, 0x00c0, 0x0080, 0x0040
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <core/registers/Cop0.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <util.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void Cop0::mtc0(Registers& regs, u32 instr) {
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <core/registers/Cop1.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <cmath>
|
||||
#include <cfenv>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void Interpreter::special(Mem& mem, u32 instr) {
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
|
||||
#define se_imm(x) ((s16)((x) & 0xFFFF))
|
||||
#define check_address_error(mask, addr) (((!regs.cop0.is_64bit_addressing) && (s32)(addr) != (addr)) || (((addr) & (mask)) != 0))
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <n64/core/mmio/AI.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <core/mmio/AI.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <n64/core/Audio.hpp>
|
||||
#include <core/Audio.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void AI::Reset() {
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct Mem;
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
|
||||
namespace n64 {
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
|
||||
namespace n64 {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
|
||||
#define MI_VERSION_REG 0x02020102
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <n64/core/mmio/PI.hpp>
|
||||
#include <util.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <core/mmio/PI.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
|
||||
namespace n64 {
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
|
||||
namespace n64 {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <n64/core/mmio/PIF.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include <core/mmio/PIF.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <util.hpp>
|
||||
#include "m64.hpp"
|
||||
#include <log.hpp>
|
||||
#include <MupenMovie.hpp>
|
||||
|
||||
namespace n64 {
|
||||
static int channel = 0;
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <n64/core/mmio/RI.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/mmio/RI.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
RI::RI() {
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <n64/core/mmio/SI.hpp>
|
||||
#include <n64/core/Mem.hpp>
|
||||
#include "Scheduler.hpp"
|
||||
#include <core/mmio/SI.hpp>
|
||||
#include <core/Mem.hpp>
|
||||
#include <Scheduler.hpp>
|
||||
|
||||
namespace n64 {
|
||||
SI::SI() {
|
||||
@@ -45,7 +45,7 @@ void DMA(Mem& mem, Registers& regs) {
|
||||
for(int i = 0; i < 64; i++) {
|
||||
mem.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)];
|
||||
}
|
||||
util::logdebug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||
util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr);
|
||||
ProcessPIFCommands(mem.pifRam, si.controller, mem);
|
||||
}
|
||||
InterruptRaise(mem.mmio.mi, regs, Interrupt::SI);
|
||||
@@ -67,7 +67,7 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) {
|
||||
status.dmaBusy = true;
|
||||
toDram = false;
|
||||
scheduler.enqueueRelative({SI_DMA_DELAY, DMA});
|
||||
util::logdebug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF);
|
||||
util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF);
|
||||
} break;
|
||||
case 0x04800018:
|
||||
InterruptLower(mem.mmio.mi, regs, Interrupt::SI);
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <n64/core/mmio/PIF.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/mmio/PIF.hpp>
|
||||
|
||||
namespace n64 {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <n64/core/mmio/VI.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/mmio/VI.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <n64/core/mmio/Interrupt.hpp>
|
||||
#include <core/mmio/MI.hpp>
|
||||
#include <core/mmio/Interrupt.hpp>
|
||||
|
||||
namespace n64 {
|
||||
VI::VI () {
|
||||
@@ -103,4 +103,4 @@ struct VI {
|
||||
int numFields;
|
||||
int cyclesPerHalfline;
|
||||
};
|
||||
} // n64
|
||||
} // backend
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <core/registers/Cop0.hpp>
|
||||
#include <util.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Cop0::Cop0() {
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <core/registers/Cop1.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <n64/core/Interpreter.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/Interpreter.hpp>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace n64 {
|
||||
Cop1::Cop1() {
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <core/registers/Cop0.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace n64 {
|
||||
union FCR31 {
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <n64/core/RSP.hpp>
|
||||
#include <util.hpp>
|
||||
#include <core/RSP.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <Interrupt.hpp>
|
||||
#include <Mem.hpp>
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <RSP.hpp>
|
||||
#include <util.hpp>
|
||||
#include <log.hpp>
|
||||
#include <core/registers/Registers.hpp>
|
||||
#include <Mem.hpp>
|
||||
#include <rcp_rsq.hpp>
|
||||
#include <RCP.hpp>
|
||||
#include <RSQ.hpp>
|
||||
|
||||
namespace n64 {
|
||||
inline bool AcquireSemaphore(RSP& rsp) {
|
||||
@@ -1093,7 +1094,7 @@ inline u32 rcp(s32 sinput) {
|
||||
u64 dinput = (u64)input;
|
||||
u32 index = ((dinput << shift) & 0x7FC00000) >> 22;
|
||||
|
||||
s32 result = rcp_rom[index];
|
||||
s32 result = rcpRom[index];
|
||||
result = (0x10000 | result) << 14;
|
||||
result = (result >> (31 - shift)) ^ mask;
|
||||
return result;
|
||||
@@ -1115,7 +1116,7 @@ inline u32 rsq(u32 input) {
|
||||
int shift = __builtin_clz(input) + 1;
|
||||
|
||||
int index = (((input << shift) >> 24) | ((shift & 1) << 8));
|
||||
u32 rom = (((u32)rsq_rom[index]) << 14);
|
||||
u32 rom = (((u32)rsqRom[index]) << 14);
|
||||
int r_shift = ((32 - shift) >> 1);
|
||||
u32 result = (0x40000000 | rom) >> r_shift;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <bitset>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/color.h>
|
||||
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
@@ -15,9 +13,6 @@ using s64 = int64_t;
|
||||
using u128 = __uint128_t;
|
||||
using s128 = __int128_t;
|
||||
|
||||
#define KiB * 1024
|
||||
#define MiB ((KiB) * 1024)
|
||||
#define GiB ((MiB) * 1024)
|
||||
#define N64_CPU_FREQ 93750000
|
||||
#define N64_CYCLES_PER_FRAME ((N64_CPU_FREQ) / 60)
|
||||
#define HALF_ADDRESS(addr) ((addr) ^ 2)
|
||||
|
||||
@@ -38,7 +38,7 @@ void App::Run() {
|
||||
switch(event.key.keysym.sym) {
|
||||
case SDLK_o: {
|
||||
nfdchar_t* outpath;
|
||||
const nfdu8filteritem_t filter {"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"};
|
||||
const nfdu8filteritem_t filter {"Nintendo 64 roms", "backend,z64,v64,N64,Z64,V64"};
|
||||
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
|
||||
if(result == NFD_OKAY) {
|
||||
LoadROM(outpath);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <imgui/Window.hpp>
|
||||
#include <util.hpp>
|
||||
#include <Discord.hpp>
|
||||
|
||||
struct App {
|
||||
App();
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <Mem.hpp>
|
||||
#include <execution>
|
||||
#include <MemoryHelpers.hpp>
|
||||
#include <File.hpp>
|
||||
|
||||
using namespace nlohmann;
|
||||
namespace fs = std::filesystem;
|
||||
@@ -18,7 +18,7 @@ GameList::GameList(const std::string& path) {
|
||||
|
||||
for(const auto& p : fs::directory_iterator{path}) {
|
||||
const auto filename = p.path().string();
|
||||
if(p.path().extension() == ".n64" || p.path().extension() == ".z64" || p.path().extension() == ".v64" ||
|
||||
if(p.path().extension() == ".backend" || p.path().extension() == ".z64" || p.path().extension() == ".v64" ||
|
||||
p.path().extension() == ".N64" || p.path().extension() == ".Z64" || p.path().extension() == ".V64") {
|
||||
std::ifstream file(filename, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
#include <Settings.hpp>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <utilities.hpp>
|
||||
#include <nfd.h>
|
||||
#include <Widgets.hpp>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
#define checkjsonentry(name, type, param1, param2, defaultVal) \
|
||||
do { \
|
||||
auto name##Entry = settings[param1][param2]; \
|
||||
if(!name##Entry.empty()) { \
|
||||
auto value = name##Entry.get<type>(); \
|
||||
name = value; \
|
||||
} else { \
|
||||
settingsFile.clear(); \
|
||||
settings[param1][param2] = defaultVal; \
|
||||
settingsFile << settings; \
|
||||
name = defaultVal; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
Settings::Settings(n64::Core& core) {
|
||||
auto modes = std::fstream::in | std::fstream::out;
|
||||
auto fileExists = fs::exists("resources/settings.json");
|
||||
if(!fileExists) {
|
||||
modes |= std::fstream::trunc;
|
||||
}
|
||||
std::fstream settingsFile{"resources/settings.json", modes};
|
||||
std::fstream settingsFile;
|
||||
if(fileExists) {
|
||||
settingsFile = std::fstream("resources/settings.json", std::fstream::in | std::fstream::out);
|
||||
settings = json::parse(settingsFile);
|
||||
auto entryCpuType = settings["cpu"]["type"];
|
||||
if(!entryCpuType.empty()) {
|
||||
@@ -37,6 +49,7 @@ Settings::Settings(n64::Core& core) {
|
||||
checkjsonentry(lockChannels, bool, "audio", "lockChannels", true);
|
||||
checkjsonentry(gamesDir, std::string, "general", "gamesDir", "");
|
||||
} else {
|
||||
settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::in | std::fstream::out);
|
||||
settings["general"]["gamesDir"] = "";
|
||||
settings["cpu"]["type"] = "interpreter";
|
||||
settings["audio"]["volumeR"] = 0.5;
|
||||
@@ -51,17 +64,23 @@ Settings::Settings(n64::Core& core) {
|
||||
|
||||
settingsFile << settings;
|
||||
}
|
||||
|
||||
settingsFile.close();
|
||||
}
|
||||
|
||||
Settings::~Settings() {
|
||||
auto modes = std::fstream::out;
|
||||
auto fileExists = fs::exists("resources/settings.json");
|
||||
std::fstream settingsFile;
|
||||
if(fileExists) {
|
||||
modes = modes | std::fstream::trunc;
|
||||
|
||||
std::fstream settingsFile{"resources/settings.json", modes};
|
||||
settingsFile = std::fstream("resources/settings.json", std::fstream::trunc | std::fstream::out);
|
||||
|
||||
settings["general"]["gamesDir"] = gamesDir;
|
||||
settings["cpu"]["type"] = cpuType;
|
||||
settings["audio"]["volumeR"] = volumeR;
|
||||
settings["audio"]["volumeL"] = volumeL;
|
||||
settings["audio"]["lockChannels"] = lockChannels;
|
||||
settingsFile << settings;
|
||||
} else {
|
||||
settingsFile = std::fstream("resources/settings.json", std::fstream::out);
|
||||
|
||||
settings["general"]["gamesDir"] = gamesDir;
|
||||
settings["cpu"]["type"] = cpuType;
|
||||
@@ -69,8 +88,9 @@ Settings::~Settings() {
|
||||
settings["audio"]["volumeL"] = volumeL;
|
||||
settings["audio"]["lockChannels"] = lockChannels;
|
||||
settingsFile << settings;
|
||||
settingsFile.close();
|
||||
}
|
||||
|
||||
settingsFile.close();
|
||||
}
|
||||
|
||||
void Settings::RenderWidget(bool& show) {
|
||||
|
||||
21
src/frontend/imgui/Widgets.hpp
Normal file
21
src/frontend/imgui/Widgets.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <imgui.h>
|
||||
|
||||
inline bool CreateComboList(const char* label, int* index, const char** items, int items_count) {
|
||||
if (ImGui::BeginCombo(label, items[*index])) {
|
||||
for (int n = 0; n < items_count; n++) {
|
||||
const bool is_selected = (*index == n);
|
||||
if (ImGui::Selectable(items[n], is_selected)) {
|
||||
*index = n;
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -5,9 +5,11 @@
|
||||
#include <Audio.hpp>
|
||||
#include <SDL.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <Discord.hpp>
|
||||
|
||||
VkInstance instance{};
|
||||
using fs = std::filesystem;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
Window::Window(n64::Core& core) : settings(core), gameList(settings.GetGamesDir()) {
|
||||
InitSDL();
|
||||
@@ -209,7 +211,7 @@ float Window::Render(n64::Core& core) {
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if (ImGui::MenuItem("Open", "O")) {
|
||||
nfdchar_t *outpath;
|
||||
const nfdu8filteritem_t filter{"Nintendo 64 roms", "n64,z64,v64,N64,Z64,V64"};
|
||||
const nfdu8filteritem_t filter{"Nintendo 64 roms", "backend,z64,v64,N64,Z64,V64"};
|
||||
nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr);
|
||||
if (result == NFD_OKAY) {
|
||||
LoadROM(core, outpath);
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#include <imgui.h>
|
||||
|
||||
inline bool CreateComboList(const char* label, int* index, const char** items, int items_count) {
|
||||
if (ImGui::BeginCombo(label, items[*index])) {
|
||||
for (int n = 0; n < items_count; n++) {
|
||||
const bool is_selected = (*index == n);
|
||||
if (ImGui::Selectable(items[n], is_selected)) {
|
||||
*index = n;
|
||||
}
|
||||
|
||||
if (is_selected) {
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define checkjsonentry(name, type, param1, param2, defaultVal) \
|
||||
do { \
|
||||
auto name##Entry = settings[param1][param2]; \
|
||||
if(!name##Entry.empty()) { \
|
||||
auto value = name##Entry.get<type>(); \
|
||||
name = value; \
|
||||
} else { \
|
||||
settingsFile.clear(); \
|
||||
settings[param1][param2] = defaultVal; \
|
||||
settingsFile << settings; \
|
||||
name = defaultVal; \
|
||||
} \
|
||||
} while(0)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <frontend/App.hpp>
|
||||
#include "m64.hpp"
|
||||
#include <MupenMovie.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define main SDL_main
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
#include <n64/core/mmio/VI.hpp>
|
||||
#include <n64/core/mmio/MI.hpp>
|
||||
#include <n64/core/mmio/AI.hpp>
|
||||
#include <n64/core/mmio/PI.hpp>
|
||||
#include <n64/core/mmio/RI.hpp>
|
||||
#include <n64/core/mmio/SI.hpp>
|
||||
#include <n64/core/RSP.hpp>
|
||||
#include <n64/core/RDP.hpp>
|
||||
|
||||
namespace n64 {
|
||||
struct Mem;
|
||||
struct Registers;
|
||||
|
||||
struct MMIO {
|
||||
MMIO();
|
||||
void Reset();
|
||||
VI vi;
|
||||
MI mi;
|
||||
AI ai;
|
||||
PI pi;
|
||||
RI ri;
|
||||
SI si;
|
||||
RSP rsp;
|
||||
RDP rdp;
|
||||
|
||||
u32 Read(u32);
|
||||
void Write(Mem&, Registers&, u32, u32);
|
||||
};
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
|
||||
static constexpr u16 rcp_rom[] = {
|
||||
0xffff, 0xff00, 0xfe01, 0xfd04, 0xfc07, 0xfb0c, 0xfa11, 0xf918, 0xf81f, 0xf727, 0xf631, 0xf53b, 0xf446, 0xf352, 0xf25f, 0xf16d,
|
||||
0xf07c, 0xef8b, 0xee9c, 0xedae, 0xecc0, 0xebd3, 0xeae8, 0xe9fd, 0xe913, 0xe829, 0xe741, 0xe65a, 0xe573, 0xe48d, 0xe3a9, 0xe2c5,
|
||||
0xe1e1, 0xe0ff, 0xe01e, 0xdf3d, 0xde5d, 0xdd7e, 0xdca0, 0xdbc2, 0xdae6, 0xda0a, 0xd92f, 0xd854, 0xd77b, 0xd6a2, 0xd5ca, 0xd4f3,
|
||||
0xd41d, 0xd347, 0xd272, 0xd19e, 0xd0cb, 0xcff8, 0xcf26, 0xce55, 0xcd85, 0xccb5, 0xcbe6, 0xcb18, 0xca4b, 0xc97e, 0xc8b2, 0xc7e7,
|
||||
0xc71c, 0xc652, 0xc589, 0xc4c0, 0xc3f8, 0xc331, 0xc26b, 0xc1a5, 0xc0e0, 0xc01c, 0xbf58, 0xbe95, 0xbdd2, 0xbd10, 0xbc4f, 0xbb8f,
|
||||
0xbacf, 0xba10, 0xb951, 0xb894, 0xb7d6, 0xb71a, 0xb65e, 0xb5a2, 0xb4e8, 0xb42e, 0xb374, 0xb2bb, 0xb203, 0xb14b, 0xb094, 0xafde,
|
||||
0xaf28, 0xae73, 0xadbe, 0xad0a, 0xac57, 0xaba4, 0xaaf1, 0xaa40, 0xa98e, 0xa8de, 0xa82e, 0xa77e, 0xa6d0, 0xa621, 0xa574, 0xa4c6,
|
||||
0xa41a, 0xa36e, 0xa2c2, 0xa217, 0xa16d, 0xa0c3, 0xa01a, 0x9f71, 0x9ec8, 0x9e21, 0x9d79, 0x9cd3, 0x9c2d, 0x9b87, 0x9ae2, 0x9a3d,
|
||||
0x9999, 0x98f6, 0x9852, 0x97b0, 0x970e, 0x966c, 0x95cb, 0x952b, 0x948b, 0x93eb, 0x934c, 0x92ad, 0x920f, 0x9172, 0x90d4, 0x9038,
|
||||
0x8f9c, 0x8f00, 0x8e65, 0x8dca, 0x8d30, 0x8c96, 0x8bfc, 0x8b64, 0x8acb, 0x8a33, 0x899c, 0x8904, 0x886e, 0x87d8, 0x8742, 0x86ad,
|
||||
0x8618, 0x8583, 0x84f0, 0x845c, 0x83c9, 0x8336, 0x82a4, 0x8212, 0x8181, 0x80f0, 0x8060, 0x7fd0, 0x7f40, 0x7eb1, 0x7e22, 0x7d93,
|
||||
0x7d05, 0x7c78, 0x7beb, 0x7b5e, 0x7ad2, 0x7a46, 0x79ba, 0x792f, 0x78a4, 0x781a, 0x7790, 0x7706, 0x767d, 0x75f5, 0x756c, 0x74e4,
|
||||
0x745d, 0x73d5, 0x734f, 0x72c8, 0x7242, 0x71bc, 0x7137, 0x70b2, 0x702e, 0x6fa9, 0x6f26, 0x6ea2, 0x6e1f, 0x6d9c, 0x6d1a, 0x6c98,
|
||||
0x6c16, 0x6b95, 0x6b14, 0x6a94, 0x6a13, 0x6993, 0x6914, 0x6895, 0x6816, 0x6798, 0x6719, 0x669c, 0x661e, 0x65a1, 0x6524, 0x64a8,
|
||||
0x642c, 0x63b0, 0x6335, 0x62ba, 0x623f, 0x61c5, 0x614b, 0x60d1, 0x6058, 0x5fdf, 0x5f66, 0x5eed, 0x5e75, 0x5dfd, 0x5d86, 0x5d0f,
|
||||
0x5c98, 0x5c22, 0x5bab, 0x5b35, 0x5ac0, 0x5a4b, 0x59d6, 0x5961, 0x58ed, 0x5879, 0x5805, 0x5791, 0x571e, 0x56ac, 0x5639, 0x55c7,
|
||||
0x5555, 0x54e3, 0x5472, 0x5401, 0x5390, 0x5320, 0x52af, 0x5240, 0x51d0, 0x5161, 0x50f2, 0x5083, 0x5015, 0x4fa6, 0x4f38, 0x4ecb,
|
||||
0x4e5e, 0x4df1, 0x4d84, 0x4d17, 0x4cab, 0x4c3f, 0x4bd3, 0x4b68, 0x4afd, 0x4a92, 0x4a27, 0x49bd, 0x4953, 0x48e9, 0x4880, 0x4817,
|
||||
0x47ae, 0x4745, 0x46dc, 0x4674, 0x460c, 0x45a5, 0x453d, 0x44d6, 0x446f, 0x4408, 0x43a2, 0x433c, 0x42d6, 0x4270, 0x420b, 0x41a6,
|
||||
0x4141, 0x40dc, 0x4078, 0x4014, 0x3fb0, 0x3f4c, 0x3ee8, 0x3e85, 0x3e22, 0x3dc0, 0x3d5d, 0x3cfb, 0x3c99, 0x3c37, 0x3bd6, 0x3b74,
|
||||
0x3b13, 0x3ab2, 0x3a52, 0x39f1, 0x3991, 0x3931, 0x38d2, 0x3872, 0x3813, 0x37b4, 0x3755, 0x36f7, 0x3698, 0x363a, 0x35dc, 0x357f,
|
||||
0x3521, 0x34c4, 0x3467, 0x340a, 0x33ae, 0x3351, 0x32f5, 0x3299, 0x323e, 0x31e2, 0x3187, 0x312c, 0x30d1, 0x3076, 0x301c, 0x2fc2,
|
||||
0x2f68, 0x2f0e, 0x2eb4, 0x2e5b, 0x2e02, 0x2da9, 0x2d50, 0x2cf8, 0x2c9f, 0x2c47, 0x2bef, 0x2b97, 0x2b40, 0x2ae8, 0x2a91, 0x2a3a,
|
||||
0x29e4, 0x298d, 0x2937, 0x28e0, 0x288b, 0x2835, 0x27df, 0x278a, 0x2735, 0x26e0, 0x268b, 0x2636, 0x25e2, 0x258d, 0x2539, 0x24e5,
|
||||
0x2492, 0x243e, 0x23eb, 0x2398, 0x2345, 0x22f2, 0x22a0, 0x224d, 0x21fb, 0x21a9, 0x2157, 0x2105, 0x20b4, 0x2063, 0x2012, 0x1fc1,
|
||||
0x1f70, 0x1f1f, 0x1ecf, 0x1e7f, 0x1e2e, 0x1ddf, 0x1d8f, 0x1d3f, 0x1cf0, 0x1ca1, 0x1c52, 0x1c03, 0x1bb4, 0x1b66, 0x1b17, 0x1ac9,
|
||||
0x1a7b, 0x1a2d, 0x19e0, 0x1992, 0x1945, 0x18f8, 0x18ab, 0x185e, 0x1811, 0x17c4, 0x1778, 0x172c, 0x16e0, 0x1694, 0x1648, 0x15fd,
|
||||
0x15b1, 0x1566, 0x151b, 0x14d0, 0x1485, 0x143b, 0x13f0, 0x13a6, 0x135c, 0x1312, 0x12c8, 0x127f, 0x1235, 0x11ec, 0x11a3, 0x1159,
|
||||
0x1111, 0x10c8, 0x107f, 0x1037, 0x0fef, 0x0fa6, 0x0f5e, 0x0f17, 0x0ecf, 0x0e87, 0x0e40, 0x0df9, 0x0db2, 0x0d6b, 0x0d24, 0x0cdd,
|
||||
0x0c97, 0x0c50, 0x0c0a, 0x0bc4, 0x0b7e, 0x0b38, 0x0af2, 0x0aad, 0x0a68, 0x0a22, 0x09dd, 0x0998, 0x0953, 0x090f, 0x08ca, 0x0886,
|
||||
0x0842, 0x07fd, 0x07b9, 0x0776, 0x0732, 0x06ee, 0x06ab, 0x0668, 0x0624, 0x05e1, 0x059e, 0x055c, 0x0519, 0x04d6, 0x0494, 0x0452,
|
||||
0x0410, 0x03ce, 0x038c, 0x034a, 0x0309, 0x02c7, 0x0286, 0x0245, 0x0204, 0x01c3, 0x0182, 0x0141, 0x0101, 0x00c0, 0x0080, 0x0040
|
||||
};
|
||||
|
||||
static constexpr u16 rsq_rom[] = {
|
||||
0xffff, 0xff00, 0xfe02, 0xfd06, 0xfc0b, 0xfb12, 0xfa1a, 0xf923, 0xf82e, 0xf73b, 0xf648, 0xf557, 0xf467, 0xf379, 0xf28c, 0xf1a0,
|
||||
0xf0b6, 0xefcd, 0xeee5, 0xedff, 0xed19, 0xec35, 0xeb52, 0xea71, 0xe990, 0xe8b1, 0xe7d3, 0xe6f6, 0xe61b, 0xe540, 0xe467, 0xe38e,
|
||||
0xe2b7, 0xe1e1, 0xe10d, 0xe039, 0xdf66, 0xde94, 0xddc4, 0xdcf4, 0xdc26, 0xdb59, 0xda8c, 0xd9c1, 0xd8f7, 0xd82d, 0xd765, 0xd69e,
|
||||
0xd5d7, 0xd512, 0xd44e, 0xd38a, 0xd2c8, 0xd206, 0xd146, 0xd086, 0xcfc7, 0xcf0a, 0xce4d, 0xcd91, 0xccd6, 0xcc1b, 0xcb62, 0xcaa9,
|
||||
0xc9f2, 0xc93b, 0xc885, 0xc7d0, 0xc71c, 0xc669, 0xc5b6, 0xc504, 0xc453, 0xc3a3, 0xc2f4, 0xc245, 0xc198, 0xc0eb, 0xc03f, 0xbf93,
|
||||
0xbee9, 0xbe3f, 0xbd96, 0xbced, 0xbc46, 0xbb9f, 0xbaf8, 0xba53, 0xb9ae, 0xb90a, 0xb867, 0xb7c5, 0xb723, 0xb681, 0xb5e1, 0xb541,
|
||||
0xb4a2, 0xb404, 0xb366, 0xb2c9, 0xb22c, 0xb191, 0xb0f5, 0xb05b, 0xafc1, 0xaf28, 0xae8f, 0xadf7, 0xad60, 0xacc9, 0xac33, 0xab9e,
|
||||
0xab09, 0xaa75, 0xa9e1, 0xa94e, 0xa8bc, 0xa82a, 0xa799, 0xa708, 0xa678, 0xa5e8, 0xa559, 0xa4cb, 0xa43d, 0xa3b0, 0xa323, 0xa297,
|
||||
0xa20b, 0xa180, 0xa0f6, 0xa06c, 0x9fe2, 0x9f59, 0x9ed1, 0x9e49, 0x9dc2, 0x9d3b, 0x9cb4, 0x9c2f, 0x9ba9, 0x9b25, 0x9aa0, 0x9a1c,
|
||||
0x9999, 0x9916, 0x9894, 0x9812, 0x9791, 0x9710, 0x968f, 0x960f, 0x9590, 0x9511, 0x9492, 0x9414, 0x9397, 0x931a, 0x929d, 0x9221,
|
||||
0x91a5, 0x9129, 0x90af, 0x9034, 0x8fba, 0x8f40, 0x8ec7, 0x8e4f, 0x8dd6, 0x8d5e, 0x8ce7, 0x8c70, 0x8bf9, 0x8b83, 0x8b0d, 0x8a98,
|
||||
0x8a23, 0x89ae, 0x893a, 0x88c6, 0x8853, 0x87e0, 0x876d, 0x86fb, 0x8689, 0x8618, 0x85a7, 0x8536, 0x84c6, 0x8456, 0x83e7, 0x8377,
|
||||
0x8309, 0x829a, 0x822c, 0x81bf, 0x8151, 0x80e4, 0x8078, 0x800c, 0x7fa0, 0x7f34, 0x7ec9, 0x7e5e, 0x7df4, 0x7d8a, 0x7d20, 0x7cb6,
|
||||
0x7c4d, 0x7be5, 0x7b7c, 0x7b14, 0x7aac, 0x7a45, 0x79de, 0x7977, 0x7911, 0x78ab, 0x7845, 0x77df, 0x777a, 0x7715, 0x76b1, 0x764d,
|
||||
0x75e9, 0x7585, 0x7522, 0x74bf, 0x745d, 0x73fa, 0x7398, 0x7337, 0x72d5, 0x7274, 0x7213, 0x71b3, 0x7152, 0x70f2, 0x7093, 0x7033,
|
||||
0x6fd4, 0x6f76, 0x6f17, 0x6eb9, 0x6e5b, 0x6dfd, 0x6da0, 0x6d43, 0x6ce6, 0x6c8a, 0x6c2d, 0x6bd1, 0x6b76, 0x6b1a, 0x6abf, 0x6a64,
|
||||
0x6a09, 0x6955, 0x68a1, 0x67ef, 0x673e, 0x668d, 0x65de, 0x6530, 0x6482, 0x63d6, 0x632b, 0x6280, 0x61d7, 0x612e, 0x6087, 0x5fe0,
|
||||
0x5f3a, 0x5e95, 0x5df1, 0x5d4e, 0x5cac, 0x5c0b, 0x5b6b, 0x5acb, 0x5a2c, 0x598f, 0x58f2, 0x5855, 0x57ba, 0x5720, 0x5686, 0x55ed,
|
||||
0x5555, 0x54be, 0x5427, 0x5391, 0x52fc, 0x5268, 0x51d5, 0x5142, 0x50b0, 0x501f, 0x4f8e, 0x4efe, 0x4e6f, 0x4de1, 0x4d53, 0x4cc6,
|
||||
0x4c3a, 0x4baf, 0x4b24, 0x4a9a, 0x4a10, 0x4987, 0x48ff, 0x4878, 0x47f1, 0x476b, 0x46e5, 0x4660, 0x45dc, 0x4558, 0x44d5, 0x4453,
|
||||
0x43d1, 0x434f, 0x42cf, 0x424f, 0x41cf, 0x4151, 0x40d2, 0x4055, 0x3fd8, 0x3f5b, 0x3edf, 0x3e64, 0x3de9, 0x3d6e, 0x3cf5, 0x3c7c,
|
||||
0x3c03, 0x3b8b, 0x3b13, 0x3a9c, 0x3a26, 0x39b0, 0x393a, 0x38c5, 0x3851, 0x37dd, 0x3769, 0x36f6, 0x3684, 0x3612, 0x35a0, 0x352f,
|
||||
0x34bf, 0x344f, 0x33df, 0x3370, 0x3302, 0x3293, 0x3226, 0x31b9, 0x314c, 0x30df, 0x3074, 0x3008, 0x2f9d, 0x2f33, 0x2ec8, 0x2e5f,
|
||||
0x2df6, 0x2d8d, 0x2d24, 0x2cbc, 0x2c55, 0x2bee, 0x2b87, 0x2b21, 0x2abb, 0x2a55, 0x29f0, 0x298b, 0x2927, 0x28c3, 0x2860, 0x27fd,
|
||||
0x279a, 0x2738, 0x26d6, 0x2674, 0x2613, 0x25b2, 0x2552, 0x24f2, 0x2492, 0x2432, 0x23d3, 0x2375, 0x2317, 0x22b9, 0x225b, 0x21fe,
|
||||
0x21a1, 0x2145, 0x20e8, 0x208d, 0x2031, 0x1fd6, 0x1f7b, 0x1f21, 0x1ec7, 0x1e6d, 0x1e13, 0x1dba, 0x1d61, 0x1d09, 0x1cb1, 0x1c59,
|
||||
0x1c01, 0x1baa, 0x1b53, 0x1afc, 0x1aa6, 0x1a50, 0x19fa, 0x19a5, 0x1950, 0x18fb, 0x18a7, 0x1853, 0x17ff, 0x17ab, 0x1758, 0x1705,
|
||||
0x16b2, 0x1660, 0x160d, 0x15bc, 0x156a, 0x1519, 0x14c8, 0x1477, 0x1426, 0x13d6, 0x1386, 0x1337, 0x12e7, 0x1298, 0x1249, 0x11fb,
|
||||
0x11ac, 0x115e, 0x1111, 0x10c3, 0x1076, 0x1029, 0x0fdc, 0x0f8f, 0x0f43, 0x0ef7, 0x0eab, 0x0e60, 0x0e15, 0x0dca, 0x0d7f, 0x0d34,
|
||||
0x0cea, 0x0ca0, 0x0c56, 0x0c0c, 0x0bc3, 0x0b7a, 0x0b31, 0x0ae8, 0x0aa0, 0x0a58, 0x0a10, 0x09c8, 0x0981, 0x0939, 0x08f2, 0x08ab,
|
||||
0x0865, 0x081e, 0x07d8, 0x0792, 0x074d, 0x0707, 0x06c2, 0x067d, 0x0638, 0x05f3, 0x05af, 0x056a, 0x0526, 0x04e2, 0x049f, 0x045b,
|
||||
0x0418, 0x03d5, 0x0392, 0x0350, 0x030d, 0x02cb, 0x0289, 0x0247, 0x0206, 0x01c4, 0x0183, 0x0142, 0x0101, 0x00c0, 0x0080, 0x0040
|
||||
};
|
||||
326
src/util.hpp
326
src/util.hpp
@@ -1,326 +0,0 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
#include <portable_endian_bswap.h>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <discord_rpc.h>
|
||||
|
||||
namespace util {
|
||||
using SteadyClock = std::chrono::steady_clock;
|
||||
using DurationMillis = std::chrono::duration<double, std::milli>;
|
||||
using TimePoint = std::chrono::time_point<SteadyClock, DurationMillis>;
|
||||
|
||||
enum MessageType : u8 {
|
||||
Info, Warn, Error
|
||||
};
|
||||
|
||||
template <MessageType messageType = Info, typename ...Args>
|
||||
constexpr void print(const std::string& fmt, Args... args) {
|
||||
#ifndef _WIN32
|
||||
if constexpr(messageType == Error) {
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red), fmt, args...);
|
||||
exit(-1);
|
||||
} else if constexpr(messageType == Warn) {
|
||||
fmt::print(fg(fmt::color::yellow), fmt, args...);
|
||||
} else if constexpr(messageType == Info) {
|
||||
fmt::print(fmt, args...);
|
||||
}
|
||||
#else
|
||||
if constexpr(messageType == Error) {
|
||||
fmt::print(fmt, args...);
|
||||
exit(-1);
|
||||
} else {
|
||||
fmt::print(fmt, args...);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void panic(const std::string& fmt, Args... args) {
|
||||
print<Error>(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void warn(const std::string& fmt, Args... args) {
|
||||
print<Warn>(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void info(const std::string& fmt, Args... args) {
|
||||
print(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void logdebug(const std::string& fmt, Args... args) {
|
||||
#ifndef NDEBUG
|
||||
print(fmt, args...);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, bool HToBE = false>
|
||||
[[maybe_unused]] auto GetSwapFunc(T num) -> T {
|
||||
static_assert(sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "GetSwapFunc used with invalid size!");
|
||||
if constexpr(sizeof(T) == 2) {
|
||||
if constexpr(HToBE) {
|
||||
return htobe16(num);
|
||||
}
|
||||
return be16toh(num);
|
||||
} else if constexpr(sizeof(T) == 4) {
|
||||
if constexpr(HToBE) {
|
||||
return htobe32(num);
|
||||
}
|
||||
return be32toh(num);
|
||||
} else if constexpr(sizeof(T) == 8) {
|
||||
if constexpr(HToBE) {
|
||||
return htobe64(num);
|
||||
}
|
||||
return be64toh(num);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T ReadAccess(u8* data, u32 index) {
|
||||
if constexpr(sizeof(T) == 1) {
|
||||
return data[index];
|
||||
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
|
||||
T result = 0;
|
||||
memcpy(&result, &data[index], sizeof(T));
|
||||
return result;
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
u32 hi = 0;
|
||||
u32 lo = 0;
|
||||
memcpy(&hi, &data[index + 0], sizeof(u32));
|
||||
memcpy(&lo, &data[index + 4], sizeof(u32));
|
||||
T result = ((T)hi << 32) | (T)lo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void WriteAccess(u8* data, u32 index, T val) {
|
||||
if constexpr(sizeof(T) == 1) {
|
||||
data[index] = val;
|
||||
return;
|
||||
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4){
|
||||
memcpy(&data[index], &val, sizeof(T));
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
u32 hi = val >> 32;
|
||||
u32 lo = val;
|
||||
memcpy(&data[index + 0], &hi, sizeof(u32));
|
||||
memcpy(&data[index + 4], &lo, sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapBuffer32(size_t size, u8* data) {
|
||||
for(int i = 0; i < size; i += 4) {
|
||||
u32 original = *(u32*)&data[i];
|
||||
*(u32*)&data[i] = bswap_32(original);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapBuffer16(size_t size, u8* data) {
|
||||
for(int i = 0; i < size; i += 2) {
|
||||
u16 original = *(u16*)&data[i];
|
||||
*(u16*)&data[i] = bswap_16(original);
|
||||
}
|
||||
}
|
||||
|
||||
inline u32 crc32(u32 crc, const u8 *buf, size_t len) {
|
||||
static u32 table[256];
|
||||
static int have_table = 0;
|
||||
u32 rem;
|
||||
u8 octet;
|
||||
int i, j;
|
||||
const u8 *p, *q;
|
||||
|
||||
if (have_table == 0) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
rem = i;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (rem & 1) {
|
||||
rem >>= 1;
|
||||
rem ^= 0xedb88320;
|
||||
} else
|
||||
rem >>= 1;
|
||||
}
|
||||
table[i] = rem;
|
||||
}
|
||||
have_table = 1;
|
||||
}
|
||||
|
||||
crc = ~crc;
|
||||
q = buf + len;
|
||||
for (p = buf; p < q; p++) {
|
||||
octet = *p; /* Cast to unsigned octet. */
|
||||
crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
enum RomTypes {
|
||||
Z64 = 0x80371240,
|
||||
N64 = 0x40123780,
|
||||
V64 = 0x37804012
|
||||
};
|
||||
|
||||
inline void SwapN64RomJustCRC(size_t size, u8* rom, u32& crc) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
|
||||
switch(endianness) {
|
||||
case RomTypes::V64: {
|
||||
SwapBuffer16(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
} break;
|
||||
case RomTypes::N64: {
|
||||
SwapBuffer32(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
} break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapN64Rom(size_t size, u8* rom, u32& crc, u32& cicChecksum) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
|
||||
switch(endianness) {
|
||||
case RomTypes::V64: {
|
||||
u8* temp = (u8*)calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer16(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
SwapBuffer32(size, rom);
|
||||
SwapBuffer16(size, rom);
|
||||
} break;
|
||||
case RomTypes::N64: {
|
||||
u8* temp = (u8*)calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer32(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
} break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
cicChecksum = crc32(0, &rom[0x40], 0x9c0);
|
||||
SwapBuffer32(size, rom);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t size, typename T = u8>
|
||||
struct CircularBuffer {
|
||||
CircularBuffer() : head(0) {
|
||||
raw.fill(T());
|
||||
}
|
||||
// make it scroll
|
||||
void PushValue(T val) {
|
||||
raw[head] = val;
|
||||
head++;
|
||||
if(head == size) {
|
||||
head = 0;
|
||||
}
|
||||
}
|
||||
|
||||
T PopValue() {
|
||||
head--;
|
||||
if(head == 0) {
|
||||
head = size - 1;
|
||||
}
|
||||
return raw[head];
|
||||
}
|
||||
|
||||
T& operator[](const int index) {
|
||||
return raw[index];
|
||||
}
|
||||
auto begin() { return raw.begin(); }
|
||||
auto end() { return raw.end(); }
|
||||
auto fill(const T& u) { raw.fill(u); }
|
||||
size_t GetHead() { return head; }
|
||||
private:
|
||||
std::array<T, size> raw;
|
||||
size_t head;
|
||||
};
|
||||
|
||||
inline size_t NextPow2(size_t num) {
|
||||
// Taken from "Bit Twiddling Hacks" by Sean Anderson:
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--num;
|
||||
num |= num >> 1;
|
||||
num |= num >> 2;
|
||||
num |= num >> 4;
|
||||
num |= num >> 8;
|
||||
num |= num >> 16;
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
inline auto ReadFileBinary(const std::string& path, u32** buf) {
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
if(!file.is_open()) {
|
||||
panic("Could not load file '{}'!\n", path);
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
*buf = (u32*)calloc(size, 1);
|
||||
file.read(reinterpret_cast<char*>(*buf), size);
|
||||
file.close();
|
||||
return size;
|
||||
}
|
||||
|
||||
enum State {
|
||||
Idling,
|
||||
Playing,
|
||||
Paused
|
||||
};
|
||||
|
||||
inline void UpdateRPC(State state, const std::string& game = "") {
|
||||
DiscordRichPresence presence{};
|
||||
std::string textState, textDetails;
|
||||
|
||||
switch(state) {
|
||||
case Idling:
|
||||
textDetails = "Idling";
|
||||
break;
|
||||
case Playing:
|
||||
textDetails = "In-game";
|
||||
textState = "Playing \"" + game + "\"";
|
||||
break;
|
||||
case Paused:
|
||||
textDetails = "In-game";
|
||||
textState = "Playing \"" + game + "\" (Paused)";
|
||||
break;
|
||||
}
|
||||
|
||||
presence.details = textDetails.c_str();
|
||||
presence.state = textState.c_str();
|
||||
presence.startTimestamp = time(nullptr);
|
||||
presence.largeImageText = "Gadolinium";
|
||||
presence.largeImageKey = "logo";
|
||||
Discord_UpdatePresence(&presence);
|
||||
}
|
||||
|
||||
inline void ClearRPC() {
|
||||
Discord_ClearPresence();
|
||||
}
|
||||
34
src/utils/File.hpp
Normal file
34
src/utils/File.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace util {
|
||||
inline auto ReadFileBinary(const std::string& path, u32** buf) {
|
||||
std::ifstream file(path, std::ios::binary);
|
||||
file.unsetf(std::ios::skipws);
|
||||
if(!file.is_open()) {
|
||||
panic("Could not load file '{}'!\n", path);
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
size_t size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
*buf = (u32*)calloc(size, 1);
|
||||
file.read(reinterpret_cast<char*>(*buf), size);
|
||||
file.close();
|
||||
return size;
|
||||
}
|
||||
|
||||
inline size_t NextPow2(size_t num) {
|
||||
// Taken from "Bit Twiddling Hacks" by Sean Anderson:
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
||||
--num;
|
||||
num |= num >> 1;
|
||||
num |= num >> 2;
|
||||
num |= num >> 4;
|
||||
num |= num >> 8;
|
||||
num |= num >> 16;
|
||||
return num + 1;
|
||||
}
|
||||
}
|
||||
154
src/utils/MemoryHelpers.hpp
Normal file
154
src/utils/MemoryHelpers.hpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <cstring>
|
||||
#include <portable_endian_bswap.h>
|
||||
#include <log.hpp>
|
||||
|
||||
namespace util {
|
||||
template<typename T>
|
||||
inline T ReadAccess(u8 *data, u32 index) {
|
||||
if constexpr (sizeof(T) == 1) {
|
||||
return data[index];
|
||||
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
|
||||
T result = 0;
|
||||
memcpy(&result, &data[index], sizeof(T));
|
||||
return result;
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
u32 hi = 0;
|
||||
u32 lo = 0;
|
||||
memcpy(&hi, &data[index + 0], sizeof(u32));
|
||||
memcpy(&lo, &data[index + 4], sizeof(u32));
|
||||
T result = ((T) hi << 32) | (T) lo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void WriteAccess(u8 *data, u32 index, T val) {
|
||||
if constexpr (sizeof(T) == 1) {
|
||||
data[index] = val;
|
||||
return;
|
||||
} else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
|
||||
memcpy(&data[index], &val, sizeof(T));
|
||||
} else {
|
||||
static_assert(sizeof(T) == 8);
|
||||
u32 hi = val >> 32;
|
||||
u32 lo = val;
|
||||
memcpy(&data[index + 0], &hi, sizeof(u32));
|
||||
memcpy(&data[index + 4], &lo, sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapBuffer32(size_t size, u8 *data) {
|
||||
for (int i = 0; i < size; i += 4) {
|
||||
u32 original = *(u32 *) &data[i];
|
||||
*(u32 *) &data[i] = bswap_32(original);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapBuffer16(size_t size, u8 *data) {
|
||||
for (int i = 0; i < size; i += 2) {
|
||||
u16 original = *(u16 *) &data[i];
|
||||
*(u16 *) &data[i] = bswap_16(original);
|
||||
}
|
||||
}
|
||||
|
||||
inline u32 crc32(u32 crc, const u8 *buf, size_t len) {
|
||||
static u32 table[256];
|
||||
static int have_table = 0;
|
||||
u32 rem;
|
||||
u8 octet;
|
||||
int i, j;
|
||||
const u8 *p, *q;
|
||||
|
||||
if (have_table == 0) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
rem = i;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (rem & 1) {
|
||||
rem >>= 1;
|
||||
rem ^= 0xedb88320;
|
||||
} else
|
||||
rem >>= 1;
|
||||
}
|
||||
table[i] = rem;
|
||||
}
|
||||
have_table = 1;
|
||||
}
|
||||
|
||||
crc = ~crc;
|
||||
q = buf + len;
|
||||
for (p = buf; p < q; p++) {
|
||||
octet = *p; /* Cast to unsigned octet. */
|
||||
crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
enum RomTypes {
|
||||
Z64 = 0x80371240,
|
||||
N64 = 0x40123780,
|
||||
V64 = 0x37804012
|
||||
};
|
||||
|
||||
inline void SwapN64RomJustCRC(size_t size, u8 *rom, u32 &crc) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
|
||||
switch (endianness) {
|
||||
case RomTypes::V64: {
|
||||
SwapBuffer16(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
}
|
||||
break;
|
||||
case RomTypes::N64: {
|
||||
SwapBuffer32(size, rom);
|
||||
crc = crc32(0, rom, size);
|
||||
}
|
||||
break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
}
|
||||
}
|
||||
|
||||
inline void SwapN64Rom(size_t size, u8 *rom, u32 &crc, u32 &cicChecksum) {
|
||||
RomTypes endianness;
|
||||
memcpy(&endianness, rom, 4);
|
||||
endianness = static_cast<RomTypes>(be32toh(endianness));
|
||||
|
||||
switch (endianness) {
|
||||
case RomTypes::V64: {
|
||||
u8 *temp = (u8 *) calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer16(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
SwapBuffer32(size, rom);
|
||||
SwapBuffer16(size, rom);
|
||||
}
|
||||
break;
|
||||
case RomTypes::N64: {
|
||||
u8 *temp = (u8 *) calloc(size, 1);
|
||||
memcpy(temp, rom, size);
|
||||
SwapBuffer32(size, temp);
|
||||
crc = crc32(0, temp, size);
|
||||
cicChecksum = crc32(0, &temp[0x40], 0x9c0);
|
||||
free(temp);
|
||||
}
|
||||
break;
|
||||
case RomTypes::Z64:
|
||||
crc = crc32(0, rom, size);
|
||||
cicChecksum = crc32(0, &rom[0x40], 0x9c0);
|
||||
SwapBuffer32(size, rom);
|
||||
break;
|
||||
default:
|
||||
panic("Unrecognized rom format! Make sure this is a valid Nintendo 64 ROM dump!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/utils/log.hpp
Normal file
59
src/utils/log.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
#include <common.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/color.h>
|
||||
|
||||
namespace util {
|
||||
enum MessageType : u8 {
|
||||
Info, Debug, Warn, Error
|
||||
};
|
||||
|
||||
template <MessageType messageType = Info, typename ...Args>
|
||||
constexpr void print(const std::string& fmt, Args... args) {
|
||||
#ifndef _WIN32
|
||||
if constexpr(messageType == Error) {
|
||||
fmt::print(fmt::emphasis::bold | fg(fmt::color::red), fmt, args...);
|
||||
exit(-1);
|
||||
} else if constexpr(messageType == Warn) {
|
||||
fmt::print(fg(fmt::color::yellow), fmt, args...);
|
||||
} else if constexpr(messageType == Info) {
|
||||
fmt::print(fmt, args...);
|
||||
} else if constexpr(messageType == Debug) {
|
||||
#ifndef NDEBUG
|
||||
fmt::print(fmt, args...);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if constexpr(messageType == Error) {
|
||||
fmt::print(fmt, args...);
|
||||
exit(-1);
|
||||
} else if constexpr(messageType == Debug) {
|
||||
#ifndef NDEBUG
|
||||
fmt::print(fmt, args...);
|
||||
#endif
|
||||
} else {
|
||||
fmt::print(fmt, args...);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void panic(const std::string& fmt, Args... args) {
|
||||
print<Error>(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void warn(const std::string& fmt, Args... args) {
|
||||
print<Warn>(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void info(const std::string& fmt, Args... args) {
|
||||
print(fmt, args...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr void debug(const std::string& fmt, Args... args) {
|
||||
print<Debug>(fmt, args...);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user