Jul 15, 2011 at 7:58 PM
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: Jan 28, 2010
Location: Internet
Posts: 1369
Age: 34
LunarSoul said:
No problem, always happy to help!

EDIT: Does anyone know how to run code when a key is pressed? I know there's a "key pressed" offset or something, and a table with the different keys, but are there certain things you need to do, like JMP to an offset (like JMPing to the beginning of the TSC parser after a command)? I want to add a gimmick to the "C" key. I think we're doing it for the deity project as well.

All you need to do is check if a key exists via ANDing (or even CMPing is technically possible for single-keypresses) on the offsets [49E210] and [49E214] at any point while the game is running.

In the Compendium, here's the keypressed table:

ANDing by the key_held or key_pressed offsets....:
0x000001 Left Arrow
0x000002 Right Arrow
0x000004 Up Arrow
0x000008 Down Arrow
0x000010 Show Mini-Map
0x000020 Shoot
0x000040 Jump
0x000080 Next Weapon
0x000100 Previous Weapon
0x000200 Shift
0x000400 F1
0x000800 F2
0x001000 Status/Menu Screen
0x008000 Escape
0x010000 "," Comma
0x020000 "." Period
0x040000 "?" Question Mark
0x080000 "L" The Letter L
0x100000 "=" Equal

And here are the offsets:

0049E210 Key_Held See Key Table.
0049E214 Key_Pressed See Key Table.
0049E218 LastKeyHeld

Now, I'm really too lazy to give a full explanation, so I'll give an example of a hack that lets you check for keypresses in TSC. I used this in my mod "The Witching Hour" to create a custom options menu for the player.

Basically, this command "gets" whether a keypress matches the the four-digit TSC number XXXX and jumps to event YYYY if true. Hopefully you'll be able to make sense of this:

Code:
=========== Carrotlord's <GET keypress hack ===========
[ How to use it ]
<GETXXXX:YYYY

If keypress X is held, then jump to TSC event Y. Otherwise, continue the code (much like <FLJ continues if flag is not set).

======= TSC Part
#0402                   ;call TSC event 402 using a Horizontal trigger that you can jump through repeatedly.
<WAI0070<GET0008:0500
<GET0001:0501
<GET0002:0502
<GET0004:0503
<GET0016:0504
<GET0032:0505
<GET0064:0506
<KEY<MSGNo checked keys are held.<NOD<END

#0500
<KEY<MSGDown key is held.<NOD<CLO<EVE0402

#0501
<KEY<MSGLeft key is held.<NOD<CLO<EVE0402

#0502
<KEY<MSGRight key is held.<NOD<CLO<EVE0402

#0503
<KEY<MSGUp key is held.<NOD<CLO<EVE0402

#0504
<KEY<MSGMap key is held.<NOD<CLO<EVE0402

#0505
<KEY<MSGAttack key is held.<NOD<CLO<EVE0402

#0506
<KEY<MSGJump key is held.<NOD<CLO<EVE0402

========= The assembly part
CPU Disasm
Address   Hex dump          Command                                  Comments
00424EAF     \E9 C8590100   JMP 0043A87C                             ; JMP to <GET command

CPU Disasm
Address   Hex dump          Command                                  Comments
0043A87C  /> \A1 D85A4A00   MOV EAX,DWORD PTR DS:[4A5AD8]
0043A881  |.  0305 E05A4A00 ADD EAX,DWORD PTR DS:[4A5AE0]            ;set up Scriptcheck
0043A887  |.  0FBE48 01     MOVSX ECX,BYTE PTR DS:[EAX+1]            ;G
0043A88B  |.  83F9 47       CMP ECX,47
0043A88E  |.^ 0F85 9FA6FEFF JNE 00424F33
0043A894  |.  0FBE48 02     MOVSX ECX,BYTE PTR DS:[EAX+2]            ;E
0043A898  |.  83F9 45       CMP ECX,45
0043A89B  |.^ 0F85 92A6FEFF JNE 00424F33
0043A8A1  |.  0FBE48 03     MOVSX ECX,BYTE PTR DS:[EAX+3]            ;T
0043A8A5  |.  83F9 54       CMP ECX,54
0043A8A8  |.^ 0F85 85A6FEFF JNE 00424F33                             ;jump to <GIT command if unsuccessful
0043A8AE  |.  8B15 E05A4A00 MOV EDX,DWORD PTR DS:[4A5AE0]
0043A8B4  |.  83C2 04       ADD EDX,4                                ;otherwise, get the first parameter
0043A8B7  |.  52            PUSH EDX                                 
0043A8B8  |.  E8 4370FEFF   CALL 00421900                           
0043A8BD  |.  83C4 04       ADD ESP,4
0043A8C0  |.  3905 10E24900 CMP DWORD PTR DS:[49E210],EAX       ;compar Param1 with KeyHeld.
0043A8C6  |.  74 0C         JE SHORT 0043A8D4                   ;if that key is Held, then goto A
0043A8C8  |.  8305 E05A4A00 ADD DWORD PTR DS:[4A5AE0],0D        ;otherwise, fix the scriptPosition
0043A8CF  |.^ E9 D3A9FEFF   JMP 004252A7                        ;jump back
0043A8D4  |>  8B15 E05A4A00 MOV EDX,DWORD PTR DS:[4A5AE0]       ;LABEL A
0043A8DA  |.  83C2 09       ADD EDX,9                           ;get the second Parameter
0043A8DD  |.  52            PUSH EDX
0043A8DE  |.  E8 1D70FEFF   CALL 00421900
0043A8E3  |.  83C4 04       ADD ESP,4
0043A8E6  |.  50            PUSH EAX                            ;push the second parameter
0043A8E7  |.  E8 0472FEFF   CALL 00421AF0                       ;jump to that TSC event.
0043A8EC  |.  83C4 04       ADD ESP,4
0043A8EF  \.^ E9 B3A9FEFF   JMP 004252A7                        ;exit. No script-fixing is needed.
 
Jul 15, 2011 at 8:10 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Ooh, I get it! Thanks!
Oh, wait, how would I make the game continually check for "C"? I can't just slap "CMP DWORD [49E214],a" in anywhere, can I?
And what does AND do? I've never heard of that command.
 
Jul 15, 2011 at 8:28 PM
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: Jan 28, 2010
Location: Internet
Posts: 1369
Age: 34
LunarSoul said:
Ooh, I get it! Thanks!
Oh, wait, how would I make the game continually check for "C"? I can't just slap "CMP DWORD [49E214],a" in anywhere, can I?
And what does AND do? I've never heard of that command.

Well, I don't think C is inside the Compendium's Keypressed table, so you're gonna have to hack it to make the C key generate a custom value in those key offsets.

Here's a conversation between me and Noxid. He sorta describes the process. You should be most interested in the last sentence or so:

(Newest post is at the bottom, oldest post is at the top)
NOXID: Did you see that thing I did where I made the game use mouse input?
CARROTLORD: Mouse input? Nope. Do Tell.
NOXID: http://www.cavestory.org/forums/posts/75877/
CARROTLORD: Christ, how did I miss that post?
Anyway, that's a pretty cool hack. Right mouse button controls Z key... left is shoot.
EDIT2: So WASD controls the player now? Is there something that prevents you from using arrow keys? Or did you just remap everything for the sake of it?
NOXID: I remapped *most* of the keys. Left Shift and space are switch weapons, Q is inventory as usual and E is map system. Z and X do nothing.
I think, if I were to do it again, I'd prefer left shift to be jump, space to be advance weapon, scroll wheel up to be weapon advance, scroll wheel down to be weapon back, and just left mouse shoot. But, it was just a for fun thing.
CARROTLORD: Okay, so you can use any keys or type of mouse inputs you want. That's pretty awesome. I was concerned that keypresses were only limited to those in the key_held / key_pressed tables (you know, the one in the Compendium)
NOXID: Normally that'd be true, but I found the function that handles system messages :]
So, I just intercepted message 0x201 (WM_LBUTTONDOWN) and such, then added my own code. There's also two big indexed pointer tables that basically represent most of the keyboard, so if you don't wanna get messy then simply editing that will allow you to make any key generate a particular value in the key_held variable.

You should ask Noxid if you don't know where those two pointer tables are.

If you want to make the C key available to be pressed by the player anywhere in the game, then you're gonna have to get something that will run "check for C" code anywhere in the game.

The simplest thing I can think of is to hack a dummy entity (hint: use the pot or some other useless NPC) and erase its sprite. Since NPC code runs all the time when you are on the map, have one copy of that dummy NPC on every map in your mod. Put your "CMP DWORD [49E214],a" inside the NPC's code, and you're done.

(There is probably a more efficient and elegant solution for this that I'm neglecting, but I think that the dummy NPC method is going to be the easiest to attempt)

---------

Also, if you want to know what AND does, read my Beginner's ASM guide or whatever it was called. AND is discussed in lessons 20 and 21.
 
Jul 15, 2011 at 8:31 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Wow, thanks a lot!
It's in your guide? I guess I didn't read everything yet.

EDIT: Ugh, another question.
0x0026530 is the offset for NPC 0, I think. But that offset's not even available. Is there something I'm supposed to be doing?
 
Jul 15, 2011 at 8:57 PM
Been here way too long...
"Life begins and ends with Nu."
Join Date: Jan 4, 2008
Location: Lingerie, but also, like, fancy curtains
Posts: 3054
tack on a 4.
 
Jul 15, 2011 at 8:58 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Gotcha, thanks.
So would 0x000200 mean I say CMP DWORD [49E214],200 or CMP DWORD [49E214],0C8? Or something completely different?
Also, sorry for asking so many questions. You guys are very patient.
 
Jul 15, 2011 at 9:50 PM
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: Jan 28, 2010
Location: Internet
Posts: 1369
Age: 34
LunarSoul said:
Gotcha, thanks.
So would 0x000200 mean I say CMP DWORD [49E214],200 or CMP DWORD [49E214],0C8? Or something completely different?
Also, sorry for asking so many questions. You guys are very patient.

It is CMP DWORD [49E214],200. Ollydbg tends to work with hex numbers mostly.

0x is a prefix that means "hex number". So 0x500 means "500, the hex number". I know it looks like 0 times 500 but that's definitely not what it means.
 
Jul 15, 2011 at 9:55 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Carrotlord said:
It is CMP DWORD [49E214],200. Ollydbg tends to work with hex numbers mostly.

0x is a prefix that means "hex number". So 0x500 means "500, the hex number". I know it looks like 0 times 500 but that's definitely not what it means.

Ah, okay! I thought the 0x was just fancy x86 speak. Thanks! Hopefully this works.
 
Jul 16, 2011 at 4:37 PM
LSD
"..."
Join Date: Jun 2, 2011
Location:
Posts: 397
Age: 25
Can anyone help me understand how H/V triggers work?
I just don't know how to change it to either be a H trigger or a V trigger.
 
Jul 16, 2011 at 4:39 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Check option 2 flag if you want it to be vertical, and uncheck it if you want it to be horizontal. Checking option 1 flag makes it run upon collision, I believe.
 
Jul 18, 2011 at 3:37 PM
In front of a computer
"Man, if only I had an apple..."
Join Date: Mar 1, 2008
Location: Grasstown
Posts: 1435
LunarSoul said:
Why do you mock my ignorance so, lace?

EDIT: That was a fancy way of saying "what do you mean?".
Presumably Pixel hard-coded the position at which each boss would appear and the level on which it would appear. That means that that info is stored somewhere in the executable, so if you can find it, you can change it.
 
Jul 18, 2011 at 10:09 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Yet another question.
I changed the framerects at 0x40f9b0 (for the title screen) so it uses a background, like King Story and WTF Story, but the background starts in the middle of the screen. Is there an offset that contains the x and y of the "background"? Or is there something else wrong?
 
Jul 19, 2011 at 2:39 AM
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: Jan 28, 2010
Location: Internet
Posts: 1369
Age: 34
LunarSoul said:
Yet another question.
I changed the framerects at 0x40f9b0 (for the title screen) so it uses a background, like King Story and WTF Story, but the background starts in the middle of the screen. Is there an offset that contains the x and y of the "background"? Or is there something else wrong?

Code:
Render Graphics:
push graphicsid
push rects ; lea [ebp-xx]
push y
push x
push FullScreenRect [48F91c]   ;Not sure about this.
call 0040C3C0
add esp,14

I think the final push is actually PUSH 48F91c (an address) instead of PUSH [48F91c]. But I don't really remember. You can try both if you want.

Anyway, you should be able to render at coordinates (0,0) and that'll make the image appear in the upper left corner.

Make sure you're not using a "half-screen rect". I've seen one used in the Cave Story HP bar and/or EXP bar where the rendering calls don't actually use the fullScreenRect.
 
Jul 19, 2011 at 3:44 AM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
Carrotlord said:
Code:
Render Graphics:
push graphicsid
push rects ; lea [ebp-xx]
push y
push x
push FullScreenRect [48F91c]   ;Not sure about this.
call 0040C3C0
add esp,14

I think the final push is actually PUSH 48F91c (an address) instead of PUSH [48F91c]. But I don't really remember. You can try both if you want.

Anyway, you should be able to render at coordinates (0,0) and that'll make the image appear in the upper left corner.

Make sure you're not using a "half-screen rect". I've seen one used in the Cave Story HP bar and/or EXP bar where the rendering calls don't actually use the fullScreenRect.

Thanks. I plug that in somewhere to render it? I guess I should put it after the framerects are specified...
Half-screen? What do you mean? My background is 640x480, is that incorrect?
 
Jul 19, 2011 at 7:19 PM
CUSTOMIZED!
"The Ultimate Sword of Extraordinary Magnitude"
Join Date: May 28, 2011
Location: Australia/Scotland
Posts: 281
OK I'm kinda rusty on all my Modding atm. I looked for this and could not see an answer. I want to change the size of my character. But of course if I do that then it will not fit in the Mychar.pbm, so the problem is that Pixel has lined up each pixel on the pbm onto the game and I don't know how to change this.

Thanks
 
Jul 19, 2011 at 9:04 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
You need to change the framerects, which are four hex numbers that define where a certain sprite is. That's why the sprites work in spritesheets. I'm sure one of the big hackers (noxid, carrotlord) will know where they are.
 
Jul 19, 2011 at 10:05 PM
Not anymore
"Run, rabbit run. Dig that hole, forget the sun."
Join Date: Jan 28, 2010
Location: Internet
Posts: 1369
Age: 34
LunarSoul said:
Thanks. I plug that in somewhere to render it? I guess I should put it after the framerects are specified...
Half-screen? What do you mean? My background is 640x480, is that incorrect?

Sorry, I wasn't being very clear about which rendering function to change.

You need to change:

Code:
[B]Address  Code[/B]
4100B4   PUSH 28
4100B6   PUSH 58

to this:

Code:
[B]Address  Code[/B]
4100B4   PUSH 0
4100B6   PUSH 0

This will set the coordinates to (0,0).
The result will look like this:

diph.php


Now it's your job to increase the size of the background rect so that it'll hold your custom background image.

If you don't know what a Half-Screen Rect is, don't worry about it. It's not gonna apply here.

And of course, I got these offsets from the almighty Runelancer:
http://www.cavestory.org/forums/threads/871/
 
Jul 20, 2011 at 12:43 AM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4481
LunarSoul said:
Thanks. I plug that in somewhere to render it? I guess I should put it after the framerects are specified...
Half-screen? What do you mean? My background is 640x480, is that incorrect?
I tried your rendering, CLord, and it didn't work. I think the title's in the same place as before. Here's my code:
Code:
CPU Disasm
Address   Hex dump          Command                                  Comments
004100AE  |.  6A 00         PUSH 0                                   ; /Arg5 = 0
004100B0  |.  8D4D E0       LEA ECX,[EBP-20]                         ; |
004100B3  |.  51            PUSH ECX                                 ; |Arg4
004100B4  |.  6A 00         PUSH 0                                   ; |Arg3 = 0
004100B6  |.  6A 00         PUSH 0                                   ; |Arg2 = 0
004100B8  |.  68 1CF94800   PUSH OFFSET 0048F91C                     ; |Arg1 = Misery2.48F91C
004100BD  |.  E8 FEC2FFFF   CALL 0040C3C0                            ; \Misery2.0040C3C0
My title.bmp is 640x480, BTW. I still don't know what you meant by fullscreenrect.
 
Top