# HG changeset patch # User Thibaut Girka # Date 1314002999 -7200 # Node ID 1f1793e7ec8e8cb806dc4a50d2b4ba795afc6d59 # Parent 25ca15f714ad83c6c968244af9468e75da1bcf58 Handle a few more opcodes diff --git a/pytouhou/game/eclrunner.py b/pytouhou/game/eclrunner.py --- a/pytouhou/game/eclrunner.py +++ b/pytouhou/game/eclrunner.py @@ -2,29 +2,62 @@ class ECLRunner(object): def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None): self.ecl = ecl - self.counters = {} - self.implementation = {4: (self.set_counter), - 2: (self.relative_jump), - 3: (self.relative_jump_ex)} - if implementation: - self.implementation.update(implementation) - + self.variables = [0, 0, 0, 0, + 0., 0., 0., 0., + 0, 0, 0, 0] self.sub = sub self.frame = frame self.instruction_pointer = instruction_pointer + self.stack = [] - def set_counter(self, counter_id, count): - self.counters[counter_id & 0xffff] = count + self.implementation = {4: self.set_variable, + 2: self.relative_jump, + 3: self.relative_jump_ex, + 35: self.call, + 36: self.ret, + 109: self.memory_write} + if implementation: + self.implementation.update(implementation) + + + def memory_write(self, value, index): + #TODO + #XXX: this is a hack to display bosses although we don't handle MSG :) + if index == 0: + self.sub = value + self.frame = 0 + self.instruction_pointer = 0 + + + def call(self, sub, param1, param2): + self.stack.append((self.sub, self.frame, self.instruction_pointer, + self.variables)) + self.sub = sub + self.frame = 0 + self.instruction_pointer = 0 + self.variables = [param1, 0, 0, 0, + param2, 0., 0., 0., + 0, 0, 0, 0] + + + def ret(self): + self.sub, self.frame, self.instruction_pointer, self.variables = self.stack.pop() + + + + def set_variable(self, variable_id, value): + #TODO: -10013 and beyond! + self.variables[-10000-variable_id] = value def relative_jump(self, frame, instruction_pointer): self.frame, self.instruction_pointer = frame, instruction_pointer - def relative_jump_ex(self, frame, instruction_pointer, counter_id): - if self.counters[counter_id & 0xffff]: - self.counters[counter_id & 0xffff] -= 1 + def relative_jump_ex(self, frame, instruction_pointer, variable_id): + if self.variables[-10000-variable_id]: + self.variables[-10000-variable_id] -= 1 self.frame, self.instruction_pointer = frame, instruction_pointer @@ -41,6 +74,7 @@ class ECLRunner(object): print('Warning: unhandled opcode %d!' % instr_type) #TODO else: callback(*args) + frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer] if frame <= self.frame: self.instruction_pointer += 1 except IndexError: