Merge develop into zelda64

This commit is contained in:
Kevin Alexis Contreras 2022-05-31 17:49:39 -05:00
commit 0067a69795
52 changed files with 2214 additions and 919 deletions

View file

@ -2,7 +2,7 @@
## Windows ## Windows
1. Install [Python](https://www.python.org/downloads/) >= 3.6. 1. Requires [Python](https://www.python.org/downloads/) >= 3.6.
2. Install [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/) 2. Install [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/)
3. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`. 3. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
4. Clone the Ship of Harkinian repository. 4. Clone the Ship of Harkinian repository.
@ -41,9 +41,9 @@ cp /usr/local/lib/libGLEW.a external
cd soh cd soh
# Extract the assets/Compile the exporter/Run the exporter # Extract the assets/Compile the exporter/Run the exporter
make setup -j$(nproc) OPTFLAGS=-O0 DEBUG=0 make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
# Compile the code # Compile the code
make -j $(nproc) OPTFLAGS=-O0 DEBUG=0 make -j $(nproc) OPTFLAGS=-O2 DEBUG=0
``` ```
# Compatible Roms # Compatible Roms
@ -57,10 +57,10 @@ OOT_PAL_GC_DBG1 checksum 0x871E1C92 (debug non-master quest)
The OTRExporter exports an `oot.otr` archive file which Ship of Harkinian requires to play. The OTRExporter exports an `oot.otr` archive file which Ship of Harkinian requires to play.
Use the `extract_assets.py` script file to run the exporter using any of the following methods: Use the `extract_assets.py` script file to run the exporter using any of the following methods:
1) Double click on the script after placing one or more roms in the directory.
2) Drag & Drop a rom onto the script.
3) In a terminal run `python3 extract_assets.py` after placing one or more roms in the directory.
4) In a terminal run `python3 extract_assets.py <path_to_rom>`
1. Double click on the script after placing one or more roms in the directory. If the script finds multiple roms the user is prompted which to use. Selection is done using the number keys and then pressing the carriage return key.
2. Drag & Drop a rom onto the script.
3. In a terminal run `python3 extract_assets.py` after placing one or more roms in the directory.
4. In a terminal run `python3 extract_assets.py <path_to_rom>`
If the script finds multiple roms the user is prompted which to use. Selection is done using the number keys and then pressing the carriage return key.

View file

@ -12,13 +12,15 @@ The Ship does not include assets and as such requires a prior copy of the game t
4) Launch `soh.exe` 4) Launch `soh.exe`
### Supported Games ### Supported Games
Ocarina of Time Debug (not Master Quest) #### Ocarina of Time Debug (not Master Quest)
> Currently the recommended option
``` ```
Build team: `zelda@srd022j` Build team: `zelda@srd022j`
Build date: `03-02-21 00:49:18` (year-month-day) Build date: `03-02-21 00:49:18` (year-month-day)
sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099 sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099
``` ```
Ocarina of Time PAL GameCube #### Ocarina of Time PAL GameCube
> May lead to crashes and instability
``` ```
sha1: 0227d7c0074f2d0ac935631990da8ec5914597b4 sha1: 0227d7c0074f2d0ac935631990da8ec5914597b4
``` ```
@ -64,6 +66,9 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
- Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe - Affirm that you have an `/assets` folder filled with XMLs in the same directory as OTRGui.exe
- Affirm that `zapd.exe` exists in the `/assets/extractor` folder - Affirm that `zapd.exe` exists in the `/assets/extractor` folder
## Nightly Builds
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
## The Harbour Masters Are... ## The Harbour Masters Are...
@ -108,4 +113,4 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
Amphibibro | Link Amphibibro | Link
AceHeart | Zelda AceHeart | Zelda
###### Lemons ###### Lemons

View file

@ -204,7 +204,7 @@ namespace Ship {
return true; return true;
} }
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) { std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) const {
auto fileList = std::vector<SFILE_FIND_DATA>(); auto fileList = std::vector<SFILE_FIND_DATA>();
SFILE_FIND_DATA findContext; SFILE_FIND_DATA findContext;
HANDLE hFind; HANDLE hFind;
@ -248,7 +248,7 @@ namespace Ship {
return fileList; return fileList;
} }
bool Archive::HasFile(const std::string& filename) { bool Archive::HasFile(const std::string& filename) const {
bool result = false; bool result = false;
auto start = std::chrono::steady_clock::now(); auto start = std::chrono::steady_clock::now();
@ -267,8 +267,9 @@ namespace Ship {
return result; return result;
} }
std::string Archive::HashToString(uint64_t hash) { const std::string* Archive::HashToString(uint64_t hash) const {
return hashes[hash]; auto it = hashes.find(hash);
return it != hashes.end() ? &it->second : nullptr;
} }
bool Archive::Load(bool enableWriting, bool genCRCMap) { bool Archive::Load(bool enableWriting, bool genCRCMap) {

View file

@ -34,9 +34,9 @@ namespace Ship
bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize); bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize);
bool RemoveFile(const std::string& path); bool RemoveFile(const std::string& path);
bool RenameFile(const std::string& oldPath, const std::string& newPath); bool RenameFile(const std::string& oldPath, const std::string& newPath);
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask); std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask) const;
bool HasFile(const std::string& searchMask); bool HasFile(const std::string& searchMask) const;
std::string HashToString(uint64_t hash); const std::string* HashToString(uint64_t hash) const;
protected: protected:
bool Load(bool enableWriting, bool genCRCMap); bool Load(bool enableWriting, bool genCRCMap);
bool Unload(); bool Unload();

View file

@ -54,14 +54,12 @@ namespace Game {
} }
void InitSettings() { void InitSettings() {
ModInternal::registerHookListener({ AUDIO_INIT, [](HookEvent ev) { ModInternal::RegisterHook<ModInternal::AudioInit>(UpdateAudio);
UpdateAudio(); ModInternal::RegisterHook<ModInternal::GfxInit>([] {
}});
ModInternal::registerHookListener({ GFX_INIT, [](HookEvent ev) {
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", THREE_POINT)); gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", THREE_POINT));
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0); SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
UpdateAudio(); UpdateAudio();
}}); });
} }
void SetSeqPlayerVolume(SeqPlayers playerId, float volume) { void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {

View file

@ -96,7 +96,6 @@ static struct {
uint32_t msaa_num_quality_levels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT]; uint32_t msaa_num_quality_levels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT];
ComPtr<ID3D11Device> device; ComPtr<ID3D11Device> device;
ComPtr<IDXGISwapChain1> swap_chain;
ComPtr<ID3D11DeviceContext> context; ComPtr<ID3D11DeviceContext> context;
ComPtr<ID3D11RasterizerState> rasterizer_state; ComPtr<ID3D11RasterizerState> rasterizer_state;
ComPtr<ID3D11DepthStencilState> depth_stencil_state; ComPtr<ID3D11DepthStencilState> depth_stencil_state;
@ -252,7 +251,24 @@ static void gfx_d3d11_init(void) {
}); });
// Create the swap chain // Create the swap chain
d3d.swap_chain = gfx_dxgi_create_swap_chain(d3d.device.Get()); gfx_dxgi_create_swap_chain(d3d.device.Get(), []() {
d3d.framebuffers[0].render_target_view.Reset();
d3d.textures[d3d.framebuffers[0].texture_id].texture.Reset();
d3d.context->ClearState();
d3d.context->Flush();
d3d.last_shader_program = nullptr;
d3d.last_vertex_buffer_stride = 0;
d3d.last_blend_state.Reset();
d3d.last_resource_views[0].Reset();
d3d.last_resource_views[1].Reset();
d3d.last_sampler_states[0].Reset();
d3d.last_sampler_states[1].Reset();
d3d.last_depth_test = -1;
d3d.last_depth_mask = -1;
d3d.last_zmode_decal = -1;
d3d.last_primitive_topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
});
// Create D3D Debug device if in debug mode // Create D3D Debug device if in debug mode
@ -266,7 +282,7 @@ static void gfx_d3d11_init(void) {
// Check the size of the window // Check the size of the window
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc; DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
ThrowIfFailed(d3d.swap_chain->GetDesc1(&swap_chain_desc)); ThrowIfFailed(gfx_dxgi_get_swap_chain()->GetDesc1(&swap_chain_desc));
d3d.textures[fb.texture_id].width = swap_chain_desc.Width; d3d.textures[fb.texture_id].width = swap_chain_desc.Width;
d3d.textures[fb.texture_id].height = swap_chain_desc.Height; d3d.textures[fb.texture_id].height = swap_chain_desc.Height;
fb.msaa_level = 1; fb.msaa_level = 1;
@ -303,8 +319,6 @@ static void gfx_d3d11_init(void) {
ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_frame_cb.GetAddressOf()), ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_frame_cb.GetAddressOf()),
gfx_dxgi_get_h_wnd(), "Failed to create per-frame constant buffer."); gfx_dxgi_get_h_wnd(), "Failed to create per-frame constant buffer.");
d3d.context->PSSetConstantBuffers(0, 1, d3d.per_frame_cb.GetAddressOf());
// Create per-draw constant buffer // Create per-draw constant buffer
constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC; constant_buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
@ -316,8 +330,6 @@ static void gfx_d3d11_init(void) {
ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_draw_cb.GetAddressOf()), ThrowIfFailed(d3d.device->CreateBuffer(&constant_buffer_desc, nullptr, d3d.per_draw_cb.GetAddressOf()),
gfx_dxgi_get_h_wnd(), "Failed to create per-draw constant buffer."); gfx_dxgi_get_h_wnd(), "Failed to create per-draw constant buffer.");
d3d.context->PSSetConstantBuffers(1, 1, d3d.per_draw_cb.GetAddressOf());
// Create compute shader that can be used to retrieve depth buffer values // Create compute shader that can be used to retrieve depth buffer values
const char* shader_source = R"( const char* shader_source = R"(
@ -737,6 +749,8 @@ static void gfx_d3d11_on_resize(void) {
static void gfx_d3d11_start_frame(void) { static void gfx_d3d11_start_frame(void) {
// Set per-frame constant buffer // Set per-frame constant buffer
ID3D11Buffer* buffers[2] = { d3d.per_frame_cb.Get(), d3d.per_draw_cb.Get() };
d3d.context->PSSetConstantBuffers(0, 2, buffers);
d3d.per_frame_cb_data.noise_frame++; d3d.per_frame_cb_data.noise_frame++;
if (d3d.per_frame_cb_data.noise_frame > 150) { if (d3d.per_frame_cb_data.noise_frame > 150) {
@ -803,15 +817,16 @@ static void gfx_d3d11_update_framebuffer_parameters(int fb_id, uint32_t width, u
if (msaa_level <= 1) { if (msaa_level <= 1) {
ThrowIfFailed(d3d.device->CreateShaderResourceView(tex.texture.Get(), nullptr, tex.resource_view.ReleaseAndGetAddressOf())); ThrowIfFailed(d3d.device->CreateShaderResourceView(tex.texture.Get(), nullptr, tex.resource_view.ReleaseAndGetAddressOf()));
} }
} else if (diff) { } else if (diff || (render_target && tex.texture.Get() == nullptr)) {
DXGI_SWAP_CHAIN_DESC1 desc1; DXGI_SWAP_CHAIN_DESC1 desc1;
ThrowIfFailed(d3d.swap_chain->GetDesc1(&desc1)); IDXGISwapChain1* swap_chain = gfx_dxgi_get_swap_chain();
ThrowIfFailed(swap_chain->GetDesc1(&desc1));
if (desc1.Width != width || desc1.Height != height) { if (desc1.Width != width || desc1.Height != height) {
fb.render_target_view.Reset(); fb.render_target_view.Reset();
tex.texture.Reset(); tex.texture.Reset();
ThrowIfFailed(d3d.swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, desc1.Flags)); ThrowIfFailed(swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, desc1.Flags));
} }
ThrowIfFailed(d3d.swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)tex.texture.ReleaseAndGetAddressOf())); ThrowIfFailed(swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)tex.texture.ReleaseAndGetAddressOf()));
} }
if (render_target) { if (render_target) {
ThrowIfFailed(d3d.device->CreateRenderTargetView(tex.texture.Get(), nullptr, fb.render_target_view.ReleaseAndGetAddressOf())); ThrowIfFailed(d3d.device->CreateRenderTargetView(tex.texture.Get(), nullptr, fb.render_target_view.ReleaseAndGetAddressOf()));

View file

@ -34,15 +34,8 @@
#define WINCLASS_NAME L"N64GAME" #define WINCLASS_NAME L"N64GAME"
#define GFX_API_NAME "DirectX" #define GFX_API_NAME "DirectX"
#ifdef VERSION_EU #define FRAME_INTERVAL_NS_NUMERATOR 1000000000
#define FRAME_INTERVAL_US_NUMERATOR_ 60000 #define FRAME_INTERVAL_NS_DENOMINATOR (dxgi.target_fps)
#define FRAME_INTERVAL_US_DENOMINATOR 3
#else
#define FRAME_INTERVAL_US_NUMERATOR_ 50000
#define FRAME_INTERVAL_US_DENOMINATOR 3
#endif
#define FRAME_INTERVAL_US_NUMERATOR (FRAME_INTERVAL_US_NUMERATOR_ * dxgi.frame_divisor)
using namespace Microsoft::WRL; // For ComPtr using namespace Microsoft::WRL; // For ComPtr
@ -66,14 +59,19 @@ static struct {
ComPtr<IDXGIFactory2> factory; ComPtr<IDXGIFactory2> factory;
ComPtr<IDXGISwapChain1> swap_chain; ComPtr<IDXGISwapChain1> swap_chain;
HANDLE waitable_object; HANDLE waitable_object;
ComPtr<IUnknown> swap_chain_device; // D3D11 Device or D3D12 Command Queue
std::function<void()> before_destroy_swap_chain_fn;
uint64_t qpc_init, qpc_freq; uint64_t qpc_init, qpc_freq;
uint64_t frame_timestamp; // in units of 1/FRAME_INTERVAL_US_DENOMINATOR microseconds uint64_t frame_timestamp; // in units of 1/FRAME_INTERVAL_NS_DENOMINATOR nanoseconds
std::map<UINT, DXGI_FRAME_STATISTICS> frame_stats; std::map<UINT, DXGI_FRAME_STATISTICS> frame_stats;
std::set<std::pair<UINT, UINT>> pending_frame_stats; std::set<std::pair<UINT, UINT>> pending_frame_stats;
bool dropped_frame; bool dropped_frame;
bool zero_latency; bool zero_latency;
float detected_hz;
UINT length_in_vsync_frames; UINT length_in_vsync_frames;
uint32_t frame_divisor; uint32_t target_fps;
uint32_t maximum_frame_latency;
uint32_t applied_maximum_frame_latency;
HANDLE timer; HANDLE timer;
bool use_timer; bool use_timer;
LARGE_INTEGER previous_present_time; LARGE_INTEGER previous_present_time;
@ -143,6 +141,22 @@ static void run_as_dpi_aware(Fun f) {
} }
} }
static void apply_maximum_frame_latency(bool first) {
ComPtr<IDXGISwapChain2> swap_chain2;
if (dxgi.swap_chain->QueryInterface(__uuidof(IDXGISwapChain2), &swap_chain2) == S_OK) {
ThrowIfFailed(swap_chain2->SetMaximumFrameLatency(dxgi.maximum_frame_latency));
if (first) {
dxgi.waitable_object = swap_chain2->GetFrameLatencyWaitableObject();
WaitForSingleObject(dxgi.waitable_object, INFINITE);
}
} else {
ComPtr<IDXGIDevice1> device1;
ThrowIfFailed(dxgi.swap_chain->GetDevice(__uuidof(IDXGIDevice1), &device1));
ThrowIfFailed(device1->SetMaximumFrameLatency(dxgi.maximum_frame_latency));
}
dxgi.applied_maximum_frame_latency = dxgi.maximum_frame_latency;
}
static void toggle_borderless_window_full_screen(bool enable, bool call_callback) { static void toggle_borderless_window_full_screen(bool enable, bool call_callback) {
// Windows 7 + flip mode + waitable object can't go to exclusive fullscreen, // Windows 7 + flip mode + waitable object can't go to exclusive fullscreen,
// so do borderless instead. If DWM is enabled, this means we get one monitor // so do borderless instead. If DWM is enabled, this means we get one monitor
@ -271,7 +285,8 @@ void gfx_dxgi_init(const char *game_name, bool start_in_fullscreen) {
dxgi.qpc_init = qpc_init.QuadPart; dxgi.qpc_init = qpc_init.QuadPart;
dxgi.qpc_freq = qpc_freq.QuadPart; dxgi.qpc_freq = qpc_freq.QuadPart;
dxgi.frame_divisor = 1; dxgi.target_fps = 60;
dxgi.maximum_frame_latency = 1;
dxgi.timer = CreateWaitableTimer(nullptr, false, nullptr); dxgi.timer = CreateWaitableTimer(nullptr, false, nullptr);
// Prepare window title // Prepare window title
@ -367,8 +382,8 @@ static void gfx_dxgi_handle_events(void) {
}*/ }*/
} }
static uint64_t qpc_to_us(uint64_t qpc) { static uint64_t qpc_to_ns(uint64_t qpc) {
return qpc / dxgi.qpc_freq * 1000000 + qpc % dxgi.qpc_freq * 1000000 / dxgi.qpc_freq; return qpc / dxgi.qpc_freq * 1000000000 + qpc % dxgi.qpc_freq * 1000000000 / dxgi.qpc_freq;
} }
static uint64_t qpc_to_100ns(uint64_t qpc) { static uint64_t qpc_to_100ns(uint64_t qpc) {
@ -406,7 +421,7 @@ static bool gfx_dxgi_start_frame(void) {
dxgi.use_timer = false; dxgi.use_timer = false;
dxgi.frame_timestamp += FRAME_INTERVAL_US_NUMERATOR; dxgi.frame_timestamp += FRAME_INTERVAL_NS_NUMERATOR;
if (dxgi.frame_stats.size() >= 2) { if (dxgi.frame_stats.size() >= 2) {
DXGI_FRAME_STATISTICS *first = &dxgi.frame_stats.begin()->second; DXGI_FRAME_STATISTICS *first = &dxgi.frame_stats.begin()->second;
@ -421,14 +436,16 @@ static bool gfx_dxgi_start_frame(void) {
} }
double estimated_vsync_interval = (double)sync_qpc_diff / (double)sync_vsync_diff; double estimated_vsync_interval = (double)sync_qpc_diff / (double)sync_vsync_diff;
uint64_t estimated_vsync_interval_us = qpc_to_us(estimated_vsync_interval); uint64_t estimated_vsync_interval_ns = qpc_to_ns(estimated_vsync_interval);
//printf("Estimated vsync_interval: %d\n", (int)estimated_vsync_interval_us); //printf("Estimated vsync_interval: %d\n", (int)estimated_vsync_interval_ns);
if (estimated_vsync_interval_us < 2 || estimated_vsync_interval_us > 1000000) { if (estimated_vsync_interval_ns < 2000 || estimated_vsync_interval_ns > 1000000000) {
// Unreasonable, maybe a monitor change // Unreasonable, maybe a monitor change
estimated_vsync_interval_us = 16666; estimated_vsync_interval_ns = 16666666;
estimated_vsync_interval = estimated_vsync_interval_us * dxgi.qpc_freq / 1000000; estimated_vsync_interval = estimated_vsync_interval_ns * dxgi.qpc_freq / 1000000000;
} }
dxgi.detected_hz = (float)((double)1000000000 / (double)estimated_vsync_interval_ns);
UINT queued_vsyncs = 0; UINT queued_vsyncs = 0;
bool is_first = true; bool is_first = true;
for (const std::pair<UINT, UINT>& p : dxgi.pending_frame_stats) { for (const std::pair<UINT, UINT>& p : dxgi.pending_frame_stats) {
@ -440,21 +457,21 @@ static bool gfx_dxgi_start_frame(void) {
} }
uint64_t last_frame_present_end_qpc = (last->SyncQPCTime.QuadPart - dxgi.qpc_init) + estimated_vsync_interval * queued_vsyncs; uint64_t last_frame_present_end_qpc = (last->SyncQPCTime.QuadPart - dxgi.qpc_init) + estimated_vsync_interval * queued_vsyncs;
uint64_t last_end_us = qpc_to_us(last_frame_present_end_qpc); uint64_t last_end_ns = qpc_to_ns(last_frame_present_end_qpc);
double vsyncs_to_wait = (double)(int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) / estimated_vsync_interval_us; double vsyncs_to_wait = (double)(int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_NS_DENOMINATOR - last_end_ns) / estimated_vsync_interval_ns;
//printf("ts: %llu, last_end_us: %llu, Init v: %f\n", dxgi.frame_timestamp / 3, last_end_us, vsyncs_to_wait); //printf("ts: %llu, last_end_ns: %llu, Init v: %f\n", dxgi.frame_timestamp / 3, last_end_ns, vsyncs_to_wait);
if (vsyncs_to_wait <= 0) { if (vsyncs_to_wait <= 0) {
// Too late // Too late
if ((int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR - last_end_us) < -66666) { if ((int64_t)(dxgi.frame_timestamp / FRAME_INTERVAL_NS_DENOMINATOR - last_end_ns) < -66666666) {
// The application must have been paused or similar // The application must have been paused or similar
vsyncs_to_wait = round(((double)FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) / estimated_vsync_interval_us); vsyncs_to_wait = round(((double)FRAME_INTERVAL_NS_NUMERATOR / FRAME_INTERVAL_NS_DENOMINATOR) / estimated_vsync_interval_ns);
if (vsyncs_to_wait < 1) { if (vsyncs_to_wait < 1) {
vsyncs_to_wait = 1; vsyncs_to_wait = 1;
} }
dxgi.frame_timestamp = FRAME_INTERVAL_US_DENOMINATOR * (last_end_us + vsyncs_to_wait * estimated_vsync_interval_us); dxgi.frame_timestamp = FRAME_INTERVAL_NS_DENOMINATOR * (last_end_ns + vsyncs_to_wait * estimated_vsync_interval_ns);
} else { } else {
// Drop frame // Drop frame
//printf("Dropping frame\n"); //printf("Dropping frame\n");
@ -464,9 +481,9 @@ static bool gfx_dxgi_start_frame(void) {
} }
double orig_wait = vsyncs_to_wait; double orig_wait = vsyncs_to_wait;
if (floor(vsyncs_to_wait) != vsyncs_to_wait) { if (floor(vsyncs_to_wait) != vsyncs_to_wait) {
uint64_t left = last_end_us + floor(vsyncs_to_wait) * estimated_vsync_interval_us; uint64_t left = last_end_ns + floor(vsyncs_to_wait) * estimated_vsync_interval_ns;
uint64_t right = last_end_us + ceil(vsyncs_to_wait) * estimated_vsync_interval_us; uint64_t right = last_end_ns + ceil(vsyncs_to_wait) * estimated_vsync_interval_ns;
uint64_t adjusted_desired_time = dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR + (last_end_us + (FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR) > dxgi.frame_timestamp / FRAME_INTERVAL_US_DENOMINATOR ? 2000 : -2000); uint64_t adjusted_desired_time = dxgi.frame_timestamp / FRAME_INTERVAL_NS_DENOMINATOR + (last_end_ns + (FRAME_INTERVAL_NS_NUMERATOR / FRAME_INTERVAL_NS_DENOMINATOR) > dxgi.frame_timestamp / FRAME_INTERVAL_NS_DENOMINATOR ? 2000000 : -2000000);
int64_t diff_left = adjusted_desired_time - left; int64_t diff_left = adjusted_desired_time - left;
int64_t diff_right = right - adjusted_desired_time; int64_t diff_right = right - adjusted_desired_time;
if (diff_left < 0) { if (diff_left < 0) {
@ -506,7 +523,7 @@ static void gfx_dxgi_swap_buffers_begin(void) {
LARGE_INTEGER t; LARGE_INTEGER t;
if (dxgi.use_timer) { if (dxgi.use_timer) {
QueryPerformanceCounter(&t); QueryPerformanceCounter(&t);
int64_t next = qpc_to_100ns(dxgi.previous_present_time.QuadPart) + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; int64_t next = qpc_to_100ns(dxgi.previous_present_time.QuadPart) + FRAME_INTERVAL_NS_NUMERATOR / (FRAME_INTERVAL_NS_DENOMINATOR * 100);
int64_t left = next - qpc_to_100ns(t.QuadPart); int64_t left = next - qpc_to_100ns(t.QuadPart);
if (left > 0) { if (left > 0) {
LARGE_INTEGER li; LARGE_INTEGER li;
@ -531,6 +548,32 @@ static void gfx_dxgi_swap_buffers_end(void) {
QueryPerformanceCounter(&t0); QueryPerformanceCounter(&t0);
QueryPerformanceCounter(&t1); QueryPerformanceCounter(&t1);
if (dxgi.applied_maximum_frame_latency > dxgi.maximum_frame_latency) {
// There seems to be a bug that if latency is decreased, there is no effect of that operation, so recreate swap chain
if (dxgi.waitable_object != nullptr) {
if (!dxgi.dropped_frame) {
// Wait the last time on this swap chain
WaitForSingleObject(dxgi.waitable_object, INFINITE);
}
CloseHandle(dxgi.waitable_object);
dxgi.waitable_object = nullptr;
}
dxgi.before_destroy_swap_chain_fn();
dxgi.swap_chain.Reset();
gfx_dxgi_create_swap_chain(dxgi.swap_chain_device.Get(), move(dxgi.before_destroy_swap_chain_fn));
dxgi.frame_timestamp = 0;
dxgi.frame_stats.clear();
dxgi.pending_frame_stats.clear();
return; // Make sure we don't wait a second time on the waitable object, since that would hang the program
} else if (dxgi.applied_maximum_frame_latency != dxgi.maximum_frame_latency) {
apply_maximum_frame_latency(false);
}
if (!dxgi.dropped_frame) { if (!dxgi.dropped_frame) {
if (dxgi.waitable_object != nullptr) { if (dxgi.waitable_object != nullptr) {
WaitForSingleObject(dxgi.waitable_object, INFINITE); WaitForSingleObject(dxgi.waitable_object, INFINITE);
@ -554,8 +597,20 @@ static double gfx_dxgi_get_time(void) {
return (double)(t.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq; return (double)(t.QuadPart - dxgi.qpc_init) / dxgi.qpc_freq;
} }
static void gfx_dxgi_set_frame_divisor(int divisor) { static void gfx_dxgi_set_target_fps(int fps) {
dxgi.frame_divisor = divisor; uint32_t old_fps = dxgi.target_fps;
uint64_t t0 = dxgi.frame_timestamp / old_fps;
uint32_t t1 = dxgi.frame_timestamp % old_fps;
dxgi.target_fps = fps;
dxgi.frame_timestamp = t0 * dxgi.target_fps + t1 * dxgi.target_fps / old_fps;
}
static void gfx_dxgi_set_maximum_frame_latency(int latency) {
dxgi.maximum_frame_latency = latency;
}
static float gfx_dxgi_get_detected_hz() {
return dxgi.detected_hz;
} }
void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)) { void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)) {
@ -592,12 +647,12 @@ void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*crea
SetWindowTextW(dxgi.h_wnd, w_title); SetWindowTextW(dxgi.h_wnd, w_title);
} }
ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device) { void gfx_dxgi_create_swap_chain(IUnknown *device, std::function<void()>&& before_destroy_fn) {
bool win8 = IsWindows8OrGreater(); // DXGI_SCALING_NONE is only supported on Win8 and beyond bool win8 = IsWindows8OrGreater(); // DXGI_SCALING_NONE is only supported on Win8 and beyond
bool dxgi_13 = dxgi.CreateDXGIFactory2 != nullptr; // DXGI 1.3 introduced waitable object bool dxgi_13 = dxgi.CreateDXGIFactory2 != nullptr; // DXGI 1.3 introduced waitable object
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {}; DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
swap_chain_desc.BufferCount = 2; swap_chain_desc.BufferCount = 3;
swap_chain_desc.Width = 0; swap_chain_desc.Width = 0;
swap_chain_desc.Height = 0; swap_chain_desc.Height = 0;
swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
@ -617,28 +672,24 @@ ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device) {
}); });
ThrowIfFailed(dxgi.factory->MakeWindowAssociation(dxgi.h_wnd, DXGI_MWA_NO_ALT_ENTER)); ThrowIfFailed(dxgi.factory->MakeWindowAssociation(dxgi.h_wnd, DXGI_MWA_NO_ALT_ENTER));
ComPtr<IDXGISwapChain2> swap_chain2; apply_maximum_frame_latency(true);
if (dxgi.swap_chain->QueryInterface(__uuidof(IDXGISwapChain2), &swap_chain2) == S_OK) {
ThrowIfFailed(swap_chain2->SetMaximumFrameLatency(1));
dxgi.waitable_object = swap_chain2->GetFrameLatencyWaitableObject();
WaitForSingleObject(dxgi.waitable_object, INFINITE);
} else {
ComPtr<IDXGIDevice1> device1;
ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&device1)));
ThrowIfFailed(device1->SetMaximumFrameLatency(1));
}
ThrowIfFailed(dxgi.swap_chain->GetDesc1(&swap_chain_desc)); ThrowIfFailed(dxgi.swap_chain->GetDesc1(&swap_chain_desc));
dxgi.current_width = swap_chain_desc.Width; dxgi.current_width = swap_chain_desc.Width;
dxgi.current_height = swap_chain_desc.Height; dxgi.current_height = swap_chain_desc.Height;
return dxgi.swap_chain; dxgi.swap_chain_device = device;
dxgi.before_destroy_swap_chain_fn = std::move(before_destroy_fn);
} }
HWND gfx_dxgi_get_h_wnd(void) { HWND gfx_dxgi_get_h_wnd(void) {
return dxgi.h_wnd; return dxgi.h_wnd;
} }
IDXGISwapChain1* gfx_dxgi_get_swap_chain() {
return dxgi.swap_chain.Get();
}
void ThrowIfFailed(HRESULT res) { void ThrowIfFailed(HRESULT res) {
if (FAILED(res)) { if (FAILED(res)) {
fprintf(stderr, "Error: 0x%08X\n", res); fprintf(stderr, "Error: 0x%08X\n", res);
@ -668,7 +719,9 @@ extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = {
gfx_dxgi_swap_buffers_begin, gfx_dxgi_swap_buffers_begin,
gfx_dxgi_swap_buffers_end, gfx_dxgi_swap_buffers_end,
gfx_dxgi_get_time, gfx_dxgi_get_time,
gfx_dxgi_set_frame_divisor, gfx_dxgi_set_target_fps,
gfx_dxgi_set_maximum_frame_latency,
gfx_dxgi_get_detected_hz,
}; };
#endif #endif

View file

@ -4,9 +4,15 @@
#include "gfx_rendering_api.h" #include "gfx_rendering_api.h"
#ifdef DECLARE_GFX_DXGI_FUNCTIONS #ifdef DECLARE_GFX_DXGI_FUNCTIONS
#include <functional>
#include <dxgi1_2.h>
void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only)); void gfx_dxgi_create_factory_and_device(bool debug, int d3d_version, bool (*create_device_fn)(IDXGIAdapter1 *adapter, bool test_only));
Microsoft::WRL::ComPtr<IDXGISwapChain1> gfx_dxgi_create_swap_chain(IUnknown *device); void gfx_dxgi_create_swap_chain(IUnknown *device, std::function<void()>&& before_destroy_fn);
HWND gfx_dxgi_get_h_wnd(void); HWND gfx_dxgi_get_h_wnd(void);
IDXGISwapChain1* gfx_dxgi_get_swap_chain();
void ThrowIfFailed(HRESULT res); void ThrowIfFailed(HRESULT res);
void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message); void ThrowIfFailed(HRESULT res, HWND h_wnd, const char *message);
#endif #endif

View file

@ -36,7 +36,7 @@
// OTRTODO: fix header files for these // OTRTODO: fix header files for these
extern "C" { extern "C" {
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc); const char* ResourceMgr_GetNameByCRC(uint64_t crc);
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc); int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc);
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
@ -88,7 +88,7 @@ struct LoadedVertex {
static struct { static struct {
TextureCacheMap map; TextureCacheMap map;
list<TextureCacheMap::iterator> lru; list<TextureCacheMapIter> lru;
vector<uint32_t> free_texture_ids; vector<uint32_t> free_texture_ids;
} gfx_texture_cache; } gfx_texture_cache;
@ -134,14 +134,14 @@ static struct RDP {
const uint8_t *addr; const uint8_t *addr;
uint8_t siz; uint8_t siz;
uint32_t width; uint32_t width;
char* otr_path; const char* otr_path;
} texture_to_load; } texture_to_load;
struct { struct {
const uint8_t *addr; const uint8_t *addr;
uint32_t size_bytes; uint32_t size_bytes;
uint32_t full_image_line_size_bytes; uint32_t full_image_line_size_bytes;
uint32_t line_size_bytes; uint32_t line_size_bytes;
char* otr_path; const char* otr_path;
} loaded_texture[2]; } loaded_texture[2];
struct { struct {
uint8_t fmt; uint8_t fmt;
@ -527,18 +527,18 @@ static bool gfx_texture_cache_lookup(int i, int tile) {
key = { orig_addr, { }, fmt, siz, palette_index }; key = { orig_addr, { }, fmt, siz, palette_index };
} }
auto it = gfx_texture_cache.map.find(key); TextureCacheMap::iterator it = gfx_texture_cache.map.find(key);
if (it != gfx_texture_cache.map.end()) { if (it != gfx_texture_cache.map.end()) {
gfx_rapi->select_texture(i, it->second.texture_id); gfx_rapi->select_texture(i, it->second.texture_id);
*n = &*it; *n = &*it;
gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, *(list<TextureCacheMap::iterator>::iterator*)&it->second.lru_location); // move to back gfx_texture_cache.lru.splice(gfx_texture_cache.lru.end(), gfx_texture_cache.lru, it->second.lru_location); // move to back
return true; return true;
} }
if (gfx_texture_cache.map.size() >= TEXTURE_CACHE_MAX_SIZE) { if (gfx_texture_cache.map.size() >= TEXTURE_CACHE_MAX_SIZE) {
// Remove the texture that was least recently used // Remove the texture that was least recently used
it = gfx_texture_cache.lru.front(); it = gfx_texture_cache.lru.front().it;
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id); gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
gfx_texture_cache.map.erase(it); gfx_texture_cache.map.erase(it);
gfx_texture_cache.lru.pop_front(); gfx_texture_cache.lru.pop_front();
@ -555,7 +555,7 @@ static bool gfx_texture_cache_lookup(int i, int tile) {
it = gfx_texture_cache.map.insert(make_pair(key, TextureCacheValue())).first; it = gfx_texture_cache.map.insert(make_pair(key, TextureCacheValue())).first;
TextureCacheNode* node = &*it; TextureCacheNode* node = &*it;
node->second.texture_id = texture_id; node->second.texture_id = texture_id;
*(list<TextureCacheMap::iterator>::iterator*)&node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), it); node->second.lru_location = gfx_texture_cache.lru.insert(gfx_texture_cache.lru.end(), { it });
gfx_rapi->select_texture(i, texture_id); gfx_rapi->select_texture(i, texture_id);
gfx_rapi->set_sampler_parameters(i, false, 0, 0); gfx_rapi->set_sampler_parameters(i, false, 0, 0);
@ -571,7 +571,7 @@ static void gfx_texture_cache_delete(const uint8_t* orig_addr)
bool again = false; bool again = false;
for (auto it = gfx_texture_cache.map.begin(bucket); it != gfx_texture_cache.map.end(bucket); ++it) { for (auto it = gfx_texture_cache.map.begin(bucket); it != gfx_texture_cache.map.end(bucket); ++it) {
if (it->first.texture_addr == orig_addr) { if (it->first.texture_addr == orig_addr) {
gfx_texture_cache.lru.erase(*(list<TextureCacheMap::iterator>::iterator*)&it->second.lru_location); gfx_texture_cache.lru.erase(it->second.lru_location);
gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id); gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id);
gfx_texture_cache.map.erase(it->first); gfx_texture_cache.map.erase(it->first);
again = true; again = true;
@ -1636,11 +1636,11 @@ static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32
rdp.viewport_or_scissor_changed = true; rdp.viewport_or_scissor_changed = true;
} }
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, char* otr_path) { static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, const char* otr_path) {
rdp.texture_to_load.addr = (const uint8_t*)addr; rdp.texture_to_load.addr = (const uint8_t*)addr;
rdp.texture_to_load.siz = size; rdp.texture_to_load.siz = size;
rdp.texture_to_load.width = width; rdp.texture_to_load.width = width;
if ( otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7; if (otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7;
rdp.texture_to_load.otr_path = otr_path; rdp.texture_to_load.otr_path = otr_path;
} }
@ -2114,7 +2114,7 @@ static void gfx_run_dl(Gfx* cmd) {
//puts("dl"); //puts("dl");
int dummy = 0; int dummy = 0;
char dlName[128]; char dlName[128];
char fileName[128]; const char* fileName;
Gfx* dListStart = cmd; Gfx* dListStart = cmd;
uint64_t ourHash = -1; uint64_t ourHash = -1;
@ -2437,7 +2437,7 @@ static void gfx_run_dl(Gfx* cmd) {
uintptr_t addr = cmd->words.w1; uintptr_t addr = cmd->words.w1;
cmd++; cmd++;
uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + (uint64_t)cmd->words.w1; uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + (uint64_t)cmd->words.w1;
ResourceMgr_GetNameByCRC(hash, fileName); fileName = ResourceMgr_GetNameByCRC(hash);
#if _DEBUG && 0 #if _DEBUG && 0
char* tex = ResourceMgr_LoadTexByCRC(hash); char* tex = ResourceMgr_LoadTexByCRC(hash);
ResourceMgr_GetNameByCRC(hash, fileName); ResourceMgr_GetNameByCRC(hash, fileName);
@ -2710,9 +2710,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
//gfx_lookup_or_create_shader_program(precomp_shaders[i]); //gfx_lookup_or_create_shader_program(precomp_shaders[i]);
} }
ModInternal::bindHook(GFX_INIT); ModInternal::ExecuteHooks<ModInternal::GfxInit>();
ModInternal::initBindHook(0);
ModInternal::callBindHook(0);
} }
struct GfxRenderingAPI *gfx_get_current_rendering_api(void) { struct GfxRenderingAPI *gfx_get_current_rendering_api(void) {
@ -2791,6 +2789,9 @@ void gfx_run(Gfx *commands, const std::unordered_map<Mtx *, MtxF>& mtx_replaceme
gfx_rapi->start_frame(); gfx_rapi->start_frame();
gfx_rapi->start_draw_to_framebuffer(game_renders_to_framebuffer ? game_framebuffer : 0, (float)gfx_current_dimensions.height / SCREEN_HEIGHT); gfx_rapi->start_draw_to_framebuffer(game_renders_to_framebuffer ? game_framebuffer : 0, (float)gfx_current_dimensions.height / SCREEN_HEIGHT);
gfx_rapi->clear_framebuffer(); gfx_rapi->clear_framebuffer();
rdp.viewport_or_scissor_changed = true;
rendering_state.viewport = {};
rendering_state.scissor = {};
gfx_run_dl(commands); gfx_run_dl(commands);
gfx_flush(); gfx_flush();
SohUtils::saveEnvironmentVar("framebuffer", string()); SohUtils::saveEnvironmentVar("framebuffer", string());
@ -2827,8 +2828,16 @@ void gfx_end_frame(void) {
} }
} }
void gfx_set_framedivisor(int divisor) { void gfx_set_target_fps(int fps) {
gfx_wapi->set_frame_divisor(divisor); gfx_wapi->set_target_fps(fps);
}
void gfx_set_maximum_frame_latency(int latency) {
gfx_wapi->set_maximum_frame_latency(latency);
}
float gfx_get_detected_hz(void) {
return gfx_wapi->get_detected_hz();
} }
int gfx_create_framebuffer(uint32_t width, uint32_t height) { int gfx_create_framebuffer(uint32_t width, uint32_t height) {

View file

@ -46,12 +46,11 @@ struct TextureCacheValue {
uint8_t cms, cmt; uint8_t cms, cmt;
bool linear_filter; bool linear_filter;
// Old versions of libstdc++ fail to compile this std::list<struct TextureCacheMapIter>::iterator lru_location;
#ifdef _MSC_VER };
std::list<TextureCacheMap::iterator>::iterator lru_location;
#else struct TextureCacheMapIter {
std::list<int>::iterator lru_location; TextureCacheMap::iterator it;
#endif
}; };
extern "C" { extern "C" {
@ -68,7 +67,9 @@ struct GfxRenderingAPI* gfx_get_current_rendering_api(void);
void gfx_start_frame(void); void gfx_start_frame(void);
void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacements); void gfx_run(Gfx* commands, const std::unordered_map<Mtx*, MtxF>& mtx_replacements);
void gfx_end_frame(void); void gfx_end_frame(void);
void gfx_set_framedivisor(int); void gfx_set_target_fps(int);
void gfx_set_maximum_frame_latency(int latency);
float gfx_get_detected_hz(void);
void gfx_texture_cache_clear(); void gfx_texture_cache_clear();
extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height); extern "C" int gfx_create_framebuffer(uint32_t width, uint32_t height);
void gfx_get_pixel_depth_prepare(float x, float y); void gfx_get_pixel_depth_prepare(float x, float y);

View file

@ -123,11 +123,10 @@ static uint64_t previous_time;
static HANDLE timer; static HANDLE timer;
#endif #endif
static int frameDivisor = 1; static int target_fps = 60;
#define FRAME_INTERVAL_US_NUMERATOR_ 50000 #define FRAME_INTERVAL_US_NUMERATOR 1000000
#define FRAME_INTERVAL_US_DENOMINATOR 3 #define FRAME_INTERVAL_US_DENOMINATOR (target_fps)
#define FRAME_INTERVAL_US_NUMERATOR (FRAME_INTERVAL_US_NUMERATOR_ * frameDivisor)
static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) { static void gfx_sdl_init(const char *game_name, bool start_in_fullscreen) {
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
@ -250,6 +249,7 @@ static void gfx_sdl_handle_events(void) {
} }
break; break;
case SDL_QUIT: case SDL_QUIT:
SDL_Quit(); // bandaid fix for linux window closing issue
exit(0); exit(0);
} }
} }
@ -266,15 +266,16 @@ static uint64_t qpc_to_100ns(uint64_t qpc) {
static inline void sync_framerate_with_timer(void) { static inline void sync_framerate_with_timer(void) {
uint64_t t; uint64_t t;
t = SDL_GetPerformanceCounter(); t = qpc_to_100ns(SDL_GetPerformanceCounter());
const int64_t next = qpc_to_100ns(previous_time) + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR; const int64_t next = previous_time + 10 * FRAME_INTERVAL_US_NUMERATOR / FRAME_INTERVAL_US_DENOMINATOR;
const int64_t left = next - qpc_to_100ns(t); const int64_t left = next - t;
if (left > 0) { if (left > 0) {
#ifdef __linux__ #ifdef __linux__
const timespec spec = { 0, left * 100 }; const timespec spec = { 0, left * 100 };
nanosleep(&spec, nullptr); nanosleep(&spec, nullptr);
#else #else
// The accuracy of this timer seems to usually be within +- 1.0 ms
LARGE_INTEGER li; LARGE_INTEGER li;
li.QuadPart = -left; li.QuadPart = -left;
SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false); SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false);
@ -282,7 +283,13 @@ static inline void sync_framerate_with_timer(void) {
#endif #endif
} }
t = SDL_GetPerformanceCounter(); t = qpc_to_100ns(SDL_GetPerformanceCounter());
if (left > 0 && t - next < 10000) {
// In case it takes some time for the application to wake up after sleep,
// or inaccurate timer,
// don't let that slow down the framerate.
t = next;
}
previous_time = t; previous_time = t;
} }
@ -299,9 +306,16 @@ static double gfx_sdl_get_time(void) {
return 0.0; return 0.0;
} }
static void gfx_sdl_set_framedivisor(int divisor) static void gfx_sdl_set_target_fps(int fps) {
{ target_fps = fps;
frameDivisor = divisor; }
static void gfx_sdl_set_maximum_frame_latency(int latency) {
// Not supported by SDL :(
}
static float gfx_sdl_get_detected_hz(void) {
return 0;
} }
struct GfxWindowManagerAPI gfx_sdl = { struct GfxWindowManagerAPI gfx_sdl = {
@ -317,7 +331,9 @@ struct GfxWindowManagerAPI gfx_sdl = {
gfx_sdl_swap_buffers_begin, gfx_sdl_swap_buffers_begin,
gfx_sdl_swap_buffers_end, gfx_sdl_swap_buffers_end,
gfx_sdl_get_time, gfx_sdl_get_time,
gfx_sdl_set_framedivisor gfx_sdl_set_target_fps,
gfx_sdl_set_maximum_frame_latency,
gfx_sdl_get_detected_hz
}; };
#endif #endif

View file

@ -17,7 +17,9 @@ struct GfxWindowManagerAPI {
void (*swap_buffers_begin)(void); void (*swap_buffers_begin)(void);
void (*swap_buffers_end)(void); void (*swap_buffers_end)(void);
double (*get_time)(void); // For debug double (*get_time)(void); // For debug
void (*set_frame_divisor)(int); void (*set_target_fps)(int fps);
void (*set_maximum_frame_latency)(int latency);
float (*get_detected_hz)(void);
}; };
#endif #endif

View file

@ -40,8 +40,11 @@ namespace Ship
for (size_t i = 0; i < patches.size(); i++) for (size_t i = 0; i < patches.size(); i++)
{ {
std::string hashStr = resMgr->HashToString(patches[i].crc); const std::string* hashStr = resMgr->HashToString(patches[i].crc);
auto resShared = resMgr->GetCachedFile(hashStr); if (hashStr == nullptr)
continue;
auto resShared = resMgr->GetCachedFile(hashStr->c_str());
if (resShared != nullptr) if (resShared != nullptr)
{ {
auto res = (Ship::DisplayList*)resShared.get(); auto res = (Ship::DisplayList*)resShared.get();

View file

@ -215,7 +215,7 @@ namespace Ship {
return ToLoad; return ToLoad;
} }
std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(std::string FilePath) { std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(const char* FilePath) const {
auto resCacheFind = ResourceCache.find(FilePath); auto resCacheFind = ResourceCache.find(FilePath);
if (resCacheFind != ResourceCache.end() && if (resCacheFind != ResourceCache.end() &&
@ -227,8 +227,13 @@ namespace Ship {
return nullptr; return nullptr;
} }
std::shared_ptr<Resource> ResourceMgr::LoadResource(std::string FilePath) { std::shared_ptr<Resource> ResourceMgr::LoadResource(const char* FilePath) {
auto Promise = LoadResourceAsync(FilePath); auto Res = LoadResourceAsync(FilePath);
if (std::holds_alternative<std::shared_ptr<Resource>>(Res))
return std::get<std::shared_ptr<Resource>>(Res);
auto& Promise = std::get<std::shared_ptr<ResourcePromise>>(Res);
if (!Promise->bHasResourceLoaded) if (!Promise->bHasResourceLoaded)
{ {
@ -241,21 +246,18 @@ namespace Ship {
return Promise->resource; return Promise->resource;
} }
std::shared_ptr<ResourcePromise> ResourceMgr::LoadResourceAsync(std::string FilePath) { std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> ResourceMgr::LoadResourceAsync(const char* FilePath) {
StringHelper::ReplaceOriginal(FilePath, "\\", "/"); if (FilePath[0] == '_' && FilePath[1] == '_' && FilePath[2] == 'O' && FilePath[3] == 'T' && FilePath[4] == 'R' && FilePath[5] == '_' && FilePath[6] == '_')
FilePath += 7;
if (StringHelper::StartsWith(FilePath, "__OTR__"))
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex); const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex);
auto resCacheFind = ResourceCache.find(FilePath); auto resCacheFind = ResourceCache.find(FilePath);
if (resCacheFind == ResourceCache.end() || resCacheFind->second->isDirty/* || !FileData->bIsLoaded*/) { if (resCacheFind == ResourceCache.end() || resCacheFind->second->isDirty/* || !FileData->bIsLoaded*/) {
if (resCacheFind == ResourceCache.end()) { if (resCacheFind == ResourceCache.end()) {
SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath.c_str()); SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath);
} }
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
std::shared_ptr<File> FileData = LoadFile(FilePath); std::shared_ptr<File> FileData = LoadFile(FilePath);
Promise->file = FileData; Promise->file = FileData;
@ -269,12 +271,13 @@ namespace Ship {
ResourceLoadQueue.push(Promise); ResourceLoadQueue.push(Promise);
ResourceLoadNotifier.notify_all(); ResourceLoadNotifier.notify_all();
} }
} else {
Promise->bHasResourceLoaded = true;
Promise->resource = resCacheFind->second;
}
return Promise; return Promise;
}
else
{
return resCacheFind->second;
}
} }
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(std::string SearchMask) { std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(std::string SearchMask) {
@ -282,10 +285,15 @@ namespace Ship {
auto fileList = OTR->ListFiles(SearchMask); auto fileList = OTR->ListFiles(SearchMask);
for (DWORD i = 0; i < fileList.size(); i++) { for (DWORD i = 0; i < fileList.size(); i++) {
auto file = LoadResourceAsync(fileList.operator[](i).cFileName); auto resource = LoadResourceAsync(fileList.operator[](i).cFileName);
if (file != nullptr) { if (std::holds_alternative<std::shared_ptr<Resource>>(resource))
loadedList->push_back(file); {
auto promise = std::make_shared<ResourcePromise>();
promise->bHasResourceLoaded = true;
promise->resource = std::get<std::shared_ptr<Resource>>(resource);
resource = promise;
} }
loadedList->push_back(std::get<std::shared_ptr<ResourcePromise>>(resource));
} }
return loadedList; return loadedList;
@ -335,7 +343,7 @@ namespace Ship {
ResourceCache.clear(); ResourceCache.clear();
} }
std::string ResourceMgr::HashToString(uint64_t Hash) { const std::string* ResourceMgr::HashToString(uint64_t Hash) const {
return OTR->HashToString(Hash); return OTR->HashToString(Hash);
} }
} }

View file

@ -4,6 +4,7 @@
#include <string> #include <string>
#include <thread> #include <thread>
#include <queue> #include <queue>
#include <variant>
#include "Resource.h" #include "Resource.h"
#include "GlobalCtx2.h" #include "GlobalCtx2.h"
@ -25,7 +26,7 @@ namespace Ship
std::shared_ptr<Archive> GetArchive() { return OTR; } std::shared_ptr<Archive> GetArchive() { return OTR; }
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); } std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
std::string HashToString(uint64_t Hash); const std::string* HashToString(uint64_t Hash) const;
void InvalidateResourceCache(); void InvalidateResourceCache();
@ -33,9 +34,10 @@ namespace Ship
void SetGameVersion(uint32_t newGameVersion); void SetGameVersion(uint32_t newGameVersion);
std::shared_ptr<File> LoadFileAsync(std::string FilePath); std::shared_ptr<File> LoadFileAsync(std::string FilePath);
std::shared_ptr<File> LoadFile(std::string FilePath); std::shared_ptr<File> LoadFile(std::string FilePath);
std::shared_ptr<Ship::Resource> GetCachedFile(std::string FilePath); std::shared_ptr<Ship::Resource> GetCachedFile(const char* FilePath) const;
std::shared_ptr<Resource> LoadResource(std::string FilePath); std::shared_ptr<Resource> LoadResource(const char* FilePath);
std::shared_ptr<ResourcePromise> LoadResourceAsync(std::string FilePath); std::shared_ptr<Resource> LoadResource(const std::string& FilePath) { return LoadResource(FilePath.c_str()); }
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> LoadResourceAsync(const char* FilePath);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(std::string SearchMask); std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(std::string SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(std::string SearchMask); std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(std::string SearchMask);
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask); std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
@ -50,7 +52,7 @@ namespace Ship
std::weak_ptr<GlobalCtx2> Context; std::weak_ptr<GlobalCtx2> Context;
volatile bool bIsRunning; volatile bool bIsRunning;
std::map<std::string, std::shared_ptr<File>> FileCache; std::map<std::string, std::shared_ptr<File>> FileCache;
std::map<std::string, std::shared_ptr<Resource>> ResourceCache; std::map<std::string, std::shared_ptr<Resource>, std::less<>> ResourceCache;
std::queue<std::shared_ptr<File>> FileLoadQueue; std::queue<std::shared_ptr<File>> FileLoadQueue;
std::queue<std::shared_ptr<ResourcePromise>> ResourceLoadQueue; std::queue<std::shared_ptr<ResourcePromise>> ResourceLoadQueue;
std::shared_ptr<Archive> OTR; std::shared_ptr<Archive> OTR;

View file

@ -5,121 +5,6 @@
#include <stdarg.h> #include <stdarg.h>
#include <iostream> #include <iostream>
std::map<std::string, std::vector<HookFunc>> listeners; void ModInternal_ExecuteAudioInitHooks() {
std::string hookName; ModInternal::ExecuteHooks<ModInternal::AudioInit>();
std::map<std::string, void*> initArgs;
std::map<std::string, void*> hookArgs;
/*
#############################
Module: Hook C++ Handle
#############################
*/
namespace ModInternal {
void registerHookListener(HookListener listener) {
listeners[listener.hookName].push_back(listener.callback);
}
bool handleHook(std::shared_ptr<HookCall> call) {
std::string hookName = std::string(call->name);
for (size_t l = 0; l < listeners[hookName].size(); l++) {
(listeners[hookName][l])(call);
}
return call->cancelled;
}
void bindHook(std::string name) {
hookName = name;
}
void initBindHook(int length, ...) {
if (length > 0) {
va_list args;
va_start(args, length);
for (int i = 0; i < length; i++) {
HookParameter currentParam = va_arg(args, struct HookParameter);
initArgs[currentParam.name] = currentParam.parameter;
}
va_end(args);
}
}
bool callBindHook(int length, ...) {
if (length > 0) {
va_list args;
va_start(args, length);
for (int i = 0; i < length; i++) {
HookParameter currentParam = va_arg(args, struct HookParameter);
hookArgs[currentParam.name] = currentParam.parameter;
}
va_end(args);
}
HookCall call = {
.name = hookName,
.baseArgs = initArgs,
.hookedArgs = hookArgs
};
const bool cancelled = handleHook(std::make_shared<HookCall>(call));
hookName = "";
initArgs.clear();
hookArgs.clear();
return cancelled;
}
} }
/*
#############################
Module: Hook C Handle
#############################
*/
extern "C" {
void bind_hook(char* name) {
hookName = std::string(name);
}
void init_hook(int length, ...) {
if (length > 0) {
va_list args;
va_start(args, length);
for (int i = 0; i < length; i++) {
HookParameter currentParam = va_arg(args, struct HookParameter);
initArgs[currentParam.name] = currentParam.parameter;
}
va_end(args);
}
}
bool call_hook(int length, ...) {
if (length > 0) {
va_list args;
va_start(args, length);
for (int i = 0; i < length; i++) {
HookParameter currentParam = va_arg(args, struct HookParameter);
hookArgs[currentParam.name] = currentParam.parameter;
}
va_end(args);
}
HookCall call = {
.name = hookName,
.baseArgs = initArgs,
.hookedArgs = hookArgs
};
const bool cancelled = ModInternal::handleHook(std::make_shared<HookCall>(call));
hookName = "";
initArgs.clear();
hookArgs.clear();
return cancelled;
}
}

View file

@ -1,80 +1,50 @@
#pragma once #pragma once
struct HookParameter {
const char* name;
void* parameter;
};
#define LOOKUP_TEXTURE "F3D::LookupCacheTexture"
#define GRAYOUT_TEXTURE "Kaleido::GrayOutTexture"
#define INVALIDATE_TEXTURE "GBI::gSPInvalidateTexCache"
#define CONTROLLER_READ "N64::ControllerRead"
#define AUDIO_INIT "AudioMgr::Init"
#define LOAD_TEXTURE "ResourceMgr::LoadTexByName"
#define UPDATE_VOLUME "AudioVolume::Bind"
#define IMGUI_API_INIT "ImGuiApiInit"
#define IMGUI_API_DRAW "ImGuiApiDraw"
#define WINDOW_API_INIT "WApiInit"
#define WINDOW_API_HANDLE_EVENTS "WApiHandleEvents"
#define WINDOW_API_START_FRAME "WApiStartFrame"
// Graphics API Hooks
#define GFX_PRE_START_FRAME "GFXApiPreStartFrame"
#define GFX_POST_START_FRAME "GFXApiPostStartFrame"
#define GFX_PRE_END_FRAME "GFXApiPreEndFrame"
#define GFX_POST_END_FRAME "GFXApiPostEndFrame"
#define GFX_ON_REZISE "GFXApiOnResize"
#define GFX_INIT "GFXApiInit"
#define GFX_SHUTDOWN "GFXApiShutdown"
// End
#ifdef __cplusplus #ifdef __cplusplus
#define HOOK_PARAMETER(name, ptr) HookParameter({ name, static_cast<void*>(ptr) })
#define BIND_HOOK(name, func) ModInternal::registerHookListener({ name, [this](HookEvent call) { func(call); }})
#define BIND_PTR(name, type) static_cast<type>(call->baseArgs[name])
#define BIND_VAR(name, type) *BIND_PTR(name, type)
#include <functional> #include <functional>
#include <string>
#include <map>
#include <memory>
struct HookCall { #include "UltraController.h"
std::string name;
std::map<std::string, void*> baseArgs;
std::map<std::string, void*> hookedArgs;
bool cancelled = false;
};
typedef std::shared_ptr<HookCall> HookEvent; #define DEFINE_HOOK(name, type) struct name { typedef std::function<type> fn; }
typedef std::function<void(HookEvent)> HookFunc;
struct HookListener {
std::string hookName;
HookFunc callback;
int priority = 0;
};
namespace ModInternal { namespace ModInternal {
void registerHookListener(HookListener listener);
void bindHook(std::string name); template <typename H>
void initBindHook(int length, ...); struct RegisteredHooks {
bool callBindHook(int length, ...); inline static std::vector<typename H::fn> functions;
};
template <typename H>
void RegisterHook(typename H::fn h) {
RegisteredHooks<H>::functions.push_back(h);
}
template <typename H, typename... Args>
void ExecuteHooks(Args&&... args) {
for (auto& fn : RegisteredHooks<H>::functions) {
fn(std::forward<Args>(args)...);
}
}
DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad));
DEFINE_HOOK(AudioInit, void());
DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture));
DEFINE_HOOK(GfxInit, void());
} }
#else #endif
void bind_hook(char* name); #ifdef __cplusplus
void init_hook(int length, ...); extern "C" {
bool call_hook(int length, ...); #endif
#endif void ModInternal_ExecuteAudioInitHooks();
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -63,11 +63,14 @@ namespace SohImGui {
extern bool needs_save; extern bool needs_save;
void Init(WindowImpl window_impl); void Init(WindowImpl window_impl);
void Update(EventImpl event); void Update(EventImpl event);
void Tooltip(const char* text);
void EnhancementRadioButton(std::string text, std::string cvarName, int value);
void EnhancementCheckbox(std::string text, std::string cvarName); void EnhancementRadioButton(const char* text, const char* cvarName, int id);
void EnhancementSliderInt(std::string text, std::string id, std::string cvarName, int min, int max, std::string format); void EnhancementCheckbox(const char* text, const char* cvarName);
void EnhancementSliderFloat(std::string text, std::string id, std::string cvarName, float min, float max, std::string format, float defaultValue); void EnhancementButton(const char* text, const char* cvarName);
void EnhancementSliderInt(const char* text, const char* id, const char* cvarName, int min, int max, const char* format);
void EnhancementSliderFloat(const char* text, const char* id, const char* cvarName, float min, float max, const char* format, float defaultValue, bool isPercentage);
void EnhancementColor(const char* text, const char* cvarName, ImVec4 ColorRGBA, ImVec4 default_colors, bool allow_rainbow = true, bool has_alpha=false, bool TitleSameLine=false);
void DrawMainMenuAndCalculateGameSize(void); void DrawMainMenuAndCalculateGameSize(void);
@ -78,6 +81,10 @@ namespace SohImGui {
void BindCmd(const std::string& cmd, CommandEntry entry); void BindCmd(const std::string& cmd, CommandEntry entry);
void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc); void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc);
void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1)); void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1));
void LoadPickersColors(ImVec4& ColorArray, const char* cvarname, const ImVec4& default_colors, bool has_alpha=false);
void RandomizeColor(const char* cvarName, ImVec4* colors);
void RainbowColor(const char* cvarName, ImVec4* colors);
void ResetColor(const char* cvarName, ImVec4* colors, ImVec4 defaultcolors, bool has_alpha);
ImTextureID GetTextureByID(int id); ImTextureID GetTextureByID(int id);
ImTextureID GetTextureByName(const std::string& name); ImTextureID GetTextureByName(const std::string& name);
} }

View file

@ -1,5 +1,7 @@
#include "TextureMod.h" #include "TextureMod.h"
#if 0
#include <map> #include <map>
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -121,4 +123,6 @@ namespace Ship {
TexturePool.clear(); TexturePool.clear();
LoadedOTRS.clear(); LoadedOTRS.clear();
} }
} }
#endif

View file

@ -3,6 +3,8 @@
#include <PR/ultra64/gbi.h> #include <PR/ultra64/gbi.h>
#include "Lib/Fast3D/gfx_pc.h" #include "Lib/Fast3D/gfx_pc.h"
#if 0
namespace Ship { namespace Ship {
enum TextureMod { enum TextureMod {
GRAYSCALE, GRAYSCALE,
@ -48,4 +50,6 @@ namespace Ship {
data[x + 2] = gray; data[x + 2] = gray;
} }
} }
} }
#endif

View file

@ -112,24 +112,19 @@ extern "C" {
} }
} }
ModInternal::bindHook(CONTROLLER_READ); ModInternal::ExecuteHooks<ModInternal::ControllerRead>(pad);
ModInternal::initBindHook(1,
HookParameter({ .name = "cont_pad", .parameter = (void*)pad })
);
ModInternal::callBindHook(0);
} }
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc) { const char* ResourceMgr_GetNameByCRC(uint64_t crc) {
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
strcpy(alloc, hashStr.c_str()); return hashStr != nullptr ? hashStr->c_str() : nullptr;
return (char*)hashStr.c_str();
} }
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc) { Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc) {
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != "") { if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr)); auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
//if (res != nullptr) //if (res != nullptr)
return (Vtx*)res->vertices.data(); return (Vtx*)res->vertices.data();
@ -142,10 +137,10 @@ extern "C" {
} }
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) { int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != "") { if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr)); auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
return (int32_t*)res->mtx.data(); return (int32_t*)res->mtx.data();
} else { } else {
return nullptr; return nullptr;
@ -153,10 +148,10 @@ extern "C" {
} }
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) { Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
if (hashStr != "") { if (hashStr != nullptr) {
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr)); auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
return (Gfx*)&res->instructions[0]; return (Gfx*)&res->instructions[0];
} else { } else {
return nullptr; return nullptr;
@ -164,17 +159,12 @@ extern "C" {
} }
char* ResourceMgr_LoadTexByCRC(uint64_t crc) { char* ResourceMgr_LoadTexByCRC(uint64_t crc) {
const std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
if (!hashStr.empty()) { if (hashStr != nullptr) {
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get()); const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get());
ModInternal::bindHook(LOAD_TEXTURE); ModInternal::ExecuteHooks<ModInternal::LoadTexture>(hashStr->c_str(), &res->imageData);
ModInternal::initBindHook(2,
HookParameter({.name = "path", .parameter = (void*)hashStr.c_str() }),
HookParameter({.name = "texture", .parameter = static_cast<void*>(&res->imageData) })
);
ModInternal::callBindHook(0);
return reinterpret_cast<char*>(res->imageData); return reinterpret_cast<char*>(res->imageData);
} else { } else {
@ -184,11 +174,11 @@ extern "C" {
void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData) void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData)
{ {
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash); const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
if (hashStr != "") if (hashStr != nullptr)
{ {
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get(); auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get();
Ship::Patch patch; Ship::Patch patch;
patch.crc = hash; patch.crc = hash;
@ -201,12 +191,7 @@ extern "C" {
char* ResourceMgr_LoadTexByName(char* texPath) { char* ResourceMgr_LoadTexByName(char* texPath) {
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get()); const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(texPath).get());
ModInternal::bindHook(LOAD_TEXTURE); ModInternal::ExecuteHooks<ModInternal::LoadTexture>(texPath, &res->imageData);
ModInternal::initBindHook(2,
HookParameter({ .name = "path", .parameter = (void*)texPath }),
HookParameter({ .name = "texture", .parameter = static_cast<void*>(&res->imageData) })
);
ModInternal::callBindHook(0);
return (char*)res->imageData; return (char*)res->imageData;
} }
@ -287,13 +272,14 @@ namespace Ship {
gfx_run(Commands, m); gfx_run(Commands, m);
gfx_end_frame(); gfx_end_frame();
} }
gfx_run(Commands, {});
gfx_end_frame();
} }
void Window::SetFrameDivisor(int divisor) { void Window::SetTargetFps(int fps) {
gfx_set_framedivisor(divisor); gfx_set_target_fps(fps);
//gfx_set_framedivisor(0); }
void Window::SetMaximumFrameLatency(int latency) {
gfx_set_maximum_frame_latency(latency);
} }
void Window::GetPixelDepthPrepare(float x, float y) { void Window::GetPixelDepthPrepare(float x, float y) {

View file

@ -20,7 +20,8 @@ namespace Ship {
void Init(); void Init();
void StartFrame(); void StartFrame();
void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements); void RunCommands(Gfx* Commands, const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
void SetFrameDivisor(int divisor); void SetTargetFps(int fps);
void SetMaximumFrameLatency(int latency);
void GetPixelDepthPrepare(float x, float y); void GetPixelDepthPrepare(float x, float y);
uint16_t GetPixelDepth(float x, float y); uint16_t GetPixelDepth(float x, float y);
void ToggleFullscreen(); void ToggleFullscreen();

View file

@ -18,8 +18,8 @@ WARN := \
-funsigned-char \ -funsigned-char \
-m32 -mhard-float -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv \ -m32 -mhard-float -fno-stack-protector -fno-common -fno-zero-initialized-in-bss -fno-strict-aliasing -fno-inline-functions -fno-inline-small-functions -fno-toplevel-reorder -ffreestanding -fwrapv \
CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib -march=i386 CXXFLAGS := $(WARN) -std=c++20 -D_GNU_SOURCE -fpermissive -no-pie -nostdlib -march=i386 -msse2 -mfpmath=sse
CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib -march=i386 CFLAGS := $(WARN) -std=c99 -D_GNU_SOURCE -no-pie -nostdlib -march=i386 -msse2 -mfpmath=sse
LDFLAGS := -m32 LDFLAGS := -m32
CPPFLAGS := -MMD CPPFLAGS := -MMD

View file

@ -1,6 +1,6 @@
<Root> <Root>
<File Name="object_triforce_spot" Segment="6"> <File Name="object_triforce_spot" Segment="6">
<Array Name="gTriforceVtx" Count="32" Offset="0x0000"> <Array Name="gTriforceVtx" Count="96" Offset="0x0000">
<Vtx/> <Vtx/>
</Array> </Array>

View file

@ -78,6 +78,12 @@ typedef enum {
/* 0x15 */ SLOT_BOTTLE_4, /* 0x15 */ SLOT_BOTTLE_4,
/* 0x16 */ SLOT_TRADE_ADULT, /* 0x16 */ SLOT_TRADE_ADULT,
/* 0x17 */ SLOT_TRADE_CHILD, /* 0x17 */ SLOT_TRADE_CHILD,
/* 0x18 */ SLOT_TUNIC_KOKIRI,
/* 0x19 */ SLOT_TUNIC_GORON,
/* 0x1A */ SLOT_TUNIC_ZORA,
/* 0x1B */ SLOT_BOOTS_KOKIRI,
/* 0x1C */ SLOT_BOOTS_IRON,
/* 0x1D */ SLOT_BOOTS_HOVER,
/* 0xFF */ SLOT_NONE = 0xFF /* 0xFF */ SLOT_NONE = 0xFF
} InventorySlot; } InventorySlot;

View file

@ -128,7 +128,16 @@ typedef enum {
/* 0x40 */ PLAYER_AP_MASK_GERUDO, /* 0x40 */ PLAYER_AP_MASK_GERUDO,
/* 0x41 */ PLAYER_AP_MASK_TRUTH, /* 0x41 */ PLAYER_AP_MASK_TRUTH,
/* 0x42 */ PLAYER_AP_LENS, /* 0x42 */ PLAYER_AP_LENS,
/* 0x43 */ PLAYER_AP_MAX /* 0x43 */ PLAYER_AP_SHIELD_DEKU,
/* 0x44 */ PLAYER_AP_SHIELD_HYLIAN,
/* 0x45 */ PLAYER_AP_SHIELD_MIRROR,
/* 0x46 */ PLAYER_AP_TUNIC_KOKIRI,
/* 0x47 */ PLAYER_AP_TUNIC_GORON,
/* 0x48 */ PLAYER_AP_TUNIC_ZORA,
/* 0x49 */ PLAYER_AP_BOOTS_KOKIRI,
/* 0x4A */ PLAYER_AP_BOOTS_IRON,
/* 0x4B */ PLAYER_AP_BOOTS_HOVER,
/* 0x4C */ PLAYER_AP_MAX
} PlayerActionParam; } PlayerActionParam;
typedef enum { typedef enum {

View file

@ -28,9 +28,13 @@ void BootCommands_Init()
CVar_RegisterS32("gRumbleEnabled", 0); CVar_RegisterS32("gRumbleEnabled", 0);
CVar_RegisterS32("gUniformLR", 1); CVar_RegisterS32("gUniformLR", 1);
CVar_RegisterS32("gTwoHandedIdle", 0); CVar_RegisterS32("gTwoHandedIdle", 0);
CVar_RegisterS32("gDekuNutUpgradeFix", 1);
CVar_RegisterS32("gNewDrops", 0); CVar_RegisterS32("gNewDrops", 0);
CVar_RegisterS32("gVisualAgony", 0); CVar_RegisterS32("gVisualAgony", 0);
CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French CVar_RegisterS32("gLanguages", 0); //0 = English / 1 = German / 2 = French
CVar_RegisterS32("gHudColors", 1); //0 = N64 / 1 = NGC / 2 = Custom
CVar_RegisterS32("gUseNaviCol", 0);
CVar_RegisterS32("gUseTunicsCol", 0);
} }
//void BootCommands_ParseBootArgs(char* str) //void BootCommands_ParseBootArgs(char* str)

View file

@ -175,8 +175,6 @@ 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) {
OTRGlobals::Instance->context->GetWindow()->SetFrameDivisor(CVar_GetS32("g60FPS", 0) == 0 ? R_UPDATE_RATE : 1);
if (!audio.initialized && 0) { if (!audio.initialized && 0) {
audio.initialized = true; audio.initialized = true;
std::thread([]() { std::thread([]() {
@ -226,15 +224,45 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) {
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;
if (CVar_GetS32("g60FPS", 0) != 0) { int target_fps = CVar_GetS32("gInterpolationFPS", 20);
int to = R_UPDATE_RATE; static int last_fps;
for (int i = 1; i < to; i++) { static int last_update_rate;
mtx_replacements.push_back(FrameInterpolation_Interpolate(i / (float)to)); static int time;
int fps = target_fps;
int original_fps = 60 / R_UPDATE_RATE;
if (target_fps == 20 || original_fps > target_fps) {
fps = original_fps;
}
if (last_fps != fps || last_update_rate != R_UPDATE_RATE) {
time = 0;
}
// time_base = fps * original_fps (one second)
int next_original_frame = fps;
while (time + original_fps <= next_original_frame) {
time += original_fps;
if (time != next_original_frame) {
mtx_replacements.push_back(FrameInterpolation_Interpolate((float)time / next_original_frame));
} else {
mtx_replacements.emplace_back();
} }
} }
time -= fps;
OTRGlobals::Instance->context->GetWindow()->SetTargetFps(fps);
int threshold = CVar_GetS32("gExtraLatencyThreshold", 80);
OTRGlobals::Instance->context->GetWindow()->SetMaximumFrameLatency(threshold > 0 && target_fps >= threshold ? 2 : 1);
OTRGlobals::Instance->context->GetWindow()->RunCommands(commands, mtx_replacements); OTRGlobals::Instance->context->GetWindow()->RunCommands(commands, mtx_replacements);
last_fps = fps;
last_update_rate = R_UPDATE_RATE;
if (0) { if (0) {
std::unique_lock<std::mutex> Lock(audio.mutex); std::unique_lock<std::mutex> Lock(audio.mutex);
while (audio.processing) { while (audio.processing) {

View file

@ -451,7 +451,7 @@ void FrameInterpolation_StartRecord(void) {
current_recording = {}; current_recording = {};
current_path.clear(); current_path.clear();
current_path.push_back(&current_recording.root_path); current_path.push_back(&current_recording.root_path);
if (CVar_GetS32("g60FPS", 0) != 0) { if (CVar_GetS32("gInterpolationFPS", 20) != 20) {
is_recording = true; is_recording = true;
} }
} }

View file

@ -19,9 +19,50 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) {
if (file == nullptr) if (file == nullptr)
return nullptr; return nullptr;
MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * file->messages.size()); // Allocate room for an additional message
MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * (file->messages.size() + 1));
for (int i = 0; i < file->messages.size(); i++) { for (int i = 0; i < file->messages.size(); i++) {
// Look for Owl Text
if (file->messages[i].id == 0x2066) {
// Create a new message based on the Owl Text
char* kaeporaPatch = (char*)malloc(sizeof(char) * file->messages[i].msg.size());
file->messages[i].msg.copy(kaeporaPatch, file->messages[i].msg.size(), 0);
// Swap the order of yes and no in this new message
if (filePath == "text/nes_message_data_static/nes_message_data_static") {
kaeporaPatch[26] = 'Y';
kaeporaPatch[27] = 'e';
kaeporaPatch[28] = 's';
kaeporaPatch[29] = 1;
kaeporaPatch[30] = 'N';
kaeporaPatch[31] = 'o';
} else if (filePath == "text/ger_message_data_static/ger_message_data_static") {
kaeporaPatch[30] = 'J';
kaeporaPatch[31] = 'a';
kaeporaPatch[32] = '!';
kaeporaPatch[33] = 1;
kaeporaPatch[34] = 'N';
kaeporaPatch[35] = 'e';
kaeporaPatch[36] = 'i';
kaeporaPatch[37] = 'n';
} else {
kaeporaPatch[26] = 'O';
kaeporaPatch[27] = 'u';
kaeporaPatch[28] = 'i';
kaeporaPatch[29] = 1;
kaeporaPatch[30] = 'N';
kaeporaPatch[31] = 'o';
kaeporaPatch[32] = 'n';
}
// load data into message
table[file->messages.size()].textId = 0x71B3;
table[file->messages.size()].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos;
table[file->messages.size()].segment = kaeporaPatch;
table[file->messages.size()].msgSize = file->messages[i].msg.size();
}
table[i].textId = file->messages[i].id; table[i].textId = file->messages[i].id;
table[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos; table[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos;
table[i].segment = file->messages[i].msg.c_str(); table[i].segment = file->messages[i].msg.c_str();

View file

@ -109,9 +109,7 @@ void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedCon
AudioLoad_SetDmaHandler(DmaMgr_DmaHandler); AudioLoad_SetDmaHandler(DmaMgr_DmaHandler);
Audio_InitSound(); Audio_InitSound();
osSendMesg(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK); osSendMesg(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK);
bind_hook(AUDIO_INIT); ModInternal_ExecuteAudioInitHooks();
init_hook(0);
call_hook(0);
// Removed due to crash // Removed due to crash
//IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74); //IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74);
hasInitialized = true; hasInitialized = true;

View file

@ -478,7 +478,10 @@ static void RunFrame()
Graph_StartFrame(); Graph_StartFrame();
PadMgr_ThreadEntry(&gPadMgr); // TODO: Workaround for rumble being too long. Implement os thread functions.
for (int i = 0; i < 3; i++) {
PadMgr_ThreadEntry(&gPadMgr);
}
Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState); Graph_Update(&runFrameContext.gfxCtx, runFrameContext.gameState);
ticksB = GetPerfCounter(); ticksB = GetPerfCounter();

View file

@ -335,38 +335,59 @@ void func_8002BE98(TargetContext* targetCtx, s32 actorCategory, GlobalContext* g
void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, GlobalContext* globalCtx) { void func_8002BF60(TargetContext* targetCtx, Actor* actor, s32 actorCategory, GlobalContext* globalCtx) {
NaviColor* naviColor = &sNaviColorList[actorCategory]; NaviColor* naviColor = &sNaviColorList[actorCategory];
if (actorCategory == ACTORCAT_PLAYER) {
naviColor->inner.r = CVar_GetS32("gNavi_Idle_Inner_Red", naviColor->inner.r); if (CVar_GetS32("gUseNaviCol",0) != 1 ) {
naviColor->inner.g = CVar_GetS32("gNavi_Idle_Inner_Green", naviColor->inner.g); if (actorCategory == ACTORCAT_PLAYER) {
naviColor->inner.b = CVar_GetS32("gNavi_Idle_Inner_Blue", naviColor->inner.b); naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 255;
naviColor->outer.r = CVar_GetS32("gNavi_Idle_Outer_Red", naviColor->outer.r); naviColor->outer.r = 115; naviColor->outer.g = 230; naviColor->outer.b = 255;
naviColor->outer.g = CVar_GetS32("gNavi_Idle_Outer_Green", naviColor->outer.g); }
naviColor->outer.b = CVar_GetS32("gNavi_Idle_Outer_Blue", naviColor->outer.b); if (actorCategory == ACTORCAT_NPC) {
} naviColor->inner.r = 100; naviColor->inner.g = 100; naviColor->inner.b = 255;
if (actorCategory == ACTORCAT_NPC) { naviColor->outer.r = 90; naviColor->outer.g = 90; naviColor->outer.b = 255;
naviColor->inner.r = CVar_GetS32("gNavi_NPC_Inner_Red", naviColor->inner.r); }
naviColor->inner.g = CVar_GetS32("gNavi_NPC_Inner_Green", naviColor->inner.g); if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
naviColor->inner.b = CVar_GetS32("gNavi_NPC_Inner_Blue", naviColor->inner.b); naviColor->inner.r = 255; naviColor->inner.g = 255; naviColor->inner.b = 0;
naviColor->outer.r = CVar_GetS32("gNavi_NPC_Outer_Red", naviColor->outer.r); naviColor->outer.r = 220; naviColor->outer.g = 220; naviColor->outer.b = 0;
naviColor->outer.g = CVar_GetS32("gNavi_NPC_Outer_Green", naviColor->outer.g); }
naviColor->outer.b = CVar_GetS32("gNavi_NPC_Outer_Blue", naviColor->outer.b); if (actorCategory == ACTORCAT_PROP) {
} naviColor->inner.r = 0; naviColor->inner.g = 255; naviColor->inner.b = 90;
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) { naviColor->outer.r = 0; naviColor->outer.g = 220; naviColor->outer.b = 0;
naviColor->inner.r = CVar_GetS32("gNavi_Enemy_Inner_Red", naviColor->inner.r); }
naviColor->inner.g = CVar_GetS32("gNavi_Enemy_Inner_Green", naviColor->inner.g); } else {
naviColor->inner.b = CVar_GetS32("gNavi_Enemy_Inner_Blue", naviColor->inner.b); if (actorCategory == ACTORCAT_PLAYER) {
naviColor->outer.r = CVar_GetS32("gNavi_Enemy_Outer_Red", naviColor->outer.r); naviColor->inner.r = CVar_GetS32("gNavi_Idle_Inner_R", naviColor->inner.r);
naviColor->outer.g = CVar_GetS32("gNavi_Enemy_Outer_Green", naviColor->outer.g); naviColor->inner.g = CVar_GetS32("gNavi_Idle_Inner_G", naviColor->inner.g);
naviColor->outer.b = CVar_GetS32("gNavi_Enemy_Outer_Blue", naviColor->outer.b); naviColor->inner.b = CVar_GetS32("gNavi_Idle_Inner_B", naviColor->inner.b);
} naviColor->outer.r = CVar_GetS32("gNavi_Idle_Outer_R", naviColor->outer.r);
if (actorCategory == ACTORCAT_PROP) { naviColor->outer.g = CVar_GetS32("gNavi_Idle_Outer_G", naviColor->outer.g);
naviColor->inner.r = CVar_GetS32("gNavi_Prop_Inner_Red", naviColor->inner.r); naviColor->outer.b = CVar_GetS32("gNavi_Idle_Outer_B", naviColor->outer.b);
naviColor->inner.g = CVar_GetS32("gNavi_Prop_Inner_Green", naviColor->inner.g); }
naviColor->inner.b = CVar_GetS32("gNavi_Prop_Inner_Blue", naviColor->inner.b); if (actorCategory == ACTORCAT_NPC) {
naviColor->outer.r = CVar_GetS32("gNavi_Prop_Outer_Red", naviColor->outer.r); naviColor->inner.r = CVar_GetS32("gNavi_NPC_Inner_R", naviColor->inner.r);
naviColor->outer.g = CVar_GetS32("gNavi_Prop_Outer_Green", naviColor->outer.g); naviColor->inner.g = CVar_GetS32("gNavi_NPC_Inner_G", naviColor->inner.g);
naviColor->outer.b = CVar_GetS32("gNavi_Prop_Outer_Blue", naviColor->outer.b); naviColor->inner.b = CVar_GetS32("gNavi_NPC_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_NPC_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_NPC_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_NPC_Outer_B", naviColor->outer.b);
}
if (actorCategory == ACTORCAT_BOSS || actorCategory == ACTORCAT_ENEMY) {
naviColor->inner.r = CVar_GetS32("gNavi_Enemy_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_Enemy_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_Enemy_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_Enemy_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_Enemy_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_Enemy_Outer_B", naviColor->outer.b);
}
if (actorCategory == ACTORCAT_PROP) {
naviColor->inner.r = CVar_GetS32("gNavi_Prop_Inner_R", naviColor->inner.r);
naviColor->inner.g = CVar_GetS32("gNavi_Prop_Inner_G", naviColor->inner.g);
naviColor->inner.b = CVar_GetS32("gNavi_Prop_Inner_B", naviColor->inner.b);
naviColor->outer.r = CVar_GetS32("gNavi_Prop_Outer_R", naviColor->outer.r);
naviColor->outer.g = CVar_GetS32("gNavi_Prop_Outer_G", naviColor->outer.g);
naviColor->outer.b = CVar_GetS32("gNavi_Prop_Outer_B", naviColor->outer.b);
}
} }
targetCtx->naviRefPos.x = actor->focus.pos.x; targetCtx->naviRefPos.x = actor->focus.pos.x;
targetCtx->naviRefPos.y = actor->focus.pos.y + (actor->targetArrowOffset * actor->scale.y); targetCtx->naviRefPos.y = actor->focus.pos.y + (actor->targetArrowOffset * actor->scale.y);
targetCtx->naviRefPos.z = actor->focus.pos.z; targetCtx->naviRefPos.z = actor->focus.pos.z;
@ -2269,8 +2290,8 @@ void Actor_DrawFaroresWindPointer(GlobalContext* globalCtx) {
((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y) + yOffset, ((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y) + yOffset,
((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z), 255, 255, 255, lightRadius); ((void)0, gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z), 255, 255, 255, lightRadius);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 5474);
} }
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_actor.c", 5474);
} }
void func_80030488(GlobalContext* globalCtx) { void func_80030488(GlobalContext* globalCtx) {

View file

@ -1,6 +1,11 @@
#include "global.h" #include "global.h"
#include "textures/parameter_static/parameter_static.h" #include "textures/parameter_static/parameter_static.h"
s16 Top_LM_Margin = 0;
s16 Left_LM_Margin = 0;
s16 Right_LM_Margin = 0;
s16 Bottom_LM_Margin = 0;
static s16 sHeartsPrimColors[3][3] = { static s16 sHeartsPrimColors[3][3] = {
{ HEARTS_PRIM_R, HEARTS_PRIM_G, HEARTS_PRIM_B }, { HEARTS_PRIM_R, HEARTS_PRIM_G, HEARTS_PRIM_B },
{ HEARTS_BURN_PRIM_R, HEARTS_BURN_PRIM_G, HEARTS_BURN_PRIM_B }, // unused { HEARTS_BURN_PRIM_R, HEARTS_BURN_PRIM_G, HEARTS_BURN_PRIM_B }, // unused
@ -106,6 +111,9 @@ static s16 sHeartsDDEnvFactors[3][3] = {
}; };
// Current colors for the double defense hearts // Current colors for the double defense hearts
s16 HeartInner[3] = {HEARTS_PRIM_R,HEARTS_PRIM_G,HEARTS_PRIM_B};
s16 HeartDDOutline[3] = {HEARTS_DD_PRIM_R,HEARTS_DD_PRIM_G,HEARTS_DD_PRIM_B};
s16 HeartDDInner[3] = {HEARTS_DD_ENV_R,HEARTS_DD_ENV_G,HEARTS_DD_ENV_B};
s16 sBeatingHeartsDDPrim[3]; s16 sBeatingHeartsDDPrim[3];
s16 sBeatingHeartsDDEnv[3]; s16 sBeatingHeartsDDEnv[3];
s16 sHeartsDDPrim[2][3]; s16 sHeartsDDPrim[2][3];
@ -113,35 +121,54 @@ s16 sHeartsDDEnv[2][3];
void HealthMeter_Init(GlobalContext* globalCtx) { void HealthMeter_Init(GlobalContext* globalCtx) {
InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx; InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx;
if (CVar_GetS32("gHudColors", 1) == 2) {
HeartInner[0] = CVar_GetS32("gCCHeartsPrimR", 90);
HeartInner[1] = CVar_GetS32("gCCHeartsPrimG", 90);
HeartInner[2] = CVar_GetS32("gCCHeartsPrimB", 90);
HeartDDOutline[0] = CVar_GetS32("gDDCCHeartsPrimR", 90);
HeartDDOutline[1] = CVar_GetS32("gDDCCHeartsPrimG", 90);
HeartDDOutline[2] = CVar_GetS32("gDDCCHeartsPrimB", 90);
} else {
HeartInner[0] = HEARTS_PRIM_R;
HeartInner[1] = HEARTS_PRIM_G;
HeartInner[2] = HEARTS_PRIM_B;
HeartDDOutline[0] = HEARTS_DD_PRIM_R;
HeartDDOutline[1] = HEARTS_DD_PRIM_G;
HeartDDOutline[2] = HEARTS_DD_PRIM_B;
}
interfaceCtx->unk_228 = 0x140; interfaceCtx->unk_228 = 0x140;
interfaceCtx->unk_226 = gSaveContext.health; interfaceCtx->unk_226 = gSaveContext.health;
interfaceCtx->unk_22A = interfaceCtx->unk_1FE = 0; interfaceCtx->unk_22A = interfaceCtx->unk_1FE = 0;
interfaceCtx->unk_22C = interfaceCtx->unk_200 = 0; interfaceCtx->unk_22C = interfaceCtx->unk_200 = 0;
interfaceCtx->heartsPrimR[0] = HEARTS_PRIM_R; interfaceCtx->heartsPrimR[0] = HeartInner[0];
interfaceCtx->heartsPrimG[0] = HEARTS_PRIM_G; interfaceCtx->heartsPrimG[0] = HeartInner[1];
interfaceCtx->heartsPrimB[0] = HEARTS_PRIM_B; interfaceCtx->heartsPrimB[0] = HeartInner[2];
interfaceCtx->heartsEnvR[0] = HEARTS_ENV_R; interfaceCtx->heartsEnvR[0] = HEARTS_ENV_R;
interfaceCtx->heartsEnvG[0] = HEARTS_ENV_G; interfaceCtx->heartsEnvG[0] = HEARTS_ENV_G;
interfaceCtx->heartsEnvB[0] = HEARTS_ENV_B; interfaceCtx->heartsEnvB[0] = HEARTS_ENV_B;
interfaceCtx->heartsPrimR[1] = HEARTS_PRIM_R; interfaceCtx->heartsPrimR[1] = HeartInner[0];
interfaceCtx->heartsPrimG[1] = HEARTS_PRIM_G; interfaceCtx->heartsPrimG[1] = HeartInner[1];
interfaceCtx->heartsPrimB[1] = HEARTS_PRIM_B; interfaceCtx->heartsPrimB[1] = HeartInner[2];
interfaceCtx->heartsEnvR[1] = HEARTS_ENV_R; interfaceCtx->heartsEnvR[1] = HEARTS_ENV_R;
interfaceCtx->heartsEnvG[1] = HEARTS_ENV_G; interfaceCtx->heartsEnvG[1] = HEARTS_ENV_G;
interfaceCtx->heartsEnvB[1] = HEARTS_ENV_B; interfaceCtx->heartsEnvB[1] = HEARTS_ENV_B;
sHeartsDDPrim[0][0] = sHeartsDDPrim[1][0] = HEARTS_DD_PRIM_R; sHeartsDDPrim[0][0] = sHeartsDDPrim[1][0] = HeartDDOutline[0];
sHeartsDDPrim[0][1] = sHeartsDDPrim[1][1] = HEARTS_DD_PRIM_G; sHeartsDDPrim[0][1] = sHeartsDDPrim[1][1] = HeartDDOutline[1];
sHeartsDDPrim[0][2] = sHeartsDDPrim[1][2] = HEARTS_DD_PRIM_B; sHeartsDDPrim[0][2] = sHeartsDDPrim[1][2] = HeartDDOutline[2];
sHeartsDDEnv[0][0] = sHeartsDDEnv[1][0] = HEARTS_DD_ENV_R; sHeartsDDPrim[2][0] = HeartInner[0];
sHeartsDDEnv[0][1] = sHeartsDDEnv[1][1] = HEARTS_DD_ENV_G; sHeartsDDPrim[2][1] = HeartInner[1];
sHeartsDDEnv[0][2] = sHeartsDDEnv[1][2] = HEARTS_DD_ENV_B; sHeartsDDPrim[2][2] = HeartInner[2];
sHeartsDDEnv[0][0] = sHeartsDDEnv[1][0] = HeartDDInner[0];
sHeartsDDEnv[0][1] = sHeartsDDEnv[1][1] = HeartDDInner[1];
sHeartsDDEnv[0][2] = sHeartsDDEnv[1][2] = HeartDDInner[2];
} }
void HealthMeter_Update(GlobalContext* globalCtx) { void HealthMeter_Update(GlobalContext* globalCtx) {
@ -154,7 +181,33 @@ void HealthMeter_Update(GlobalContext* globalCtx) {
s16 gFactor; s16 gFactor;
s16 bFactor; s16 bFactor;
if (interfaceCtx) {} if (CVar_GetS32("gHUDMargins", 0) != 0) {
Top_LM_Margin = CVar_GetS32("gHUDMargin_T", 0);
Left_LM_Margin = CVar_GetS32("gHUDMargin_L", 0);
Right_LM_Margin = CVar_GetS32("gHUDMargin_R", 0);
Bottom_LM_Margin = CVar_GetS32("gHUDMargin_B", 0);
} else {
Top_LM_Margin = 0;
Left_LM_Margin = 0;
Right_LM_Margin = 0;
Bottom_LM_Margin = 0;
}
if (CVar_GetS32("gHudColors", 1) == 2) {
HeartInner[0] = CVar_GetS32("gCCHeartsPrimR", sHeartsPrimColors[0][0]);
HeartInner[1] = CVar_GetS32("gCCHeartsPrimG", sHeartsPrimColors[0][1]);
HeartInner[2] = CVar_GetS32("gCCHeartsPrimB", sHeartsPrimColors[0][2]);
HeartDDOutline[0] = CVar_GetS32("gDDCCHeartsPrimR", sHeartsDDPrim[0][0]);
HeartDDOutline[1] = CVar_GetS32("gDDCCHeartsPrimG", sHeartsDDPrim[0][1]);
HeartDDOutline[2] = CVar_GetS32("gDDCCHeartsPrimB", sHeartsDDPrim[0][2]);
} else {
HeartInner[0] = HEARTS_PRIM_R;
HeartInner[1] = HEARTS_PRIM_G;
HeartInner[2] = HEARTS_PRIM_B;
HeartDDOutline[0] = HEARTS_DD_PRIM_R;
HeartDDOutline[1] = HEARTS_DD_PRIM_G;
HeartDDOutline[2] = HEARTS_DD_PRIM_B;
}
if (interfaceCtx->unk_200 != 0) { if (interfaceCtx->unk_200 != 0) {
interfaceCtx->unk_1FE--; interfaceCtx->unk_1FE--;
@ -172,17 +225,23 @@ void HealthMeter_Update(GlobalContext* globalCtx) {
ddFactor = factor; ddFactor = factor;
interfaceCtx->heartsPrimR[0] = HEARTS_PRIM_R; interfaceCtx->heartsPrimR[0] = HeartInner[0];
interfaceCtx->heartsPrimG[0] = HEARTS_PRIM_G; interfaceCtx->heartsPrimG[0] = HeartInner[1];
interfaceCtx->heartsPrimB[0] = HEARTS_PRIM_B; interfaceCtx->heartsPrimB[0] = HeartInner[2];
interfaceCtx->heartsEnvR[0] = HEARTS_ENV_R; interfaceCtx->heartsEnvR[0] = HEARTS_ENV_R;
interfaceCtx->heartsEnvG[0] = HEARTS_ENV_G; interfaceCtx->heartsEnvG[0] = HEARTS_ENV_G;
interfaceCtx->heartsEnvB[0] = HEARTS_ENV_B; interfaceCtx->heartsEnvB[0] = HEARTS_ENV_B;
interfaceCtx->heartsPrimR[1] = sHeartsPrimColors[type][0]; if (CVar_GetS32("gHudColors", 1) == 2) {
interfaceCtx->heartsPrimG[1] = sHeartsPrimColors[type][1]; interfaceCtx->heartsPrimR[1] = HeartInner[0];
interfaceCtx->heartsPrimB[1] = sHeartsPrimColors[type][2]; interfaceCtx->heartsPrimG[1] = HeartInner[1];
interfaceCtx->heartsPrimB[1] = HeartInner[2];
} else {
interfaceCtx->heartsPrimR[1] = sHeartsPrimColors[type][0];
interfaceCtx->heartsPrimG[1] = sHeartsPrimColors[type][1];
interfaceCtx->heartsPrimB[1] = sHeartsPrimColors[type][2];
}
interfaceCtx->heartsEnvR[1] = sHeartsEnvColors[type][0]; interfaceCtx->heartsEnvR[1] = sHeartsEnvColors[type][0];
interfaceCtx->heartsEnvG[1] = sHeartsEnvColors[type][1]; interfaceCtx->heartsEnvG[1] = sHeartsEnvColors[type][1];
@ -192,52 +251,90 @@ void HealthMeter_Update(GlobalContext* globalCtx) {
gFactor = sHeartsPrimFactors[0][1] * factor; gFactor = sHeartsPrimFactors[0][1] * factor;
bFactor = sHeartsPrimFactors[0][2] * factor; bFactor = sHeartsPrimFactors[0][2] * factor;
interfaceCtx->beatingHeartPrim[0] = (u8)(rFactor + HEARTS_PRIM_R) & 0xFF; interfaceCtx->beatingHeartPrim[0] = (u8)(rFactor + HeartInner[0]) & 0xFF;
interfaceCtx->beatingHeartPrim[1] = (u8)(gFactor + HEARTS_PRIM_G) & 0xFF; interfaceCtx->beatingHeartPrim[1] = (u8)(gFactor + HeartInner[1]) & 0xFF;
interfaceCtx->beatingHeartPrim[2] = (u8)(bFactor + HEARTS_PRIM_B) & 0xFF; interfaceCtx->beatingHeartPrim[2] = (u8)(bFactor + HeartInner[2]) & 0xFF;
rFactor = sHeartsEnvFactors[0][0] * factor; rFactor = sHeartsEnvFactors[0][0] * factor;
gFactor = sHeartsEnvFactors[0][1] * factor; gFactor = sHeartsEnvFactors[0][1] * factor;
bFactor = sHeartsEnvFactors[0][2] * factor; bFactor = sHeartsEnvFactors[0][2] * factor;
if (1) {}
ddType = type;
interfaceCtx->beatingHeartEnv[0] = (u8)(rFactor + HEARTS_ENV_R) & 0xFF; interfaceCtx->beatingHeartEnv[0] = (u8)(rFactor + HEARTS_ENV_R) & 0xFF;
interfaceCtx->beatingHeartEnv[1] = (u8)(gFactor + HEARTS_ENV_G) & 0xFF; interfaceCtx->beatingHeartEnv[1] = (u8)(gFactor + HEARTS_ENV_G) & 0xFF;
interfaceCtx->beatingHeartEnv[2] = (u8)(bFactor + HEARTS_ENV_B) & 0xFF; interfaceCtx->beatingHeartEnv[2] = (u8)(bFactor + HEARTS_ENV_B) & 0xFF;
sHeartsDDPrim[0][0] = HEARTS_DD_PRIM_R; ddType = type;
sHeartsDDPrim[0][1] = HEARTS_DD_PRIM_G;
sHeartsDDPrim[0][2] = HEARTS_DD_PRIM_B;
sHeartsDDEnv[0][0] = HEARTS_DD_ENV_R; sHeartsDDPrim[0][0] = HeartDDOutline[0];
sHeartsDDEnv[0][1] = HEARTS_DD_ENV_G; sHeartsDDPrim[0][1] = HeartDDOutline[1];
sHeartsDDEnv[0][2] = HEARTS_DD_ENV_B; sHeartsDDPrim[0][2] = HeartDDOutline[2];
sHeartsDDPrim[1][0] = sHeartsDDPrimColors[ddType][0]; sHeartsDDEnv[0][0] = HeartDDInner[0];
sHeartsDDPrim[1][1] = sHeartsDDPrimColors[ddType][1]; sHeartsDDEnv[0][1] = HeartDDInner[1];
sHeartsDDPrim[1][2] = sHeartsDDPrimColors[ddType][2]; sHeartsDDEnv[0][2] = HeartDDInner[2];
sHeartsDDEnv[1][0] = sHeartsDDEnvColors[ddType][0]; if (CVar_GetS32("gHudColors", 1) == 2) {
sHeartsDDEnv[1][1] = sHeartsDDEnvColors[ddType][1]; sHeartsDDPrim[2][0] = HeartInner[0];
sHeartsDDEnv[1][2] = sHeartsDDEnvColors[ddType][2]; sHeartsDDPrim[2][1] = HeartInner[1];
sHeartsDDPrim[2][2] = HeartInner[2];
rFactor = sHeartsDDPrimFactors[ddType][0] * ddFactor; sHeartsDDPrim[1][0] = HeartDDOutline[0];
gFactor = sHeartsDDPrimFactors[ddType][1] * ddFactor; sHeartsDDPrim[1][1] = HeartDDOutline[1];
bFactor = sHeartsDDPrimFactors[ddType][2] * ddFactor; sHeartsDDPrim[1][2] = HeartDDOutline[2];
sBeatingHeartsDDPrim[0] = (u8)(rFactor + HEARTS_DD_PRIM_R) & 0xFF; sHeartsDDEnv[1][0] = HeartDDInner[0];
sBeatingHeartsDDPrim[1] = (u8)(gFactor + HEARTS_DD_PRIM_G) & 0xFF; sHeartsDDEnv[1][1] = HeartDDInner[1];
sBeatingHeartsDDPrim[2] = (u8)(bFactor + HEARTS_DD_PRIM_B) & 0xFF; sHeartsDDEnv[1][2] = HeartDDInner[2];
rFactor = sHeartsDDEnvFactors[ddType][0] * ddFactor; HeartDDInner[0] = HeartInner[0];
gFactor = sHeartsDDEnvFactors[ddType][1] * ddFactor; HeartDDInner[1] = HeartInner[1];
bFactor = sHeartsDDEnvFactors[ddType][2] * ddFactor; HeartDDInner[2] = HeartInner[2];
rFactor = sHeartsDDPrimFactors[ddType][0] * ddFactor;
gFactor = sHeartsDDPrimFactors[ddType][1] * ddFactor;
bFactor = sHeartsDDPrimFactors[ddType][2] * ddFactor;
sBeatingHeartsDDPrim[0] = (u8)(rFactor + HeartDDOutline[0]) & 0xFF;
sBeatingHeartsDDPrim[1] = (u8)(gFactor + HeartDDOutline[1]) & 0xFF;
sBeatingHeartsDDPrim[2] = (u8)(bFactor + HeartDDOutline[2]) & 0xFF;
rFactor = sHeartsDDEnvFactors[ddType][0] * ddFactor;
gFactor = sHeartsDDEnvFactors[ddType][1] * ddFactor;
bFactor = sHeartsDDEnvFactors[ddType][2] * ddFactor;
sBeatingHeartsDDEnv[0] = (u8)(rFactor + HeartDDInner[0]) & 0xFF;
sBeatingHeartsDDEnv[1] = (u8)(gFactor + HeartDDInner[1]) & 0xFF;
sBeatingHeartsDDEnv[2] = (u8)(bFactor + HeartDDInner[2]) & 0xFF;
} else {
sHeartsDDPrim[2][0] = HEARTS_PRIM_R;
sHeartsDDPrim[2][1] = HEARTS_PRIM_G;
sHeartsDDPrim[2][2] = HEARTS_PRIM_B;
sHeartsDDPrim[1][0] = HEARTS_DD_PRIM_R;
sHeartsDDPrim[1][1] = HEARTS_DD_PRIM_G;
sHeartsDDPrim[1][2] = HEARTS_DD_PRIM_B;
sHeartsDDEnv[1][0] = HEARTS_PRIM_R;
sHeartsDDEnv[1][1] = HEARTS_PRIM_G;
sHeartsDDEnv[1][2] = HEARTS_PRIM_B;
rFactor = sHeartsDDPrimFactors[ddType][0] * ddFactor;
gFactor = sHeartsDDPrimFactors[ddType][1] * ddFactor;
bFactor = sHeartsDDPrimFactors[ddType][2] * ddFactor;
sBeatingHeartsDDPrim[0] = (u8)(rFactor + HEARTS_DD_PRIM_R) & 0xFF;
sBeatingHeartsDDPrim[1] = (u8)(gFactor + HEARTS_DD_PRIM_G) & 0xFF;
sBeatingHeartsDDPrim[2] = (u8)(bFactor + HEARTS_DD_PRIM_B) & 0xFF;
rFactor = sHeartsDDEnvFactors[ddType][0] * ddFactor;
gFactor = sHeartsDDEnvFactors[ddType][1] * ddFactor;
bFactor = sHeartsDDEnvFactors[ddType][2] * ddFactor;
sBeatingHeartsDDEnv[0] = (u8)(rFactor + HEARTS_PRIM_R) & 0xFF;
sBeatingHeartsDDEnv[1] = (u8)(gFactor + HEARTS_PRIM_G) & 0xFF;
sBeatingHeartsDDEnv[2] = (u8)(bFactor + HEARTS_PRIM_B) & 0xFF;
}
sBeatingHeartsDDEnv[0] = (u8)(rFactor + HEARTS_DD_ENV_R) & 0xFF;
sBeatingHeartsDDEnv[1] = (u8)(gFactor + HEARTS_DD_ENV_G) & 0xFF;
sBeatingHeartsDDEnv[2] = (u8)(bFactor + HEARTS_DD_ENV_B) & 0xFF;
} }
s32 func_80078E18(GlobalContext* globalCtx) { s32 func_80078E18(GlobalContext* globalCtx) {
@ -322,8 +419,8 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
} }
curColorSet = -1; curColorSet = -1;
offsetY = 0.0f; offsetY = 0.0f+(Top_LM_Margin*-1);
offsetX = OTRGetDimensionFromLeftEdge(0.0f); offsetX = OTRGetDimensionFromLeftEdge(0.0f)+(Left_LM_Margin*-1);
for (i = 0; i < totalHeartCount; i++) { for (i = 0; i < totalHeartCount; i++) {
if ((ddHeartCountMinusOne < 0) || (i > ddHeartCountMinusOne)) { if ((ddHeartCountMinusOne < 0) || (i > ddHeartCountMinusOne)) {
@ -483,7 +580,7 @@ void HealthMeter_Draw(GlobalContext* globalCtx) {
offsetX += 10.0f; offsetX += 10.0f;
if (i == 9) { if (i == 9) {
offsetY += 10.0f; offsetY += 10.0f;
offsetX = OTRGetDimensionFromLeftEdge(0.0f); offsetX = OTRGetDimensionFromLeftEdge(0.0f)+(Left_LM_Margin*-1);
} }
} }
@ -498,8 +595,8 @@ void HealthMeter_HandleCriticalAlarm(GlobalContext* globalCtx) {
if (interfaceCtx->unk_22A <= 0) { if (interfaceCtx->unk_22A <= 0) {
interfaceCtx->unk_22A = 0; interfaceCtx->unk_22A = 0;
interfaceCtx->unk_22C = 0; interfaceCtx->unk_22C = 0;
if (!Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) && if (CVar_GetS32("gLowHpAlarm", 0) == 0 && !Player_InCsMode(globalCtx) && (globalCtx->pauseCtx.state == 0) &&
(globalCtx->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Gameplay_InCsMode(globalCtx)) { (globalCtx->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Gameplay_InCsMode(globalCtx)) {
func_80078884(NA_SE_SY_HITPOINT_ALARM); func_80078884(NA_SE_SY_HITPOINT_ALARM);
} }
} }
@ -530,4 +627,4 @@ u32 HealthMeter_IsCritical(void) {
} else { } else {
return false; return false;
} }
} }

View file

@ -12,6 +12,11 @@ s16 sPlayerInitialPosZ = 0;
s16 sPlayerInitialDirection = 0; s16 sPlayerInitialDirection = 0;
s16 sEntranceIconMapIndex = 0; s16 sEntranceIconMapIndex = 0;
s16 Top_MM_Margin = 0;
s16 Left_MM_Margin = 0;
s16 Right_MM_Margin = 0;
s16 Bottom_MM_Margin = 0;
void Map_SavePlayerInitialInfo(GlobalContext* globalCtx) { void Map_SavePlayerInitialInfo(GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx); Player* player = GET_PLAYER(globalCtx);
@ -604,11 +609,11 @@ void Minimap_DrawCompassIcons(GlobalContext* globalCtx) {
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
gDPSetCombineMode(OVERLAY_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); gDPSetCombineMode(OVERLAY_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE);
tempX = player->actor.world.pos.x; tempX = player->actor.world.pos.x+Right_MM_Margin;
tempZ = player->actor.world.pos.z; tempZ = player->actor.world.pos.z+Bottom_MM_Margin;
tempX /= R_COMPASS_SCALE_X; tempX /= R_COMPASS_SCALE_X;
tempZ /= R_COMPASS_SCALE_Y; tempZ /= R_COMPASS_SCALE_Y;
Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X + tempX) / 10.0f), (R_COMPASS_OFFSET_Y - tempZ) / 10.0f, 0.0f, MTXMODE_NEW); Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X+(Right_MM_Margin*10) + tempX) / 10.0f), (R_COMPASS_OFFSET_Y+((Bottom_MM_Margin*10)*-1) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
Matrix_Scale(0.4f, 0.4f, 0.4f, MTXMODE_APPLY); Matrix_Scale(0.4f, 0.4f, 0.4f, MTXMODE_APPLY);
Matrix_RotateX(-1.6f, MTXMODE_APPLY); Matrix_RotateX(-1.6f, MTXMODE_APPLY);
tempX = (0x7FFF - player->actor.shape.rot.y) / 0x400; tempX = (0x7FFF - player->actor.shape.rot.y) / 0x400;
@ -619,11 +624,11 @@ void Minimap_DrawCompassIcons(GlobalContext* globalCtx) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 255, 0, 255); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 255, 0, 255);
gSPDisplayList(OVERLAY_DISP++, gCompassArrowDL); gSPDisplayList(OVERLAY_DISP++, gCompassArrowDL);
tempX = sPlayerInitialPosX; tempX = sPlayerInitialPosX+Right_MM_Margin;
tempZ = sPlayerInitialPosZ; tempZ = sPlayerInitialPosZ+Bottom_MM_Margin;
tempX /= R_COMPASS_SCALE_X; tempX /= R_COMPASS_SCALE_X;
tempZ /= R_COMPASS_SCALE_Y; tempZ /= R_COMPASS_SCALE_Y;
Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X + tempX) / 10.0f), (R_COMPASS_OFFSET_Y - tempZ) / 10.0f, 0.0f, MTXMODE_NEW); Matrix_Translate(OTRGetDimensionFromRightEdge((R_COMPASS_OFFSET_X+(Right_MM_Margin*10) + tempX) / 10.0f), (R_COMPASS_OFFSET_Y+((Bottom_MM_Margin*10)*-1) - tempZ) / 10.0f, 0.0f, MTXMODE_NEW);
Matrix_Scale(VREG(9) / 100.0f, VREG(9) / 100.0f, VREG(9) / 100.0f, MTXMODE_APPLY); Matrix_Scale(VREG(9) / 100.0f, VREG(9) / 100.0f, VREG(9) / 100.0f, MTXMODE_APPLY);
Matrix_RotateX(VREG(52) / 10.0f, MTXMODE_APPLY); Matrix_RotateX(VREG(52) / 10.0f, MTXMODE_APPLY);
Matrix_RotateY(sPlayerInitialDirection / 10.0f, MTXMODE_APPLY); Matrix_RotateY(sPlayerInitialDirection / 10.0f, MTXMODE_APPLY);
@ -662,17 +667,22 @@ void Minimap_Draw(GlobalContext* globalCtx) {
TEXEL0, 0, PRIMITIVE, 0); TEXEL0, 0, PRIMITIVE, 0);
if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, mapIndex)) { if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, mapIndex)) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 255, 255, interfaceCtx->minimapAlpha); if (CVar_GetS32("gHudColors", 1) == 2) { //Dungeon minimap
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCMinimapPrimR", R_MINIMAP_COLOR(0)), CVar_GetS32("gCCMinimapPrimG", R_MINIMAP_COLOR(1)), CVar_GetS32("gCCMinimapPrimB", R_MINIMAP_COLOR(2)), interfaceCtx->minimapAlpha);
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 100, 255, 255, interfaceCtx->minimapAlpha);
}
gSPInvalidateTexCache(OVERLAY_DISP++, interfaceCtx->mapSegment); gSPInvalidateTexCache(OVERLAY_DISP++, interfaceCtx->mapSegment);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegment, G_IM_FMT_I, 96, 85, 0, gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegment, G_IM_FMT_I, 96, 85, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
const s16 dgnMiniMapX = OTRGetRectDimensionFromRightEdge(R_DGN_MINIMAP_X); const s16 dgnMiniMapX = OTRGetRectDimensionFromRightEdge(R_DGN_MINIMAP_X + Right_MM_Margin);
const s16 dgnMiniMapY = R_DGN_MINIMAP_Y + Bottom_MM_Margin;
gSPWideTextureRectangle(OVERLAY_DISP++, dgnMiniMapX << 2, R_DGN_MINIMAP_Y << 2, gSPWideTextureRectangle(OVERLAY_DISP++, dgnMiniMapX << 2, dgnMiniMapY << 2,
(dgnMiniMapX + 96) << 2, (R_DGN_MINIMAP_Y + 85) << 2, G_TX_RENDERTILE, (dgnMiniMapX + 96) << 2, (dgnMiniMapY + 85) << 2, G_TX_RENDERTILE,
0, 0, 1 << 10, 1 << 10); 0, 0, 1 << 10, 1 << 10);
} }
@ -719,27 +729,35 @@ void Minimap_Draw(GlobalContext* globalCtx) {
func_80094520(globalCtx->state.gfxCtx); func_80094520(globalCtx->state.gfxCtx);
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MINIMAP_COLOR(0), R_MINIMAP_COLOR(1), R_MINIMAP_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 2) {//Overworld minimap
interfaceCtx->minimapAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCMinimapPrimR", R_MINIMAP_COLOR(0)), CVar_GetS32("gCCMinimapPrimG", R_MINIMAP_COLOR(1)), CVar_GetS32("gCCMinimapPrimB", R_MINIMAP_COLOR(2)), interfaceCtx->minimapAlpha);
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MINIMAP_COLOR(0), R_MINIMAP_COLOR(1), R_MINIMAP_COLOR(2), interfaceCtx->minimapAlpha);
}
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegment, G_IM_FMT_IA, gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->mapSegment, G_IM_FMT_IA,
gMapData->owMinimapWidth[mapIndex], gMapData->owMinimapHeight[mapIndex], 0, gMapData->owMinimapWidth[mapIndex], gMapData->owMinimapHeight[mapIndex], 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
const s16 oWMiniMapX = OTRGetRectDimensionFromRightEdge(R_OW_MINIMAP_X); const s16 oWMiniMapX = OTRGetRectDimensionFromRightEdge(R_OW_MINIMAP_X + Right_MM_Margin);
const s16 oWMiniMapY = R_OW_MINIMAP_Y + Bottom_MM_Margin;
gSPWideTextureRectangle(OVERLAY_DISP++, oWMiniMapX << 2, R_OW_MINIMAP_Y << 2, gSPWideTextureRectangle(OVERLAY_DISP++, oWMiniMapX << 2, oWMiniMapY << 2,
(oWMiniMapX + gMapData->owMinimapWidth[mapIndex]) << 2, (oWMiniMapX + gMapData->owMinimapWidth[mapIndex]) << 2,
(R_OW_MINIMAP_Y + gMapData->owMinimapHeight[mapIndex]) << 2, G_TX_RENDERTILE, 0, (oWMiniMapY + gMapData->owMinimapHeight[mapIndex]) << 2, G_TX_RENDERTILE, 0,
0, 1 << 10, 1 << 10); 0, 1 << 10, 1 << 10);
if (CVar_GetS32("gHudColors", 1) != 2) {//This need to be added else it will color dungeon entrance icon too. (it re-init prim color to default color)
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MINIMAP_COLOR(0), R_MINIMAP_COLOR(1), R_MINIMAP_COLOR(2), interfaceCtx->minimapAlpha);
}
if (((globalCtx->sceneNum != SCENE_SPOT01) && (globalCtx->sceneNum != SCENE_SPOT04) && if (((globalCtx->sceneNum != SCENE_SPOT01) && (globalCtx->sceneNum != SCENE_SPOT04) &&
(globalCtx->sceneNum != SCENE_SPOT08)) || (globalCtx->sceneNum != SCENE_SPOT08)) ||
(LINK_AGE_IN_YEARS != YEARS_ADULT)) { (LINK_AGE_IN_YEARS != YEARS_ADULT)) {
s16 IconSize = 8; s16 IconSize = 8;
s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex]; s16 PosX = gMapData->owEntranceIconPosX[sEntranceIconMapIndex]+Right_MM_Margin;
s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex]; s16 PosY = gMapData->owEntranceIconPosY[sEntranceIconMapIndex]+Bottom_MM_Margin;
//gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed. //gFixDungeonMinimapIcon fix both Y position of visible icon and hide these non needed.
if (CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){ if (CVar_GetS32("gFixDungeonMinimapIcon", 1) != 0){
//No idea why and how Original value work but this does actually fix them all. //No idea why and how Original value work but this does actually fix them all.
@ -766,14 +784,20 @@ void Minimap_Draw(GlobalContext* globalCtx) {
} }
} }
const s16 entranceX = OTRGetRectDimensionFromRightEdge(270 + Right_MM_Margin);
const s16 entranceY = 154 + Bottom_MM_Margin;
if ((globalCtx->sceneNum == SCENE_SPOT08) && (gSaveContext.infTable[26] & gBitFlags[9])) { if ((globalCtx->sceneNum == SCENE_SPOT08) && (gSaveContext.infTable[26] & gBitFlags[9])) {
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8,
8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + 32) << 2, (entranceY + 8) << 2,
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
} else if ((globalCtx->sceneNum == SCENE_SPOT08) && CVar_GetS32("gAlwaysShowDungeonMinimapIcon", 0) != 0){
gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, gDPLoadTextureBlock(OVERLAY_DISP++, gMapDungeonEntranceIconTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8,
8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, 8, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
const s16 entranceX = OTRGetRectDimensionFromRightEdge(270); gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, entranceY << 2, (entranceX + 32) << 2, (entranceY + 8) << 2,
gSPWideTextureRectangle(OVERLAY_DISP++, entranceX << 2, 154 << 2, (entranceX + 32) << 2, (154 + 8) << 2,
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
} }
@ -809,6 +833,18 @@ void Map_Update(GlobalContext* globalCtx) {
s16 floor; s16 floor;
s16 i; s16 i;
if (CVar_GetS32("gHUDMargins", 0) != 0) {
Top_MM_Margin = CVar_GetS32("gHUDMargin_T", 0);
Left_MM_Margin = CVar_GetS32("gHUDMargin_L", 0);
Right_MM_Margin = CVar_GetS32("gHUDMargin_R", 0);
Bottom_MM_Margin = CVar_GetS32("gHUDMargin_B", 0);
} else {
Top_MM_Margin = 0;
Left_MM_Margin = 0;
Right_MM_Margin = 0;
Bottom_MM_Margin = 0;
}
if ((globalCtx->pauseCtx.state == 0) && (globalCtx->pauseCtx.debugState == 0)) { if ((globalCtx->pauseCtx.state == 0) && (globalCtx->pauseCtx.debugState == 0)) {
switch (globalCtx->sceneNum) { switch (globalCtx->sceneNum) {
case SCENE_YDAN: case SCENE_YDAN:

View file

@ -108,6 +108,22 @@ void MapMark_DrawForDungeon(GlobalContext* globalCtx) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->minimapAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->minimapAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, interfaceCtx->minimapAlpha); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, interfaceCtx->minimapAlpha);
s16 Top_MC_Margin = 0;
s16 Left_MC_Margin = 0;
s16 Right_MC_Margin = 0;
s16 Bottom_MC_Margin = 0;
if (CVar_GetS32("gHUDMargins", 0) != 0) {
Top_MC_Margin = CVar_GetS32("gHUDMargin_T", 0);
Left_MC_Margin = CVar_GetS32("gHUDMargin_L", 0);
Right_MC_Margin = CVar_GetS32("gHUDMargin_R", 0);
Bottom_MC_Margin = CVar_GetS32("gHUDMargin_B", 0);
} else {
Top_MC_Margin = 0;
Left_MC_Margin = 0;
Right_MC_Margin = 0;
Bottom_MC_Margin = 0;
}
markPoint = &mapMarkIconData->points[0]; markPoint = &mapMarkIconData->points[0];
for (i = 0; i < mapMarkIconData->count; i++) { for (i = 0; i < mapMarkIconData->count; i++) {
if ((mapMarkIconData->markType != MAP_MARK_CHEST) || !Flags_GetTreasure(globalCtx, markPoint->chestFlag)) { if ((mapMarkIconData->markType != MAP_MARK_CHEST) || !Flags_GetTreasure(globalCtx, markPoint->chestFlag)) {
@ -118,8 +134,8 @@ void MapMark_DrawForDungeon(GlobalContext* globalCtx) {
markInfo->textureWidth, markInfo->textureHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, markInfo->textureWidth, markInfo->textureHeight, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
rectLeft = (GREG(94) + OTRGetRectDimensionFromRightEdge(markPoint->x) + 204) << 2; rectLeft = (GREG(94) + OTRGetRectDimensionFromRightEdge(markPoint->x+Right_MC_Margin) + 204) << 2;
rectTop = (GREG(95) + markPoint->y + 140) << 2; rectTop = (GREG(95) + markPoint->y + Bottom_MC_Margin + 140) << 2;
gSPTextureRectangle(OVERLAY_DISP++, rectLeft, rectTop, markInfo->rectWidth + rectLeft, gSPTextureRectangle(OVERLAY_DISP++, rectLeft, rectTop, markInfo->rectWidth + rectLeft,
rectTop + markInfo->rectHeight, G_TX_RENDERTILE, 0, 0, markInfo->dsdx, rectTop + markInfo->rectHeight, G_TX_RENDERTILE, 0, 0, markInfo->dsdx,
markInfo->dtdy); markInfo->dtdy);

View file

@ -272,6 +272,13 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) {
const char** languageSegmentTable; const char** languageSegmentTable;
Font* font; Font* font;
const char* seg; const char* seg;
u16 bufferId = textId;
// Use the better owl message if better owl is enabled
if (CVar_GetS32("gBetterOwl", 0) != 0 && (bufferId == 0x2066 || bufferId == 0x607B ||
bufferId == 0x10C2 || bufferId == 0x10C6 || bufferId == 0x206A))
{
bufferId = 0x71B3;
}
if (gSaveContext.language == LANGUAGE_GER) if (gSaveContext.language == LANGUAGE_GER)
messageTableEntry = sGerMessageEntryTablePtr; messageTableEntry = sGerMessageEntryTablePtr;
@ -287,7 +294,7 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) {
while (messageTableEntry->textId != 0xFFFF) { while (messageTableEntry->textId != 0xFFFF) {
font = &globalCtx->msgCtx.font; font = &globalCtx->msgCtx.font;
if (messageTableEntry->textId == textId) { if (messageTableEntry->textId == bufferId) {
foundSeg = messageTableEntry->segment; foundSeg = messageTableEntry->segment;
font->charTexBuf[0] = messageTableEntry->typePos; font->charTexBuf[0] = messageTableEntry->typePos;
@ -298,14 +305,14 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) {
// "Message found!!!" // "Message found!!!"
osSyncPrintf(" メッセージが,見つかった!!! = %x " osSyncPrintf(" メッセージが,見つかった!!! = %x "
"(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n", "(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n",
textId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); bufferId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg);
return; return;
} }
messageTableEntry++; messageTableEntry++;
} }
// "Message not found!!!" // "Message not found!!!"
osSyncPrintf(" メッセージが,見つからなかった!!! = %x\n", textId); osSyncPrintf(" メッセージが,見つからなかった!!! = %x\n", bufferId);
font = &globalCtx->msgCtx.font; font = &globalCtx->msgCtx.font;
messageTableEntry = sNesMessageEntryTablePtr; messageTableEntry = sNesMessageEntryTablePtr;
@ -446,6 +453,46 @@ void Message_DrawTextboxIcon(GlobalContext* globalCtx, Gfx** p, s16 x, s16 y) {
static s16 sIconEnvR = 0; static s16 sIconEnvR = 0;
static s16 sIconEnvG = 0; static s16 sIconEnvG = 0;
static s16 sIconEnvB = 0; static s16 sIconEnvB = 0;
if (CVar_GetS32("gHudColors", 1) == 0) {
sIconPrimColors[0][0] = 4;
sIconPrimColors[0][1] = 84;
sIconPrimColors[0][2] = 204;
sIconPrimColors[1][0] = 45;
sIconPrimColors[1][1] = 125;
sIconPrimColors[1][2] = 255;
sIconEnvColors[0][0] = 0;
sIconEnvColors[0][1] = 0;
sIconEnvColors[0][2] = 0;
sIconEnvColors[1][0] = 0;
sIconEnvColors[1][1] = 70;
sIconEnvColors[1][2] = 255;
} else if (CVar_GetS32("gHudColors", 1) == 1) {
sIconPrimColors[0][0] = 4;
sIconPrimColors[0][1] = 200;
sIconPrimColors[0][2] = 80;
sIconPrimColors[1][0] = 50;
sIconPrimColors[1][1] = 255;
sIconPrimColors[1][2] = 130;
sIconEnvColors[0][0] = 0;
sIconEnvColors[0][1] = 0;
sIconEnvColors[0][2] = 0;
sIconEnvColors[1][0] = 0;
sIconEnvColors[1][1] = 255;
sIconEnvColors[1][2] = 130;
} else if (CVar_GetS32("gHudColors", 1) == 2) {
sIconPrimColors[0][0] = (CVar_GetS32("gCCABtnPrimR", 50)/255)*95;
sIconPrimColors[0][1] = (CVar_GetS32("gCCABtnPrimG", 255)/255)*95;
sIconPrimColors[0][2] = (CVar_GetS32("gCCABtnPrimB", 130)/255)*95;
sIconPrimColors[1][0] = CVar_GetS32("gCCABtnPrimR", 50);
sIconPrimColors[1][1] = CVar_GetS32("gCCABtnPrimG", 255);
sIconPrimColors[1][2] = CVar_GetS32("gCCABtnPrimB", 130);
sIconEnvColors[0][0] = 0;
sIconEnvColors[0][1] = 0;
sIconEnvColors[0][2] = 0;
sIconEnvColors[1][0] = 10;
sIconEnvColors[1][1] = 10;
sIconEnvColors[1][2] = 10;
}
MessageContext* msgCtx = &globalCtx->msgCtx; MessageContext* msgCtx = &globalCtx->msgCtx;
Font* font = &msgCtx->font; Font* font = &msgCtx->font;
Gfx* gfx = *p; Gfx* gfx = *p;
@ -1843,6 +1890,7 @@ void Message_DrawTextBox(GlobalContext* globalCtx, Gfx** p) {
MessageContext* msgCtx = &globalCtx->msgCtx; MessageContext* msgCtx = &globalCtx->msgCtx;
Gfx* gfx = *p; Gfx* gfx = *p;
gSPInvalidateTexCache(gfx++, msgCtx->textboxSegment);
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
gDPSetPrimColor(gfx++, 0, 0, msgCtx->textboxColorRed, msgCtx->textboxColorGreen, msgCtx->textboxColorBlue, gDPSetPrimColor(gfx++, 0, 0, msgCtx->textboxColorRed, msgCtx->textboxColorGreen, msgCtx->textboxColorBlue,
msgCtx->textboxColorAlphaCurrent); msgCtx->textboxColorAlphaCurrent);
@ -2828,12 +2876,22 @@ void Message_DrawMain(GlobalContext* globalCtx, Gfx** p) {
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
if (sOcarinaNoteBuf[i] == OCARINA_NOTE_A) { if (sOcarinaNoteBuf[i] == OCARINA_NOTE_A) {
gDPSetPrimColor(gfx++, 0, 0, sOcarinaNoteAPrimR, sOcarinaNoteAPrimG, sOcarinaNoteAPrimB, if (CVar_GetS32("gHudColors", 1) == 0) { //A buttons :)
sOcarinaNotesAlphaValues[i]); gDPSetPrimColor(gfx++, 0, 0, 80, 150, 255, sOcarinaNotesAlphaValues[i]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(gfx++, 0, 0, sOcarinaNoteAPrimR, sOcarinaNoteAPrimG, sOcarinaNoteAPrimB, sOcarinaNotesAlphaValues[i]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(gfx++, 0, 0, CVar_GetS32("gCCABtnPrimR", 0), CVar_GetS32("gCCABtnPrimG", 0), CVar_GetS32("gCCABtnPrimB", 0), sOcarinaNotesAlphaValues[i]);
}
gDPSetEnvColor(gfx++, sOcarinaNoteAEnvR, sOcarinaNoteAEnvG, sOcarinaNoteAEnvB, 0); gDPSetEnvColor(gfx++, sOcarinaNoteAEnvR, sOcarinaNoteAEnvG, sOcarinaNoteAEnvB, 0);
} else { } else {
gDPSetPrimColor(gfx++, 0, 0, sOcarinaNoteCPrimR, sOcarinaNoteCPrimG, sOcarinaNoteCPrimB, if (CVar_GetS32("gHudColors", 1) == 0) { //C buttons :)
sOcarinaNotesAlphaValues[i]); gDPSetPrimColor(gfx++, 0, 0, sOcarinaNoteCPrimR, sOcarinaNoteCPrimG, sOcarinaNoteCPrimB, sOcarinaNotesAlphaValues[i]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(gfx++, 0, 0, sOcarinaNoteCPrimR, sOcarinaNoteCPrimG, sOcarinaNoteCPrimB, sOcarinaNotesAlphaValues[i]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(gfx++, 0, 0, CVar_GetS32("gCCCBtnPrimR", 0), CVar_GetS32("gCCCBtnPrimG", 0), CVar_GetS32("gCCCBtnPrimB", 0), sOcarinaNotesAlphaValues[i]);
}
gDPSetEnvColor(gfx++, sOcarinaNoteCEnvR, sOcarinaNoteCEnvG, sOcarinaNoteCEnvB, 0); gDPSetEnvColor(gfx++, sOcarinaNoteCEnvR, sOcarinaNoteCEnvG, sOcarinaNoteCEnvB, 0);
} }

View file

@ -15,6 +15,11 @@
#define DO_ACTION_TEX_HEIGHT 16 #define DO_ACTION_TEX_HEIGHT 16
#define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2) // (sizeof(gCheckDoActionENGTex)) #define DO_ACTION_TEX_SIZE ((DO_ACTION_TEX_WIDTH * DO_ACTION_TEX_HEIGHT) / 2) // (sizeof(gCheckDoActionENGTex))
s16 Top_HUD_Margin = 0;
s16 Left_HUD_Margin = 0;
s16 Right_HUD_Margin = 0;
s16 Bottom_HUD_Margin = 0;
typedef struct { typedef struct {
/* 0x00 */ u8 scene; /* 0x00 */ u8 scene;
/* 0x01 */ u8 flags1; /* 0x01 */ u8 flags1;
@ -753,7 +758,15 @@ void func_80083108(GlobalContext* globalCtx) {
gSaveContext.buttonStatus[0] = BTN_DISABLED; gSaveContext.buttonStatus[0] = BTN_DISABLED;
for (i = 1; i < 4; i++) { for (i = 1; i < 4; i++) {
if (func_8008F2F8(globalCtx) == 2) { if ((gSaveContext.equips.buttonItems[i] >= ITEM_SHIELD_DEKU) &&
(gSaveContext.equips.buttonItems[i] <= ITEM_BOOTS_HOVER)) {
// Equipment on c-buttons is always enabled
if (gSaveContext.buttonStatus[i] == BTN_DISABLED) {
sp28 = 1;
}
gSaveContext.buttonStatus[i] = BTN_ENABLED;
} else if (func_8008F2F8(globalCtx) == 2) {
if ((gSaveContext.equips.buttonItems[i] != ITEM_HOOKSHOT) && if ((gSaveContext.equips.buttonItems[i] != ITEM_HOOKSHOT) &&
(gSaveContext.equips.buttonItems[i] != ITEM_LONGSHOT)) { (gSaveContext.equips.buttonItems[i] != ITEM_LONGSHOT)) {
if (gSaveContext.buttonStatus[i] == BTN_ENABLED) { if (gSaveContext.buttonStatus[i] == BTN_ENABLED) {
@ -1795,7 +1808,7 @@ u8 Item_Give(GlobalContext* globalCtx, u8 item) {
} }
} }
} else if ((item >= ITEM_WEIRD_EGG) && (item <= ITEM_CLAIM_CHECK)) { } else if ((item >= ITEM_WEIRD_EGG) && (item <= ITEM_CLAIM_CHECK)) {
if (item == ITEM_SAW) { if ((item == ITEM_SAW) && CVar_GetS32("gDekuNutUpgradeFix", 0) == 0) {
gSaveContext.itemGetInf[1] |= 0x8000; gSaveContext.itemGetInf[1] |= 0x8000;
} }
@ -2151,13 +2164,15 @@ void Interface_SetNaviCall(GlobalContext* globalCtx, u16 naviCallState) {
if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling && if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling &&
(globalCtx->csCtx.state == CS_STATE_IDLE)) { (globalCtx->csCtx.state == CS_STATE_IDLE)) {
// clang-format off if (!CVar_GetS32("gDisableNaviCallAudio", 0)) {
if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &D_801333D4, 4, // clang-format off
&D_801333E0, &D_801333E0, &D_801333E8); } if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &D_801333D4, 4,
// clang-format on &D_801333E0, &D_801333E0, &D_801333E8); }
// clang-format on
if (naviCallState == 0x1D) { if (naviCallState == 0x1D) {
func_800F4524(&D_801333D4, NA_SE_VO_NA_HELLO_2, 32); func_800F4524(&D_801333D4, NA_SE_VO_NA_HELLO_2, 32);
}
} }
interfaceCtx->naviCalling = 1; interfaceCtx->naviCalling = 1;
@ -2433,6 +2448,25 @@ void Interface_UpdateMagicBar(GlobalContext* globalCtx) {
{ 255, 255, 150 }, { 255, 255, 150 },
{ 255, 255, 50 }, { 255, 255, 50 },
}; };
if (CVar_GetS32("gHudColors", 1) == 2) { //This will make custom color based on users selected colors.
sMagicBorderColors[0][0] = CVar_GetS32("gCCMagicBorderPrimR", 255);
sMagicBorderColors[0][1] = CVar_GetS32("gCCMagicBorderPrimG", 255);
sMagicBorderColors[0][2] = CVar_GetS32("gCCMagicBorderPrimB", 255);
sMagicBorderColors[1][0] = CVar_GetS32("gCCMagicBorderPrimR", 255)/2;
sMagicBorderColors[1][1] = CVar_GetS32("gCCMagicBorderPrimG", 255)/2;
sMagicBorderColors[1][2] = CVar_GetS32("gCCMagicBorderPrimB", 255)/2;
sMagicBorderColors[2][0] = CVar_GetS32("gCCMagicBorderPrimR", 255)/3;
sMagicBorderColors[2][1] = CVar_GetS32("gCCMagicBorderPrimG", 255)/3;
sMagicBorderColors[2][2] = CVar_GetS32("gCCMagicBorderPrimB", 255)/3;
sMagicBorderColors[3][0] = CVar_GetS32("gCCMagicBorderPrimR", 255)/2;
sMagicBorderColors[3][1] = CVar_GetS32("gCCMagicBorderPrimG", 255)/2;
sMagicBorderColors[3][2] = CVar_GetS32("gCCMagicBorderPrimB", 255)/2;
}
static s16 sMagicBorderIndexes[] = { 0, 1, 1, 0 }; static s16 sMagicBorderIndexes[] = { 0, 1, 1, 0 };
static s16 sMagicBorderRatio = 2; static s16 sMagicBorderRatio = 2;
static s16 sMagicBorderStep = 1; static s16 sMagicBorderStep = 1;
@ -2623,27 +2657,31 @@ void Interface_DrawMagicBar(GlobalContext* globalCtx) {
if (gSaveContext.magicLevel != 0) { if (gSaveContext.magicLevel != 0) {
if (gSaveContext.healthCapacity > 0xA0) { if (gSaveContext.healthCapacity > 0xA0) {
magicBarY = R_MAGIC_BAR_LARGE_Y; magicBarY = R_MAGIC_BAR_LARGE_Y + (Top_HUD_Margin*-1);
} else { } else {
magicBarY = R_MAGIC_BAR_SMALL_Y; magicBarY = R_MAGIC_BAR_SMALL_Y + (Top_HUD_Margin*-1);
} }
func_80094520(globalCtx->state.gfxCtx); func_80094520(globalCtx->state.gfxCtx);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sMagicBorderR, sMagicBorderG, sMagicBorderB, interfaceCtx->magicAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, sMagicBorderR, sMagicBorderG, sMagicBorderB, interfaceCtx->magicAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 100, 50, 50, 255); if (CVar_GetS32("gHudColors", 1) == 2) {//Original game add color there so to prevent miss match we make it all white :)
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
} else {
gDPSetEnvColor(OVERLAY_DISP++, 100, 50, 50, 255);
}
OVERLAY_DISP = OVERLAY_DISP =
Gfx_TextureIA8(OVERLAY_DISP, gMagicBarEndTex, 8, 16, OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X), Gfx_TextureIA8(OVERLAY_DISP, gMagicBarEndTex, 8, 16, OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X + (Left_HUD_Margin*-1)),
magicBarY, 8, 16, 1 << 10, 1 << 10); magicBarY, 8, 16, 1 << 10, 1 << 10);
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gMagicBarMidTex, 24, 16, OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X) + 8, magicBarY, OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gMagicBarMidTex, 24, 16, OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X + (Left_HUD_Margin*-1)) + 8, magicBarY,
gSaveContext.unk_13F4, 16, 1 << 10, 1 << 10); gSaveContext.unk_13F4, 16, 1 << 10, 1 << 10);
gDPLoadTextureBlock(OVERLAY_DISP++, gMagicBarEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 16, 0, gDPLoadTextureBlock(OVERLAY_DISP++, gMagicBarEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 8, 16, 0,
G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 3, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_MIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 3, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
const s16 rMagicBarX = OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X); const s16 rMagicBarX = OTRGetRectDimensionFromLeftEdge(R_MAGIC_BAR_X + (Left_HUD_Margin*-1));
gSPWideTextureRectangle(OVERLAY_DISP++, ((rMagicBarX + gSaveContext.unk_13F4) + 8) << 2, magicBarY << 2, gSPWideTextureRectangle(OVERLAY_DISP++, ((rMagicBarX + gSaveContext.unk_13F4) + 8) << 2, magicBarY << 2,
((rMagicBarX + gSaveContext.unk_13F4) + 16) << 2, (magicBarY + 16) << 2, G_TX_RENDERTILE, ((rMagicBarX + gSaveContext.unk_13F4) + 16) << 2, (magicBarY + 16) << 2, G_TX_RENDERTILE,
@ -2654,11 +2692,15 @@ void Interface_DrawMagicBar(GlobalContext* globalCtx) {
ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE); ENVIRONMENT, TEXEL0, ENVIRONMENT, 0, 0, 0, PRIMITIVE);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
const s16 rMagicFillX = OTRGetRectDimensionFromLeftEdge(R_MAGIC_FILL_X); const s16 rMagicFillX = OTRGetRectDimensionFromLeftEdge(R_MAGIC_FILL_X + (Left_HUD_Margin*-1));
if (gSaveContext.unk_13F0 == 4) { if (gSaveContext.unk_13F0 == 4) {
// Yellow part of the bar indicating the amount of magic to be subtracted // Yellow part of the bar indicating the amount of magic to be subtracted
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha); if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCMagicUsePrimR", 250), CVar_GetS32("gCCMagicUsePrimG", 250), CVar_GetS32("gCCMagicUsePrimB", 0), interfaceCtx->magicAlpha);
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 250, 250, 0, interfaceCtx->magicAlpha);
}
gDPLoadMultiBlock_4b(OVERLAY_DISP++, gMagicBarFillTex, 0, G_TX_RENDERTILE, G_IM_FMT_I, 16, 16, 0, gDPLoadMultiBlock_4b(OVERLAY_DISP++, gMagicBarFillTex, 0, G_TX_RENDERTILE, G_IM_FMT_I, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
@ -2670,16 +2712,22 @@ void Interface_DrawMagicBar(GlobalContext* globalCtx) {
// Fill the rest of the bar with the normal magic color // Fill the rest of the bar with the normal magic color
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MAGIC_FILL_COLOR(0), R_MAGIC_FILL_COLOR(1), R_MAGIC_FILL_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 2) {
interfaceCtx->magicAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCMagicPrimR", 0), CVar_GetS32("gCCMagicPrimG", 200), CVar_GetS32("gCCMagicPrimB", 0), interfaceCtx->magicAlpha);
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MAGIC_FILL_COLOR(0), R_MAGIC_FILL_COLOR(1), R_MAGIC_FILL_COLOR(2), interfaceCtx->magicAlpha);
}
gSPWideTextureRectangle(OVERLAY_DISP++, rMagicFillX << 2, (magicBarY + 3) << 2, gSPWideTextureRectangle(OVERLAY_DISP++, rMagicFillX << 2, (magicBarY + 3) << 2,
(rMagicFillX + gSaveContext.unk_13F8) << 2, (magicBarY + 10) << 2, G_TX_RENDERTILE, (rMagicFillX + gSaveContext.unk_13F8) << 2, (magicBarY + 10) << 2, G_TX_RENDERTILE,
0, 0, 1 << 10, 1 << 10); 0, 0, 1 << 10, 1 << 10);
} else { } else {
// Fill the whole bar with the normal magic color // Fill the whole bar with the normal magic color
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MAGIC_FILL_COLOR(0), R_MAGIC_FILL_COLOR(1), R_MAGIC_FILL_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 2) {
interfaceCtx->magicAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCMagicPrimR", 0), CVar_GetS32("gCCMagicPrimG", 200), CVar_GetS32("gCCMagicPrimB", 0), interfaceCtx->magicAlpha);
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_MAGIC_FILL_COLOR(0), R_MAGIC_FILL_COLOR(1), R_MAGIC_FILL_COLOR(2), interfaceCtx->magicAlpha);
}
gDPLoadMultiBlock_4b(OVERLAY_DISP++, gMagicBarFillTex, 0, G_TX_RENDERTILE, G_IM_FMT_I, 16, 16, 0, gDPLoadMultiBlock_4b(OVERLAY_DISP++, gMagicBarFillTex, 0, G_TX_RENDERTILE, G_IM_FMT_I, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
@ -2753,58 +2801,109 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
s16 width; s16 width;
s16 height; s16 height;
s16 C_Left_BTN_Pos[] = { C_LEFT_BUTTON_X+Right_HUD_Margin, C_LEFT_BUTTON_Y+(Top_HUD_Margin*-1) }; //(X,Y)
s16 C_Right_BTN_Pos[] = { C_RIGHT_BUTTON_X+Right_HUD_Margin, C_RIGHT_BUTTON_Y+(Top_HUD_Margin*-1) };
s16 C_Up_BTN_Pos[] = { C_UP_BUTTON_X+Right_HUD_Margin, C_UP_BUTTON_Y+(Top_HUD_Margin*-1) };
s16 C_Down_BTN_Pos[] = { C_DOWN_BUTTON_X+Right_HUD_Margin, C_DOWN_BUTTON_Y+(Top_HUD_Margin*-1) };
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 2900); OPEN_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 2900);
// B Button Color & Texture // B Button Color & Texture
// Also loads the Item Button Texture reused by other buttons afterwards // Also loads the Item Button Texture reused by other buttons afterwards
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_B_BTN_COLOR(0), R_B_BTN_COLOR(1), R_B_BTN_COLOR(2), interfaceCtx->bAlpha); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 150, 0, interfaceCtx->bAlpha);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_B_BTN_COLOR(0), R_B_BTN_COLOR(1), R_B_BTN_COLOR(2), interfaceCtx->bAlpha);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCBBtnPrimR", R_B_BTN_COLOR(0)), CVar_GetS32("gCCBBtnPrimG", R_B_BTN_COLOR(1)), CVar_GetS32("gCCBBtnPrimB", R_B_BTN_COLOR(2)), interfaceCtx->bAlpha);
}
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255);
OVERLAY_DISP = OVERLAY_DISP =
Gfx_TextureIA8(OVERLAY_DISP, gButtonBackgroundTex, 32, 32, OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(0)), R_ITEM_BTN_Y(0), Gfx_TextureIA8(OVERLAY_DISP, gButtonBackgroundTex, 32, 32, OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(0)+Right_HUD_Margin), R_ITEM_BTN_Y(0)+(Top_HUD_Margin*-1),
R_ITEM_BTN_WIDTH(0), R_ITEM_BTN_WIDTH(0), R_ITEM_BTN_DD(0) << 1, R_ITEM_BTN_DD(0) << 1); R_ITEM_BTN_WIDTH(0), R_ITEM_BTN_WIDTH(0), R_ITEM_BTN_DD(0) << 1, R_ITEM_BTN_DD(0) << 1);
// C-Left Button Color & Texture // C-Left Button Color & Texture
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 0) {
interfaceCtx->cLeftAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cLeftAlpha);
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(1)) << 2, R_ITEM_BTN_Y(1) << 2, } else if (CVar_GetS32("gHudColors", 1) == 1) {
(OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(1)) + R_ITEM_BTN_WIDTH(1)) << 2, gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cLeftAlpha);
(R_ITEM_BTN_Y(1) + R_ITEM_BTN_WIDTH(1)) << 2, } else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), interfaceCtx->cLeftAlpha);
}
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(C_Left_BTN_Pos[0]) << 2, C_Left_BTN_Pos[1] << 2,
(OTRGetRectDimensionFromRightEdge(C_Left_BTN_Pos[0]) + R_ITEM_BTN_WIDTH(1)) << 2,
(C_Left_BTN_Pos[1] + R_ITEM_BTN_WIDTH(1)) << 2,
G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(1) << 1, R_ITEM_BTN_DD(1) << 1); G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(1) << 1, R_ITEM_BTN_DD(1) << 1);
// C-Down Button Color & Texture // C-Down Button Color & Texture
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 0) {
interfaceCtx->cDownAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cDownAlpha);
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(2)) << 2, R_ITEM_BTN_Y(2) << 2, } else if (CVar_GetS32("gHudColors", 1) == 1) {
(OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(2)) + R_ITEM_BTN_WIDTH(2)) << 2, gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cDownAlpha);
(R_ITEM_BTN_Y(2) + R_ITEM_BTN_WIDTH(2)) << 2, } else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), interfaceCtx->cDownAlpha);
}
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(C_Down_BTN_Pos[0]) << 2, C_Down_BTN_Pos[1] << 2,
(OTRGetRectDimensionFromRightEdge(C_Down_BTN_Pos[0]) + R_ITEM_BTN_WIDTH(2)) << 2,
(C_Down_BTN_Pos[1] + R_ITEM_BTN_WIDTH(2)) << 2,
G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(2) << 1, R_ITEM_BTN_DD(2) << 1); G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(2) << 1, R_ITEM_BTN_DD(2) << 1);
// C-Right Button Color & Texture // C-Right Button Color & Texture
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 0) {
interfaceCtx->cRightAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cRightAlpha);
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(3)) << 2, R_ITEM_BTN_Y(3) << 2, } else if (CVar_GetS32("gHudColors", 1) == 1) {
(OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(3)) + R_ITEM_BTN_WIDTH(3)) << 2, gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), interfaceCtx->cRightAlpha);
(R_ITEM_BTN_Y(3) + R_ITEM_BTN_WIDTH(3)) << 2, } else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), interfaceCtx->cRightAlpha);
}
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(C_Right_BTN_Pos[0]) << 2, C_Right_BTN_Pos[1] << 2,
(OTRGetRectDimensionFromRightEdge(C_Right_BTN_Pos[0]) + R_ITEM_BTN_WIDTH(3)) << 2,
(C_Right_BTN_Pos[1] + R_ITEM_BTN_WIDTH(3)) << 2,
G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(3) << 1, R_ITEM_BTN_DD(3) << 1); G_TX_RENDERTILE, 0, 0, R_ITEM_BTN_DD(3) << 1, R_ITEM_BTN_DD(3) << 1);
if ((pauseCtx->state < 8) || (pauseCtx->state >= 18)) { if ((pauseCtx->state < 8) || (pauseCtx->state >= 18)) {
if ((globalCtx->pauseCtx.state != 0) || (globalCtx->pauseCtx.debugState != 0)) { if ((globalCtx->pauseCtx.state != 0) || (globalCtx->pauseCtx.debugState != 0)) {
// Start Button Texture, Color & Label // Start Button Texture, Color & Label
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 120, 120, interfaceCtx->startAlpha); if (CVar_GetS32("gHudColors", 1) == 0) {
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(startButtonLeftPos[gSaveContext.language]) << 2, 68, gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 0, 0, interfaceCtx->startAlpha);
(OTRGetRectDimensionFromRightEdge(startButtonLeftPos[gSaveContext.language]) + 22) << 2, 156, } else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 120, 120, 120, interfaceCtx->startAlpha);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCStartBtnPrimR", 120), CVar_GetS32("gCCStartBtnPrimG", 120), CVar_GetS32("gCCStartBtnPrimB", 120), interfaceCtx->startAlpha);
}
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(startButtonLeftPos[gSaveContext.language]+Right_HUD_Margin) << 2, 68+((Top_HUD_Margin*-1)*4),
(OTRGetRectDimensionFromRightEdge(startButtonLeftPos[gSaveContext.language]+Right_HUD_Margin) + 22) << 2, 156+((Top_HUD_Margin*-1)*4),
G_TX_RENDERTILE, 0, 0, 1462, 1462); G_TX_RENDERTILE, 0, 0, 1462, 1462);
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->startAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->startAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
//There is probably a more elegant way to do it.
char* doAction = actionsTbl[3];
char newName[512];
if (gSaveContext.language != LANGUAGE_ENG) {
size_t length = strlen(doAction);
strcpy(newName, doAction);
if (gSaveContext.language == LANGUAGE_FRA) {
newName[length - 6] = 'F';
newName[length - 5] = 'R';
newName[length - 4] = 'A';
} else if (gSaveContext.language == LANGUAGE_GER) {
newName[length - 6] = 'G';
newName[length - 5] = 'E';
newName[length - 4] = 'R';
}
doAction = newName;
}
memcpy(interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, ResourceMgr_LoadTexByName(doAction), DO_ACTION_TEX_SIZE);
gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, G_IM_FMT_IA, gDPLoadTextureBlock_4b(OVERLAY_DISP++, interfaceCtx->doActionSegment + DO_ACTION_TEX_SIZE * 2, G_IM_FMT_IA,
DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP, DO_ACTION_TEX_WIDTH, DO_ACTION_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
@ -2812,11 +2911,11 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
dxdy = (1 << 10) / (R_START_LABEL_DD(gSaveContext.language) / 100.0f); dxdy = (1 << 10) / (R_START_LABEL_DD(gSaveContext.language) / 100.0f);
width = DO_ACTION_TEX_WIDTH / (R_START_LABEL_DD(gSaveContext.language) / 100.0f); width = DO_ACTION_TEX_WIDTH / (R_START_LABEL_DD(gSaveContext.language) / 100.0f);
height = DO_ACTION_TEX_HEIGHT / (R_START_LABEL_DD(gSaveContext.language) / 100.0f); height = DO_ACTION_TEX_HEIGHT / (R_START_LABEL_DD(gSaveContext.language) / 100.0f);
const s16 rStartLabelX = OTRGetRectDimensionFromRightEdge(R_START_LABEL_X(gSaveContext.language)); const s16 rStartLabelX = OTRGetRectDimensionFromRightEdge(R_START_LABEL_X(gSaveContext.language)+Right_HUD_Margin);
gSPWideTextureRectangle( gSPWideTextureRectangle(
OVERLAY_DISP++, rStartLabelX << 2, OVERLAY_DISP++, rStartLabelX << 2,
R_START_LABEL_Y(gSaveContext.language) << 2, (rStartLabelX + width) << 2, R_START_LABEL_Y(gSaveContext.language)+(Top_HUD_Margin*-1) << 2, (rStartLabelX + width) << 2,
(R_START_LABEL_Y(gSaveContext.language) + height) << 2, G_TX_RENDERTILE, 0, 0, dxdy, dxdy); (R_START_LABEL_Y(gSaveContext.language)+(Top_HUD_Margin*-1) + height) << 2, G_TX_RENDERTILE, 0, 0, dxdy, dxdy);
} }
} }
@ -2835,12 +2934,18 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
temp = interfaceCtx->healthAlpha; temp = interfaceCtx->healthAlpha;
} }
const s16 rCUpBtnX = OTRGetRectDimensionFromRightEdge(R_C_UP_BTN_X); const s16 rCUpBtnX = OTRGetRectDimensionFromRightEdge(R_C_UP_BTN_X+Right_HUD_Margin);
const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X); const s16 rCUPIconX = OTRGetRectDimensionFromRightEdge(R_C_UP_ICON_X+Right_HUD_Margin);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), temp);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), temp);
}
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gSPWideTextureRectangle(OVERLAY_DISP++, rCUpBtnX << 2, R_C_UP_BTN_Y << 2, (rCUpBtnX + 16) << 2, gSPWideTextureRectangle(OVERLAY_DISP++, rCUpBtnX << 2, R_C_UP_BTN_Y+(Top_HUD_Margin*-1) << 2, (rCUpBtnX + 16) << 2,
(R_C_UP_BTN_Y + 16) << 2, G_TX_RENDERTILE, 0, 0, 2 << 10, 2 << 10); (R_C_UP_BTN_Y+(Top_HUD_Margin*-1) + 16) << 2, G_TX_RENDERTILE, 0, 0, 2 << 10, 2 << 10);
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, temp); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, temp);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
@ -2851,8 +2956,8 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
G_TX_NOLOD, G_TX_NOLOD); G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, rCUPIconX << 2, R_C_UP_ICON_Y << 2, (rCUPIconX + 32) << 2, gSPWideTextureRectangle(OVERLAY_DISP++, rCUPIconX << 2, R_C_UP_ICON_Y+(Top_HUD_Margin*-1) << 2, (rCUPIconX + 32) << 2,
(R_C_UP_ICON_Y + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); (R_C_UP_ICON_Y+(Top_HUD_Margin*-1) + 8) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
} }
sCUpTimer--; sCUpTimer--;
@ -2878,8 +2983,13 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
interfaceCtx->cRightAlpha); interfaceCtx->cRightAlpha);
} }
if (CVar_GetS32("gHudColors", 1) == 2) {
//This later will feature color per C button right now that it.
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), interfaceCtx->cRightAlpha);
}
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, ((u8*)gButtonBackgroundTex), 32, 32, OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, ((u8*)gButtonBackgroundTex), 32, 32,
OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(temp)), R_ITEM_BTN_Y(temp), R_ITEM_BTN_WIDTH(temp), OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(temp)+Right_HUD_Margin), R_ITEM_BTN_Y(temp)+(Top_HUD_Margin*-1), R_ITEM_BTN_WIDTH(temp),
R_ITEM_BTN_WIDTH(temp), R_ITEM_BTN_DD(temp) << 1, R_ITEM_BTN_DD(temp) << 1); R_ITEM_BTN_WIDTH(temp), R_ITEM_BTN_DD(temp) << 1, R_ITEM_BTN_DD(temp) << 1);
const char* cButtonIcons[] = { gButtonBackgroundTex, gEquippedItemOutlineTex, gEmptyCLeftArrowTex, const char* cButtonIcons[] = { gButtonBackgroundTex, gEquippedItemOutlineTex, gEmptyCLeftArrowTex,
@ -2887,7 +2997,7 @@ void Interface_DrawItemButtons(GlobalContext* globalCtx) {
}; };
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, cButtonIcons[(temp + 1)], 32, 32, OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, cButtonIcons[(temp + 1)], 32, 32,
OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(temp)), R_ITEM_BTN_Y(temp), R_ITEM_BTN_WIDTH(temp), OTRGetRectDimensionFromRightEdge(R_ITEM_BTN_X(temp)+Right_HUD_Margin), R_ITEM_BTN_Y(temp)+(Top_HUD_Margin*-1), R_ITEM_BTN_WIDTH(temp),
R_ITEM_BTN_WIDTH(temp), R_ITEM_BTN_DD(temp) << 1, R_ITEM_BTN_DD(temp) << 1); R_ITEM_BTN_WIDTH(temp), R_ITEM_BTN_DD(temp) << 1, R_ITEM_BTN_DD(temp) << 1);
} }
} }
@ -2901,9 +3011,9 @@ void Interface_DrawItemIconTexture(GlobalContext* globalCtx, void* texture, s16
gDPLoadTextureBlock(OVERLAY_DISP++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, gDPLoadTextureBlock(OVERLAY_DISP++, texture, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(R_ITEM_ICON_X(button)) << 2, R_ITEM_ICON_Y(button) << 2, gSPWideTextureRectangle(OVERLAY_DISP++, OTRGetRectDimensionFromRightEdge(R_ITEM_ICON_X(button)+Right_HUD_Margin) << 2, R_ITEM_ICON_Y(button)+(Top_HUD_Margin*-1) << 2,
(OTRGetRectDimensionFromRightEdge(R_ITEM_ICON_X(button)) + R_ITEM_ICON_WIDTH(button)) << 2, (OTRGetRectDimensionFromRightEdge(R_ITEM_ICON_X(button)+Right_HUD_Margin) + R_ITEM_ICON_WIDTH(button)) << 2,
(R_ITEM_ICON_Y(button) + R_ITEM_ICON_WIDTH(button)) << 2, G_TX_RENDERTILE, 0, 0, (R_ITEM_ICON_Y(button)+(Top_HUD_Margin*-1) + R_ITEM_ICON_WIDTH(button)) << 2, G_TX_RENDERTILE, 0, 0,
R_ITEM_ICON_DD(button) << 1, R_ITEM_ICON_DD(button) << 1); R_ITEM_ICON_DD(button) << 1, R_ITEM_ICON_DD(button) << 1);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 3094); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 3094);
@ -2964,11 +3074,11 @@ void Interface_DrawAmmoCount(GlobalContext* globalCtx, s16 button, s16 alpha) {
if (i != 0) { if (i != 0) {
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, (u8*)_gAmmoDigit0Tex[i], 8, 8, OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, (u8*)_gAmmoDigit0Tex[i], 8, 8,
OTRGetRectDimensionFromRightEdge(R_ITEM_AMMO_X(button)), R_ITEM_AMMO_Y(button), 8, 8, 1 << 10, 1 << 10); OTRGetRectDimensionFromRightEdge(R_ITEM_AMMO_X(button)+Right_HUD_Margin), R_ITEM_AMMO_Y(button)+(Top_HUD_Margin*-1), 8, 8, 1 << 10, 1 << 10);
} }
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, (u8*)_gAmmoDigit0Tex[ammo], 8, 8, OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, (u8*)_gAmmoDigit0Tex[ammo], 8, 8,
OTRGetRectDimensionFromRightEdge(R_ITEM_AMMO_X(button)) + 6, R_ITEM_AMMO_Y(button), 8, 8, 1 << 10, 1 << 10); OTRGetRectDimensionFromRightEdge(R_ITEM_AMMO_X(button)+Right_HUD_Margin) + 6, R_ITEM_AMMO_Y(button)+(Top_HUD_Margin*-1), 8, 8, 1 << 10, 1 << 10);
} }
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 3158); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_parameter.c", 3158);
@ -3187,10 +3297,16 @@ void Interface_Draw(GlobalContext* globalCtx) {
rColor = &rupeeWalletColors[0]; rColor = &rupeeWalletColors[0];
} }
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, rColor[0], rColor[1], rColor[2], interfaceCtx->magicAlpha); if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetEnvColor(OVERLAY_DISP++, 0, 80, 0, 255); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCRupeePrimR", rColor[0]), CVar_GetS32("gCCRupeePrimG", rColor[1]), CVar_GetS32("gCCRupeePrimB", rColor[2]), interfaceCtx->magicAlpha);
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, OTRGetRectDimensionFromLeftEdge(26), gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); //We reset this here so it match user color :)
206, 16, 16, 1 << 10, 1 << 10); } else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, rColor[0], rColor[1], rColor[2], interfaceCtx->magicAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 80, 0, 255);
}
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gRupeeCounterIconTex, 16, 16, OTRGetRectDimensionFromLeftEdge(26+(Left_HUD_Margin*-1)),
206+(Bottom_HUD_Margin), 16, 16, 1 << 10, 1 << 10);
switch (globalCtx->sceneNum) { switch (globalCtx->sceneNum) {
case SCENE_BMORI1: case SCENE_BMORI1:
@ -3210,9 +3326,15 @@ void Interface_Draw(GlobalContext* globalCtx) {
if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) { if (gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] >= 0) {
// Small Key Icon // Small Key Icon
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 230, 255, interfaceCtx->magicAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 20, 255); if (CVar_GetS32("gHudColors", 1) == 2) {
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gSmallKeyCounterIconTex, 16, 16, OTRGetRectDimensionFromLeftEdge(26), 190, 16, 16, gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCKeysPrimR", 200), CVar_GetS32("gCCKeysPrimG", 230), CVar_GetS32("gCCKeysPrimB", 255), interfaceCtx->magicAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 255); //We reset this here so it match user color :)
} else {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 200, 230, 255, interfaceCtx->magicAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 20, 255);
}
OVERLAY_DISP = Gfx_TextureIA8(OVERLAY_DISP, gSmallKeyCounterIconTex, 16, 16, OTRGetRectDimensionFromLeftEdge(26+(Left_HUD_Margin*-1)), 190+(Bottom_HUD_Margin), 16, 16,
1 << 10, 1 << 10); 1 << 10, 1 << 10);
// Small Key Counter // Small Key Counter
@ -3229,17 +3351,17 @@ void Interface_Draw(GlobalContext* globalCtx) {
interfaceCtx->counterDigits[3] -= 10; interfaceCtx->counterDigits[3] -= 10;
} }
svar3 = OTRGetRectDimensionFromLeftEdge(42); svar3 = OTRGetRectDimensionFromLeftEdge(42+(Left_HUD_Margin*-1));
if (interfaceCtx->counterDigits[2] != 0) { if (interfaceCtx->counterDigits[2] != 0) {
OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)((u8*)digitTextures[interfaceCtx->counterDigits[2]])), 8, OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, ((u8*)((u8*)digitTextures[interfaceCtx->counterDigits[2]])), 8,
16, svar3, 190, 8, 16, 1 << 10, 1 << 10); 16, svar3, 190+(Bottom_HUD_Margin), 8, 16, 1 << 10, 1 << 10);
svar3 += 8; svar3 += 8;
} }
OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP, OVERLAY_DISP = Gfx_TextureI8(OVERLAY_DISP,
((u8*)digitTextures[interfaceCtx->counterDigits[3]]), 8, 16, ((u8*)digitTextures[interfaceCtx->counterDigits[3]]), 8, 16,
svar3, 190, 8, 16, 1 << 10, 1 << 10); svar3, 190+(Bottom_HUD_Margin), 8, 16, 1 << 10, 1 << 10);
} }
break; break;
default: default:
@ -3283,7 +3405,7 @@ void Interface_Draw(GlobalContext* globalCtx) {
for (svar1 = 0, svar3 = 42; svar1 < svar5; svar1++, svar2++, svar3 += 8) { for (svar1 = 0, svar3 = 42; svar1 < svar5; svar1++, svar2++, svar3 += 8) {
OVERLAY_DISP = OVERLAY_DISP =
Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[svar2]]), 8, 16, Gfx_TextureI8(OVERLAY_DISP, ((u8*)digitTextures[interfaceCtx->counterDigits[svar2]]), 8, 16,
OTRGetRectDimensionFromLeftEdge(svar3), 206, 8, 16, 1 << 10, 1 << 10); OTRGetRectDimensionFromLeftEdge(svar3+(Left_HUD_Margin*-1)), 206+(Bottom_HUD_Margin), 8, 16, 1 << 10, 1 << 10);
} }
} }
else { else {
@ -3345,8 +3467,8 @@ void Interface_Draw(GlobalContext* globalCtx) {
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
R_B_LABEL_DD = (1 << 10) / (WREG(37 + gSaveContext.language) / 100.0f); R_B_LABEL_DD = (1 << 10) / (WREG(37 + gSaveContext.language) / 100.0f);
const s16 rBLabelX = OTRGetRectDimensionFromRightEdge(R_B_LABEL_X(gSaveContext.language)); const s16 rBLabelX = OTRGetRectDimensionFromRightEdge(R_B_LABEL_X(gSaveContext.language)+Right_HUD_Margin);
gSPWideTextureRectangle(OVERLAY_DISP++, rBLabelX << 2, R_B_LABEL_Y(gSaveContext.language) << 2, gSPWideTextureRectangle(OVERLAY_DISP++, rBLabelX << 2, R_B_LABEL_Y(gSaveContext.language)+(Top_HUD_Margin*-1) << 2,
(rBLabelX + DO_ACTION_TEX_WIDTH) << 2, (rBLabelX + DO_ACTION_TEX_WIDTH) << 2,
(R_B_LABEL_Y(gSaveContext.language) + DO_ACTION_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, 0, (R_B_LABEL_Y(gSaveContext.language) + DO_ACTION_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, 0,
R_B_LABEL_DD, R_B_LABEL_DD); R_B_LABEL_DD, R_B_LABEL_DD);
@ -3393,24 +3515,29 @@ void Interface_Draw(GlobalContext* globalCtx) {
// A Button // A Button
func_80094A14(globalCtx->state.gfxCtx); func_80094A14(globalCtx->state.gfxCtx);
const f32 rABtnX = OTRGetDimensionFromRightEdge(R_A_BTN_X); const f32 rABtnX = OTRGetDimensionFromRightEdge(R_A_BTN_X+Right_HUD_Margin);
//func_8008A8B8(globalCtx, R_A_BTN_Y, R_A_BTN_Y + 45, rABtnX, rABtnX + 45); //func_8008A8B8(globalCtx, R_A_BTN_Y, R_A_BTN_Y + 45, rABtnX, rABtnX + 45);
gSPClearGeometryMode(OVERLAY_DISP++, G_CULL_BOTH); gSPClearGeometryMode(OVERLAY_DISP++, G_CULL_BOTH);
gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_A_BTN_COLOR(0), R_A_BTN_COLOR(1), R_A_BTN_COLOR(2), if (CVar_GetS32("gHudColors", 1) == 0) {
interfaceCtx->aAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 90, 90, 255, interfaceCtx->aAlpha);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, R_A_BTN_COLOR(0), R_A_BTN_COLOR(1), R_A_BTN_COLOR(2), interfaceCtx->aAlpha);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", R_A_BTN_COLOR(0)), CVar_GetS32("gCCABtnPrimG", R_A_BTN_COLOR(1)), CVar_GetS32("gCCABtnPrimB", R_A_BTN_COLOR(2)), interfaceCtx->aAlpha);
}
if (fullUi) { if (fullUi) {
Interface_DrawActionButton(globalCtx, rABtnX, R_A_BTN_Y); Interface_DrawActionButton(globalCtx, rABtnX, R_A_BTN_Y+(Top_HUD_Margin*-1));
} }
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
const f32 rAIconX = OTRGetDimensionFromRightEdge(R_A_ICON_X); const f32 rAIconX = OTRGetDimensionFromRightEdge(R_A_ICON_X+Right_HUD_Margin);
//func_8008A8B8(globalCtx, R_A_ICON_Y, R_A_ICON_Y + 45, rAIconX, rAIconX + 45); //func_8008A8B8(globalCtx, R_A_ICON_Y, R_A_ICON_Y + 45, rAIconX, rAIconX + 45);
gSPSetGeometryMode(OVERLAY_DISP++, G_CULL_BACK); gSPSetGeometryMode(OVERLAY_DISP++, G_CULL_BACK);
gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0,
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->aAlpha); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, interfaceCtx->aAlpha);
gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0); gDPSetEnvColor(OVERLAY_DISP++, 0, 0, 0, 0);
Matrix_Translate(-138.0f + rAIconX, 98.0f - R_A_ICON_Y, WREG(46 + gSaveContext.language) / 10.0f, MTXMODE_NEW); Matrix_Translate(-138.0f + rAIconX, 98.0f - (R_A_ICON_Y+(Top_HUD_Margin*-1)), WREG(46 + gSaveContext.language) / 10.0f, MTXMODE_NEW);
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
Matrix_RotateX(interfaceCtx->unk_1F4 / 10000.0f, MTXMODE_APPLY); Matrix_RotateX(interfaceCtx->unk_1F4 / 10000.0f, MTXMODE_APPLY);
gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_parameter.c", 3701), gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_parameter.c", 3701),
@ -3979,6 +4106,18 @@ void Interface_Update(GlobalContext* globalCtx) {
u16 action; u16 action;
Input* debugInput = &globalCtx->state.input[2]; Input* debugInput = &globalCtx->state.input[2];
if (CVar_GetS32("gHUDMargins", 0) != 0) {
Top_HUD_Margin = CVar_GetS32("gHUDMargin_T", 0);
Left_HUD_Margin = CVar_GetS32("gHUDMargin_L", 0);
Right_HUD_Margin = CVar_GetS32("gHUDMargin_R", 0);
Bottom_HUD_Margin = CVar_GetS32("gHUDMargin_B", 0);
} else {
Top_HUD_Margin = 0;
Left_HUD_Margin = 0;
Right_HUD_Margin = 0;
Bottom_HUD_Margin = 0;
}
if (CHECK_BTN_ALL(debugInput->press.button, BTN_DLEFT)) { if (CHECK_BTN_ALL(debugInput->press.button, BTN_DLEFT)) {
gSaveContext.language = LANGUAGE_ENG; gSaveContext.language = LANGUAGE_ENG;
osSyncPrintf("J_N=%x J_N=%x\n", gSaveContext.language, &gSaveContext.language); osSyncPrintf("J_N=%x J_N=%x\n", gSaveContext.language, &gSaveContext.language);

View file

@ -29,7 +29,8 @@ s16 sBootData[PLAYER_BOOTS_MAX][17] = {
// Used to map action params to model groups // Used to map action params to model groups
u8 sActionModelGroups[] = { u8 sActionModelGroups[] = {
3, 15, 10, 2, 2, 5, 10, 11, 6, 6, 6, 6, 6, 6, 6, 6, 9, 9, 7, 7, 8, 3, 3, 6, 3, 3, 3, 3, 12, 13, 14, 14, 14, 14, 3, 15, 10, 2, 2, 5, 10, 11, 6, 6, 6, 6, 6, 6, 6, 6, 9, 9, 7, 7, 8, 3, 3, 6, 3, 3, 3, 3, 12, 13, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3
}; };
TextTriggerEntry sTextTriggers[] = { TextTriggerEntry sTextTriggers[] = {
@ -743,25 +744,38 @@ void func_8008F470(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable,
#else #else
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sMouthTextures[eyeIndex])); gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sMouthTextures[eyeIndex]));
#endif #endif
Color_RGB8 sTemp; Color_RGB8 sTemp;
Color_RGB8 sOriginalTunicColors[] = {
{ 30, 105, 27 },
{ 100, 20, 0 },
{ 0, 60, 100 },
};
color = &sTemp; color = &sTemp;
if (tunic == PLAYER_TUNIC_KOKIRI) { if (tunic == PLAYER_TUNIC_KOKIRI && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r); color->r = CVar_GetS32("gTunic_Kokiri_R", sTunicColors[PLAYER_TUNIC_KOKIRI].r);
color->g = CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g); color->g = CVar_GetS32("gTunic_Kokiri_G", sTunicColors[PLAYER_TUNIC_KOKIRI].g);
color->b = CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b); color->b = CVar_GetS32("gTunic_Kokiri_B", sTunicColors[PLAYER_TUNIC_KOKIRI].b);
} else if (tunic == PLAYER_TUNIC_GORON) { } else if (tunic == PLAYER_TUNIC_GORON && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Goron_Red", sTunicColors[PLAYER_TUNIC_GORON].r); color->r = CVar_GetS32("gTunic_Goron_R", sTunicColors[PLAYER_TUNIC_GORON].r);
color->g = CVar_GetS32("gTunic_Goron_Green", sTunicColors[PLAYER_TUNIC_GORON].g); color->g = CVar_GetS32("gTunic_Goron_G", sTunicColors[PLAYER_TUNIC_GORON].g);
color->b = CVar_GetS32("gTunic_Goron_Blue", sTunicColors[PLAYER_TUNIC_GORON].b); color->b = CVar_GetS32("gTunic_Goron_B", sTunicColors[PLAYER_TUNIC_GORON].b);
} else if (tunic == PLAYER_TUNIC_ZORA) { } else if (tunic == PLAYER_TUNIC_ZORA && CVar_GetS32("gUseTunicsCol",0)) {
color->r = CVar_GetS32("gTunic_Zora_Red", sTunicColors[PLAYER_TUNIC_ZORA].r); color->r = CVar_GetS32("gTunic_Zora_R", sTunicColors[PLAYER_TUNIC_ZORA].r);
color->g = CVar_GetS32("gTunic_Zora_Green", sTunicColors[PLAYER_TUNIC_ZORA].g); color->g = CVar_GetS32("gTunic_Zora_G", sTunicColors[PLAYER_TUNIC_ZORA].g);
color->b = CVar_GetS32("gTunic_Zora_Blue", sTunicColors[PLAYER_TUNIC_ZORA].b); color->b = CVar_GetS32("gTunic_Zora_B", sTunicColors[PLAYER_TUNIC_ZORA].b);
} else { } else if (!CVar_GetS32("gUseTunicsCol",0)){
color->r = CVar_GetS32("gTunic_Kokiri_Red", sTunicColors[PLAYER_TUNIC_KOKIRI].r); if (tunic >= 3) {
color->g = CVar_GetS32("gTunic_Kokiri_Green", sTunicColors[PLAYER_TUNIC_KOKIRI].g); color->r = sOriginalTunicColors[0].r;
color->b = CVar_GetS32("gTunic_Kokiri_Blue", sTunicColors[PLAYER_TUNIC_KOKIRI].b); color->g = sOriginalTunicColors[0].g;
color->b = sOriginalTunicColors[0].b;
} else {
color->r = sOriginalTunicColors[tunic].r;
color->g = sOriginalTunicColors[tunic].g;
color->b = sOriginalTunicColors[tunic].b;
}
} }
gDPSetEnvColor(POLY_OPA_DISP++, color->r, color->g, color->b, 0); gDPSetEnvColor(POLY_OPA_DISP++, color->r, color->g, color->b, 0);
sDListsLodOffset = lod * 2; sDListsLodOffset = lod * 2;
@ -1648,26 +1662,118 @@ void func_80091A24(GlobalContext* globalCtx, void* seg04, void* seg06, SkelAnime
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_player_lib.c", 3288); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_player_lib.c", 3288);
} }
uintptr_t SelectedAnim = 0; // Current Animaiton on the menu
s16 EquipedStance; // Link's current mode (Two handed, One handed...)
s16 FrameCountSinceLastAnim = 0; // Time since last animation
s16 MinFrameCount; // Frame to wait before checking if we need to change the animation
void func_8009214C(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime, Vec3f* pos, Vec3s* rot, f32 scale, void func_8009214C(GlobalContext* globalCtx, u8* segment, SkelAnime* skelAnime, Vec3f* pos, Vec3s* rot, f32 scale,
s32 sword, s32 tunic, s32 shield, s32 boots) { s32 sword, s32 tunic, s32 shield, s32 boots) {
Input* p1Input = &globalCtx->state.input[0];
Vec3f eye = { 0.0f, 0.0f, -400.0f }; Vec3f eye = { 0.0f, 0.0f, -400.0f };
Vec3f at = { 0.0f, 0.0f, 0.0f }; Vec3f at = { 0.0f, 0.0f, 0.0f };
Vec3s* destTable; Vec3s* destTable;
Vec3s* srcTable; Vec3s* srcTable;
s32 i; s32 i;
bool canswitchrnd = false;
s16 SelectedMode = CVar_GetS32("gPauseLiveLink", 1);
MinFrameCount = CVar_GetS32("gMinFrameCount", 200);
gSegments[4] = VIRTUAL_TO_PHYSICAL(segment + 0x3800); gSegments[4] = VIRTUAL_TO_PHYSICAL(segment + 0x3800);
gSegments[6] = VIRTUAL_TO_PHYSICAL(segment + 0x8800); gSegments[6] = VIRTUAL_TO_PHYSICAL(segment + 0x8800);
if (CVar_GetS32("gPauseLiveLink", 0) || CVar_GetS32("gPauseTriforce", 0)) { uintptr_t* PauseMenuAnimSet[15][4] = {
uintptr_t anim = gPlayerAnim_003238; // idle { 0, 0, 0, 0 }, // 0 = none
// IDLE // Two Handed // No shield // Kid Hylian Shield
{ gPlayerAnim_003238, gPlayerAnim_002BE0, gPlayerAnim_003240, gPlayerAnim_003240 }, // Idle
{ gPlayerAnim_003200, gPlayerAnim_003200, gPlayerAnim_003200, gPlayerAnim_003200 }, // Idle look around
{ gPlayerAnim_0033E0, gPlayerAnim_0033E0, gPlayerAnim_0033E0, gPlayerAnim_0033E0 }, // Idle Belt
{ gPlayerAnim_003418, gPlayerAnim_003418, gPlayerAnim_003418, gPlayerAnim_003418 }, // Idle shield adjust
{ gPlayerAnim_003420, gPlayerAnim_003428, gPlayerAnim_003420, gPlayerAnim_003420 }, // Idle test sword
{ gPlayerAnim_0033F0, gPlayerAnim_0033F0, gPlayerAnim_0033F0, gPlayerAnim_0033F0 }, // Idle yawn
{ gPlayerAnim_0025D0, gPlayerAnim_002BD0, gPlayerAnim_0025D0, gPlayerAnim_0025D0 }, // Battle Stance
{ gPlayerAnim_003290, gPlayerAnim_002BF8, gPlayerAnim_003290, gPlayerAnim_003290 }, // Walking (No shield)
{ gPlayerAnim_003268, gPlayerAnim_002BF8, gPlayerAnim_003268, gPlayerAnim_003268 }, // Walking (Holding shield)
{ gPlayerAnim_003138, gPlayerAnim_002B40, gPlayerAnim_003138, gPlayerAnim_003138 }, // Running (No shield)
{ gPlayerAnim_003140, gPlayerAnim_002B40, gPlayerAnim_003140, gPlayerAnim_003140 }, // Running (Holding shield)
{ gPlayerAnim_0031A8, gPlayerAnim_0031A8, gPlayerAnim_0031A8, gPlayerAnim_0031A8 }, // Hand on hip
{ gPlayerAnim_002AF0, gPlayerAnim_002928, gPlayerAnim_002AF0, gPlayerAnim_002AF0 }, // Spin Charge
{ gPlayerAnim_002820, gPlayerAnim_002820, gPlayerAnim_002820, gPlayerAnim_002820 }, // Look at hand
};
s16 AnimArraySize = ARRAY_COUNT(PauseMenuAnimSet);
if (CUR_EQUIP_VALUE(EQUIP_SWORD) >= 3) if (CVar_GetS32("gPauseLiveLink", !0) || CVar_GetS32("gPauseTriforce", 0)) {
anim = gPlayerAnim_002BE0; // Two Handed Anim uintptr_t anim = 0; // Initialise anim
else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 0)
anim = gPlayerAnim_003240; if (CUR_EQUIP_VALUE(EQUIP_SWORD) >= 3) {
else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 2 && LINK_AGE_IN_YEARS == YEARS_CHILD) EquipedStance = 1;
anim = gPlayerAnim_003240; } else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 0) {
EquipedStance = 2;
} else if (CUR_EQUIP_VALUE(EQUIP_SHIELD) == 2 && LINK_AGE_IN_YEARS == YEARS_CHILD) {
EquipedStance = 3;
} else {
// Link is idle so revert to 0
EquipedStance = 0;
}
if (SelectedMode == 16) {
// Apply Random function
s16 SwitchAtFrame = 0;
s16 CurAnimDuration = 0;
if (FrameCountSinceLastAnim == 0) {
// When opening Kaleido this will be passed one time
SelectedAnim = rand() % (AnimArraySize - 0);
if (SelectedAnim == 0) {
// prevent loading 0 that would result to a crash.
SelectedAnim = 1;
}
} else if (FrameCountSinceLastAnim >= 1) {
SwitchAtFrame = Animation_GetLastFrame(PauseMenuAnimSet[SelectedAnim][EquipedStance]);
CurAnimDuration = Animation_GetLastFrame(PauseMenuAnimSet[SelectedAnim][EquipedStance]);
if (SwitchAtFrame < MinFrameCount) {
// Animation frame count is lower than minimal wait time then we wait for another round.
// This will be looped to always add current animation time if that still lower than minimum time
while (SwitchAtFrame < MinFrameCount) {
SwitchAtFrame = SwitchAtFrame + CurAnimDuration;
}
} else if (CurAnimDuration >= MinFrameCount) {
// Since we have more (or same) animation time than min duration we set the wait time to animation
// time.
SwitchAtFrame = CurAnimDuration;
}
if (FrameCountSinceLastAnim >= SwitchAtFrame) {
SelectedAnim = rand() % (AnimArraySize - 0);
if (SelectedAnim == 0) {
// prevent loading 0 that would result to a crash.
SelectedAnim = 1;
}
FrameCountSinceLastAnim = 1;
}
anim = PauseMenuAnimSet[SelectedAnim][EquipedStance];
}
FrameCountSinceLastAnim++;
} else if (SelectedMode == 15) {
// When opening Kaleido this will be passed one time
if (FrameCountSinceLastAnim < 1) {
SelectedAnim = rand() % (AnimArraySize - 0);
FrameCountSinceLastAnim++;
if (SelectedAnim == 0) {
// prevent loading 0 that would result to a crash.
SelectedAnim = 1;
}
FrameCountSinceLastAnim = 1;
}
if (CHECK_BTN_ALL(p1Input->press.button, BTN_B) || CHECK_BTN_ALL(p1Input->press.button, BTN_START)) {
FrameCountSinceLastAnim = 0;
}
anim = PauseMenuAnimSet[SelectedAnim][EquipedStance];
} else if (SelectedMode < 16) {
// Not random so we place our CVar as SelectedAnim
SelectedAnim = SelectedMode;
anim = PauseMenuAnimSet[SelectedAnim][EquipedStance];
}
anim = PauseMenuAnimSet[SelectedAnim][EquipedStance];
//anim = gPlayerAnim_003428; // Use for biggoron sword? //anim = gPlayerAnim_003428; // Use for biggoron sword?

View file

@ -836,7 +836,7 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) { for (i = 0; i < ARRAY_COUNTU(sZeldaMagic) - 3; i++) {
if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) { if (sZeldaMagic[i + SRAM_HEADER_MAGIC] != sramCtx->readBuff[i + SRAM_HEADER_MAGIC]) {
osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !" osSyncPrintf("SRAM破壊!!!!!!\n"); // "SRAM destruction! ! ! ! ! !"
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE]; gSaveContext.language = CVar_GetS32("gLanguages", 0);
memcpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic)); memcpy(sramCtx->readBuff, sZeldaMagic, sizeof(sZeldaMagic));
sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language; sramCtx->readBuff[SRAM_HEADER_LANGUAGE] = gSaveContext.language;
Sram_WriteSramHeader(sramCtx); Sram_WriteSramHeader(sramCtx);
@ -845,7 +845,7 @@ void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3; gSaveContext.audioSetting = sramCtx->readBuff[SRAM_HEADER_SOUND] & 3;
gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1; gSaveContext.zTargetSetting = sramCtx->readBuff[SRAM_HEADER_ZTARGET] & 1;
gSaveContext.language = sramCtx->readBuff[SRAM_HEADER_LANGUAGE]; gSaveContext.language = CVar_GetS32("gLanguages", 0);
if (gSaveContext.language >= LANGUAGE_MAX) { if (gSaveContext.language >= LANGUAGE_MAX) {
gSaveContext.language = LANGUAGE_ENG; gSaveContext.language = LANGUAGE_ENG;

View file

@ -427,7 +427,8 @@ void EnFloormas_SetupFreeze(EnFloormas* this) {
} }
void EnFloormas_Die(EnFloormas* this, GlobalContext* globalCtx) { void EnFloormas_Die(EnFloormas* this, GlobalContext* globalCtx) {
if (this->actor.scale.x > 0.004f) { //Originally was doing > 0.004f, better fix thanks Gary :D
if (this->actor.scale.x > (f32)0.004f) {
// split // split
this->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000; this->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000;
EnFloormas_SetupSplit((EnFloormas*)this->actor.child); EnFloormas_SetupSplit((EnFloormas*)this->actor.child);

View file

@ -1887,9 +1887,19 @@ void EnOssan_UpdateCursorAnim(EnOssan* this) {
this->cursorAnimState = 0; this->cursorAnimState = 0;
} }
} }
this->cursorColorR = ColChanMix(0, 0.0f, t); if (CVar_GetS32("gHudColors", 1) == 0) {
this->cursorColorG = ColChanMix(255, 80.0f, t); this->cursorColorR = ColChanMix(0, 0.0f, t);
this->cursorColorB = ColChanMix(80, 0.0f, t); this->cursorColorG = ColChanMix(80, 80.0f, t);
this->cursorColorB = ColChanMix(255, 0.0f, t);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
this->cursorColorR = ColChanMix(0, 0.0f, t);
this->cursorColorG = ColChanMix(255, 80.0f, t);
this->cursorColorB = ColChanMix(80, 0.0f, t);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
this->cursorColorR = ColChanMix(CVar_GetS32("gCCABtnPrimR", 90), ((CVar_GetS32("gCCABtnPrimR", 90)/255)*100), t);
this->cursorColorG = ColChanMix(CVar_GetS32("gCCABtnPrimG", 90), ((CVar_GetS32("gCCABtnPrimG", 90)/255)*100), t);
this->cursorColorB = ColChanMix(CVar_GetS32("gCCABtnPrimB", 90), ((CVar_GetS32("gCCABtnPrimB", 90)/255)*100), t);
}
this->cursorColorA = ColChanMix(255, 0.0f, t); this->cursorColorA = ColChanMix(255, 0.0f, t);
this->cursorAnimTween = t; this->cursorAnimTween = t;
} }

View file

@ -366,7 +366,9 @@ void func_80ACA7E0(EnOwl* this, GlobalContext* globalCtx) {
void EnOwl_ConfirmKokiriMessage(EnOwl* this, GlobalContext* globalCtx) { void EnOwl_ConfirmKokiriMessage(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x2065); Message_ContinueTextbox(globalCtx, 0x2065);
break; break;
@ -393,7 +395,9 @@ void EnOwl_WaitOutsideKokiri(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACA998(EnOwl* this, GlobalContext* globalCtx) { void func_80ACA998(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x2069); Message_ContinueTextbox(globalCtx, 0x2069);
this->actionFunc = func_80ACAA54; this->actionFunc = func_80ACAA54;
@ -437,7 +441,9 @@ void EnOwl_WaitHyruleCastle(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACAB88(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAB88(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
// obtained zelda's letter // obtained zelda's letter
if (gSaveContext.eventChkInf[4] & 1) { if (gSaveContext.eventChkInf[4] & 1) {
@ -478,7 +484,9 @@ void EnOwl_WaitKakariko(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACAD34(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAD34(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x206F); Message_ContinueTextbox(globalCtx, 0x206F);
this->actionFunc = func_80ACADF0; this->actionFunc = func_80ACADF0;
@ -514,7 +522,9 @@ void EnOwl_WaitGerudo(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACAEB8(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAEB8(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x2071); Message_ContinueTextbox(globalCtx, 0x2071);
this->actionFunc = func_80ACAF74; this->actionFunc = func_80ACAF74;
@ -634,7 +644,9 @@ void EnOwl_WaitDeathMountainShortcut(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACB344(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB344(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x607A); Message_ContinueTextbox(globalCtx, 0x607A);
break; break;
@ -657,7 +669,9 @@ void func_80ACB3E0(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACB440(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB440(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x10C1); Message_ContinueTextbox(globalCtx, 0x10C1);
this->actionFunc = func_80ACB4FC; this->actionFunc = func_80ACB4FC;
@ -692,7 +706,9 @@ void EnOwl_WaitLWPreSaria(EnOwl* this, GlobalContext* globalCtx) {
void func_80ACB5C4(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB5C4(EnOwl* this, GlobalContext* globalCtx) {
if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) {
switch (globalCtx->msgCtx.choiceIndex) { // swap the order of the responses if better owl is enabled
uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex);
switch (index) {
case OWL_REPEAT: case OWL_REPEAT:
Message_ContinueTextbox(globalCtx, 0x10C5); Message_ContinueTextbox(globalCtx, 0x10C5);
this->actionFunc = func_80ACB680; this->actionFunc = func_80ACB680;

View file

@ -898,6 +898,15 @@ static s8 sItemActionParams[] = {
PLAYER_AP_SWORD_KOKIRI, PLAYER_AP_SWORD_KOKIRI,
PLAYER_AP_SWORD_MASTER, PLAYER_AP_SWORD_MASTER,
PLAYER_AP_SWORD_BGS, PLAYER_AP_SWORD_BGS,
PLAYER_AP_SHIELD_DEKU,
PLAYER_AP_SHIELD_HYLIAN,
PLAYER_AP_SHIELD_MIRROR,
PLAYER_AP_TUNIC_KOKIRI,
PLAYER_AP_TUNIC_GORON,
PLAYER_AP_TUNIC_ZORA,
PLAYER_AP_BOOTS_KOKIRI,
PLAYER_AP_BOOTS_IRON,
PLAYER_AP_BOOTS_HOVER,
}; };
static s32(*D_80853EDC[])(Player* this, GlobalContext* globalCtx) = { static s32(*D_80853EDC[])(Player* this, GlobalContext* globalCtx) = {
@ -910,7 +919,8 @@ static s32(*D_80853EDC[])(Player* this, GlobalContext* globalCtx) = {
func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C,
func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C,
func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C,
func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C,
func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C, func_8083485C,
}; };
static void (*D_80853FE8[])(GlobalContext* globalCtx, Player* this) = { static void (*D_80853FE8[])(GlobalContext* globalCtx, Player* this) = {
@ -923,7 +933,8 @@ static void (*D_80853FE8[])(GlobalContext* globalCtx, Player* this) = {
func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770,
func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770,
func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770,
func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770,
func_80833770, func_80833770, func_80833770, func_80833770, func_80833770, func_80833770,
}; };
typedef enum { typedef enum {
@ -2752,7 +2763,8 @@ void func_80835F44(GlobalContext* globalCtx, Player* this, s32 item) {
if ((actionParam == PLAYER_AP_NONE) || !(this->stateFlags1 & PLAYER_STATE1_27) || if ((actionParam == PLAYER_AP_NONE) || !(this->stateFlags1 & PLAYER_STATE1_27) ||
((this->actor.bgCheckFlags & 1) && ((this->actor.bgCheckFlags & 1) &&
((actionParam == PLAYER_AP_HOOKSHOT) || (actionParam == PLAYER_AP_LONGSHOT)))) { ((actionParam == PLAYER_AP_HOOKSHOT) || (actionParam == PLAYER_AP_LONGSHOT))) ||
((actionParam >= PLAYER_AP_SHIELD_DEKU) && (actionParam <= PLAYER_AP_BOOTS_HOVER))) {
if ((globalCtx->bombchuBowlingStatus == 0) && if ((globalCtx->bombchuBowlingStatus == 0) &&
(((actionParam == PLAYER_AP_STICK) && (AMMO(ITEM_STICK) == 0)) || (((actionParam == PLAYER_AP_STICK) && (AMMO(ITEM_STICK) == 0)) ||
@ -2764,6 +2776,33 @@ void func_80835F44(GlobalContext* globalCtx, Player* this, s32 item) {
return; return;
} }
if (actionParam >= PLAYER_AP_BOOTS_KOKIRI) {
u16 bootsValue = actionParam - PLAYER_AP_BOOTS_KOKIRI + 1;
if (CUR_EQUIP_VALUE(EQUIP_BOOTS) == bootsValue) {
Inventory_ChangeEquipment(EQUIP_BOOTS, 1);
} else {
Inventory_ChangeEquipment(EQUIP_BOOTS, bootsValue);
}
Player_SetEquipmentData(globalCtx, this);
return;
}
if (actionParam >= PLAYER_AP_TUNIC_KOKIRI) {
u16 tunicValue = actionParam - PLAYER_AP_TUNIC_KOKIRI + 1;
if (CUR_EQUIP_VALUE(EQUIP_TUNIC) == tunicValue) {
Inventory_ChangeEquipment(EQUIP_TUNIC, 1);
} else {
Inventory_ChangeEquipment(EQUIP_TUNIC, tunicValue);
}
Player_SetEquipmentData(globalCtx, this);
return;
}
if (actionParam >= PLAYER_AP_SHIELD_DEKU) {
// Changing shields through action commands is unimplemented
return;
}
if (actionParam == PLAYER_AP_LENS) { if (actionParam == PLAYER_AP_LENS) {
if (func_80087708(globalCtx, 0, 3)) { if (func_80087708(globalCtx, 0, 3)) {
if (globalCtx->actorCtx.unk_03 != 0) { if (globalCtx->actorCtx.unk_03 != 0) {
@ -10285,6 +10324,14 @@ void func_80848EF8(Player* this, GlobalContext* globalCtx) {
int rectHeight = 24; //Texture Heigh int rectHeight = 24; //Texture Heigh
int DefaultIconA= 50; //Default icon alphe (55 on 255) int DefaultIconA= 50; //Default icon alphe (55 on 255)
if (CVar_GetS32("gHUDMargins", 0) != 0) {
rectLeft = OTRGetRectDimensionFromLeftEdge(26+(CVar_GetS32("gHUDMargin_L", 0)*-1));
rectTop = 60+(CVar_GetS32("gHUDMargin_T", 0)*-1);
} else {
rectTop = 60;
rectLeft = OTRGetRectDimensionFromLeftEdge(26);
}
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_player.c", 2824); OPEN_DISPS(globalCtx->state.gfxCtx, "../z_player.c", 2824);
gDPPipeSync(OVERLAY_DISP++); gDPPipeSync(OVERLAY_DISP++);
gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, DefaultIconA); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 255, 255, 255, DefaultIconA);

View file

@ -5,6 +5,8 @@
#include "textures/title_static/title_static.h" #include "textures/title_static/title_static.h"
#include "textures/parameter_static/parameter_static.h" #include "textures/parameter_static/parameter_static.h"
#include "soh/frame_interpolation.h"
static s16 sUnused = 106; static s16 sUnused = 106;
static s16 sScreenFillAlpha = 255; static s16 sScreenFillAlpha = 255;
@ -1136,6 +1138,8 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
FileChoose_SetWindowVtx(&this->state); FileChoose_SetWindowVtx(&this->state);
FileChoose_SetWindowContentVtx(&this->state); FileChoose_SetWindowContentVtx(&this->state);
FrameInterpolation_RecordOpenChild(this, this->configMode);
if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY)) { if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY)) {
gDPPipeSync(POLY_OPA_DISP++); gDPPipeSync(POLY_OPA_DISP++);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
@ -1227,6 +1231,8 @@ void FileChoose_ConfigModeDraw(GameState* thisx) {
gDPPipeSync(POLY_OPA_DISP++); gDPPipeSync(POLY_OPA_DISP++);
FileChoose_SetView(this, 0.0f, 0.0f, 64.0f); FileChoose_SetView(this, 0.0f, 0.0f, 64.0f);
FrameInterpolation_RecordCloseChild();
CLOSE_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2352); CLOSE_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2352);
} }
@ -1669,7 +1675,9 @@ void FileChoose_Main(GameState* thisx) {
FileChoose_PulsateCursor(&this->state); FileChoose_PulsateCursor(&this->state);
gFileSelectUpdateFuncs[this->menuMode](&this->state); gFileSelectUpdateFuncs[this->menuMode](&this->state);
FrameInterpolation_StartRecord();
gFileSelectDrawFuncs[this->menuMode](&this->state); gFileSelectDrawFuncs[this->menuMode](&this->state);
FrameInterpolation_StopRecord();
// do not draw controls text in the options menu // do not draw controls text in the options menu
if ((this->configMode <= CM_NAME_ENTRY_TO_MAIN) || (this->configMode >= CM_UNUSED_DELAY)) { if ((this->configMode <= CM_NAME_ENTRY_TO_MAIN) || (this->configMode >= CM_UNUSED_DELAY)) {

View file

@ -222,6 +222,72 @@ void Title_Draw(TitleContext* this) {
void Title_Main(GameState* thisx) { void Title_Main(GameState* thisx) {
TitleContext* this = (TitleContext*)thisx; TitleContext* this = (TitleContext*)thisx;
if (CVar_GetS32("gSkipLogoTitle",0)!=0) {
gSaveContext.language = CVar_GetS32("gLanguages", 0);
Sram_InitSram(&this->state, &this->sramCtx);
s16 selectedfile = CVar_GetS32("gSaveFileID", 0);
if (selectedfile == 4) {
selectedfile = 0xFF;
} else if(selectedfile == 0){
gSaveContext.fileNum = selectedfile;
gSaveContext.gameMode = 0;
this->state.running = false;
SET_NEXT_GAMESTATE(&this->state, FileChoose_Init, SelectContext);
return;
} else {
selectedfile--;
if (selectedfile < 0) {
selectedfile = 0xFF;
}
}
if (selectedfile == 0xFF) {
gSaveContext.fileNum = selectedfile;
Sram_OpenSave(&this->sramCtx);
gSaveContext.gameMode = 0;
this->state.running = false;
SET_NEXT_GAMESTATE(&this->state, Select_Init, SelectContext);
} else {
gSaveContext.fileNum = selectedfile;
Sram_OpenSave(&this->sramCtx);
gSaveContext.gameMode = 0;
this->state.running = false;
//return;
SET_NEXT_GAMESTATE(&this->state, Gameplay_Init, GlobalContext);
}
gSaveContext.respawn[0].entranceIndex = -1;
gSaveContext.respawnFlag = 0;
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = 0xFF;
gSaveContext.showTitleCard = true;
gSaveContext.dogParams = 0;
gSaveContext.timer1State = 0;
gSaveContext.timer2State = 0;
gSaveContext.eventInf[0] = 0;
gSaveContext.eventInf[1] = 0;
gSaveContext.eventInf[2] = 0;
gSaveContext.eventInf[3] = 0;
gSaveContext.unk_13EE = 0x32;
gSaveContext.nayrusLoveTimer = 0;
gSaveContext.healthAccumulator = 0;
gSaveContext.unk_13F0 = 0;
gSaveContext.unk_13F2 = 0;
gSaveContext.forcedSeqId = NA_BGM_GENERAL_SFX;
gSaveContext.skyboxTime = 0;
gSaveContext.nextTransition = 0xFF;
gSaveContext.nextCutsceneIndex = 0xFFEF;
gSaveContext.cutsceneTrigger = 0;
gSaveContext.chamberCutsceneNum = 0;
gSaveContext.nextDayTime = 0xFFFF;
gSaveContext.unk_13C3 = 0;
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = gSaveContext.buttonStatus[4] = BTN_ENABLED;
gSaveContext.unk_13E7 = gSaveContext.unk_13E8 = gSaveContext.unk_13EA = gSaveContext.unk_13EC = gSaveContext.unk_13F4 = 0;
gSaveContext.unk_13F6 = gSaveContext.magic;
gSaveContext.magic = 0;
gSaveContext.magicLevel = gSaveContext.magic;
gSaveContext.naviTimer = 0;
return;
}
OPEN_DISPS(this->state.gfxCtx, "../z_title.c", 494); OPEN_DISPS(this->state.gfxCtx, "../z_title.c", 494);
gSPSegment(POLY_OPA_DISP++, 0, NULL); gSPSegment(POLY_OPA_DISP++, 0, NULL);

View file

@ -494,9 +494,21 @@ void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfx
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
if (D_8082A124[sp218] == 0) { if (D_8082A124[sp218] == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, D_8082A150[sp218]); if (CVar_GetS32("gHudColors", 1) == 0) { // A Button notes
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 150, 255, D_8082A150[sp218]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, D_8082A150[sp218]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", 80), CVar_GetS32("gCCABtnPrimG", 255), CVar_GetS32("gCCABtnPrimB", 150), D_8082A150[sp218]);
}
} else { } else {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[sp218]); if (CVar_GetS32("gHudColors", 1) == 0) { // C Buttons notes
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[sp218]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[sp218]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", 255), CVar_GetS32("gCCCBtnPrimG", 255), CVar_GetS32("gCCCBtnPrimB", 50), D_8082A150[sp218]);
}
} }
gDPSetEnvColor(POLY_KAL_DISP++, 10, 10, 10, 0); gDPSetEnvColor(POLY_KAL_DISP++, 10, 10, 10, 0);
@ -524,9 +536,21 @@ void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfx
if (pauseCtx->unk_1E4 == 8) { if (pauseCtx->unk_1E4 == 8) {
if (gOcarinaSongNotes[sp224].notesIdx[phi_s3] == 0) { if (gOcarinaSongNotes[sp224].notesIdx[phi_s3] == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, 200); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 150, 255, 200);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, 200);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", 80), CVar_GetS32("gCCABtnPrimG", 255), CVar_GetS32("gCCABtnPrimB", 150), 200);
}
} else { } else {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, 200); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, 200);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, 200);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", 255), CVar_GetS32("gCCCBtnPrimG", 255), CVar_GetS32("gCCCBtnPrimB", 50), 200);
}
} }
} else { } else {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 150, 150, 150, 150); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 150, 150, 150, 150);
@ -579,9 +603,21 @@ void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfx
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
if (D_8082A124[phi_s3] == 0) { if (D_8082A124[phi_s3] == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, D_8082A150[phi_s3]); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 150, 255, D_8082A150[phi_s3]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 80, 255, 150, D_8082A150[phi_s3]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", 80), CVar_GetS32("gCCABtnPrimG", 255), CVar_GetS32("gCCABtnPrimB", 150), D_8082A150[phi_s3]);
}
} else { } else {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[phi_s3]); if (CVar_GetS32("gHudColors", 1) == 0) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[phi_s3]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 50, D_8082A150[phi_s3]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", 255), CVar_GetS32("gCCCBtnPrimG", 160), CVar_GetS32("gCCCBtnPrimB", 0), D_8082A150[phi_s3]);
}
} }
gDPSetEnvColor(POLY_KAL_DISP++, 10, 10, 10, 0); gDPSetEnvColor(POLY_KAL_DISP++, 10, 10, 10, 0);

View file

@ -89,11 +89,17 @@ void KaleidoScope_DrawEquipmentImage(GlobalContext* globalCtx, void* source, u32
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_kaleido_equipment.c", 122); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_kaleido_equipment.c", 122);
} }
Vec3s link_kaleido_rot = { 0, 32300, 0 }; // Default rotation link face us.
void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) { void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) {
PauseContext* pauseCtx = &globalCtx->pauseCtx; PauseContext* pauseCtx = &globalCtx->pauseCtx;
Vec3f pos; Vec3f pos;
Vec3s rot; //Vec3s rot; // Removed for not having it use din the function
f32 scale; f32 scale;
Input* input = &globalCtx->state.input[0];
s16 RotationSpeed = 150 * CVar_GetS32("gPauseLiveLinkRotationSpeed", 0);
bool AllowCRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 2) ? true : false;
bool AllowDPadRotation = (CVar_GetS32("gPauseLiveLinkRotation", 0) == 1) ? true : false;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) { if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
pos.x = 2.0f; pos.x = 2.0f;
@ -112,11 +118,29 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx) {
scale = 0.047f; scale = 0.047f;
} }
rot.y = 32300; link_kaleido_rot.x = link_kaleido_rot.z = 0;
rot.x = rot.z = 0;
if (AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DLEFT) ||
AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CLEFT)) {
link_kaleido_rot.y = link_kaleido_rot.y - RotationSpeed;
} else if (AllowDPadRotation && CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT) ||
AllowCRotation && CHECK_BTN_ALL(input->cur.button, BTN_CRIGHT)) {
link_kaleido_rot.y = link_kaleido_rot.y + RotationSpeed;
}
if (AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DUP) ||
AllowDPadRotation && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
link_kaleido_rot.y = 32300;
} else if (AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CUP) ||
AllowCRotation && CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) {
link_kaleido_rot.y = 32300;
}
link_kaleido_rot.x = 0;
extern int fbTest; extern int fbTest;
gsSPSetFB(globalCtx->state.gfxCtx->polyOpa.p++, fbTest); gsSPSetFB(globalCtx->state.gfxCtx->polyOpa.p++, fbTest);
func_8009214C(globalCtx, pauseCtx->playerSegment, &pauseCtx->playerSkelAnime, &pos, &rot, scale, func_8009214C(globalCtx, pauseCtx->playerSegment, &pauseCtx->playerSkelAnime, &pos, &link_kaleido_rot, scale,
CUR_EQUIP_VALUE(EQUIP_SWORD), CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1, CUR_EQUIP_VALUE(EQUIP_SHIELD), CUR_EQUIP_VALUE(EQUIP_SWORD), CUR_EQUIP_VALUE(EQUIP_TUNIC) - 1, CUR_EQUIP_VALUE(EQUIP_SHIELD),
CUR_EQUIP_VALUE(EQUIP_BOOTS) - 1); CUR_EQUIP_VALUE(EQUIP_BOOTS) - 1);
gsSPResetFB(globalCtx->state.gfxCtx->polyOpa.p++); gsSPResetFB(globalCtx->state.gfxCtx->polyOpa.p++);
@ -471,39 +495,76 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) {
KaleidoScope_SetCursorVtx(pauseCtx, cursorSlot * 4, pauseCtx->equipVtx); KaleidoScope_SetCursorVtx(pauseCtx, cursorSlot * 4, pauseCtx->equipVtx);
if ((pauseCtx->cursorSpecialPos == 0) && (cursorItem != PAUSE_ITEM_NONE) && (pauseCtx->state == 6) && if ((pauseCtx->cursorSpecialPos == 0) && (cursorItem != PAUSE_ITEM_NONE) && (pauseCtx->state == 6) &&
(pauseCtx->unk_1E4 == 0) && CHECK_BTN_ALL(input->press.button, BTN_A) && (pauseCtx->unk_1E4 == 0) &&
CHECK_BTN_ANY(input->press.button, BTN_A | BTN_CLEFT | BTN_CDOWN | BTN_CRIGHT) &&
(pauseCtx->cursorX[PAUSE_EQUIP] != 0)) { (pauseCtx->cursorX[PAUSE_EQUIP] != 0)) {
if ((gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == 9) || if ((gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == 9) ||
(gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] == (gEquipAgeReqs[pauseCtx->cursorY[PAUSE_EQUIP]][pauseCtx->cursorX[PAUSE_EQUIP]] ==
((void)0, gSaveContext.linkAge))) { ((void)0, gSaveContext.linkAge))) {
Inventory_ChangeEquipment(pauseCtx->cursorY[PAUSE_EQUIP], pauseCtx->cursorX[PAUSE_EQUIP]); if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Inventory_ChangeEquipment(pauseCtx->cursorY[PAUSE_EQUIP], pauseCtx->cursorX[PAUSE_EQUIP]);
if (pauseCtx->cursorY[PAUSE_EQUIP] == 0) { if (pauseCtx->cursorY[PAUSE_EQUIP] == 0) {
gSaveContext.infTable[29] = 0; gSaveContext.infTable[29] = 0;
gSaveContext.equips.buttonItems[0] = cursorItem; gSaveContext.equips.buttonItems[0] = cursorItem;
if ((pauseCtx->cursorX[PAUSE_EQUIP] == 3) && (gSaveContext.bgsFlag != 0)) { if ((pauseCtx->cursorX[PAUSE_EQUIP] == 3) && (gSaveContext.bgsFlag != 0)) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
gSaveContext.swordHealth = 8;
} else {
if (gSaveContext.equips.buttonItems[0] == ITEM_HEART_PIECE_2) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
gSaveContext.swordHealth = 8;
} else {
if (gSaveContext.equips.buttonItems[0] == ITEM_HEART_PIECE_2) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS;
}
if ((gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS) && (gSaveContext.bgsFlag == 0) &&
(gBitFlags[3] & gSaveContext.inventory.equipment)) {
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE;
}
} }
if ((gSaveContext.equips.buttonItems[0] == ITEM_SWORD_BGS) && (gSaveContext.bgsFlag == 0) &&
(gBitFlags[3] & gSaveContext.inventory.equipment)) { Interface_LoadItemIcon1(globalCtx, 0);
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE;
}
} }
Interface_LoadItemIcon1(globalCtx, 0); Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
pauseCtx->unk_1E4 = 7;
sEquipTimer = 10;
} else if (CVar_GetS32("gAssignableTunicsAndBoots", 0) != 0) {
// Only allow assigning tunic and boots to c-buttons
if (pauseCtx->cursorY[PAUSE_EQUIP] > 1) {
u16 slot = 0;
switch (cursorItem) {
case ITEM_TUNIC_KOKIRI:
slot = SLOT_TUNIC_KOKIRI;
break;
case ITEM_TUNIC_GORON:
slot = SLOT_TUNIC_GORON;
break;
case ITEM_TUNIC_ZORA:
slot = SLOT_TUNIC_ZORA;
break;
case ITEM_BOOTS_KOKIRI:
slot = SLOT_BOOTS_KOKIRI;
break;
case ITEM_BOOTS_IRON:
slot = SLOT_BOOTS_IRON;
break;
case ITEM_BOOTS_HOVER:
slot = SLOT_BOOTS_HOVER;
break;
default:
break;
}
KaleidoScope_SetupItemEquip(globalCtx, cursorItem, slot,
pauseCtx->equipVtx[cursorSlot * 4].v.ob[0] * 10,
pauseCtx->equipVtx[cursorSlot * 4].v.ob[1] * 10);
}
} }
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
pauseCtx->unk_1E4 = 7;
sEquipTimer = 10;
} else { } else {
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
} else if ((CVar_GetS32("gAssignableTunicsAndBoots", 0) != 0) && (pauseCtx->cursorY[PAUSE_EQUIP] > 1)) {
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
} }
} }

View file

@ -351,43 +351,9 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
if (((gSlotAgeReqs[cursorSlot] == 9) || if (((gSlotAgeReqs[cursorSlot] == 9) ||
(gSlotAgeReqs[cursorSlot] == ((void)0, gSaveContext.linkAge))) && (gSlotAgeReqs[cursorSlot] == ((void)0, gSaveContext.linkAge))) &&
(cursorItem != ITEM_SOLD_OUT)) { (cursorItem != ITEM_SOLD_OUT)) {
if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) { KaleidoScope_SetupItemEquip(globalCtx, cursorItem, cursorSlot,
pauseCtx->equipTargetCBtn = 0; pauseCtx->itemVtx[index].v.ob[0] * 10,
} else if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) { pauseCtx->itemVtx[index].v.ob[1] * 10);
pauseCtx->equipTargetCBtn = 1;
} else if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
pauseCtx->equipTargetCBtn = 2;
}
pauseCtx->equipTargetItem = cursorItem;
pauseCtx->equipTargetSlot = cursorSlot;
pauseCtx->unk_1E4 = 3;
pauseCtx->equipAnimX = pauseCtx->itemVtx[index].v.ob[0] * 10;
pauseCtx->equipAnimY = pauseCtx->itemVtx[index].v.ob[1] * 10;
pauseCtx->equipAnimAlpha = 255;
sEquipAnimTimer = 0;
sEquipState = 3;
sEquipMoveTimer = 10;
if ((pauseCtx->equipTargetItem == ITEM_ARROW_FIRE) ||
(pauseCtx->equipTargetItem == ITEM_ARROW_ICE) ||
(pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT)) {
index = 0;
if (pauseCtx->equipTargetItem == ITEM_ARROW_ICE) {
index = 1;
}
if (pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT) {
index = 2;
}
Audio_PlaySoundGeneral(NA_SE_SY_SET_FIRE_ARROW + index, &D_801333D4, 4, &D_801333E0,
&D_801333E0, &D_801333E8);
pauseCtx->equipTargetItem = 0xBF + index;
sEquipState = 0;
pauseCtx->equipAnimAlpha = 0;
sEquipMoveTimer = 6;
} else {
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
}
} else { } else {
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8); &D_801333E8);
@ -419,7 +385,9 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
gDPSetEnvColor(POLY_KAL_DISP++, 0, 0, 0, 0); gDPSetEnvColor(POLY_KAL_DISP++, 0, 0, 0, 0);
for (i = 0, j = 24 * 4; i < 3; i++, j += 4) { for (i = 0, j = 24 * 4; i < 3; i++, j += 4) {
if (gSaveContext.equips.buttonItems[i + 1] != ITEM_NONE) { if ((gSaveContext.equips.buttonItems[i + 1] != ITEM_NONE) &&
!((gSaveContext.equips.buttonItems[i + 1] >= ITEM_SHIELD_DEKU) &&
(gSaveContext.equips.buttonItems[i + 1] <= ITEM_BOOTS_HOVER))) {
gSPVertex(POLY_KAL_DISP++, &pauseCtx->itemVtx[j], 4, 0); gSPVertex(POLY_KAL_DISP++, &pauseCtx->itemVtx[j], 4, 0);
POLY_KAL_DISP = KaleidoScope_QuadTextureIA8(POLY_KAL_DISP, gEquippedItemOutlineTex, 32, 32, 0); POLY_KAL_DISP = KaleidoScope_QuadTextureIA8(POLY_KAL_DISP, gEquippedItemOutlineTex, 32, 32, 0);
} }
@ -496,6 +464,46 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) {
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_kaleido_item.c", 516); CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_kaleido_item.c", 516);
} }
void KaleidoScope_SetupItemEquip(GlobalContext* globalCtx, u16 item, u16 slot, s16 animX, s16 animY) {
Input* input = &globalCtx->state.input[0];
PauseContext* pauseCtx = &globalCtx->pauseCtx;
if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) {
pauseCtx->equipTargetCBtn = 0;
} else if (CHECK_BTN_ALL(input->press.button, BTN_CDOWN)) {
pauseCtx->equipTargetCBtn = 1;
} else if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) {
pauseCtx->equipTargetCBtn = 2;
}
pauseCtx->equipTargetItem = item;
pauseCtx->equipTargetSlot = slot;
pauseCtx->unk_1E4 = 3;
pauseCtx->equipAnimX = animX;
pauseCtx->equipAnimY = animY;
pauseCtx->equipAnimAlpha = 255;
sEquipAnimTimer = 0;
sEquipState = 3;
sEquipMoveTimer = 10;
if ((pauseCtx->equipTargetItem == ITEM_ARROW_FIRE) || (pauseCtx->equipTargetItem == ITEM_ARROW_ICE) ||
(pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT)) {
u16 index = 0;
if (pauseCtx->equipTargetItem == ITEM_ARROW_ICE) {
index = 1;
}
if (pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT) {
index = 2;
}
Audio_PlaySoundGeneral(NA_SE_SY_SET_FIRE_ARROW + index, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
pauseCtx->equipTargetItem = 0xBF + index;
sEquipState = 0;
pauseCtx->equipAnimAlpha = 0;
sEquipMoveTimer = 6;
} else {
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
}
static s16 sCButtonPosX[] = { 66, 90, 114 }; static s16 sCButtonPosX[] = { 66, 90, 114 };
static s16 sCButtonPosY[] = { 110, 92, 110 }; static s16 sCButtonPosY[] = { 110, 92, 110 };

View file

@ -18,6 +18,7 @@ void KaleidoScope_DrawPlayerWork(GlobalContext* globalCtx);
void KaleidoScope_DrawEquipment(GlobalContext* globalCtx); void KaleidoScope_DrawEquipment(GlobalContext* globalCtx);
void KaleidoScope_SetCursorVtx(PauseContext* pauseCtx, u16 index, Vtx* vtx); void KaleidoScope_SetCursorVtx(PauseContext* pauseCtx, u16 index, Vtx* vtx);
void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx); void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx);
void KaleidoScope_SetupItemEquip(GlobalContext* globalCtx, u16 item, u16 slot, s16 animX, s16 animY);
void KaleidoScope_UpdateItemEquip(GlobalContext* globalCtx); void KaleidoScope_UpdateItemEquip(GlobalContext* globalCtx);
void KaleidoScope_DrawDungeonMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx); void KaleidoScope_DrawDungeonMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx);
void KaleidoScope_DrawWorldMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx); void KaleidoScope_DrawWorldMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx);

View file

@ -916,6 +916,13 @@ void KaleidoScope_SwitchPage(PauseContext* pauseCtx, u8 pt) {
gSaveContext.buttonStatus[3] = D_8082AB6C[pauseCtx->pageIndex + pt][3]; gSaveContext.buttonStatus[3] = D_8082AB6C[pauseCtx->pageIndex + pt][3];
gSaveContext.buttonStatus[4] = D_8082AB6C[pauseCtx->pageIndex + pt][4]; gSaveContext.buttonStatus[4] = D_8082AB6C[pauseCtx->pageIndex + pt][4];
if ((CVar_GetS32("gAssignableTunicsAndBoots", 0) != 0) && (D_8082ABEC[pauseCtx->mode] == PAUSE_EQUIP)) {
gSaveContext.buttonStatus[1] = BTN_ENABLED;
gSaveContext.buttonStatus[2] = BTN_ENABLED;
gSaveContext.buttonStatus[3] = BTN_ENABLED;
gSaveContext.buttonStatus[4] = BTN_ENABLED;
}
osSyncPrintf("kscope->kscp_pos+pt = %d\n", pauseCtx->pageIndex + pt); osSyncPrintf("kscope->kscp_pos+pt = %d\n", pauseCtx->pageIndex + pt);
gSaveContext.unk_13EA = 0; gSaveContext.unk_13EA = 0;
@ -968,6 +975,29 @@ void KaleidoScope_DrawCursor(GlobalContext* globalCtx, u16 pageIndex) {
temp = pauseCtx->unk_1E4; temp = pauseCtx->unk_1E4;
if (CVar_GetS32("gHudColors", 1) == 0) {
sCursorColors[1][0] = 255;
sCursorColors[1][1] = 255;
sCursorColors[1][2] = 0;
sCursorColors[2][0] = 0;
sCursorColors[2][1] = 50;
sCursorColors[2][2] = 255;
} else if (CVar_GetS32("gHudColors", 1) == 1) {
sCursorColors[1][0] = 255;
sCursorColors[1][1] = 255;
sCursorColors[1][2] = 0;
sCursorColors[2][0] = 0;
sCursorColors[2][1] = 255;
sCursorColors[2][2] = 50;
} else if (CVar_GetS32("gHudColors", 1) == 2) {
sCursorColors[1][0] = CVar_GetS32("gCCCBtnPrimR", 255);
sCursorColors[1][1] = CVar_GetS32("gCCCBtnPrimG", 255);
sCursorColors[1][2] = CVar_GetS32("gCCCBtnPrimB", 0);
sCursorColors[2][0] = CVar_GetS32("gCCABtnPrimR", 0);
sCursorColors[2][1] = CVar_GetS32("gCCABtnPrimG", 255);
sCursorColors[2][2] = CVar_GetS32("gCCABtnPrimB", 50);
}
if ((((pauseCtx->unk_1E4 == 0) || (temp == 8)) && (pauseCtx->state == 6)) || if ((((pauseCtx->unk_1E4 == 0) || (temp == 8)) && (pauseCtx->state == 6)) ||
((pauseCtx->pageIndex == PAUSE_QUEST) && ((temp < 3) || (temp == 5) || (temp == 8)))) { ((pauseCtx->pageIndex == PAUSE_QUEST) && ((temp < 3) || (temp == 5) || (temp == 8)))) {
@ -1038,6 +1068,46 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) {
{ 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 255, 255, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 255, 255, 0 }, { 0, 0, 0 },
{ 0, 0, 0 }, { 255, 255, 0 }, { 0, 255, 50 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 255, 50 }, { 0, 0, 0 }, { 255, 255, 0 }, { 0, 255, 50 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 255, 50 },
}; };
if (CVar_GetS32("gHudColors", 1) == 0) {
D_8082ACF4[4][0] = 255;
D_8082ACF4[4][1] = 255;
D_8082ACF4[4][2] = 0;
D_8082ACF4[7][0] = 255;
D_8082ACF4[7][1] = 255;
D_8082ACF4[7][2] = 0;
D_8082ACF4[8][0] = 0;
D_8082ACF4[8][1] = 50;
D_8082ACF4[8][2] = 255;
D_8082ACF4[11][0] = 0;
D_8082ACF4[11][1] = 50;
D_8082ACF4[11][2] = 255;
} else if (CVar_GetS32("gHudColors", 1) == 1) {
D_8082ACF4[4][0] = 255;
D_8082ACF4[4][1] = 255;
D_8082ACF4[4][2] = 0;
D_8082ACF4[7][0] = 255;
D_8082ACF4[7][1] = 255;
D_8082ACF4[7][2] = 0;
D_8082ACF4[8][0] = 0;
D_8082ACF4[8][1] = 255;
D_8082ACF4[8][2] = 50;
D_8082ACF4[11][0] = 0;
D_8082ACF4[11][1] = 255;
D_8082ACF4[11][2] = 50;
} else if (CVar_GetS32("gHudColors", 1) == 2) {
D_8082ACF4[4][0] = CVar_GetS32("gCCCBtnPrimR", 255);
D_8082ACF4[4][1] = CVar_GetS32("gCCCBtnPrimG", 255);
D_8082ACF4[4][2] = CVar_GetS32("gCCCBtnPrimB", 0);
D_8082ACF4[7][0] = CVar_GetS32("gCCCBtnPrimR", 255);
D_8082ACF4[7][1] = CVar_GetS32("gCCCBtnPrimG", 255);
D_8082ACF4[7][2] = CVar_GetS32("gCCCBtnPrimB", 0);
D_8082ACF4[8][0] = CVar_GetS32("gCCABtnPrimR", 0);
D_8082ACF4[8][1] = CVar_GetS32("gCCABtnPrimG", 255);
D_8082ACF4[8][2] = CVar_GetS32("gCCABtnPrimB", 50);
D_8082ACF4[11][0] = CVar_GetS32("gCCABtnPrimR", 0);
D_8082ACF4[11][1] = CVar_GetS32("gCCABtnPrimG", 255);
D_8082ACF4[11][2] = CVar_GetS32("gCCABtnPrimB", 50);
}
static s16 D_8082AD3C = 20; static s16 D_8082AD3C = 20;
static s16 D_8082AD40 = 0; static s16 D_8082AD40 = 0;
static s16 D_8082AD44 = 0; static s16 D_8082AD44 = 0;
@ -1366,7 +1436,13 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) {
gDPSetCombineLERP(POLY_KAL_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0, gDPSetCombineLERP(POLY_KAL_DISP++, 1, 0, PRIMITIVE, 0, TEXEL0, 0, PRIMITIVE, 0, 1, 0, PRIMITIVE, 0, TEXEL0,
0, PRIMITIVE, 0); 0, PRIMITIVE, 0);
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 255, 100, VREG(61)); if (CVar_GetS32("gHudColors", 1) == 0) {//Save prompt cursor colour
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 100, 255, VREG(61));
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 100, 255, 100, VREG(61));
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", 100), CVar_GetS32("gCCABtnPrimG", 255), CVar_GetS32("gCCABtnPrimB", 100), VREG(61)); //Save prompt cursor colour
}
if (pauseCtx->promptChoice == 0) { if (pauseCtx->promptChoice == 0) {
gSPDisplayList(POLY_KAL_DISP++, gPromptCursorLeftDL); gSPDisplayList(POLY_KAL_DISP++, gPromptCursorLeftDL);
@ -1425,6 +1501,10 @@ void KaleidoScope_DrawPages(GlobalContext* globalCtx, GraphicsContext* gfxCtx) {
} }
void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) { void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) {
static s16 gABtnTexColour[][4] = { //A button colors
{ 0, 255, 100, 255 },//Gamecube
{ 0, 100, 255, 255 },//Original N64
};
static void* D_8082AD54[3] = { static void* D_8082AD54[3] = {
gPauseToEquipENGTex, gPauseToEquipENGTex,
gPauseToEquipGERTex, gPauseToEquipGERTex,
@ -1750,8 +1830,16 @@ void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) {
pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] = D_8082ADE0[gSaveContext.language] pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] = D_8082ADE0[gSaveContext.language]
<< 5; << 5;
if (CVar_GetS32("gHudColors", 1) == 0) {//A icon to decide in save prompt
gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[1][0], gABtnTexColour[1][1], gABtnTexColour[1][2], gABtnTexColour[1][3]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[0][0], gABtnTexColour[0][1], gABtnTexColour[0][2], gABtnTexColour[0][3]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", gABtnTexColour[0][0]), CVar_GetS32("gCCABtnPrimG", gABtnTexColour[0][1]), CVar_GetS32("gCCABtnPrimB", gABtnTexColour[0][2]), gABtnTexColour[0][3]);
}
//gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL);//This is changed to load the texture only so we can prim color it.
gDPLoadTextureBlock(POLY_KAL_DISP++, gABtnSymbolTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(POLY_KAL_DISP++, 0, 2, 3, 1, 0);
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255);
@ -1797,7 +1885,16 @@ void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) {
pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] = pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] =
D_8082ADD8[gSaveContext.language] << 5; D_8082ADD8[gSaveContext.language] << 5;
gSPDisplayList(POLY_KAL_DISP++, gCButtonIconsDL); if (CVar_GetS32("gHudColors", 1) == 0) {//To equip text C button icon
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), 255);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, R_C_BTN_COLOR(0), R_C_BTN_COLOR(1), R_C_BTN_COLOR(2), 255);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCCBtnPrimR", R_C_BTN_COLOR(0)), CVar_GetS32("gCCCBtnPrimG", R_C_BTN_COLOR(1)), CVar_GetS32("gCCCBtnPrimB", R_C_BTN_COLOR(2)), 255);
}
//gSPDisplayList(POLY_KAL_DISP++, gCButtonIconsDL); //Same reason for every A button, to be able to recolor them.
gDPLoadTextureBlock(POLY_KAL_DISP++, gCBtnSymbolsTex, G_IM_FMT_IA, G_IM_SIZ_8b, 48, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(POLY_KAL_DISP++, 0, 2, 3, 1, 0);
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255);
@ -1831,7 +1928,16 @@ void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) {
pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] = pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] =
D_8082ADE8[gSaveContext.language] << 5; D_8082ADE8[gSaveContext.language] << 5;
gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL); if (CVar_GetS32("gHudColors", 1) == 0) {//To play melody A button
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[1][0], gABtnTexColour[1][1], gABtnTexColour[1][2], gABtnTexColour[1][3]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[0][0], gABtnTexColour[0][1], gABtnTexColour[0][2], gABtnTexColour[0][3]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", gABtnTexColour[0][0]), CVar_GetS32("gCCABtnPrimG", gABtnTexColour[0][1]), CVar_GetS32("gCCABtnPrimB", gABtnTexColour[0][2]), gABtnTexColour[0][3]);
}
//gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL);
gDPLoadTextureBlock(POLY_KAL_DISP++, gABtnSymbolTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(POLY_KAL_DISP++, 0, 2, 3, 1, 0);
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255);
@ -1857,7 +1963,16 @@ void KaleidoScope_DrawInfoPanel(GlobalContext* globalCtx) {
pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] = pauseCtx->infoPanelVtx[21].v.tc[0] = pauseCtx->infoPanelVtx[23].v.tc[0] =
D_8082ADD8[gSaveContext.language] << 5; D_8082ADD8[gSaveContext.language] << 5;
gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL); //gSPDisplayList(POLY_KAL_DISP++, gAButtonIconDL);
if (CVar_GetS32("gHudColors", 1) == 0) {//To equip A button
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[1][0], gABtnTexColour[1][1], gABtnTexColour[1][2], gABtnTexColour[1][3]);
} else if (CVar_GetS32("gHudColors", 1) == 1) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, gABtnTexColour[0][0], gABtnTexColour[0][1], gABtnTexColour[0][2], gABtnTexColour[0][3]);
} else if (CVar_GetS32("gHudColors", 1) == 2) {
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, CVar_GetS32("gCCABtnPrimR", gABtnTexColour[0][0]), CVar_GetS32("gCCABtnPrimG", gABtnTexColour[0][1]), CVar_GetS32("gCCABtnPrimB", gABtnTexColour[0][2]), gABtnTexColour[0][3]);
}
gDPLoadTextureBlock(POLY_KAL_DISP++, gABtnSymbolTex, G_IM_FMT_IA, G_IM_SIZ_8b, 24, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, G_TX_NOLOD, G_TX_NOLOD);
gSP1Quadrangle(POLY_KAL_DISP++, 0, 2, 3, 1, 0);
gDPPipeSync(POLY_KAL_DISP++); gDPPipeSync(POLY_KAL_DISP++);
gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, 255);
@ -2860,14 +2975,6 @@ void KaleidoScope_GrayOutTextureRGBA32(u32* texture, u16 pixelCount) {
u16 gray; u16 gray;
u16 i; u16 i;
bind_hook( GRAYOUT_TEXTURE);
init_hook(2,
(struct HookParameter){ .name = "texture", .parameter = &texture },
(struct HookParameter){ .name = "pixelCount", .parameter = &pixelCount }
);
if (!call_hook(0))
return;
texture = ResourceMgr_LoadTexByName(texture); texture = ResourceMgr_LoadTexByName(texture);
for (i = 0; i < pixelCount; i++) { for (i = 0; i < pixelCount; i++) {
@ -2902,7 +3009,16 @@ void func_808265BC(GlobalContext* globalCtx) {
gSaveContext.buttonStatus[2] = D_8082AB6C[pauseCtx->pageIndex][2]; gSaveContext.buttonStatus[2] = D_8082AB6C[pauseCtx->pageIndex][2];
gSaveContext.buttonStatus[3] = D_8082AB6C[pauseCtx->pageIndex][3]; gSaveContext.buttonStatus[3] = D_8082AB6C[pauseCtx->pageIndex][3];
gSaveContext.buttonStatus[4] = D_8082AB6C[pauseCtx->pageIndex][4]; gSaveContext.buttonStatus[4] = D_8082AB6C[pauseCtx->pageIndex][4];
pauseCtx->pageIndex = D_8082ABEC[pauseCtx->mode]; pauseCtx->pageIndex = D_8082ABEC[pauseCtx->mode];
if ((CVar_GetS32("gAssignableTunicsAndBoots", 0) != 0) && (pauseCtx->pageIndex == PAUSE_EQUIP)) {
gSaveContext.buttonStatus[1] = BTN_ENABLED;
gSaveContext.buttonStatus[2] = BTN_ENABLED;
gSaveContext.buttonStatus[3] = BTN_ENABLED;
gSaveContext.buttonStatus[4] = BTN_ENABLED;
}
pauseCtx->unk_1E4 = 0; pauseCtx->unk_1E4 = 0;
pauseCtx->state++; pauseCtx->state++;
pauseCtx->alpha = 255; pauseCtx->alpha = 255;