1 button cycles 3 values

Started by strakn, February 11, 2011, 06:57:12 PM

Previous topic - Next topic

strakn

Ok, I have a made a working code that cyles 3 three different float values at one location.
The code cycles the size of a mini map (default value 1.0) between 0.25, 1.0, and 1.5.

I'm looking for some feedback on the method used, and find out if there is maybe a better
way to perform this function.

Map Size Changer:
4E00000C 00000000 # these next four lines do a 1-shot button activator
28200EE0 00008000 # button activator = home key
CC000000 00000001 # credit to dcx2 for the 1-shot code
14000000 00000003
214C84A8 3F800000 # if equal to 1
054C84A8 3FC00000 # change to 1.5
E2100000 00000000 # else
274C84A8 3F800000 # if less than 1
054C84A8 3F800000 # change to 1
E2100000 00000000 # else
254C84A8 3F800000 # if greater than 1
054C84A8 3E800000 # change to 0.25
E0000000 80008000 # end all

toonlink444

It looks good to me. but I am still learning ask dcx2 or Jamesx57(is that how you spell it?)
In the begining there was nothing. Then it exploded
New blog!! Check it out for hacking Smash Bros Brawl!! http://letshackblank.blogspot.com/

dcx2

#2
I think your else lines may be wrong.  I was under the impression that an end-if is required anywhere that you would need a closing brace for an equivalent C++ style if/else requires one end-if (V = 1), but you use V = 0.  And it makes me wonder if I'm using else correctly...most of the time I just use ASM because branches are easier for me to grok.

---

Your last if statement should be unnecessary.

if (map_size < 1.0) { map_size = 1.0; // map_size was 0.25 }
else if (map_size > 1.0) { map_size = 0.25; // map_size was 1.5 }
else { map_size = 1.5; // process of elimination: map_size must have been 1.0 }

EDIT:

Actually, the more I think about it, the more V = 0 makes more sense

kenobi

#3
It's been quite a long time since I've looked into geckoos codes.
However, by looking at my old geckoos code handler source again, I can say the "Else" code is definitly buggy/useless.
Right now :
- If you don't use endif in an else code (like you did), it'll just turn the code status from true to false (which is useless). If the code status is false, it'll do nothing.
- If you use an endif, it'll apply the endif, and then invert the code status, but now that I think about it again that seems kinda useless too.
I guess it was rushed, and not tested it properly back then. Sorry for that.

So it should need either a complete rewriting, but it will increase the code handler size a lot, or just remove it from the code handler.

The final word is, people should stop using the Else code from now on because it's buggy :/ !!!
(but I guess/hope people that tried it saw it was kinda buggy).


However, you'll see you can use other codes type to achieve your goal properly.

Also, instead of using the CC code type, which is really meant for and on/off status, you can use the If...counter code type in your case.

28200EE0 00008000 # home key check
A8000000 00000001 # if counter == 1
80000000 3FC00000 # set gr0 to 1.5
254C84A8 3F800000 # if map size greater than 1
80000000 3E800000 # set gr0 to 0.25
274C84A9 3F800000 # endif/if map size less than 1
80000000 3F800000 # set gr0 to 1
E2000001 00000000 # endif
84200000 814C84A8 # write gr0 to 814C84A8
E0000000 80008000 # end all

(This code is totally untested, written based on the informations about the gecko codes type, so I apoligize if it doesn't work properly).


I'll let you closely examine the codes, so you can understand how they work. Don't hesitate to post any question to have more infos about it.



PS to Link, if you even read this : the description of the If... counter code type in wiird.l0nk.org is messed up. All the codes 2nd part should be "ZZZZYYYY", and not "NM00YYYY".

Deathwolf

Quote from: kenobi on February 13, 2011, 11:02:53 AM
It's been quite a long time since I've looked into geckoos codes.
However, by looking at my old geckoos code handler source again, I can say the "Else" code is definitly buggy/useless.
Right now :
- If you don't use endif in an else code (like you did), it'll just turn the code status from true to false (which is useless). If the code status is false, it'll do nothing.
- If you use an endif, it'll apply the endif, and then invert the code status, but now that I think about it again that seems kinda useless too.
I guess it was rushed, and not tested it properly back then. Sorry for that.

So it should need either a complete rewriting, but it will increase the code handler size a lot, or just remove it from the code handler.

The final word is, people should stop using the Else code from now on because it's buggy :/ !!!
(but I guess/hope people that tried it saw it was kinda buggy).


However, you'll see you can use other codes type to achieve your goal properly.

Also, instead of using the CC code type, which is really meant for and on/off status, you can use the If...counter code type in your case.

28200EE0 00008000 # home key check
A8000000 00000001 # if counter == 1
80000000 3FC00000 # set gr0 to 1.5
254C84A8 3F800000 # if map size greater than 1
80000000 3E800000 # set gr0 to 0.25
274C84A9 3F800000 # endif/if map size less than 1
80000000 3F800000 # set gr0 to 1
E2000001 00000000 # endif
84200000 814C84A8 # write gr0 to 814C84A8
E0000000 80008000 # end all

(This code is totally untested, written based on the informations about the gecko codes type, so I apoligize if it doesn't work properly).


I'll let you closely examine the codes, so you can understand how they work. Don't hesitate to post any question to have more infos about it.



PS to Link, if you even read this : the description of the If... counter code type in wiird.l0nk.org is messed up. All the codes 2nd part should be "ZZZZYYYY", and not "NM00YYYY".

what does the A8 codetype do? is it for geckoregister?
lolz

kenobi

No, A8 code type is a "If... Counter egal" code.
Taken from Wiird Code Database's Gecko Codetype Documentation :

QuoteA80ZZZZT MMMMXXXX

ZZZZ : The code's counter.
Code's Operation : If current execution status is true, increase counter by 1. If it's false, reset counter to 0.
Condition : If ZZZZ and not(MMMM))==XXXX, codes following this are executed (else code execution set to false).
T = 0 : Do Code's Operation, then run Condition.
T = 1 : Apply an Endif, then do Code's Operation, finally run Condition.
T = 8 : Do Code's Operation, then run Condition (and if it is true, reset counter to 0).
T = 9 : Apply an Endif, then do Code's Operation, finally run Condition (and if it is true, reset counter to 0).



It works like this :
As long as the code status is true (ie. as long as the A8 code type is executed), the ZZZZ counter is increased.
ZZZZ is an "internal value", stored inside the A8 code. It should be set to 0000 by the user, and then the geckoos code handler takes care of incrementing/reset it. It's a 16bits value, so once it goes beyond 0xFFFF it'll actually go back to 0x0000.
Then, each time the counter is increased, the geckoos code handler checks if (ZZZZ and not (MMMM))==XXXX. If that's true, the execution status is set to true (and the codes following the A8 code type are executed). If not, the execution status is set to false.
Finaly, if when the A8 code type is reached the execution status is set to false, the counter is reset (set to 0000).

There are different ways of using it, but usually it should be used after a button check (for exemple, "If Home button is pressed"), so I'll assume it's the case in my following exemples :


A8000000 00000001 = executes the codes just once "right away". (note than if you keep the button pressed, the code will be executed again once the code handler has been executed 0x10000 times).

A8000000 0000003C = executes the code once when the counter reaches 60 (0x3C) (in case the geckoos is run every frame, and the game runs at 60fps, it means the codes will be executed after one second of button press).(note than if you keep the button pressed, the code will be executed again once the code handler has been executed 0x10000 times).

A8000008 0000003C = executes the code each time the counter reaches 60 (0x3C). Also, once the counter reaches 60, the counter is reset to 0000, because the T value is 8. (in case the geckoos is run every frame, and the game runs at 60fps, it means the codes will be executed once every second while the button is pressed).

A8000000 FFCF0000 = executes the code "0x40 times", then stops executing is "0x40 times", then execute it "0x40 times"... (0x40 times means during 0x40 code handler execution). That could be useful to simulate an "autoshoot" code, for games that have an "overload" feature (that stops you from shooting if you shoot too many times in the same row ; having the code be turned off during some time will cool down the weapon). I'm sure there could be a lot of other ways to use this.

A8000000 00000000 = Using 0 as the counter check value would be an error, as the counter is first increased, then checked. So, if you put 0, the codes will be executed once each time the counter reaches 0x10000, which should take some time...


PS to James0x57 : The description of the A8 code type in the Wiird Code Database's Gecko Codetype Documentation is wrong. It should be "If ZZZZ and not(MMMM))==XXXX", and not "If XXXX and not(MMMM))==ZZZZ".


Deathwolf

very nice. thanks for explaining kenobi.  ;D

btw maybe this sounds very stupid but are there any other hidden codetypes?
lolz

wiiztec

If there's any code at all that you want to be button activated, or even able to toggle on & off, and I have the game, just PM me and I'll make it happen

Deathwolf

Quote from: wiiztec on February 13, 2011, 03:47:49 PM
It wasn't hidden

I know that thx but maybe there are more codetypes whatever.
lolz

kenobi

As wiiztec said, there are no hidden codetypes, everything is public information.

Learning by looking at what other people do is a good think, and everyone should still look at other people work because they could learn a lot (even me).

However, every "advanced" code hacker (or wannabe advanced) should know (and understand) all the codetypes.

They are avaible here :
http://www.geckocodes.org/index.php?arsenal=1
and here :
http://wiird.l0nk.org/codetypes.html

(both link should have the same information, shown in a different way).

Also, I believe all the links (that are not down) in this topic have useful information.

dcx2

#10
Thanks for clearing up the confusion on the endif + else thing.  And also for the great examples of using the counter if codes.  Remember that it's an if code so it requires endifs.

At 60 FPS, a 16-bit counter will take just over 18 minutes to roll over.

If you had a pattern, you could simplify the code a bit, and make more sizes.  For instance, home key increments size by 0.25, from min 0.25 to max 1.5

28200EE0 00008000 # if home key
A8000000 00000001 # if counter == 1
80000000 814C84A8 # gr0 = 814C84A8
86910000 3E800000 # [gr0] += (float)0.25
254C84A8 3FC00000 # if [814C84A8] > 1.5
054C84A8 3E800000 # [814C84A8] = 0.25
E0000000 80008000 # end all

EDIT:

We can extend this code so that it will increment the map size by 0.25 about once every 64 frames (~1 second at 60 FPS) while the home key is held down.  Set the mask bits of the if counter to 0xFFC0 and the counter will roll over every 64 frames.  If your game is 30 FPS, then use a mask of 0xFFE0 so that it rolls over every 32 frames.  I think this trick only works for rolling over at counts which are powers of 2 (16, 32, 64, 128, etc).

A8000000 FFC00001 # if (counter & 0x3F) == 1; executes about once per second at 60 FPS

EDIT2:

If you want a timeout that's not a power of 2 (like 180 frames instead of 128 or 256), you can get that by adding another line just before the A8 if counter.

AE000008 000000B4 # if (counter < 0xB4) else counter = 0

What this should do is only allow the A8 counter to count for 0xB4 frames.  At this point, the AE code will be false, and it will also reset itself to 0 (T = 8 ).  When the AE code is false, the A8 code will not run and its counter will be reset to 0, too!  Then, during the next frame, both if counters will run again once.


EDIT3: The stuff in EDIT2 was wrong.  I got the functionality of T = 8 backwards.