Zen Nihon GT Senshuken Server Technical Documentation 0.2
July 28, 2024
Shonumi aka D.S. Baxter, Winter1760

***************************************************
1. Introduction
***************************************************

Zen Nihon GT Senshuken (released as Top Gear GT Championship in the west) is a behind-the-car racing game for the Game Boy Advance. It served as a launch title in Japan and supported the Mobile Adapter GB for several functions including downloading custom racetracks and ghost car data, as well as uploading race result to get ranked.

***************************************************
2. Server Structure
***************************************************

Zen Nihon GT Senshuken is currently known to access the following URLs:

* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtconfig.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/100.gtexcrs***.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst00.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst01.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst02.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst03.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst04.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst05.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/gtgst06.cgb

Additionally, the following files are accessed with a URL prefix defined in gtconfig.cgb:

* gtrkconfig.cgb
* gtrk00.cgb
* gtrk01.cgb
* gtrk02.cgb
* gtrk03.cgb
* gtrk04.cgb
* gtrk05.cgb
* gtrk06.cgb

Finally, ghost data can have any file name prefixed with "http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/".


***************************************************
3. gtconfig.cgb
***************************************************

This file configures downloads for additional courses, Time Trial Ghosts, and online mobile rankings. gtconfig.cgb is only 200 bytes (0xC8) in size, as the game will not process any data beyond that. The format is as follows:

----------------------------------
File Structure
----------------------------------
0x00				::	Service status bitfield, see below.
0x01				::	Enables Time Trial Ghost downloads for select race tracks.
0x02				::	Downloadable course ID.
0x03				::	Course ID for ghost uploads.
0x04 - 0xC3			::	Dynamic URL data for mobile rank files. Uses ASCII characters.
0xC4 - 0xC7			::	A 32-bit checksum for all bytes from 0x00 - 0xC3. All bytes are added, one-by-one. Checksum stored LSB first.

Byte 0x00 is a bitfield indicating the current service status. When Bit 1 is set, course downloads cannot be accessed, with an error message implying that the service will not return. When Bit 1 is clear but Bit 0 is set, course downloads cannot be accessed, with an error message implying that the outage is temporary. Only when both bits are clear can course downloads be accessed. Bits 5 and 4 apply in the same way to all other services.

When downloading Time Trial Ghosts, the game will display 7 menus, 1 for each race track. For Byte 0x01, each of the bits from Bit 0 through Bit 6 controls whether an individual track is enabled. Setting the bit to "0" enables it, while setting the bit to "1" disables it. 

When downloading extra courses, Byte 0x02 is converted to Base 10 (decimal) and appended to the file name as a 3 digit number. For example, if the value of Byte 0x02 is 0x30, the game will download the file "100.gtexcrs048.cgb" for the course.

The game's programmers evidently tried to prevent ghost uploads for custom courses other than the one whose ID matches Byte 0x03, but in practice, the upload still goes through, rendering Byte 0x03 meaningless.

The dynamic URL data is an ASCII string terminated with a null character (0x00). The string points the game to the file gtrkconfig.cgb as well as the gtrk00.cgb through gtrk06.cgb files.


***************************************************
4. gtrkconfig.cgb
***************************************************

The purpose of this file is similar to gtconfig.cgb. It controls which menus to display for online mobile rankings. It has a total length of 8 bytes. The last 4 bytes compose a simple additive checksum of the file's first half. The format is as follows:

----------------------------------
File Structure
----------------------------------
0x00				::	Enables mobile rankings for select race tracks.
0x01				::	Enables ghost uploads for select race tracks.
0x02 - 0x03 			::	Unused.
0x04 - 0x07			::	A 32-bit checksum for all bytes from 0x00 - 0x03. All bytes are added, one-by-one. Checksum stored LSB first.

When downloading mobile rankings, the game will display 7 menus, 1 for each race track. For Byte 0x00, each of the bits from Bit 0 through Bit 6 controls whether an individual track is enabled. Setting the bit to "0" enables it, while setting the bit to "1" disables it. Byte 0x01 is intended to apply in the same way to ghost uploads, but like Byte 0x03 of gtconfig.cgb, all uploads go through regardless of Byte 0x01.


***************************************************
5. 100.gtexcrs***.cgb
***************************************************

This file represents a custom racetrack that can be downloaded from the servers and saved on the player's game cartridge. It is available through the Mobile Menu and selecting Course Download. A 100 yen service charge is attached to each download. The "***" part of the file name is replaced by Byte 0x02 of gtconfig.cgb when converted into a 3-digit decimal. The file length is 272 bytes total. The format is as follows:

----------------------------------
Racetrack Download Format
----------------------------------
0x0000				::	Course ID. Used to prevent purchasing the same course twice.
0x0001				::	A value of 0x01 changes the scenery to promote the Famitsu magazine.
0x0002 - 0x0003			::	Unused. Should be zero.
0x0004 - 0x001B			::	11 character title. Uses a custom 16-bit character encoding.
0x001C - 0x010B			::	Racetrack data.
0x010C - 0x010F			::	A 32-bit checksum for all bytes from 0x0000 - 0x010B. All bytes are added, one-by-one. Checksum stored LSB first.

The format of the racetrack data is identical to the same data saved on the cartridge when a user creates their own custom track. Each racetrack consists of a 10x6 grid wherein blocks of the track are positioned. The binary data for the racetracks allocates 4 bytes for each block. Blocks are arranged left to right, top to bottom. The format is as follows:

----------------------------------
Racetrack Block Format
----------------------------------
0x00				::	Block Type. 0x01 = Straight Track, 0x02 = Turn, 0x03 = Starting Position.
0x01				::	Turn Type or Starting Position Type.
0x02				::	Must be 0x01 to signal a valid block.
0x03				::	Not used, reads 0x00.

Depending on whether the block is a turn or a starting position, Byte 0x01 has different meanings. They are listed below:

----------------------------------
Block Turn Types
----------------------------------
0x00				::	East-to-South turn.
0x01				::	South-to-West turn.
0x02				::	West-to-North turn.
0x03				::	North-to-East turn.

----------------------------------
Block Starting Position Types
----------------------------------
0x00				::	Start race facing East.
0x01				::	Start race facing South.
0x02				::	Start race facing West.
0x03				::	Start race facing North.


***************************************************
6. gtgst00.cgb - gtgst06.cgb
***************************************************

These 7 files represent menus for different ghost data that can be downloaded. From this menu, the player can choose a specific ghost from a specific track and then proceed to save it to the game cartridge. Each file 0x9E4 bytes long. Together, they give the player access to 210 sets of ghost data for each of the 7 race courses available (30 per track). The file for each .cgb file is as follows

----------------------------------
Ghost Menu File Structure
----------------------------------
0x0000 - 0x0007			::	Local timestamp for last update.
0x000A - 0x09DF			::	Ghost Data Entries.
0x09E0 - 0x09E3			::	A 32-bit checksum for all bytes from 0x0000 - 0x09DF. All bytes are added, one-by-one. Checksum stored LSB first.


----------------------------------
Ghost Data Entries
----------------------------------
0x00 - 0x33			::	Mobile Rank Entry.
0x34 - 0x53			::	URL to download the ghost data. Uses ASCII characters.

Each Ghost Data Entry takes up 84 bytes. Once the player selects an entry, the game goes on to download the file specified by the URL. The URL in the entry is limited to 32 characters. Ultimately, if the URL is something like "myghostfile.cgb", the game ends up downloading from the following address:

http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/myghostfile.cgb

The URL must contain one or two dots. If it contains one dot, it is marked as free in the download menu. If it contains two dots, it must have a service fee of 0, 50, 100, 150, 200, 250, or 300 yen (which is shown in the download menu), or the entry will not be displayed.

The total time used for the ghost is stored in a 32-bit value. The overall time works based on 1/100s of a second. To calculate the total time, start counting at zero and add according to this table:

----------------------------------
Ghost Entry Time Format
----------------------------------
0x00				::	Time = Time + (1/100) * Byte Value
0x01				::	Time = Time + (256 * (1/100)) * Byte Value
0x02				::	Time = Time + (65536 * (1/100)) * Byte Value
0x03				::	Time = Time + (16777216 * (1/100)) * Byte Value

The maximum time alotted for any Ghost is 99 minutes, 59 seconds, and 99 hundredths of a second.


***************************************************
7. Ghost Data
***************************************************

The actual Ghost Data downloaded from the servers is saved to Flash RAM inside the cartridge. A fairly large portion of the 64KB of backup data is reserved just for Time Trial ghosts, and out of all the downloadable content, Ghost Data is potentially the largest. The file format is described below.

----------------------------------
Ghost Data File Format
----------------------------------
0x00 - 0x33			::	Mobile Rank Entry.
0x34 - EOF			::	Track Movement Data.

This is the only file where Byte 0x00 of the Mobile Rank Entry is used. This forces the game to run that exact course, regardless of which menu it was downloaded from online. A list of all possible options follows:

----------------------------------
Ghost Race Track Values
----------------------------------
0x00				::	Twin Ring Motegi
0x01				::	Fuji Speedway
0x02				::	Sportsland Sugo
0x03				::	Ti Circuit Aida
0x04				::	Central Park Mine Circuit
0x05				::	Suzuka Circuit
0x06				::	EDIT - 1st custom course name
0x07				::	EDIT - 2nd custom course name
0x08				::	EDIT - 3rd custom course name
0x09				::	Twin Ring Motegi (Mirror)
0x0A				::	Fuji Speedway (Mirror)
0x0B				::	Sportsland Sugo (Mirror)
0x0C				::	Ti Circuit Aida (Mirror)
0x0D				::	Central Park Mine Circuit (Mirror)
0x0E				::	Suzuka Circuit (Mirror)
0x0F				::	EDIT - (Mirror) 1st custom course name
0x10				::	EDIT - (Mirror) 2nd custom course name
0x11				::	EDIT - (Mirror) 3rd custom course name

Time Trial Ghost Data can apply to custom courses as well, thus allowing players of Zen Nihon GT to both download a unique track from the server as well as a ghost for it as well. Mirrored versions of each course is also available.

The Track Movement Data is a recording of a car's movements along the race course. For the downloaded file, it has the exact same format as regular Time Trial ghosts made locally by the player and saved on the cartridge. Zen Nihon GT essentially copy + pastes this section to Flash RAM as is, only adding a checksum every 4KB. No checksum is need for the file itself.


***************************************************
8. gtrk00.cgb - gtrk06.cgb
***************************************************

These files are the online mobile rankings. Players could sumbit their completion times for a certain race track (in the form of a Time Trial Ghost) and the fastest times would be listed for all to see. It was essentially a somewhat static leaderboard, as it required the player to manually send data to the servers. The exact URL is specified by the first string in gtconfig.cgb. Each file is 0xA34 bytes long. The format is as follows:

----------------------------------
Mobile Ranking File Format
----------------------------------
0x0000 - 0x0007			::	Local timestamp for last update.
0x0008 - 0x0A2F			::	Mobile Rank Entries.
0x0A30 - 0x0A33			::	A 32-bit checksum for all bytes from 0x0000 - 0x0A2F. All bytes are added, one-by-one. Checksum stored LSB first.

Each file corresponds to a different race track and contains 50 entries. Each entry is 52 bytes long. The format of these entries (nearly identical to Ghost Data Entries) is as specified:

----------------------------------
Mobile Rank Entry
----------------------------------
0x00				::	Race Track (see above).
0x01				::	Weather condition for ghost data (0 = Sunny, 1 = Rain).
0x02				::	Car type used for the race.
0x03				::	Car transmission used for the race (0 = Automatic, 1 = Manual).
0x04				::	Gear Ratio (0 = Low, 1 = Medium, 2 = High).
0x05				::	Steering (0 = Slow, 1 = Medium, 2 = Quick).
0x06				::	Brake (0 = Soft, 1 = Medium, 2 = Hard).
0x07				::	Tire (0 = Soft, 1 = Medium, 2 = Hard).
0x08				::	Aerodynamics (0 = Low, 1 = Medium, 2 = High).
0x09				::	Course ID (for custom courses).
0x0A - 0x0B			::	Unused. Should be zero.
0x0C - 0x0D			::	Handicap Weight in kilograms. 16-bit value stored LSB first. Max value is 990, game displays values as units of 10 (e.g. 10, 20, 30, 40...). May be zero.
0x0E - 0x23			::	11 character player name. Uses a custom 16-bit character encoding.
0x24 - 0x27			::	Course Completion Time. 32-bit value stored LSB first. Same format as Ghost Time, see notes above.
0x28 - 0x2F			::	GMT timestamp for registration.
0x30 - 0x33			::	Ghost ID. 32-bit value stored LSB first. Must not be zero.

----------------------------------
Timestamp
----------------------------------
0x00 - 0x01			::	Year. 16-bit value stored LSB first.
0x02				::	Month.
0x03				::	Day.
0x04				::	Hour.
0x05				::	Minute.
0x06				::	Second.
0x07				::	Unused. Should be zero.


***************************************************
9. Ghost Entry
***************************************************

Players could enter their Time Trial Ghosts to participate in online mobile rankings. Zen Nihon GT transfers to Ghost Data to the server and the leaderboard would be updated. It is unknown if the process was manually handled by server administrators or if server-side software automatically parsed and sorted the fastest times. The game transmits the data as part of an email attachment via SMTP. The format of the sent email is as follows:

From: xxxxxxxx@yyyy.dion.ne.jp
To: 
Subject: GT-CHAMP-ENTRY
X-Game-code: AGB-AGTJ-00
X-Game-title: GT-CHAMP
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="--AGB-AGTJ"
----AGB-AGTJ
Content-Type: text/plain; charset=iso-2022-jp
Context-Transfer-Encoding: 7bit
-----------------------
【全日本ＧＴ選手権】でランキング登録が失敗している可能性があります。
-----------------------
----AGB-AGTJ
Content-Type: application/octec-stream; name="gtent**.cgb"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="gtent**.cgb"
DATA
DATA
DATA
----AGB-AGTJ--

The message, encoded as ISO-2022-JP, translates to: "There is a possibility that ranking registration has failed in the [All Japan GT Championship]." "octec-stream" is not a typo.

The attached file varies depending on which race track was recorded in the Time Trial Ghost. The server will receive files from gtent00.cgb through gtent06.cgb in the following format:

----------------------------------
Ghost Entry Format
----------------------------------
0x0000 - 0x001F			::	Player's email address.
0x0020 - 0x0053			::	Mobile Rank Entry.
0x0054 - 0x2FAB			::	Track Movement Data.
0x2FAC - 0x2FAF			::	Always zero.
0x2FB0 - 0x2FB3			::	A 32-bit checksum for all bytes from 0x0000 - 0x2FAF. All bytes are added, one-by-one. Checksum stored LSB first.

The player name as uploaded is limited to 5 characters. The Ghost ID as uploaded is calculated by starting with 0x20031DC, adding the remaining bytes of the Mobile Rank Entry, then adding all bytes of the Track Movement Data, one-by-one.


***************************************************
10. Character Encoding
***************************************************

	0	1	2	3	4	5	6	7	8	9	A	B	C	D	E	F
0x000	 	!	"	#	$	%	&	'	(	)	*	+	,	-	.	/
0x010	0	1	2	3	4	5	6	7	8	9	:	;	<	=	>	?
0x020	@	A	B	C	D	E	F	G	H	I	J	K	L	M	N	O
0x030	P	Q	R	S	T	U	V	W	X	Y	Z	[	¥	]	^	_
0x040	`	a	b	c	d	e	f	g	h	i	j	k	l	m	n	o
0x050	p	q	r	s	t	u	v	w	x	y	z	{	|	}	~	〒
0x060	☆	★	○	●	◎	◇	◆	□	■	△	▲	▽	▼	❤	♂	♀
0x070	\	≠	＜	＞	±	✕	÷	‖	‘	’	“	”	〔	〕	《	》
0x080	 	。	「	」	、	・	ヲ	ァ	ィ	ゥ	ェ	ォ	ャ	ュ	ョ	ッ
0x090	ー	ア	イ	ウ	エ	オ	カ	キ	ク	ケ	コ	サ	シ	ス	セ	ソ
0x0A0	タ	チ	ツ	テ	ト	ナ	ニ	ヌ	ネ	ノ	ハ	ヒ	フ	ヘ	ホ	マ
0x0B0	ミ	ム	メ	モ	ヤ	ユ	ヨ	ラ	リ	ル	レ	ロ	ワ	ン	゛	゜
0x0C0	‥	…	ヰ	ヴ	ヱ	 	ガ	ギ	グ	ゲ	ゴ	ザ	ジ	ズ	ゼ	ゾ
0x0D0	ダ	ヂ	ヅ	デ	ド	パ	ピ	プ	ペ	ポ	バ	ビ	ブ	ベ	ボ	♪
0x0E0	∞	【	】	℃	¢	£	§	＝	～	™	©	®	→	←	↑	↓
0x0F0	 	。	『	』	、	・	を	ぁ	ぃ	ぅ	ぇ	ぉ	ゃ	ゅ	ょ	っ
0x100	ー	あ	い	う	え	お	か	き	く	け	こ	さ	し	す	せ	そ
0x110	た	ち	つ	て	と	な	に	ぬ	ね	の	は	ひ	ふ	へ	ほ	ま
0x120	み	む	め	も	や	ゆ	よ	ら	り	る	れ	ろ	わ	ん	゛	゜
0x130	‥	…	ゐ	 	ゑ	 	が	ぎ	ぐ	げ	ご	ざ	じ	ず	ぜ	ぞ
0x140	だ	ぢ	づ	で	ど	ぱ	ぴ	ぷ	ぺ	ぽ	ば	び	ぶ	べ	ぼ

For user input, the game uses characters 0x000, 0x081, 0x084, 0x0F5, and 0x100. Characters 0x0BE and 0x0BF appear on the katakana keyboard, while characters 0x12E and 0x12F appear on the hiragana keyboard, though none are actual input characters, and they are unlikely to have been used in downloadable content. Characters 0x0C0, 0x0C1, 0x130, and 0x131 are not available for user input, so it is unknown which, if any, were used in downloadable content. Character 0x135, along with all characters starting at 0x14F, have garbage tile data and should not be used. Finally, character 0xFFFF is used as a terminator.
