Phoenix’s tech blog


GTA2 map and graphics loader


Date posted: May 5th, 2008 (checksum: F6BAD0746A0F1AA5)

In past few days I wrote GTA2 map and graphics (”style”) loader. They follow format docs from DMA design, but there are some unknown chunks in each format, they are not really important though.

Map convert utility (GMP -> RMP map format, opengta2 celled map format):

Graphics convert utility (STY -> RIM, opengta2 texture pack files):
vsm4f3tmp.jpg

Map rendered in-game (without texture rotation and slopes yet):

Commerical district port area (without textures):

GTA2 sounds


Date posted: April 30th, 2008 (checksum: E7EF1CAAE2E1A651)

So here is my new idea - OpenGTA2 project! This will be a remake/redo of original GTA2, with same graphics, but new gameplay, also possibly better and up-to-date multiplayer.

Today I wrote a GTA2 sound extractor - it extracts in-game sounds into separate WAV files, instead of GTA2 .SDT/.RAW formats.

Here is it: http://users.d2k5.com/Black%20Phoenix/files/soundext2.rar

GTA2 sound format was easy, to figure it out I just opened .SDT file in hex editor (SDT is the main one), and looked for patterns:
hexedit_gta2.JPG

I selected the repeating pattern, now we just compare the repeating patterns, and use some data inspect (for example, I spotted 22050 value - standart sound rate value). This is the final format (some fields are unknown, but are not vital):
.sdt file stores array of following 24-byte records:
[0] Start offset (in bytes)
[4] Size (in samples!)
[8] Frequency
[12] [unkown]
[16] [unkown]
[24] End marker (0xFFFFFFFF)
 
.raw just stores 16-bit signed PCM samples. Data is pointed by start offset and size from .sdt

In case you are interested, here are full program sources (it’s not final version, there might be changes, especially regarding the unknown fields). It ain’t the best code, but it works:
#include "stdafx.h"
#include "stdio.h"
 
char gbuffer[1024*1024*8];
 
void extract(char* regionname) {
char filename[256];
 
sprintf(&filename[0],"%s.raw",regionname); FILE* snd = fopen(&filename[0],"rb");
sprintf(&filename[0],"%s.sdt",regionname); FILE* sdt = fopen(&filename[0],"rb");
 
int fileid = 0;
fseek(sdt,0,2);
int fmax = ftell(sdt) / 24;
fseek(sdt,0,0);
 
while (fileid < fmax) {
printf("%s - #%d | ",regionname,fileid);
 
int start_offset,size,freq,unk1,unk2,unk3;
 
fread(&start_offset,4,1,sdt);
fread(&size,4,1,sdt);
fread(&freq,4,1,sdt);
fread(&unk1,4,1,sdt);
fread(&unk2,4,1,sdt);
fread(&unk3,4,1,sdt);
 
int t = ftell(sdt);
 
printf("off: %d | sz: %d | freq %d | %d %d %d\n",start_offset,size,freq,t,unk2,unk3);
 
fseek(snd,start_offset,0);
fread(&gbuffer,size,1,snd);
 
//Write it
int data;
sprintf(&filename[0],"out\\%s_%d.wav",regionname,fileid);
FILE* wave = fopen(&filename[0],"wb+");
 
//WAVE header:
data = 0x46464952; fwrite(&data,4,1,wave); //RIFF
data = size+36; fwrite(&data,4,1,wave); //Header size
data = 0x45564157; fwrite(&data,4,1,wave); //WAVE
data = 0x20746D66; fwrite(&data,4,1,wave); //fmt
data = 16; fwrite(&data,4,1,wave); //fixed1
data = 1; fwrite(&data,2,1,wave); //format tag
data = 1; fwrite(&data,2,1,wave); //Channels (mono)
data = freq; fwrite(&data,4,1,wave); //Sample rate
data = freq*2; fwrite(&data,4,1,wave); //Bytes per second
data = 2; fwrite(&data,2,1,wave); //Bytes per sample
data = 16; fwrite(&data,2,1,wave); //Bits per sample
data = 0x61746164; fwrite(&data,4,1,wave); //data
data = size; fwrite(&data,4,1,wave); //Audio data size
 
fwrite(&gbuffer,size,1,wave);
fclose(wave);
 
fileid++;
}
 
fclose(snd);
fclose(sdt);
}
 
int _tmain(int argc, _TCHAR* argv[])
{
printf("GTA2 sound convertor\n");
 
extract("wil");
extract("bil");
extract("ste");
extract("fstyle");
return 0;
}

Grr, wordpress ate idents!

April fools :D


Date posted: April 1st, 2008 (checksum: 4B64BE7AF2C5D83C)

My monitor is really fine, it’s not broken or anything. It was just the picture, here it is:
crack-deskx.JPG

Many people fell for it ;)

(It’s a bit resized version, original was found here!)

Go in this direction »