Conversation
Port the 32-bit x86 PC build to 64-bit platforms. The game compiles, links, and boots to the trademark screen on macOS Apple Silicon with GCC 15. Type system: - u32/s32/u64/s64 use stdint.h fixed-width types on PC (always 4/8 bytes) - Compile-time static_assert validation for type sizes Pointer safety (~120 casts across 83 files): - PC port layer: GXTexObj rewritten as proper struct, texture/EFB cache uses uintptr_t, ARAM DMA uses uintptr_t for MRAM addresses - Decomp code: JKRExpHeap, JKRHeap, JKRAram, JKRThread, JKRMemArchive, JKRCompArchive, JKRDvdRipper, and 8 JUtility files wrapped in #ifdef TARGET_PC using uintptr_t (preserves decomp matching in #else) - emu64: segments[], DL_stack[] are uintptr_t; resolved_imgaddr field avoids 32-bit bitfield truncation for texture addresses - jaudio_NES: OFS2RAM/BANK_ENTRY macros, PTconvert relocation, Nas_HeapInit alignment, audio command buffer (Acmd.w1), RSP simulator pointer recovery - Header fixes: ARStartDMA, ARQPostRequest, AIInitDMA declarations match uintptr_t implementations; OSRoundUp32B/OSRoundDown32B use uintptr_t seg2k0 64-bit: - Simple threshold check (addresses > 0x0FFFFFFF are real PC pointers) - Pointer recovery from truncated 32-bit GBI values using image/arena base - Eliminates VirtualQuery dependency on 64-bit Build system: - Removed 32-bit enforcement; added macOS platform support - GCC required on 64-bit (Clang rejects pointer truncation in GBI statics) - macOS: GL_SILENCE_DEPRECATION, forward-compatible GL context, Cocoa/IOKit frameworks, dladdr-based image detection, no elf.h dependency - Clang-incompatible flags guarded; decomp -Wno-return-type for Clang Runtime fixes: - operator new/delete uses malloc/free (prevents macOS framework corruption); operator delete checks arena range for JKR heap pointers - Audio heap doubled (0x70000→0xE0000) for wider 64-bit structs - Arena increased to 48MB on 64-bit; system heap overhead adjusted - malloc.h→stdlib.h on macOS; errno field conflict; bcmp/bcopy builtins; CARD sub-header long/s32 conflicts; _mem.h memcpy builtin conflicts Known limitations: - Static GBI display lists with direct C pointers use 0 placeholder (_GBI_STATIC_PTR), recovered at runtime via seg2k0 pointer recovery - Audio bank struct layout mismatch (PTconvert reads void* from 32-bit ROM fields) causes crash during bank loading after trademark screen - Requires GCC (brew install gcc) on macOS; Clang 64-bit not supported
Fix crashes on macOS ARM64 / Linux x86_64 caused by 64-bit pointer truncation throughout the codebase. The game now boots crash-free through trademark init and into the main game loop. Audio system (system.c): - Define GC-compat structs (smzwavetable_gc, wtstr_gc, perctable_gc, voicetable_gc, percvoicetable_gc) that match the GC binary layout with u32 for pointer fields - Add Nas_BankOfsToAddr_Inner_PC + __WaveTouch_PC to allocate native 64-bit structs from GC ROM data during bank ctrl relocation - Add safety guards: __Link_BankNum NULL check, __Nas_SzCacheCheck_Inner default case, __Load_Bank_BG range check Pointer truncation (22 files): - GRAPH_ALLOC macro: (int) -> (intptr_t) for pointer arithmetic - TwoHeadArena: (u32) -> (uintptr_t) in allocator functions - __osMalloc: (u32) -> (uintptr_t) in macros and pointer math - ARQRequest struct: u32 source/dest -> uintptr_t on 64-bit - ALIGN_NEXT((u32)ptr) -> (uintptr_t) across 12+ game files - m_play.c / famicom_emu.c: THA_alloc u32 -> uintptr_t GBI display list (emu64.c): - Recover full 64-bit pointer via pc_gbi_recover_ptr when setting segment bases in dl_G_MOVEWORD Build config: - Add BUGFIXES define to fix original game buffer overflows that crash on modern platforms with fortified libc
On 64-bit, Gwords.w1 is now uintptr_t (8 bytes) instead of u32,
making sizeof(Gfx) = 16. This allows static display list initializers
to store full 64-bit pointers via _GBI_STATIC_PTR(s) = (uintptr_t)(s)
instead of the 0u placeholder that produced a black screen.
gbi.h:
- Gwords.w1: u32 -> uintptr_t on 64-bit
- _GBI_STATIC_PTR: 0u -> (uintptr_t)(s) on 64-bit
- _GBI_SET_W1 / _GBI_SET_W1_RAW: new macros for runtime w1 writes
- All g* runtime macros updated to use _GBI_SET_W1
emu64.c:
- EMU64_GFX_COMPACT_PTR: builds packed 8-byte {w0,(u32)w1} buffer
for safe casting to union member structs (Gsettile, Gsetcolor, etc.)
whose second u32 field would land in padding with 16-byte Gfx
- All command handlers read pointers from gfx.words.w1 (full width)
instead of union views that truncate to u32
- seg2k0 already returns full 64-bit values directly (> 0xFFFFFFFF)
emu64.hpp: rdpHalf_1 widened to uintptr_t, segchk param widened
Result: ~1300 GBI commands/frame, 70-95 triangles, 60-98 GL draws.
Game renders title screen and character movement is visible.
SDIFileEntry had void* mData at offset 0x10, making sizeof() = 0x18 on 64-bit instead of the RARC binary layout's 0x14. This caused fileEntry++ iteration to misalign, breaking archive file lookups (most resources returned address 0 from JW_GetAramAddress). Fix: replace void* mData with u32 mData_pad on TARGET_PC to keep the binary-compatible 0x14 stride. Store actual mData pointers in a parallel heap-allocated array (mFileEntryDataPtrs) accessed via getFileEntryData()/setFileEntryData() methods. Updated: JKRAramArchive, JKRDvdArchive, JKRMemArchive, JKRCompArchive, JKRArchivePri, JKRArchivePub (all mData accesses). pallet_boy.bin now resolves to valid ARAM address (0x8a4080). Texture/color rendering still WIP — ARAM DMA reads return zeros, suggesting the resource data within the archive wasn't decompressed or the ARAM buffer contents at those offsets are empty.
Updated the DVDFileInfo and DVDCommandBlock structures to ensure correct field offsets on 64-bit systems. This includes replacing hardcoded offsets with offsetof() macros for better maintainability and accuracy. Adjusted memory initialization to use sizeof() for the structures instead of fixed sizes, enhancing compatibility across different architectures. Additionally, added a new fast-forward feature in the main PC application loop and included pixel color diagnostics for debugging purposes.
- game.c: use %p format for crash diagnostic pointer printing - m_card.c: cast pointer arithmetic through uintptr_t instead of u32 - m_mail.c: fix mMl_strlen to use typed pointer instead of u32 cast - m_font_main.c_inc: fix vertex alpha (255), cache char code to avoid re-dereferencing, clean up trailing whitespace - emu64.c: fix G_TEXTURE dirty check to compare against incoming texture command rather than self
Halves the frame pacing target from 16667µs to 8333µs when active, doubling the game loop rate. Audio is unaffected (decoupled thread). Window title shows [2x] indicator when enabled.
…flush - m_font_main.c_inc: Route FONT_DISP callers (NPC names, choices) through poly path for correct matrix-transformed positioning. Route POLY_OPA callers (editor keyboard) through rect path with absolute screen coords, working around a poly rendering issue on the POLY_OPA display list. - emu64.c dirty_check: Flush pending GX batch at the start of dirty_check before any state changes. Fixes texture binding race where a previous batch would be flushed mid-dirty_check with partially-updated state (wrong texture bound at draw time). - emu64.c dirty_check lighting: Use GX_SRC_REG instead of GX_SRC_VTX for channel material source when G_SHADE is off. Matches N64 behavior where vertex colors are ignored when shade is disabled. - emu64.c: Add extern declaration for pc_gx_flush_if_begin_complete.
The original GameCube code stored pointers in u32 fields and used (u32) casts on pointer values. On the 64-bit PC port, this truncates addresses causing silent failures — most visibly, the house door entry during the intro sequence would permanently black-screen because the player's door label (an actor pointer) was truncated and never matched. Changes: - Widen u32 label/pointer fields to uintptr_t in m_player.h (door, demo wait, net catch, snowball, mosquito, force speak labels) - Fix (u32)pointer casts to (uintptr_t) across ~90 source files including all insect actors, fishing actors, furniture, effects, NPCs, and the player state machine - Update function signatures for sAdo_OngenPos, Na_OngenPos, sAdos_KishaStatusLevel, mPlib_Get/Change_item_net_catch_label, and related function pointer typedefs to use uintptr_t - Add GitHub Actions release workflow for macOS, Windows, and Linux builds
Add Arch Linux support
Made-with: Cursor
Static display lists used hardcoded byte offsets (e.g. anime_4_txt + 0x18) to index into Gfx arrays via segment addresses. These offsets assumed sizeof(Gfx) == 8 (32-bit), but on 64-bit platforms sizeof(Gfx) == 16 due to uintptr_t widening of Gwords.w1. This caused the emu64 segment resolver to land in the middle of Gfx entries, producing garbage display list commands. Replace all hardcoded offsets with entry_index * sizeof(Gfx) so they scale correctly on both 32-bit and 64-bit builds.
Resolved merge conflicts in: - pc/src/pc_main.c: Kept uintptr_t types for 64-bit, integrated typing support - src/static/libforest/emu64/emu64_utility.c: Added arena checking and large offset heuristic to 64-bit seg2k0
2539dcc to
a85a704
Compare
|
@birabittoh is this similar to #33? seems to have identical commits, until the last few |
It is! I created this draft because the original author explicitly said he wasn't going to spend any more time on it. I will actually open it once I get the game working on linux i686 and people confirm the macOS versions are still working. |
Resolved pointer truncation issues in ac_house.c and ac_ins_goki.c where 64-bit pointers were being stored in 32-bit integer fields. On PC, aHUS_GET_ANIMAL_P now uses the animal index to retrieve the pointer from Save data instead of relying on the truncated value in arg1. Similarly, aIGK_GET_ITEM_P now retrieves the FG unit from home position.
This commit addresses animation "twitching" and camera positioning bugs specific to 32-bit Linux builds by: 1. Enabling SSE2 floating-point math in the Linux 32-bit toolchain to avoid x87 excess precision inconsistencies. 2. Forcing 8-byte alignment for 64-bit types (s64, u64, f64) on PC targets to ensure consistent structure layouts across platforms. 3. Aligning the 'Mtx' structure and its conversion logic in pc_mtx.c with the GBI definition and ensuring 8-byte alignment.
|
Finally fixed linux i686, now we just need confirmation for macOS. |
|
I was able to get the arm version for macOS to run. I'm unable to get custom textures to work, though. |
Interesting. Your file structure should look like this:
Can you run the game with the --verbose option and see if there are any errors? |
Yep, I got the texture pack installed correctly. I ran with verbose mode and got a handful of errors. I saved the log to a txt file. |
Update codebase to make the game work on many different platforms.
https://nightly.link/birabittoh/ACGC-PC-Port/workflows/build.yaml/master?preview
Tested working platforms as of commit
4d58e47: