Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I'm thinking input.getmouse could be used in, for example, the NES storybook, such as Deja Vu and Shadowgate. I'm thinking about making a script such that you can use the mouse to play these game. In this case mapping X and Y to NES pixels rather than screen pixels is a lot better, since the command boxes have fixed positions on the NES game screen, but if X and Y refer to screen X and Y, the position of the boxes change if I move the Bizhawk window around. I hope that made sense.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I have some thoughts on the input.getmouse() implementation:
1. Right now the tables X and Y give the mouse X and Y position for the screen rather than the emulator window. I think it would make more sense to return the X and Y pixel position of where on the Bizhawk window your mouse is positioned. Thoughts on this?
2. All logical tables seem to always be true. Consider the lua script
while true do
m=input.getmouse()
if m.Left then
gui.text(10,40,"Left is pressed")
else
gui.text(10,40,"Not pressed")
end
emu.frameadvance()
end
This will always display "Left is pressed" even when you don't do anything with the mouse.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Maybe I'm not the best person to answer this (in particular because I haven't used lua in a PSX emulator), but I'll try to give some help:
Note that since I'm not familiar with PSX lua scripting, you might need to tweak my syntax a bit to get it to work.
Do you mean that you want to update the displayed values only when they change, but display them every frame? If so, we can construct new variables, called stepid_disp, danger_disp, ..., that only update each time fieldid changes.
I think this can be accomplished by a counter that checks if StepID changes on each frame, and if so increase this counter by 1. This counter could then be reset each time FieldID changes.
This is at least possible in lua scripting for FCEUX, BizHawk and SNES9X, and I've used this command before. If it's the same syntax here, I can help out.
So, here's my quick attempt at making a complete lua script that does all the above. I have added comments here and there to help you understand what's going on. As I said before, you'll probably need to tweak a few things to get the syntax right.
--create the "display" variables. These will be used to display values when FieldID changes
stepid_disp=memory.read_u8(0x0009C540)
danger_disp=memory.read_u16_le(0x0007173C)
fraction_disp=memory.read_u8(0009C6D8)
offset_disp=memory.read_u16_le(0009AD2C)
timer_disp=memory.read_u16_le(0009D264)
--previous fieldId value
fieldid_old=memory.read_u16_le(0009A05C)
--open up text file results will be dumped to. this text file should appear in your emulator folder
myfile1 = io.open("ff7_results.txt", "w")
--write text file header (tab separated)
myfile1:write("FieldID")
myfile1:write("\t")
myfile1:write("StepID")
myfile1:write("\t")
myfile1:write("Danger")
myfile1:write("\t")
myfile1:write("Fraction")
myfile1:write("\t")
myfile1:write("Offset")
myfile1:write("\t")
myfile1:write("Timer")
myfile1:write("\n") --do not forget newline!
--text coordinates for displaying values on screen
x0=10 --x coordinate
y0=40 --y coordinate
dy=16 --pixels between each line
stepid_changes=0 --counter for stepID changes
stepid_old=memory.read_u8(0x0009C540) --stepID value the previous frame
while true do --main loop, executed once per frame
--read in the values for this frame
stepid=memory.read_u8(0x0009C540)
danger=memory.read_u16_le(0x0007173C)
fraction=memory.read_u8(0009C6D8)
offset=memory.read_u16_le(0009AD2C)
fieldid=memory.read_u16_le(0009A05C)
timer=memory.read_u16_le(0009D264)
if fieldid ~= fieldid_old then --when FieldID is not equal to its value the previous frame
--reset stepid_changes, because we are in a new fieldID
stepid_changes=0
--update the "disp"-variables
stepid_disp=stepid
danger_disp=danger
fraction_disp=fraction
offset_disp=offset_disp
timer_disp=timer_disp
--also, dump to text file
myfile1:write(fieldid)
myfile1:write("\t")
myfile1:write(stepid)
myfile1:write("\t")
myfile1:write(danger)
myfile1:write("\t")
myfile1:write(fraction)
myfile1:write("\t")
myfile1:write(offset)
myfile1:write("\t")
myfile1:write(timer)
myfile1:write("\n") --do not forget newline!
end
--display the disp variables
gui.text(x0,y0+0*dy,"FieldID: " .. fieldid)
gui.text(x0,y0+1*dy,"StepID: " .. stepid_disp)
gui.text(x0,y0+2*dy,"Danger: " .. danger_disp)
gui.text(x0,y0+3*dy,"Fraction: " .. fraction_disp)
gui.text(x0,y0+4*dy,"Offset: " .. offset_disp)
gui.text(x0,y0+5*dy,"Timer: " .. timer_disp)
if stepid~=stepid_old then --if stepid has changed, increase counter by 1
stepid_changes=stepid_changes+1
end
gui.text(x0,y0+7*dy,"StepID changes: " .. stepid_changes)
--create the variables holding values for the previous frame
fieldid_old=fieldid
stepid_old=stepid
emu.frameadvance() --frame advance
end
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I usually TAS 2 player games like this: I have a gamepad that controls player 1, and the keyboard controls player 2 (or the other way around). It's usually possible to hold down buttons both on the gamepad and the keyboard, and press frame advance. You'll have to stretch your fingers a bit, but it can be done.
If you don't TAS with a gamepad, it might be possible to control both of them with the keyboard, if you assign the buttons with some care, so that you can stretch your fingers to the necessary positions.
If the 2 players' inputs are independent, you could record them separately, and then splice them together into one input file, if you're comfortable doing these kind of things.
Another, more sophisticated but more time consuming, way is to have a lua script running in the background that controls one of the players. This is how I've TASed many rooms in Goof Troop. I have a lua script running in the background that controls one of the players, recording button press with the joypad.set command, while I record input with the other player in the normal way. The good thing about this solution is that it rules out the possible of pressing the wrong buttons, which is quite possible given that you're pressing many buttons all at once.
I think most TASers will agree that doing a 2 player TAS is a lot trickier than doing a 1 player TAS, and there are several ways of doing it. I'm sure other TASers here use their own ways of recording input for two players.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Sorry for the late reply, but thanks a lot scaryice, I managed to get this to work. Just like you said, the trick is to get hit on the very edge of the water square, which can be done by jumping up in the air and getting hit right as you land. Thanks again!
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Hi, I've been working on this game for some days now (I wanted something nice and simple to TAS) and finished my first version of a complete TAS yesterday. For reference, here is Dacicus' published TAS:
http://tasvideos.org/1050M.html
The userfile page is not working for me right now (and microstorage doesn't accept .bkm movies), so I've uploaded the movie file to mediafire here:
http://www.mediafire.com/?bqhbx4r921xtk8c
I used the interim version of Bizhawk 1.3.0, but it synchs with 1.2.0 as well.
This movie is about 16 seconds faster than the published movie. There are some new tricks scattered throughout the run, as well as some faster boss fights. Having the RAM addresses for health and position of enemies helped out a lot.
Some notes that might interest you:
*There is a 5 frame timer that determines how many frames you stay on the ground before jumping. This address changes like this: 5,4,3,2,1,5,4,3,2,1. Its value is the number of frames you pause before jumping up in the air, so you want to jump when this has value 1. Its value changes when you walk, rather than each frame.
I've found a failsafe way to be able to jump any frame you want, though it costs 3 frame. Crouch-walk forward, and when you want to jump, release all buttons for 1 frame, and then perform the jump. By releasing all buttons from crouching position, this timer will be set to 1. This trick costs 3 frames to perform, but it is a safe way to be able to perform a jump at any time without having to wait for up to 5 frames.
*Your attacks deal 1 damage per frame they are in contact with an enemy. Because of this, your attacks can differ quite a lot in damage. Bosses are killed faster in this run because I tried to optimize the damage dealt by each of my attacks. High swings deal the most damage (up to 10), normal attacks deal up to 7 damage, and crouching attacks deal up to 5 damage, depending on how long they are in contact with the enemy.
I'm posting it here rather than submitting it both because I want to hear if anyone has any ideas for new tricks or strategies, and also because I suspect there are more frames that can be squeezed out. In particular, I want to understand how enemy spawning works, because some enemies can be manipulated out of existence.
EDIT: I managed to upload the movie file to my userfiles here at TASVideos:
http://tasvideos.org/userfiles/info/3609930750110778
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I get an error when I try to upload a certain .bkm file to my userfiles page. I get the error:
<<< Can't parse movie (error from format parser) >>>
Errors from the movie parser:
error_handler:
errstr=Division by zero
errfile=/home/tasvideos/public_html/formats/bkm.php
errline=77
The movie file isn't broken, I've played it back in several versions of Bizhawk without any problems.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I don't know if this is a bug or intentional, but I've found something weird (and slightly annoying) with the RAM search:
Any 2 byte values that start on an odd address don't show up in the RAM search. For example, the 2 byte RAM address for EXP in Seiken Densetsu 3 is 1EDFF to 1EE00 (little endian). This value can not show up in the RAM search, since it only looks for values that start on an even address, so it checks 1EDFE to 1EDFF and 1EE00 to 1EE01, but misses out on all potential values that start on an odd number.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Two friends go down to the horse track and bet on a horse. Once the race has started, the horse they bet their money on starts to fall behind. Suddenly, one of the friends starts flailing his arms and leg, moving around, yelling out random words and kicking around stuff on the ground. The other friend looks alarmed and asks:
"What the heck are you doing??"
"Oh, don't worry, I'm just manipulating luck!"
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
Hi, I'm trying to play the SNES game Seiken Densetsu 3 on BizHawk, but it keep changing aspect ratio to widescreen, from 256*224 to 512*224, whenever a dialogue box pops up.
Example:
No text box: http://i49.tinypic.com/vsjqqd.png
With text box: http://i49.tinypic.com/1oxis3.png
Is there any way to "force" Bizhawk to keep the resolution to the normal 256*224, so it doesn't keep changing to widescreen whenever there's a dialogue box? If there isn't, I think it could be a nice feature to have.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
scaryice: do you know how those tricks work, i.e. how you are able to walk on water/air directly after taking damage? Are there any specific RAM addresses you need to keep an eye on, or a specific frame window when this can be pulled off? Any details on how this is done would be helpful! Input files are also welcome, if you still have them.
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
The lua command joypad.set is not working correctly: consider, for example, the following (simple) script:
while true do
mf=emu.framecount()
key1={}
if math.mod(mf,4)==0 then key1.Start=1 end
if math.mod(mf,4)==1 then key1.Select=1 end
if math.mod(mf,4)==2 then key1.B=1 end
if math.mod(mf,4)==3 then key1.A=1 end
joypad.set(key1,1)
emu.frameadvance()
end
This should press Start, select, B and A, in that order (which is what it does in FCEUX), and never two buttons at the same time. However, when running this in the latest version of Bizhawk, the input registered seems quite random, and often more than one button is pressed at the same time.
Oh, and while I'm here, I'm still having problems with the gui.drawImage command, though admittedly this might be something I'm doing wrong. What I'm trying to do is display an image with this code:
but nothing happens - the code passes without an error, but nothing is displayed. Is my syntax wrong, or is the command broken? I've looked at the Lua functions page but didn't get any wiser. Any help is very welcome!
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
I made a Pitfall TAS, partly to try out TASing on BizHawk, but also simply because I felt like it could be fun.
I aimed for highest score, 114 000, and no deaths, while getting an as good (in game) time as possible. I finish the game with 1:34 left on the timer.
The game is quite slow and not very exciting in my opinion... It is very easy (and quite fun) to TAS, so I think it's quite a good game for beginners to try out on. Everything in this game is based on global timers, so no fancy features like RNG in this game. And this game is also too cool to have an ending, so it just stops after you get the last treasure.
I made maps, planned the route in detail, dissected all the object timers and such, so I had quite fun making this.
Here's the movie file:
http://tasvideos.org/userfiles/info/2039595497723066
I would be interested in hearing if anyone else has TASed this game, and if so, how their TAS compares to mine.
I'm having serious doubts about this game quality when it comes to getting published... I think you can watch this in 200% speed (or even higher) without missing anything. Though I think (and hope) that some of you might enjoy this run purely for nostalgia's sake, and perhaps if you are interested the fastest route to get a perfect score in this game.
Oh, and any encoder is very welcome to encode this run.
Enjoy!
Experienced Forum User, Published Author, Skilled player
(1890)
Joined: 4/20/2005
Posts: 2160
Location: Norrköping, Sweden
The youtube user "tasvideosrandil" is me, by the way. I'm glad you liked it. :)
If you're serious about making a Star Force TAS I can share what I have (input file, RAM addresses, etc.).
EDIT: I found now that I already my a post about it in the original Star Force thread:
http://tasvideos.org/forum/viewtopic.php?p=234352#234352
A moderator might want to merge these threads.