 |
 |
GoldenEye 007 Nintendo 64 Community, GoldenEye X, Nintendo 64 Games Discussion GoldenEye Cheats, GoldenEye X Codes, Tips, Help, Nintendo 64 Gaming Community
|
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
zoinkity 007


Joined: 24 Nov 2005 Posts: 1729
 |
Posted: Thu Feb 23, 2012 5:16 pm Post subject: More debug than debug: stderr |
 |
|
Just identified another 'debug' display tucked away behind some code. Much like the debug display, there's another writable buffer to print text to the screen. Unlike debug, now dubbed 'stdout', this one is unformatted straight text, printed in white directly to the screen buffer using its own embedded font and no microcode. I'm calling it 'stderr'.
There are several ways to get it to appear, but the easiest is to write 1 to 80023097. (Anywhere in 80023094 should work.)
Chances are you can't even see it right now if you're using an emulator. You're going to have to play with your frame buffer settings to get it to draw it to the screen.
With no text to display you should have a large, black window obscuring you the same size as the debug menu. You write text into the buffer spanning from 80023718 - 80023FF8. There's a maximum of 0x47 chars per line with upwards of 0x1F lines. If you type some text into this region it should appear on screen.
Actually, this behaves a lot differently than the usual display method. Unlike those, this one scrolls! In fact, it turns out that it is used, so to speak. By default, if you parse a c-style string with arguments but don't give it a target address or alternate copy function by default it prints it to stderr.
So far, the functions attached to this are:
Code: | 7000CEE8 DAE8 write A2 chars in string A1 to stderr
accepts: A0=p->target (unused), A1=p->string, A2=length
70005630 6230 write char A2 to (A0,A1) in stderr
accepts: A0=xpos, A1=ypos, A2=char
700056BC 62BC write char A0 to stderr
accepts: A0=char
700057CC 63CC scroll stderr down one line
accepts: A0=ypos
7000585C 645C print char A2 to stderr screen position (A0,A1) in video buffer 1
accepts: A0=xpos, A1=ypos, A2=char |
The highest level would be 7000CEE8, fed a string. That calls 700056BC for each char, placing them at the next available position, dictated by stderr.curxpos (80023FF8) and stderr.curypos (80023FFC). 700056BC also prints tabs aligned to 8-byte boundries and handles newlines. If you exceed the screen bounds it calls 700057CC to scroll a line. Internally, it uses 70005630 to do the writing, in turn calling 7000585C to do the drawing.
There are other methods to display the stderr screen. In particular, the word at 8002309C activates the menu when called, and calls are sent to 80023098 and rewritten each iteration. You can also rig it to display as a periodic event, since each routine to call it also keeps a Count/Compare pair, though this is a little more involved. _________________ (\_/) Beware
(O.o) ze
(> <) Hoppentruppen!
Last edited by zoinkity on Fri Feb 24, 2012 6:19 am; edited 1 time in total |
|
|
|
|
|
 |
 |
 |
 |
 |
SubDrag Administrator

Joined: 16 Aug 2006 Posts: 6171
 |
Posted: Thu Feb 23, 2012 6:09 pm Post subject: |
 |
|
That's really cool! Guess testers hit a lot of this when something crashed, bam, out to stderr. So you're saying game actually writes to here? Or is this just c stderr somehow changed in way it displays? It's surprising no one's ever hit it with all the GS poking over years on console. |
|
|
|
|
|
 |
 |
 |
 |
 |
zoinkity 007


Joined: 24 Nov 2005 Posts: 1729
 |
Posted: Fri Feb 24, 2012 4:45 am Post subject: |
 |
|
I know the reason I didn't hit it before was because the routines looked a little long and silly. In one doc it was tagged "Needlessly long and stupid function that probably doesn't do anything useful anyway."
Also, it is surprisingly similiar code-wise to the debug menu's own draw routines until you get to the drawing part. Couldn't blame anyone for confusion.
Besides, if you did just happen across the flag the screen would go black. Lets face it--whenever we poked a random address and the screen when black we assumed we crashed the game yet again.
I love some of those old cheat lists: "screws up graphics", "flicker mode", "pschodelic mode", "gnarly sound", etc.
I haven't found anything that activates the screen on its own yet, but there is one time they explicitly do not permit it from displaying. There are a few things that write to it though, usually if no other target was specified. In fact, that explains some older annotated code. Never could figure out why they would sometimes print a line and then print it again. Just sort of assumed it went to Indi or something, and didn't feel like tracing.
Oh, there are these too to disable and enable it. A0 should be a True/False thing. stderr.enable forces it on regardless, but normal operation would be to permit it, then activate or deactivate as desired.
Code: | 1570 70000970 A0-> stderr.activated [80023098]
157C 7000097C A0-> stderr.enable [80023094]
1588 70000988 A0-> stderr.permitted [8002309C] |
Didn't mention this before, but even when it did display it would only do it periodically unless you specificly displayed it. That was done using a counter which only executed the tests every 16 iterations. The other method was explicit, likely on an error. It doesn't just display stderr if enabled but also grabs the current Count for debug purposes. Its caller also sets up the user compare system, seperate from the built-in register.
Code: | 15F8 700009F8 test to display stderr every 16th frame
15A0 700009A0 test to display stderr and update Count |
Have to write up a big, scary post for threads soon. It is so very integral to GE its stunning we never noticed before. _________________ (\_/) Beware
(O.o) ze
(> <) Hoppentruppen! |
|
|
|
|
|
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
 |