mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-08 12:16:17 -04:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1520205403 | |||
| d2d7459d05 | |||
| c71272af05 | |||
| 30b7087f30 | |||
| 0c1372f986 | |||
| a4777045fe | |||
| bbe8ea6aa6 | |||
| d662db69f0 | |||
| 9b259143be |
@@ -1453,6 +1453,7 @@ set(DUSK_FILES
|
|||||||
src/dusk/imgui/ImGuiProcessOverlay.cpp
|
src/dusk/imgui/ImGuiProcessOverlay.cpp
|
||||||
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
||||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||||
|
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||||
src/dusk/imgui/ImGuiDebugPad.cpp
|
src/dusk/imgui/ImGuiDebugPad.cpp
|
||||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||||
src/dusk/imgui/ImGuiStubLog.cpp
|
src/dusk/imgui/ImGuiStubLog.cpp
|
||||||
@@ -1466,6 +1467,7 @@ set(DUSK_FILES
|
|||||||
src/dusk/iso_validate.cpp
|
src/dusk/iso_validate.cpp
|
||||||
src/dusk/livesplit.cpp
|
src/dusk/livesplit.cpp
|
||||||
src/dusk/offset_ptr.cpp
|
src/dusk/offset_ptr.cpp
|
||||||
|
src/dusk/vmem.cpp
|
||||||
src/dusk/OSContext.cpp
|
src/dusk/OSContext.cpp
|
||||||
src/dusk/OSThread.cpp
|
src/dusk/OSThread.cpp
|
||||||
src/dusk/OSMutex.cpp
|
src/dusk/OSMutex.cpp
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef DUSK_MEMORY_H
|
|
||||||
#define DUSK_MEMORY_H
|
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
#define HEAP_SIZE(original, dusk) (dusk)
|
|
||||||
#else
|
|
||||||
#define HEAP_SIZE(original, dusk) (original)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -76,6 +76,7 @@ struct UserSettings {
|
|||||||
ConfigVar<bool> fastClimbing;
|
ConfigVar<bool> fastClimbing;
|
||||||
ConfigVar<bool> noMissClimbing;
|
ConfigVar<bool> noMissClimbing;
|
||||||
ConfigVar<bool> fastTears;
|
ConfigVar<bool> fastTears;
|
||||||
|
ConfigVar<bool> no2ndFishForCat;
|
||||||
ConfigVar<bool> instantSaves;
|
ConfigVar<bool> instantSaves;
|
||||||
ConfigVar<bool> instantText;
|
ConfigVar<bool> instantText;
|
||||||
ConfigVar<bool> sunsSong;
|
ConfigVar<bool> sunsSong;
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace dusk {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Reserve a contiguous virtual address range without committing physical pages
|
||||||
|
void* vmem_reserve(size_t size);
|
||||||
|
|
||||||
|
// Commit physical backing for pages in a previously reserved range, ptr and size should be page-aligned
|
||||||
|
bool vmem_commit(void* ptr, size_t size);
|
||||||
|
|
||||||
|
// Decommit physical pages in a reserved range, releasing RAM without releasing address space
|
||||||
|
void vmem_decommit(void* ptr, size_t size);
|
||||||
|
|
||||||
|
// Release an entire virtual reservation obtained from vmem_reserve
|
||||||
|
void vmem_release(void* ptr, size_t size);
|
||||||
|
|
||||||
|
// Returns the OS page size
|
||||||
|
size_t vmem_page_size();
|
||||||
|
|
||||||
|
// Shared vmem arena
|
||||||
|
// All JKR heap vmem reservations are sub-allocated from a single large reservation,
|
||||||
|
// keeping the total entry count at 1 regardless of how many heaps exist
|
||||||
|
|
||||||
|
// Must be called once before any JKR heap is created
|
||||||
|
void vmem_arena_init();
|
||||||
|
|
||||||
|
// Allocate a slot of size bytes (page-aligned) from the arena
|
||||||
|
void* vmem_arena_alloc(size_t size);
|
||||||
|
|
||||||
|
// Return a slot to the arena and decommit its physical pages
|
||||||
|
void vmem_arena_free(void* ptr, size_t size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // namespace dusk
|
||||||
|
|
||||||
|
// Total virtual address space reserved for the shared JKR heap arena
|
||||||
|
inline constexpr size_t JKR_VMEM_ARENA_SIZE = 128ULL * 1024 * 1024 * 1024; // 128 GB
|
||||||
|
|
||||||
|
// Virtual address space reserved per JKR heap (one slot in the shared arena)
|
||||||
|
inline constexpr size_t JKR_HEAP_VIRTUAL_RESERVE = 64ULL * 1024 * 1024; // 64 MB
|
||||||
|
|
||||||
|
// Minimum growth increment when a JKR heap expands into reserved but uncommitted pages
|
||||||
|
inline constexpr size_t JKR_HEAP_GROW_CHUNK = 4ULL * 1024 * 1024; // 4 MB
|
||||||
|
|
||||||
|
// Maximum number of free slots the arena can track (= total slots in the arena)
|
||||||
|
inline constexpr size_t JKR_VMEM_MAX_FREE_SLOTS = JKR_VMEM_ARENA_SIZE / JKR_HEAP_VIRTUAL_RESERVE;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -127,6 +127,13 @@ public:
|
|||||||
[[nodiscard]] const CMemBlock* getFreeHead() const { return mHeadFreeList; }
|
[[nodiscard]] const CMemBlock* getFreeHead() const { return mHeadFreeList; }
|
||||||
[[nodiscard]] CMemBlock* getUsedHead() { return mHeadUsedList; }
|
[[nodiscard]] CMemBlock* getUsedHead() { return mHeadUsedList; }
|
||||||
[[nodiscard]] const CMemBlock* getUsedHead() const { return mHeadUsedList; }
|
[[nodiscard]] const CMemBlock* getUsedHead() const { return mHeadUsedList; }
|
||||||
|
|
||||||
|
void* mVmemBase; // base of VM reservation
|
||||||
|
size_t mVmemCapacity; // total reserved bytes
|
||||||
|
size_t mVmemCommitted; // page-aligned committed bytes so far
|
||||||
|
|
||||||
|
// Commit more pages and splice them into the free list
|
||||||
|
bool growHeap(u32 needed);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ public:
|
|||||||
static JKRSolidHeap* create(u32, JKRHeap*, bool);
|
static JKRSolidHeap* create(u32, JKRHeap*, bool);
|
||||||
|
|
||||||
static void* getState_(TState* state) { return getState_buf_(state); }
|
static void* getState_(TState* state) { return getState_buf_(state); }
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
void* mVmemBase; // base of VM reservation
|
||||||
|
size_t mVmemCapacity; // total reserved bytes
|
||||||
|
size_t mVmemCommitted; // page-aligned committed bytes so far
|
||||||
|
|
||||||
|
// Commit more pages and extend the free region
|
||||||
|
bool growHeap(u32 needed);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline JKRSolidHeap* JKRCreateSolidHeap(u32 param_0, JKRHeap* heap, bool param_2) {
|
inline JKRSolidHeap* JKRCreateSolidHeap(u32 param_0, JKRHeap* heap, bool param_2) {
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
#include "JSystem/JUtility/JUTConsole.h"
|
#include "JSystem/JUtility/JUTConsole.h"
|
||||||
#include "JSystem/JUtility/JUTException.h"
|
#include "JSystem/JUtility/JUTException.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#if TARGET_PC
|
||||||
|
#include "dusk/vmem.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "dusk/logging.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
JKRExpHeap* JKRExpHeap::createRoot(int maxHeaps, bool errorFlag) {
|
JKRExpHeap* JKRExpHeap::createRoot(int maxHeaps, bool errorFlag) {
|
||||||
JKRExpHeap* heap = NULL;
|
JKRExpHeap* heap = NULL;
|
||||||
@@ -71,21 +76,49 @@ JKRExpHeap* JKRExpHeap::create(u32 size, JKRHeap* parent, bool errorFlag) {
|
|||||||
|
|
||||||
u32 alignedSize = ALIGN_PREV(size, 0x10);
|
u32 alignedSize = ALIGN_PREV(size, 0x10);
|
||||||
|
|
||||||
if (alignedSize < expHeapSize + blockSize)
|
if (alignedSize < expHeapSize + blockSize) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
u8* memory = (u8*)JKRAllocFromHeap(parent, alignedSize, 0x10);
|
#if TARGET_PC
|
||||||
u8* dataPtr = (memory + expHeapSize);
|
u8* vmemBase = (u8*)dusk::vmem_arena_alloc(JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
if (!vmemBase) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t pageSize = dusk::vmem_page_size();
|
||||||
|
size_t commitSize = ALIGN_NEXT((size_t)alignedSize, pageSize);
|
||||||
|
if (!dusk::vmem_commit(vmemBase, commitSize)) {
|
||||||
|
dusk::vmem_arena_free(vmemBase, JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* memory = vmemBase;
|
||||||
|
u8* dataPtr = memory + expHeapSize;
|
||||||
|
|
||||||
|
newHeap = JKR_NEW_ARGS(memory) JKRExpHeap(dataPtr, alignedSize - expHeapSize, parent, errorFlag);
|
||||||
|
if (newHeap == NULL) {
|
||||||
|
dusk::vmem_arena_free(vmemBase, JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
newHeap->mVmemBase = vmemBase;
|
||||||
|
newHeap->mVmemCapacity = JKR_HEAP_VIRTUAL_RESERVE;
|
||||||
|
newHeap->mVmemCommitted = commitSize;
|
||||||
|
#else
|
||||||
|
u8* memory = (u8*)JKRAllocFromHeap(parent, alignedSize, 0x10);
|
||||||
|
u8* dataPtr = memory + expHeapSize;
|
||||||
if (!memory) {
|
if (!memory) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
newHeap = JKR_NEW_ARGS (memory) JKRExpHeap(dataPtr, alignedSize - expHeapSize, parent, errorFlag);
|
newHeap = JKR_NEW_ARGS(memory) JKRExpHeap(dataPtr, alignedSize - expHeapSize, parent, errorFlag);
|
||||||
|
|
||||||
if (newHeap == NULL) {
|
if (newHeap == NULL) {
|
||||||
JKRFree(memory);
|
JKRFree(memory);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (newHeap) {
|
if (newHeap) {
|
||||||
u8* local_30 = dataPtr + sizeof(CMemBlock);
|
u8* local_30 = dataPtr + sizeof(CMemBlock);
|
||||||
@@ -102,9 +135,16 @@ JKRExpHeap* JKRExpHeap::create(u32 size, JKRHeap* parent, bool errorFlag) {
|
|||||||
JKRExpHeap* JKRExpHeap::create(void* ptr, u32 size, JKRHeap* parent, bool errorFlag) {
|
JKRExpHeap* JKRExpHeap::create(void* ptr, u32 size, JKRHeap* parent, bool errorFlag) {
|
||||||
JKRHeap* parent2;
|
JKRHeap* parent2;
|
||||||
if (parent == NULL) {
|
if (parent == NULL) {
|
||||||
|
#if TARGET_PC
|
||||||
|
// VM-backed heaps live outside the root heap's address range, so find() fails
|
||||||
|
// findAllHeap() searches the full tree
|
||||||
|
parent2 = getRootHeap()->findAllHeap(ptr);
|
||||||
|
#else
|
||||||
parent2 = getRootHeap()->find(ptr);
|
parent2 = getRootHeap()->find(ptr);
|
||||||
if (!parent2)
|
#endif
|
||||||
|
if (!parent2) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
parent2 = parent;
|
parent2 = parent;
|
||||||
}
|
}
|
||||||
@@ -136,6 +176,15 @@ JKRExpHeap* JKRExpHeap::create(void* ptr, u32 size, JKRHeap* parent, bool errorF
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JKRExpHeap::do_destroy() {
|
void JKRExpHeap::do_destroy() {
|
||||||
|
#if TARGET_PC
|
||||||
|
if (mVmemBase) {
|
||||||
|
void* vmemBase = mVmemBase;
|
||||||
|
size_t vmemCapacity = mVmemCapacity;
|
||||||
|
this->~JKRExpHeap();
|
||||||
|
dusk::vmem_arena_free(vmemBase, vmemCapacity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (!field_0x6e) {
|
if (!field_0x6e) {
|
||||||
JKRHeap* heap = getParent();
|
JKRHeap* heap = getParent();
|
||||||
if (heap) {
|
if (heap) {
|
||||||
@@ -163,6 +212,11 @@ JKRExpHeap::JKRExpHeap(void* data, u32 size, JKRHeap* parent, bool errorFlag)
|
|||||||
mHeadFreeList->initiate(NULL, NULL, size - sizeof(CMemBlock), 0, 0);
|
mHeadFreeList->initiate(NULL, NULL, size - sizeof(CMemBlock), 0, 0);
|
||||||
mHeadUsedList = NULL;
|
mHeadUsedList = NULL;
|
||||||
mTailUsedList = NULL;
|
mTailUsedList = NULL;
|
||||||
|
#if TARGET_PC
|
||||||
|
mVmemBase = nullptr;
|
||||||
|
mVmemCapacity = 0;
|
||||||
|
mVmemCommitted = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
JKRExpHeap::~JKRExpHeap() {
|
JKRExpHeap::~JKRExpHeap() {
|
||||||
@@ -214,6 +268,24 @@ void* JKRExpHeap::do_alloc(u32 size, int alignment) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TARGET_PC
|
#if TARGET_PC
|
||||||
|
if (!ptr && mVmemBase) {
|
||||||
|
// Heap is full, commit the next chunk of reserved VM and retry
|
||||||
|
if (growHeap(size)) {
|
||||||
|
if (alignment >= 0) {
|
||||||
|
if (alignment <= 4) {
|
||||||
|
ptr = allocFromHead(size);
|
||||||
|
} else {
|
||||||
|
ptr = allocFromHead(size, alignment);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (-alignment <= 4) {
|
||||||
|
ptr = allocFromTail(size);
|
||||||
|
} else {
|
||||||
|
ptr = allocFromTail(size, -alignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
// Allocation failed.
|
// Allocation failed.
|
||||||
OSReport_Error(
|
OSReport_Error(
|
||||||
@@ -491,6 +563,49 @@ static void dummy() {
|
|||||||
OS_REPORT("newSize > 0");
|
OS_REPORT("newSize > 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
bool JKRExpHeap::growHeap(u32 needed) {
|
||||||
|
// Determine how much to commit
|
||||||
|
// Always grow by at least JKR_HEAP_GROW_CHUNK
|
||||||
|
const size_t pageSize = dusk::vmem_page_size();
|
||||||
|
size_t wantBytes = (size_t)needed + sizeof(CMemBlock);
|
||||||
|
size_t growAmount = std::max(wantBytes, JKR_HEAP_GROW_CHUNK);
|
||||||
|
growAmount = ALIGN_NEXT(growAmount, pageSize);
|
||||||
|
|
||||||
|
size_t remaining = mVmemCapacity - mVmemCommitted;
|
||||||
|
if (growAmount > remaining) {
|
||||||
|
// Clamp to whatever reservation is left
|
||||||
|
growAmount = ALIGN_PREV(remaining, pageSize);
|
||||||
|
if (growAmount < wantBytes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* commitBase = (u8*)mVmemBase + mVmemCommitted;
|
||||||
|
if (!dusk::vmem_commit(commitBase, growAmount)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splice the new committed region into the free list as a single block at mEnd
|
||||||
|
CMemBlock* newBlock = (CMemBlock*)mEnd;
|
||||||
|
newBlock->size = (u32)(growAmount - sizeof(CMemBlock));
|
||||||
|
newBlock->mFlags = 0;
|
||||||
|
|
||||||
|
mEnd = (u8*)mEnd + growAmount;
|
||||||
|
mSize += (u32)growAmount;
|
||||||
|
mVmemCommitted += growAmount;
|
||||||
|
|
||||||
|
recycleFreeBlock(newBlock);
|
||||||
|
|
||||||
|
DuskLog.debug("[JKRExpHeap] '{}' grew by {} MB (committed: {} MB / reserved: {} MB)\n",
|
||||||
|
getName(),
|
||||||
|
growAmount / (1024 * 1024),
|
||||||
|
mVmemCommitted / (1024 * 1024),
|
||||||
|
mVmemCapacity / (1024 * 1024));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void JKRExpHeap::do_freeAll() {
|
void JKRExpHeap::do_freeAll() {
|
||||||
lock();
|
lock();
|
||||||
JKRHeap::callAllDisposer();
|
JKRHeap::callAllDisposer();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||||
|
|
||||||
#include "JSystem/JKernel/JKRSolidHeap.h"
|
#include "JSystem/JKernel/JKRSolidHeap.h"
|
||||||
#include "JSystem/JGadget/binary.h"
|
#include "JSystem/JGadget/binary.h"
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#if TARGET_PC
|
||||||
|
#include "dusk/vmem.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "dusk/logging.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
JKRSolidHeap* JKRSolidHeap::create(u32 size, JKRHeap* heap, bool useErrorHandler) {
|
JKRSolidHeap* JKRSolidHeap::create(u32 size, JKRHeap* heap, bool useErrorHandler) {
|
||||||
if (!heap) {
|
if (!heap) {
|
||||||
@@ -19,18 +24,56 @@ JKRSolidHeap* JKRSolidHeap::create(u32 size, JKRHeap* heap, bool useErrorHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 alignedSize = ALIGN_PREV(size, 0x10);
|
u32 alignedSize = ALIGN_PREV(size, 0x10);
|
||||||
if (alignedSize < solidHeapSize)
|
if (alignedSize < solidHeapSize) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
u8* vmemBase = (u8*)dusk::vmem_arena_alloc(JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
if (!vmemBase) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const size_t pageSize = dusk::vmem_page_size();
|
||||||
|
size_t commitSize = ALIGN_NEXT((size_t)alignedSize, pageSize);
|
||||||
|
if (!dusk::vmem_commit(vmemBase, commitSize)) {
|
||||||
|
dusk::vmem_arena_free(vmemBase, JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* mem = vmemBase;
|
||||||
|
void* dataPtr = mem + solidHeapSize;
|
||||||
|
|
||||||
|
JKRSolidHeap* newHeap = JKR_NEW_ARGS(mem) JKRSolidHeap(dataPtr, alignedSize - solidHeapSize, heap, useErrorHandler);
|
||||||
|
if (newHeap == NULL) {
|
||||||
|
dusk::vmem_arena_free(vmemBase, JKR_HEAP_VIRTUAL_RESERVE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
newHeap->mVmemBase = vmemBase;
|
||||||
|
newHeap->mVmemCapacity = JKR_HEAP_VIRTUAL_RESERVE;
|
||||||
|
newHeap->mVmemCommitted = commitSize;
|
||||||
|
return newHeap;
|
||||||
|
#else
|
||||||
u8* mem = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x10);
|
u8* mem = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x10);
|
||||||
void* dataPtr = mem + solidHeapSize;
|
void* dataPtr = mem + solidHeapSize;
|
||||||
if (!mem)
|
if (!mem) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return JKR_NEW_ARGS (mem) JKRSolidHeap(dataPtr, alignedSize - solidHeapSize, heap, useErrorHandler);
|
return JKR_NEW_ARGS (mem) JKRSolidHeap(dataPtr, alignedSize - solidHeapSize, heap, useErrorHandler);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKRSolidHeap::do_destroy(void) {
|
void JKRSolidHeap::do_destroy(void) {
|
||||||
|
#if TARGET_PC
|
||||||
|
if (mVmemBase) {
|
||||||
|
void* vmemBase = mVmemBase;
|
||||||
|
size_t vmemCapacity = mVmemCapacity;
|
||||||
|
this->~JKRSolidHeap();
|
||||||
|
dusk::vmem_arena_free(vmemBase, vmemCapacity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
JKRHeap* parent = getParent();
|
JKRHeap* parent = getParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this->~JKRSolidHeap();
|
this->~JKRSolidHeap();
|
||||||
@@ -44,6 +87,11 @@ JKRSolidHeap::JKRSolidHeap(void* start, u32 size, JKRHeap* parent, bool useError
|
|||||||
mSolidHead = (u8*)mStart;
|
mSolidHead = (u8*)mStart;
|
||||||
mSolidTail = (u8*)mEnd;
|
mSolidTail = (u8*)mEnd;
|
||||||
field_0x78 = NULL;
|
field_0x78 = NULL;
|
||||||
|
#if TARGET_PC
|
||||||
|
mVmemBase = nullptr;
|
||||||
|
mVmemCapacity = 0;
|
||||||
|
mVmemCommitted = 0;
|
||||||
|
#endif
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (mDebugFill) {
|
if (mDebugFill) {
|
||||||
JKRFillMemory(mStart, mSize, JKRValue_DEBUGFILL_NOTUSE);
|
JKRFillMemory(mStart, mSize, JKRValue_DEBUGFILL_NOTUSE);
|
||||||
@@ -59,6 +107,15 @@ s32 JKRSolidHeap::adjustSize(void) {
|
|||||||
int r25 = 0;
|
int r25 = 0;
|
||||||
JKRHeap* parent = getParent();
|
JKRHeap* parent = getParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
#if TARGET_PC
|
||||||
|
if (mVmemBase) {
|
||||||
|
// VM-backed heap, can't resize in parent, but this is not a failure
|
||||||
|
// Return what the trimmed size would have been so the caller doesn't log an error
|
||||||
|
u32 thisSize = (uintptr_t)mStart - (uintptr_t)this;
|
||||||
|
u32 newSize = ALIGN_NEXT(mSolidHead - mStart, 0x20);
|
||||||
|
return (s32)(thisSize + newSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
lock();
|
lock();
|
||||||
u32 thisSize = (uintptr_t)mStart - (uintptr_t)this;
|
u32 thisSize = (uintptr_t)mStart - (uintptr_t)this;
|
||||||
u32 newSize = ALIGN_NEXT(mSolidHead - mStart, 0x20);
|
u32 newSize = ALIGN_NEXT(mSolidHead - mStart, 0x20);
|
||||||
@@ -110,6 +167,11 @@ void* JKRSolidHeap::allocFromHead(u32 size, int alignment) {
|
|||||||
void* ptr = NULL;
|
void* ptr = NULL;
|
||||||
uintptr_t alignedStart = (alignment - 1 + (uintptr_t)mSolidHead) & ~(alignment - 1);
|
uintptr_t alignedStart = (alignment - 1 + (uintptr_t)mSolidHead) & ~(alignment - 1);
|
||||||
u32 totalSize = size + (alignedStart - (uintptr_t)mSolidHead);
|
u32 totalSize = size + (alignedStart - (uintptr_t)mSolidHead);
|
||||||
|
#if TARGET_PC
|
||||||
|
if (totalSize > mFreeSize && mVmemBase) {
|
||||||
|
growHeap(totalSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (totalSize <= mFreeSize) {
|
if (totalSize <= mFreeSize) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (mCheckMemoryFilled) {
|
if (mCheckMemoryFilled) {
|
||||||
@@ -137,6 +199,15 @@ void* JKRSolidHeap::allocFromTail(u32 size, int alignment) {
|
|||||||
void* ptr = NULL;
|
void* ptr = NULL;
|
||||||
uintptr_t alignedStart = ALIGN_PREV((uintptr_t)mSolidTail - size, alignment);
|
uintptr_t alignedStart = ALIGN_PREV((uintptr_t)mSolidTail - size, alignment);
|
||||||
u32 totalSize = (uintptr_t)mSolidTail - (uintptr_t)alignedStart;
|
u32 totalSize = (uintptr_t)mSolidTail - (uintptr_t)alignedStart;
|
||||||
|
#if TARGET_PC
|
||||||
|
if (totalSize > mFreeSize && mVmemBase) {
|
||||||
|
if (growHeap(totalSize)) {
|
||||||
|
// mSolidTail moved to new mEnd; recompute from the new tail position
|
||||||
|
alignedStart = ALIGN_PREV((uintptr_t)mSolidTail - size, alignment);
|
||||||
|
totalSize = (uintptr_t)mSolidTail - (uintptr_t)alignedStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (totalSize <= mFreeSize) {
|
if (totalSize <= mFreeSize) {
|
||||||
ptr = (void*)alignedStart;
|
ptr = (void*)alignedStart;
|
||||||
mSolidTail -= totalSize;
|
mSolidTail -= totalSize;
|
||||||
@@ -158,6 +229,47 @@ void* JKRSolidHeap::allocFromTail(u32 size, int alignment) {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
bool JKRSolidHeap::growHeap(u32 needed) {
|
||||||
|
// Growth is only safe when no tail allocations exist yet
|
||||||
|
if (mSolidTail != mEnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t pageSize = dusk::vmem_page_size();
|
||||||
|
size_t wantBytes = (size_t)needed;
|
||||||
|
size_t growAmount = std::max(wantBytes, JKR_HEAP_GROW_CHUNK);
|
||||||
|
growAmount = ALIGN_NEXT(growAmount, pageSize);
|
||||||
|
|
||||||
|
size_t remaining = mVmemCapacity - mVmemCommitted;
|
||||||
|
if (growAmount > remaining) {
|
||||||
|
growAmount = ALIGN_PREV(remaining, pageSize);
|
||||||
|
if (growAmount < wantBytes) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* commitBase = (u8*)mVmemBase + mVmemCommitted;
|
||||||
|
if (!dusk::vmem_commit(commitBase, growAmount)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extend the heap end and the tail pointer
|
||||||
|
mEnd = (u8*)mEnd + growAmount;
|
||||||
|
mSolidTail = mEnd;
|
||||||
|
mFreeSize += (u32)growAmount;
|
||||||
|
mSize += (u32)growAmount;
|
||||||
|
mVmemCommitted += growAmount;
|
||||||
|
|
||||||
|
DuskLog.debug("[JKRSolidHeap] '{}' grew by {} MB (committed: {} MB / reserved: {} MB)\n",
|
||||||
|
getName(),
|
||||||
|
growAmount / (1024 * 1024),
|
||||||
|
mVmemCommitted / (1024 * 1024),
|
||||||
|
mVmemCapacity / (1024 * 1024));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void JKRSolidHeap::do_free(void* ptr) {
|
void JKRSolidHeap::do_free(void* ptr) {
|
||||||
JUTWarningConsole_f("free: cannot free memory block (%08x)\n", ptr);
|
JUTWarningConsole_f("free: cannot free memory block (%08x)\n", ptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
#include "JSystem/J2DGraph/J2DAnmLoader.h"
|
#include "JSystem/J2DGraph/J2DAnmLoader.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "dusk/memory.h"
|
|
||||||
|
|
||||||
class daCoach2D_HIO_c : public mDoHIO_entry_c {
|
class daCoach2D_HIO_c : public mDoHIO_entry_c {
|
||||||
public:
|
public:
|
||||||
struct Param {
|
struct Param {
|
||||||
@@ -155,7 +153,7 @@ int daCoach2D_c::createHeap() {
|
|||||||
int daCoach2D_c::create() {
|
int daCoach2D_c::create() {
|
||||||
int phase_state = dComIfG_resLoad(this, l_arcName);
|
int phase_state = dComIfG_resLoad(this, l_arcName);
|
||||||
if (phase_state == cPhs_COMPLEATE_e) {
|
if (phase_state == cPhs_COMPLEATE_e) {
|
||||||
if (!fopAcM_entrySolidHeap(this, daCoach2D_createHeap, HEAP_SIZE(0x5050, 0x6000))) {
|
if (!fopAcM_entrySolidHeap(this, daCoach2D_createHeap, 0x5050)) {
|
||||||
return cPhs_ERROR_e;
|
return cPhs_ERROR_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -956,7 +956,7 @@ static void npc_ne_tame(npc_ne_class* i_this) {
|
|||||||
i_this->mpMorf->setPlaySpeed(i_this->mAnmSpeed);
|
i_this->mpMorf->setPlaySpeed(i_this->mAnmSpeed);
|
||||||
|
|
||||||
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
||||||
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
|
if (IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) {
|
||||||
if (fpcEx_Search(s_fish_sub, _this) != NULL) {
|
if (fpcEx_Search(s_fish_sub, _this) != NULL) {
|
||||||
i_this->mAction = npc_ne_class::ACT_HOME;
|
i_this->mAction = npc_ne_class::ACT_HOME;
|
||||||
i_this->mMode = 10;
|
i_this->mMode = 10;
|
||||||
@@ -2948,8 +2948,7 @@ static int daNpc_Ne_Execute(npc_ne_class* i_this) {
|
|||||||
|
|
||||||
if (i_this->mWantsFish && (i_this->mCounter & 0xf) == 0) {
|
if (i_this->mWantsFish && (i_this->mCounter & 0xf) == 0) {
|
||||||
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
/* dSv_event_flag_c::F_0470 - Fishing Pond - Reserved for fishing */
|
||||||
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])
|
if ((IF_DUSK(dusk::getSettings().game.no2ndFishForCat) || dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[470])) && i_this->mDistToTarget < 1500.0f) {
|
||||||
&& i_this->mDistToTarget < 1500.0f) {
|
|
||||||
if (fopAcM_SearchByName(fpcNm_MG_ROD_e) != NULL) {
|
if (fopAcM_SearchByName(fpcNm_MG_ROD_e) != NULL) {
|
||||||
i_this->mNoFollow = false;
|
i_this->mNoFollow = false;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+33
-20
@@ -794,16 +794,15 @@ void dCamera_c::updatePad() {
|
|||||||
|
|
||||||
if (mTriggerLeftLast > mCamSetup.ManualEndVal()) {
|
if (mTriggerLeftLast > mCamSetup.ManualEndVal()) {
|
||||||
if (mLockLActive == 0) {
|
if (mLockLActive == 0) {
|
||||||
|
#if TARGET_PC
|
||||||
|
mCamParam.mManualMode = 0;
|
||||||
|
#endif
|
||||||
mLockLJustActivated = 1;
|
mLockLJustActivated = 1;
|
||||||
} else {
|
} else {
|
||||||
mLockLJustActivated = 0;
|
mLockLJustActivated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLockLActive = 1;
|
mLockLActive = 1;
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
mCamParam.mManualMode = 0;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
mLockLJustActivated = 0;
|
mLockLJustActivated = 0;
|
||||||
mLockLActive = 0;
|
mLockLActive = 0;
|
||||||
@@ -1178,12 +1177,6 @@ bool dCamera_c::Run() {
|
|||||||
} else {
|
} else {
|
||||||
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
|
sp0F = (this->*engine_tbl[mCamParam.Algorythmn(mCamStyle)])(mCamStyle);
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
if (mCamParam.Algorythmn(mCamStyle) != 1) {
|
|
||||||
mCamParam.mManualMode = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
field_0x170++;
|
field_0x170++;
|
||||||
field_0x160++;
|
field_0x160++;
|
||||||
mCurCamStyleTimer++;
|
mCurCamStyleTimer++;
|
||||||
@@ -3527,6 +3520,12 @@ void dCamera_c::checkGroundInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool dCamera_c::chaseCamera(s32 param_0) {
|
bool dCamera_c::chaseCamera(s32 param_0) {
|
||||||
|
#if TARGET_PC
|
||||||
|
if (freeCamera()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static f32 JumpCushion = 0.9f;
|
static f32 JumpCushion = 0.9f;
|
||||||
f32 charge_latitude = mCamSetup.ChargeLatitude();
|
f32 charge_latitude = mCamSetup.ChargeLatitude();
|
||||||
int charge_timer = mCamSetup.ChargeTimer();
|
int charge_timer = mCamSetup.ChargeTimer();
|
||||||
@@ -4631,10 +4630,6 @@ bool dCamera_c::chaseCamera(s32 param_0) {
|
|||||||
sp110 = mViewCache.mDirection.R();
|
sp110 = mViewCache.mDirection.R();
|
||||||
mViewCache.mDirection.R(mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * chase->field_0x74);
|
mViewCache.mDirection.R(mViewCache.mDirection.R() + (fVar55 - mViewCache.mDirection.R()) * chase->field_0x74);
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
freeCamera();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
|
chase->field_0x64 = mViewCache.mCenter + mViewCache.mDirection.Xyz();
|
||||||
mViewCache.mEye = chase->field_0x64;
|
mViewCache.mEye = chase->field_0x64;
|
||||||
|
|
||||||
@@ -7482,6 +7477,9 @@ bool dCamera_c::freeCamera() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mCamParam.freeXAngle = mViewCache.mDirection.mAzimuth.Degree();
|
||||||
|
mCamParam.freeYAngle = mViewCache.mDirection.mInclination.Degree();
|
||||||
|
|
||||||
cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f};
|
cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f};
|
||||||
f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY);
|
f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY);
|
||||||
|
|
||||||
@@ -7498,14 +7496,29 @@ bool dCamera_c::freeCamera() {
|
|||||||
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
|
mCamParam.freeYAngle += camMovement.y * magnitude * dusk::getSettings().game.freeCameraSensitivity * 4.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCamParam.mManualMode) {
|
if (!mCamParam.mManualMode) {
|
||||||
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, -35.0f, 60.0f);
|
return false;
|
||||||
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
|
|
||||||
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
|
|
||||||
mViewCache.mDirection.mRadius = std::clamp((mCamParam.freeYAngle + 35.0f) * 10.0f, 300.0f, 10000.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mCamParam.mManualMode;
|
f32 minYAngle = -10.0f;
|
||||||
|
f32 maxAngle = 50.0f;
|
||||||
|
|
||||||
|
mCamParam.freeYAngle = std::clamp(mCamParam.freeYAngle, minYAngle, maxAngle);
|
||||||
|
mViewCache.mDirection.mAzimuth = cSAngle(mCamParam.freeXAngle);
|
||||||
|
mViewCache.mDirection.mInclination = cSAngle(mCamParam.freeYAngle);
|
||||||
|
f32 currentLerp = (mCamParam.freeYAngle - minYAngle) / (maxAngle - minYAngle);
|
||||||
|
mViewCache.mDirection.mRadius = std::lerp(200.0f, 1000.0f, currentLerp);
|
||||||
|
|
||||||
|
cXyz finalCenter = mpPlayerActor->current.pos;
|
||||||
|
finalCenter.y += mIsWolf ? 90.0f : 100.0f;
|
||||||
|
mViewCache.mCenter = finalCenter;
|
||||||
|
|
||||||
|
cXyz finalEye = finalCenter + mViewCache.mDirection.Xyz();
|
||||||
|
mViewCache.mEye = finalEye;
|
||||||
|
|
||||||
|
mViewCache.mFovy = 60.0f;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,14 @@ void dEyeHL_mng_c::remove(dEyeHL_c* i_obj) {
|
|||||||
next = m_obj;
|
next = m_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
// Skip the write if the heap owning m_timg was already destroyed
|
||||||
|
if (JKRHeap::findFromRoot(i_obj->m_timg) != nullptr) {
|
||||||
|
i_obj->m_timg->LODBias = i_obj->m_lodBias;
|
||||||
|
}
|
||||||
|
#else
|
||||||
i_obj->m_timg->LODBias = i_obj->m_lodBias;
|
i_obj->m_timg->LODBias = i_obj->m_lodBias;
|
||||||
|
#endif
|
||||||
i_obj->m_timg = NULL;
|
i_obj->m_timg = NULL;
|
||||||
i_obj->m_pre = NULL;
|
i_obj->m_pre = NULL;
|
||||||
i_obj->m_next = NULL;
|
i_obj->m_next = NULL;
|
||||||
|
|||||||
+1
-2
@@ -6,7 +6,6 @@
|
|||||||
#include "d/dolzel.h" // IWYU pragma: keep
|
#include "d/dolzel.h" // IWYU pragma: keep
|
||||||
|
|
||||||
#include "d/d_k_wmark.h"
|
#include "d/d_k_wmark.h"
|
||||||
#include "dusk/memory.h"
|
|
||||||
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
||||||
#include "SSystem/SComponent/c_math.h"
|
#include "SSystem/SComponent/c_math.h"
|
||||||
#include "d/actor/d_a_player.h"
|
#include "d/actor/d_a_player.h"
|
||||||
@@ -34,7 +33,7 @@ int dkWmark_c::create() {
|
|||||||
mColorType = this->parameters;
|
mColorType = this->parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpHeap = mDoExt_createSolidHeapFromGameToCurrent(HEAP_SIZE(0x880, 0x1100), 0x20);
|
mpHeap = mDoExt_createSolidHeapFromGameToCurrent(0x880, 0x20);
|
||||||
if (mpHeap != NULL) {
|
if (mpHeap != NULL) {
|
||||||
JKRHEAP_NAME(mpHeap, "dkWmark_c::mpHeap");
|
JKRHEAP_NAME(mpHeap, "dkWmark_c::mpHeap");
|
||||||
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("Alink", 0x23);
|
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes("Alink", 0x23);
|
||||||
|
|||||||
+1
-2
@@ -1,7 +1,6 @@
|
|||||||
#include "d/dolzel.h" // IWYU pragma: keep
|
#include "d/dolzel.h" // IWYU pragma: keep
|
||||||
|
|
||||||
#include "d/d_kankyo.h"
|
#include "d/d_kankyo.h"
|
||||||
#include "dusk/memory.h"
|
|
||||||
#ifdef __REVOLUTION_SDK__
|
#ifdef __REVOLUTION_SDK__
|
||||||
#include <revolution.h>
|
#include <revolution.h>
|
||||||
#else
|
#else
|
||||||
@@ -1186,7 +1185,7 @@ static void undwater_init() {
|
|||||||
J3DModelData* modelData2 = (J3DModelData*)dComIfG_getObjectRes("Always", 0x1D);
|
J3DModelData* modelData2 = (J3DModelData*)dComIfG_getObjectRes("Always", 0x1D);
|
||||||
JUT_ASSERT(1867, modelData2 != NULL);
|
JUT_ASSERT(1867, modelData2 != NULL);
|
||||||
|
|
||||||
g_env_light.undwater_ef_heap = mDoExt_createSolidHeapFromGameToCurrent(HEAP_SIZE(0x600, 0xC00), 0x20);
|
g_env_light.undwater_ef_heap = mDoExt_createSolidHeapFromGameToCurrent(0x600, 0x20);
|
||||||
JKRHEAP_NAME(g_env_light.undwater_ef_heap, "g_env_light.undwater_ef_heap");
|
JKRHEAP_NAME(g_env_light.undwater_ef_heap, "g_env_light.undwater_ef_heap");
|
||||||
|
|
||||||
if (g_env_light.undwater_ef_heap != NULL) {
|
if (g_env_light.undwater_ef_heap != NULL) {
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include "d/d_msg_object.h"
|
#include "d/d_msg_object.h"
|
||||||
#include "d/d_msg_scrn_explain.h"
|
#include "d/d_msg_scrn_explain.h"
|
||||||
#include "d/d_stage.h"
|
#include "d/d_stage.h"
|
||||||
#include "dusk/memory.h"
|
|
||||||
#include "f_op/f_op_msg_mng.h"
|
#include "f_op/f_op_msg_mng.h"
|
||||||
|
|
||||||
static dMf_HIO_c g_fmHIO;
|
static dMf_HIO_c g_fmHIO;
|
||||||
@@ -190,7 +189,7 @@ dMenu_Fmap_c::dMenu_Fmap_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
|
|||||||
field_0x148[i] = 0.0f;
|
field_0x148[i] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpTalkHeap = JKRCreateExpHeap(HEAP_SIZE(0x32000, 0x40000), mpHeap, false);
|
mpTalkHeap = JKRCreateExpHeap(0x32000, mpHeap, false);
|
||||||
JUT_ASSERT(359, mpTalkHeap != NULL);
|
JUT_ASSERT(359, mpTalkHeap != NULL);
|
||||||
JKRHEAP_NAME(mpTalkHeap, "dMenu_Fmap_c::mpTalkHeap");
|
JKRHEAP_NAME(mpTalkHeap, "dMenu_Fmap_c::mpTalkHeap");
|
||||||
field_0x200 = 0;
|
field_0x200 = 0;
|
||||||
|
|||||||
+9
-13
@@ -24,16 +24,12 @@
|
|||||||
#include "d/actor/d_a_horse.h"
|
#include "d/actor/d_a_horse.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "dusk/memory.h"
|
|
||||||
|
|
||||||
#include "dusk/memory.h"
|
|
||||||
|
|
||||||
int dMeter2_c::_create() {
|
int dMeter2_c::_create() {
|
||||||
stage_stag_info_class* stag_info = dComIfGp_getStageStagInfo();
|
stage_stag_info_class* stag_info = dComIfGp_getStageStagInfo();
|
||||||
if (dStage_stagInfo_GetUpButton(stag_info) == 1) {
|
if (dStage_stagInfo_GetUpButton(stag_info) == 1) {
|
||||||
mpHeap = fopMsgM_createExpHeap(HEAP_SIZE(0x5A400, 0xA0000), NULL);
|
mpHeap = fopMsgM_createExpHeap(0x5A400, NULL);
|
||||||
} else {
|
} else {
|
||||||
mpHeap = fopMsgM_createExpHeap(HEAP_SIZE(0x60800, 0xC1000), NULL);
|
mpHeap = fopMsgM_createExpHeap(0x60800, NULL);
|
||||||
}
|
}
|
||||||
JKRHEAP_NAME(mpHeap, "dMeter2_c");
|
JKRHEAP_NAME(mpHeap, "dMeter2_c");
|
||||||
|
|
||||||
@@ -236,7 +232,7 @@ int dMeter2_c::_create() {
|
|||||||
dMeter2Info_setMeterMapClass(mpMap);
|
dMeter2Info_setMeterMapClass(mpMap);
|
||||||
|
|
||||||
mpHeap->getTotalFreeSize();
|
mpHeap->getTotalFreeSize();
|
||||||
mpSubHeap = fopMsgM_createExpHeap(HEAP_SIZE(0x5000, 0x6500), mpHeap);
|
mpSubHeap = fopMsgM_createExpHeap(0x5000, mpHeap);
|
||||||
JKRHEAP_NAME(mpSubHeap, "dMeter2_c mpSubHeap");
|
JKRHEAP_NAME(mpSubHeap, "dMeter2_c mpSubHeap");
|
||||||
field_0x108 = NULL;
|
field_0x108 = NULL;
|
||||||
mpSubContents = NULL;
|
mpSubContents = NULL;
|
||||||
@@ -316,6 +312,12 @@ int dMeter2_c::_execute() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dMeter2_c::_draw() {
|
int dMeter2_c::_draw() {
|
||||||
|
#if TARGET_PC
|
||||||
|
if (dusk::getSettings().game.disableMainHUD) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mpMap != NULL) {
|
if (mpMap != NULL) {
|
||||||
mpMap->_draw();
|
mpMap->_draw();
|
||||||
}
|
}
|
||||||
@@ -424,12 +426,6 @@ void dMeter2_c::setLifeZero() {
|
|||||||
void dMeter2_c::checkStatus() {
|
void dMeter2_c::checkStatus() {
|
||||||
mStatus = 0;
|
mStatus = 0;
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
if (dusk::getSettings().game.disableMainHUD) {
|
|
||||||
mStatus |= 0xF0000000;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
field_0x12c = field_0x128;
|
field_0x12c = field_0x128;
|
||||||
|
|
||||||
field_0x128 = daPy_py_c::checkNowWolf();
|
field_0x128 = daPy_py_c::checkNowWolf();
|
||||||
|
|||||||
+18
-6
@@ -36,15 +36,27 @@ dRes_info_c::dRes_info_c() {
|
|||||||
|
|
||||||
dRes_info_c::~dRes_info_c() {
|
dRes_info_c::~dRes_info_c() {
|
||||||
if (mDMCommand != NULL) {
|
if (mDMCommand != NULL) {
|
||||||
mDMCommand->destroy();
|
#if TARGET_PC
|
||||||
|
if (JKRHeap::findFromRoot(mDMCommand) != nullptr) {
|
||||||
|
#endif
|
||||||
|
mDMCommand->destroy();
|
||||||
|
#if TARGET_PC
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mDMCommand = NULL;
|
mDMCommand = NULL;
|
||||||
} else if (mArchive != NULL) {
|
} else if (mArchive != NULL) {
|
||||||
deleteArchiveRes();
|
#if TARGET_PC
|
||||||
if (mDataHeap != NULL) {
|
if (JKRHeap::findFromRoot(mArchive) != nullptr) {
|
||||||
mDoExt_destroySolidHeap(mDataHeap);
|
#endif
|
||||||
mDataHeap = NULL;
|
deleteArchiveRes();
|
||||||
mArchive->unmount();
|
if (mDataHeap != NULL) {
|
||||||
|
mDoExt_destroySolidHeap(mDataHeap);
|
||||||
|
mDataHeap = NULL;
|
||||||
|
mArchive->unmount();
|
||||||
|
}
|
||||||
|
#if TARGET_PC
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
mRes = NULL;
|
mRes = NULL;
|
||||||
mArchive = NULL;
|
mArchive = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -10,7 +10,6 @@
|
|||||||
#include "d/d_meter2_info.h"
|
#include "d/d_meter2_info.h"
|
||||||
#include "d/d_s_name.h"
|
#include "d/d_s_name.h"
|
||||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||||
#include "dusk/memory.h"
|
|
||||||
#include "dusk/settings.h"
|
#include "dusk/settings.h"
|
||||||
#include "f_op/f_op_overlap_mng.h"
|
#include "f_op/f_op_overlap_mng.h"
|
||||||
#include "f_op/f_op_scene_mng.h"
|
#include "f_op/f_op_scene_mng.h"
|
||||||
@@ -77,7 +76,7 @@ static s32 resLoad(request_of_phase_process_class* i_phase, char* i_resName) {
|
|||||||
s32 dScnName_c::create() {
|
s32 dScnName_c::create() {
|
||||||
int phase_state = resLoad(&phase, "fileSel");
|
int phase_state = resLoad(&phase, "fileSel");
|
||||||
if (phase_state == cPhs_COMPLEATE_e) {
|
if (phase_state == cPhs_COMPLEATE_e) {
|
||||||
mHeap = JKRCreateExpHeap(HEAP_SIZE(0x180000, 0x1C0000), mDoExt_getGameHeap(), false);
|
mHeap = JKRCreateExpHeap(0x180000, mDoExt_getGameHeap(), false);
|
||||||
JUT_ASSERT(289, mHeap != NULL);
|
JUT_ASSERT(289, mHeap != NULL);
|
||||||
JKRHEAP_NAME(mHeap, "File select");
|
JKRHEAP_NAME(mHeap, "File select");
|
||||||
|
|
||||||
|
|||||||
+2
-6
@@ -39,10 +39,6 @@
|
|||||||
#include "JSystem/JKernel/JKRAram.h"
|
#include "JSystem/JKernel/JKRAram.h"
|
||||||
#include "JSystem/JKernel/JKRAramArchive.h"
|
#include "JSystem/JKernel/JKRAramArchive.h"
|
||||||
|
|
||||||
#if TARGET_PC
|
|
||||||
#include "dusk/memory.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
#include "d/d_s_menu.h"
|
#include "d/d_s_menu.h"
|
||||||
#include "d/d_debug_pad.h"
|
#include "d/d_debug_pad.h"
|
||||||
@@ -1424,7 +1420,7 @@ static int phase_4(dScnPly_c* i_this) {
|
|||||||
dComIfGd_setViewport(NULL);
|
dComIfGd_setViewport(NULL);
|
||||||
dComIfGd_setView(NULL);
|
dComIfGd_setView(NULL);
|
||||||
|
|
||||||
JKRExpHeap* heap = fopMsgM_createExpHeap(HEAP_SIZE(0xBB800, 0x177000), NULL);
|
JKRExpHeap* heap = fopMsgM_createExpHeap(0xBB800, NULL);
|
||||||
#if TARGET_PC
|
#if TARGET_PC
|
||||||
heap->setName("Scene2DHeap");
|
heap->setName("Scene2DHeap");
|
||||||
#endif
|
#endif
|
||||||
@@ -1432,7 +1428,7 @@ static int phase_4(dScnPly_c* i_this) {
|
|||||||
JUT_ASSERT(2704, heap != NULL);
|
JUT_ASSERT(2704, heap != NULL);
|
||||||
dComIfGp_setExpHeap2D(heap);
|
dComIfGp_setExpHeap2D(heap);
|
||||||
|
|
||||||
JKRExpHeap* heap2 = fopMsgM_createExpHeap(HEAP_SIZE(0xA800, 0x15000), NULL);
|
JKRExpHeap* heap2 = fopMsgM_createExpHeap(0xA800, NULL);
|
||||||
#if TARGET_PC
|
#if TARGET_PC
|
||||||
heap2->setName("SceneMsgHeap");
|
heap2->setName("SceneMsgHeap");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
#include "ImGuiMenuTools.hpp"
|
||||||
|
#include "d/actor/d_a_alink.h"
|
||||||
|
#include "d/d_com_inf_game.h"
|
||||||
|
#include "f_op/f_op_actor_mng.h"
|
||||||
|
#include "SSystem/SComponent/c_sxyz.h"
|
||||||
|
#include "SSystem/SComponent/c_xyz.h"
|
||||||
|
|
||||||
|
namespace dusk {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ActorSpawnerState {
|
||||||
|
int actorId = 0;
|
||||||
|
int params = -1;
|
||||||
|
int argument = -1;
|
||||||
|
int angleX = 0;
|
||||||
|
int angleY = 0;
|
||||||
|
int angleZ = 0;
|
||||||
|
float scaleX = 1.0f;
|
||||||
|
float scaleY = 1.0f;
|
||||||
|
float scaleZ = 1.0f;
|
||||||
|
bool usePlayerRoom = true;
|
||||||
|
int manualRoom = 0;
|
||||||
|
int spawnCount = 1;
|
||||||
|
bool hasResult = false;
|
||||||
|
unsigned int lastResult = 0;
|
||||||
|
int lastAttempted = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ActorSpawnerState s_state;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void ImGuiMenuTools::ShowActorSpawner() {
|
||||||
|
if (!m_showActorSpawner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ImGui::Begin("Actor Spawner", &m_showActorSpawner)) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
daAlink_c* player = (daAlink_c*)dComIfGp_getPlayer(0);
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Actor");
|
||||||
|
ImGui::InputInt("Actor ID", &s_state.actorId);
|
||||||
|
ImGui::InputInt("Params (hex)", &s_state.params, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
|
ImGui::InputInt("Argument", &s_state.argument);
|
||||||
|
s_state.argument = (s_state.argument < -128) ? -128 : (s_state.argument > 127) ? 127 : s_state.argument;
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Angle");
|
||||||
|
ImGui::InputInt("Angle X", &s_state.angleX);
|
||||||
|
ImGui::InputInt("Angle Y", &s_state.angleY);
|
||||||
|
ImGui::InputInt("Angle Z", &s_state.angleZ);
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Scale");
|
||||||
|
ImGui::InputFloat("Scale X", &s_state.scaleX, 0.1f, 1.0f);
|
||||||
|
ImGui::InputFloat("Scale Y", &s_state.scaleY, 0.1f, 1.0f);
|
||||||
|
ImGui::InputFloat("Scale Z", &s_state.scaleZ, 0.1f, 1.0f);
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Spawn");
|
||||||
|
ImGui::InputInt("Count", &s_state.spawnCount);
|
||||||
|
if (s_state.spawnCount < 1) {
|
||||||
|
s_state.spawnCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Position");
|
||||||
|
ImGui::Checkbox("Use player room", &s_state.usePlayerRoom);
|
||||||
|
if (!s_state.usePlayerRoom) {
|
||||||
|
ImGui::InputInt("Room No", &s_state.manualRoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player != nullptr) {
|
||||||
|
ImGui::Text("Spawn pos: %.2f, %.2f, %.2f",
|
||||||
|
player->current.pos.x, player->current.pos.y, player->current.pos.z);
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled("Player not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
bool canSpawn = player != nullptr;
|
||||||
|
if (!canSpawn) {
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Spawn", ImVec2(-1, 0))) {
|
||||||
|
cXyz pos = player->current.pos;
|
||||||
|
csXyz angle;
|
||||||
|
angle.set((s16)s_state.angleX, (s16)s_state.angleY, (s16)s_state.angleZ);
|
||||||
|
cXyz scale(s_state.scaleX, s_state.scaleY, s_state.scaleZ);
|
||||||
|
int roomNo = s_state.usePlayerRoom ? player->current.roomNo : s_state.manualRoom;
|
||||||
|
|
||||||
|
layer_class* savedLayer = fpcLy_CurrentLayer();
|
||||||
|
base_process_class* playScene = fpcM_SearchByName(fpcNm_PLAY_SCENE_e);
|
||||||
|
if (playScene != nullptr) {
|
||||||
|
fpcLy_SetCurrentLayer(&((process_node_class*)playScene)->layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
s_state.lastResult = 0;
|
||||||
|
s_state.lastAttempted = s_state.spawnCount;
|
||||||
|
for (int i = 0; i < s_state.spawnCount; ++i) {
|
||||||
|
unsigned int result = fopAcM_create(
|
||||||
|
(s16)s_state.actorId,
|
||||||
|
(u32)s_state.params,
|
||||||
|
&pos,
|
||||||
|
roomNo,
|
||||||
|
&angle,
|
||||||
|
&scale,
|
||||||
|
(s8)s_state.argument
|
||||||
|
);
|
||||||
|
if (result != 0) {
|
||||||
|
s_state.lastResult = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_state.hasResult = true;
|
||||||
|
|
||||||
|
fpcLy_SetCurrentLayer(savedLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canSpawn) {
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_state.hasResult) {
|
||||||
|
if (s_state.lastResult != 0) {
|
||||||
|
if (s_state.lastAttempted == 1) {
|
||||||
|
ImGui::Text("Spawned: proc ID %u", s_state.lastResult);
|
||||||
|
} else {
|
||||||
|
ImGui::Text("Spawned %d (last proc ID %u)", s_state.lastAttempted, s_state.lastResult);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::TextColored(ImVec4(1, 0.4f, 0.4f, 1), "Spawn failed (returned 0)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dusk
|
||||||
@@ -56,21 +56,6 @@ ImGuiWindow* FindDragScrollWindow(ImGuiWindow* window) {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FocusLastMenuBarItem() {
|
|
||||||
ImGuiContext& g = *ImGui::GetCurrentContext();
|
|
||||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
|
||||||
const ImGuiID itemId = g.LastItemData.ID;
|
|
||||||
if (window == nullptr || itemId == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::FocusWindow(window);
|
|
||||||
ImGui::SetNavID(itemId, ImGuiNavLayer_Menu, g.CurrentFocusScopeId,
|
|
||||||
ImGui::WindowRectAbsToRel(window, g.LastItemData.NavRect));
|
|
||||||
ImGui::SetNavCursorVisibleAfterMove();
|
|
||||||
g.NavHighlightItemUnderNav = true;
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace dusk {
|
namespace dusk {
|
||||||
@@ -344,17 +329,7 @@ namespace dusk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_isHidden = !getSettings().backend.duskMenuOpen;
|
m_isHidden = !getSettings().backend.duskMenuOpen;
|
||||||
if (dusk::IsGameLaunched) {
|
bool showMenu = !dusk::IsGameLaunched || !CheckMenuViewToggle(ImGuiKey_F1, m_isHidden);
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_F1)) {
|
|
||||||
m_isHidden = !m_isHidden;
|
|
||||||
}
|
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_GamepadBack)) {
|
|
||||||
m_isHidden = !m_isHidden;
|
|
||||||
m_focusMenuBar = !m_isHidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool showMenu = !dusk::IsGameLaunched || !m_isHidden;
|
|
||||||
if (dusk::IsGameLaunched) {
|
if (dusk::IsGameLaunched) {
|
||||||
const bool menuOpen = !m_isHidden;
|
const bool menuOpen = !m_isHidden;
|
||||||
if (getSettings().backend.duskMenuOpen != menuOpen) {
|
if (getSettings().backend.duskMenuOpen != menuOpen) {
|
||||||
@@ -368,10 +343,6 @@ namespace dusk {
|
|||||||
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
if (showMenu && ImGui::BeginMainMenuBar()) {
|
if (showMenu && ImGui::BeginMainMenuBar()) {
|
||||||
m_menuGame.draw();
|
m_menuGame.draw();
|
||||||
if (m_focusMenuBar) {
|
|
||||||
FocusLastMenuBarItem();
|
|
||||||
m_focusMenuBar = false;
|
|
||||||
}
|
|
||||||
m_menuTools.draw();
|
m_menuTools.draw();
|
||||||
|
|
||||||
const auto fpsLabel =
|
const auto fpsLabel =
|
||||||
@@ -396,7 +367,7 @@ namespace dusk {
|
|||||||
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
|
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
|
||||||
m_toasts.emplace_back(ImGui::GetIO().MouseSource == ImGuiMouseSource_TouchScreen ?
|
m_toasts.emplace_back(ImGui::GetIO().MouseSource == ImGuiMouseSource_TouchScreen ?
|
||||||
"Tap to toggle menu"s :
|
"Tap to toggle menu"s :
|
||||||
"Press F1 or Minus/Back to toggle menu"s,
|
"Press F1 to toggle menu"s,
|
||||||
2.5f);
|
2.5f);
|
||||||
m_isLaunchInitialized = true;
|
m_isLaunchInitialized = true;
|
||||||
if (getSettings().game.liveSplitEnabled) {
|
if (getSettings().game.liveSplitEnabled) {
|
||||||
@@ -430,6 +401,7 @@ namespace dusk {
|
|||||||
m_menuTools.ShowAudioDebug();
|
m_menuTools.ShowAudioDebug();
|
||||||
m_menuTools.ShowSaveEditor();
|
m_menuTools.ShowSaveEditor();
|
||||||
m_menuTools.ShowStateShare();
|
m_menuTools.ShowStateShare();
|
||||||
|
m_menuTools.ShowActorSpawner();
|
||||||
}
|
}
|
||||||
m_menuTools.ShowAchievements();
|
m_menuTools.ShowAchievements();
|
||||||
DuskDebugPad(); // temporary, remove later
|
DuskDebugPad(); // temporary, remove later
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ private:
|
|||||||
float mouseHideTimer = 0.0f;
|
float mouseHideTimer = 0.0f;
|
||||||
|
|
||||||
bool m_isHidden = true;
|
bool m_isHidden = true;
|
||||||
bool m_focusMenuBar = false;
|
|
||||||
bool m_isLaunchInitialized = false;
|
bool m_isLaunchInitialized = false;
|
||||||
bool m_touchTapActive = false;
|
bool m_touchTapActive = false;
|
||||||
bool m_touchTapMoved = false;
|
bool m_touchTapMoved = false;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ static void ApplyPresetHD() {
|
|||||||
s.game.biggerWallets.setValue(true);
|
s.game.biggerWallets.setValue(true);
|
||||||
s.game.invertCameraXAxis.setValue(true);
|
s.game.invertCameraXAxis.setValue(true);
|
||||||
s.game.freeCamera.setValue(true);
|
s.game.freeCamera.setValue(true);
|
||||||
|
s.game.no2ndFishForCat.setValue(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ApplyPresetDusk() {
|
static void ApplyPresetDusk() {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "JSystem/JFramework/JFWSystem.h"
|
#include "JSystem/JFramework/JFWSystem.h"
|
||||||
#include "JSystem/JKernel/JKRExpHeap.h"
|
#include "JSystem/JKernel/JKRExpHeap.h"
|
||||||
#include "JSystem/JKernel/JKRHeap.h"
|
#include "JSystem/JKernel/JKRHeap.h"
|
||||||
|
#include "JSystem/JKernel/JKRSolidHeap.h"
|
||||||
#include "absl/container/flat_hash_map.h"
|
#include "absl/container/flat_hash_map.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
|
||||||
@@ -178,11 +179,11 @@ namespace dusk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShowHeapDetailed(JKRHeap* heap, OpenHeapData& data, bool& open) {
|
void ShowHeapDetailed(JKRHeap* heap, OpenHeapData& data, bool& open) {
|
||||||
|
const char* heapName = data.Safe ? heap->getName() : "INVALID";
|
||||||
char title[128];
|
char title[128];
|
||||||
const char* name = data.Safe ? heap->getName() : "INVALID";
|
snprintf(title, sizeof(title), "Heap %s##%p", heapName, static_cast<const void*>(heap));
|
||||||
snprintf(title, sizeof(title), "Heap %s##%p", heap->getName(), static_cast<const void*>(heap));
|
|
||||||
|
|
||||||
if (!ImGui::Begin(name, &open)) {
|
if (!ImGui::Begin(title, &open)) {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -200,6 +201,30 @@ namespace dusk {
|
|||||||
const auto freeSize = BytesToString(heap->getFreeSize());
|
const auto freeSize = BytesToString(heap->getFreeSize());
|
||||||
ImGui::Text("Size: %08X (%s), free: %08X (%s)", heap->getSize(), size.c_str(), heap->getFreeSize(), freeSize.c_str());
|
ImGui::Text("Size: %08X (%s), free: %08X (%s)", heap->getSize(), size.c_str(), heap->getFreeSize(), freeSize.c_str());
|
||||||
|
|
||||||
|
{
|
||||||
|
void* vmemBase = nullptr;
|
||||||
|
size_t vmemCapacity = 0;
|
||||||
|
size_t vmemCommitted = 0;
|
||||||
|
if (heap->getHeapType() == 'EXPH') {
|
||||||
|
auto* h = static_cast<JKRExpHeap*>(heap);
|
||||||
|
vmemBase = h->mVmemBase; vmemCapacity = h->mVmemCapacity; vmemCommitted = h->mVmemCommitted;
|
||||||
|
} else if (heap->getHeapType() == 'SLID') {
|
||||||
|
auto* h = static_cast<JKRSolidHeap*>(heap);
|
||||||
|
vmemBase = h->mVmemBase; vmemCapacity = h->mVmemCapacity; vmemCommitted = h->mVmemCommitted;
|
||||||
|
}
|
||||||
|
if (vmemBase) {
|
||||||
|
ImGui::SeparatorText("Virtual Memory");
|
||||||
|
ImGui::Text("Base: %p", vmemBase);
|
||||||
|
const auto committedStr = BytesToString(vmemCommitted);
|
||||||
|
const auto capacityStr = BytesToString(vmemCapacity);
|
||||||
|
ImGui::Text("Committed: %s / %s reserved", committedStr.c_str(), capacityStr.c_str());
|
||||||
|
float pct = vmemCapacity > 0 ? (float)vmemCommitted / (float)vmemCapacity : 0.0f;
|
||||||
|
char overlayBuf[32];
|
||||||
|
snprintf(overlayBuf, sizeof(overlayBuf), "%.1f%%", pct * 100.0f);
|
||||||
|
ImGui::ProgressBar(pct, ImVec2(-1.0f, 0.0f), overlayBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::Button("Check")) {
|
if (ImGui::Button("Check")) {
|
||||||
data.HeapCheckFailed = !heap->check();
|
data.HeapCheckFailed = !heap->check();
|
||||||
data.HeapCheckRan = true;
|
data.HeapCheckRan = true;
|
||||||
|
|||||||
@@ -23,15 +23,6 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int kInternalResolutionScaleMax = 12;
|
constexpr int kInternalResolutionScaleMax = 12;
|
||||||
|
|
||||||
bool is_controller_neutral(int port) {
|
|
||||||
if (port < 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PADGetNativeButtonPressed(port) == -1 &&
|
|
||||||
PADGetNativeAxisPulled(port).nativeAxis == -1;
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace aurora::gx {
|
namespace aurora::gx {
|
||||||
@@ -205,7 +196,7 @@ namespace dusk {
|
|||||||
ImGui::SetTooltip("Restores patched glitches from Wii USA 1.0,\n"
|
ImGui::SetTooltip("Restores patched glitches from Wii USA 1.0,\n"
|
||||||
"the first released version.");
|
"the first released version.");
|
||||||
}
|
}
|
||||||
|
|
||||||
config::ImGuiCheckbox("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation);
|
config::ImGuiCheckbox("Enable Rotating Link Doll", getSettings().game.enableLinkDollRotation);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Enables rotating Link in the collection menu with the C-Stick");
|
ImGui::SetTooltip("Enables rotating Link in the collection menu with the C-Stick");
|
||||||
@@ -276,6 +267,11 @@ namespace dusk {
|
|||||||
ImGui::SetTooltip("Link won't recoil when his sword hits walls.");
|
ImGui::SetTooltip("Link won't recoil when his sword hits walls.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config::ImGuiCheckbox("No 2nd Fish for Cat", getSettings().game.no2ndFishForCat);
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::SetTooltip("Only need to fish once for Sera's cat to return.");
|
||||||
|
}
|
||||||
|
|
||||||
config::ImGuiCheckbox("Skip TV Settings Screen", getSettings().game.hideTvSettingsScreen);
|
config::ImGuiCheckbox("Skip TV Settings Screen", getSettings().game.hideTvSettingsScreen);
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::SetTooltip("Skip the TV calibration screen shown when loading a save.");
|
ImGui::SetTooltip("Skip the TV calibration screen shown when loading a save.");
|
||||||
@@ -651,90 +647,39 @@ namespace dusk {
|
|||||||
|
|
||||||
void ImGuiMenuGame::windowControllerConfig() {
|
void ImGuiMenuGame::windowControllerConfig() {
|
||||||
if (!m_showControllerConfig) {
|
if (!m_showControllerConfig) {
|
||||||
if (m_controllerConfig.m_isReading ||
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease)
|
|
||||||
{
|
|
||||||
m_controllerConfig.m_isReading = false;
|
|
||||||
m_controllerConfig.m_pendingButtonMapping = nullptr;
|
|
||||||
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
|
||||||
m_controllerConfig.m_pendingPort = -1;
|
|
||||||
m_controllerConfig.m_waitForInputRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = -1;
|
|
||||||
PADBlockInput(false);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool suppressRemapActivationThisFrame = m_controllerConfig.m_suppressRemapActivationUntilRelease;
|
|
||||||
if (m_controllerConfig.m_suppressRemapActivationUntilRelease &&
|
|
||||||
is_controller_neutral(m_controllerConfig.m_suppressRemapActivationPort))
|
|
||||||
{
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = -1;
|
|
||||||
PADBlockInput(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_controllerConfig.m_pendingButtonMapping != nullptr ||
|
|
||||||
m_controllerConfig.m_pendingAxisMapping != nullptr) &&
|
|
||||||
m_controllerConfig.m_waitForInputRelease)
|
|
||||||
{
|
|
||||||
m_controllerConfig.m_waitForInputRelease =
|
|
||||||
!is_controller_neutral(m_controllerConfig.m_pendingPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if pending for a button mapping, check to set new input
|
// if pending for a button mapping, check to set new input
|
||||||
if (m_controllerConfig.m_pendingButtonMapping != nullptr &&
|
if (m_controllerConfig.m_pendingButtonMapping != nullptr) {
|
||||||
!m_controllerConfig.m_waitForInputRelease)
|
|
||||||
{
|
|
||||||
s32 nativeButton = PADGetNativeButtonPressed(m_controllerConfig.m_pendingPort);
|
s32 nativeButton = PADGetNativeButtonPressed(m_controllerConfig.m_pendingPort);
|
||||||
if (nativeButton != -1) {
|
if (nativeButton != -1) {
|
||||||
const int suppressPort = m_controllerConfig.m_pendingPort;
|
|
||||||
m_controllerConfig.m_pendingButtonMapping->nativeButton = nativeButton;
|
m_controllerConfig.m_pendingButtonMapping->nativeButton = nativeButton;
|
||||||
m_controllerConfig.m_pendingButtonMapping = nullptr;
|
m_controllerConfig.m_pendingButtonMapping = nullptr;
|
||||||
m_controllerConfig.m_pendingPort = -1;
|
m_controllerConfig.m_pendingPort = -1;
|
||||||
m_controllerConfig.m_isReading = false;
|
PADBlockInput(false);
|
||||||
m_controllerConfig.m_waitForInputRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = true;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = suppressPort;
|
|
||||||
suppressRemapActivationThisFrame = true;
|
|
||||||
PADBlockInput(true);
|
|
||||||
PADSerializeMappings();
|
PADSerializeMappings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if pending for an axis mapping, check to set new input
|
// if pending for an axis mapping, check to set new input
|
||||||
if (m_controllerConfig.m_pendingAxisMapping != nullptr &&
|
if (m_controllerConfig.m_pendingAxisMapping != nullptr) {
|
||||||
!m_controllerConfig.m_waitForInputRelease)
|
|
||||||
{
|
|
||||||
auto nativeAxis = PADGetNativeAxisPulled(m_controllerConfig.m_pendingPort);
|
auto nativeAxis = PADGetNativeAxisPulled(m_controllerConfig.m_pendingPort);
|
||||||
if (nativeAxis.nativeAxis != -1) {
|
if (nativeAxis.nativeAxis != -1) {
|
||||||
const int suppressPort = m_controllerConfig.m_pendingPort;
|
|
||||||
m_controllerConfig.m_pendingAxisMapping->nativeAxis = nativeAxis;
|
m_controllerConfig.m_pendingAxisMapping->nativeAxis = nativeAxis;
|
||||||
m_controllerConfig.m_pendingAxisMapping->nativeButton = -1;
|
m_controllerConfig.m_pendingAxisMapping->nativeButton = -1;
|
||||||
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
||||||
m_controllerConfig.m_pendingPort = -1;
|
m_controllerConfig.m_pendingPort = -1;
|
||||||
m_controllerConfig.m_isReading = false;
|
PADBlockInput(false);
|
||||||
m_controllerConfig.m_waitForInputRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = true;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = suppressPort;
|
|
||||||
suppressRemapActivationThisFrame = true;
|
|
||||||
PADBlockInput(true);
|
|
||||||
PADSerializeMappings();
|
PADSerializeMappings();
|
||||||
} else {
|
} else {
|
||||||
auto nativeButton = PADGetNativeButtonPressed(m_controllerConfig.m_pendingPort);
|
auto nativeButton = PADGetNativeButtonPressed(m_controllerConfig.m_pendingPort);
|
||||||
if (nativeButton != -1) {
|
if (nativeButton != -1) {
|
||||||
const int suppressPort = m_controllerConfig.m_pendingPort;
|
|
||||||
m_controllerConfig.m_pendingAxisMapping->nativeAxis = {-1, AXIS_SIGN_POSITIVE};
|
m_controllerConfig.m_pendingAxisMapping->nativeAxis = {-1, AXIS_SIGN_POSITIVE};
|
||||||
m_controllerConfig.m_pendingAxisMapping->nativeButton = nativeButton;
|
m_controllerConfig.m_pendingAxisMapping->nativeButton = nativeButton;
|
||||||
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
||||||
m_controllerConfig.m_pendingPort = -1;
|
m_controllerConfig.m_pendingPort = -1;
|
||||||
m_controllerConfig.m_isReading = false;
|
PADBlockInput(false);
|
||||||
m_controllerConfig.m_waitForInputRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = true;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = suppressPort;
|
|
||||||
suppressRemapActivationThisFrame = true;
|
|
||||||
PADBlockInput(true);
|
|
||||||
PADSerializeMappings();
|
PADSerializeMappings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -770,10 +715,6 @@ namespace dusk {
|
|||||||
m_controllerConfig.m_pendingButtonMapping = nullptr;
|
m_controllerConfig.m_pendingButtonMapping = nullptr;
|
||||||
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
m_controllerConfig.m_pendingAxisMapping = nullptr;
|
||||||
m_controllerConfig.m_pendingPort = -1;
|
m_controllerConfig.m_pendingPort = -1;
|
||||||
m_controllerConfig.m_waitForInputRelease = false;
|
|
||||||
m_controllerConfig.m_isReading = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationUntilRelease = false;
|
|
||||||
m_controllerConfig.m_suppressRemapActivationPort = -1;
|
|
||||||
PADBlockInput(false);
|
PADBlockInput(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,7 +791,7 @@ namespace dusk {
|
|||||||
|
|
||||||
std::string dispName;
|
std::string dispName;
|
||||||
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingButtonMapping == &btnMappingList[i]) {
|
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingButtonMapping == &btnMappingList[i]) {
|
||||||
dispName = fmt::format("{}##{}", m_controllerConfig.m_waitForInputRelease ? "Release..." : "Press a Key...", btnName);
|
dispName = fmt::format("Press a Key...##{}", btnName);
|
||||||
} else {
|
} else {
|
||||||
const char* nativeName = GetNameForGamepadButton(gamepad, btnMappingList[i].nativeButton);
|
const char* nativeName = GetNameForGamepadButton(gamepad, btnMappingList[i].nativeButton);
|
||||||
if (nativeName == nullptr) {
|
if (nativeName == nullptr) {
|
||||||
@@ -861,11 +802,10 @@ namespace dusk {
|
|||||||
bool pressed = ImGui::Button(dispName.c_str(),
|
bool pressed = ImGui::Button(dispName.c_str(),
|
||||||
btnSize);
|
btnSize);
|
||||||
|
|
||||||
if (pressed && !m_controllerConfig.m_isReading && !suppressRemapActivationThisFrame) {
|
if (pressed) {
|
||||||
m_controllerConfig.m_isReading = true;
|
m_controllerConfig.m_isReading = true;
|
||||||
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
||||||
m_controllerConfig.m_pendingButtonMapping = &btnMappingList[i];
|
m_controllerConfig.m_pendingButtonMapping = &btnMappingList[i];
|
||||||
m_controllerConfig.m_waitForInputRelease = true;
|
|
||||||
PADBlockInput(true);
|
PADBlockInput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,18 +835,17 @@ namespace dusk {
|
|||||||
|
|
||||||
std::string dispName;
|
std::string dispName;
|
||||||
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[trigger]) {
|
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[trigger]) {
|
||||||
dispName = fmt::format("{}##{}", m_controllerConfig.m_waitForInputRelease ? "Release..." : "Press a Key...", axisName);
|
dispName = fmt::format("Press a Key...##{}", axisName);
|
||||||
} else {
|
} else {
|
||||||
dispName = fmt::format("{0}##-{1}", PADGetNativeAxisName(axisMappingList[trigger].nativeAxis), trigger);
|
dispName = fmt::format("{0}##-{1}", PADGetNativeAxisName(axisMappingList[trigger].nativeAxis), trigger);
|
||||||
}
|
}
|
||||||
bool pressed = ImGui::Button(dispName.c_str(),
|
bool pressed = ImGui::Button(dispName.c_str(),
|
||||||
btnSize);
|
btnSize);
|
||||||
|
|
||||||
if (pressed && !m_controllerConfig.m_isReading && !suppressRemapActivationThisFrame) {
|
if (pressed) {
|
||||||
m_controllerConfig.m_isReading = true;
|
m_controllerConfig.m_isReading = true;
|
||||||
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
||||||
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[trigger];
|
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[trigger];
|
||||||
m_controllerConfig.m_waitForInputRelease = true;
|
|
||||||
PADBlockInput(true);
|
PADBlockInput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -963,7 +902,7 @@ namespace dusk {
|
|||||||
|
|
||||||
std::string dispName;
|
std::string dispName;
|
||||||
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[axis]) {
|
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[axis]) {
|
||||||
dispName = fmt::format("{}##{}", m_controllerConfig.m_waitForInputRelease ? "Release..." : "Press a Key...", label);
|
dispName = fmt::format("Press a Key...##{}", label);
|
||||||
} else {
|
} else {
|
||||||
if (axisMappingList[axis].nativeAxis.nativeAxis != -1) {
|
if (axisMappingList[axis].nativeAxis.nativeAxis != -1) {
|
||||||
const char* signStr;
|
const char* signStr;
|
||||||
@@ -982,11 +921,10 @@ namespace dusk {
|
|||||||
}
|
}
|
||||||
bool pressed = ImGui::Button(dispName.c_str(), btnSize);
|
bool pressed = ImGui::Button(dispName.c_str(), btnSize);
|
||||||
|
|
||||||
if (pressed && !m_controllerConfig.m_isReading && !suppressRemapActivationThisFrame) {
|
if (pressed) {
|
||||||
m_controllerConfig.m_isReading = true;
|
m_controllerConfig.m_isReading = true;
|
||||||
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
||||||
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[axis];
|
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[axis];
|
||||||
m_controllerConfig.m_waitForInputRelease = true;
|
|
||||||
PADBlockInput(true);
|
PADBlockInput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1027,7 +965,7 @@ namespace dusk {
|
|||||||
|
|
||||||
std::string dispName;
|
std::string dispName;
|
||||||
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[axis]) {
|
if (m_controllerConfig.m_isReading && m_controllerConfig.m_pendingAxisMapping == &axisMappingList[axis]) {
|
||||||
dispName = fmt::format("{}##sub{}", m_controllerConfig.m_waitForInputRelease ? "Release..." : "Press a Key...", label);
|
dispName = fmt::format("Press a Key...##sub{}", label);
|
||||||
} else {
|
} else {
|
||||||
if (axisMappingList[axis].nativeAxis.nativeAxis != -1) {
|
if (axisMappingList[axis].nativeAxis.nativeAxis != -1) {
|
||||||
const char* signStr;
|
const char* signStr;
|
||||||
@@ -1046,11 +984,10 @@ namespace dusk {
|
|||||||
}
|
}
|
||||||
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), btnSize);
|
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), btnSize);
|
||||||
|
|
||||||
if (pressed && !m_controllerConfig.m_isReading && !suppressRemapActivationThisFrame) {
|
if (pressed) {
|
||||||
m_controllerConfig.m_isReading = true;
|
m_controllerConfig.m_isReading = true;
|
||||||
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
m_controllerConfig.m_pendingPort = m_controllerConfig.m_selectedPort;
|
||||||
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[axis];
|
m_controllerConfig.m_pendingAxisMapping = &axisMappingList[axis];
|
||||||
m_controllerConfig.m_waitForInputRelease = true;
|
|
||||||
PADBlockInput(true);
|
PADBlockInput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1081,7 +1018,7 @@ namespace dusk {
|
|||||||
PADSerializeMappings();
|
PADSerializeMappings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PADSupportsRumbleIntensity(m_controllerConfig.m_selectedPort)) {
|
if (PADSupportsRumbleIntensity(m_controllerConfig.m_selectedPort)) {
|
||||||
ImGuiBeginGroupPanel("Rumble Intensity", ImVec2(150 * scale, -1));
|
ImGuiBeginGroupPanel("Rumble Intensity", ImVec2(150 * scale, -1));
|
||||||
u16 low;
|
u16 low;
|
||||||
@@ -1100,7 +1037,7 @@ namespace dusk {
|
|||||||
if (ImGui::Button(fmt::format("{0}...##rumbleTest", m_controllerConfig.m_isRumbling ? "Stop": "Test").c_str(), {-1, 0})) {
|
if (ImGui::Button(fmt::format("{0}...##rumbleTest", m_controllerConfig.m_isRumbling ? "Stop": "Test").c_str(), {-1, 0})) {
|
||||||
PADControlMotor(m_controllerConfig.m_selectedPort, !m_controllerConfig.m_isRumbling ? PAD_MOTOR_RUMBLE : PAD_MOTOR_STOP_HARD);
|
PADControlMotor(m_controllerConfig.m_selectedPort, !m_controllerConfig.m_isRumbling ? PAD_MOTOR_RUMBLE : PAD_MOTOR_STOP_HARD);
|
||||||
m_controllerConfig.m_isRumbling ^= 1;
|
m_controllerConfig.m_isRumbling ^= 1;
|
||||||
}
|
}
|
||||||
ImGuiEndGroupPanel();
|
ImGuiEndGroupPanel();
|
||||||
}
|
}
|
||||||
ImGuiEndGroupPanel();
|
ImGuiEndGroupPanel();
|
||||||
|
|||||||
@@ -68,9 +68,6 @@ namespace dusk {
|
|||||||
PADButtonMapping* m_pendingButtonMapping = nullptr;
|
PADButtonMapping* m_pendingButtonMapping = nullptr;
|
||||||
PADAxisMapping* m_pendingAxisMapping = nullptr;
|
PADAxisMapping* m_pendingAxisMapping = nullptr;
|
||||||
int m_pendingPort = -1;
|
int m_pendingPort = -1;
|
||||||
bool m_waitForInputRelease = false;
|
|
||||||
bool m_suppressRemapActivationUntilRelease = false;
|
|
||||||
int m_suppressRemapActivationPort = -1;
|
|
||||||
bool m_isRumbling = false;
|
bool m_isRumbling = false;
|
||||||
} m_controllerConfig;
|
} m_controllerConfig;
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ namespace dusk {
|
|||||||
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
|
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
|
||||||
ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow);
|
ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow);
|
||||||
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
|
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
|
||||||
|
ImGui::MenuItem("Actor Spawner", nullptr, &m_showActorSpawner);
|
||||||
|
|
||||||
if (!dusk::IsGameLaunched) {
|
if (!dusk::IsGameLaunched) {
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace dusk {
|
|||||||
void ShowStateShare();
|
void ShowStateShare();
|
||||||
void ShowAchievements();
|
void ShowAchievements();
|
||||||
void notifyAchievement(std::string name);
|
void notifyAchievement(std::string name);
|
||||||
|
void ShowActorSpawner();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_showDebugOverlay = false;
|
bool m_showDebugOverlay = false;
|
||||||
@@ -71,6 +72,8 @@ namespace dusk {
|
|||||||
|
|
||||||
bool m_showAchievements = false;
|
bool m_showAchievements = false;
|
||||||
ImGuiAchievements m_achievementsWindow;
|
ImGuiAchievements m_achievementsWindow;
|
||||||
|
|
||||||
|
bool m_showActorSpawner = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ UserSettings g_userSettings = {
|
|||||||
.fastClimbing {"game.fastClimbing", false},
|
.fastClimbing {"game.fastClimbing", false},
|
||||||
.noMissClimbing {"game.noMissClimbing", false},
|
.noMissClimbing {"game.noMissClimbing", false},
|
||||||
.fastTears {"game.fastTears", false},
|
.fastTears {"game.fastTears", false},
|
||||||
|
.no2ndFishForCat {"game.no2ndFishForCat", false},
|
||||||
.instantSaves {"game.instantSaves", false},
|
.instantSaves {"game.instantSaves", false},
|
||||||
.instantText {"game.instantText", false},
|
.instantText {"game.instantText", false},
|
||||||
.sunsSong {"game.sunsSong", false},
|
.sunsSong {"game.sunsSong", false},
|
||||||
@@ -147,6 +148,7 @@ void registerSettings() {
|
|||||||
Register(g_userSettings.game.instantDeath);
|
Register(g_userSettings.game.instantDeath);
|
||||||
Register(g_userSettings.game.fastClimbing);
|
Register(g_userSettings.game.fastClimbing);
|
||||||
Register(g_userSettings.game.fastTears);
|
Register(g_userSettings.game.fastTears);
|
||||||
|
Register(g_userSettings.game.no2ndFishForCat);
|
||||||
Register(g_userSettings.game.instantSaves);
|
Register(g_userSettings.game.instantSaves);
|
||||||
Register(g_userSettings.game.instantText);
|
Register(g_userSettings.game.instantText);
|
||||||
Register(g_userSettings.game.sunsSong);
|
Register(g_userSettings.game.sunsSong);
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#include "dusk/vmem.h"
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifndef MAP_ANONYMOUS
|
||||||
|
#define MAP_ANONYMOUS MAP_ANON
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace dusk {
|
||||||
|
|
||||||
|
size_t vmem_page_size() {
|
||||||
|
#if _WIN32
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
return si.dwPageSize;
|
||||||
|
#else
|
||||||
|
return (size_t)sysconf(_SC_PAGESIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vmem_reserve(size_t size) {
|
||||||
|
#if _WIN32
|
||||||
|
return VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_NOACCESS);
|
||||||
|
#else
|
||||||
|
void* p = mmap(nullptr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
return (p == MAP_FAILED) ? nullptr : p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vmem_commit(void* ptr, size_t size) {
|
||||||
|
#if _WIN32
|
||||||
|
return VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != nullptr;
|
||||||
|
#else
|
||||||
|
return mprotect(ptr, size, PROT_READ | PROT_WRITE) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void vmem_decommit(void* ptr, size_t size) {
|
||||||
|
#if _WIN32
|
||||||
|
VirtualFree(ptr, size, MEM_DECOMMIT);
|
||||||
|
#else
|
||||||
|
mprotect(ptr, size, PROT_NONE);
|
||||||
|
madvise(ptr, size, MADV_DONTNEED);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void vmem_release(void* ptr, size_t size) {
|
||||||
|
#if _WIN32
|
||||||
|
(void)size;
|
||||||
|
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||||
|
#else
|
||||||
|
munmap(ptr, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static void* s_arenaBase = nullptr;
|
||||||
|
static size_t s_arenaTotal = 0;
|
||||||
|
static std::atomic<size_t> s_arenaBump{0};
|
||||||
|
|
||||||
|
struct FreeSlot { void* ptr; size_t size; };
|
||||||
|
static FreeSlot s_free[JKR_VMEM_MAX_FREE_SLOTS];
|
||||||
|
static size_t s_freeCount = 0;
|
||||||
|
static std::mutex s_freeMutex;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void vmem_arena_init() {
|
||||||
|
s_arenaBase = vmem_reserve(JKR_VMEM_ARENA_SIZE);
|
||||||
|
s_arenaTotal = JKR_VMEM_ARENA_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vmem_arena_alloc(size_t size) {
|
||||||
|
const size_t pageSize = vmem_page_size();
|
||||||
|
size = (size + pageSize - 1) & ~(pageSize - 1);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(s_freeMutex);
|
||||||
|
for (size_t i = 0; i < s_freeCount; ++i) {
|
||||||
|
if (s_free[i].size >= size) {
|
||||||
|
void* ptr = s_free[i].ptr;
|
||||||
|
s_free[i] = s_free[--s_freeCount];
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t offset = s_arenaBump.fetch_add(size);
|
||||||
|
if (offset + size > s_arenaTotal) {
|
||||||
|
s_arenaBump.fetch_sub(size);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return static_cast<uint8_t*>(s_arenaBase) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vmem_arena_free(void* ptr, size_t size) {
|
||||||
|
if (!ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const size_t pageSize = vmem_page_size();
|
||||||
|
size = (size + pageSize - 1) & ~(pageSize - 1);
|
||||||
|
|
||||||
|
vmem_decommit(ptr, size);
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(s_freeMutex);
|
||||||
|
if (s_freeCount < JKR_VMEM_MAX_FREE_SLOTS) {
|
||||||
|
s_free[s_freeCount++] = {ptr, size};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dusk
|
||||||
@@ -71,6 +71,7 @@
|
|||||||
#include "dusk/config.hpp"
|
#include "dusk/config.hpp"
|
||||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||||
#include "dusk/settings.h"
|
#include "dusk/settings.h"
|
||||||
|
#include "dusk/vmem.h"
|
||||||
#include "dusk/version.hpp"
|
#include "dusk/version.hpp"
|
||||||
#include "dusk/discord_presence.hpp"
|
#include "dusk/discord_presence.hpp"
|
||||||
#include "tracy/Tracy.hpp"
|
#include "tracy/Tracy.hpp"
|
||||||
@@ -551,12 +552,19 @@ int game_main(int argc, char* argv[]) {
|
|||||||
config.desiredBackend = ResolveDesiredBackend(parsed_arg_options);
|
config.desiredBackend = ResolveDesiredBackend(parsed_arg_options);
|
||||||
config.logCallback = &aurora_log_callback;
|
config.logCallback = &aurora_log_callback;
|
||||||
config.logLevel = startupLogLevel;
|
config.logLevel = startupLogLevel;
|
||||||
config.mem1Size = 256 * 1024 * 1024;
|
// Child heaps use independent vmem reservations on PC
|
||||||
|
config.mem1Size = DUSK_IF_ELSE(16, 256) * 1024 * 1024;
|
||||||
config.mem2Size = 24 * 1024 * 1024;
|
config.mem2Size = 24 * 1024 * 1024;
|
||||||
config.allowJoystickBackgroundEvents = true;
|
config.allowJoystickBackgroundEvents = true;
|
||||||
config.imGuiInitCallback = &aurora_imgui_init_callback;
|
config.imGuiInitCallback = &aurora_imgui_init_callback;
|
||||||
config.allowTextureReplacements = true;
|
config.allowTextureReplacements = true;
|
||||||
config.allowTextureDumps = false;
|
config.allowTextureDumps = false;
|
||||||
|
|
||||||
|
#if TARGET_PC
|
||||||
|
dusk::vmem_arena_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
auroraInfo = aurora_initialize(argc, argv, &config);
|
auroraInfo = aurora_initialize(argc, argv, &config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user