1 2 3 4 5 6 7 8 9
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Edit: Fixed my problem. The problem was with using a string that ends in \". Fixed by using \\". ------ So I want to make a quick map of a level of a gba game. I was directed to this program. So my plan was to save a screenshot every frame using this script:
Language: Lua

p=0 while true do client.screenshot("D:\StuartScreens\" .. p .. ".png") p=p+1 emu.frameadvance() end
(Btw, the lua highlighting is wrong) But when I run that script, I get an error:
System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei Bizhawk.Client.Common.LuaSandbox(Action callback, Action exceptionCallback)
bei Bizhawk.Client.Emuhawk.LuaConsole.ToggleScriptMenuItem_Click(Object sender, EventArgs e)
Used 1.11.6.
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
I have a huge table that I iterate through every frame to draw something for each entry. Is it possible to somehow just draw it once on a canvas and then display that canvas? How to use gui.createcanvas?
Joined: 10/23/2009
Posts: 545
Location: Where?
Language: lua

while true do currentvalue = mainmemory.readbyte(0x043C) Pastvalue[1] = Pastvalue[0] Pastvalue[0] = currentvalue speedX = Pastvalue[1] - Pastvalue[0] gui.pixelText(138,128,"sX:".. speedX) emu.frameadvance() end
So I have this code in order to try to calculate a speed by myself by substracting two x position: the one the frame before and the current frame. But I don't know why it says this:
LuaInterface.LuaScriptException: [string "main"]:3: attempt to index global 'Pastvalue' (a nil value)
Does anyone knows why Pastvalue[0] is a nil value?
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Add Pastvalue {0,0} at the top of the script.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Noxxa
They/Them
Moderator, Expert player (4125)
Joined: 8/14/2009
Posts: 4090
Location: The Netherlands
feos wrote:
Add Pastvalue {0,0} at the top of the script.
To be precisely correct, add:
Language: Lua

Pastvalue = {0, 0}
Or alternatively, just add:
Language: Lua

Pastvalue = {}
http://www.youtube.com/Noxxa <dwangoAC> This is a TAS (...). Not suitable for all audiences. May cause undesirable side-effects. May contain emulator abuse. Emulator may be abusive. This product contains glitches known to the state of California to cause egg defects. <Masterjun> I'm just a guy arranging bits in a sequence which could potentially amuse other people looking at these bits <adelikat> In Oregon Trail, I sacrificed my own family to save time. In Star trek, I killed helpless comrades in escape pods to save time. Here, I kill my allies to save time. I think I need help.
Joined: 10/23/2009
Posts: 545
Location: Where?
EDIT: Now with this:
Language: lua

local function speed(name,address,x,y) currentvalue = mainmemory.readbyte(address) Pastvalue[1] = Pastvalue[0] Pastvalue[0] = currentvalue speed = Pastvalue[0] - Pastvalue[1] gui.pixelText(x,y,name.. speed) end Pastvalue = { [0] = 0,--current frame [1] = 0 --Previous frame } while true do mainmemory.writebyte(0x005B,58) --Unlimited Time --mainmemory.writebyte(0x00FD,74) --Fixed cam position speed(speedX:,0x043C,138,128) emu.frameadvance() end
Throws me this: http://imgur.com/a/PcRTB as well as the first. But at first I got a different window, So I am really confused. EDIT: Removed the fixed problems and with now a new problem.
Language: lua

local function speedtext(name,address,x,y) currentvalue = mainmemory.read_u16_le(address) Pastvalue[1] = Pastvalue[0] Pastvalue[0] = currentvalue speed = Pastvalue[0] - Pastvalue[1] gui.pixelText(x,y,name.. speed) end Pastvalue = { [0] = 0,--current frame [1] = 0 --Previous frame } while true do mainmemory.writebyte(0x005B,58) --Unlimited Time --mainmemory.writebyte(0x00FD,74) --Fixed cam position speedtext("1spX:",0x043C,138,128) speedtext("1spY:",0x043E,138,136) emu.frameadvance() end
So I have that, but it seems that my two speeds are messed up now.
Invariel
He/Him
Editor, Site Developer, Player (171)
Joined: 8/11/2011
Posts: 539
Location: Toronto, Ontario
After our conversation on IRC, give this a whirl. I haven't tested it, but you should be able to massage it into doing exactly what you want.
Language: lua

local function speedtext (addressX, addressY, whereX, whereY) Pastvalue[0] = Currentvalue[0] Pastvalue[1] = Currentvalue[1] Currentvalue[0] = mainmemory.read_u16_le(addressX) Currentvalue[1] = mainmemory.read_u16_le(addressY) gui.pixelText(whereX, whereY, "ispX: " .. Currentvalue[0] - Pastvalue[0]) gui.pixelText(whereX, whereY + 8, "ispY: " .. Currentvalue[1] - Pastvalue[1]) end Pastvalue = { [0] = 0, -- X coordinate [1] = 0 -- Y coordinate } Currentvalue = { [0] = 0, -- X coordinate [1] = 0 -- Y coordinate } while true do mainmemory.writebyte(0x005B, 58) -- Unlimited time -- mainmemory.writebyte(0x00FD, 74) -- Fixed cam position speedtext (0x043C, 0x043E, 138, 128) emu.frameadvance end
I am still the wizard that did it. "On my business card, I am a corporate president. In my mind, I am a game developer. But in my heart, I am a gamer." -- Satoru Iwata <scrimpy> at least I now know where every map, energy and save room in this game is
Amaraticando
It/Its
Editor, Player (159)
Joined: 1/10/2012
Posts: 673
Location: Brazil
You can do something like this (I've tested):
Language: lua

-- add other entries if you want -- you might want to index by name and use a table of tables: address_name = {address = 0x43c, value = 0} local past_values = { [0x043c] = 0, [0x043e] = 0, } -- IMO, the position of the text as the first arguments is more consistent local function speedtext(whereX, whereY, address, address_name) if not past_values[address] then print("Address", address) error"is invalid" end local current_value = mainmemory.read_u16_le(address) local speed = current_value - past_values[address] past_values[address] = current_value address_name = address_name or string.format("%4x", address) gui.pixelText(whereX, whereY, address_name .. ": " .. speed) end while true do local whereX, whereY = 138, 128 speedtext(whereX, whereY, 0x043c, "1spX") speedtext(whereX, whereY + 8, 0x043e, "1spY") emu.frameadvance() end
Joined: 10/23/2009
Posts: 545
Location: Where?
I am not sure to understand these lines from the code. Could you explain these lines?
Language: lua

if not past_values[address] then print("Address", address) error"is invalid" end
Language: lua

address_name = address_name or string.format("%4x", address)
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Amaraticando
It/Its
Editor, Player (159)
Joined: 1/10/2012
Posts: 673
Location: Brazil
Niamek wrote:
I am not sure to understand these lines from the code. Could you explain these lines?
Language: lua

if not past_values[address] then print("Address", address) error"is invalid" end
Language: lua

address_name = address_name or string.format("%4x", address)
1) If there's no entry <address> in past_values (or if it's false), then raise an error. It's just a sanity check, in case you didn't write this table correctly. 2) var1 = var2 or var3 is a typical Lua idiom. It's the same of:
Language: lua

if address_name == nil or address_name == false then address_name = string.format("%4x", address) -- i.e., address_name is the hexadecimal representation of address else address_name = address_name -- effectively does nothing end
Joined: 11/18/2011
Posts: 31
Location: Siberia
   s='0x8b16' 
   xpos = memory.read_s16_be(s)
Hello! How do I make this work? I have an address in string variable, how do I use it with memory.read()? ------------------------- Oh, 0x8b16 is hexadecimal, not string? Wait, I'll try to put s=0x8b16 instead. ------------------------- Oh, thank goodness it works. Nice work, myself!
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Is there a difference between console.log() and print()?
Masterjun
He/Him
Site Developer, Skilled player (1988)
Joined: 10/12/2010
Posts: 1185
Location: Germany
Nope, they are programmed to link to the same thing. The print is relinked here, which links this method, which calls this, which is the same as console.log (defined in the 4 lines above the previous link).
Warning: Might glitch to credits I will finish this ACE soon as possible (or will I?)
Fortranm
He/Him
Editor, Experienced player (878)
Joined: 10/19/2013
Posts: 1121
local tabl = {}
tabl = input.get()
if tabl["E"] then
  if (emu.framecount()%2)>0 then
    joypad.set("A")
  end
  if (emu.framecount()%2)<1 then
    joypad.set("B")
  end
end
I wrote this code to make the game press A on odd frames and press B on even frames, but the script doesn't run at all. Which part should I change to make it work?
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
try
Language: Lua

local tabl = {} while true do tabl = input.get() if tabl["E"] then if emu.framecount()%2==0 then tabl.A=true joypad.set(tabl) end if emu.framecount()%2==1 then tabl.B=true joypad.set(tabl) end end emu.frameadvance() end
Edit: Ok that doesn't work. I'll try to revise it. Edit: Should work now.
Fortranm
He/Him
Editor, Experienced player (878)
Joined: 10/19/2013
Posts: 1121
It worked. Thanks a lot!
Editor, Skilled player (1202)
Joined: 9/27/2008
Posts: 1085
Language: lua

BtnA, BtnB= {A=true}, {B=true} while true do local tbl= input.get() if tabl["E"] then if emu.framecount()%2 == 0 then joypad.set(BtnA) else joypad.set(BtnB) end end emu.frameadvance() end
This would be my recommendation. In MUGG's revised code, tabl holds all the pressed keys. Now, joypad.set takes a table and looks for specific table keys to figure out which buttons to press. At the start of the loop, tabl gets a new table, then it is modified based on emu.framecount(). There is no explicit code to set nil or false to remove the true from A or B. The main reason why it's able to alternate A and B is that A and B are no longer true when the table is reset from the first line in the loop, as it keeps getting a new table from input.get(), and it's using a new table every loop that gets the default not-true value for both A and B. If it matters, the glitch in MUGG's code means that if you hold A or B on the keyboard while holding E as well, then A or B will be always set regardless of the frame count. If you have something set for those keys, and have something important to press while holding E that happens to be assigned to A or B, then you'll hit this glitch even if the controller A or B aren't assigned to keyboard A or B.
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Language: Lua

local totime = function(frames,fps) mins = math.floor((frames/fps)/60) secs = math.floor((frames/fps-mins*60)*100+0.5)/100 returnvalue = string.format("%02d:%05.2f",mins,secs) return returnvalue end
I would like to include hours but I can't seem to get it to work. If someone can help me, have my thanks!
Site Admin, Skilled player (1254)
Joined: 4/17/2010
Posts: 11478
Location: Lake Char­gogg­a­gogg­man­chaugg­a­gogg­chau­bun­a­gung­a­maugg
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Amaraticando
It/Its
Editor, Player (159)
Joined: 1/10/2012
Posts: 673
Location: Brazil
In my script, I use something similar to this, but taking into account PAL and NTSC framerates.
Language: lua

local FRAMERATE = 60 -- Returns a string in the format hh:mm:ss.mmm -- hh only appears if non-zero -- mmm is the miliseconds local function framecount_to_time(frame) local floor = math.floor local total_seconds = frame/FRAMERATE local hours = floor(total_seconds/3600) local tmp = total_seconds - 3600*hours local minutes = floor(tmp/60) tmp = tmp - 60*minutes local seconds = floor(tmp) local miliseconds = 1000* (total_seconds%1) if hours == 0 then hours = "" else hours = string.format("%d:", hours) end local str = string.format("%s%.2d:%.2d.%03.0f", hours, minutes, seconds, miliseconds) return str end
Editor, Expert player (2330)
Joined: 5/15/2007
Posts: 3933
Location: Germany
Thanks. I ended up finishing a version of my own via trial and error.
Language: Lua

local totime = function(frames,fps) hours = math.floor((frames/fps)/3600) mins = math.floor((frames/fps)/60)%60 secs = math.floor(((frames/fps-mins*60)*100+0.5)/100) %60 ms = (frames % fps)/60 * 100 if hours==0 then returnvalue = string.format("%02d:%02d.%02d",mins,secs,ms) else returnvalue = string.format("%02d:%02d:%02d.%02d",hours,mins,secs,ms) end return returnvalue end
If you can improve it, feel free to do so.
Amaraticando
It/Its
Editor, Player (159)
Joined: 1/10/2012
Posts: 673
Location: Brazil
I think it's the best that can be done:
Language: lua

-- use 100 and %.2d if you wanna display only centiseconds local function frames_to_time(frame, fps) local floor = math.floor local total = floor(0.5 + 1000*frame/fps) -- rounds to the nearest integer local hours = floor(total/(1000*60*60)) local mins = floor(total/(1000*60) % 60) local secs = floor(total/(1000) % 60) local ms = total % 1000 return hours == 0 and string.format("%.2d:%.2d.%.3d", mins, secs, ms) or string.format("%d:%.2d:%.2d.%.3d", hours, mins, secs, ms) end
Masterjun
He/Him
Site Developer, Skilled player (1988)
Joined: 10/12/2010
Posts: 1185
Location: Germany
Why do you make your own round_to_integer function instead of simply
Language: lua

math.floor(number+0.5)
Warning: Might glitch to credits I will finish this ACE soon as possible (or will I?)
1 2 3 4 5 6 7 8 9