Merge branch 'develop-zhora' of https://github.com/HarbourMasters/Shipwright into get-item-rework

This commit is contained in:
Christopher Leggett 2022-08-07 16:24:59 -04:00
commit 7516725f13
No known key found for this signature in database
GPG Key ID: 7093AE5FF7037D79
12 changed files with 102 additions and 84 deletions

3
.gitignore vendored
View File

@ -441,4 +441,5 @@ compile_commands.json
CTestTestfile.cmake CTestTestfile.cmake
_deps _deps
*/extract_assets_cmake* */extract_assets_cmake*
/build* /build*
build.c

View File

@ -30,8 +30,8 @@ With the cmake build system you have two options for working on the project:
#### Visual Studio #### Visual Studio
To develop using Visual Studio you only need to use cmake to generate the solution file: To develop using Visual Studio you only need to use cmake to generate the solution file:
```powershell ```powershell
# Generates Ship.sln at the root directory # Generates Ship.sln at `build/x64`
& 'C:\Program Files\CMake\bin\cmake' -S . -G "Visual Studio 17 2022" -T v142 -A x64 & 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v142 -A x64
``` ```
#### Visual Studio Code or another editor #### Visual Studio Code or another editor
@ -53,7 +53,7 @@ cd "build/x64"
``` ```
## Linux ## Linux
1. Requires `gcc, x11, curl, python3, sdl2, libpng, glew, ninja, cmake` 1. Requires `gcc >= 10, x11, curl, python3, sdl2 >= 2.0.22, libpng, glew >= 2.2, ninja, cmake, lld`
**Important: For maximum performance make sure you have ninja build tools installed!** **Important: For maximum performance make sure you have ninja build tools installed!**

View File

@ -20,6 +20,9 @@ add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows") if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
include(cmake/automate-vcpkg.cmake) include(cmake/automate-vcpkg.cmake)
set(VCPKG_TRIPLET x64-windows-static)
set(VCPKG_TARGET_TRIPLET x64-windows-static)
vcpkg_bootstrap() vcpkg_bootstrap()
vcpkg_install_packages(zlib bzip2 libpng) vcpkg_install_packages(zlib bzip2 libpng)
endif() endif()
@ -140,6 +143,7 @@ add_custom_target(
COMMAND ${CMAKE_COMMAND} -E rm -f oot.otr COMMAND ${CMAKE_COMMAND} -E rm -f oot.otr
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets_cmake2.py COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets_cmake2.py
COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_SOURCE_DIR} COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_BINARY_DIR}/soh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
COMMENT "Running asset extraction..." COMMENT "Running asset extraction..."
DEPENDS ZAPD DEPENDS ZAPD

View File

@ -46,7 +46,8 @@ RUN curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz && \
cd SDL2-${SDL2VER} && \ cd SDL2-${SDL2VER} && \
./configure --build=x86_64-linux-gnu && \ ./configure --build=x86_64-linux-gnu && \
make -j$(nproc) && make install && \ make -j$(nproc) && make install && \
rm ../SDL2-${SDL2VER}.tar.gz rm ../SDL2-${SDL2VER}.tar.gz && \
cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
RUN \ RUN \
ln -sf /proc/self/mounts /etc/mtab && \ ln -sf /proc/self/mounts /etc/mtab && \

View File

@ -456,6 +456,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
"NDEBUG" "NDEBUG"
">" ">"
"ENABLE_OPENGL;" "ENABLE_OPENGL;"
"SPDLOG_ACTIVE_LEVEL=0;"
) )
endif() endif()
################################################################################ ################################################################################

View File

@ -239,8 +239,8 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par
dxgi.current_height = (uint32_t)(l_param >> 16); dxgi.current_height = (uint32_t)(l_param >> 16);
break; break;
case WM_DESTROY: case WM_DESTROY:
Ship::ExecuteHooks<Ship::ExitGame>(); PostQuitMessage(0);
exit(0); break;
case WM_PAINT: case WM_PAINT:
if (dxgi.in_paint) { if (dxgi.in_paint) {
dxgi.recursive_paint_detected = true; dxgi.recursive_paint_detected = true;
@ -378,6 +378,8 @@ static void gfx_dxgi_main_loop(void (*run_one_game_iter)(void)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
Ship::ExecuteHooks<Ship::ExitGame>();
} }
static void gfx_dxgi_get_dimensions(uint32_t *width, uint32_t *height) { static void gfx_dxgi_get_dimensions(uint32_t *width, uint32_t *height) {

View File

@ -238,6 +238,8 @@ static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
Ship::Switch::Exit(); Ship::Switch::Exit();
#endif #endif
Ship::ExecuteHooks<Ship::ExitGame>(); Ship::ExecuteHooks<Ship::ExitGame>();
SDL_Quit();
} }
static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) { static void gfx_sdl_get_dimensions(uint32_t *width, uint32_t *height) {
@ -307,9 +309,8 @@ static void gfx_sdl_handle_events(void) {
CVar_Save(); CVar_Save();
break; break;
case SDL_QUIT: case SDL_QUIT:
Ship::ExecuteHooks<Ship::ExitGame>(); is_running = false;
SDL_Quit(); // bandaid fix for linux window closing issue break;
exit(0);
} }
} }
} }

View File

@ -1576,7 +1576,7 @@ set(ALL_FILES
################################################################################ ################################################################################
# Target # Target
################################################################################ ################################################################################
add_executable(${PROJECT_NAME} ${ALL_FILES}) add_executable(${PROJECT_NAME} ${ALL_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows") if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}") use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
@ -1996,13 +1996,16 @@ endif()
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch") if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch")
set_target_properties(soh PROPERTIES nx_generate_nacp(Ship.nacp
APP_TITLE "Ship of Harkirian" NAME "Ship of Harkinian"
APP_AUTHOR "Ship" AUTHOR "Harbour Masters"
APP_VERSION "3.0.0" VERSION "3.1.0"
ICON "icon.jpg") )
nx_create_nro(soh) nx_create_nro(soh
NACP Ship.nacp
ICON ${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg
)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.nro DESTINATION . COMPONENT ship) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/soh.nro DESTINATION . COMPONENT ship)

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
static struct { static struct {
std::thread thread;
std::condition_variable cv_to_thread, cv_from_thread; std::condition_variable cv_to_thread, cv_from_thread;
std::mutex mutex; std::mutex mutex;
bool initialized; bool running;
bool processing; bool processing;
} audio; } audio;

View File

@ -85,11 +85,73 @@ extern "C" void ResourceMgr_CacheDirectory(const char* resName);
extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path); extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path);
std::unordered_map<std::string, ExtensionEntry> ExtensionCache; std::unordered_map<std::string, ExtensionEntry> ExtensionCache;
void OTRAudio_Thread() {
while (audio.running) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing && audio.running) {
audio.cv_to_thread.wait(Lock);
}
if (!audio.running) {
break;
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
//AudioMgr_ThreadEntry(&gAudioMgr);
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
//#define SAMPLES_HIGH 560
//#define SAMPLES_LOW 528
// PAL values
//#define SAMPLES_HIGH 656
//#define SAMPLES_LOW 624
// 44KHZ values
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
// 3 is the maximum authentic frame divisor.
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}
// C->C++ Bridge // C->C++ Bridge
extern "C" void OTRAudio_Init() extern "C" void OTRAudio_Init()
{ {
// Precache all our samples, sequences, etc... // Precache all our samples, sequences, etc...
ResourceMgr_CacheDirectory("audio"); ResourceMgr_CacheDirectory("audio");
if (!audio.running) {
audio.running = true;
audio.thread = std::thread(OTRAudio_Thread);
}
}
extern "C" void OTRAudio_Exit() {
// Tell the audio thread to stop
{
std::unique_lock<std::mutex> Lock(audio.mutex);
audio.running = false;
}
audio.cv_to_thread.notify_all();
// Wait until the audio thread quit
audio.thread.join();
} }
extern "C" void VanillaItemTable_Init() { extern "C" void VanillaItemTable_Init() {
@ -267,6 +329,10 @@ extern "C" void InitOTR() {
VanillaItemTable_Init(); VanillaItemTable_Init();
} }
extern "C" void DeinitOTR() {
OTRAudio_Exit();
}
#ifdef _WIN32 #ifdef _WIN32
extern "C" uint64_t GetFrequency() { extern "C" uint64_t GetFrequency() {
LARGE_INTEGER nFreq; LARGE_INTEGER nFreq;
@ -366,56 +432,10 @@ extern "C" void Graph_StartFrame() {
// C->C++ Bridge // C->C++ Bridge
extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
#ifndef __SWITCH__
if (!audio.initialized) {
audio.initialized = true;
std::thread([]() {
for (;;) {
{
std::unique_lock<std::mutex> Lock(audio.mutex);
while (!audio.processing) {
audio.cv_to_thread.wait(Lock);
}
}
std::unique_lock<std::mutex> Lock(audio.mutex);
//AudioMgr_ThreadEntry(&gAudioMgr);
// 528 and 544 relate to 60 fps at 32 kHz 32000/60 = 533.333..
// in an ideal world, one third of the calls should use num_samples=544 and two thirds num_samples=528
//#define SAMPLES_HIGH 560
//#define SAMPLES_LOW 528
// PAL values
//#define SAMPLES_HIGH 656
//#define SAMPLES_LOW 624
// 44KHZ values
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
// 3 is the maximum authentic frame divisor.
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
audio.processing = false;
audio.cv_from_thread.notify_one();
}
}).detach();
}
{ {
std::unique_lock<std::mutex> Lock(audio.mutex); std::unique_lock<std::mutex> Lock(audio.mutex);
audio.processing = true; audio.processing = true;
} }
#endif
audio.cv_to_thread.notify_one(); audio.cv_to_thread.notify_one();
std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements; std::vector<std::unordered_map<Mtx*, MtxF>> mtx_replacements;
@ -458,14 +478,12 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
last_fps = fps; last_fps = fps;
last_update_rate = R_UPDATE_RATE; last_update_rate = R_UPDATE_RATE;
#ifndef __SWITCH__
{ {
std::unique_lock<std::mutex> Lock(audio.mutex); std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) { while (audio.processing) {
audio.cv_from_thread.wait(Lock); audio.cv_from_thread.wait(Lock);
} }
} }
#endif
// OTRTODO: FIGURE OUT END FRAME POINT // OTRTODO: FIGURE OUT END FRAME POINT
/* if (OTRGlobals::Instance->context->GetWindow()->lastScancode != -1) /* if (OTRGlobals::Instance->context->GetWindow()->lastScancode != -1)

View File

@ -481,22 +481,6 @@ static void RunFrame()
uint64_t ticksA, ticksB; uint64_t ticksA, ticksB;
ticksA = GetPerfCounter(); ticksA = GetPerfCounter();
#ifdef __SWITCH__
#define SAMPLES_HIGH 752
#define SAMPLES_LOW 720
#define AUDIO_FRAMES_PER_UPDATE (R_UPDATE_RATE > 0 ? R_UPDATE_RATE : 1 )
#define NUM_AUDIO_CHANNELS 2
int samples_left = AudioPlayer_Buffered();
u32 num_audio_samples = samples_left < AudioPlayer_GetDesiredBuffered() ? SAMPLES_HIGH : SAMPLES_LOW;
s16 audio_buffer[SAMPLES_HIGH * NUM_AUDIO_CHANNELS * 3];
for (int i = 0; i < AUDIO_FRAMES_PER_UPDATE; i++) {
AudioMgr_CreateNextAudioBuffer(audio_buffer + i * (num_audio_samples * NUM_AUDIO_CHANNELS), num_audio_samples);
}
AudioPlayer_Play((u8*)audio_buffer, num_audio_samples * (sizeof(int16_t) * NUM_AUDIO_CHANNELS * AUDIO_FRAMES_PER_UPDATE));
#endif
Graph_StartFrame(); Graph_StartFrame();
// TODO: Workaround for rumble being too long. Implement os thread functions. // TODO: Workaround for rumble being too long. Implement os thread functions.

View File

@ -36,12 +36,14 @@ void Main_LogSystemHeap(void) {
osSyncPrintf(VT_RST); osSyncPrintf(VT_RST);
} }
void main(int argc, char** argv) int main(int argc, char** argv)
{ {
GameConsole_Init(); GameConsole_Init();
InitOTR(); InitOTR();
BootCommands_Init(); BootCommands_Init();
Main(0); Main(0);
DeinitOTR();
return 0;
} }
void Main(void* arg) { void Main(void* arg) {