mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-24 04:14:59 +00:00
WIP overlay support and some libultra function implementations for other games
This commit is contained in:
parent
0af9d489b3
commit
c6de2b6189
17 changed files with 13096 additions and 214 deletions
|
@ -150,7 +150,7 @@ XCOPY "$(ProjectDir)Lib\SDL2-2.24.0\lib\$(Platform)\SDL2.dll" "$(TargetDir)" /S
|
|||
<ClCompile Include="funcs\lookup.cpp" />
|
||||
<ClCompile Include="portultra\events.cpp" />
|
||||
<ClCompile Include="portultra\ultrainit.cpp" />
|
||||
<ClCompile Include="portultra\main.c" />
|
||||
<ClCompile Include="portultra\port_main.c" />
|
||||
<ClCompile Include="portultra\mesgqueue.cpp" />
|
||||
<ClCompile Include="portultra\scheduler.cpp" />
|
||||
<ClCompile Include="portultra\task_pthreads.cpp" />
|
||||
|
@ -162,6 +162,7 @@ XCOPY "$(ProjectDir)Lib\SDL2-2.24.0\lib\$(Platform)\SDL2.dll" "$(TargetDir)" /S
|
|||
<ClCompile Include="src\dp.cpp" />
|
||||
<ClCompile Include="src\eep.cpp" />
|
||||
<ClCompile Include="portultra\misc_ultra.cpp" />
|
||||
<ClCompile Include="src\math_routines.cpp" />
|
||||
<ClCompile Include="src\pi.cpp" />
|
||||
<ClCompile Include="src\portultra_translation.cpp" />
|
||||
<ClCompile Include="src\recomp.cpp" />
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,5 @@
|
|||
#include "ultra64.h"
|
||||
|
||||
extern uint64_t start_time;
|
||||
|
||||
#define K0BASE 0x80000000
|
||||
#define K1BASE 0xA0000000
|
||||
#define K2BASE 0xC0000000
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <cstdio>
|
||||
#include <thread>
|
||||
#include <cassert>
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "multilibultra.hpp"
|
||||
|
@ -102,6 +103,14 @@ extern "C" void osCreateThread(RDRAM_ARG PTR(OSThread) t_, OSId id, PTR(thread_f
|
|||
t->context->host_thread = std::thread{_thread_func, PASS_RDRAM t_, entrypoint, arg};
|
||||
}
|
||||
|
||||
extern "C" void osStopThread(RDRAM_ARG PTR(OSThread) t_) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
extern "C" void osDestroyThread(RDRAM_ARG PTR(OSThread) t_) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
extern "C" void osSetThreadPri(RDRAM_ARG PTR(OSThread) t, OSPri pri) {
|
||||
if (t == NULLPTR) {
|
||||
t = thread_self;
|
||||
|
@ -120,6 +129,20 @@ extern "C" void osSetThreadPri(RDRAM_ARG PTR(OSThread) t, OSPri pri) {
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" OSPri osGetThreadPri(RDRAM_ARG PTR(OSThread) t) {
|
||||
if (t == NULLPTR) {
|
||||
t = thread_self;
|
||||
}
|
||||
return TO_PTR(OSThread, t)->priority;
|
||||
}
|
||||
|
||||
extern "C" OSId osGetThreadId(RDRAM_ARG PTR(OSThread) t) {
|
||||
if (t == NULLPTR) {
|
||||
t = thread_self;
|
||||
}
|
||||
return TO_PTR(OSThread, t)->id;
|
||||
}
|
||||
|
||||
// TODO yield thread, need a stable priority queue in the scheduler
|
||||
|
||||
void Multilibultra::set_self_paused(RDRAM_ARG1) {
|
||||
|
|
|
@ -149,7 +149,11 @@ typedef void (thread_func_t)(PTR(void));
|
|||
|
||||
void osCreateThread(RDRAM_ARG PTR(OSThread) t, OSId id, PTR(thread_func_t) entry, PTR(void) arg, PTR(void) sp, OSPri p);
|
||||
void osStartThread(RDRAM_ARG PTR(OSThread) t);
|
||||
void osStopThread(RDRAM_ARG PTR(OSThread) t);
|
||||
void osDestroyThread(RDRAM_ARG PTR(OSThread) t);
|
||||
void osSetThreadPri(RDRAM_ARG PTR(OSThread) t, OSPri pri);
|
||||
OSPri osGetThreadPri(RDRAM_ARG PTR(OSThread) thread);
|
||||
OSId osGetThreadId(RDRAM_ARG PTR(OSThread) t);
|
||||
|
||||
s32 MQ_GET_COUNT(RDRAM_ARG PTR(OSMesgQueue));
|
||||
s32 MQ_IS_EMPTY(RDRAM_ARG PTR(OSMesgQueue));
|
||||
|
|
|
@ -54,6 +54,14 @@ extern "C" void osContGetReadData_recomp(uint8_t* restrict rdram, recomp_context
|
|||
MEM_B(4, pad) = 0;
|
||||
}
|
||||
|
||||
extern "C" void osContSetCh_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void __osMotorAccess_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
|
||||
}
|
||||
|
||||
extern "C" void osMotorInit_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
|
80
test/src/math_routines.cpp
Normal file
80
test/src/math_routines.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
#include "../portultra/multilibultra.hpp"
|
||||
#include "recomp.h"
|
||||
|
||||
|
||||
extern "C" void __udivdi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
uint64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
uint64_t ret = a / b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __divdi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
int64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
int64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
int64_t ret = a / b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __umoddi3_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
uint64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
uint64_t ret = a % b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __ull_div_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
uint64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
uint64_t ret = a / b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __ll_div_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
int64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
int64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
int64_t ret = a / b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __ll_mul_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
uint64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
uint64_t ret = a * b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __ull_rem_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
uint64_t b = (ctx->r6 << 32) | (ctx->r7 << 0);
|
||||
uint64_t ret = a % b;
|
||||
|
||||
ctx->r2 = (int32_t)(ret >> 32);
|
||||
ctx->r3 = (int32_t)(ret >> 0);
|
||||
}
|
||||
|
||||
extern "C" void __ull_to_d_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
double ret = (double)a;
|
||||
|
||||
ctx->f0.d = ret;
|
||||
}
|
||||
|
||||
extern "C" void __ull_to_f_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
uint64_t a = (ctx->r4 << 32) | (ctx->r5 << 0);
|
||||
float ret = (float)a;
|
||||
|
||||
ctx->f0.fl = ret;
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
#include <memory>
|
||||
#include "../portultra/ultra64.h"
|
||||
#include "../portultra/multilibultra.hpp"
|
||||
#include "recomp.h"
|
||||
|
||||
extern "C" void osInitialize_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
|
@ -10,40 +12,56 @@ extern "C" void __osInitialize_common_recomp(uint8_t * restrict rdram, recomp_co
|
|||
}
|
||||
|
||||
extern "C" void osCreateThread_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osCreateThread(rdram, (uint32_t)ctx->r4, (OSId)ctx->r5, (uint32_t)ctx->r6, (uint32_t)ctx->r7,
|
||||
(uint32_t)MEM_W(0x10, ctx->r29), (OSPri)MEM_W(0x14, ctx->r29));
|
||||
osCreateThread(rdram, (int32_t)ctx->r4, (OSId)ctx->r5, (int32_t)ctx->r6, (int32_t)ctx->r7,
|
||||
(int32_t)MEM_W(0x10, ctx->r29), (OSPri)MEM_W(0x14, ctx->r29));
|
||||
}
|
||||
|
||||
extern "C" void osStartThread_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osStartThread(rdram, (uint32_t)ctx->r4);
|
||||
osStartThread(rdram, (int32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osStopThread_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
osStopThread(rdram, (int32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osDestroyThread_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
osDestroyThread(rdram, (int32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osSetThreadPri_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osSetThreadPri(rdram, (uint32_t)ctx->r4, (OSPri)ctx->r5);
|
||||
osSetThreadPri(rdram, (int32_t)ctx->r4, (OSPri)ctx->r5);
|
||||
}
|
||||
|
||||
extern "C" void osGetThreadPri_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = osGetThreadPri(rdram, (int32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osGetThreadId_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = osGetThreadId(rdram, (int32_t)ctx->r4);
|
||||
}
|
||||
|
||||
extern "C" void osCreateMesgQueue_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osCreateMesgQueue(rdram, (uint32_t)ctx->r4, (uint32_t)ctx->r5, (s32)ctx->r6);
|
||||
osCreateMesgQueue(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osRecvMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osRecvMesg(rdram, (uint32_t)ctx->r4, (uint32_t)ctx->r5, (s32)ctx->r6);
|
||||
ctx->r2 = osRecvMesg(rdram, (int32_t)ctx->r4, (int32_t)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osSendMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osSendMesg(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
ctx->r2 = osSendMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osJamMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
ctx->r2 = osJamMesg(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
ctx->r2 = osJamMesg(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (s32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osSetEventMesg_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
osSetEventMesg(rdram, (OSEvent)ctx->r4, (uint32_t)ctx->r5, (OSMesg)ctx->r6);
|
||||
osSetEventMesg(rdram, (OSEvent)ctx->r4, (int32_t)ctx->r5, (OSMesg)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osViSetEvent_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
osViSetEvent(rdram, (uint32_t)ctx->r4, (OSMesg)ctx->r5, (u32)ctx->r6);
|
||||
osViSetEvent(rdram, (int32_t)ctx->r4, (OSMesg)ctx->r5, (u32)ctx->r6);
|
||||
}
|
||||
|
||||
extern "C" void osGetCount_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
|
@ -91,3 +109,77 @@ extern "C" void __osRestoreInt_recomp(uint8_t * restrict rdram, recomp_context *
|
|||
extern "C" void __osSetFpcCsr_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void __checkHardware_msp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void __checkHardware_kmc_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void __checkHardware_isv_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
ctx->r2 = 0;
|
||||
}
|
||||
|
||||
extern "C" void __osInitialize_msp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
}
|
||||
|
||||
extern "C" void __osInitialize_kmc_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
}
|
||||
|
||||
extern "C" void __osInitialize_isv_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
}
|
||||
|
||||
extern "C" void __osRdbSend_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
gpr buf = ctx->r4;
|
||||
size_t size = ctx->r5;
|
||||
u32 type = (u32)ctx->r6;
|
||||
std::unique_ptr<char[]> to_print = std::make_unique<char[]>(size);
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
to_print[i] = MEM_B(i, buf);
|
||||
}
|
||||
to_print[size] = '\x00';
|
||||
|
||||
fwrite(to_print.get(), 1, size, stdout);
|
||||
|
||||
ctx->r2 = size;
|
||||
}
|
||||
|
||||
// For the Mario Party games (not working)
|
||||
//extern "C" void longjmp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
// RecompJmpBuf* buf = TO_PTR(RecompJmpBuf, ctx->r4);
|
||||
//
|
||||
// // Check if this is a buffer that was set up with setjmp
|
||||
// if (buf->magic == SETJMP_MAGIC) {
|
||||
// // If so, longjmp to it
|
||||
// // Setjmp/longjmp does not work across threads, so verify that this buffer was made by this thread
|
||||
// assert(buf->owner == Multilibultra::this_thread());
|
||||
// longjmp(buf->storage->buffer, ctx->r5);
|
||||
// } else {
|
||||
// // Otherwise, check if it was one built manually by the game with $ra pointing to a function
|
||||
// gpr sp = MEM_W(0, ctx->r4);
|
||||
// gpr ra = MEM_W(4, ctx->r4);
|
||||
// ctx->r29 = sp;
|
||||
// recomp_func_t* target = LOOKUP_FUNC(ra);
|
||||
// if (target == nullptr) {
|
||||
// fprintf(stderr, "Failed to find function for manual longjmp\n");
|
||||
// std::quick_exit(EXIT_FAILURE);
|
||||
// }
|
||||
// target(rdram, ctx);
|
||||
//
|
||||
// // TODO kill this thread if the target function returns
|
||||
// assert(false);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//#undef setjmp_recomp
|
||||
//extern "C" void setjmp_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
// fprintf(stderr, "Program called setjmp_recomp\n");
|
||||
// std::quick_exit(EXIT_FAILURE);
|
||||
//}
|
||||
//
|
||||
//extern "C" int32_t osGetThreadEx(void) {
|
||||
// return Multilibultra::this_thread();
|
||||
//}
|
||||
|
|
|
@ -66,8 +66,6 @@ void do_rom_read(uint8_t* rdram, gpr ram_address, uint32_t dev_address, size_t n
|
|||
std::unique_ptr<uint8_t[]> rom;
|
||||
size_t rom_size;
|
||||
|
||||
uint64_t start_time;
|
||||
|
||||
// Recomp generation functions
|
||||
extern "C" void recomp_entrypoint(uint8_t * restrict rdram, recomp_context * restrict ctx);
|
||||
gpr get_entrypoint_address();
|
||||
|
@ -117,18 +115,6 @@ int main(int argc, char **argv) {
|
|||
func_map[funcs[i].first] = funcs[i].second;
|
||||
}
|
||||
|
||||
// TODO move this to a more appropriate place
|
||||
#ifdef _WIN32
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
|
||||
start_time = ((uint64_t)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set up stack pointer
|
||||
context.r29 = 0xFFFFFFFF803FFFF0u;
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "../portultra/multilibultra.hpp"
|
||||
#include "recomp.h"
|
||||
|
||||
extern "C" void osViSetYScale_recomp(uint8_t * restrict rdram, recomp_context * restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
||||
extern "C" void osCreateViManager_recomp(uint8_t* restrict rdram, recomp_context* restrict ctx) {
|
||||
;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue