Dragon Quest III (SNES)/ROM map: Difference between revisions

From Data Crystal
Jump to navigation Jump to search
m (Fix typo; fix incorrect pointers for dialogue font metadata table)
(added monster data structure)
Line 78: Line 78:
For now, these are rom file addresses. Placeholder for much more complete monster info.
For now, these are rom file addresses. Placeholder for much more complete monster info.
The data will be moved out and a more general explanation will be added.
The data will be moved out and a more general explanation will be added.
===Primary Data Structure===
The main data structure starts at <code>$c20000</code>. Each entry is $25 bytes long.
{| class="wikitable sortable"
|-
!  Offset  !!  Mask  !! Size  !!  Description
|-
|  $00-$01  ||  $ffff  ||  word  ||  Name, index of string
|-
|  $02  ||  $3f  ||  6 bits  ||  Level
|-
|  $02  ||  $40  ||  bit  ||  Is a Dragon
|-
|  $02  ||  $80  ||  bit  ||  Is a Zombie, doesn't seem to actually be checked
|-
|  $03-$04  ||  $ffff  ||  word  ||  Experience given when beaten
|-
|  $05-$06  ||  $03ff  ||  10 bits  ||  Gold given when beaten
|-
|  $06-$07  ||  $0ffc  ||  10 bits  ||  Attack Power
|-
|  $07-$08  ||  $3ff0  ||  10 bits  ||  Defensive Strength
|-
|  $08-$09  ||  $ffc0  ||  10 bits  ||  Palette, index
|-
|  $0a  ||  $ff  ||  byte  ||  Agility
|-
|  $0b  ||  $ff  ||  byte  ||  MP
|-
|  $0c  ||  $ff  ||  byte  ||  Item, can be given when beaten
|-
|  $0d  ||  $ff  ||  byte  ||  Sprite, index
|-
|  $0e-$0f  ||  $01ff  ||  9 bits  ||  Command 0
|-
|  $0f-$10  ||  $03fe  ||  9 bits  ||  Command 1
|-
|  $10-$11  ||  $07fc  ||  9 bits  ||  Command 2
|-
|  $11-$12  ||  $0ff8  ||  9 bits  ||  Command 3
|-
|  $12-$13  ||  $1ff0  ||  9 bits  ||  Command 4
|-
|  $13-$14  ||  $3fe0  ||  9 bits  ||  Command 5
|-
|  $14-$15  ||  $7fc0  ||  9 bits  ||  Command 6
|-
|  $15-$16  ||  $ff80  ||  9 bits  ||  Command 7
|-
|  $17  ||  $01  ||  bit  ||  Command 0 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $02  ||  bit  ||  Command 1 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $04  ||  bit  ||  Command 2 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $08  ||  bit  ||  Command 3 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $10  ||  bit  ||  Command 4 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $20  ||  bit  ||  Command 5 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $40  ||  bit  ||  Command 6 Constraint, command can only be used once per group per turn
|-
|  $17  ||  $80  ||  bit  ||  Command 7 Constraint, command can only be used once per group per turn
|-
|  $18  ||  $0f  ||  nibble  ||  Command 0 Animation
|-
|  $18  ||  $f0  ||  nibble  ||  Command 1 Animation
|-
|  $19  ||  $0f  ||  nibble  ||  Command 2 Animation
|-
|  $19  ||  $f0  ||  nibble  ||  Command 3 Animation
|-
|  $1a  ||  $0f  ||  nibble  ||  Command 4 Animation
|-
|  $1a  ||  $f0  ||  nibble  ||  Command 5 Animation
|-
|  $1b  ||  $0f  ||  nibble  ||  Command 6 Animation
|-
|  $1b  ||  $f0  ||  nibble  ||  Command 7 Animation
|-
|  $1c  ||  $0f  ||  nibble  ||  Command 8 Animation, default for no-action taken
|-
|  $1c  ||  $30  ||  2 bits  ||  Command Selection Judgment, ??
|-
|  $1c  ||  $c0  ||  2 bits  ||  Command Decision Strategies, determines probablity table use when picking a command
|-
|  $1d  ||  $07  ||  3 bits  ||  Mikawashi ???
|-
|  $1d  ||  $38  ||  3 bits  ||  Item drop probability, probabilities are at $c2aa34
|-
|  $1d  ||  $c0  ||  2 bits  ||  Run Multiple Commands, 0=Run Once, 1=50% Run Twice, 2=Run 1 to 3 times (random), 3=Run Twice
|-
|  $1e  ||  $03  ||  2 bits  ||  Auto-recovery, heals each turn, table at $c2c3a6
|-
|  $1e  ||  $0c  ||  2 bits  ||  Concentrated Attacks, enemy group shares the same target
|-
|  $1e  ||  $30  ||  2 bits  ||  Resistance $00
|-
|  $1e  ||  $c0  ||  2 bits  ||  Resistance $01
|-
|  $1f  ||  $03  ||  2 bits  ||  Resistance $02
|-
|  $1f  ||  $0c  ||  2 bits  ||  Resistance $03
|-
|  $1f  ||  $30  ||  2 bits  ||  Resistance $04
|-
|  $1f  ||  $c0  ||  2 bits  ||  Resistance $05
|-
|  $20  ||  $03  ||  2 bits  ||  Resistance $06
|-
|  $20  ||  $0c  ||  2 bits  ||  Resistance $07
|-
|  $20  ||  $30  ||  2 bits  ||  Resistance $08
|-
|  $20  ||  $c0  ||  2 bits  ||  Resistance $09
|-
|  $21  ||  $03  ||  2 bits  ||  Resistance $0a
|-
|  $21  ||  $0c  ||  2 bits  ||  Resistance $0b
|-
|  $21  ||  $30  ||  2 bits  ||  Resistance $0c
|-
|  $21  ||  $c0  ||  2 bits  ||  Resistance $0d
|-
|  $22-$23  ||  $ffff  ||  word  ||  HP
|-
|  $24  ||  $01  ||  bit  ||  Is a Metal monster
|-  style="background-color:#eaecf0;"
|  $24  ||  $fe  ||  7 bits  ||  (Unused)
|}
====Data====


{| class="wikitable sortable"
{| class="wikitable sortable"

Revision as of 18:18, 4 April 2025

Chip tiny.png The following article is a ROM map for Dragon Quest III (SNES).

Main

For now, these are rom file addresses

Category Address Size Description
Levels $0417ad - $0418d2 98 longs (294 bytes) Soldier's experience required per level, first value is to reach level 2
??? $0418d3 - $04191f $4d bytes ???
Levels $041920 - $041a45 98 longs (294 bytes) Fighter's experience required per level, first value is to reach level 2
??? $041a46 - $041a92 $4d bytes ???
Levels $041a93 - $041bb8 98 longs (294 bytes) Wizard's experience required per level, first value is to reach level 2
??? $041bb9 - $041c05 $4d bytes ???
Levels $041c06 - $041d2b 98 longs (294 bytes) Pilgrim's experience required per level, first value is to reach level 2
??? $041d2c - $041d78 $4d bytes ???
Levels $041d79 - $041e9e 98 longs (294 bytes) Merchant's experience required per level, first value is to reach level 2
??? $041e9f - $041eeb $4d bytes ???
Levels $041eec - $042011 98 longs (294 bytes) GoofOff's experience required per level, first value is to reach level 2
??? $042012 - $04205e $4d bytes ???
Levels $04205f - $042184 98 longs (294 bytes) Thief's experience required per level, first value is to reach level 2
??? $042185 - $0421d1 $4d bytes ???
Levels $0421d2 - $0422f7 98 longs (294 bytes) Sage's experience required per level, first value is to reach level 2
??? $0422f8 - $042344 $4d bytes ???
Levels $042345 - $04246a 98 longs (294 bytes) Hero's experience required per level, first value is to reach level 2
??? $04246b - $0424b7 $4d bytes ???

Text and Script

Dialog Font

Referenced code: on github

Dialog font lookup table: data file

Category Address Size Description
Font Data $c10ed3 - $c151a9 $42d7 bytes Dialog font data
Font Settings $c151aa - $c152a3 $fa bytes Dialog font lookup table, 50 structs of 5 bytes each
Font Settings $c1bbd5 byte ROM Bank for the Dialog script font (value = $c1)

Dialog font lookup table structure

gggggggg wwwwgggg aaaaaaaa aaaaaaaa 00hhhh00

g: group size, 12 bits

w: width, 4 bits

a: offset address, 16 bits (combines with bank to create pointer to data)

h: height, 4 bits

Monsters

For now, these are rom file addresses. Placeholder for much more complete monster info. The data will be moved out and a more general explanation will be added.

Primary Data Structure

The main data structure starts at $c20000. Each entry is $25 bytes long.

Offset Mask Size Description
$00-$01 $ffff word Name, index of string
$02 $3f 6 bits Level
$02 $40 bit Is a Dragon
$02 $80 bit Is a Zombie, doesn't seem to actually be checked
$03-$04 $ffff word Experience given when beaten
$05-$06 $03ff 10 bits Gold given when beaten
$06-$07 $0ffc 10 bits Attack Power
$07-$08 $3ff0 10 bits Defensive Strength
$08-$09 $ffc0 10 bits Palette, index
$0a $ff byte Agility
$0b $ff byte MP
$0c $ff byte Item, can be given when beaten
$0d $ff byte Sprite, index
$0e-$0f $01ff 9 bits Command 0
$0f-$10 $03fe 9 bits Command 1
$10-$11 $07fc 9 bits Command 2
$11-$12 $0ff8 9 bits Command 3
$12-$13 $1ff0 9 bits Command 4
$13-$14 $3fe0 9 bits Command 5
$14-$15 $7fc0 9 bits Command 6
$15-$16 $ff80 9 bits Command 7
$17 $01 bit Command 0 Constraint, command can only be used once per group per turn
$17 $02 bit Command 1 Constraint, command can only be used once per group per turn
$17 $04 bit Command 2 Constraint, command can only be used once per group per turn
$17 $08 bit Command 3 Constraint, command can only be used once per group per turn
$17 $10 bit Command 4 Constraint, command can only be used once per group per turn
$17 $20 bit Command 5 Constraint, command can only be used once per group per turn
$17 $40 bit Command 6 Constraint, command can only be used once per group per turn
$17 $80 bit Command 7 Constraint, command can only be used once per group per turn
$18 $0f nibble Command 0 Animation
$18 $f0 nibble Command 1 Animation
$19 $0f nibble Command 2 Animation
$19 $f0 nibble Command 3 Animation
$1a $0f nibble Command 4 Animation
$1a $f0 nibble Command 5 Animation
$1b $0f nibble Command 6 Animation
$1b $f0 nibble Command 7 Animation
$1c $0f nibble Command 8 Animation, default for no-action taken
$1c $30 2 bits Command Selection Judgment, ??
$1c $c0 2 bits Command Decision Strategies, determines probablity table use when picking a command
$1d $07 3 bits Mikawashi ???
$1d $38 3 bits Item drop probability, probabilities are at $c2aa34
$1d $c0 2 bits Run Multiple Commands, 0=Run Once, 1=50% Run Twice, 2=Run 1 to 3 times (random), 3=Run Twice
$1e $03 2 bits Auto-recovery, heals each turn, table at $c2c3a6
$1e $0c 2 bits Concentrated Attacks, enemy group shares the same target
$1e $30 2 bits Resistance $00
$1e $c0 2 bits Resistance $01
$1f $03 2 bits Resistance $02
$1f $0c 2 bits Resistance $03
$1f $30 2 bits Resistance $04
$1f $c0 2 bits Resistance $05
$20 $03 2 bits Resistance $06
$20 $0c 2 bits Resistance $07
$20 $30 2 bits Resistance $08
$20 $c0 2 bits Resistance $09
$21 $03 2 bits Resistance $0a
$21 $0c 2 bits Resistance $0b
$21 $30 2 bits Resistance $0c
$21 $c0 2 bits Resistance $0d
$22-$23 $ffff word HP
$24 $01 bit Is a Metal monster
$24 $fe 7 bits (Unused)

Data

Category Address Size Description
Stats $020028 - $020029 word Monster #01 - Slime (スライム) - experience points gained: 4
Stats $02002a byte Monster #01 - Slime (スライム) - gold gained: 2
Stats $02004d - $02004e word Monster #02 - Raven (おおがらす) - experience points gained: 6
Stats $02004f byte Monster #02 - Raven (おおがらす) - gold gained: 3

Names

All strings end with ac and are encoded according to the Text Table

Index Address Size Japanese English Data
01 $3ed958 - $3ed95c 5 bytes スライム Slime 4F 69 44 63 AC
02 $3ed95d - $3ed962 6 bytes おおがらす Raven 10 10 C9 32 18 AC
03 $3ed963 - $3ed96a 8 bytes いっかくうさぎ Pointed Rabbit 0D 3F 11 13 0E 16 CA AC
04 $3ed96b - $3ed971 7 bytes おおありくい Large Anteater 10 10 0C 33 13 0D AC
05 $3ed972 - $3ed979 8 bytes じんめんちょう Human Face Butterfly CF 39 2D 39 1C 42 0E AC
06 $3ed97a - $3ed97f 6 bytes フロッガー Frogger 5E 6D 76 DE 7D AC
07 $3ed980 - $3ed987 8 bytes バブルスライム Bubble Slime ED EF 6B 4F 69 44 63 AC
08 $3ed988 - $3ed98e 7 bytes まほうつかい Magician 2A 29 0E 1D 11 0D AC
09 $3ed98f - $3ed994 6 bytes さそりばち Scorpion Wasp 16 1A 33 D8 1C AC
0a $3ed995 - $3ed99c 8 bytes ホイミスライム Hoimi Slime 60 44 62 4F 69 44 63 AC
0b $3ed99d - $3ed9a4 8 bytes おばけありくい Ghost Anteater 10 D8 14 0C 33 13 0D AC
0c $3ed9a5 - $3ed9ab 7 bytes アルミラージ Almirage 43 6B 62 69 7D E4 AC
0d $3ed9ac - $3ed9b3 8 bytes ポイズントード Poison Toad FB 44 E5 70 56 7D EC AC
0e $3ed9b4 - $3ed9ba 7 bytes キャタピラー Caterpillar 49 77 52 F8 69 7D AC
0f $3ed9bb - $3ed9c2 8 bytes こうもりおとこ Bat Man 15 0E 2E 33 10 1F 15 AC
10 $3ed9c3 - $3ed9ca 8 bytes アニマルゾンビ Animal Zombie 43 58 61 6B E7 70 EE AC
11 $3ed9cb - $3ed9d0 6 bytes キラービー Killer Bee 49 69 7D EE 7D AC
12 $3ed9d1 - $3ed9d7 7 bytes ぐんたいガニ - CB 39 1B 0D DE 58 AC
13 $3ed9d8 - $3ed9db 4 bytes ギズモ Gizmo DF E5 65 AC
14 $3ed9dc - $3ed9e2 7 bytes おばけキノコ - 10 D8 14 49 5B 4C AC
15 $3ed9e3 - $3ed9e9 7 bytes どくイモムシ - D7 13 44 65 63 4E AC
16 $3ed9ea - $3ed9f1 8 bytes デスフラッター Death Flatter EB 4F 5E 69 76 52 7D AC
17 $3ed9f2 - $3ed9f9 8 bytes バリイドドッグ Bariaid Dog ED 6A 44 EC EC 76 E0 AC
18 $3ed9fa - $3ed9fe 5 bytes マタンゴ Matango 61 52 70 E2 AC
19 $3ed9ff - $3eda05 7 bytes あやしいかげ Suspicious Silhouette 0C 2F 17 0D 11 CC AC
1a $3eda06 - $3eda0b 6 bytes バンパイア Vampire ED 70 F7 44 43 AC
1b $3eda0c - $3eda11 6 bytes ひとくいが Cannibal Moth 26 1F 13 0D C9 AC
1c $3eda12 - $3eda19 8 bytes さまようよろい Roaming Armor 16 2A 31 0E 31 36 0D AC
1d $3eda1a - $3eda21 8 bytes キャットフライ Cat Fly 49 77 76 56 5E 69 44 AC
1e $3eda22 - $3eda28 7 bytes だいおうガマ - D3 0D 10 0E DE 61 AC
1f $3eda29 - $3eda2e 6 bytes あばれザル - 0C D8 35 E3 6B AC
20 $3eda2f - $3eda35 7 bytes わらいぶくろ Laughing Sack 37 32 0D DA 13 36 AC
21 $3eda36 - $3eda3c 7 bytes ミイラおとこ - 62 44 69 10 1F 15 AC
22 $3eda3d - $3eda44 8 bytes じごくのハサミ - CF CD 13 24 5C 4D 62 AC
23 $3eda45 - $3eda49 5 bytes ドルイド Druid EC 6B 44 EC AC
24 $3eda4a - $3eda50 7 bytes かえんムカデ - 11 0F 39 63 48 EB AC
25 $3eda51 - $3eda54 4 bytes マミー Mummy 61 62 7D AC
26 $3eda55 - $3eda5c 8 bytes マージマタンゴ Mage Matango 61 7D E4 61 52 70 E2 AC
27 $3eda5d - $3eda64 8 bytes ハンターフライ Hunter Fly 5C 70 52 7D 5E 69 44 AC
28 $3eda65 - $3eda6c 8 bytes デスジャッカル Death Jackal EB 4F E4 77 76 48 6B AC
29 $3eda6d - $3eda73 7 bytes げんじゅつし Witchcraft Expert CC 39 CF 41 1D 17 AC
2a $3eda74 - $3eda7a 7 bytes ヒートギズモ Heat Gizmo 5D 7D 56 DF E5 65 AC
2b $3eda7b - $3eda80 6 bytes アントベア Ant Bear 43 70 56 F0 43 AC
2c $3eda81 - $3eda88 8 bytes ベホマスライム Behoma Slime F0 60 61 4F 69 44 63 AC
2d $3eda89 - $3eda90 8 bytes マッドオックス Mad Ox 61 76 EC 47 76 4A 4F AC
2e $3eda91 - $3eda98 8 bytes キャットバット Cat Bat 49 77 76 56 ED 76 56 AC
2f $3eda99 - $3eda9f 7 bytes エビルマージ Evil Mage 46 EE 6B 61 7D E4 AC
30 $3edaa0 - $3edaa6 7 bytes キラーエイプ Killer Ape 49 69 7D 46 44 F9 AC
31 $3edaa7 - $3edaab 5 bytes ガルーダ Garuda DE 6B 7D E8 AC
32 $3edaac - $3edab3 8 bytes メタルスライム Metal Slime 64 52 6B 4F 69 44 63 AC
33 $3edab4 - $3edab9 6 bytes ゴートドン Goat Don E2 7D 56 EC 70 AC
34 $3edaba - $3edabf 6 bytes さつじんき Devilish Murderer 16 1D CF 39 12 AC
35 $3edac0 - $3edac6 7 bytes ベビーサタン Baby Satan F0 EE 7D 4D 52 70 AC
36 $3edac7 - $3edacd 7 bytes きめんどうし Devil Mask Sorceror 12 2D 39 D7 0E 17 AC
37 $3edace - $3edad4 7 bytes ひとくいばこ Cannibal Box 26 1F 13 0D D8 15 AC
38 $3edad5 - $3edadc 8 bytes エリミネーター Eliminator 46 6A 62 5A 7D 52 7D AC
39 $3edadd - $3edae3 7 bytes おおくちばし Large Beak 10 10 13 1C D8 17 AC
3a $3edae4 - $3edaeb 8 bytes スライムつむり - 4F 69 44 63 1D 2C 33 AC
3b $3edaec - $3edaf3 8 bytes スカイドラゴン Sky Dragon 4F 48 44 EC 69 E2 70 AC
3c $3edaf4 - $3edaf9 6 bytes バーナバス Barnabas ED 7D 57 ED 4F AC
3d $3edafa - $3edafd 4 bytes まじょ Witch 2A CF 42 AC
3e $3edafe - $3edb05 8 bytes デッドペッカー Dead Pecker EB 76 EC FA 76 48 7D AC
3f $3edb06 - $3edb0d 8 bytes じごくのよろい Hell Armor CF CD 13 24 31 36 0D AC
40 $3edb0e - $3edb15 8 bytes マリンスライム Marine Slime 61 6A 70 4F 69 44 63 AC
41 $3edb16 - $3edb1c 7 bytes しびれくらげ Numb Jellyfish 17 D9 35 13 32 CC AC
42 $3edb1d - $3edb21 5 bytes マーマン Merman 61 7D 61 70 AC
43 $3edb22 - $3edb28 7 bytes だいおうイカ - D3 0D 10 0E 44 48 AC
44 $3edb29 - $3edb2d 5 bytes ガニラス Ganiras DE 58 69 4F AC
45 $3edb2e - $3edb35 8 bytes マーマンダイン Merman Dyne 61 7D 61 70 E8 44 70 AC
46 $3edb36 - $3edb3c 7 bytes ヘルコンドル Hell Condor 5F 6B 4C 70 EC 6B AC
47 $3edb3d - $3edb43 7 bytes ごうけつぐま Overpowering Bear CD 0E 14 1D CB 2A AC
48 $3edb44 - $3edb4b 8 bytes くさったしたい Rotten Corpse 13 16 3F 1B 17 1B 0D AC
49 $3edb4c - $3edb52 7 bytes ビッグホーン Big Horn EE 76 E0 60 7D 70 AC
4a $3edb53 - $3edb59 7 bytes しびれあげは Paralysis Swallowtail 17 D9 35 0C CC 25 AC
4b $3edb5a - $3edb61 8 bytes どくどくゾンビ - D7 13 D7 13 E7 70 EE AC
4c $3edb62 - $3edb67 6 bytes アカイライ Akairai 43 48 44 69 44 AC
4d $3edb68 - $3edb6f 8 bytes キラーアーマー Killer Armor 49 69 7D 43 7D 61 7D AC
4e $3edb70 - $3edb77 8 bytes デスストーカー Death Stalker EB 4F 4F 56 7D 48 7D AC
4f $3edb78 - $3edb7f 8 bytes ようがんまじん Lava Devil 31 0E C9 39 2A CF 39 AC
50 $3edb80 - $3edb85 6 bytes シャーマン Shaman 4E 77 7D 61 70 AC
51 $3edb86 - $3edb8c 7 bytes まほうおばば Magic Hag 2A 29 0E 10 D8 D8 AC
52 $3edb8d - $3edb91 5 bytes シャドー Shadow 4E 77 EC 7D AC
53 $3edb92 - $3edb99 8 bytes ひょうがまじん Glacier Devil 26 42 0E C9 2A CF 39 AC
54 $3edb9a - $3edb9d 4 bytes キメラ Chimera 49 64 69 AC
55 $3edb9e - $3edba1 4 bytes コング Kong 4C 70 E0 AC
56 $3edba2 - $3edba6 5 bytes ガメゴン Gamegon DE 64 E2 70 AC
57 $3edba7 - $3edbae 8 bytes ごくらくちょう Bird of Paradise CD 13 32 13 1C 42 0E AC
58 $3edbaf - $3edbb5 7 bytes ばくだんいわ Bomb Rock D8 13 D3 39 0D 37 AC
59 $3edbb6 - $3edbbb 6 bytes グリズリー Grizzly E0 6A E5 6A 7D AC
5a $3edbbc - $3edbc3 8 bytes ゾンビマスター Zombie Master E7 70 EE 61 4F 52 7D AC
5b $3edbc4 - $3edbcb 8 bytes ガメゴンロード Gamegon Lord DE 64 E2 70 6D 7D EC AC
5c $3edbcc - $3edbd3 8 bytes スノードラゴン Snow Dragon 4F 5B 7D EC 69 E2 70 AC
5d $3edbd4 - $3edbd7 4 bytes トロル Troll 56 6D 6B AC
5e $3edbd8 - $3edbdf 8 bytes フロストギズモ Frost Gizmo 5E 6D 4F 56 DF E5 65 AC
5f $3edbe0 - $3edbe7 8 bytes おどるほうせき Dancing Jewel 10 D7 34 29 0E 19 12 AC
60 $3edbe8 - $3edbee 7 bytes ミニデーモン Mini Demon 62 58 EB 7D 65 70 AC
61 $3edbef - $3edbf5 7 bytes テンタクルス Tentacles 55 70 52 4A 6B 4F AC
62 $3edbf6 - $3edbfd 8 bytes がいこつけんし Skeleton Swordsman C9 0D 15 1D 14 39 17 AC
63 $3edbfe - $3edc02 5 bytes ミミック Mimic 62 62 76 4A AC
64 $3edc03 - $3edc09 7 bytes じごくのきし Knight of Hell CF CD 13 24 12 17 AC
65 $3edc0a - $3edc10 7 bytes ホロゴースト Horror Ghost 60 6D E2 7D 4F 56 AC
66 $3edc11 - $3edc18 8 bytes やまたのおろち Mythical Serpent of Eight Heads 2F 2A 1B 24 10 36 1C AC
67 $3edc19 - $3edc20 8 bytes うごくせきぞう Moving Stone Statue 0E CD 13 19 12 D2 0E AC
68 $3edc21 - $3edc27 7 bytes サラマンダー Salamander 4D 69 61 70 E8 7D AC
69 $3edc28 - $3edc2e 7 bytes スライムベス Slime Bess 4F 69 44 63 F0 4F AC
6a $3edc2f - $3edc34 6 bytes マドハンド Mud Hand 61 EC 5C 70 EC AC
6b $3edc35 - $3edc3b 7 bytes まおうのかげ - 2A 10 0E 24 11 CC AC
6c $3edc3c - $3edc42 7 bytes マクロベータ Macro Beta 61 4A 6D F0 7D 52 AC
6d $3edc43 - $3edc49 7 bytes はぐれメタル - 25 CB 35 64 52 6B AC
6e $3edc4a - $3edc4d 4 bytes グール Ghoul E0 7D 6B AC
6f $3edc4e - $3edc55 8 bytes ライオンヘッド Lion Head 69 44 47 70 5F 76 EC AC
70 $3edc56 - $3edc5c 7 bytes ボストロール - F1 4F 56 6D 7D 6B AC
71 $3edc5d - $3edc63 7 bytes ゴールドマン Gold Man E2 7D 6B EC 61 70 AC
72 $3edc64 - $3edc69 6 bytes スカルゴン Skull Gon 4F 48 6B E2 70 AC
73 $3edc6a - $3edc71 8 bytes キングマーマン King Merman 49 70 E0 61 7D 61 70 AC
74 $3edc72 - $3edc77 6 bytes クラーゴン Kragon 4A 69 7D E2 70 AC
75 $3edc78 - $3edc7f 8 bytes ダースリカント Darth Rikanto E8 7D 4F 6A 48 70 56 AC
76 $3edc80 - $3edc85 6 bytes だいまじん Great Devil D3 0D 2A CF 39 AC
77 $3edc86 - $3edc8a 5 bytes ラゴンヌ Ragon'nu 69 E2 70 59 AC
78 $3edc8b - $3edc91 7 bytes アークマージ Arch Mage 43 7D 4A 61 7D E4 AC
79 $3edc92 - $3edc98 7 bytes メイジキメラ Mage Chimera 64 44 E4 49 64 69 AC
7a $3edc99 - $3edc9f 7 bytes サタンパピー Satan Puppy 4D 52 70 F7 F8 7D AC
7b $3edca0 - $3edca3 4 bytes ヒドラ Hydra 5D EC 69 AC
7c $3edca4 - $3edcaa 7 bytes トロルキング Troll King 56 6D 6B 49 70 E0 AC
7d $3edcab - $3edcaf 5 bytes ドラゴン Dragon EC 69 E2 70 AC
7e $3edcb0 - $3edcb4 5 bytes バルログ Balrog ED 6B 6D E0 AC
7f $3edcb5 - $3edcbc 8 bytes ドラゴンゾンビ Dragon Zombie EC 69 E2 70 E7 70 EE AC
80 $3edcbd - $3edcc3 7 bytes マントゴーア Mantgoa 61 70 56 E2 7D 43 AC
81 $3edcc4 - $3edcc9 6 bytes ソードイド Sword Id 51 7D EC 44 EC AC
82 $3edcca - $3edcd0 7 bytes キングヒドラ King Hydra 49 70 E0 5D EC 69 AC
83 $3edcd1 - $3edcd8 8 bytes バラモスブロス Baramos Bros ED 69 65 4F EF 6D 4F AC
84 $3edcd9 - $3edce0 8 bytes バラモスゾンビ Baramos Zombie ED 69 65 4F E7 70 EE AC
85 $3edce1 - $3edce5 5 bytes バラモス Baramos ED 69 65 4F AC
86 $3edce6 - $3edce9 4 bytes ゾーマ Zoma E7 7D 61 AC
87 $3edcea - $3edcee 5 bytes オルテガ Orutega 47 6B 55 DE AC
88 $3edcef - $3edcf3 5 bytes カンダタ Kandata 48 70 E8 52 AC
89 $3edcf4 - $3edcfb 8 bytes カンダタこぶん - 48 70 E8 52 15 DA 39 AC
8a $3edcfc - $3edd01 6 bytes けいけんち Experience Value 14 0D 14 39 1C AC
8b $3edd02 - $3edd05 4 bytes おかね Gold 10 11 23 AC
8c $3edd06 - $3edd0c 7 bytes せんたくバカ Selection Idiot 19 39 1B 13 ED 48 AC
8d $3edd0d - $3edd15 9 bytes せんたくにんげん Selection Human 19 39 1B 13 21 39 CC 39 AC
8e $3edd16 - $3edd1c 7 bytes せんたくかみ Selection Deity 19 39 1B 13 11 2B AC
8f $3edd1d - $3edd22 6 bytes せんたく0 Selection 0 19 39 1B 13 87 AC
90 $3edd23 - $3edd28 6 bytes せんたく1 Selection 1 19 39 1B 13 88 AC
91 $3edd29 - $3edd2e 6 bytes せんたく2 Selection 2 19 39 1B 13 89 AC
92 $3edd2f - $3edd34 6 bytes せんたく3 Selection 3 19 39 1B 13 8A AC
93 $3edd35 - $3edd39 5 bytes ほうおう Phoenix 29 0E 10 0E AC
94 $3edd3a - $3edd41 8 bytes てんのもんばん Heaven's Gate Watcher 1E 39 24 2E 39 D8 39 AC
95 $3edd42 - $3edd48 7 bytes メタルキメラ Metal Chimera 64 52 6B 49 64 69 AC
96 $3edd49 - $3edd51 9 bytes デビルウィザード Devil Wizard EB EE 6B 45 72 E3 7D EC AC
97 $3edd52 - $3edd58 7 bytes キラークラブ Killer Crab 49 69 7D 4A 69 EF AC
98 $3edd59 - $3edd5f 7 bytes ダークトロル Dark Troll E8 7D 4A 56 6D 6B AC
99 $3edd60 - $3edd67 8 bytes デーモンソード Demon Sword EB 7D 65 70 51 7D EC AC
9a $3edd68 - $3edd6f 8 bytes バラモスエビル Baramos Evil ED 69 65 4F 46 EE 6B AC
9b $3edd70 - $3edd75 6 bytes しんりゅう God Dragon 17 39 33 41 0E AC

Notes

All values given are ROM offsets. They assume that a 512-byte copier header is not present. If there is a header present, you will have to add 512 ($200) to each offset lister here to get the correct offset in the ROM file.

Note that the ROM is mapped into the SNES address space starting at $C00000. Therefore, if you want to use one of these ROM offsets as a breakpoint, you should add $C00000 to it. I've given a few examples below that already do this.

Menu Size Data

Almost every menu has a 16-bit (2-byte) value that determines its starting position (X/Y coordinates) and its width. Menu size data is stored in the following binary format:

%1WWW WWYY YYYX XXXX

  • WWWWW = menu width (not just usable space, this includes the edge characters)
  • YYYYY = vertical tile offset from top of screen
  • XXXXX = horizontal tile offset from left of screen

There is no value to determine the height of a menu. This is done internally by the drawing code for each individual menu.

Like almost everything else on the SNES, this data is in low-endian format. Thus, the YYYX XXXX byte comes first in the ROM, then the 1WWW WWYY byte.

Here are a few menu size values that I have found. Note again that this controls only menu width and position. Menu content string pointers are stored elsewhere.

  • $30348-$30349: Introductory menu (contains Begin a New Quest, Continue Quest, Copy Quest, etc., etc.)
  • $30378-$30379: Change Message Speed menu (opened from introductory menu)
  • $30384-$30385: Mono/Stereo selector menu
  • $30024-$30025: Main walkabout menu (contains Talk, Spell, Item, Search, Status, Tactics)
  • $300FC-$300FD: Gold menu, associated with the main walkabout menu
  • $3036C-$3036D: Change Message Speed menu (opened from Tactics)


What if the menu you want to expand (or contract!) isn't listed above? Here's how to find it.

  • Open the menu you want, and take a screenshot of it. As an example, let's try the gold box that appears when you open the main menu.
  • Open the screenshot in a paint program, and find out the X coordinate, Y coordinate, and width. Remember that these coordinates are in tiles, so you have to find the coordinate (or width) in pixels and then divide that number by 8.
  • Convert these values to hexadecimal and write them down. In this case, our X coordinate is 21 ($15), the Y coordinate is 16 ($10), and the width (including borders) is 9 ($09).
  • Open the ROM in a debugging emulator (I use Geiger's Snes9x debugging version).
  • Prepare things so that it will only take 1 more button press to get into the menu you want.
  • Set an execution breakpoint at $C90717.
  • Open the menu — this should set off the breakpoint.
  • Keep an eye on the A register.
  • You might see something like this as the breakpoint is hit four times (On Geiger Snes9x, hit the "Run" button to get to the next breakpoint).
    • $C9/0717 08 PHP A:0000 X:0000 Y:0015 P:envmxdIZc
    • $C9/0717 08 PHP A:0015 X:0000 Y:0015 P:envmxdIzc
    • $C9/0717 08 PHP A:1015 X:0000 Y:0015 P:envmxdIzc
    • $C9/0717 08 PHP A:0009 X:0000 Y:0015 P:envmxdIzc
  • This is for the gold menu. If you followed the steps above, you should see some familiar information here. Note how on the second iteration, we see the X coordinate in the accumulator, and on the third iteration, we can see both the X *and* Y coordinates in the top and bottom halves. And on the fifth iteration, there is the width.
  • Don't proceed past the fifth iteration (the one where A = menu width). Instead, single step ("Step Into" button on Geiger Snes9x) until you get to $C902B1.
  • You'll see something like this:
    • $C9/02B1 33 10 AND ($10,s),y[$C3:00FD] A:0F80 X:00C3 Y:0000 P:envmXdIzc
  • See that [$C3:00FD]? Now just take that number and subtract $C00001 (yes, $C00001, not $C00000) from it.
  • We now have the location of the menu size data; in this case, $300FC. Remember that the value at this address is two bytes long, and low-endian.
  • Note that, in some cases, there will be unwanted $C90717 breakpoints before the one we're looking for. That's why you should monitor the A register and make sure we're looking at the right iteration. The method I detailed above works only if you check the address on the iteration that contains the menu width ($0009, in this case).

Menu Text Pointers

To change the menu text, you need to find the pointers for that text. In most cases, this pointer is actually the 16-bit operand of an LDA opcode. Pointers can usually only reference the 64K block of memory from which they are called; in other words, if a pointer is at $360D1 in the ROM, it can't reference anything above $3FFFF or below $30000. In some cases, a pointer can't be made to point backwards without further hacking, because of the way that they are referenced. (More to come...) Fortunately, this shouldn't really be a big issue, because there is a block of apparently unused space (solid $FFs) from $3F30A-$3FFFF. Most pointers are in the range of this memory. (Please let me know if I'm mistaken and this empty space actually serves a purpose!)

A list of menu pointers can be found at the Kojiro Translations wiki.

Menu Padding Routine

Some menu entries have extra spaces padded onto the end that is not accounted for by the data at the expected pointers. These spaces are inserted by the use of a special routine located at $32B70 in the ROM. When this routine is called, the X register contains the number of spaces to insert. If you're doing some menu expansion, you may have to set breakpoints at $C32B70. Single-step through until RTL is executed, so you can see where it came from, and then back up five bytes from the resulting address. If these padding spaces are throwing off your menu borders, replace the JSL $C32B70 opcode with four NOPs.

Calling $32B8D inserts a single dummy space. The "Change Message Speed" option on the "Tactics" menu uses this method, so look out for it if you're editing that menu item. There may be others I haven't found yet that do the same thing. Again, you can track down the originating JSL opcode by breaking on the subroutine start, stepping through until RTL is executed, and then subtracting five bytes from the program counter at that point.

Overworld Map

The overworld map is made up of a 64x64 grid of chunks which are a 4x4 grid of 16x16 pixel tiles which are really four 8x8 tiles. This results in a 4096x4096 pixel sized map.

Top level grid

Location in ROM: $2D8A00 - $2D9BE2

The top level of the overworld tilemap data is a 64x64 grid composed of a word length (2 byte) index indicating which chunk to use. This is $2000 bytes. Most of the data is just a counter that increments by one each time since most of the land chunks are unique. However the open parts of the sea are represented by chunk $0001 so you will see long runs of that index. Some other reused chunks are composed of all desert or all forest or all grass, that kind of thing. Values range from $0001 to $0A3C, and $0000 is not used although is a valid chunk made of zeros.

Decompression uses a $400 byte ring buffer that is all zeros at the beginning and a starting write position of $3BE. Every decompressed byte is written to the output and the ring buffer. The compressed data is composed of a command byte followed by 8 to 16 data bytes. For each bit in the command byte, if the bit is 1 then read and write one byte. If the bit is 0 then perform a copy operation from the ring buffer using the next two bytes of source data. The 10 lower bits are a pointer into the ring buffer that will be used as the source address. The number of bytes to copy is the upper 6 bits plus 3. Note that the copied bytes are written to the output and also into the ring buffer so if the buffer read address is close behind the buffer write address then you're copying what was just written. This is mostly used to generate long stretches of $0001 which represents the chunks of open sea.

Chunks

Location in ROM: $2DA49C - $2E486B‬

The chunks are 4x4 grids of tile indexes (1 byte) accessed with an index. The chunk data is in one contiguous area but is actually 16 different byte arrays, one after another and each one $A3D bytes long, so that all 16 tiles can be accessed with the same index.

The starting addresses for each array are shown in the layout the tiles appear on screen:

X + 0 X + 1 X + 2 X + 3
Y + 0 $2DA49C $2DAED9 $2DB916 $2DC353
Y + 1 $2DCD90 $2DD7CD $2DE20A $2DEC47
Y + 2 $2DF684 $2E00C1 $2E0AFE $2E153B
Y + 3 $2E1F78 $2E29B5 $2E33F2 $2E3E2F

Values range from $00 to $EC because the definitions for tiles $ED to $FF are not loaded, although there is space in RAM for them.

Tiles

Location in ROM: $254F38 - $25569F

Each entry is 8 bytes with each 2 bytes representing one of the 4 tiles (8x8) that make up the larger 16x16 tile. These 2 byte parts are in the standard SNES tilemap format and are copied as is into VRAM.

Japanese Dialogue Text

In the Japanese game revision with CRC32 13836bd2, text is compressed with Huffman coding, and spans the range $3CC258 to $3ECFB5 in the ROM. This section assumes that you are familiar with how Huffman coding works. Pointers and data in the examples are based on the previously mentioned revision.

It is worth noting that the dialogue in Dragon Quest VI SNES uses the exact same system, only with different pointers and table sizes.

Huffman tree data

Two parallel data blocks, each $7D4 bytes ($3EA two-byte entries): one from $159D3-$161A6 (for 0 bits, "left"), and another from $161A7-$1697A (for 1 bits, "right"). The blocks are parallel in that the number of entries into a block represents a split point in the Huffman tree, either left or right. A two-byte (little endian) entry has a flag for inner/leaf node in the tree (MSB set = inner node, MSB clear = leaf node). Inner nodes encode the byte position to go to for checking the next bit. Leaf nodes contain the character encoding value itself.

As an example, tree entry $3E4 represents the offsets $159D3 + $3E4*2 = $1619B (left) and $161A7 + $3E4*2 = $1696F (right). The data at each offset is, respectively, $0200 (leaf node for character encoding $0200 = a space) and $87BC. The latter represents an inner node for the byte position $7BC in the tree data, which corresponds to tree entry ($7BC >> 1) = $3DE.

Text pointer table

Range $15331-$1591E in the ROM. It consists of $1FA three-byte entries, each of which is for a block of 8 strings, except the last one which has 7. Thus, there is a total of $FCF (4047) strings. Each string is terminated with the control code 00AC or 00AE.

The 24 bits of a text pointer consist of two parts. The high 21 bits represent a byte offset from the start of the script at $3CC258, and the low 3 bits represent a bit within that byte (bit 7 is the most significant, bit 0 is the least significant).

As an example, the bytes of the sixth pointer value at $15340 are 79 12 00, or the hex value $001279. The bit offset is ($001279 & 7) = 1. The byte offset is ($001279 >> 3) = $24F. So the sixth pointer goes to byte ($3CC258 + $24F) = $3CC4A7 at bit position 1.

Decompression example

To decompress a character from the script, feed in text bits to the Huffman tree, starting at tree position $3E9 (end position in the tree). In the text data, start at the bit position in the byte and going "left to right" = from most significant to least significant. Keep getting offsets in the Huffman tree data until you reach a leaf node.

If you were to feed in bits starting at $3CC4A7 bit position 1, you should start on the 111111_0_1 bit of the FD byte there, consume the twelve bits 01 1111 1010 01 in the buffer from the FD FA 76 bytes, and take a path in the Huffman tree data to ROM position $166C1 (character value $0521, ツ).

Dialogue Font

There are two blocks of data for the variable-width and variable-height font: a metadata table from $151AA-$152A3, and the compressed font data itself from $10ED3-$151A9.

Font metadata table

The table consists of 50 five-byte entries that come in the following binary format:

SSSSSSSS WWWWSSSS [bank $C1 offset] --HHHH--

W = character width, H = character height

S = number of characters in a group for a particular W*H pair

The bank number being $C1 is hard-coded into the LDA #$C1 instruction at $1BBD4. Which is to say, the `C1` byte is located at $1BBD5.

Summary of font metadata table

Font data compression format

The 1bpp font data for each character is stored as a block of W*H bits in the appropriate range. TODO add more to this.

Links

None currently.