The VG Resource
Lionel TrainTown Deluxe Sprites - Printable Version

+- The VG Resource (https://www.vg-resource.com)
+-- Forum: Archive (https://www.vg-resource.com/forum-65.html)
+--- Forum: Old (https://www.vg-resource.com/forum-148.html)
+---- Forum: Requests (https://www.vg-resource.com/forum-131.html)
+---- Thread: Lionel TrainTown Deluxe Sprites (/thread-39974.html)



Lionel TrainTown Deluxe Sprites - jmkrebs30 - 12-01-2021

Just curious, but is it possible to rip the sprites and backgrounds from this game?


RE: Lionel TrainTown Deluxe Sprites - DarkWolf - 12-02-2021

The game's archives are easy enough to extract, but unfortunately it looks like a lot of the files that are probably graphics use some kind of LZO compression that I can't wrap my head around.

Below is a Python script to extract the .tbv files if anyone wants to take a shot or stumbles upon this in the future.

Code:
#extractor script for Train Town .tbv files
# by DarkWolf

import struct
import sys
import os

def get_base(path):
    tmp = os.path.basename(path)
    pieces = tmp.split('.')
    return pieces[0]
    
def check_dir(path):
  if not os.path.exists(path):
    os.makedirs(path)

def main():
    if len(sys.argv) != 2:
        print("Please pass in a file path");
        sys.exit(1)
        
    header_struct = struct.Struct('<2I')
    name_struct = struct.Struct('<24sI')
    out_base = f'extracted{os.path.sep}'
    check_dir(out_base)
    input_path = sys.argv[1]
    input_base = f'{out_base}{get_base(input_path)}'
    check_dir(input_base)
    
    with open(input_path, 'rb') as fp:
        fp.seek(0x0B)
        header_items = struct.unpack('<H', fp.read(2))[0]
        
        fp.seek(0x29)
        offsets = []
        for ndx in range(0, header_items):
            data = header_struct.unpack(fp.read(header_struct.size))
            offsets.append(data[1])
        
        for addr in offsets:
            fp.seek(addr)
            data = name_struct.unpack(fp.read(name_struct.size))
            name = data[0].decode('ascii').rstrip('\x00')
            length = data[1]
            
            out_path = f'{input_base}{os.path.sep}{name}'
            with open(out_path, 'wb') as outfp:
                outfp.write(fp.read(length))
            

if __name__ == "__main__":
    main()