Code with Gecko Registers

Started by goemon_guy, December 22, 2010, 11:25:01 PM

Previous topic - Next topic

goemon_guy

Ok, so I was trying to make a code using Gecko registers, to cycle through the item values of slot 1 to change the item, and its quantities. I managed to do it, but when I press the buttons to change the value, they change too quickly.

So, my question is :
Is there a way to make it so that the button activator only changes the value once per time that it is pressed?

Example:
The original value is 01.
I press it, it changes to 02.
I continue to hold the button, and it remains 02.
I release, and press again, and it elevates by 01 again to 03.
etc.
-Currently hacking the following game(s):
...
Request a code via PM, if you wish.

Nutmeg

Okay, so here is your button activator: 28XXXXXX YYYYYYY
Under that, you need to put a second if (preferably 'if !=') statement to continue.

It will look like this:
28XXXXXX YYYYYYYY
22001550 00000001
04001550 00000001
Insert the code you want to activate here
E0000000 80008000  //full terminator to end both if statements.  If your code does not use a pointer, there is a better way to do this.
2AXXXXXX YYYYYYYY  //This is the same as the first activator except with an 'if !=' codetype
04001550 00000000  //sets the 'if !=' address back to default, which is 0.
E0000000 80008000  //full terminator

So, here is the code:

28XXXXXX YYYYYYYY
22001550 00000001
04001550 00000001
insert code here
E0000000 80008000
2AXXXXXX YYYYYYYY 
04001550 00000000
E0000000 80008000

Where X and Y values are equal for both button activators.

I'm inbetween your legs... that's not awkward.

Romaap

I used this in one of my codes:

82000000 80313FD9  //load the address in gecko register
28319DEA 00000800  //button activator
A8000000 F0000000  //counter (which keeps on counting to a really high number while the button is pressed)
86000000 00000001  //increase the gecko register
84000000 80313FD9  //write the gecko register back to the address
E0000000 80008000  //full terminator


The "A8000000 F0000000" after the button activator causes the code handler to wait until the buttons are released, then it writes the value to the address.
This simulates a 'once per press'.

Thomas83Lin

#3
I use Special Button activators to solve this problem in my codes, that execute only once per button press. But that's a little hard to explain without posting a video. I like romaap's suggestion though, your better off using that.

edit:
I'll try to explain it
What i mean by special is that they are only in memory for like a mil sec. they are normally found around regular button activators, but you'll have to hit the button really fast to see them in the mem viewer. using these also eliminates the need for masking since they register every button separately. These activators are only good for selector codes since they will only execute once per button press. but one downside to using these is that you can't combine buttons in your code since they register every button separately    

In Newer Mario Bros USA Check this address Wiimote Pad 1 803A1ACC (This is the button activator address i used in my transformation code.)

for a example of a Special Activator, at first it will look like its doing nothing when a button is hit, but if you hit the button really fast you'll eventually see it, notice how it is right next to a regular activator. every single game i've have seen has this; if you dont find it on your first activator try the next you'll eventually run across it. I've used this trick for every single Item Selector Code that i've done.

dcx2

There are several ways to do this, each with their own merits and flaws.

Romaap has suggested a generally good solution.  It uses the counter code types; after the code executes, it will not run again until the counter resets.  Unfortunately, if you hold the button down long enough, you will get a second execution, which is not consistent with what you wan.  However, in practice you can make the counter so large that you pretty much only ever move by one, unless you sit there and hold the button in forever...

I like thomas83lin's solution, when it works.  There are what I call "delta activators", where delta means change.  The game runs in frames, right?  The frame that a button becomes pressed, an address in memory right after the regular button activator address will have a 1.  After the frame ends, that value is set to 0 again, which is why no one finds it using the search.  When the button is released, another address after the button activator becomes 1.

I call the usual button activator address the "state activator", since it knows the current state of the button - up or down.  The other ones are "press activators" and "release activators".  The problem is that the code handler can run more than once per frame for some games, depending on the hook!  So press activators won't always work, or they'll sometimes work.  When these don't work, Romaap's solution is good.

You could also use the CC code type with the 4E code type to make a "one shot", although this approach is a bit awkward.  You could also use ASM; store the value of the buttons from the last execution and calculate your own press activator, which would always work no matter how often the code handler runs.

Thomas83Lin

#5
Quote from: dcx2 on December 23, 2010, 04:48:18 AM
I like thomas83lin's solution, when it works.  There are what I call "delta activators", where delta means change.  The game runs in frames, right?  The frame that a button becomes pressed, an address in memory right after the regular button activator address will have a 1.  After the frame ends, that value is set to 0 again, which is why no one finds it using the search.  When the button is released, another address after the button activator becomes 1.
Yes this is how it works except instead of holding just 1 it does hold the full button value, but only for like a frame I'm truly not sure on how many frames. I don't know how to test that, but the code will only execute once.

Quote
I call the usual button activator address the "state activator", since it knows the current state of the button - up or down.  The other ones are "press activators" and "release activators".  The problem is that the code handler can run more than once per frame for some games, depending on the hook!  So press activators won't always work, or they'll sometimes work.  When these don't work, Romaap's solution is good.
This is something i will keep in mind when testing. Thanks, I actually haven't run across this problem yet but i do see how it could happen.
EDIT:
Yes i just tested this in Mario Kart, using ossleepthread, I'll need to add afew checks i guess.lol So my thinking is using romaap method together with the delta activator should be perfection. 

Quote
You could also use ASM; store the value of the buttons from the last execution and calculate your own press activator, which would always work no matter how often the code handler runs.
Now this is something i would be interested in.

dcx2

When I say "1", I mean in the binary sense, meaning that one of the bits is set.  If you want to see things from the code handler's perspective with Gecko.NET, make sure BPNext is checked on the About tab.  Then, go to the button activator address in memory.  Press Pause.  Then press Next repeatedly.  While spamming Next, press a button on the Wiimote and you'll see the bits pop up briefly.

If you're using non-ASM code types, then the CC/4E technique is probably better.  X is the button activator address, Y is the button value, M is the mask, ... is whatever code you want to run only once per press.

4E00000C 00000000
28XXXXXX MMMMYYYY
CC000000 00000001
14000000 00000003
....
E0000000 80008000

The ASM code would be harder, because you'd have to do ASM button activators and you'd need somewhere to store the old button values at, which means using a gecko register or using the bl trick.

Thomas83Lin

Thank you will do, Most of my Asm codes dont seem to suffer from this, but my standard Gecko Register ones do. But i just tried your Method it works like a charm with both Hook Types,  Ossleepthread really has its way with some of my codes. I'm surprised i've never tested this before, or that no one has complained.

dcx2

C2 codes don't run with the code handler, so hook type has no effect on them and that's why you don't usually have a problem.  C0 codes would have the same problem that regular code types have, because the C0 hooks the code handler.

I also prefer C2 codes because you can find a hook that only runs at certain times e.g. in a menu or on the battlefield.  So the button combination won't *always* run, which can actually be troublesome sometimes.

Thomas83Lin

Gotcha, I managed to fix all of my codes that were effected by this.

goemon_guy

Thanks for all the help! I ended up using Romaap's suggestion, and it worked greatly. ;)
-Currently hacking the following game(s):
...
Request a code via PM, if you wish.