1 2 3 4
13 14
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
I'm looking at the lua functions, and there's gui.DrawNew(string name). What sort of shenanigans can I do with this?
Adventures in Lua When did I get a vest?
Joined: 3/11/2012
Posts: 149
Location: WI
Pokota wrote:
EDIT: I think I fixed it but I'm not sure why this fixes it - for whatever reason it just fails at drawing images when you use event.onframestart(), but not when you use the old while true do loop method.
I don't know anything about this, having no real knowledge of Lua, so this may seem like a stupid comment, but... OnFrameStart() would imply to me something that happens before the frame is drawn, such that if you draw the frame is going to draw over that afterwards. So you'll get the exact problem you're describing. Not sure if there's any reality to that, but if I were to draw against someone's API I would expect to do it after they do, so they don't draw over me.
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
Pokota wrote:
I'm looking at the lua functions, and there's gui.DrawNew(string name). What sort of shenanigans can I do with this?
I've tried it before when testing functions. I don't even know what it is supposed to do, and it has never worked for me.
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
Pokota wrote:
I'm looking at the lua functions, and there's gui.DrawNew(string name). What sort of shenanigans can I do with this?
It calls "LockLuaSurface()", which is defined at "BizHawk.Client.EmuHawk\DisplayManager\DisplayManager.cs". There are only two available surfaces: "emu" and "native". I've toyed with it only once. Let me try to explain... Suppose you emulating a GameBoy game. Since the 160x144 is very small, you configure the emulator to 3x zoom. Then, for all Lua gui functions, the coordinate system is the emulator one, which is just 160x144. However, if you call DrawNew("native"), all gui functions will now use the native coordinate system, which will be 480x432 (= 160x144 times 3). As I said, I only tried it once, discovered what happened, and never tried again. I don't even know what side-effects it has. I guess one small "issue" to be aware is that the "emu" surface always gets cleared and redrawn on each frame (by the emulation itself), while the "native" surface doesn't. Which means if you draw something on it once, it will stay there until it is overwritten. Again, I'm not 100% sure about it. And I'm not sure how it interacts with other built-in features (such as messages at the bottom, on-screen input indicators and frame counters).
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
Sappharad wrote:
Pokota wrote:
EDIT: I think I fixed it but I'm not sure why this fixes it - for whatever reason it just fails at drawing images when you use event.onframestart(), but not when you use the old while true do loop method.
I don't know anything about this, having no real knowledge of Lua, so this may seem like a stupid comment, but... OnFrameStart() would imply to me something that happens before the frame is drawn, such that if you draw the frame is going to draw over that afterwards. So you'll get the exact problem you're describing. Not sure if there's any reality to that, but if I were to draw against someone's API I would expect to do it after they do, so they don't draw over me.
I tried it with OnFrameEnd() just now and it gives the same problems as OnFrameStart(). What's interesting is that it only happens to drawImage (and maybe drawIcon? I don't know if I tested that or not).
CrazyTerabyte wrote:
As I said, I only tried it once, discovered what happened, and never tried again. I don't even know what side-effects it has.
Adding gui.DrawNew("native") as the first line of main() in my zelda 2 script leads to this: Amusing, but not expected. And not particularly helpful for replacement ui shenanigans, but probably good for popup messages and the like. EDIT: And the duplication turns out to be because I didn't clear the lua session properly. So bluh there. Also using Native and not having the client window match the game resolution/aspect ratio is a good workaround if you need more space than you've got.
Adventures in Lua When did I get a vest?
Joined: 5/19/2015
Posts: 3
-deleting-
Amaraticando
It/Its
Editor, Player (158)
Joined: 1/10/2012
Posts: 673
Location: Brazil
Damn, this gui.DrawNew("native") makes the gui.drawText look decent and work in the lateral black space. However, it makes the emulator quite slow. To me, it goes from 50-ish fps to 35...
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
Amaraticando, what are you working on and does it still go slowly at a simple 1x or 2x size?
Adventures in Lua When did I get a vest?
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
waterise wrote:
Basically: How do I code a Twitch bot that receives commands from a Java bridge and then posts in the Channel chat based on the commands it receives?
EDIT: I was wrong about writing to files. See the message(s) just after this one. AFAIK, there is no Lua binding in BizHawk to communicate with the outer world. So, it is impossible to write to files or to sockets. Solution for this? Maybe propose a good API for a new Lua module, and even implement it in BizHawk. The only I/O it seems to have is capturing screenshots or savestates, which can optionally take a pathname. So, as a very very very ugly workaround, you could write some kind of code outside BizHawk that monitors a specific directory for new files, and then you use your Lua script inside BizHawk to write savestates or screenshots with specific filenames. That would be a very hacky way to do one-way communication from BizHawk Lua to the outer world. Have I already told you it is very ugly? Other than that awful workaround, I'm afraid you need to modify BizHawk itself. Either to implement a new API, or maybe to make "console.write" write stuff into your JavaBridge (in addition to the console screen).
AntyMew
It/Its
Encoder, Player (35)
Joined: 10/22/2014
Posts: 425
CrazyTerabyte wrote:
AFAIK, there is no Lua binding in BizHawk to communicate with the outer world. So, it is impossible to write to files or to sockets.
Vanilla lua can write files using its io library
Just a Mew! 〜 It/She ΘΔ 〜
Amaraticando
It/Its
Editor, Player (158)
Joined: 1/10/2012
Posts: 673
Location: Brazil
Pokota wrote:
Amaraticando, what are you working on and does it still go slowly at a simple 1x or 2x size?
I'm working on a Super Mario World script. In fact, if the size is 1,the slowdown is small. However, there's no way to show all the info in such a small resolution. In higher sizes,the slowdown is very noticeable. Therefore, I'll have to accept that and include less functionality than the lsnes script... :(
CrazyTerabyte
He/Him
Joined: 5/7/2005
Posts: 74
Anty-Lemon wrote:
Vanilla lua can write files using its io library
Thanks for pointing it out! I just tried and indeed the "io" module is available within BizHawk, and I could write a file using Lua. Today I learned that I can inspect all available modules by just looking at the symbols from the "_G" variable.
waterise wrote:
That message (console output) gets pushed through a LuaSocket, then to some Java bridge (which connects with the chat bot)
On Linux or most unixes, it is easy to create a "named pipe", or a "socket" file, which allows writing to it using like if it was writing to any file. So, for Linux or unixes, probably you don't even need LuaSocket. On Windows, however, I don't believe there is such thing (feel free to prove me wrong!); which means you need to add the LuaSocket C code into BizHawk before you can use LuaSocket. At least that's where I would start.
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
Amaraticando wrote:
Pokota wrote:
Amaraticando, what are you working on and does it still go slowly at a simple 1x or 2x size?
I'm working on a Super Mario World script. In fact, if the size is 1,the slowdown is small. However, there's no way to show all the info in such a small resolution. In higher sizes,the slowdown is very noticeable. Therefore, I'll have to accept that and include less functionality than the lsnes script... :(
It's dreadfully resource-intensive. I was averaging 55 fps at 4x size, so machine power is going to be a factor with this one. It looks like it'd be very useful for shenanigans though, just not as much for general play.
Adventures in Lua When did I get a vest?
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
Hm. Seems that gui.DrawNew("native") is rather interesting. (gui.DrawNew("emu") is default, so it doesn't do anything new). Apparently, gui.DrawNew("native") not only can draw in the black space around the emulated system's screen, but all drawings persist there even if the script advances a frame or is turned off. The only way I know to clear the drawings is to call gui.DrawNew("native") each time. Also, frame advances automatically switch the mode back to "emu". So the question of being able to draw in the black space is pretty much solved now. By the way, there are a few extra gui methods that don't even appear in the documentation. They are: gui.defaultForeground(color), which sets the default drawing color for drawing methods, gui.defaultBackground(color), which sets the default fill color for drawing methods, and gui.createcanvas(width,height), which, despite being in the code, doesn't even work.
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
FractalFusion wrote:
gui.createcanvas(width,height), which, despite being in the code, doesn't even work.
If only I could create a canvas on a form box, that would solve so many of my projects.
Adventures in Lua When did I get a vest?
Player (142)
Joined: 7/16/2009
Posts: 686
FractalFusion wrote:
gui.createcanvas(width,height), which, despite being in the code, doesn't even work.
I'm going to out on a limb and guess that you're using 1.9.4 or earlier, in which case: of course. You're looking at the most recent code but using a release that was built from older code. If you've compiled the code yourself it should just work, and you're free to ignore what I said.
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
This was less a deliberate thing and more me getting used to manipulating the console and switching memory domains on the fly.
Language: lua

-- "Megaman Battle Network 2" -- This just generates a strobe effect powered by the RNG in the upper left corner. local rngvalue local EWRAM = "EWRAM" function strobe() memory.usememorydomain(EWRAM) local color = memory.read_s32_le(0x9080) local invert = color * -1 gui.drawBox(0,0,3,3,color,invert) end while (true) do strobe() emu.frameadvance() end
Adventures in Lua When did I get a vest?
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Can someone please help me? This code won't run, but I'm not sure what I did wrong:
memory.usememorydomain("Combined WRAM")
while true do
gui.drawText(3,3,"State: "..memory.readbyte(0x03A5B2).."("..memory.readbyte(0x03A5AE)..")")
end
Even removing the first line freezes BizHawk regardless.
mz
Player (79)
Joined: 10/26/2007
Posts: 693
You need to add emu.frameadvance() or something similar inside that loop.
You're just fucking stupid, everyone hates you, sorry to tell you the truth. no one likes you, you're someone pretentious and TASes only to be on speed game, but don't have any hope, you won't get there.
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
Pokota
He/Him
Joined: 2/5/2014
Posts: 778
I generally only use the while true do loop when I have reason to put images on the canvas; for anything other than that (text and simple vector draws) I stick with calling my main function via onframestart. As an example, my strobe function above could be rewritten as
Language: lua

-- "Megaman Battle Network 2" -- This just generates a strobe effect powered by the RNG in the upper left corner. local rngvalue = 0x9080 local EWRAM = "EWRAM" function strobe() memory.usememorydomain(EWRAM) local color = memory.read_s32_le(rngvalue) local invert = color * -1 gui.drawBox(0,0,3,3,color,invert) end event.onframestart(strobe)
and it still works the same. The onframestart/onframeend methods do not play well with drawIcon and drawImage though (this is true as of 1.9.4, haven't tried breaking this with the new version yet)
Adventures in Lua When did I get a vest?
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
How does joypad.set work? I tried this:
memory.usememorydomain("Combined WRAM")
local p = memory.readbyte(0x03A54E) -- your position
local t1 = {[1]=0x03A5B6,[2]=0x03A61E,[3]=0x03A686,[4]=0x03A6EE,[5]=0x03A756} --stick positions

function Joy(button)
  joypad.set({button = true},1)
end

function move(d,a)
if (d == true) then
	if (a == 4) and (p == 1) then
		Joy('Left')
	elseif (a == 4) and (p == 2) then
		Joy('A')
	elseif (a == 12) and (p == 0) then
		Joy('Right')
	elseif (a == 12) and (p == 2) then
		Joy('B')
	elseif (a == 18) and (p == 1) then
		Joy('Left')
	elseif (a == 18) and (p == 0) then
		Joy('A')
	end
end
end
while true do
	for i = 1, 5 do 
		if (memory.readbyte(t1[i]+2)<=0x10) then
			if (memory.readbyte(t1[i]) == 4) or (memory.readbyte(t1[i]) == 12) or (memory.readbyte(t1[i]) == 18) then
				move(true,memory.readbyte(t1[i])) end
		end
	end
	emu.frameadvance()
end
and it doesnt give an error nor does it do anything. Setting it to joypad.set({Left = true},1) results in similar nothing happening. Edit: I also checked if the script ever reaches the joypad part, and placing gui.text under there for debug shows that it does. Not sure why won't joypad work.
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
Some systems like GBA and GB do not use numbered controllers. It must be specified as
joypad.set({button = true})
without any controller number. To check, go to Config -> Controllers ... . If it does not specifically say Player 1, etc., then it does not use numbered controllers.
Skilled player (1706)
Joined: 9/17/2009
Posts: 4952
Location: ̶C̶a̶n̶a̶d̶a̶ "Kanatah"
FractalFusion wrote:
Some systems like GBA and GB do not use numbered controllers. It must be specified as
joypad.set({button = true})
without any controller number. To check, go to Config -> Controllers ... . If it does not specifically say Player 1, etc., then it does not use numbered controllers.
I checked. It doesn't. But even after changing the code to this: http://pastebin.com/0eEhyNqW No input is ever set even if the statement was reached: http://i.imgur.com/SZ192E3.png
Editor, Skilled player (1938)
Joined: 6/15/2005
Posts: 3246
jlun2 wrote:
But even after changing the code to this: http://pastebin.com/0eEhyNqW No input is ever set even if the statement was reached: http://i.imgur.com/SZ192E3.png
The line that says
joypad.set({left = 1}) 
should be
joypad.set({Left = true}) 
instead.
1 2 3 4
13 14