Skip to content

Commit 1514060

Browse files
committed
Start on a Crash Bash module
1 parent cb990d5 commit 1514060

3 files changed

Lines changed: 216 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ A collection of Lua scripts and RAM watches for [BizHawk](https://github.com/TAS
130130
- Wonder Boy in Monster World (SMS)
131131

132132
## Partially Supported Games
133+
- Crash Bash
133134
- Duck Dodgers Starring Daffy Duck
134135
- Elmo's Number Journey (N64 only)
135136
- Elmo's Letter Adventure (N64 only)

ScriptHawk.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,12 @@ local supportedGames = {
424424
["7E59A4CE"] = {moduleName="games.crash3", friendlyName="Crash Bandicoot 3 - Buttobi! Sekai Isshuu (Japan)", version=3},
425425
["A2E93AEC"] = {moduleName="games.crash3", friendlyName="Crash Bandicoot 3 - Buttobi! Sekai Isshuu (Japan)", version=3},
426426

427+
-- Crash Bash
428+
["C829C610"] = {moduleName="games.crash_bash", friendlyName="Crash Bash (USA)", version=1},
429+
["69A6CD83"] = {moduleName="games.crash_bash", friendlyName="Crash Bash (USA)", version=1},
430+
["D9D78CC9"] = {moduleName="games.crash_bash", friendlyName="Crash Bash (Europe)", version=2},
431+
["2FA7F930"] = {moduleName="games.crash_bash", friendlyName="Crash Bash (Europe)", version=2},
432+
427433
-- Day Dreamin' Davey
428434
["4C88391318E3BD79C14BFF6724A377688E47261B"] = {moduleName="games.day_dreamin_davey", friendlyName="Day Dreamin' Davey"},
429435

games/crash_bash.lua

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
if type(ScriptHawk) ~= "table" then
2+
print("This script is not designed to run by itself");
3+
print("Please run ScriptHawk.lua from the parent directory instead");
4+
print("Thanks for using ScriptHawk :)");
5+
return;
6+
end
7+
8+
local Game = {
9+
max_rot_units = 4096,
10+
rot_speed = 16,
11+
speedy_index = 7,
12+
speedy_speeds = {
13+
0.001, 0.01, 0.1, 1, 5, 10, 20, 50, 100
14+
},
15+
squish_memory_table = true,
16+
Memory = { -- Version order: USA, Europe
17+
--global_timer = {0x4E0D8, 0x4EA2C},
18+
global_timer = {0x5B690, 0x5D274},
19+
warp_room_2_unlocked = {0x5A780, 0x5C564},
20+
warp_room_3_unlocked = {0x5A792, 0x5C576},
21+
warp_room_4_unlocked = {0x5A785, 0x5C569},
22+
warp_room_5_unlocked = {0x5A79B, 0x5C57F},
23+
p1_x_position_warp_room = {0x9EEA0, nil}, -- Fixed point
24+
p1_z_position_warp_room = {0x9EEA4, nil}, -- Fixed point
25+
-- PLAYER 1
26+
p1_pointer = {0x9D530, 0x9BA6C}, -- Game.minigamePlayer
27+
p1_health = {0x9D562, 0x9BA9E},
28+
p1_tank_health = {0xCAD50, 0xC9638},
29+
p1_mines = {0xCAD78, 0xC9660},
30+
-- PLAYER 2
31+
p2_pointer = {0x9D59C, 0x9BAD8}, -- Game.minigamePlayer
32+
p2_health = {0x9D5CE, 0x9BB0A},
33+
p2_tank_health = {0xCADF4, 0xC96DC},
34+
p2_mines = {0xCAE1C, 0xC9704},
35+
-- PLAYER 3
36+
p3_pointer = {0x9D608, 0x9BB44}, -- Game.minigamePlayer
37+
p3_health = {0x9D63A, 0x9BB76},
38+
p3_tank_health = {0xCAE98, 0xC9780},
39+
p3_mines = {0xCAEC0, 0xC97A8},
40+
-- PLAYER 4
41+
p4_pointer = {0x9D674, 0x9BBB0}, -- Game.minigamePlayer
42+
p4_health = {0x9D6A6, 0x9BBE2},
43+
p4_tank_health = {0xCAF3C, 0xC9824},
44+
p4_mines = {0xCAF64, 0xC984C},
45+
},
46+
minigamePlayer = {
47+
x_pos = 0x10, -- Signed fixed point 16.16 little endian
48+
y_pos = 0x14, -- Signed fixed point 16.16 little endian
49+
z_pos = 0x18, -- Signed fixed point 16.16 little endian
50+
-- TODO: Rotation
51+
-- TODO: Velocity
52+
},
53+
};
54+
55+
local global_timer = {
56+
current = 0,
57+
previous = 0,
58+
};
59+
60+
function mainmemory.read_s1616_le(address) -- Signed fixed point 16.16 little endian
61+
return mainmemory.read_s32_le(address) / 0x10000;
62+
end
63+
64+
function mainmemory.write_s1616_le(address, value) -- Signed fixed point 16.16 little endian
65+
return mainmemory.write_u32_le(address, value * 0x10000);
66+
end
67+
68+
function mainmemory.read_s2012_le(address) -- Signed fixed point 20.12 little endian
69+
return mainmemory.read_s32_le(address) / 0x1000;
70+
end
71+
72+
function mainmemory.write_s2012_le(address, value) -- Signed fixed point 20.12 little endian
73+
return mainmemory.write_u32_le(address, value * 0x1000);
74+
end
75+
76+
function mainmemory.read_s248_le(address) -- Signed fixed point 24.8 little endian
77+
return mainmemory.read_s32_le(address) / 0x100;
78+
end
79+
80+
function mainmemory.write_s248_le(address, value) -- Signed fixed point 24.8 little endian
81+
return mainmemory.write_u32_le(address, value * 0x100);
82+
end
83+
84+
function Game.unlockWarpRooms()
85+
mainmemory.writebyte(Game.Memory.warp_room_2_unlocked, 1);
86+
mainmemory.writebyte(Game.Memory.warp_room_3_unlocked, 1);
87+
mainmemory.writebyte(Game.Memory.warp_room_4_unlocked, 1);
88+
mainmemory.writebyte(Game.Memory.warp_room_5_unlocked, 1);
89+
end
90+
91+
function Game.applyInfinites()
92+
local max_health = 0x14;
93+
local max_tank_health = 0x63;
94+
local max_mines = 0x03;
95+
96+
mainmemory.writebyte(Game.Memory.p1_health, max_health);
97+
mainmemory.writebyte(Game.Memory.p1_tank_health, max_tank_health);
98+
mainmemory.writebyte(Game.Memory.p1_mines, max_mines);
99+
100+
--[[
101+
mainmemory.writebyte(Game.Memory.p2_health, max_health);
102+
mainmemory.writebyte(Game.Memory.p2_tank_health, max_tank_health);
103+
mainmemory.writebyte(Game.Memory.p2_mines, max_mines);
104+
105+
mainmemory.writebyte(Game.Memory.p3_health, max_health);
106+
mainmemory.writebyte(Game.Memory.p3_tank_health, max_tank_health);
107+
mainmemory.writebyte(Game.Memory.p3_mines, max_mines);
108+
109+
mainmemory.writebyte(Game.Memory.p4_health, max_health);
110+
mainmemory.writebyte(Game.Memory.p4_tank_health, max_tank_health);
111+
mainmemory.writebyte(Game.Memory.p4_mines, max_mines);
112+
--]]
113+
end
114+
115+
function Game.getMinigamePlayer(playerIndex)
116+
playerIndex = playerIndex or 0;
117+
return dereferencePointer(Game.Memory.p1_pointer + playerIndex * 0x6C);
118+
end
119+
120+
function Game.getXPosition(playerIndex)
121+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
122+
if isRAM(minigamePlayer) then
123+
return mainmemory.read_s248_le(minigamePlayer + Game.minigamePlayer.x_pos);
124+
end
125+
return 0;
126+
end
127+
128+
function Game.getYPosition(playerIndex)
129+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
130+
if isRAM(minigamePlayer) then
131+
return mainmemory.read_s248_le(minigamePlayer + Game.minigamePlayer.y_pos);
132+
end
133+
return 0;
134+
end
135+
136+
function Game.getZPosition(playerIndex)
137+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
138+
if isRAM(minigamePlayer) then
139+
return mainmemory.read_s248_le(minigamePlayer + Game.minigamePlayer.z_pos);
140+
end
141+
return 0;
142+
end
143+
144+
function Game.setXPosition(value, playerIndex)
145+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
146+
if isRAM(minigamePlayer) then
147+
mainmemory.write_s248_le(minigamePlayer + Game.minigamePlayer.x_pos, value);
148+
end
149+
end
150+
151+
function Game.setYPosition(value, playerIndex)
152+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
153+
if isRAM(minigamePlayer) then
154+
mainmemory.write_s248_le(minigamePlayer + Game.minigamePlayer.y_pos, value);
155+
end
156+
end
157+
158+
function Game.setZPosition(value, playerIndex)
159+
local minigamePlayer = Game.getMinigamePlayer(playerIndex);
160+
if isRAM(minigamePlayer) then
161+
mainmemory.write_s248_le(minigamePlayer + Game.minigamePlayer.z_pos, value);
162+
end
163+
end
164+
165+
function Game.detectVersion(romName, romHash)
166+
ScriptHawk.dpad.joypad.enabled = false;
167+
ScriptHawk.dpad.key.enabled = false;
168+
return true;
169+
end
170+
171+
function Game.initUI()
172+
ScriptHawk.UI.button(0, 6, {4, 10}, nil, nil, "Unlock Rooms", Game.unlockWarpRooms);
173+
end
174+
175+
function Game.eachFrame()
176+
global_timer.previous = global_timer.current;
177+
global_timer.current = mainmemory.read_u32_le(Game.Memory.global_timer);
178+
end
179+
180+
function Game.isPhysicsFrame()
181+
return global_timer.current ~= global_timer.previous;
182+
end
183+
184+
Game.OSD = {
185+
{"P1", hexifyOSD(function() return Game.getMinigamePlayer(0) end)},
186+
{"P1 X", function() return Game.getXPosition(0) end},
187+
{"P1 Y", function() return Game.getYPosition(0) end},
188+
{"P1 Z", function() return Game.getZPosition(0) end},
189+
{"Separator"},
190+
{"dY"},
191+
{"dXZ"},
192+
{"Separator"},
193+
{"P2", hexifyOSD(function() return Game.getMinigamePlayer(1) end)},
194+
{"P2 X", function() return Game.getXPosition(1) end},
195+
{"P2 Y", function() return Game.getYPosition(1) end},
196+
{"P2 Z", function() return Game.getZPosition(1) end},
197+
{"Separator"},
198+
{"P3", hexifyOSD(function() return Game.getMinigamePlayer(2) end)},
199+
{"P3 X", function() return Game.getXPosition(2) end},
200+
{"P3 Y", function() return Game.getYPosition(2) end},
201+
{"P3 Z", function() return Game.getZPosition(2) end},
202+
{"Separator"},
203+
{"P4", hexifyOSD(function() return Game.getMinigamePlayer(3) end)},
204+
{"P4 X", function() return Game.getXPosition(3) end},
205+
{"P4 Y", function() return Game.getYPosition(3) end},
206+
{"P4 Z", function() return Game.getZPosition(3) end},
207+
};
208+
209+
return Game;

0 commit comments

Comments
 (0)