Skip to content

Instantly share code, notes, and snippets.

@Treeki
Created March 29, 2018 20:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Treeki/feab284f417ef7112a32d3129d7f4dbe to your computer and use it in GitHub Desktop.
Save Treeki/feab284f417ef7112a32d3129d7f4dbe to your computer and use it in GitHub Desktop.
fucking around with Professor Layton and the Curious Village
import struct
import sys
# 1 is maybe s32?
# Commands:
# Room In --
# 18 -- (8?)
# 88 -- (1:a, 6:b)
# 236 -- (1:a, 1:b)
# 81 -- (3:'event')
# 96 -- (1:a, 7:b)
# Room Param --
# 90 -- (1:a, 1:b, 1:c, 1:d, 1:e)
# 67 -- (1:a, 1:b, 1:c, 1:d, 1:e, 1:f, 1:g)
# some other shite
# 186 -- Set puzzle title (1:number, 3:title)
# 194 -- Dog (1:a, 1:b, 1:c, 1:d, 1:e, 1:f)
# 220 -- Set puzzle location (1:number, 3:type, 3:location)
# 229 -- Babascript (1:?, 2:?, 3:?, 4:?)
# qscript files for the matchstick puzzles:
# 0 : (?)
# 1 : One Poor Pooch : Manor Foyer
# 25 : Of Dust and Dustpan : Inn
# 113 : The Vanishing Cube : Manor Parlour
# 114 : Make it Smaller : None
# 119 : From Five to Four : None
path = sys.argv[1]
with open(path, 'rb') as f:
data = f.read()
def extract_items(data):
data_size = struct.unpack_from('<I', data, 0)[0]
assert(data_size == (len(data) - 4))
pos = 4
while pos < len(data):
cmd = struct.unpack_from('<H', data, pos)[0]
pos += 2
if cmd == 12:
return
elif cmd == 0:
u16 = struct.unpack_from('<H', data, pos)[0]
pos += 2
yield 'command', u16
elif cmd == 1:
u32 = struct.unpack_from('<I', data, pos)[0]
pos += 4
yield u32
elif cmd == 6 or cmd == 7:
u32 = struct.unpack_from('<I', data, pos)[0]
pos += 4
yield cmd, u32
elif cmd == 2:
f32 = struct.unpack_from('<f', data, pos)[0]
pos += 4
yield f32
elif cmd == 3 or cmd == 4:
size = struct.unpack_from('<H', data, pos)[0]
pos += 2
bits = data[pos:pos+size]
pos += size
yield cmd, bits
else:
print('unk cmd %d' % cmd)
def split_into_commands(items):
items = list(items)
this_cmd = None
for item in items:
if isinstance(item, tuple) and item[0] == 'command':
if this_cmd is not None:
yield this_cmd
this_cmd = [item[1]]
else:
this_cmd.append(item)
if this_cmd is not None:
yield this_cmd
for cmd in split_into_commands(extract_items(data)):
print(cmd)
import struct
import sys
in_path = sys.argv[1]
out_path = sys.argv[2]
results = []
with open(in_path, 'r') as f:
for line in f.readlines():
if line[0] == '#' or line[0] == '\n':
continue
bit = eval(line)
cmd = bit[0]
args = bit[1:]
results.append(struct.pack('<HH', 0, cmd))
for arg in args:
if isinstance(arg, int):
results.append(struct.pack('<HI', 1, arg))
elif isinstance(arg, float):
results.append(struct.pack('<Hf', 2, arg))
elif arg[0] == 3:
results.append(struct.pack('<HH', 3, len(arg[1])))
results.append(arg[1])
else:
raise 'unhandled command type'
results.append(struct.pack('<H', 12))
data = b''.join(results)
with open(out_path, 'wb') as f:
f.write(struct.pack('<I', len(data)))
f.write(data)
[27, (3, b'Match\x00')]
[28, 3]
[31, 1, 0]
# set maximum amount of moves allowed
[39, 3]
[102]
# INITIAL CONFIG
# cmd, x, y, rotation
# Top Left
[42, 58, 55, 270.0]
[42, 52, 85, 90.0]
# Top Right
[42, 63, 118, 180.0]
[42, 222, 79, 270.0]
# Bottom Left
[42, 46, 142, 270.0]
[42, 40, 172, 90.0]
[42, 86, 142, 270.0]
[42, 80, 172, 90.0]
# Bottom Right
[42, 160, 124, 270.0]
[42, 154, 140, 90.0]
# bed
[42, 132, 102, 180.0]
[42, 182, 108, 0.0]
[42, 232, 151, 180.0]
# SOLUTION
# cmd, x, y, rotation, match threshold X?, match threshold Y?
# Top Left
[43, 58, 55, 270.0, 1.0, 1.0]
[43, 52, 85, 90.0, 1.0, 1.0]
# Top Right
[43, 160, 63, 270.0, 16.0, 16.0]
[43, 222, 79, 270.0, 1.0, 1.0]
# Bottom Left
[43, 46, 142, 270.0, 1.0, 1.0]
[43, 40, 172, 90.0, 1.0, 1.0]
[43, 86, 142, 270.0, 1.0, 1.0]
[43, 80, 172, 90.0, 1.0, 1.0]
# Bottom Right
[43, 160, 124, 270.0, 1.0, 1.0]
[43, 154, 140, 90.0, 1.0, 1.0]
# bed
[43, 152, 151, 180.0, 16.0, 16.0]
[43, 193, 156, 0.0, 16.0, 16.0]
[43, 232, 151, 180.0, 1.0, 1.0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment