From 2865ef758e8192fd561d0ad1083315ab8621ddf5 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 23 Oct 2023 15:03:05 -0400 Subject: [PATCH] Initial compile on linux --- Makefile | 80 +++++++++++++++++++++++++++++----------- include/recomp.h | 2 + include/rsp_vu.h | 5 +++ include/rt64_layer.h | 5 +++ portultra/events.cpp | 2 +- portultra/task_win32.cpp | 4 ++ portultra/threads.cpp | 38 ++++++++++++++++++- src/overlays.cpp | 5 +++ src/pi.cpp | 1 + src/recomp.cpp | 11 +++++- src/rt64_layer.cpp | 3 +- 11 files changed, 129 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 57a9d9e..8a9fbb2 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CONFIG ?= Debug LIB ?= 0 ifeq ($(CONFIG),Debug) -BUILD_DIR := build/debug +BUILD_DIR := build/Debug FUNC_OPTFLAGS := -Og -g -fno-strict-aliasing OPTFLAGS := -Og -g -fno-strict-aliasing # Static C runtime linking @@ -10,21 +10,56 @@ LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultl # Dynamic # LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultlib:libucrt -lmsvcrtd -lvcruntimed -lucrtd else ifeq ($(CONFIG),Release) -BUILD_DIR := build/release +BUILD_DIR := build/Release FUNC_OPTFLAGS := -O2 -g -fno-strict-aliasing OPTFLAGS := -O2 -g -fno-strict-aliasing -# Static C runtime linking -LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultlib:libucrt -llibcmt -llibvcruntime -llibucrt -# Dynamic -# LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultlib:libucrt -lmsvcrt -lvcruntime -lucrt else $(error "Invalid build configuration: $(CONFIG)") endif +ifeq ($(OS),Windows_NT) +DYN_EXT := .dll +LIB_EXT := .lib +EXE_EXT := .exe +AR := clang++ +ARFLAGS := $(OPTFLAGS) -fuse-ld=llvm-lib -o +# Static C runtime linking +LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultlib:libucrt -llibcmt -llibvcruntime -llibucrt +# Dynamic +# LIBS := -Wl,/nodefaultlib:libcmt -Wl,/nodefaultlib:ucrt -Wl,/nodefaultlib:libucrt -lmsvcrt -lvcruntime -lucrt +LIB_DIR ?= C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64 +UCRT_DIR ?= C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64; +SDK_DIR ?= C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\um\x64 + define mkdir + mkdir $(subst /,\\,$(1)) + endef + define rmdir + rmdir /S /Q $(subst /,\\,$(1)) + endef +else +DYN_EXT := .so +LIB_EXT := .a +EXE_EXT := +LIB_PRE := lib +AR := ar +ARFLAGS := rcs + define mkdir + mkdir -p $(1) + endef + define rmdir + rm -rf $(1) + endef +endif + SRC_DIRS := portultra src rsp +# Add the main folder if not building a library +ifneq ($(LIB),1) +SRC_DIRS += src/main +endif + FUNCS_DIR := RecompiledFuncs -FUNCS_LIB := $(BUILD_DIR)/RecompiledFuncs.lib +FUNCS_LIB := $(BUILD_DIR)/$(LIB_PRE)RecompiledFuncs$(LIB_EXT) FUNCS_C_SRCS := $(wildcard $(FUNCS_DIR)/*.c) FUNCS_CXX_SRCS := $(wildcard $(FUNCS_DIR)/*.cpp) @@ -44,34 +79,37 @@ ALL_OBJS := $(C_OBJS) $(CXX_OBJS) CC := clang CXX := clang++ -LIB := clang++ LD := clang++ FUNC_CFLAGS := $(FUNC_OPTFLAGS) -c -Wno-unused-but-set-variable FUNC_CXXFLAGS := $(FUNC_OPTFLAGS) -std=c++20 -c FUNC_CPPFLAGS := -Iinclude -LIBFLAGS := $(OPTFLAGS) -fuse-ld=llvm-lib -LIB_DIR ?= C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64 -UCRT_DIR ?= C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\ucrt\x64; -SDK_DIR ?= C:\Program Files (x86)\Windows Kits\10\lib\10.0.22000.0\um\x64 WARNFLAGS := -Wall -Wextra -Wpedantic -Wno-gnu-anonymous-struct CFLAGS := -ffunction-sections -fdata-sections -march=nehalem $(OPTFLAGS) $(WARNFLAGS) -c CXXFLAGS := -ffunction-sections -fdata-sections -march=nehalem $(OPTFLAGS) $(WARNFLAGS) -std=c++20 -c CPPFLAGS := -Iinclude -Ithirdparty -LDFLAGS := -v -Wl,/OPT:REF $(OPTFLAGS) $(LIBS) -L"$(LIB_DIR:;=)" -L"$(UCRT_DIR:;=)" -L"$(SDK_DIR:;=)" lib/RT64/$(CONFIG)/RT64.lib + +ifeq ($(OS),Windows_NT) +LDFLAGS := -v -Wl,/OPT:REF $(OPTFLAGS) $(LIBS) -L"$(LIB_DIR:;=)" -L"$(UCRT_DIR:;=)" -L"$(SDK_DIR:;=)" lib/RT64/$(CONFIG)/RT64.lib +else +LDFLAGS := $(OPTFLAGS) -L$(BUILD_DIR) -lRecompiledFuncs -L. -lrt64 -lSDL2 -lX11 -Wl,--gc-sections +FUNC_CFLAGS += -ffunction-sections -fdata-sections +FUNC_CXXFLAGS += -ffunction-sections -fdata-sections +EXTRA_DEPS := librt64.a +endif ifeq ($(LIB),1) -TARGET := $(BUILD_DIR)/MMRecomp.dll +TARGET := $(BUILD_DIR)/MMRecomp$(DYN_EXT) LDFLAGS += -shared else -TARGET := $(BUILD_DIR)/MMRecomp.exe +TARGET := $(BUILD_DIR)/MMRecomp$(EXE_EXT) endif default: $(TARGET) -clean: - rmdir /S /Q $(subst /,\\,$(BUILD_DIR)) +clean: + $(call rmdir,$(BUILD_DIR)) cleanfuncs: @@ -83,7 +121,7 @@ $(FUNCS_C_OBJS) : $(BUILD_DIR)/%.o : %.c | $(FUNC_BUILD_DIR) @$(CC) $(FUNC_CFLAGS) $(FUNC_CPPFLAGS) $^ -o $@ $(FUNCS_LIB): $(ALL_FUNC_OBJS) | $(BUILD_DIR) - $(LIB) $(LIBFLAGS) $(FUNC_BUILD_DIR)/*.o -o $@ + $(AR) $(ARFLAGS) $@ $(FUNC_BUILD_DIR)/*.o @@ -93,11 +131,11 @@ $(CXX_OBJS) : $(BUILD_DIR)/%.o : %.cpp | $(BUILD_SRC_DIRS) $(C_OBJS) : $(BUILD_DIR)/%.o : %.c | $(BUILD_SRC_DIRS) $(CC) -MMD -MF $(@:.o=.d) $(CFLAGS) $(CPPFLAGS) $< -o $@ -$(TARGET): $(FUNCS_LIB) $(ALL_OBJS) | $(BUILD_SRC_DIRS) - $(LD) $(LDFLAGS) -o $@ $^ +$(TARGET): $(FUNCS_LIB) $(ALL_OBJS) $(EXTRA_DEPS) | $(BUILD_SRC_DIRS) + $(LD) -o $@ $^ $(LDFLAGS) $(BUILD_SRC_DIRS) $(FUNC_BUILD_DIR) $(BUILD_DIR): - mkdir $(subst /,\\,$@) + $(call mkdir,$@) -include $(ALL_OBJS:.o=.d) diff --git a/include/recomp.h b/include/recomp.h index e627a8c..b33645d 100644 --- a/include/recomp.h +++ b/include/recomp.h @@ -304,6 +304,8 @@ extern int32_t section_addresses[]; // ctx->r2 = setjmp(buf->storage->buffer); \ //} +void pause_self(uint8_t *rdram); + #ifdef __cplusplus } #endif diff --git a/include/rsp_vu.h b/include/rsp_vu.h index d60e62f..8be1b1c 100644 --- a/include/rsp_vu.h +++ b/include/rsp_vu.h @@ -58,6 +58,11 @@ template inline auto sclamp(s64 x) -> s64 { return (x > m) ? m : (x < -b) ? -b : x; } +template 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; diff --git a/include/rt64_layer.h b/include/rt64_layer.h index b38d4f1..c334c1c 100644 --- a/include/rt64_layer.h +++ b/include/rt64_layer.h @@ -45,9 +45,14 @@ typedef struct { // const unsigned int* RDRAM_SIZE; } GFX_INFO; +#ifdef _WIN32 #define DLLEXPORT extern "C" __declspec(dllexport) #define DLLIMPORT extern "C" __declspec(dllimport) #define CALL __cdecl +#else +#define DLLEXPORT extern "C" __attribute__((visibility("default"))) +#define DLLIMPORT extern "C" +#endif // Dynamic loading //DLLEXPORT int (CALL *InitiateGFX)(GFX_INFO Gfx_Info) = nullptr; diff --git a/portultra/events.cpp b/portultra/events.cpp index 51de43a..eb8686f 100644 --- a/portultra/events.cpp +++ b/portultra/events.cpp @@ -7,8 +7,8 @@ #include #include #include +#include -#include #include "blockingconcurrentqueue.h" #include "ultra64.h" diff --git a/portultra/task_win32.cpp b/portultra/task_win32.cpp index 86159a9..7f6d8fe 100644 --- a/portultra/task_win32.cpp +++ b/portultra/task_win32.cpp @@ -1,3 +1,5 @@ +#ifdef _WIN32 + #include #include "ultra64.h" @@ -7,3 +9,5 @@ extern "C" unsigned int sleep(unsigned int seconds) { Sleep(seconds * 1000); return 0; } + +#endif \ No newline at end of file diff --git a/portultra/threads.cpp b/portultra/threads.cpp index 6d8f273..b8891e4 100644 --- a/portultra/threads.cpp +++ b/portultra/threads.cpp @@ -7,8 +7,10 @@ #include "multilibultra.hpp" // Native APIs only used to set thread names for easier debugging -#ifdef _WIN32 +#if defined(_WIN32) #include +#elif defined(__linux__) +#include #endif extern "C" void bootproc(); @@ -43,7 +45,7 @@ void run_thread_function(uint8_t* rdram, uint64_t addr, uint64_t sp, uint64_t ar struct thread_terminated : std::exception {}; -#ifdef _WIN32 +#if defined(_WIN32) void Multilibultra::set_native_thread_name(const std::string& name) { std::wstring wname{name.begin(), name.end()}; @@ -80,6 +82,38 @@ void Multilibultra::set_native_thread_priority(ThreadPriority pri) { } // SetThreadPriority(GetCurrentThread(), nPriority); } +#elif defined(__linux__) +void Multilibultra::set_native_thread_name(const std::string& name) { + pthread_setname_np(pthread_self(), name.c_str()); +} + +void Multilibultra::set_native_thread_priority(ThreadPriority pri) { + // TODO linux thread priority + printf("set_native_thread_priority unimplemented\n"); + // int nPriority = THREAD_PRIORITY_NORMAL; + + // // Convert ThreadPriority to Win32 priority + // switch (pri) { + // case ThreadPriority::Low: + // nPriority = THREAD_PRIORITY_BELOW_NORMAL; + // break; + // case ThreadPriority::Normal: + // nPriority = THREAD_PRIORITY_NORMAL; + // break; + // case ThreadPriority::High: + // nPriority = THREAD_PRIORITY_ABOVE_NORMAL; + // break; + // case ThreadPriority::VeryHigh: + // nPriority = THREAD_PRIORITY_HIGHEST; + // break; + // case ThreadPriority::Critical: + // nPriority = THREAD_PRIORITY_TIME_CRITICAL; + // break; + // default: + // throw std::runtime_error("Invalid thread priority!"); + // break; + // } +} #endif static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entrypoint, PTR(void) arg) { diff --git a/src/overlays.cpp b/src/overlays.cpp index 23f6eea..fb3d9f7 100644 --- a/src/overlays.cpp +++ b/src/overlays.cpp @@ -12,6 +12,11 @@ struct LoadedSection { int32_t loaded_ram_addr; size_t section_table_index; + LoadedSection(int32_t loaded_ram_addr_, size_t section_table_index_) { + loaded_ram_addr = loaded_ram_addr_; + section_table_index = section_table_index_; + } + bool operator<(const LoadedSection& rhs) { return loaded_ram_addr < rhs.loaded_ram_addr; } diff --git a/src/pi.cpp b/src/pi.cpp index 7ebf868..86366d8 100644 --- a/src/pi.cpp +++ b/src/pi.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "recomp.h" #include "../portultra/ultra64.h" #include "../portultra/multilibultra.hpp" diff --git a/src/recomp.cpp b/src/recomp.cpp index 220211a..6c8de60 100644 --- a/src/recomp.cpp +++ b/src/recomp.cpp @@ -3,6 +3,7 @@ #endif #include #include +#include #include #include #include @@ -11,6 +12,12 @@ #include "recomp.h" #include "../portultra/multilibultra.hpp" +#ifdef _WIN32 +#define EXPORT __declspec(dllexport) +#else +#define EXPORT __attribute__((visibility("default"))) +#endif + #ifdef _MSC_VER inline uint32_t byteswap(uint32_t val) { return _byteswap_ulong(val); @@ -72,7 +79,7 @@ extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); std::unique_ptr rdram_buffer; recomp_context context{}; -__declspec(dllexport) extern "C" void init() { +EXPORT extern "C" void init() { { std::basic_ifstream rom_file{ get_rom_name(), std::ios::binary }; @@ -133,7 +140,7 @@ __declspec(dllexport) extern "C" void init() { MEM_W(osMemSize, 0) = 8 * 1024 * 1024; // 8MB } -__declspec(dllexport) extern "C" void start(void* window_handle, const Multilibultra::audio_callbacks_t* audio_callbacks, const Multilibultra::input_callbacks_t* input_callbacks) { +EXPORT extern "C" void start(void* window_handle, const Multilibultra::audio_callbacks_t* audio_callbacks, const Multilibultra::input_callbacks_t* input_callbacks) { Multilibultra::set_audio_callbacks(audio_callbacks); Multilibultra::set_input_callbacks(input_callbacks); std::thread game_thread{[](void* window_handle) { diff --git a/src/rt64_layer.cpp b/src/rt64_layer.cpp index 192183b..a101b39 100644 --- a/src/rt64_layer.cpp +++ b/src/rt64_layer.cpp @@ -1,5 +1,6 @@ #include -#include +#include +// #include #include "../portultra/multilibultra.hpp" #include "rt64_layer.h"