From a1ed7e76583127562c73bf12766ba2958451b9dc Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Sun, 3 Mar 2013 21:42:35 -0600 Subject: vba - basic cheating infrastructure --- extras/vba.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'extras/vba.py') diff --git a/extras/vba.py b/extras/vba.py index 8ed0d7b5a..c1ff3538d 100644 --- a/extras/vba.py +++ b/extras/vba.py @@ -564,6 +564,66 @@ def call(bank, address): else: registers["pc"] = address +class cheats: + """ + Helpers to manage the cheating infrastructure. + + import vba; vba.load_rom(); vba.cheats.add_gameshark("0100CFCF", "text speedup 1"); vba.cheats.add_gameshark("0101CCCF", "text speedup 2"); vba.go() + """ + + @staticmethod + def enable(id): + """ + void gbCheatEnable(int i) + """ + Gb.cheatEnable(id) + + @staticmethod + def disable(id): + """ + void gbCheatDisable(int i) + """ + Gb.cheatDisable(id) + + @staticmethod + def load_file(filename): + """ + Loads a .clt file. By default each cheat is disabled. + """ + Gb.loadCheatsFromFile(filename) + + @staticmethod + def remove_all(): + """ + Removes all cheats from memory. + + void gbCheatRemoveAll() + """ + Gb.cheatRemoveAll() + + @staticmethod + def remove_cheat(id): + """ + Removes a specific cheat from memory by id. + + void gbCheatRemove(int i) + """ + Gb.cheatRemove(id) + + @staticmethod + def add_gamegenie(code, description=""): + """ + void gbAddGgCheat(const char *code, const char *desc) + """ + Gb.cheatAddGamegenie(code, description) + + @staticmethod + def add_gameshark(code, description=""): + """ + gbAddGsCheat(const char *code, const char *desc) + """ + Gb.cheatAddGameshark(code, description) + class crystal: """ Just a simple namespace to store a bunch of functions for Pokémon Crystal. -- cgit v1.2.3 From 0fa5d9a16217993922c88f7ec83ae99857a31267 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Mon, 4 Mar 2013 03:08:00 -0600 Subject: vba - keyboard input optimization --- extras/vba.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'extras/vba.py') diff --git a/extras/vba.py b/extras/vba.py index c1ff3538d..b8c3dc9d3 100644 --- a/extras/vba.py +++ b/extras/vba.py @@ -104,6 +104,11 @@ Gb.loadVBA() from vba_config import * +try: + import vba_keyboard as keyboard +except ImportError: + print "Not loading the keyboard module (which uses networkx)." + if not os.path.exists(rom_path): raise Exception("rom_path is not configured properly; edit vba_config.py?") @@ -163,6 +168,10 @@ def button_combiner(buttons): buttons.replace("select", "") result |= button_masks["select"] + if isinstance(buttons, list): + if len(buttons) > 9: + raise Exception("can't combine more than 9 buttons at a time") + for each in buttons: result |= button_masks[each] @@ -826,6 +835,25 @@ class crystal: return output + @staticmethod + def keyboard_apply(button_sequence): + """ + Applies a sequence of buttons to the on-screen keyboard. + """ + for buttons in button_sequence: + press(buttons) + nstep(2) + press([]) + + @staticmethod + def write(something="TrAiNeR"): + """ + Uses a planning algorithm to type out a word in the most efficient way + possible. + """ + button_sequence = keyboard.plan_typing(something) + crystal.keyboard_apply([[x] for x in button_sequence]) + @staticmethod def set_partymon2(): """ @@ -896,6 +924,14 @@ class TestEmulator(unittest.TestCase): self.assertTrue("TRAINER" in text) +class TestWriter(unittest.TestCase): + def test_very_basic(self): + button_sequence = keyboard.plan_typing("an") + expected_result = ["select", "a", "d", "r", "r", "r", "r", "a"] + + self.assertEqual(len(expected_result), len(button_sequence)) + self.assertEqual(expected_result, button_sequence) + if __name__ == "__main__": unittest.main() -- cgit v1.2.3 From 6a3cf4e39391560ec978432ec797ce77d13cd76b Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Tue, 5 Mar 2013 01:56:25 -0600 Subject: vba - record/replay button sequences --- extras/vba.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'extras/vba.py') diff --git a/extras/vba.py b/extras/vba.py index b8c3dc9d3..b57e8e699 100644 --- a/extras/vba.py +++ b/extras/vba.py @@ -443,6 +443,69 @@ def press(buttons, steplimit=1): for step_counter in range(0, steplimit): Gb.step(number) +def get_buttons(): + """ + Returns the currentButtons[0] value (an integer with bits set for which + buttons are currently pressed). + """ + return Gb.getCurrentButtons() + +class State(RomList): + name = None + +class Recording: + def __init__(self): + self.frames = [] + self.states = {} + + def _get_frame_count(self): + return len(self.frames) + + frame_count = property(fget=_get_frame_count) + + def save(self, name=None): + """ + Saves the current state. + """ + state = State(get_state()) + state.name = name + self.states[self.frame_count] = state + + def load(self, name): + """ + Loads a state by name in the state list. + """ + for state in self.states.items(): + if state.name == name: + set_state(state) + return state + return False + + def step(self, stepcount=1, first_frame=0, replay=False): + """ + Records button presses for each frame. + """ + if replay: + stepcount = len(self.frames[first_name:]) + + for counter in range(first_frame, stepcount): + if replay: + press(self.frames[counter], steplimit=0) + else: + self.frames.append(get_buttons()) + nstep(1) + + def replay_from(self, thing): + """ + Replays based on a State or the name of a saved state. + """ + if isinstance(thing, State): + set_state(thing) + else: + thing = self.load(thing) + frame_id = self.states.index(thing) + self.step(first_frame=frame_id, replay=True) + class Registers: order = [ "pc", -- cgit v1.2.3 From 91b24953f615569d5130cb1ccceffa8149cc42c0 Mon Sep 17 00:00:00 2001 From: yenatch Date: Thu, 7 Mar 2013 23:27:55 -0500 Subject: vba - suppress joypad input message --- extras/vba.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extras/vba.py') diff --git a/extras/vba.py b/extras/vba.py index 8ed0d7b5a..61265765d 100644 --- a/extras/vba.py +++ b/extras/vba.py @@ -166,7 +166,7 @@ def button_combiner(buttons): for each in buttons: result |= button_masks[each] - print "button: " + str(result) + #print "button: " + str(result) return result def load_rom(path=None): -- cgit v1.2.3