Skip to content

Commit c17f874

Browse files
committed
macOS Apple Silicon port + Vulkan/MoltenVK backend opt-in (WIP)
Outer-repo half of the macOS arm64 + Vulkan port. The PsyCross submodule holds the new Vulkan backend itself (separate PR on its own `vulkan-port` branch); this commit tracks that submodule head and provides the build-system, game-side and macOS-portability fixes the backend needs to actually link and run. State of the port: builds clean on macOS arm64 with both renderers; on Apple Silicon the OpenGL path also works but exhibits geometry flicker / dropped primitives because of the GL-on-Metal compatibility layer's relaxed sync, which motivated the Vulkan port. Driver 2 menu / HUD / 3D world geometry render under Vulkan; remaining gaps are blend modes, stencil, scissor, and a few PSX scratch-render paths (GR_StoreFrameBuffer). Build system: - src_rebuild/premake5.lua: --renderer={opengl|vulkan} option, macOS Homebrew prefix detection, Vulkan headers + loader + MoltenVK + shaderc (statically linked for GLSL→SPIR-V at runtime), framework links (Metal / QuartzCore / IOSurface), and exclusion of OpenGL sources when Vulkan is selected. - src_rebuild/premake5_psycross.lua: same wiring on the static-lib side; `removefiles` switches PsyX_render.cpp ↔ PsyX_render_vk.cpp. - src_rebuild/premake_modules/usage/usage.lua: tolerate the modern premake5 `uses` field already existing as a core API (older custom registration would error out on premake5 >= beta8). Game-side fixes (LP64 / arm64): - src_rebuild/Game/driver2.h: `trap()` macro now uses `__builtin_trap()` instead of the x86-only `__asm__("int3")`. - src_rebuild/Game/psyx_compat.h: OTTYPE = OT_TAG also on __aarch64__/__arm64__/_M_ARM64. Without this the OT array allocates 8-byte slots while ClearOTagR/addPrim/DrawOTag treat the array as 12-byte OT_TAG — silent corruption of every OT linked-list pointer. - src_rebuild/Game/dr2locale.{c,h}: malloc.h guard for macOS; GET_GAME_TXT/GET_MISSION_TXT cast pointers via u_intptr first to avoid clang's "cast from pointer to smaller type loses information" error. - src_rebuild/Game/C/civ_ai.c, dr2roads.c, draw.c, event.c, glaunch.c, mission.c, targets.c: same intptr_t-routed casts where the engine packed small integers into pointer-sized fields. - src_rebuild/utils/{fs.{cpp,h}, targa.cpp, audio_source/snd_wav_cache.cpp, video_source/VideoPlayer.cpp}, src_rebuild/tools/font_tool/font_tool_main.cpp: malloc.h guards (macOS uses stdlib.h), `__unix__` guards extended to include `__APPLE__`, GL-only paths in VideoPlayer guarded so the Vulkan build doesn't drag GL symbols. Misc: - BUILD_MACOS.md: build instructions (deps, premake invocation, both renderer options). - data/config.ini: NTSC defaults sized for the new window. - .gitignore: keep the user's CD-ROM images (Driver2CD1/2.bin) out of the repo.
1 parent 006c759 commit c17f874

24 files changed

Lines changed: 376 additions & 43 deletions

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,15 @@ src_rebuild/obj/*
4040
src_rebuild/project_*
4141
src_rebuild/*.make
4242
src_rebuild/Makefile
43+
44+
# Driver 2 game data (CD images + extracted FMV/XA — too large for git)
45+
data/install/*.bin
46+
data/install/*.cue
47+
data/DRIVER2/FMV/
48+
data/DRIVER2/XA/
49+
data/REDRIVER2.log
50+
51+
# Build outputs
52+
src_rebuild/bin/
53+
src_rebuild/obj/
54+
src_rebuild/project_gmake_*/

BUILD_MACOS.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# REDRIVER2 — Build para macOS Apple Silicon
2+
3+
Port de build do REDRIVER2 para macOS arm64 (Apple Silicon — M1/M2/M3/M4).
4+
Também funciona em macs Intel (x86_64) com pequenas adaptações automáticas.
5+
6+
## Pré-requisitos
7+
8+
1. **Xcode Command Line Tools**
9+
10+
```bash
11+
xcode-select --install
12+
```
13+
14+
2. **Homebrew**https://brew.sh
15+
16+
3. **Dependências via Homebrew**
17+
18+
```bash
19+
brew install premake sdl2 jpeg openal-soft
20+
```
21+
22+
No Apple Silicon, o brew instala em `/opt/homebrew`. Em macs Intel,
23+
o caminho é `/usr/local`. O `premake5.lua` detecta automaticamente.
24+
25+
## Build
26+
27+
```bash
28+
git clone https://github.com/OpenDriver2/REDRIVER2.git
29+
cd REDRIVER2
30+
git submodule update --init --recursive
31+
cd src_rebuild
32+
33+
# Gerar Makefiles
34+
premake5 gmake
35+
36+
cd project_gmake_macosx
37+
38+
# Apple Silicon (arm64)
39+
make config=release_arm64 -j$(sysctl -n hw.ncpu)
40+
41+
# Intel (x86_64)
42+
make config=release_x64 -j$(sysctl -n hw.ncpu)
43+
```
44+
45+
Configurações disponíveis: `debug_arm64`, `release_arm64`, `release_dev_arm64`
46+
(e equivalentes para `x64`).
47+
48+
Binário final: `src_rebuild/bin/Release/REDRIVER2`.
49+
50+
## Rodando o jogo
51+
52+
O REDRIVER2 precisa dos arquivos de dados originais do Driver 2 (PSX) ao
53+
lado do executável. Veja o
54+
[wiki de instalação](https://github.com/OpenDriver2/REDRIVER2/wiki/Installation-instructions)
55+
para instruções de extração dos assets.
56+
57+
## Variáveis de ambiente opcionais
58+
59+
Caso queira apontar para instalações não-Homebrew das dependências:
60+
61+
```bash
62+
export MAC_SDL2_DIR=/caminho/sdl2
63+
export MAC_OPENAL_DIR=/caminho/openal-soft
64+
export MAC_JPEG_DIR=/caminho/jpeg
65+
```
66+
67+
## Modificações feitas para macOS arm64
68+
69+
Resumo das mudanças em relação ao upstream:
70+
71+
### Build system
72+
- `src_rebuild/premake5.lua` — filtro `system:macosx` com platforms
73+
`x64` e `arm64`, includes/libdirs do Homebrew, links de
74+
`OpenGL.framework`/`Cocoa.framework`/`SDL2`/`openal`/`jpeg`,
75+
rpath para os dylibs do brew. Substituiu o módulo `usage` (incompatível
76+
com premake5 ≥ beta8) por `dependson`+`links`+`includedirs`.
77+
- `src_rebuild/premake5_psycross.lua` — filtro `system:macosx` análogo.
78+
- `src_rebuild/premake_modules/usage/usage.lua` — guard para evitar
79+
conflito com a API `uses` agora nativa do premake5.
80+
81+
### Portabilidade arm64 / 64-bit
82+
- `src_rebuild/Game/driver2.h``trap()` agora usa `__builtin_trap()`
83+
no lugar de `__asm__("int3")` (x86-only).
84+
- `src_rebuild/PsyCross/include/psx/libgpu.h``P_LEN = 3` também para
85+
`__aarch64__`/`__arm64__`/`_M_ARM64`, igualando a configuração de 64-bit.
86+
- `src_rebuild/PsyCross/include/psx/types.h` — em LP64 (macOS arm64/x64,
87+
Linux x64), `u_long` e `ulong` viram `uint32_t` para preservar a
88+
semântica de 32-bit do PSX. Pré-define guards `_U_LONG`/`_U_INT`/
89+
`_U_CHAR`/`_U_SHORT` no macOS para impedir o `<sys/types.h>` do sistema
90+
de redefinir esses tipos como 64-bit.
91+
- `premake5.lua` adiciona `-include` forçado de `psx/types.h` no filtro
92+
macOS para garantir que esses guards sejam setados antes de qualquer
93+
header do sistema.
94+
95+
### Headers macOS-específicos
96+
- Substituído `<malloc.h>` (não existe no macOS) por `<stdlib.h>`
97+
com guard em:
98+
- `src_rebuild/PsyCross/src/psx/LIBCD.C`
99+
- `src_rebuild/utils/fs.cpp`
100+
- `src_rebuild/utils/audio_source/snd_wav_cache.cpp`
101+
- `src_rebuild/utils/targa.cpp`
102+
- `src_rebuild/Game/dr2locale.c`
103+
- `src_rebuild/tools/font_tool/font_tool_main.cpp`
104+
- `LIBCD.C` e `utils/fs.{cpp,h}` — guards `__unix__` ampliados para
105+
incluir `__APPLE__` (macOS não define `__unix__`).
106+
107+
### Casts pointer→int em LP64
108+
Pointers são 64-bit em arm64/x86_64; `(int)ptr` perde informação e
109+
o clang trata como erro. Usado `(int)(intptr_t)ptr` ou `(u_intptr)ptr`
110+
em:
111+
- `src_rebuild/Game/dr2locale.h` — macros `GET_GAME_TXT`/`GET_MISSION_TXT`
112+
- `src_rebuild/Game/C/civ_ai.c``Random2((int)straight)`
113+
- `src_rebuild/Game/C/dr2roads.c``(int)plane & 3`
114+
- `src_rebuild/Game/C/draw.c` — checagens de `primtab`/`primptr`
115+
- `src_rebuild/Game/C/event.c``FIXEDH((int)ev->node * RSIN(...))`
116+
- `src_rebuild/Game/C/glaunch.c``(int)param` em vários callbacks
117+
- `src_rebuild/Game/C/mission.c``(u_int)((char*)...)`
118+
119+
### C++ stricter checks
120+
- `src_rebuild/PsyCross/src/psx/LIBETC.C` — cast de pointer para int via
121+
`intptr_t` (`ResetCallback`/`VSyncCallback`).
122+
- `src_rebuild/PsyCross/src/psx/LIBGPU.C` — cast explícito `(DR_TPAGE*)opri`.
123+
- `src_rebuild/PsyCross/src/psx/LIBSPU.C` — include de `psx/libetc.h`
124+
para `ResetCallback()`.
125+
126+
### Função GTE faltante
127+
- `src_rebuild/Game/C/targets.c:327``RotTransPers()` é declarado mas
128+
não definido no PsyCross. Substituído pela macro `gte_RotTransPers()`
129+
com a quinta saída (`otz`) capturada localmente.
130+
131+
## Status
132+
133+
- ✅ Build limpo em arm64 (Apple Silicon)
134+
- ✅ Binário Mach-O 64-bit nativo (`file` confirma `arm64`)
135+
- ⚠️ OpenGL no macOS está oficialmente *deprecated* desde 10.14 mas o
136+
driver legacy ainda funciona até OpenGL 4.1. O PsyCross usa GL 2.x,
137+
então roda. Para uma migração futura, considerar Metal/MoltenVK.
138+
- ⚠️ Não foi rodado um playtest completo — o jogo precisa dos assets
139+
originais do Driver 2 para inicializar.

data/config.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pad1device=-1 # player 1 controller device; -1 for automatic assignment
8181
pad2device=-1 # player 2 controller device; -1 for automatic assignment
8282

8383
[render]
84-
windowWidth=1280
84+
windowWidth=960
8585
windowHeight=720
8686
fullscreen=0 # enable full screen mode; it takes screen resolution
8787
pgxpTextureMapping=1
@@ -97,7 +97,7 @@ fieldOfView=256 # 128..384, 256 is default
9797
disableChicagoBridges=0 # Experimental: also activate AI roads
9898
freeCamera=1 # Press F7 in game to enable
9999
fastLoadingScreens=1
100-
widescreenOverlays=1 # set 1 to see map, bars and stats aligned to screen corners
100+
widescreenOverlays=0 # set 1 to see map, bars and stats aligned to screen corners
101101
driver1music=0 # put Driver 1's MUSIC.BIN as D1MUSIC.BIN to DRIVER2\SOUND folder
102102
overrideContent=0 # this enables texture and car model modding
103103
userChases=RacingFreak,Snoopi,Olanov,Vortex,Fireboyd78

src_rebuild/Game/C/civ_ai.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ int CheckChangeLanes(DRIVER2_STRAIGHT* straight, DRIVER2_CURVE* curve, int distA
10831083
segLen = straight->length;
10841084
}
10851085

1086-
newLane = currentLane + (Random2((int)straight) >> 7 & 2U) + 0xff & 0xff;
1086+
newLane = currentLane + (Random2((int)(intptr_t)straight) >> 7 & 2U) + 0xff & 0xff;
10871087

10881088
if (tryToPark)
10891089
{

src_rebuild/Game/C/dr2roads.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ sdPlane* sdGetCell(VECTOR *pos)
407407

408408
plane = &planeData[*surface];
409409

410-
if (((int)plane & 3) == 0 && *(int *)plane != -1)
410+
if (((intptr_t)plane & 3) == 0 && *(int *)plane != -1)
411411
{
412412
if (plane->surface - 16U < 16)
413413
plane = EventSurface(pos, plane);

src_rebuild/Game/C/draw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,11 @@ void DrawAllTheCars(int view)
555555
for (i = 0; i < num_cars_to_draw; i++)
556556
{
557557
// Don't exceed draw buffers
558-
if ((int)(current->primtab + (-3000 - (int)(current->primptr - PRIMTAB_SIZE))) < 5800)
558+
if ((int)(intptr_t)(current->primtab + (-3000 - (int)(intptr_t)(current->primptr - PRIMTAB_SIZE))) < 5800)
559559
return;
560560

561561
// make cars look uglier
562-
if ((int)(current->primtab + (-3000 - (int)(current->primptr - PRIMTAB_SIZE)) - spacefree) < 5800)
562+
if ((int)(intptr_t)(current->primtab + (-3000 - (int)(intptr_t)(current->primptr - PRIMTAB_SIZE)) - spacefree) < 5800)
563563
gForceLowDetailCars = 1;
564564

565565
if (cars_to_draw[i]->controlType == CONTROL_TYPE_PLAYER)

src_rebuild/Game/C/event.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2989,7 +2989,7 @@ void DrawEvents(int camera)
29892989

29902990
pos.vx = pos.vx - boatOffset.vx;
29912991
pos.vz = pos.vz - boatOffset.vz;
2992-
pos.vy = (pos.vy - boatOffset.vy) + FIXEDH((int)ev->node * RSIN(*ev->data));
2992+
pos.vy = (pos.vy - boatOffset.vy) + FIXEDH((int)(intptr_t)ev->node * RSIN(*ev->data));
29932993
}
29942994
else if (type == 0x400)
29952995
{

src_rebuild/Game/C/glaunch.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,14 +288,14 @@ void State_GameStart(void* param)
288288

289289
void State_InitFrontEnd(void* param)
290290
{
291-
if ((int)param == 2)
291+
if ((int)(intptr_t)param == 2)
292292
{
293293
InitFrontend();
294294
InitFrontendDisplay();
295295
}
296296
else
297297
{
298-
ReInitFrontend((int)param == 0);
298+
ReInitFrontend((int)(intptr_t)param == 0);
299299
}
300300

301301
SetState(STATE_FRONTEND);
@@ -304,7 +304,7 @@ void State_InitFrontEnd(void* param)
304304
// [D] [T]
305305
void State_FMVPlay(void* param)
306306
{
307-
PlayFMV((int)param);
307+
PlayFMV((int)(intptr_t)param);
308308
SetState(STATE_INITFRONTEND, (void*)1);
309309
}
310310

@@ -376,7 +376,7 @@ void State_MissionLadder(void* param)
376376
MISSION_STEP* CurrentStep;
377377
RENDER_ARGS RenderArgs;
378378

379-
newgame = (int)param;
379+
newgame = (int)(intptr_t)param;
380380
quit = 0;
381381

382382
RenderArgs.nRenders = 0;

src_rebuild/Game/C/mission.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ void LoadMission(int missionnum)
441441
MissionStrings = (char*)(MissionScript + MissionLoadAddress->strings);
442442

443443
if (MissionLoadAddress->route && !NewLevel)
444-
loadsize = (u_int)((char*)MissionStrings + ((char*)MissionLoadAddress->route - (char*)MissionLoadAddress));
444+
loadsize = (u_int)(uintptr_t)((char*)MissionStrings + ((char*)MissionLoadAddress->route - (char*)MissionLoadAddress));
445445
else
446446
loadsize = length;
447447

src_rebuild/Game/C/targets.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,10 @@ void DrawStopZone(VECTOR *pPosition)
324324
temp.vy = pVector->vy;
325325
temp.vz = pVector->vz;
326326

327-
RotTransPers(&temp, pOut, &p, &flag);
327+
{
328+
long otz;
329+
gte_RotTransPers(&temp, pOut, &p, &flag, &otz);
330+
}
328331

329332
if (pOut == (long*)&pPoly->x0)
330333
pOut = (long*)&pPoly->x1;

0 commit comments

Comments
 (0)