Currently support TR1 (USA v1.6), TR2 (USA v1.3), TR3 (USA v1.2), TR3 (JAP Disc 1) and TR4 (USA v1.1) (no enemy names yet though).
TR5 should be easy to implement but I was too lazy for it.
--console.log( joypad.getimmediate() )
local HASH=gameinfo.getromhash()
local POINTER = 0 --Pointer to Lara's data location
local POINTPOS = 0x40 --Coordinates location in Lara's data
local POINTSPD = 0x1E --Speed location in Lara's data
local POINTANG = 0x4E --Angle location in Lara's data
local POINTHEA = 0x22 --Health location in Lara's data
local POINTTIM --Timer location in the RAM
local POINTTTIM = 0 --Pointer to individual levels time (for total time)
local FIXPOINT = 0 --Fix for pointers in TR1
local FIXTIMER = 0 --Fix for individual level timer in TR3
local POINTENT = 0 --Pointer to the camera current target (equal to 0 if none)
local ENTITY_LIST={} --Entities list based on the entities ID
local POINTID = 0xC --ID location in entity's data
local POINTHP = 0x22 --HP location in entity's data
while true do
BASE_OLD=0
if HASH=='5651035B' then --TR1 (USA) (v1.6)
POINTER = 0x89FAC
POINTPOS = 0x30
POINTANG = 0x3E
POINTTIM = 0x928F8
FIXPOINT = 0x80000000
POINTENT = 0x1DE050
ENTITY_LIST={
'';'';'';'';'';'';'';'Wolf';'Bear';'Bat';'Crocodile';'Crocodile';'Lion';'Lion';'Panther';'Gorilla';
'Rat';'Rat';'T-Rex';'Velociraptor';'Winged Atlantean';'Crawling Atlantean';'Crawling Atlantean';'Centaur';'Mummy';'';'';'Larson';'Pierre DuPont';'';'Skateboard Kid';'The Coyboy';
'Kold';'Winged Natla';'Legless Mutant';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'Scion';'';'';'';'';'';'';'';'';'';'';'';'';'';''
}
end
if HASH=='B089D427' then --TR2 (USA) (v1.3)
POINTER = 0x8C6B8
POINTPOS = 0x34
POINTANG = 0x42
POINTTIM = 0x89FC0
POINTENT = 0x8C568 --0x1FFCFC
ENTITY_LIST={
'';'';'';'';'';'';'';'';'';'';'';'';'';'Red Snowmobile';'Boat';'Doberman';
'Masked Goon';'Masked Goon';'Masked Goon';'Knifethrower';'Shotgun Goon';'Rat';'Dragon';'Dragon';'Gondola';'Shark';'Yellow Moray Eel';'Black Moray Eel';'Barracuda';'Scuba Diver';'Gunman';'Gunman';
'Stick-wielding goon';'Stick-wielding goon';'Flamethrower goon';'Spider';'Giant Spider';'Crow';'Snow Leopard';'Marco Bartoli';'Xian Guard';'Xian Guard';'Yeti';'Bird Monster';'Eagle';'Mercenary';'Mercenary';'Mercenary';
'Black Snowmobile';'Mercenary';'Monk';'Monk';'';'';'';'';'';'';'';'';'';'';'';''
}
end
if HASH=='FC8FB87A' then --TR3 (USA) (v1.2)
POINTER = 0x9961C
POINTTIM = 0xA699C
FIXTIMER = 2
POINTENT = 0x995A4
ENTITY_LIST={
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'Tribesman';'Tribesman';'Dog';'Rat';'';'Killer Whale';'Scuba Diver';'Crow';'Tiger';'Vulture';'Target';'Crawler Mutant';
'Crocodile';'';'Compsognathus';'Lizard Man';'Puna';'Mercenary';'Velociraptor';'RX-Tech Guy';'RX-Tech Guy';'Dog';'Crawler Mutant';'';'Tinnos Wasp';'Tinnos Monster';'Brute Mutant';'';
'';'Willard Mutant';'RX-Tech Guy';'Mercenary';'';'Punk';'';'';'Guard';'Sophia Leigh';'Cleaner Robot';'';'Military Police';'Military Police';'Prisoner';'Military Police';
'Gun Turret';'Dam Guard';'';'';'';'Cobra';'Shiva';'Monkey';'Tony';'';'';'';'';'';'';''
}
end
if HASH=='4F422104' then --TR3 (JAP) (Disc 1)
POINTER = 0x99AB0
POINTTIM = 0xA6EA4
POINTTTIM = 0x0A69E4
FIXTIMER = 2
POINTENT = 0x99A38 --0xA9610 0xAB638
ENTITY_LIST={
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'Tribesman';'Tribesman';'Dog';'Rat';'';'Killer Whale';'Scuba Diver';'Crow';'Tiger';'Vulture';'Target';'Crawler Mutant';
'Crocodile';'';'Compsognathus';'Lizard Man';'Puna';'Mercenary';'Velociraptor';'RX-Tech Guy';'RX-Tech Guy';'Dog';'Crawler Mutant';'';'Tinnos Wasp';'Tinnos Monster';'Brute Mutant';'';
'';'Willard Mutant';'RX-Tech Guy';'Mercenary';'';'Punk';'';'';'Guard';'Sophia Leigh';'Cleaner Robot';'';'Military Police';'Military Police';'Prisoner';'Military Police';
'Gun Turret';'Dam Guard';'';'';'';'Cobra';'Shiva';'Monkey';'Tony';'';'';'';'';'';'';''
}
end
if HASH=='9415F6B7' then --TR4 (USA) (v1.1)
POINTER = 0xA8000
POINTTIM = 0xA7FC0
POINTENT = 0xA95BC --0xA9610 0xAB638
ENTITY_LIST={
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';
'';'';'';'';'';'';'';'';'';'';'';'';'';'';'';''
}
end
if POINTER==0 then
print("ROM Hash : "..HASH)
print("game not in the database")
break
end
--print("Current pointer : "..string.format("%08x", POINTER))
while true do
X = 0
Y = 0
Z = 0
ANGLE = 0
HEALTH = 0
X_SPD = 0
Y_SPD = 0
Z_SPD = 0
ANGLE_SPD = 0
DIST = 0
TIMER2 = 0
ENTITY = 0
COUNT = 301
NAME = ''
HP = 0
TEMP = 0
while true do
BASE = memory.read_u32_le( POINTER ) - FIXPOINT
if (BASE<=0 or BASE>=0x200000) then
emu.frameadvance()
--print(string.format("%x", BASE+0x80000000))
--print(string.format("%x", POINTER ))
--print(memory.read_u32_le( POINTER ))
--print(BASE+0x80000000)
break
end
if (BASE~=BASE_OLD) then
BASE_OLD=BASE
print("Current Lara's data location : "..string.format("%06X", BASE))
end
X_ANC=X
Y_ANC=Y
Z_ANC=Z
ANGLE_ANC=ANGLE
TIMER_ANC=TIMER2
X = memory.read_u16_le( BASE + POINTPOS + 0x8 )
Y = memory.read_u16_le( BASE + POINTPOS )
Z = memory.read_s16_le( BASE + POINTPOS + 0x4 )
SPEED=memory.read_s16_le( BASE + POINTSPD )
ANGLE=memory.read_u16_le( BASE + POINTANG )/65536*360
HEALTH = memory.read_s16_le( BASE + POINTHEA )
TIMER2=math.max(memory.read_u16_le( POINTTIM ) - FIXTIMER, 0)
MINUTES=math.floor(TIMER2/1800)
SECONDS=math.floor(TIMER2/30)-MINUTES*60
CENTS=math.floor((TIMER2 % 30)/30*100+0.5)
if ((X_ANC~=X) or (Y_ANC~=Y) or (ANGLE_ANC~=ANGLE) or (TIMER_ANC~=TIMER2)) then
X_SPD=X-X_ANC
Y_SPD=Y-Y_ANC
Z_SPD=Z-Z_ANC
ANGLE_SPD=ANGLE-ANGLE_ANC
DIST=math.sqrt((X-X_ANC)^2+(Y-Y_ANC)^2)
end
gui.text(50,60,"X position : " .. X .. " (" .. X_SPD .. ")","white")
gui.text(50,80,"Y position : " .. Y .. " (" .. Y_SPD .. ")","white")
gui.text(50,100,"Z position : " .. Z .. " (" .. Z_SPD .. ")","white")
gui.text(50,120,"Speed (RAM) : " .. SPEED,"white")
gui.text(50,140,"Speed (True) : " .. string.format("%.2f", DIST),"white")
gui.text(50,160,
"Angle : " .. string.format("%6.2f", ANGLE) ..
" / " .. string.format("%5d",ANGLE*65536/360) ..
" (" .. string.format("%d",(ANGLE_SPD)*65536/360) ..
")", "white")
gui.text(50,180,
"Timer : " .. string.format("%1d", MINUTES) ..
":" .. string.format("%02d", SECONDS) ..
"." .. string.format("%02d", CENTS) ..
" / " .. string.format("%5d", TIMER2),
"white")
gui.text(50,200,"Health : " .. HEALTH,"white")
--Current entity targeted
TEMP = memory.read_u32_le( POINTENT ) - FIXPOINT
if (TEMP>0)
then ENTITY = TEMP
COUNT = 0
else COUNT = COUNT + 1
end
NAME = ENTITY_LIST[1 + memory.read_u8( ENTITY + POINTID )]
HP = memory.read_s16_le( ENTITY + POINTHP )
if HP < -100
then HP=0
end
if (COUNT<60) then
if (NAME=='' or NAME==nil)
then gui.text(50, 260, "ID = " .. string.format("%02X", memory.read_u8( ENTITY + POINTID )), "white")
else gui.text(50, 260, NAME, "white")
end
gui.text(50, 280, "HP : " .. string.format("%2d", HP), "white")
end
--Total Time (currently only for TR3 JAP)
if (POINTTTIM~=0) then
TOTAL = 0
for i=0, 18 do
TOTAL = TOTAL + memory.read_u16_le( POINTTTIM + i*0x34 )
end
MINUTES=math.floor(TOTAL/1800)
SECONDS=math.floor(TOTAL/30)-MINUTES*60
CENTS=math.floor((TOTAL % 30)/30*100+0.5)
gui.text(50,220,
"Total Time : " .. string.format("%1d", MINUTES) ..
":" .. string.format("%02d", SECONDS) ..
"." .. string.format("%02d", CENTS) ..
" / " .. string.format("%5d", TOTAL),
"white")
end
emu.frameadvance()
end
end
end