Pmd2 SSB

From ProjectPokemon Wiki
Revision as of 22:22, 15 April 2016 by UniqueGeek (talk | contribs) (→‎File Format: Added distinction between US and EU header formats →‎String table entry: The string table metadata is relative to each table)
Jump to navigation Jump to search

SSB files are always found with an associated .SSA, .SSE, or .SSS file, with the single exception of unionall.ssb, found in the /SCRIPT/COMMON/ folder of the Nitro File System. These files contain the actual scripting code, much like the canon series of Pokémon games. The main differences are the number and format of these commands.

SSB files are all 16-bit word-based. Because of this, the file itself must be an even number of bytes, and in fact the string and constant tables have special rules to ensure this.

Special cases

unionall

This file is a very special case for two reasons. It does not have an SSA, SSE, or SSS file connected with it, and it stays in memory for the entire time scripts are being run.

This is the master script that is the first to run when the power is turned on, and handles all the scene changes, events, and anything else that can be scripted. The entire titlescreen is run with unionall.ssb, as is the entire game. It is the ONLY script that is called through ASM, and is put in a very special location in memory, staying there until the game is turned off.

When scripts end that this script calls, the script continues from where it left off, doing various things depending on the outcome of these scripts. More research needs to be done to find out everything this script does.

File Format

Header

The header format differs slightly depending on the game's region. This is because while the US version stores only 1 language, the European game stores 5, each in its own string table.

Header (US)

Hex Short Name Description
00 numConst The number of 'constants' in the file
02 numString The number of 'strings' in the file
04 offsetConst First const offset or beginning of string table
06 sizeConst Size of the 'constant' table (in words)
08 sizeString Size of the 'string' table (in words)
0A unknown Unknown
0C data... Script data
...

Header (European)

Hex Short Name Description
00 numConst The number of 'constants' in the file
02 numString The number of 'strings' in each string table
04 offsetConst First const offset or beginning of string table
06 sizeConst Size of the 'constant' table (in words)
08 sizeEnglish Size of the 'English' table (in words)
0A sizeFrench Size of the 'French' table (in words)
0C sizeGerman Size of the 'German' table (in words)
0E sizeItalian Size of the 'Italian' table (in words)
10 sizeSpanish Size of the 'Spanish' table (in words)
12 data... Script data
...

Data

Header

Hex Short Name Description
00 LEN Length of data, usually first constant offset + 2*numConst
02 numGroups The number of 'groups' in the file
04 entry... (numGroup entries) Group entries
06
08
... more groups if numGroups > 1 extra groups, up to numGroups
... commands... (LEN words) Script commands area

Groups

Hex Short Name Description
00 scriptLoc Commands location (will always be at the start of a valid command)
02 type? possibly the type of group? unsure
04 unknown Unknown (char if type=3?)

Commands

Main article: Table of PMD2 Scripting Commands

Time/Darkness

Time has 0x150 commands in total in its scripting subsystem. It is currently unknown what every one does, but a lot have been figured out.

Sky

Sky has 0x180 commands in total in its scripting subsystem. It is currently unknown what every one does, but a lot have been figured out. Also, EVERY command from Time is in these commands as well. This means there are 0x30 new commands introduced in Sky. Some of the old commands are also changed slightly.

The introduced commands were inserted into various locations in the time commands, which means the same command in Time/Darkness and Sky usually has two different command numbers. For example, 0x8B in Time is the same as 0x9D in Sky.

Constants/strings tables

If there is nothing in a particular table, then that table is omitted. The strings table strings are at (offset from string table) + (LEN).

The constant table strings have offsets as if they were part of the string table. Therefore, the constants are actually at (offset from const table) + (LEN) - (2 * numStrings). Another way of calculating the constants offset is assume the first offset leads to offsetConst, subtract the first offset from all the others and you will get the offset from offsetConst. Or (offset from const table) - (first offset from const table) + (offsetConst)

Regardless of the table, if the size in bytes of the table + offsets is an odd number, then an extra null byte is added to the end of the otherwise complete table before being stored.

Constant table entry

0000: (word) start of string + 2* num strings.

String table entry

0000: (word) start of string (from the beginning of the string table).

Const/String

The differences between these two types of strings are unknown. What is known is as follows:

  • Every constant and every string is null-terminated.
  • Constants are always in all-caps
  • Strings can hold special formatting instructions and be any conceivable length
  • Commands that accept strings will also accept constants and display them as if they would a string.
  • Commands that accept constants can conceivably accept strings, but it is unknown if this will work in most cases

Notes

Constant Locations

Constant offsets - 2*numStrings = actual constant locations.

It is unclear why this is the case, but it is clear that the script commands act as if constants and strings were all in the same big array.