1 2
8 9
Post subject: Adjusting my luascript / Lua help
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
I'm considering TASing Mario & Luigi again. This time around, the English version may be faster than the Japanese, but VBA24m has emulation issues in the English version. People have mentioned Bizhawk so I will check if the issues are fixed in Bizhawk. I'm using Bizhawk 1.8.2. For your information, these are the emulation issues: - "Action Command Glitch" lets you acquire action commands you're not supposed to have. But there are differences between console and emu. Either 1) the same action command "ID" will give different commands between the two, or 2) advancing the action commands works differently between the two (so you skip ahead more/less than you're supposed to). This issue is only true for the English version. The glitch works correctly in Japanese. - The action commands that can be acquired using the "Action Command Glitch" sometimes cause the screen to be graphically glitched, while the game is lagging. This behavior differs between console and emulator for English and (to a lesser extent) for Japanese. The screen may be graphically glitched on console but the same screen may do nothing in VBA24m - or the game may be lagging continuously on console but only lags for 2 frames in VBA24m, etc. It would be a good thing (and if Bizhawk turns out to be the go-to-emulator for GBA TASing, it would be mandatory) to adjust my luascript to make it work in Bizhawk. It's fairly simple although kind of lengthy. http://pastebin.com/SZj73czH I would really appreciate it if someone could help me adjust it. You will earn an internet cookie and my love. And maybe even a grand Mario & Luigi TAS that might be sub 1 hour.
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
... I'll take a look. I'm probably the most qualified to make the conversion. (I hope this isn't my ego speaking) Considering no one else has stepped forward to say something, I'll provide some hope now by making this post, and then results later when I have the time to touch up the script. Depending on how long it takes me to get used to BizHawk, and how compatible the two emulators are, we'll see how soon I get things together.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Thank you very much! In VBA, the script will output something like this http://i.imgur.com/BqiZQ.png Just a bunch of values, RNG, position.. I could put most of this into a memory watch list but I prefer having all information on the screen in one small place where I can spot it easily. -Font/text/size may need additional adjusting because Bizhawk's lua text will be different (I think?). Please try to be close to the original, maybe I can do fine tuning later myself. The main job will be to adjust function names. -You can use a table for all the items as long as I understand the script later. -For the nut/mushroom/syrup graphics, is it possible to load small images instead of drawing it? -Please don't use too difficult coding. I want to be able to edit it later.
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
Some results. This should get pretty close to what you need. Unfortunately, I couldn't find an appropriate mirror of gui.opacity, so I changed a fair number of colors around to have the alpha in them. Aside from that, I probably did not get the display neatly aligned, as I wasn't actually running Mario & Luigi while getting the script converted, so I only had 1s and -1s showing instead of larger, more appropriate values. I'm there most of the way, and I'm hoping the script is intact enough that your own changes won't be too difficult to remove any alignment problems. Just in case it is needed, a list of BizHawk functions are here. I have made minimal tweaks to the script itself, editing the stuff that I didn't like seeing, but otherwise left the script mostly intact. When running BizHawk, Tools -> Lua Console, and in the Lua Console window, Script -> Open Script... will let you load the file. If you need to restart it, I've double-clicked the file in the list (now it's off), then double-clicked again (turn it back on), as a method to restart the script. I hope this gives a decent enough start into BizHawk. What I've given isn't perfect, but if you can't make further tweaks yourself, I may need to rethink the sort of help I've given. On a side note, I haven't noticed any functions that let you create your own images from within the script, but apparently there are some that reads up an image file to paint that.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Thank you for your effort. I think that I estimated the job wrong though. I thought the script would end up looking just like in VBA, but it doesn't. Text is neatly stroked in VBA, but pixelated and not stroked in Bizhawk. I tried to make changes to the script but I couldn't make it look nice at all and I have run into this problem: All values are zero when they shouldn't be. Bizhawk somehow only shows me 4 digit addresses in its hex editor*, memory search and memory watch although I'm running M&L in it. memory.readbyte, memory.read_s16_le, and all that don't seem to work...
text( 70+x, 6+y, memory.readbyte(0x020048e0), "yellow")
As well as other lines all show zeros (when it is not really zero). *In the case of the hex editor, I'm terribly confused about "memory domains". In VBA, memory viewer would show me all the addresses and it was nice. Bizhawk's hex editor shows me each memory domain itself with different address range (4 digit or 6 digit, ...). The memory domains aren't even the same between VBA and Bizhawk. IWRAM, WRAM, I/O, PALRAM, etc. are only in one emulator but not in the other. ___ After we find out what is the deal with values showing up as zeros, maybe I will try making a script myself.
Player (146)
Joined: 7/16/2009
Posts: 686
The problem is that the "memory" functions (memory.readbyte ...) assume a default memory domain. What this memory domain is differs per core. But what you could do is either set the memory domain to "System Bus" (memory.usememorydomain), which will probably result in correct addresses or alter the addresses to fit the default memory domain, which is probably done by subtracting 0x2000000 from each address (so 0x20048E0 becomes 0x48E0). I'd recommend the latter, as it makes the script more readable.
Editor, Emulator Coder, Site Developer
Joined: 5/11/2011
Posts: 1108
Location: Murka
MUGG wrote:
The memory domains aren't even the same between VBA and Bizhawk. IWRAM, WRAM, I/O, PALRAM, etc. are only in one emulator but not in the other.
I'm sorry that there's no canonical names for them. I shall send a formal apology letter to you by royal post, and then go and live amongst the monks for some years to learn humility. On my return, I will rename the memory domains. Or, you could just remember that IWRAM == IRAM and EWRAM == WRAM and PALRAM == PALETTE. Bizhawk doesn't have MMIO in a separate domain, as there's no real point; it's only on BUS.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Thank you natt. This solves my trouble. I'm going to finish adjusting my script and post it when it's done.
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
That proves there's a lot I haven't figured out about BizHawk's lua in my short time looking through it. And memory domains. Anyway, the main thing is we have made progress. Whether someone would have come by anyway or it was instigated by my mistakes doesn't matter too much. If the script works, great. I want to see things done.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Could someone explain to me how I can display buttons currently pressed onscreen?
joypad.getimmediate * luatable joypad.getimmediate() * returns a lua table of any controller buttons currently pressed by the user
How can I convert luatable to string? The script is almost ready, by the way. Looking pretty good.
Patashu
He/Him
Joined: 10/2/2005
Posts: 4043
MUGG wrote:
Could someone explain to me how I can display buttons currently pressed onscreen?
joypad.getimmediate * luatable joypad.getimmediate() * returns a lua table of any controller buttons currently pressed by the user
How can I convert luatable to string? The script is almost ready, by the way. Looking pretty good.
http://lua-users.org/wiki/TablesTutorial
To loop over all the key/value pairs in a table, use the pairs iterator: > t = {foo = "bar", [123] = 456} > for key,value in pairs(t) do print(key,value) end foo bar 123 456
My Chiptune music, made in Famitracker: http://soundcloud.com/patashu My twitch. I stream mostly shmups & rhythm games http://twitch.tv/patashu My youtube, again shmups and rhythm games and misc stuff: http://youtube.com/user/patashu
Editor, Expert player (2073)
Joined: 6/15/2005
Posts: 3282
By the way, if you need it, the keys used in joypad functions are, as far as I know: http://tasvideos.org/Bizhawk/LuaFunctions/JoypadTableKeyNames.html It might have changed since the last time I tested; I don't know.
Player (146)
Joined: 7/16/2009
Posts: 686
console.log(joypad.getimmediate()) will log the table to the console window (visible in the Lua window), putting this at the start of your Lua script will display the correct names. I say this because GBA isn't on the page FractalFusion linked.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
@Patashu: Your example worked, but when I try this
for key,value in pairs(joypad.get() ) do gui.text(200,200,value) end
it says wrong arguments to method call. (I realized the difference between joypad.getimmediate() and joypad.get(). What I want is to have input display such as in VBA, so I think joypad.get() is what I want.)
adelikat
He/Him
Emulator Coder, Site Developer, Site Owner, Expert player (3573)
Joined: 11/3/2004
Posts: 4754
Location: Tennessee
FractalFusion wrote:
By the way, if you need it, the keys used in joypad functions are, as far as I know: http://tasvideos.org/Bizhawk/LuaFunctions/JoypadTableKeyNames.html It might have changed since the last time I tested; I don't know.
Yes, things have most definiately changed, and the page is very outdated.
It's hard to look this good. My TAS projects
Player (146)
Joined: 7/16/2009
Posts: 686
MUGG wrote:
@Patashu: Your example worked, but when I try this
for key,value in pairs(joypad.get() ) do gui.text(200,200,value) end
it says wrong arguments to method call.
That's because you're calling gui.text with a boolean. Use tostring(value).
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
gui.text(200,200,tostring(joypad.get()))
will show "table: [8 digit hexademical which increments by 78 (hex) each frame]" ... I don't know why and what this is. Please give me a complete code that will do what I need.
Editor, Emulator Coder
Joined: 8/7/2008
Posts: 1156
That isnt what you were just told to try
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
I've tried many things and I don't know what to try else so please post a complete solution.
Player (146)
Joined: 7/16/2009
Posts: 686
MUGG wrote:
I've tried many things and I don't know what to try else so please post a complete solution.
As I literally just said:
for key, value in pairs(joypad.get()) do
    gui.text(200, 200, tostring(value))
end
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
EDIT: Thanks but more changes needed to be made to this code in order for it to do what I wanted. This is the working code.
t = " "
for key, value in pairs(joypad.get()) do
    if tostring(value) ~= "false" then    t = t .." ".. tostring(key) end
end
gui.text(340,238,tostring(t))
EDIT: I will post my finished script over in the M&L topic.
Player (146)
Joined: 7/16/2009
Posts: 686
t = " "
for button, held in pairs(joypad.get()) do
    if held then
        t = t .. " " .. button
    end
end
gui.text(340, 238, t)
I renamed the iteration variables ("key" & "value") to "button" & "held" for added clarity (hopefully). Anyway; joypad.get() returns a table with strings as key (the buttons) and booleans as value (whether a button is held or not). As such, there is no need to convert the value to a string and then compare on that, you can just check the variable directly. Also, the key (button) is already a string, so there is no need to apply tostring() before appending it to t. Lastly, t is also a string, so again there is no need for tostring() when passing it to gui.text(). I'm not sure how much knowledge you have of Lua or programming in general, and please don't take this any other way than as friendly advice, but I suggest you try learning a bit more. Your current script is unnecessarily long and contains a lot of duplicate code: it could be made a lot more comprehensible (and maintainable) by moving some code to functions and some object-oriented programming. Feel free to completely disregard this, after all, these scripts are mostly for yourself, and if you're happy with them and don't see any need to improve your coding skill then that's okay. But if you'd like to ask some questions or get more help, feel free to pm me.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Your current script is unnecessarily long and contains a lot of duplicate code: it could be made a lot more comprehensible (and maintainable) by moving some code to functions and some object-oriented programming. Feel free to completely disregard this, after all, these scripts are mostly for yourself, and if you're happy with them and don't see any need to improve your coding skill then that's okay. But if you'd like to ask some questions or get more help, feel free to pm me.
Thank you for your concern. I'm aware but I made this script initially just to display information on screen no matter how ugly the code was going to look - also whenever I try something new with lua, it takes me forever. Now, I could maybe re-organise some of the script and try to make a table for all items. But it would be optional; it does what I want so I'm going to be happy. I will understand that people want me to look at programming stuff myself instead of asking them, but I think, as for the luatable case, you could have posted the completed code snippet from the beginning. I will always need to see an example before I can understand it, and "try to use x instead of y" is just going to confuse me.
Editor, Expert player (2329)
Joined: 5/15/2007
Posts: 3933
Location: Germany
I want to output all items (that can be sold in shop) currently in my possession. So I put all items in a table which is before the "while true do" statement.
local itemsTbl = { 
[0] = "mushrooms",
[1] = "supermushrooms",
[2] = "ultramushrooms",
[3] = "maxmushrooms",
[4] = "nuts",
[5] = "supernuts",
[6] = "ultranuts",
[7] = "maxnuts",
[8] = "syrups",
[9] = "supersyrups",
[10] = "ultrasyrups",
[11] = "maxsyrups",
[12] = "1ups",
[13] = "1ups DX",
[14] = "goldmushrooms",
[15] = "herbs",
[16] = "redpeppers",
[17] = "greenpeppers",
[18] = "woohoo blends",
[19] = "hoohoo blends",
[20] = "chuckle blends",
[21] = "teehee blends",
[22] = "hoolumbians",
[23] = "chuckoccinos",
[24] = "teeheespressos",
--[32] = "woo beans",
--[33] = "hoo beans",
--[34] = "chuckle beans",
--[35] = "hee beans",
[48] = "bean badges",
[49] = "castle badges",
[50] = "pea badges",
[51] = "bean B. badges",
[52] = "counter badges",
[53] = "charity badges",
[54] = "bros. badges",
[55] = "miracle badges",
[56] = "ohoracle badges",
[57] = "mush badges",
[58] = "mari-lui badges",
[59] = "muscle badges",
[60] = "spiny badges AA",
[61] = "mush badges A",
[62] = "grab badges",
[63] = "mush badges AA",
[64] = "power badges",
[65] = "wonder badges",
[66] = "beauty badges",
[67] = "salvage badges",
[68] = "oh-pah badges",
[69] = "brilliant badges",
[70] = "sarge badges",
[71] = "general badges",
[72] = "tank badges",
[73] = "school emblem",
[74] = "steady badges",
[75] = "oho jee symbol",
[76] = "spiny badges A",
[77] = "bros. lifes",
[78] = "piranha swings",
[79] = "bros. rocks",
[80] = "lucky ribbons",
[81] = "mush badges A",
[82] = "soulful bros.",
[83] = "high-end badges",
[84] = "hand auras",
[85] = "sledge hearts",
[86] = "lucky bros.",
[87] = "bros. respects",
[88] = "bowser fists",
[89] = "bowser fangs",
[90] = "spike badges",
[91] = "chuckola badges",
[104] = "work pants",
[105] = "work jeans",
[106] = "bean pants",
[107] = "blue jeans",
[108] = "parasol pants",
[109] = "hard pants",
[110] = "heart jeans",
[111] = "plaid trousers",
[112] = "#1 trousers",
[113] = "safety slacks",
[114] = "shroom pants",
[115] = "shroom bells",
[116] = "shroom slacks",
[117] = "peachy jeans",
[118] = "mushwin pants",
[119] = "mushluck pants",
[120] = "scandal jeans",
[121] = "street jeans",
[122] = "tropic jeans",
[123] = "hermetic jeans",
[124] = "beanstar pants",
[125] = "peasley slacks",
[126] = "queen B. slacks",
[127] = "B. brand jeans",
[128] = "heart slacks",
[129] = "casual slacks",
[130] = "bubble's gears",
[131] = "chuckola pants",
[132] = "smart pants",
[133] = "school slacks",
[134] = "oho jee wears",
[135] = "oho gears",
[136] = "casual corals",
[137] = "piranha suits",
[138] = "anuboo jeans",
[139] = "ancient pants",
[140] = "heavy slacks",
[141] = "light slacks",
[142] = "harhall's pants",
[143] = "jeanie jeans",
[144] = "wool trousers",
[145] = "random slacks",
[146] = "jeaniest jeans",
[147] = "safe guards",
[148] = "iron pants"
}
key = offset value = itemname Mushrooms are stored at 0x48E2 Supermushrooms are stored at 0x48E3 etc. If I don't have one of an item, the address value will be FF or 00. I can only carry 99 (decimal) of an item at max. After the "while true do" statement, I run this code in order to output my items:
itempos=0
for offset, itemname in pairs(itemsTbl) do
    if memory.read_s8(0x48E2 + offset) > 0 then
            gui.text(200,100+itempos, memory.read_s8(0x48E2 + offset).. "x " ..itemname)
            itempos = itempos +14
    end
end
"itempos" will affect the y-position of each line so I output all items 14 pixels below each time. If the value at address+offset is greater than 0 then it should output the string and update "itempos". EDIT: It seems to somewhat work, but items are out of order... It outputs in this order:
6x syrups (correct)
1x oho jee wears (I don't have it. address might be wrong...)
1x supersyrups (correct, but should have been listed above oho jee wears...)
1x maxsyrups (correct, ...)
(some badges, they are correct...)
1x work pants (correct)
1x work jeans (correct)
1x maxnuts (should have been listed above syrups...)
So I wonder why items are out of order (please refer to the itemtable above for the correct order - I would appreciate your help with fixing the wrong order). As for oho jee wears and other items that I'm not possessing, I will have to fix wrong addresses or find some other way to account for it. EDIT: When starting a new game, it looks nice but the items are still in the wrong order (correct would be: mushrooms, supermushrooms, 1ups, pants) How can I fix this? I'm going to be interested in learning about (click or other) events, so I can maybe put these items in an expandable rectangle.
Player (146)
Joined: 7/16/2009
Posts: 686
pairs() gives no guarantee about the order in which the values are returned. An alternative is to index the table manually, using a maximum offset of sorts:
itempos = 0

-- 150 is high enough to cover all items
for offset = 0, 150 do
    if itemsTbl[offset] then
        amount = memory.read_s8(0x48E2 + offset)
        
        if (amount > 0) then
            gui.text(200, 100 + itempos, amount .. "x " .. itemsTbl[offset])
            itempos = itempos + 14
        end
    end
end
1 2
8 9