Noitu Love: Devolution

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
DPS2004
Posts: 4
Joined: Sat Apr 06, 2019 9:16 pm

Noitu Love: Devolution

Post by DPS2004 »

Hello! I am having trouble with getting sprites from this game. I know that this game is in the same engine as Freedom Planet, but the .bms I found did not work. I have attached the assets.dat file.
akintos
Posts: 88
Joined: Tue May 08, 2018 7:48 pm

Re: Noitu Love: Devolution

Post by akintos »

Code: Select all

comtype zlib_noerror

goto 0x1c6a #0x83fa #0x841e
for i = 0
    get OFFSET long
    if i == 0
        math MAX_OFF = OFFSET
    endif
    savepos TMP
    if TMP >= MAX_OFF
        break
    endif
    putarray 0 -1 OFFSET
next i

get OFFSET asize
putarray 0 -1 OFFSET
sortarray 0

math FILES = i
for i = 0 < FILES
    getarray OFFSET 0 i
    math i + 1
    getarray SIZE   0 i
    math SIZE - OFFSET

    # some files are compressed (probably compressed textures)
    # I try to dump them automatically using this trick

    if SIZE <= 0x10
        log "" OFFSET SIZE
    else
        xmath XOFFSET "OFFSET + 0x11"
        xmath XSIZE   "SIZE   - 0x11"
        clog MEMORY_FILE XOFFSET XSIZE XSIZE
        get TMP asize MEMORY_FILE
        if TMP == XSIZE
            log "" OFFSET SIZE
        else
            log "" 0 TMP MEMORY_FILE
        endif
    endif
next
DPS2004
Posts: 4
Joined: Sat Apr 06, 2019 9:16 pm

Re: Noitu Love: Devolution

Post by DPS2004 »

That just gave me a bunch of other .dat files. Is there anyway to get images out of this?
akintos
Posts: 88
Joined: Tue May 08, 2018 7:48 pm

Re: Noitu Love: Devolution

Post by akintos »

Well then try this python script I made. Don't ask me how to run python script.

Code: Select all

from __future__ import print_function

import zlib
import os
import struct

from PIL import Image


OFFSETS_START = 0x1C6A

f = open("Assets.dat", "rb")

offsets = []
f.seek(OFFSETS_START)

start_pos = struct.unpack('<I', f.read(4))[0]
offsets.append(start_pos)

while f.tell() <= start_pos:
    offset = struct.unpack('<I', f.read(4))[0]
    offsets.append(offset)

if not os.path.isdir('img'):
    os.makedirs('img')

print("Extracting images...")

count = 0
for offset in offsets:
    print(count, end='\r')
    f.seek(offset),
    width, height, comp_size = struct.unpack('<HH9xI', f.read(0x11))

    if width == 0 or height == 0:
        break

    img_data = zlib.decompress(f.read(comp_size))
    img = Image.frombytes("RGBA", (width, height), img_data)
    img.save("img/0x%06X.png" % offset)

    count += 1

print("\nExtracted %d images from Assets.dat" % count)
Doctor Loboto
Posts: 376
Joined: Sun May 31, 2015 2:23 am

Re: Noitu Love: Devolution

Post by Doctor Loboto »

Does this python script work? I've tried it myself with no results, which version of python does it require? I might be too far behind on updates.
akintos
Posts: 88
Joined: Tue May 08, 2018 7:48 pm

Re: Noitu Love: Devolution

Post by akintos »

Doctor Loboto wrote:which version of python does it require?


I tested on 2.7 and 3.6 with the Assets.dat attached on original post.

Image

You have to put the script and assets file in same directory
and install 'Pillow' python package first (with 'python -m pip install Pillow' command)
DPS2004
Posts: 4
Joined: Sat Apr 06, 2019 9:16 pm

Re: Noitu Love: Devolution

Post by DPS2004 »

It worked! Thank you so much!