For those of you who participated in these threads, thanks again(or just thanks if I haven't already thank you)
trainer?
http://wiird.l0nk.org/forum/index.php/topic,9045.0.html
scroll speed
http://wiird.l0nk.org/forum/index.php/topic,9196.0.html
This is the outcome of those discussions:
[spoiler](http://i46.servimg.com/u/f46/16/26/51/46/sharpr10.jpg)[/spoiler]
As you can see, I have a nice working code. I'll have a YT vid up today or tomorrow or something showing all the possible sharpness "benchmarks" along with what you would put in for sharpness in the weapon mod codes thanks to this. However, I replaced some text. And I noticed something interesting after the code's hook.
80214FA0: 4BE47871 bl 0x8005c810
I have a "Copy Function" of Monster info Display saved in a txt. When I saw that^, it looked familiar.
817C53E8: 4A897429 bl 0x8005c810 # bl this quite a few times.
I guess that's why.
817C53D4: 88B4FFFA lbz r5,-6(r20)
817C53D8: 88F20919 lbz r7,2329(r18)
iirc, -6(r20) points to the color switcher portion of the code. I made the text green by replacing li r5, 0 with li r5, 3. Very interesting. And the argument from before was r7. Mhmmmmm. MID passes more arguments, but that'll be for later.
So bl 0x8005c810 is a call to the wonderful printf() that gets called for anything text related probably. But I wonder. Do you think printf() is the same in all games? Or at least in most games. Or some. Or a few.. Or just MH3... Can I search for the first few instructions and find it in any game so could have something to bl to? Cuz printf() would be awesome. After fully understanding this, no game would not have some display made by me >:D. Here's a "Copy Function" of what I think is printf() in case you want to see/compare to one of your games.
[spoiler="I guess printf()"]8005C804: 7C630734 extsh r3,r3
8005C808: 7C840734 extsh r4,r4
8005C80C: 4BFFEEA4 b 0x8005b6b0
8005C810: 9421FD80 stwu r1,-640(r1)
8005C814: 7C0802A6 mflr r0
8005C818: 90010284 stw r0,644(r1)
8005C81C: 93E1027C stw r31,636(r1)
8005C820: 93C10278 stw r30,632(r1)
8005C824: 7CBE2B78 mr r30,r5
8005C828: 7CDF3378 mr r31,r6
8005C82C: 40860024 bne- cr1,0x8005c850
8005C830: D8210028 stfd f1,40(r1)
8005C834: D8410030 stfd f2,48(r1)
8005C838: D8610038 stfd f3,56(r1)
8005C83C: D8810040 stfd f4,64(r1)
8005C840: D8A10048 stfd f5,72(r1)
8005C844: D8C10050 stfd f6,80(r1)
8005C848: D8E10058 stfd f7,88(r1)
8005C84C: D9010060 stfd f8,96(r1)
8005C850: 90610008 stw r3,8(r1)
8005C854: 9081000C stw r4,12(r1)
8005C858: 90A10010 stw r5,16(r1)
8005C85C: 90C10014 stw r6,20(r1)
8005C860: 90E10018 stw r7,24(r1)
8005C864: 9101001C stw r8,28(r1)
8005C868: 91210020 stw r9,32(r1)
8005C86C: 91410024 stw r10,36(r1)
8005C870: 3CA08066 lis r5,-32666
8005C874: 38A585E0 subi r5,r5,31264
8005C878: 88050023 lbz r0,35(r5)
8005C87C: 28000003 cmplwi r0,3
8005C880: 40820010 bne- 0x8005c890
8005C884: 80050010 lwz r0,16(r5)
8005C888: 2C000000 cmpwi r0,0
8005C88C: 4082004C bne- 0x8005c8d8
8005C890: 7C630734 extsh r3,r3
8005C894: 7C840734 extsh r4,r4
8005C898: 4BFFFF4D bl 0x8005c7e4
8005C89C: 7FC30734 extsh r3,r30
8005C8A0: 4BFFFF51 bl 0x8005c7f0
8005C8A4: 38C10068 addi r6,r1,104
8005C8A8: 3C000400 lis r0,1024
8005C8AC: 90010068 stw r0,104(r1)
8005C8B0: 38010288 addi r0,r1,648
8005C8B4: 9001006C stw r0,108(r1)
8005C8B8: 38010008 addi r0,r1,8
8005C8BC: 90010070 stw r0,112(r1)
8005C8C0: 38610078 addi r3,r1,120
8005C8C4: 38800200 li r4,512
8005C8C8: 7FE5FB78 mr r5,r31
8005C8CC: 48401401 bl 0x8045dccc
8005C8D0: 38610078 addi r3,r1,120
8005C8D4: 4BFFFD45 bl 0x8005c618
8005C8D8: 83E1027C lwz r31,636(r1)
8005C8DC: 83C10278 lwz r30,632(r1)
8005C8E0: 80010284 lwz r0,644(r1)
8005C8E4: 7C0803A6 mtlr r0
8005C8E8: 38210280 addi r1,r1,640
8005C8EC: 4E800020 blr
[/spoiler]
tr;dl
Is printf() the same in every game? printf() in spoiler.
printf is a part of the C Run Time Library. This will probably be the same, or quite similar, for pretty much every single game. Unless the run time changes, which is possible but probably rare for something as mature as printf.
Note that there also a few different types of printf, and not all games will use the same version of *that*.
Ah. I tried to find it in LOZ and Kirby and didn't find it. :/ I guess a RBP on text is the way to go. So far, all text reads' callers were calling that printf().
we definitely need some noob friendly tut to create or own custom text displays for any game.
This will be so beast xD
printf doesn't usually go to the screen for wii games.
I'd bet it's vsprintf that was found and that is being sent to another function that does the screen rendering
Well. I guess if you want to get technical about it, I was only calling it printf cuz idk what else to call it. For now, I'll call it (vs)printf
hmm.. dropbox's photos folder is not good. Gonna have to upload it somewhere then. First post has the image fixed now.
Quote from: Bully@Wiiplaza on January 24, 2012, 04:17:32 PM
we definitely need some noob friendly tut to create or own custom text displays for any game.
This will be so beast xD
[spoiler](http://i46.servimg.com/u/f46/16/26/51/46/rmhe0810.jpg)[/spoiler]
5 sec tutorial :p
In this game 8005c810 is (vs)printf. You just gotta call it from somewhere and your good. When you call it, this is what I've noticed:
r3 = x coordinate in pixels
r4 = y coordinate in pixels
r5 = color
r6 = points to string
r7 = 1st arg
r8 = 2nd arg
r9 = 3rd arg
r10 = 4th arg
And when the function returns, all these registers were modified. :/ So if you wanted to display more than one string, you'd need to put the pointer in another register like 20. r12 and r11 are also modified. Maybe they're 5th and 6th arguments. idk. I didn't bother experimenting more. These are the registers I know and 20-22 don't get modified by (vs)printf. MID uses these registers.
Then it's the same as printf in C++.
printf ("Stuff: %d %X %04x %4d", r7, r8, r9, r10);
r3 and r4 would affect where the text is displayed. It's easy to find a good position with gecko.net.
r5 would change the text color. They're listed somewhere
r6 would have to point to "Stuff: %d...
when it gets up to %d, it'll show r7 as decimal, %X is r8 in uppercase hex, %04x is r9 as a 4 digit lower case hex padded with 0 and so on. It'll stop at null of course.
That's it. Now to find it, I'm sure doing a RBP on some text is enough. The equipment box text is being read by some funtion. It's caller was calling (vs)printf.
Oh and when you find (vs)printf, you'd have to mess with the registers to see what can be done in case it doesn't follow the same rules. You could probably look around and see it loading a pointer to some string into rX and possible a li rY, 0 to display white text. Replacing the text that it's reading with some text that includes "%X %X %X" would most likely lead you to find the argument registers. That's how I found out it was r7. It displaying 80746ca4 and r7 was the only register with that value before the bl. I changed an instruction that didn't look important to li r7, something, and saw the change immediately. r8-10 came from seeing it being used by MID. But I'm sure %Xing would show you all the argument registers.
ah, the text output in mh3
that function is calling a pformat or a vsprintf as any *printf does to handle conversion of special characters.
it then uses the graphics engine to render to screen. unfortunately, most games aren't as nice. 99.999% of the time you can find the proper pformat to use to convert your const char* string and ... args to the string buffer, but you won't get a special output function. and almost assuredly you won't get a nice function like this. for many games it will involve setting up a buffer, wsprintf'ing into that buffer, and then calling their static string output function such as a nw4r::lyt::TextBox::SetText(wchar* buffer);
it's a shame, but it's just not usually done in games
Aww. That sounds complicated. Oh well. I thought I had a thing going on. XD.
Wow, thanks for the insights megazig.
I did something like this for Tales of Symphonia: DotNW. It had some format strings that were used to display things like character level, HP, MP, name, etc. I hijacked them for displaying real-time feedback for my rollers.
I didn't even realize that Stuff was talking about writing arbitrary text to arbitrary coordinates on the screen. That is quite a badass function. I figured he was also hijacking an existing format string that gets written onto the screen by the game on its own but I assumed incorrectly. I wonder if it would be possible to port the function and its dependencies to other games?
Quote from: Stuff on January 25, 2012, 12:20:15 AM
And when the function returns, all these registers were modified. :/ So if you wanted to display more than one string, you'd need to put the pointer in another register like 20. r12 and r11 are also modified. Maybe they're 5th and 6th arguments. idk.
Recall that the registers below r13 (excluding r1 and r2) are
volatile. The PPC EABI (the "rules of the game" for the compiler) stipulate that when you call a function, you cannot rely on the contents of volatile registers being the same after the function call returns. The caller is allowed to do anything and everything it wants to those registers.
The PPC EABI stipulates that r11 and r12 cannot be arguments.
QuoteThese are the registers I know and 20-22 don't get modified by (vs)printf. MID uses these registers.
Just because they do not get modified does not mean that they are free to use. Everything above r13 are non-volatile registers. After a function call returns, the contents of non-volatile registers *must be the same* (hence all the pushing and popping). Ironically, they often can be changed without problems, but the results can be unpredictable. If you plan on using them, back them up just for safety. Even if they don't look like they were used nearby, they could be used by some function much lower in the call stack that you might not even know about.
that's easy to verify by finding the _restgpr_20, 21, 22 functions and check for xrefs. you'll likely see them being used at some point. just need to make sure it's being used not on your current stack
easiest to just follow the EABI and save your volatile regs though
Quote from: dcx2 on January 25, 2012, 02:29:36 AMI figured he was also hijacking an existing format string that gets written onto the screen by the game on its own but I assumed incorrectly. I wonder if it would be possible to port the function and its dependencies to other games?
Well that is where I started. The string said "Select equipment to reorder" and I replaced it with my own text and added %x to see what would happen. Then the display happened. I'm glad I was able to understand it. My MID is fixed :p.
Well, 0x8045dccc has a bl that has a b to a function with conditional branches and some more bl's. It'll probably be 30-40 lines if it works. I would like to just put it after a 68 code. Then you just gotta lis, lwz bX, and mtlr(I still like blrl better XD).
The only thing is it doesn't display float properly. The image in my last post shows coordinates entirely based off of Bully's Teleport(near the map). So I assume it's correct because his code did work. But If I display it as float, I get
x: 1.2400000~ish and it's shaky o.O
y: 0.000000
z: 0.000000
So I changed it to hex because it's just wrong as float. Or maybe I'm doing it wrong. %f
You were probably getting the right output, you just needed to specify width/precision.
http://en.wikipedia.org/wiki/Printf_format_string
try %5.2f instead of %f
Personally I prefer %g
Alright I'll try that in a little bit. I tried %g and got the same stuff though.
Edit:
Nope. Maybe it's displaying a value from a float register.. And now I noticed the fregs are constantly changing >.>. Any instruction makes them change.
It is. When I change %x to %g, the x and y values were pushed to y and z. But what about those changing fregs?
The fregs have this weird issue where they lie sometimes. I never fully figured it out, but I think the fregs only tell the truth for one breakpoint after an instruction that uses the floating point unit. There's a bit in SRR1 that lets you know whether the fregs are fake; not sure which bit, but if you set a breakpoint and then step through a bunch of code with integer/fpu instructions, it should pop out at you.
So when you set the BP, there has almost certainly been *some* FPU instruction executed. However, when you press step and it's not an FPU instruction, then the fregs will lie (FYI: steps are also breakpoints). They will continue to lie as long as you step over non-fpu code. Once you execute an fpu instruction, they'll tell the truth for one frame. If you have a series of consecutive fpu instructions, they will all tell the truth until after the next non-fpu instruction is stepped over.
Ah well in my case(if it's situational) the lying bit was the 19th(?). 0000B032 for truth, 00009032 for lies.
I also tried to modify all the fregs to see if anything would change. I replaced the color instruction with lfs fX,60(r21) and went through each freg and nothing happened. I also did a XBP before and after the print function and searched memory for the first float displayed but got no results. So idk where it's pulling those floats from. It's not the regs because r7 gets used as the 2nd argument after cchhanging %x to %f or %g. I don't see it in the fregs or in memory. I'm just gonna leave coordinates as hex.
yes, 0x2000 in the MSR is the fpbit
as that gets copied to SRR1, that's the one you're seeing
in 7xx_um.pdf you can search for MSR[FP]
----------------------
you can also see it enabling fp instructions at the start of the codehandler, but it backs up the msr to r25. then it does another mfmsr r25 at the end.
(which is a sort of lucky bug since _terminator_onoff_ messes with r25 and doesn't back it up, just one of the many bugs that I'm hoping I can share the fix for if GeckoOS's next version is open source again)