Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- This script has been superseded by:
- -- https://github.com/yoshifan/ram-watch-cheat-engine
- -- This script might be simpler to use in some ways, but it's not likely
- -- to work on newer Dolphin versions.
- -- Script to display stuff on the screen of Dolphin.
- --
- -- 2013 Aug 26 - Created (Masterjun) (http://pastebin.com/vUCmhwMQ)
- -- 2013 Sep 17 - Modified to have permanent addresses for "Textures
- -- created" and the frame counter, and to tolerate game start addresses
- -- greater than 0x7FFFFFFF (yoshifan) (http://pastebin.com/4MsADD5W)
- -- 2013 Sep 29 - Modified to track SMG2 addresses, and optionally output
- -- stats to a file (yoshifan)
- --
- -- You need to change the variables that are listed after the functions.
- -- And make sure that you checked "Graphics > Advanced > Show Statistics".
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- --appends a string s to a table t as hex values
- local function appendstr(t,s)
- for i=1,#s do table.insert(t,string.byte(string.sub(s,i,i))) end
- table.insert(t,0x0A)
- return t
- end
- --converts a number into float
- local function tofloat(x)
- if x==0 then return 0 end
- local s = 1
- if x>=0x80000000 then
- s = -1
- x=x-0x80000000
- end
- local e = math.floor(x/0x800000)-127
- local m=(x%0x800000)/0x800000+1
- return s*(2^e)*m
- end
- --converts a table of bytes to a string
- local function tabletostr(x)
- local s = ""
- for k,v in pairs(x) do s=s..string.format("%02X",v) end
- return s
- end
- --converts a table of bytes (little endian) to a string
- local function tableLittleEndianToStr(x)
- local s = ""
- for k,v in pairs(x) do s=string.format("%02X",v)..s end
- return s
- end
- -- table of bytes (little endian) -> number
- local function tableLittleEndianToNumber(x)
- local littleEndianStr = tableLittleEndianToStr(x)
- return tonumber(littleEndianStr, 16)
- end
- -- table -> float
- local function tabletofloat(x)
- return tofloat(tonumber(tabletostr(x), 16))
- end
- -- float -> string. The number of decimal places can be optionally specified
- local function floattostr(x,precision)
- if not precision then
- precision = 3
- end
- format_str = "%." .. precision .. "f"
- local s = string.format(format_str, x)
- return s
- end
- -- 4byte table representing a float -> string representing that float.
- -- The number of decimal places can be optionally specified
- local function toflstr(x,precision)
- local str_x = tabletostr(x)
- local hex_x = tonumber(str_x,16)
- return floattostr(tofloat(hex_x),precision)
- end
- --scans for a string and returns the address of the first result
- --if there is no result it returns nil
- local function scanstr(str)
- local startaddr=0
- local stopaddr=0x7fffffffffffffff
- local scan = createMemScan()
- scan.OnlyOneResult=true
- scan.firstScan(soExactValue,vtString,rtTruncated,str,"",startaddr,stopaddr,
- "+W-C",fsmNotAligned,"",false,false,false,true)
- scan.waitTillDone()
- return scan.getOnlyResult()
- end
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- -- And again make sure that you checked "Graphics > Advanced > Show Statistics".
- ----
- -- Enter here if you have 64bit Dolphin
- local DolphinIs64bit = true
- ----
- -- You must set the following addresses for your version of Dolphin. Since
- -- addresses are written in hex, make sure you have the "0x" before the
- -- actual number.
- -----
- -- Follow this: http://tasvideos.org/forum/t/13462 tutorial to get a
- -- "pointerscan result". Doubleclick on the Address column and enter the address
- -- after the ' "Dolphin.exe"+ ' (don't forget the 0x).
- local GameRAMStartPointerAddress = 0x04961818
- -----
- -----
- -- Choose "String" for Value Type and start a Scan searching "Textures created".
- -- There should be only one result.
- --
- -- Next, take the result's address and scan for it. Have the Value Type set to
- -- "4 Bytes", and make sure the "Hex" box is checked. Find the result with a
- -- green address.
- --
- -- Rightclick this green address and click "Disassemble this memory region".
- -- Enter the number after the "Dolphin.exe+" at the top.
- local TexturesCreatedPointerAddress = 0x00D7D3A0
- -----
- -----
- -- Set the Value Type to "Array of byte" and uncheck "Writable" under Memory
- -- Scan Options. Make sure the "Hex" box is checked and search for
- --
- -- 48 63 D8 48 03 DF 48 83 7D C0 10
- -- if you have 64 bit Dolphin
- --
- -- 83 C4 0C 83 7C 24 1C 10 8D 3C 06
- -- if you have 32 bit Dolphin
- --
- -- There should be one result, rightclick that resuld and click "Disassemble
- -- this memory region". Enter the number after the "Dolphin.exe+" at the top.
- --
- -- Make sure to check "Writable" again, and really check it, because it has
- -- three states
- local ArrayOfBytesAddress = 0x00425671
- -----
- -----
- -- "local FrameCounterAddress = nil" if you don't want it.
- -- Not necessary but it adds a neat Frame- and Movecounter to the screen.
- -- When playing or recording a movie scan for the VI-Count+1 (on the top of the
- -- game window) and setting the Value Type to 4 Bytes. The first result should
- -- be a green address. Rightclick that result and click "Disassemble this
- -- memory region". Enter the number after the "Dolphin.exe+" at the top.
- local FrameCounterAddress = 0x0496B6A0
- -----
- -----
- -- When you want to output some stats to a file, set this to the number
- -- of frames you want to take stats for, and then click "Execute Script"
- -- again.
- -- If you don't want to output stats to a file, set this to 0.
- local stats_frames_to_take = 0
- -----
- local stats_current_frame = 1
- local stats = {} -- array
- local pos_x_initial = nil
- local pos_y_initial = nil
- local pos_z_initial = nil
- --------------------------------------------------------------------------------
- --------------------------------------------------------------------------------
- debug_removeBreakpoint(getAddress("Dolphin.exe")+ArrayOfBytesAddress)
- debug_setBreakpoint(getAddress("Dolphin.exe")+ArrayOfBytesAddress)
- function debugger_onBreakpoint()
- local mode=""
- if FrameCounterAddress then
- local fcaddr=getAddress("Dolphin.exe")+FrameCounterAddress
- local curfc=readInteger(fcaddr)
- local fc=readInteger(fcaddr+0x08)
- local readonly=readBytes(fcaddr-((DolphinIs64bit and 0x30) or 0x28))
- mode=curfc.." [recording]"
- if readonly==2 then mode=curfc.."/"..fc.." [playback]"
- elseif readonly==0 then mode=curfc.."/"..fc.." [inactive]" end
- end
- -- We use readBytes() instead of readInteger() here, because readInteger()
- -- can't handle values greater than the max integer-type value, which
- -- is 0x7FFFFFFF.
- local oBytes = readBytes(getAddress("Dolphin.exe")+GameRAMStartPointerAddress,4,true)
- local o = tableLittleEndianToNumber(oBytes)
- -- local variable_name = readBytes(addressoffset+o,4,true)
- local ref_pointer2_address = 0x80C7A2C8
- local ref_pointer2_bytes = readBytes(ref_pointer2_address+o,4,true)
- local ref_pointer1_address = tonumber(tabletostr(ref_pointer2_bytes),16) + 0x750
- local ref_pointer1_bytes = readBytes(ref_pointer1_address+o,4,true)
- local ref_pointer = tonumber(tabletostr(ref_pointer1_bytes),16)
- local pos_start = o + ref_pointer - 0x8670
- local pos_x = readBytes(pos_start,4,true)
- local pos_y = readBytes(pos_start+0x4,4,true)
- local pos_z = readBytes(pos_start+0x8,4,true)
- local vel_start = o + ref_pointer - 0x8C20
- local vel_x = readBytes(vel_start,4,true)
- local vel_y = readBytes(vel_start+0x4,4,true)
- local vel_z = readBytes(vel_start+0x8,4,true)
- if pos_x == nil then
- -- We're reading a non-readable address. Must be switching between
- -- Mario and Luigi, or just starting up the game.
- return 1
- end
- local vel_x_float = tabletofloat(vel_x)
- local vel_y_float = tabletofloat(vel_y)
- local vel_z_float = tabletofloat(vel_z)
- local speed_xz_float = math.sqrt(
- vel_x_float*vel_x_float + vel_z_float*vel_z_float
- )
- local speed_xyz_float = math.sqrt(
- vel_x_float*vel_x_float + vel_y_float*vel_y_float + vel_z_float*vel_z_float
- )
- local t = {0x0A,0x0A,0x0A,0x0A}
- --0x0A = new line. This makes the display start a few lines down.
- t = appendstr(t, mode)
- t = appendstr(t, "")
- t = appendstr(t, "XZ speed: " .. floattostr(speed_xz_float))
- t = appendstr(t, string.format(
- "XZ position: %s | %s", toflstr(pos_x,1), toflstr(pos_z,1)
- ))
- t = appendstr(t, "Y velocity: " .. toflstr(vel_y))
- t = appendstr(t, "Y position: " .. toflstr(pos_y))
- t = appendstr(t, "XYZ speed: " .. floattostr(speed_xyz_float))
- table.insert(t,0x00)
- --0x00 = end of text
- local textures_created_address = readInteger(
- getAddress("Dolphin.exe")+TexturesCreatedPointerAddress
- )
- writeBytes(textures_created_address,t)
- -- You can run the following lines in Cheat Engine's Lua Engine
- -- (in Memory Viewer, Tools -> Lua Engine) to verify that this address has
- -- the string "Textures Created".
- --print(string.format("Address: 0x%08X",textures_created_address))
- --local textures_created_string = readString(textures_created_address,16)
- --print("String: "..textures_created_string)
- -- Take some statistics on each frame. If
- -- stats_frames_to_take is 0, then this doesn't do anything.
- if stats_current_frame <= stats_frames_to_take then
- -- XZ Speed
- --stats[stats_current_frame] = floattostr(speed_xz_float)
- -- XZ Distance
- --local pos_x_float = tabletofloat(pos_x)
- --local pos_z_float = tabletofloat(pos_z)
- --if not pos_x_initial then
- -- pos_x_initial = pos_x_float
- -- pos_z_initial = pos_z_float
- --end
- --distance_xz_float = math.sqrt(
- -- (pos_x_float-pos_x_initial)*(pos_x_float-pos_x_initial) + (pos_z_float-pos_z_initial)*(pos_z_float-pos_z_initial)
- --)
- --stats[stats_current_frame] = floattostr(distance_xz_float,6)
- -- Y Velocity
- --stats[stats_current_frame] = toflstr(vel_y)
- -- Y Position Change
- local pos_y_float = tabletofloat(pos_y)
- if not pos_y_initial then
- pos_y_initial = pos_y_float
- end
- local y_pos_change_float = pos_y_float - pos_y_initial
- stats[stats_current_frame] = toflstr(y_pos_change_float,6)
- if stats_current_frame == stats_frames_to_take then
- -- Done taking stats. Collect them in string form and write them
- -- to a file.
- stats_str = table.concat(stats, "\n")
- -- This file will be created in either:
- -- (A) The same directory as the cheat table you have open.
- -- (B) The same directory as the Cheat Engine .exe file, it you don't
- -- have a cheat table open.
- local stats_file = io.open("stats.txt", "w")
- stats_file:write(stats_str)
- stats_file:close()
- end
- stats_current_frame = stats_current_frame + 1
- end
- return 1
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement