Post subject: What do I do with weirdly-used memory addresses?
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
I found the memory address for the player's X position in a game I was doing, but it works very weirdly:
    • The value starts at 11 for the left-most position, and increments as such: 01, F1, E1, D1, C1, B1, A1, 91, 72, 62, 52, 42, 32, 22. • At this point, the pattern repeats, decreasing the upper value and skipping 8, while increasing the lower value every time the upper value hits 9. • The value representing the right-most position legitimately reachable in the game is displayed as AA. • The highest legitimate value for this address is FA, which the game interprets as 5 pixels to the left of the right-most legitimate position. • Values can legitimately end in 8.
Is there a way I can have Bizhawk display this value to me in a more legible way?
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Take the lower 4 bits, subtract 1, and multiply by 15. Take the upper 4 bits, invert them, subtract 8, clamp result to unsigned 4 bits. Add this to the result above. If I'm correct then "11" will become 9 and "AA" will become 148. You could then subtract 9 if "11" is really the lowest number in all cases.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
creaothceann wrote:
Take the lower 4 bits, subtract 1, and multiply by 15. Take the upper 4 bits, invert them, subtract 8, clamp result to unsigned 4 bits. Add this to the result above. If I'm correct then "11" will become 9 and "AA" will become 148. You could then subtract 9 if "11" is really the lowest number in all cases.
That sounds like it would work, but I don't know how to do any of that. Is that done through Bizhawk, or do I need another program to get it to work? Oh yeah, and before I forget, thanks for the response. I really appreciate it and I owe you a cookie.
adelikat
He/Him
Emulator Coder, Site Developer, Site Owner, Expert player (3600)
Joined: 11/3/2004
Posts: 4739
Location: Tennessee
Is it perhaps a 12.4 fixed point value?
It's hard to look this good. My TAS projects
Player (144)
Joined: 7/16/2009
Posts: 686
Ford wrote:
That sounds like it would work, but I don't know how to do any of that. Is that done through Bizhawk, or do I need another program to get it to work?
Try using Lua to interpret and display the actual values.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
adelikat wrote:
Is it perhaps a 12.4 fixed point value?
Being very new at this, I couldn't tell you, though I'll gladly direct you to where I go into more detail about it.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
I'm starting to get the hang of the basics of lua. I don't know how to grab specific bits from memory, though I think I can turn that weird address into something more useful to me through the use of an equation or two...and possibly also having the script check a condition or something. This is a bit of a jump for me considering the only prior programming language I've ever learned to any considerable extent was QBASIC. This could be more fun than I initially anticipated.
Player (144)
Joined: 7/16/2009
Posts: 686
The page I linked you to should open to BizHawk's bit manipulation functions. You can use Wikipedia's page to get a good idea of how you can use these to do what you want. I'll give you example too: if you want to grab the first 4 bits of a number x (say, 0x7B = 0111 1011), you'd use bit.rshift(x, 4) to shift the bits 4 places to the right (in the example, 0111 1011 becomes 0000 0111 = 0x07). For the last 4 bits, use bit.band(x, 0x0F) to filter these out. (0x0F = 0000 1111, so 0x7B AND 0x0F = 0111 1011 AND 0000 1111 = 0000 1011 = 0x0B).
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Scepheo wrote:
if you want to grab the first 4 bits of a number x (say, 0x7B = 0111 1011), you'd use bit.rshift(x, 4)
That's the last 4 bits of the byte though. ;)
Player (144)
Joined: 7/16/2009
Posts: 686
creaothceann wrote:
Scepheo wrote:
if you want to grab the first 4 bits of a number x (say, 0x7B = 0111 1011), you'd use bit.rshift(x, 4)
That's the last 4 bits of the byte though. ;)
Depends, I read from left to right, so the leftmost/highest/most significant bits are the "first" bits to me. Maybe I should have just said "the 4 highest bits".
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
Thanks, these tips are working out great! Now all I have to do is address the issue of the lower 4 bits incrementing every time the upper 4 bits hit 9 instead of a more sensible number like 0. I got a plan for doing that, but it requires checking a condition. I'll tinker around with it more before I start asking for help again.
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
Just do it like I described it above? No need to check anything.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
creaothceann wrote:
Take the lower 4 bits, subtract 1, and multiply by 15. Take the upper 4 bits, invert them, subtract 8, clamp result to unsigned 4 bits. Add this to the result above.
I think I have everything figured out EXCEPT the bold part. Maybe it'll be easier if I show you what I have so far:
while true do
	XLow = ( bit.band( memory.readbyte(0x4f),0x0f ) - 1 ) * 15
	XHi = 15 - bit.rshift( memory.readbyte(0x4f),4 )
	gui.text(350,352,"  X pos: " .. XLow + XHi )
	gui.text(350,364,"  Y pos: " .. memory.readbyte(0x5c) )
	gui.text(350,376,"Targets: " .. memory.readbyte(0x35) )
	gui.text(350,388,"FrCount: " .. memory.readbyte(0x16) )
	emu.frameadvance()
end
I imagine I'd have to change something in the third line or add a line between that and the fourth line.
Joined: 7/2/2007
Posts: 3960
You can clamp to a set number of bits pretty easily by doing a bitwise-AND with a bitpattern of 1s (same number of 1s as the number of bits you want to clamp to). You can represent a set of 4 1s as 15, 0b1111, or 0xf. I don't know offhand what the syntax is for a bitwise-AND in Lua, but in most languages it's a single &, so your command would be "value & 0xf", for example.
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
Derakon wrote:
You can clamp to a set number of bits pretty easily by doing a bitwise-AND with a bitpattern of 1s (same number of 1s as the number of bits you want to clamp to). You can represent a set of 4 1s as 15, 0b1111, or 0xf. I don't know offhand what the syntax is for a bitwise-AND in Lua, but in most languages it's a single &, so your command would be "value & 0xf", for example.
while true do
	XLow = ( bit.band( memory.readbyte(0x4f),0x0f ) - 1 ) * 15
	XHi = bit.band( ( 15 - bit.rshift( memory.readbyte(0x4f),4 ) - 8 ),0x0f )
	gui.text(350,352,"  X pos: " .. XLow + XHi )
	gui.text(350,364,"  Y pos: " .. memory.readbyte(0x5c) )
	gui.text(350,376,"Targets: " .. memory.readbyte(0x35) )
	gui.text(350,388,"FrCount: " .. memory.readbyte(0x16) )
	emu.frameadvance()
end
This appears to be doing what I had hoped for. Thank you very much, Derakon!
creaothceann
He/Him
Editor
Joined: 4/7/2005
Posts: 1874
Location: Germany
IIRC I wrote that part because after subtracting 8 you'd end up with negative numbers. If you're subtracting from 15 instead it might already be correct. Just try it with a few values from the game.
Ford
He/Him
Joined: 3/5/2013
Posts: 183
Location: California
creaothceann wrote:
IIRC I wrote that part because after subtracting 8 you'd end up with negative numbers. If you're subtracting from 15 instead it might already be correct. Just try it with a few values from the game.
I did. I ran the script while watching my TAS of the first area of the game. And you were right, too. Simply subtracting made the resulting value jump once every eight pixels. Clamping it to an unsigned 4 bits made it behave itself. Tl;dr: you all earned gold star stickers.