Skip to content

1ST_READ.BIN

Gong Xian edited this page Jun 10, 2023 · 29 revisions

These hacks to the main executable will facilitate script editing.

Offset Memory Location Original Value Remarks
0xaba66-0xadf0b 8c0bba66-8c0bdf0b 00 Blank area 9,382 bytes long.
0xae0f4-0xafd67 8c0be0f4-8c0bfd67 00 Blank area 7,284 bytes long.
0xb00f4-0xb1baf 8c0c00f4-8c0c1baf 00 Blank area 6,884 bytes long.
0xe25b6 8c0f25b6 1a e1 Writes 0x1A to R1. This value sets the character size. This is written by 8c0f25b8 and 8c0f25bc to the ATXT region, allowing for square characters only.
0xe25c0 8c0f25c0 1c e1 Writes 0x1C to R1. This value sets the character offset. This is written by 8c0f25c2 and 8c0f25ce to the ATXT region, allowing for square characters only.
0xfc656 8c10c656 04 e6 Writes 0x4 to R6. This value sets the number of lines in the text box for dialogue.
0xfc658 8c10c658 10 e5 Writes 0x10 to R5. This value sets the number of characters per line in the text box for dialogue. Changing this and the value above will change the amount of memory allocated for the text box, as well as the number of characters before a line break is forced.
0x115774 8c125774 4a d0 4b 70 Writes a pointer to the string "s_sound_v.cbd" to r0 and adds 0x4B to it. This offset leads to a string that is shown when the Kinematron is scrolling a message in the player's VMU.
0x1158a0 8c1258a0 20 10 22 8c Pointer to the string "s_sound_v.cbd".
0x132e94 8c142e94 04 e6 Writes 0x4 to R6. This value sets the number of lines in the text box for non-dialogue text, such as item descriptions.
0x132e96 8c142e96 10 e5 Writes 0x10 to R5. This value sets the number of characters per line in the text box for non-dialogue text. Changing this and the value above will change the amount of memory allocated for the non-dialogue text box, as well as the number of characters before a line break is forced.
0x204c60-0x2052bf 8c214c60-8c2152bf 00 Blank area 1,632 bytes long.
0x2110d2 8c2210d2 04 Number of frames between each character of text written to the screen. Decreasing this value will accelerate text writing speed.
0x214c00-0x215053 8c224c00-8c225053 Strings for map labels. See Translating map labels.
0x21581e 8c22581e @fs22,22@fm24,0 Most strings for map labels are located in the above block, but some are read from script files instead. In these cases, this string containing control codes is prepended to the string from the script.
0x21d574-0x21d8e7 8c22d574-8c22d8e7 Strings for Koubu Knuckle.
0x21f704 8c22f704 10 Character limit for the small system message dialog window, such as those seen in save file management screens.
0x21f708 8c22f708 06 Line limit for the small system message dialog window, such as those seen in save file management screens.
0x21fce5-0x223d08 8c22fce5-8c233d08 Strings for various system messages.
0x226570 8c236570 00 00 85 43, 266.0 Normal LIPS dialog box coordinates. Bottom-right corner, Y coordinate. Copied to 8c1fe180. These four coordinates are floating points that are copied to 8c1fe174-8c1fe180 during the Licensed by Sega screen during console boot.
0x226574 8c236574 00 c0 09 44, 551.0 Normal LIPS dialog box coordinates. Bottom-right corner, X coordinate. Copied to 8c1fe17c.
0x226578 8c236578 00 00 07 43, 135.0 Normal LIPS dialog box coordinates. Top-left corner, Y coordinate. Copied to 8c1fe178.
0x22657c 8c23657c 00 00 b2 42, 89.0 Normal LIPS dialog box coordinates. Top-left corner, X coordinate. Copied to 8c1fe174.

The file containing textures for the main font, SKFONT.CG, is loaded into memory at 8ccd7ec0. As the kanji will not be used for translations, their textures can be overwritten with new code and pointed to from the main executable. Addresses for the below hacks begin at the arbitrary location 8cd70000.

Changing Dialogue Box Text Properties

This routine sets properties for text in dialogue boxes.

        8c10c754 2c e0           mov        #0x2c,r0
        8c10c756 1a e1           mov        #0x1a,r1                                         ; Text character size
        8c10c758 14 03           mov.b      r1,@(r0,r3)
        8c10c75a 2d e0           mov        #0x2d,r0
                                                                                             ; Add a mov instruction to r1 here to change vertical size
        8c10c75c 14 03           mov.b      r1,@(r0,r3)
        8c10c75e 43 60           mov        r4,r0
        8c10c760 ee 01           mov.l      @(r0,r14),r1
        8c10c762 2e e0           mov        #0x2e,r0
        8c10c764 1c e6           mov        #0x1c,r6                                         ; Text character offset
        8c10c766 65 01           mov.w      r6,@(r0,r1)
        8c10c768 30 e0           mov        #0x30,r0
                                                                                             ; Add a mov instruction to r6 here to change line height
        8c10c76a 55 01           mov.w      r5,@(r0,r1)
        8c10c76c 43 60           mov        r4,r0
        8c10c76e ee 04           mov.l      @(r0,r14),r4

This routine will write a value to R1 and copy it to the bytes for horizontal and vertical sizes, creating square characters. Adding an instruction to write to R1 before 8c10c75c 14 03 mov.b r1,@(r0,r3) will set the vertical character size. Changing only the first value will create half-width text.

In the same vein, R6 contains the horizontal offset before subsequent characters, which is also used as the line height. To change only the horizontal offset, R6 must be redefined before the upcoming jump at 8c10c770 to 8c0f2da8.

This hack consists of a jump from 8c10c754 to a subroutine that makes extra register writes before the instructions that write text box properties to memory. It is recommended to change the horizontal offset while keeping the character size unchanged, and create new tiles that use the left side for the glyph.

Address Default value Remarks
8cd70002 0x1A Character horizontal size
8cd70008 0x1A Character vertical size
8cd70012 0x1C Character horizontal offset
8cd70018 0x1C Line height
        8c10c754 01 d0           mov.l      ->set_text_props_sub,r0                          = 8c0bba6a
        8c10c756 2b 40           jmp        @r0                                              
        8c10c758 09 00           nop
        8c10c75a 00              ??         00h
        8c10c75b 00              ??         00h
                             PTR_set_text_props_sub_8c10c75c                 XREF[1]:     8c10c754(R)  
        8c10c75c 00 00 d7 8c     addr       set_text_props_sub

        ...

                             set_text_props_sub
        8cd70000 2c e0           mov        #0x2c,r0
        8cd70002 1a e1           mov        #0x1a,r1                                         ; Set character h.size
        8cd70004 14 03           mov.b      r1,@(r0,r3)
        8cd70006 2d e0           mov        #0x2d,r0
        8cd70008 1a e1           mov        #0x1a,r1                                         ; Set character v.size
        8cd7000a 14 03           mov.b      r1,@(r0,r3)
        8cd7000c 43 60           mov        r4,r0
        8cd7000e ee 01           mov.l      @(r0,r14),r1
        8cd70010 2e e0           mov        #0x2e,r0
        8cd70012 0b e6           mov        #0xb,r6                                          ; Set character h.offset
        8cd70014 65 01           mov.w      r6,@(r0,r1)
        8cd70016 30 e0           mov        #0x30,r0
        8cd70018 1c e6           mov        #0x1c,r6                                         ; Override r6 with hardcoded v.offset
        8cd7001a 55 01           mov.w      r5,@(r0,r1)
        8cd7001c 43 60           mov        r4,r0
        8cd7001e ee 04           mov.l      @(r0,r14),r4
        8cd70020 01 d0           mov.l      PTR_LAB_8cd70028,r0                              = 8c10c770
        8cd70022 2b 40           jmp        @r0=>LAB_8c10c770                                ; Return to set_text_props
        8cd70024 09 00           _nop
        8cd70026 09 00           nop
                             PTR_LAB_8cd70028                                XREF[1]:     set_text_props_sub:8cd70020(R)  
        8cd70028 70 c7 10 8c     addr       LAB_8c10c770

Changing Global Text Properties

The main text box sets its own text properties with the same values as global text values, which are used in every other location that text is written, including LIPS prompts.

        8c0f25b4 2c e0           mov        #0x2c,r0
        8c0f25b6 1a e1           mov        #0x1a,r1                                         ; Text character size
        8c0f25b8 14 0e           mov.b      r1,@(r0,r14)
        8c0f25ba 2d e0           mov        #0x2d,r0
                                                                                             ; Add a mov instruction to r1 here to change vertical size
        8c0f25bc 14 0e           mov.b      r1,@(r0,r14)
        8c0f25be 2e e0           mov        #0x2e,r0
        8c0f25c0 1c e1           mov        #0x1c,r1                                         ; Text horizontal offset
        8c0f25c2 15 0e           mov.w      r1,@(r0,r14)
        8c0f25c4 30 e0           mov        #0x30,r0
        8c0f25c6 35 0e           mov.w      r3,@(r0,r14)
        8c0f25c8 32 e0           mov        #0x32,r0
        8c0f25ca 35 0e           mov.w      r3,@(r0,r14)
        8c0f25cc 34 e0           mov        #0x34,r0
                                                                                             ; Add a mov instruction to r1 here to change line height
        8c0f25ce 15 0e           mov.w      r1,@(r0,r14)
        8c0f25d0 38 e0           mov        #0x38,r0
        8c0f25d2 35 0e           mov.w      r3,@(r0,r14)
        8c0f25d4 36 e0           mov        #0x36,r0
        8c0f25d6 35 0e           mov.w      r3,@(r0,r14)
        8c0f25d8 3c e0           mov        #0x3c,r0
        8c0f25da 35 0e           mov.w      r3,@(r0,r14)
        8c0f25dc 3a e0           mov        #0x3a,r0
        8c0f25de 35 0e           mov.w      r3,@(r0,r14)
        8c0f25e0 e3 64           mov        r14,r4

The routine to set these properties is very similar to that of the text box properties. As before, a customized routine with extra mov instructions will change text properties outside of the text box.

Address Default value Remarks
8c0bbab6 0x1A Character horizontal size
8c0bbabc 0x1A Character vertical size
8c0bbac2 0x1C Character horizontal offset
8c0bbad0 0x1C Line height
                             define_ATXT                                     XREF[1]:     8c0f258e(j)  
        8c0f25a0 01 d0           mov.l      ->set_text_props_global,r0                       = 8c0bbaa0
        8c0f25a2 2b 40           jmp        @r0=>set_text_props_global
        8c0f25a4 09 00           _nop
        8c0f25a6 00              ??         00h
        8c0f25a7 00              ??         00h
                             PTR_set_text_props_global_sub_8c0f25a8              XREF[1]:     8c0f25a0(R)  
        8c0f25a8 2c 00 d7 8c     addr       set_text_props_global_sub

...

                             set_text_props_global_sub
        8cd7002c 00 e3           mov        #0x0,r3
        8cd7002e 28 e0           mov        #0x28,r0
        8cd70030 35 0e           mov.w      r3,@(r0,r14)
        8cd70032 26 e0           mov        #0x26,r0
        8cd70034 35 0e           mov.w      r3,@(r0,r14)
        8cd70036 24 e0           mov        #0x24,r0
        8cd70038 35 0e           mov.w      r3,@(r0,r14)
        8cd7003a 2a e0           mov        #0x2a,r0
        8cd7003c 07 e1           mov        #0x7,r1
        8cd7003e 15 0e           mov.w      r1,@(r0,r14)
        8cd70040 2c e0           mov        #0x2c,r0
        8cd70042 1a e1           mov        #0x1a,r1                                         ; Set character h.size
        8cd70044 14 0e           mov.b      r1,@(r0,r14)
        8cd70046 2d e0           mov        #0x2d,r0
        8cd70048 1a e1           mov        #0x1a,r1                                         ; Override character v.size
        8cd7004a 14 0e           mov.b      r1,@(r0,r14)
        8cd7004c 2e e0           mov        #0x2e,r0
        8cd7004e 0b e1           mov        #0xb,r1                                          ; Set character h.offset
        8cd70050 15 0e           mov.w      r1,@(r0,r14)
        8cd70052 30 e0           mov        #0x30,r0
        8cd70054 35 0e           mov.w      r3,@(r0,r14)
        8cd70056 32 e0           mov        #0x32,r0
        8cd70058 35 0e           mov.w      r3,@(r0,r14)
        8cd7005a 34 e0           mov        #0x34,r0
        8cd7005c 1c e1           mov        #0x1c,r1                                         ; Override character v.offset
        8cd7005e 15 0e           mov.w      r1,@(r0,r14)
        8cd70060 38 e0           mov        #0x38,r0
        8cd70062 35 0e           mov.w      r3,@(r0,r14)
        8cd70064 36 e0           mov        #0x36,r0
        8cd70066 35 0e           mov.w      r3,@(r0,r14)
        8cd70068 3c e0           mov        #0x3c,r0
        8cd7006a 35 0e           mov.w      r3,@(r0,r14)
        8cd7006c 3a e0           mov        #0x3a,r0
        8cd7006e 35 0e           mov.w      r3,@(r0,r14)
        8cd70070 e3 64           mov        r14,r4
        8cd70072 01 d0           mov.l      PTR_LAB_8cd70078,r0                              = 8c0f25e2
        8cd70074 2b 40           jmp        @r0=>LAB_8c0f25e2                                ; Return to set_text_props_global
        8cd70076 09 00           _nop
                             PTR_LAB_8cd70078                                XREF[1]:     set_text_props_global_sub:8cd700
        8cd70078 e2 25 0f 8c     addr       LAB_8c0f25e2

Changing LIPS Dialog Text Limits

The LIPS dialogs have a character limit of 18. This is calculated using the function at 8c11738c. This function takes the total width of the LIPS dialog (551 - 89 = 462) and divides it by a float constant of 26.0 from a subroutine at 8c11817c to get a result of 17. 1.0 is added to this, for a total of 18.

        8c1173f8 e3 60           mov        r14,r0                                          ; Load base address for stored LIPS properties
        8c1173fa 08 70           add        #0x8,r0
        8c1173fc 08 f1           fmov.s     @r0,fr1                                         ; Load bottom-right X coordinate of dialog
        8c1173fe e8 f0           fmov.s     @r14,fr0                                        ; Load top-left X coordinate of dialog
        8c117400 01 f1           fsub       fr0,fr1                                         ; Bottom-right X - Top-left X
        8c117402 f3 f1           fdiv       fr15,fr1                                        ; ...divided by character width
        8c117404 20 f1           fadd       fr2,fr1                                         ; ...plus 1
        8c117406 3d f1           ftrc       fr1,FPUL
        8c117408 5a 05           sts        FPUL,r5                                         ; Store result of LIPS line character limit calculations
        8c11740a 73 d0           mov.l      DAT_8c1175d8,r0                                 = 00000134h
        8c11740c d3 64           mov        r13,r4
        8c11740e 0c 34           add        r0,r4
        8c117410 72 d0           mov.l      ->FUN_8c0f24b0,r0                               = 8c0f24b0
        8c117412 0b 40           jsr        @r0=>FUN_8c0f24b0                               ; Write results to new ATXT region

Rather than change the calculations to get a larger result, these floating point operations can be replaced with another subroutine that returns another float constant. The largest usable value with this method is 36 characters. For Analog LIPS dialogs, the effective character limit for characters with a width of 11 is about 30 characters due to the smaller size of the graphic.

        8c1173f8 01 d0           mov.l      ->get_new_lips_char_limit,r0                    
        8c1173fa 0b 40           jsr        @r0=>get_new_lips_char_limit                     
        8c1173fc 09 00           _nop                                                       
        8c1173fe 09 00           nop                                                         
                             PTR_get_new_lips_char_limit_8c117400            XREF[1]:     8c1173f8(R)  
        8c117400 7c 00 d7 8c     addr       get_new_lips_char_limit                          
        8c117404 09 00           nop                                                         

...

                             get_new_lips_char_limit
        8cd7007c 02 c7           mova       lips_text_limit,r0                               = 38.0
        8cd7007e 01 d5           mov.l      PTR_LAB_8cd70084,r5                              = 8c117406
        8cd70080 2b 45           jmp        @r5=>LAB_8c117406
        8cd70082 08 f1           _fmov.s    @r0=>lips_text_limit,fr1                         = 38.0
                             PTR_LAB_8cd70084                                XREF[1]:     get_new_lips_char_limit:8cd7007e
        8cd70084 06 74 11 8c     addr       LAB_8c117406
                             lips_text_limit                                 XREF[2]:     get_new_lips_char_limit:8cd7007c
                                                                                          get_new_lips_char_limit:8cd70082
        8cd70088 00 00 18 42     float      38.0

Translating the Kinematron Hint

When the portable Kinematron is showing a text message, the TV screen presents a message to the player informing them to look at their controller to read the message. This message is hardcoded at 8c22106b. To read this string, the program first retrieves a pointer to an earlier string at 8c221020 and adds 0x4b to it. The pointer is used only by the function that retrieves the Kinematron hint; the first string itself is never read by this function.

        8c125774 4a d0           mov.l      PTR_DAT_8c1258a0,r0                              = 8c221020
        8c125776 4b 70           add        #0x4b,r0
        8c125778 4a d2           mov.l      DAT_8c1258a4,r2                                  = 00000274h
        8c12577a fc 32           add        r15,r2
        8c12577c 02 22           mov.l      r0=>s_kinematron_hint,@r2                         = 81h,"i",8Ch,"g",91h,D1h,83h,"L

...

                             PTR_DAT_8c1258a0                                XREF[1]:     8c125774(R)  
        8c1258a0 20 10 22 8c     addr       DAT_8c221020

The message can be changed by changing the pointer to a later location and changing the add instruction to a nop. This will change the location of the hint to 8cd90d00 in SKFONT.CG:

        8c125774 4a d0           mov.l      PTR_DAT_8c1258a0,r0                              = 8cd90d00
        8c125776 09 00           nop

...

                             PTR_DAT_8c1258a0                                XREF[1]:     8c125774(R)  
        8c1258a0 00 0d d9 8c     addr       DAT_8cd90d00