also, would you be able to do some more reverse engineering?
I was wondering if we can write values to memory address or registers to trigger the 2p to do a special move?
Since you have a “Flash Kick: [not] ready” check, if we can program the 2p to do a Flash Kick as soon as it’s ready, we can create a training mode to practice safe jump a reversal, etc.
For throw v throw you could just make it a net throw range
077 Ryu
077 Ken
094 Honda Normals
099 Honda Oichio
091 Chun Li
092 Blanka
082 Zangief Normal
082 Zangief Suplex Short/Forward
096 Zangief Suplex Roundhouse
086 Zangief Run Grab Short/Forward
087 Zangief Run Grab Roundhouse
124 Zangief SPD
077 Zangief FAB
076 Guile
087 Dhalsim
071 T. Hawk Normal
106 T. Hawk 360/720
075 Cammy
069 Fei Long
076 Dee Jay
082 Boxer Strong
072 Boxer Fierce
078 Claw
074 Sagat
082 Dictator
077 Akuma
If I have time I’ll ask the author if I can incorporate it or something at some point.
As for reverse engineering the 2p to do a move, that would be extremely over complicated and annoying. Also, the lua library for mame-rr does not include anything for input from a user.
static int doPopup(lua_State *L, const char* deftype, const char* deficon) {
const char *str = luaL_checkstring(L, 1);
const char* type = lua_type(L,2) == LUA_TSTRING ? lua_tostring(L,2) : deftype;
const char* icon = lua_type(L,3) == LUA_TSTRING ? lua_tostring(L,3) : deficon;
int itype = -1, iters = 0;
int iicon = -1;
static const char * const titles [] = {"Notice", "Question", "Warning", "Error"};
const char* answer = "ok";
while(itype == -1 && iters++ < 2)
{
if(!core_stricmp(type, "ok")) itype = 0;
else if(!core_stricmp(type, "yesno")) itype = 1;
else if(!core_stricmp(type, "yesnocancel")) itype = 2;
else if(!core_stricmp(type, "okcancel")) itype = 3;
else if(!core_stricmp(type, "abortretryignore")) itype = 4;
else type = deftype;
}
assert(itype >= 0 && itype <= 4);
if(!(itype >= 0 && itype <= 4)) itype = 0;
iters = 0;
while(iicon == -1 && iters++ < 2)
{
if(!core_stricmp(icon, "message") || !core_stricmp(icon, "notice")) iicon = 0;
else if(!core_stricmp(icon, "question")) iicon = 1;
else if(!core_stricmp(icon, "warning")) iicon = 2;
else if(!core_stricmp(icon, "error")) iicon = 3;
else icon = deficon;
}
assert(iicon >= 0 && iicon <= 3);
if(!(iicon >= 0 && iicon <= 3)) iicon = 0;
#ifdef WIN32
{
static const int etypes [] = {MB_OK, MB_YESNO, MB_YESNOCANCEL, MB_OKCANCEL, MB_ABORTRETRYIGNORE};
static const int eicons [] = {MB_ICONINFORMATION, MB_ICONQUESTION, MB_ICONWARNING, MB_ICONERROR};
int ianswer = MessageBoxA(win_window_list->hwnd, str, titles[iicon], etypes[itype] | eicons[iicon]);
switch(ianswer)
{
case IDOK: answer = "ok"; break;
case IDCANCEL: answer = "cancel"; break;
case IDABORT: answer = "abort"; break;
case IDRETRY: answer = "retry"; break;
case IDIGNORE: answer = "ignore"; break;
case IDYES: answer = "yes"; break;
case IDNO: answer = "no"; break;
}
lua_pushstring(L, answer);
return 1;
}
#else
char *t;
#ifdef __linux
int pid; // appease compiler
// Before doing any work, verify the correctness of the parameters.
if (strcmp(type, "ok") == 0)
t = "OK:100";
else if (strcmp(type, "yesno") == 0)
t = "Yes:100,No:101";
else if (strcmp(type, "yesnocancel") == 0)
t = "Yes:100,No:101,Cancel:102";
else
return luaL_error(L, "invalid popup type \"%s\"", type);
// Can we find a copy of xmessage? Search the path.
char *path = strdup(getenv("PATH"));
char *current = path;
char *colon;
int found = 0;
while (current) {
colon = strchr(current, ':');
// Clip off the colon.
*colon++ = 0;
int len = strlen(current);
char *filename = (char*)malloc(len + 12); // always give excess
snprintf(filename, len+12, "%s/xmessage", current);
if (access(filename, X_OK) == 0) {
free(filename);
found = 1;
break;
}
// Failed, move on.
current = colon;
free(filename);
}
free(path);
// We've found it?
if (!found)
goto use_console;
pid = fork();
if (pid == 0) {// I'm the virgin sacrifice
// I'm gonna be dead in a matter of microseconds anyways, so wasted memory doesn't matter to me.
// Go ahead and abuse strdup.
char * parameters[] = {"xmessage", "-buttons", t, strdup(str), NULL};
execvp("xmessage", parameters);
// Aw shitty
perror("exec xmessage");
exit(1);
}
else if (pid < 0) // something went wrong!!! Oh hell... use the console
goto use_console;
else {
// We're the parent. Watch for the child.
int r;
int res = waitpid(pid, &r, 0);
if (res < 0) // wtf?
goto use_console;
// The return value gets copmlicated...
if (!WIFEXITED(r)) {
luaL_error(L, "don't screw with my xmessage process!");
}
r = WEXITSTATUS(r);
// We assume it's worked.
if (r == 0)
{
return 0; // no parameters for an OK
}
if (r == 100) {
lua_pushstring(L, "yes");
return 1;
}
if (r == 101) {
lua_pushstring(L, "no");
return 1;
}
if (r == 102) {
lua_pushstring(L, "cancel");
return 1;
}
// Wtf?
return luaL_error(L, "popup failed due to unknown results involving xmessage (%d)", r);
}
So there is no way to grab input from users. You can only make popups that can show “Yes”, “No”, “Cancel”, and “Ok”, I could add the library myself to mame-rr and recompile it (adding more lua hotkeys while I’m at it), but it’d be pointless to do so when you can just use:
It’s the same shit Mr. Dhalsim (XSPR) is using in his T.R.U.S.T. program. Why make a character do a special move via hotkey, when you can just program his inputs and press play?
Born2SPD:
I haven’t had time to absorb everything you said, I’m studying for finals this week, but I’ll come back and take a look at some point.
why gief has two numbers next to his move and ken only has one?
what are the differences between these 2 numbers?
OK so XSPR explained macrolua to me
[media=youtube]FiyUIjC8sm4[/media]
so you can program 2p to do a dragon punch.
but let’s say you knock 2p out of a jump attack, how do you use macrolua to tell 2p to do dp at the reversal frame without reading the game state (i.e. dp [ready/not ready])?
i hope you can really figure out how!
[nvm: it’s pretty straight forward i commented them out already. good job creating functions =]
PS. may I suggest we remove (or have an option to disable) the hud highlighted in red?
I use 2P mode to gather more data at the same time. I use the stick for a few attacks and the keyboard for some more. Anyway, I will say I rarely use anything but damage, timer and stun, so those numbers do not get used by me often.
You never use 2P mode just cos you have no friends!
Really great stuff, you guys are geniuses. Good job to Born2SPD for figuring out the “throw constant”, now Akiba’s data is a little easier to understand.
I’m really amazed that each character has a factor that can increase/decrease the opponent’s throw range. It just goes to show you that ST is a very complex, very well designed game.
If anybody can figure out these 2 questions I have, it would be appreciated:
Are the throw ranges measured in pixels?
Why are some meaty normals so hard to reversal throw than others?
I have an incredibly tough time reversal throwing Boxer’s meaty cr Forward and Dictator’s meaty cr Forward, even from point blank range. I don’t really have a problem reversal throwing any other normals after wakeup, but it seems to me like these 2 crouching normals may have a property where they reduce the opponent’s throw range or something. Similar to the “throw constant” mentioned above, possibly for a very short time during the hitting frames.
It may not be that their throw range is reduced or increase, but that some unknown “hitbox” for throws moves back when you do certain normals. How throws are determined is still somewhat of a mystery aside from knowing the range in numbers.
The numbers I have displaying on the screen are not in pixels, although I guess I could make the calculation to translate it to pixels. The numbers displayed are the actual values the game uses to determine where the character is on the stage, not pixels.
Basically you’re repeating what I said in different words. We may not know everything about how throws work in the game, but I wouldn’t call it a “mystery”. So much info has been fleshed out about how throws work in ST over the years, that I think we can say that we have a good grasp of throw knowledge.
It’s obvious that the “throw factor” does reduce/increase throw range depending on which character the opponent is facing. If the opponent’s character is Ryu/Ken/Akuma/Fei, then throw range is not affected. But if it’s anybody else, it’s increased or reduced, and if the opponent is Zangief, then it’s REALLY increased.
This is why Honda is harder to tick with SPD or Typhoon. I’ve noticed that Gief or Hawk players will do less ticks vs Honda compared to other characters. This is so they’re not pushed out too far in order to grab Honda. The reason for this is obviously Honda’s throw factor being a negative number, meaning he decreases the opposing character’s throw range by 1 unit (what their default throw range would be vs Ryu/Ken/Akuma/Fei since those 4 characters have a neutral factor).
Training mode cheat in the works, although it won’t work with the lua script, it needs to be added to the xml cheat file because I have to do writes to the actual ROM to make a jump after the hit stun decrement loop, the lua engine doesn’t have the ability to write to the decrypted CPU instructions memory addresses.
Already tested the jump and it works great, it should refill both players health bars after the hit stun timer decrements all the way, haven’t tested it with throws however, they work differently. Just need to hope that the memory address I’m jumping to doesn’t get written to by the game, so far I haven’t seen it change.
EDIT:
After some testing, it still has bugs, the stun meter is some how affected and can randomly stun so I have to disable stun.
Also, I’m not gonna bother today to find the throw damage subroutine and modify it, so throwing will damage the dummies. I may possibly look into this further to fix the stun, but as of right now, this was a bitch to make to begin with, tracing through literally thousands of cpu instructions and setting breakpoints to find out when the hit stun timer loop ended was time consuming.
Wasn’t fun…well in a weird way it was seeing how the hit stun decremented before the dummy is pushed back…but still
For those interested in the actual workings:
Basically I wrote a memory hook that jumps out of the original code, into my own code and then returns back, so ya…basic memory hook:
Original game code:
04C97C: addq.b #2, ($2,A6)
04C980: rts // Return out of the hit stun timer counter
Modified with a memory hook:
04C97C: jmp $ffffd12.l // This is our spiffy memory hook, jump the PC to the new memory location
FFFFD12: addq.b #2, ($2,A6) // Do the overwritten instruction
FFFFD16: move.b #$90, $ff8479.l // Set P1's life to 144
FFFFD1E: move.b #$90, $ff860b.l // Set P1's Life bar to 144
FFFFD26: move.b #$90, $ff8879.l // Set P2's Life to 144
FFFFD2E: move.b #$90, $ff8a0b.l // Set P2's Life bar to 144
FFFFD36: rts // Return out of the hit stun time counter and everythings back to normal
Only works with mame-rr/mame, not sure how to do ROM address hacks in FBA.
Install:
[LIST=1]
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[]DO NOT UNZIP THE CHEAT.ZIP, LEAVE IT ZIPPED
[*]Place the cheat.zip in the same directory as mame.exe
[*]You have two options to run mame with cheats, either run mame from the command line like this: mame.exe -cheat.
[*]The 2nd option is to open mame-rr.ini and edit the line under ‘Core Misc Options’ that says ‘cheat 0’ and change it to ‘cheat 1’. This is the better option because once you save this file you won’t ever have to edit it again and mame will always run with the cheat option enabled.
[*]Press tab during the game to bring up the mame menu, go to cheats and turn it on or off.
[/LIST]
Stun does not work during the training mode cheat, unfortunately I haven’t fixed that yet. Throws also still do damage in training mode, but this shouldn’t be a problem, just hit the dummy again to refill it’s life. Throw hit stun is also messed up.
fcs-pasky, why are you so awesome? just tested it, works great! i actually dont like dizzy in training mode, perfect!
on a side node, the original mame has all those [easy dragon punch] [easy spd] cheats, do you think you can get some insight from those and see if we can trigger 2p dummy to do reversal dp, etc?
i see in your script you can actually write values to memory addresses (move p1 left 1 pixel)
See those values I’m monitoring in the HUD? All those “easy special” cheats do, is set them to the maximum value (e.g. flashkick to 0x06), so that when you press :u::k: the move instantly comes out without a charge. It doesn’t make them do the special instantly because it still requires the final input (:f::p: for fireball, :k: for hurricane kick etc…)
I told you, if you want a special, use input macro, set a hotkey with it and that will make them dp (after you’ve set it to dp)…
I’ll be writing my own input scroll display sometime next week.
I’ll never go that far in to find the reversal flag and trigger a special on that frame…it’s too annoying to dig through, I have other projects I work on in my free time too (Doing Cadash right now).
You’re just gonna have to deal with using T.R.U.S.T and have it load a save state where the dummy is knocked down and will dp in a pre-determined amount of frames if you wanna practice safe jumps (which i assume that’s what you wanna do). That’s what that program seems designed to do anyways.
If I had the actual game source it’d be easy as hell, good luck getting that.
Auto block is good for seeing which part of a combo you missed. It’s not really necessary in ST.
if you were to do the horizontal scrolling input display, please consider make the icons much smaller.
the current set they have is too big, i barely see all my inputs for 1 SPD.
another reason is that you might need to display 3+ buttons as the same time stacked together, so you’ll need smaller icons anyway.
damn the current vertical icons look so much like sf4 it’s disgusting
its nice to see why i’m getting green hands instead of spd, i pressed the punch just right before i hit up
[PS. for those who don’t know how to create mame-rr.ini, type “mame -createconfig” in the command prompt]
Pasky, please add something to make ST to run in actually 60 fps, u know, no frame skipping, because speed 0 still skips some frames, when u finish the game, u can see how the CPU vs CPU at the ending credits run with no frame skipping, I suppose its like speed -1?