ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax
It is currently Tue Aug 09, 2022 2:48 pm

All times are UTC




Post new topic  Reply to topic  [ 31 posts ]  Go to page 1 2 Next
Author Message
PostPosted: Sat May 21, 2022 5:10 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
I want to rip the sprites from Railroad Tycoon II. I've extracted the data .pak, and the sprites appear to be in .imb and .pal files. Does anyone know anything about viewing/converting these?

Extracted .pak: https://mega.nz/file/164EGLDb#6TB8nqyeq ... LPvMSvP8Kc


Top
   
PostPosted: Mon Jun 06, 2022 10:12 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
In case it helps anyone, here are some examples of the apparent headers for the files:
Quote:
29 00 00 00 03 00 00 00 CE 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84 80 B5 82 01 00 00 00 01 00 00 00 01 00 2A 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 5F 00 00 00 63 00 00 00 DC 80 B5 82 B3 1B 00 00 0C

Quote:
01 00 00 00 03 00 00 00 F6 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C4 93 9C 82 01 00 00 00 01 00 00 00 01 00 2A 00 00 00 00 03 00 00 00 18 00 00 00 08 00 00 00 F0 00 00 00 03 01 00 00 38 F0 1B 83 0D D0 00 00 29

Quote:
08 00 00 00 03 00 00 00 BF 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 30 14 BF 82 02 00 00 00 01 00 00 00 01 00 2A 00 00 00 00 03 00 00 00 F9 FF FF FF EE FF FF FF 0E 00 00 00 16 00 00 00 A4 14 BF 82 35 01 00 00 04


Top
   
PostPosted: Fri Jun 10, 2022 3:25 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Quote:
29 00 00 00 03 00 00 00 CE 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84 80 B5 82 01 00 00 00 01 00 00 00 01 00 2A 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 5F 00 00 00 63 00 00 00 DC 80 B5 82 B3 1B 00 00 0C


My guesses:

00 00 00 29 - number of sprites in this file

next bytes you provided are the header for first sprite
...
00 00 00 5F - something like width of sprite (not exactly)
00 00 00 63 - something like height of sprite (not exactly)
...
00 00 1B B3 - size of sprite body (starting from last byte of provided header).
<sprite body>
<next header> (if any)

As for "not exactly" part - for Credits.IMB dimencions in header are 400h * 300h, while real data are 40Ch * 300h.
Image is divided by 7 one-pixel vertical lines and has 2 two-pixel vertical lines on the borders. But it's still Bh out of extra 0Сh. Size of blocks between vertical lines is 80h, so it may be somehow connected to the value of the last header byte (84h for Credits).


Top
   
PostPosted: Fri Jun 10, 2022 8:18 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
Bwolna wrote:
As for "not exactly" part - for Credits.IMB dimencions in header are 400h * 300h, while real data are 40Ch * 300h.

How do you know the size of the real data?


Top
   
PostPosted: Fri Jun 10, 2022 10:11 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Size of real data is provided in header.
"Real" dimensions could be found for some non-compressed sprites in programs for visualization of raw data. I used GBS:



Image


Top
   
PostPosted: Fri Jun 10, 2022 10:22 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
Er, how did you extract sprites from CREDITS.IMB?


Top
   
PostPosted: Sat Jun 11, 2022 9:40 am 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Using any program that allows to copy parts of the binary file. Many hex-editors can do this, but I used dd utility:

Code:
dd if=CREDITS.IMB bs=1 skip=$((0x70)) count=$((0xC2401)) of=00.sprite

Code:
dd if=WINLOSE.IMB bs=1 skip=$((0x70)) count=$((0x451A9)) of=00.sprite


Instructions: https://stackoverflow.com/questions/142 ... hin-a-file


Top
   
PostPosted: Sat Jun 11, 2022 12:52 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
That isn't any good if I don't know how to identify the actual sprite data.


Top
   
PostPosted: Sat Jun 11, 2022 7:49 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Sprites are compressed. Simple cases like CREDITS can be decompressed with something like this:

Code:
         int position = 0;
         int destPos = 0;
         boolean finish = false;
         while (!finish) {
            int lineStartPos = destPos;
            int firstByte = readByte(source, position++);
            if ((firstByte & 0x80) > 0) position++;
            boolean lineFinished = false;
            while (!lineFinished && !finish) {
               int controlByte = readByte(source, position++);
               if ((controlByte & 0x80) > 0) {
                  if ((controlByte & 0x40) > 0) {
                     int skipSize = controlByte & 0x3F;
                     if (skipSize == 0) {
                        finish = true;
                     } else {
                        destPos += skipSize;
                     }
                  } else if ((controlByte & 0x20) == 0) {
                     // !TODO
                  } else {
                     // !TODO
                  }
               } else if (controlByte == 0) {
                  destPos = lineStartPos + width;
                  lineFinished = true;
               } else {
                  for (int i=0; i<controlByte; i++) result[destPos++] = source[position++];
               }
            }
         }


Top
   
PostPosted: Sat Jun 11, 2022 10:06 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
That doesn't help me identify the sprite data. If I can identify the precise values that contain the actual images, then I can easily extract them without the aid of scripts.


Top
   
PostPosted: Sun Jun 12, 2022 2:34 am 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Sorry, I don't understand what do you mean.
Size of compressed sprite and dimension of decompressed sprite are written in headers.


Top
   
PostPosted: Sun Jun 12, 2022 3:55 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
I have several questions:

How "compressed" are the sprites? If I deleted everything but the image data, would I have an image or would I have to do something else?

What do you mean by "simple cases like CREDITS"? Is this just about the number of images contained in each files, or is there something more going on?


Top
   
PostPosted: Sun Jun 12, 2022 7:33 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
eldomtom2 wrote:
How "compressed" are the sprites?

Some sort of Run-length_encoding algorithm was used to compress "empty" (transparent?) parts of images.

eldomtom2 wrote:
If I deleted everything but the image data, would I have an image or would I have to do something else?


If by "everything but the image data" you mean only headers, the answer will be "no". But if you'll delete headers, delete control sequences of commands (inserted to compressed sprite by original compressor) and insert missed transparent blocks then you will get the uncompressed image data.

eldomtom2 wrote:
What do you mean by "simple cases like CREDITS"? Is this just about the number of images contained in each files, or is there something more going on?


No, not the number of images in one file. Simple cases are cases where original image did not contain transparent pixels. Like CREDITS and some other rectangular pictures.

For such images compressor still added some control sequences of command, but did not remove anything. So this files could be viewed in Texture Finder or GBS (that I personally use) even in "compressed form". In those tools control sequences of commands will look like vertical lines (look at my screenshot in previous post).

P.S. I didn't completely understand the algorithm of compression so far, so it could be that some sprites are compressed with some other tricks in addition to RLE.

P.P.S. first sprite from file BL1SHEEP.IMB. Compressed size = 11999 bytes. Decompressed size = 20736. After decompression:

Image


Top
   
PostPosted: Mon Jun 13, 2022 3:00 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
BL1SHEEP.IMB seems to contain transparent pixels from that image and what I know of how it's used in the game, so did you work out how to decompress images that contain transparent pixels?


Top
   
PostPosted: Mon Jun 13, 2022 3:36 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Bwolna wrote:
can be decompressed with something like this:

Code:
         int position = 0;
         int destPos = 0;
         boolean finish = false;
         while (!finish) {
            int lineStartPos = destPos;
            int firstByte = readByte(source, position++);
            if ((firstByte & 0x80) > 0) position++;
            boolean lineFinished = false;
            while (!lineFinished && !finish) {
               int controlByte = readByte(source, position++);
               if ((controlByte & 0x80) > 0) {
                  if ((controlByte & 0x40) > 0) {
                     int skipSize = controlByte & 0x3F;
                     if (skipSize == 0) {
                        finish = true;
                     } else {
                        destPos += skipSize;
                     }
                  } else if ((controlByte & 0x20) == 0) {
                     // !TODO
                  } else {
                     // !TODO
                  }
               } else if (controlByte == 0) {
                  destPos = lineStartPos + width;
                  lineFinished = true;
               } else {
                  for (int i=0; i<controlByte; i++) result[destPos++] = source[position++];
               }
            }
         }


Top
   
PostPosted: Sat Jun 18, 2022 5:21 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
Huh, but didn't you say that was only for simple cases?


Top
   
PostPosted: Sat Jun 18, 2022 8:02 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
Yes, I did. But later tests showed that more complex cases (like BL1SHEEP and BL2CMINE) could be de decompressed by this code. There are still TODO left, that would be (probably) needed for some of the images.


Top
   
PostPosted: Mon Jun 20, 2022 9:08 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
Great, I suppose my main question then is how would I run that code?


Top
   
PostPosted: Wed Jun 22, 2022 5:13 pm 

Joined: Fri Jun 10, 2022 3:09 pm
Posts: 15
That code snippet is a part of small java program (quick and dirty).
But you can treat it as a Pseudocode and write your own decompressor with any language you know the best.


Top
   
PostPosted: Wed Jun 22, 2022 5:22 pm 

Joined: Sat May 21, 2022 5:07 pm
Posts: 17
Would it be possible for you to share the actual program?


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 31 posts ]  Go to page 1 2 Next

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited