Skip to content

Instantly share code, notes, and snippets.

@uyjulian
Last active August 22, 2023 22:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uyjulian/249d17eac10acbd9ccec32a1768e3de9 to your computer and use it in GitHub Desktop.
Save uyjulian/249d17eac10acbd9ccec32a1768e3de9 to your computer and use it in GitHub Desktop.
-- Better code have been released since then; see Trails Research Group: https://github.com/Trails-Research-Group
fu = require"file_util"
struct = require"struct"
up = struct.unpack
rp = struct.pack
proc = require"ipc.proc"
xxhash = require"xxhash"
stdinoutcmd = (s, cmd) ->
ostr = ""
cb = (e, ee) ->
if e == "stdout"
ostr ..= ee
handle = proc.spawn(cmd, {stdin: true, stdout: true, callback:cb})
for a in s\gmatch'.'
handle\write(a)
handle\write(proc.EOF)
handle\wait()
return ostr
compress_falcom3 = (s) ->
return stdinoutcmd(s, "python3 /Users/julian/Documents/itpex/ITPcnv_PSP/__pycache__/falcom_compress.cpython-36.opt-1.pyc")
nicehash = (s) ->
palette = compress_falcom3(string.rep("\000", 256))
uncindex = s .. string.rep("\000", 256 - #s)
index = compress_falcom3(uncindex)
final = rp('<III', 0x3EA, 16, 16) .. palette .. index .. "\000"
return string.format("000000003551d74c%08x = %s.png", xxhash.xxh32(uncindex, 0xBACD7814), s), final
d = fu.readfile(arg[1])
b = 1
chunks = {}
while true
s, sd, b = up("<c4I4c0", d, b)
table.insert(chunks, {s, sd})
if #d - b == -1
break
imgcnt = 1
for i, v in pairs(chunks)
if v[1] == "TEXI"
tmp = ""
if v[2]\sub(2,2) ~= 0x03
tmp = v[2]\sub(1, 36)
v[2] = v[2]\sub(37)
fmt, hased = nicehash(string.format("%s_%03d", arg[1]\sub(1, -5), imgcnt))
print(fmt)
v[2] = tmp .. hased
imgcnt += 1
--reassemble
r = ""
for i, v in pairs(chunks)
r ..= rp("<c4I4c0", v[1], #v[2], v[2])
fu.writefile(arg[1], r)
-- Better code have been released since then; see Trails Research Group: https://github.com/Trails-Research-Group
-- In V101 of the file
-- header V101
-- 256 pairs of 4byte Offset and Size
-- 256 bytes of 0x00
-- 4*256 bytes of 0x0000803F
-- header is always 3332
-- ITP data starts
fu = require"file_util"
struct = require"struct"
serpent = require"serpent"
bit = require"bit"
ffi = require"ffi"
proc = require"ipc.proc"
fu = require"file_util"
struct = require"struct"
xxhash = require"xxhash"
up = struct.unpack
rp = struct.pack
stdinoutcmd = (s, cmd) ->
ostr = ""
cb = (e, ee) ->
if e == "stdout"
ostr ..= ee
handle = proc.spawn(cmd, {stdin: true, stdout: true, callback:cb})
for a in s\gmatch'.'
handle\write(a)
handle\write(proc.EOF)
handle\wait()
return ostr
compress_falcom3 = (s) ->
return stdinoutcmd(s, "python3 /Users/julian/Documents/itpex/ITPcnv_PSP/__pycache__/falcom_compress.cpython-36.opt-1.pyc")
widthHeightITP = (inData) ->
b = 1
width = 0
height = 0
header, b = up("I4", inData, b)
b += 2
if header == 0x03EE
b += 4
ccpiMagic, b = up("I4", inData, b)
if ccpiMagic ~= 1229996867 --CCPI
error("CCPI not detected")
b += 2
b += 2
b += 1
b += 1
width, b = up("I2", inData, b)
height, b = up("I2", inData, b)
if width < 16 or height < 16
error("Invalid dimensions")
return width, height
elseif header == 0x03E8 or header == 0x03EA or header == 0x03EC or header == 0x03ED
width, b = up("I4", inData, b)
if width == 0
metaInfoSize, b = up("I4", inData, b)
inData += metaInfoSize --TODO: verify if set or add?
width, b = up("I4", inData, b)
height, b = up("I4", inData, b)
return width, height
else
print(arg[1], tonumber(header))
error("unsupported file")
nicehash = (s, w, h) ->
palette = compress_falcom3(string.rep("\000", w*h))
uncindex = s .. string.rep("\000", (w*h) - #s)
index = compress_falcom3(uncindex)
final = rp('<III', 0x3EA, w, h) .. palette .. index .. "\000"
return string.format("000000003551d74c%08x = %s.png", xxhash.xxh32(uncindex, 0xBACD7814), s), final
in1 = fu.readfile(arg[1])
header, b = struct.unpack("c4", in1)
if header ~= "V101" and header ~= "V102"
print(arg[1])
error("unsupported file")
frames = 0
framez = {}
dontdoanything = false
for i = 1, 256
offset, size, b = struct.unpack("I4I4", in1, b)
if offset == 0 and size == 0
table.insert(framez, {0, 0})
else
width, height = widthHeightITP(in1\sub(offset + 1, offset + size))
table.insert(framez, {width, height})
blob, b = struct.unpack("c1280")
header = "V101"
appendindex = ""
totalsize = 3332
for i, v in pairs(framez)
if v[1] == 0
header ..= rp("<I4I4", 0, 0)
else
fmt, hased = nicehash(string.format("%s_%03d", arg[1]\sub(1, -5), i))
appendindex ..= hased
print(fmt)
header ..= rp("<I4I4", totalsize, #hased)
totalsize += #hased
header ..= blob
-- header ..= string.rep("\000", 256)
-- header ..= string.rep(rp(">I4", 0x0000803F), 256)
fu.writefile(arg[1], header .. appendindex)
-- Better code have been released since then; see Trails Research Group: https://github.com/Trails-Research-Group
proc = require"ipc.proc"
fu = require"file_util"
struct = require"struct"
xxhash = require"xxhash"
up = struct.unpack
rp = struct.pack
stdinoutcmd = (s, cmd) ->
ostr = ""
cb = (e, ee) ->
if e == "stdout"
ostr ..= ee
handle = proc.spawn(cmd, {stdin: true, stdout: true, callback:cb})
for a in s\gmatch'.'
handle\write(a)
handle\write(proc.EOF)
handle\wait()
return ostr
compress_falcom3 = (s) ->
return stdinoutcmd(s, "python3 /Users/julian/Documents/itpex/ITPcnv_PSP/__pycache__/falcom_compress.cpython-36.opt-1.pyc")
dat = arg[1]
palette = compress_falcom3(string.rep("\000", 256))
uncindex = dat .. string.rep("\000", 256 - #dat)
index = compress_falcom3(uncindex)
final = rp('<III', 0x3EA, 16, 16) .. palette .. index .. "\000"
fu.writefile(arg[1], final)
print(string.format("000000003551d74c%08x = %s.png", xxhash.xxh32(uncindex, 0xBACD7814), arg[1]\sub(1, -5)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment