Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.
Zero Tolerance for Disrespect

[Psx] Devilman TIM compressed

Featured Replies

Hello,

The Devilman PSX game doesn’t have much text, and I’d like to edit it. Most of the dialogue is audio and is stored in the PSOUND folder. These are .VAG files without header, so they’re easy to extract, edit, and reinsert.

I need some help with the game’s images. QDATA.BIN contains many .TIM images, but I don’t see any that contain Japanese text. The game script seems to be stored in .TIM images—I’ve been able to confirm this by analyzing RAM dumps—but when I look for those images in the ISO, I can’t find them. I’ve checked the files one by one with Tile Molester, but I still can’t see the text images that do appear in RAM.

They’re most likely compressed inside the HDATA or TDATA folders. I can see some data that looks like .TIM structures, but I haven’t been able to view any actual images.

Any help with this would be really appreciated.

Ram_TIMS.thumb.jpg.52b7b6d72003358b0a41e133e5b1e0ce.jpg

Attached are game files (without sound and video) and RAM dump.

https://www.mediafire.com/file/ce0sfz30qtob351/Devilman_psx_files.rar/file

https://www.mediafire.com/file/k54kjfbtf2isz15/RAM_dump.rar/file

Edited by JoseKenshin

Solved by Rabatini

  • Supporter
5 hours ago, JoseKenshin said:

Hello,

The Devilman PSX game doesn’t have much text, and I’d like to edit it. Most of the dialogue is audio and is stored in the PSOUND folder. These are .VAG files without header, so they’re easy to extract, edit, and reinsert.

I need some help with the game’s images. QDATA.BIN contains many .TIM images, but I don’t see any that contain Japanese text. The game script seems to be stored in .TIM images—I’ve been able to confirm this by analyzing RAM dumps—but when I look for those images in the ISO, I can’t find them. I’ve checked the files one by one with Tile Molester, but I still can’t see the text images that do appear in RAM.

They’re most likely compressed inside the HDATA or TDATA folders. I can see some data that looks like .TIM structures, but I haven’t been able to view any actual images.

Any help with this would be really appreciated.

Ram_TIMS.thumb.jpg.52b7b6d72003358b0a41e133e5b1e0ce.jpg

Attached are game files (without sound and video) and RAM dump.

https://www.mediafire.com/file/ce0sfz30qtob351/Devilman_psx_files.rar/file

https://www.mediafire.com/file/k54kjfbtf2isz15/RAM_dump.rar/file

It’s compressed using a custom LZSS algorithm with token counting.
Your files are both compressed and packed, so you will need to unpack and decompress them simultaneously.
Inside the TEX files, there are multiple TIM images.



HOPNTEX_BIN.decomp@0000000640.png.bd32f060468d40cdaff5700de845d454.png

file_00051000@0000001056.png.a0bee94871c03b711aea9840c0e269be.pngfile_0006F800@0000001056.png.49f0867c618c0e3a038e553a12333389.pngfile_0005F800@0000047616.png.0e85332ed3f173c8835b21cec9efb194.pngfile_0000B800@0000000608.png.c813eb5457b8941f189faaaf50f8d7e4.pngfile_0002D800@0000000064.png.74f01c6be973cb75d3e5ebba95b29741.pngfile_0003C800@0000000064.png.c189435fac7083b4b95be8d406a25912.png

Edited by Rabatini

  • Author

Amazing!

I’ve been trying to figure out the compression for several days.

Thank you! Could you explain a bit more about the custom LZSS algorithm?

Also, if you’d like, you could share the tools you used. 😁

Edited by JoseKenshin

  • Supporter
3 hours ago, JoseKenshin said:

Amazing!

I’ve been trying to figure out the compression for several days.

Thank you! Could you explain a bit more about the custom LZSS algorithm?

Also, if you’d like, you could share the tools you used. 😁

Yeah, I can do that. For the translation part, I’ll need to build a compression tool as well.
Which language are you planning to translate?

  • Author

ok, thanks!
I want to translate it into Spanish. 

You already helped me with Granstream Saga. I owe you a bunch of coffees. 😄

  • Supporter
4 hours ago, JoseKenshin said:

ok, thanks!
I want to translate it into Spanish. 

You already helped me with Granstream Saga. I owe you a bunch of coffees. 😄

 

Quote

image.png.aa0e2bbcaf8ea49bc93b7415d53d927a.pngThank you! Could you explain a bit more about the custom LZSS algorithm?

It’s a token-based LZSS/LZ77 stream.

Header (2 bytes, little-endian): this is NOT the output size. It is the number of commands/tokens to execute.

After the header, the data is processed in groups of 8 tokens:

Before each group, read 1 flag byte.

You consume its bits from MSB to LSB (bit 7 → bit 0).

Each bit decides what the next token is.

If the bit = 0 (literal token):

Read 1 byte from input and copy it directly to the output.

If the bit = 1 (reference token):

Read 2 bytes (byte1, byte2).

Decode:

length = (byte1 >> 2) + 1 → range 1..64

offset = ((byte1 & 0x03) << 8') | byte2 → range 0..1023

distance = offset + 1 → range 1..1024

Copy length bytes from output position:

copy_pos = current_output_pos - distance

Copy forward (overlap allowed), like standard LZSS.

Stop condition: stops when you’ve executed exactly token_count tokens (each literal counts as 1 token, each reference also counts as 1 token), regardless of how many output bytes the references produce.

----------------------------------------------------------------------------------------------------------------------------------------------------

Good news.

Compressor is working, with good rate.

image.thumb.png.6df28c76deffd7198675d7de9b4b5354.png
 

Edited by Rabatini

  • Author

I tried to find the compression with Ghidra and Chatgpt, analyzing SLPS_022.75. I think the FUN_80013a34 function is the one that manages the compression. Thank you for your explanations, they are very helpful.

Unfortunately, I don't know how to make a tool, so I need your help ;)

#Function extracted from Ghidra
void FUN_80013a34(ushort *param_1,undefined *param_2)

{
  undefined *puVar1;
  byte bVar2;
  ushort uVar3;
  uint uVar4;
  ushort *puVar5;
  int iVar6;
  uint uVar7;
  int in_t2;
  uint uVar8;
  
  uVar7 = 0;
  uVar3 = *param_1;
  param_1 = param_1 + 1;
  do {
    while( true ) {
      uVar4 = (uint)*(byte *)param_1;
      puVar5 = param_1;
      if ((uVar7 & 7) == 0) {
        puVar5 = (ushort *)((int)param_1 + 1);
        in_t2 = uVar4 << 0x18;
        uVar4 = (uint)*(byte *)puVar5;
      }
      param_1 = (ushort *)((int)puVar5 + 1);
      if (in_t2 < 0) break;
      *param_2 = (char)uVar4;
      param_2 = param_2 + 1;
      uVar7 = uVar7 + 1;
      in_t2 = in_t2 << 1;
      if (uVar7 == uVar3) {
        return;
      }
    }
    uVar8 = uVar4 >> 2;
    bVar2 = *(byte *)param_1;
    param_1 = puVar5 + 1;
    iVar6 = (int)param_2 - ((uVar4 & 3) << 8 | (uint)bVar2);
    do {
      puVar1 = (undefined *)(iVar6 + -1);
      iVar6 = iVar6 + 1;
      *param_2 = *puVar1;
      uVar8 = uVar8 - 1;
      param_2 = param_2 + 1;
    } while (-1 < (int)uVar8);
    uVar7 = uVar7 + 1;
    in_t2 = in_t2 << 1;
  } while (uVar7 != uVar3);
  return;
}

 

  • Supporter
  • Solution
43 minutes ago, JoseKenshin said:

I tried to find the compression with Ghidra and Chatgpt, analyzing SLPS_022.75. I think the FUN_80013a34 function is the one that manages the compression. Thank you for your explanations, they are very helpful.

Unfortunately, I don't know how to make a tool, so I need your help 😉

#Function extracted from Ghidra
void FUN_80013a34(ushort *param_1,undefined *param_2)

{
  undefined *puVar1;
  byte bVar2;
  ushort uVar3;
  uint uVar4;
  ushort *puVar5;
  int iVar6;
  uint uVar7;
  int in_t2;
  uint uVar8;
  
  uVar7 = 0;
  uVar3 = *param_1;
  param_1 = param_1 + 1;
  do {
    while( true ) {
      uVar4 = (uint)*(byte *)param_1;
      puVar5 = param_1;
      if ((uVar7 & 7) == 0) {
        puVar5 = (ushort *)((int)param_1 + 1);
        in_t2 = uVar4 << 0x18;
        uVar4 = (uint)*(byte *)puVar5;
      }
      param_1 = (ushort *)((int)puVar5 + 1);
      if (in_t2 < 0) break;
      *param_2 = (char)uVar4;
      param_2 = param_2 + 1;
      uVar7 = uVar7 + 1;
      in_t2 = in_t2 << 1;
      if (uVar7 == uVar3) {
        return;
      }
    }
    uVar8 = uVar4 >> 2;
    bVar2 = *(byte *)param_1;
    param_1 = puVar5 + 1;
    iVar6 = (int)param_2 - ((uVar4 & 3) << 8 | (uint)bVar2);
    do {
      puVar1 = (undefined *)(iVar6 + -1);
      iVar6 = iVar6 + 1;
      *param_2 = *puVar1;
      uVar8 = uVar8 - 1;
      param_2 = param_2 + 1;
    } while (-1 < (int)uVar8);
    uVar7 = uVar7 + 1;
    in_t2 = in_t2 << 1;
  } while (uVar7 != uVar3);
  return;
}

 

I've already did Tool, Just cant sente It now, because, i'am not at home.

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.