- 5,256
- Posts
- 17
- Years
- Age 27
- Leicester, UK
- Seen Mar 31, 2025
Would it be within the realm of possibility to do this using 256 colours? I don't think it would be, but it'd be interesting to see.
I don't know if it's just me, but could you possibly upload the firered tbl again? Sendspace said Sorry, the file you requested is not available.
Hacking the Diploma Screen
0xF4CE4 - 05 E0
Well it took me about 2 hours or so doing this and trying to perfect it.
So here it is! The thingy in the spoiler are routines that allow you to have up to 255 diplomas. That's enough maybe even too much in a hack!
Instructions are included in the spoiler.
Spoiler:
I'LL EXPLAIN EVERYTHING AT THE BOTTOM :)
I decided to keep the old special and diploma intact. So this is going to be some work you'll be doing!
Now, if you set 0x8002 to something not equal to 0 before you use the special, it will display alternate diplomas from a table.
The .word 0xFFFFFFFF's are pointers to your own table! Up to 256 pointers. (Note that these routines ignore the pointer at position 0x0 in all of your tables!)
I'll provide the compiled ones at the bottom.
The XX XX XX 08 represents the pointer to where you placed the respective routine (+1).
Tilemap/Tileset Related Routines:
at 0x080F4CCA, place 00 00 00 4C 20 47 XX XX XX 08 00 00.Code:.align 2 .thumb /*Tilemap (Raw Image) Replacer*/ main: ldr r0, .VAR_8002 ldrb r0, [r0] cmp r0, #0x0 bne go_table ldr r1, .ORIG_RAW continue: mov r0, #0x1 mov r2, #0x0 mov r3, #0x0 bl func ldr r4, .NEXT_INT bx r4 go_table: ldr r1, .TABLE_RAWS lsl r0, r0, #0x2 add r1, r1, r0 ldr r1, [r1] b continue func: ldr r4, .DO_FNC bx r4 .hword 0x0000 .ORIG_RAW: .word 0x084154E8 .TABLE_RAWS: .word 0xFFFFFFFF /*Change accordingly; word-aligned*/ .NEXT_INT: .word 0x080F4CD7 .VAR_8002: .word 0x020370BC .DO_FNC: .word 0x08002041
at 0x080F4FC8, place 00 4C 20 47 XX XX XX 08.Code:.align 2 .thumb /*Tileset (Actual Tiles) Replacer*/ main: ldr r0, .VAR_8002 ldrb r0, [r0] cmp r0, #0x0 bne go_table ldr r1, .ORIG_DIPLOMA continue: mov r0, #0x0 str r0, [sp, #0x0] mov r0, #0x1 ldr r4, .NEXT_INT bx r4 go_table: ldr r1, .TABLE_DIPLOMAS lsl r0, r0, #0x2 add r1, r1, r0 ldr r1, [r1] b continue .hword 0x0000 .ORIG_DIPLOMA: .word 0x084147C0 .TABLE_DIPLOMAS: .word 0xFFFFFFFF /*Change accordingly; word-aligned*/ .NEXT_INT: .word 0x080F4FD1 .VAR_8002: .word 0x020370BC
at 0x080F4FEE, place 01 49 08 47 00 00 XX XX XX 08.Code:.align 2 .thumb /*Palette Replacer*/ main: ldr r1, .VAR_8002 ldrb r1, [r1] cmp r1, #0x0 bne go_table ldr r0, .ORIG_PAL continue: mov r1, #0x0 mov r2, #0x40 bl func ldr r7, .NEXT_INT bx r7 go_table: ldr r0, .TABLE_PALS lsl r1, r1, #0x2 add r0, r0, r1 ldr r0, [r0] b continue func: ldr r7, .DO_FNC bx r7 .align 2 .ORIG_PAL: .word 0x08415954 .TABLE_PALS: .word 0xFFFFFFFF /*Change accordingly; word-aligned*/ .NEXT_INT: .word 0x080F4FF9 .VAR_8002: .word 0x020370BC .DO_FNC: .word 0x080703ED
Text Related Routines:
at 0x080F5058, place 00 4C 20 47 XX XX XX 08.Code:.align 2 .thumb /*Header Text Replacer*/ main: ldr r5, .VAR_8002 ldrb r5, [r5] cmp r5, #0x0 bne go_table ldr r1, .ORIG_MSG continue: add r0, sp, #0xC bl func ldr r4, .NEXT_INT bx r4 go_table: ldr r1, .LDPTR_0 ldr r1, [r1] b continue func: ldr r4, .DO_FNC bx r4 .hword 0x0000 .ORIG_MSG: .word 0x0841B60E .LDPTR_0: .word 0x03000F14 /*Loadpointer slot 0x0*/ .NEXT_INT: .word 0x080F5061 .VAR_8002: .word 0x020370BC .DO_FNC: .word 0x0813CCC9
at 0x080F508C, place 00 4F 38 47 XX XX XX 08.Code:.align 2 .thumb /*Body Text Replacer*/ main: ldr r1, .VAR_8002 ldrb r1, [r1] cmp r1, #0x0 bne go_table ldr r1, .ORIG_MSG continue: add r0, sp, #0xC bl func ldr r7, .NEXT_INT bx r7 go_table: ldr r1, .LDPTR_1 ldr r1, [r1] b continue func: ldr r7, .DO_FNC bx r7 .hword 0x0000 .ORIG_MSG: .word 0x0841B619 .LDPTR_1: .word 0x03000F18 /*Loadpointer slot 0x1*/ .NEXT_INT: .word 0x080F5095 .VAR_8002: .word 0x020370BC .DO_FNC: .word 0x0813CCC9
at 0x080F50C0, place 00 4F 38 47 XX XX XX 08.Code:.align 2 .thumb /*Signature Text Replacer*/ main: ldr r0, .VAR_8002 ldrb r0, [r0] cmp r0, #0x0 bne go_table ldr r0, .ORIG_MSG continue: str r0, [sp, #0x8] mov r0, #0x0 mov r1, #0x2 ldr r7, .NEXT_INT bx r7 go_table: ldr r0, .LDPTR_2 ldr r0, [r0] b continue .hword 0x0000 .ORIG_MSG: .word 0x0841B684 .LDPTR_2: .word 0x03000F1C /*Loadpointer slot 0x2*/ .NEXT_INT: .word 0x080F50C9 .VAR_8002: .word 0x020370BC
at 0x080F5078, place 00 4F 38 47 XX XX XX 08.Code:.align 2 .thumb /*Text Properties Replacer*/ main: ldr r7, .VAR_8002 ldrb r7, [r7] cmp r7, #0x0 bne go_table ldr r6, .ORIG_DATA continue: str r6, [sp, #0x0] str r5, [sp, #0x4] add r0, sp, #0xC ldr r7, .NEXT_INT bx r7 go_table: ldr r6, .VAR_8000 b continue .align 2 .ORIG_DATA: .word 0x08415A04 .VAR_8000: .word 0x020370B8 /*Var 0x8000 and 0x8001*/ .NEXT_INT: .word 0x080F5081 .VAR_8002: .word 0x020370BC
Finally:
at 0x080F50D8, place 00 4F 70 BD F0 30 00 03.
Now, here's how it goes:
Before you use special 0x108, if you set 0x8002 to another value other than 0, it will use the alternate diplomas (in terms of images, palettes and texts if desired), else it will show the original diploma.
Now for the text parts:
Before you use special 0x108, if you want to display your own text on the "PLAYER: [player]" part, just do:
Code:loadpointer 0x0 0xYYYYYYYY
If you want to display your own text on the middle part, just do:
Code:loadpointer 0x1 0xYYYYYYYY
If you want to display your own text on the "GAMEFREAK" part, just do:
Code:loadpointer 0x2 0xYYYYYYYY
Remember that you must load something onto those locations (even if it's to 0x08FFFFFF) or else it will cause the game to crash.
Finally, you don't need to change the contents of 0x415A04 because they now depend on vars 0x8000 and 0x8001 (if using the alternate diplomas anyway, the original ones still use 0x415A04). So, if you want to use 00 02 03 00, you'll do:
Or 00 01 00 00:Code:setvar 0x8000 0x200 setvar 0x8001 0x3
Code:setvar 0x8000 0x100 setvar 0x8001 0x0
So here's a full example:
Code:#dynamic 0x700000 #org @start lockall setvar 0x8002 0x1 //Use custom diploma #0 (position 0x1 in table) setvar 0x8000 0x100 //This produces the same effect setvar 0x8001 0x0 //like the one on Spherical Ice's tut. loadpointer 0x0 @HEADER loadpointer 0x1 @BODY loadpointer 0x2 @SIG special 0x108 waitstate releaseall end #org @HEADER = KYORDON #org @BODY = GROUDON and KYOGRE were once best\nbuddies just so you know[.]\n\nBut RAYQUAZA screwed up\neverything[.] Real bad! #org @SIG = BRENDAN
The final result:
![]()
Using:
Code:setvar 0x8000 0x800 setvar 0x8001 0x602
![]()
Sorry for the bad quality... Stupid JPEG...
Other things to remember:
Your table can have less than 255 pointers.
Also, setting 0x8002 to 0xF43, for example, is the same as setvar 0x8002 0x43.
The table in the Tilemap (RAW) Replacer routine must contain pointers to the RAW images.
The table in the Tileset (Actual Tiles) Replacer routine must contain pointers to your tileset in compressed form (the ones in unLZ).
The table in the Palette Replacer routine must contain pointers to uncompressed palettes.
Like what Spherical Ice said, you still have little room to work with at the SIG ("GAMEFREAK") location.
Final words:
And that's about it. You can now have up to 255 diplomas + the original to use!
The routines are not fully optimized (the ignoring slot 0x0 thingy), so sorry about that.
If you have any problems or experience any bugs with these routines, please tell me (I just started doing ASM about a month ago). I'll get it fixed as soon as possible.
I would like to thank Spherical Ice for the awesome tutorial and Chaos Rush for the idea of multiple diplomas. :)