-- Disney's Toy Story (Sega Genesis) -- by Jimmie1717 -- BizHawk 1.11.1 -- This will only work with the NTSC-U version of the game. -- ** This probably works with the PAL version too. console.clear(); -- Clear the console of previous errors/data. console.writeline("Disney's Toy Story (Sega Genesis)"); console.writeline("By Jimmie1717"); -- Globals readByte = mainmemory.read_u8; readSByte = mainmemory.read_s8; readWord = mainmemory.read_u16_be; readSWord = mainmemory.read_s16_be; readDWord = mainmemory.read_u32_be; readSDWord = mainmemory.read_s32_be; readFloat = mainmemory.readfloat; writeByte = mainmemory.write_u8; writeSByte = mainmemory.write_s8; writeWord = mainmemory.write_u16_be; writeSWord = mainmemory.write_s16_be; writeDWord = mainmemory.write_u32_be; writeSDWord = mainmemory.write_s32_be; writeFloat = mainmemory.writefloat; formNew = forms.newform; formLabel = forms.label; formSetText = forms.settext; formGetText = forms.gettext; formSetProperty = forms.setproperty; formGetProperty = forms.getproperty; formButton = forms.button; formDroplist = forms.dropdown; formTextbox = forms.textbox; formCheckbox = forms.checkbox; formCheckboxChecked = forms.ischecked; formDestroy = forms.destroy; formDestroyAll = forms.destroyall; -- RAM Addresses local addrs = { general = { level = 0x049A, bonus_stars = { total = 0x049C, level = 0x049E } }, woody = { position = { x = 0x0686, y = 0x068A }, velocity = { x = 0x069A, y = 0x069E }, ground = 0x06A2, state = 0x06F6, lives = 0x04A0, health = 0x04A2 }, screen = { position = { x = 0x05B4, y = 0x05B6 }, velocity = { x = 0x05CA, y = 0x05CC } }, level_data = { [5] = { battery = 0x0C05 }, [8] = { buzz = { position = { x = 0x0AEE, y = 0x0AE2 } }, tire = { position = { x = 0x0B08, y = nil } } }, [12] = { buzz = { position = { x = 0x2522, y = 0x2524 } }, claw = { mode = 0x0ADE, health = 0x0B00 }, aliens = { [0] = { position = { x = 0x0B08, y = 0x0B0C }, velocity = { x = 0x0B10, y = 0x0B14 }, active = 0x0B1A }, [1] = { position = { x = 0x0B1C, y = 0x0B20 }, velocity = { x = 0x0B24, y = 0x0B28 }, active = 0x0B2E }, [2] = { position = { x = 0x0B30, y = 0x0B34 }, velocity = { x = 0x0B38, y = 0x0B3C }, active = 0x0B42 } } } } }; local values = { woody_state = { [0x00] = "Stationary", [0x01] = "Moving", [0x02] = "Riding Rex", [0x03] = "Crouching", [0x04] = "Uncrouching", [0x05] = "Hanging or Riding RC", [0x06] = "Climbing", [0x07] = "Swinging", [0x08] = "Jumping", [0x09] = "Jumping (from Moving)", [0x0A] = "Falling", [0x0B] = "Falling (from Moving)", [0x0C] = "Falling (extended)", [0x0D] = "Landing", [0x0E] = "Landing (from Moving)", [0x0F] = "Landing (from Falling)", [0x10] = "Whipping", [0x11] = "Crouch Whipping", [0x12] = "Upward Whipping", [0x13] = "Moving Mega Gulp", [0x14] = "Stationary Mega Gulp", [0x15] = "Riding Rollerbob", [0x16] = "Air Whipping", [0x17] = "Release Swinging", [0x18] = "Tiptoe at Edge", [0x19] = "Jumping (from Hanging)", [0x1A] = "Playing Dead", [0x1B] = "Burned", [0x1C] = "Cooling Off", [0x1D] = "Pushing Buzz", [0x1E] = "Attacking with Buzz", [0x1F] = "Pushing Buzz (Stationary)", [0x20] = "Jumping (Riding Rex)", [0x21] = "Falling (Riding Rex)", [0x22] = "Looking over Shoulder", [0xFFFF] = "" }, claw = { [0xFFFF] = "Scanning", [0x0000] = "Target Found", [0x0001] = "Target Aquired", } }; local starsCurrent = 0; local pokeFormState = true; local pokeList = { "Bonus Stars - Level", "Bonus Stars - Total", "Woody - X Position", "Woody - Y Position", "Woody - X Velocity", "Woody - Y Velocity" }; -- Use these to define the base location of where text should appear in the form. -- i.e. 0, 0 is the top left. local x = 2; local y = 3; -- 1286, 3193, 5017, 1824 -- 21439 24632 26456 function mainForm() MAINFORM = formNew(228, 315, "TS"); -- General level_value = formLabel(MAINFORM, "", x + 27, y + 15, 40, 13, false); stars_l_value = formLabel(MAINFORM, "", x + 87, y + 15, 40, 13, false); stars_t_value = formLabel(MAINFORM, "", x + 87, y + 30, 40, 13, false); stars_c_value = formLabel(MAINFORM, "", x + 147, y + 15, 40, 13, false); general = formLabel(MAINFORM, "General:", x, y, 200, 13, false); level = formLabel(MAINFORM, "#:", x + 5, y + 15, 17, 13, false); stars_l = formLabel(MAINFORM, "L*:", x + 65, y + 15, 25, 13, false); stars_t = formLabel(MAINFORM, "T*:", x + 65, y + 30, 25, 13, false); stars_c = formLabel(MAINFORM, "C*:", x + 125, y + 15, 25, 13, false); -- Woody woody_x_value = formLabel(MAINFORM, "", x + 27, y + 65, 40, 13, false); woody_y_value = formLabel(MAINFORM, "", x + 27, y + 80, 40, 13, false); woody_vx_value = formLabel(MAINFORM, "", x + 87, y + 65, 40, 13, false); woody_vy_value = formLabel(MAINFORM, "", x + 87, y + 80, 40, 13, false); woody_hp_value = formLabel(MAINFORM, "", x + 147, y + 65, 40, 13, false); woody_lives_value = formLabel(MAINFORM, "", x + 147, y + 80, 40, 13, false); woody_state_value = formLabel(MAINFORM, "", x + 41, y + 50, 200, 13, false); woody = formLabel(MAINFORM, "Woody:", x, y + 50, 200, 13, false); woody_x = formLabel(MAINFORM, "X:", x + 5, y + 65, 17, 13, false); woody_y = formLabel(MAINFORM, "Y:", x + 5, y + 80, 17, 13, false); woody_vx = formLabel(MAINFORM, "VX:", x + 65, y + 65, 25, 13, false); woody_vy = formLabel(MAINFORM, "VY:", x + 65, y + 80, 25, 13, false); woody_hp = formLabel(MAINFORM, "HP:", x + 125, y + 65, 25, 13, false); woody_lives = formLabel(MAINFORM, "L:", x + 125, y + 80, 25, 13, false); -- Screen screen_x_value = formLabel(MAINFORM, "", x + 27, y + 115, 40, 13, false); screen_y_value = formLabel(MAINFORM, "", x + 27, y + 130, 40, 13, false); screen_vx_value = formLabel(MAINFORM, "", x + 87, y + 115, 40, 13, false); screen_vy_value = formLabel(MAINFORM, "", x + 87, y + 130, 40, 13, false); screen = formLabel(MAINFORM, "Screen:", x, y + 100, 200, 13, false); screen_x = formLabel(MAINFORM, "X:", x + 5, y + 115, 17, 13, false); screen_y = formLabel(MAINFORM, "Y:", x + 5, y + 130, 17, 13, false); screen_vx = formLabel(MAINFORM, "VX:", x + 65, y +115, 25, 13, false); screen_vy = formLabel(MAINFORM, "VY:", x + 65, y + 130, 25, 13, false); -- Level Data 1 level1_1_value = formLabel(MAINFORM, "", x + 27, y + 165, 40, 13, false); level1_2_value = formLabel(MAINFORM, "", x + 27, y + 180, 40, 13, false); level1_3_value = formLabel(MAINFORM, "", x + 87, y + 165, 40, 13, false); level1_4_value = formLabel(MAINFORM, "", x + 87, y + 180, 40, 13, false); level1_5_value = formLabel(MAINFORM, "", x + 147, y + 165, 40, 13, false); level1_6_value = formLabel(MAINFORM, "", x + 147, y + 180, 40, 13, false); level1 = formLabel(MAINFORM, "", x, y + 150, 200, 13, false); level1_1 = formLabel(MAINFORM, "", x + 5, y + 165, 17, 13, false); level1_2 = formLabel(MAINFORM, "", x + 5, y + 180, 17, 13, false); level1_3 = formLabel(MAINFORM, "", x + 65, y + 165, 25, 13, false); level1_4 = formLabel(MAINFORM, "", x + 65, y + 180, 25, 13, false); level1_5 = formLabel(MAINFORM, "", x + 125, y + 165, 25, 13, false); level1_6 = formLabel(MAINFORM, "", x + 125, y + 180, 25, 13, false); -- Level Data 2 level2_1_value = formLabel(MAINFORM, "", x + 27, y + 215, 40, 13, false); level2_2_value = formLabel(MAINFORM, "", x + 27, y + 230, 40, 13, false); level2_3_value = formLabel(MAINFORM, "", x + 87, y + 215, 40, 13, false); level2_4_value = formLabel(MAINFORM, "", x + 87, y + 230, 40, 13, false); level2_5_value = formLabel(MAINFORM, "", x + 147, y + 215, 40, 13, false); level2_6_value = formLabel(MAINFORM, "", x + 147, y + 230, 40, 13, false); level2 = formLabel(MAINFORM, "", x, y + 200, 200, 13, false); level2_1 = formLabel(MAINFORM, "", x + 5, y + 215, 17, 13, false); level2_2 = formLabel(MAINFORM, "", x + 5, y + 230, 17, 13, false); level2_3 = formLabel(MAINFORM, "", x + 65, y + 215, 25, 13, false); level2_4 = formLabel(MAINFORM, "", x + 65, y + 230, 25, 13, false); level2_5 = formLabel(MAINFORM, "", x + 125, y + 215, 25, 13, false); level2_6 = formLabel(MAINFORM, "", x + 125, y + 230, 25, 13, false); poke_button = formButton(MAINFORM, "Poke", pokeForm, x + 2, y + 247, 204, 22); end function pokeForm() if (pokeFormState == true) then pokeFormState = false; POKEFORM = formNew(228, 318, "Poke"); -- Enter Address e_value_hex = formTextbox(POKEFORM, "0", 86, 20, "HEX", 61, 48, false, false); e_value_l = formLabel(POKEFORM, "Value: 0x", 13, 51, 62, 13, false); e_address_size = formDroplist(POKEFORM, {"1 Byte", "2 Byte", "4 Byte"}, 152, 22, 55, 0); e_address_hex = formTextbox(POKEFORM, "0", 86, 20, "HEX", 61, 23, false, false); e_address_l = formLabel(POKEFORM, "Address: 0x", 2, 26, 62, 13, false); e_address_cb_l = formLabel(POKEFORM, "Enter an Address to Poke:", 18, 6, 140, 13, false); e_address_cb = formCheckbox(POKEFORM, "", 5, 1); -- Select Address s_value_hex = formTextbox(POKEFORM, "0", 86, 20, "HEX", 61, 128, false, false); s_value_l = formLabel(POKEFORM, "Value: 0x", 13, 131, 62, 13, false); s_address_list = formDroplist(POKEFORM, pokeList, 61, 102, 146, 20); s_address_l = formLabel(POKEFORM, "Address: 0x", 2, 106, 62, 13, false); s_address_cb_l = formLabel(POKEFORM, "Select an Address to Poke:", 18, 86, 140, 13, false); s_address_cb = formCheckbox(POKEFORM, "", 5, 81); forms.addclick(e_address_cb, function() pokeOption("e"); end); forms.addclick(s_address_cb, function() pokeOption("s"); end); --list = formDroplist(POKEFORM, pokeList, 5, 5, 142, 10); --value_size = formDroplist(POKEFORM, {"1 Byte", "2 Byte", "4 Byte"}, 152, 5, 55, 0); --value_address = formTextbox(POKEFORM, "0", 142, 20, "HEX", 5, 5, false, false); --value_dec = formTextbox(POKEFORM, "0", 99, 20, "UNSIGNED", 5, 31, false, false); --value_hex = formTextbox(POKEFORM, "0", 99, 20, "HEX", 108, 31, false, false); --button = formButton(POKEFORM, "Update", pokeValue, 4, 55, 204, 22); --checkbox = forms.checkbox(POKEFORM, "", 5, 82); -- Default Size to 2 byte. formSetProperty(e_address_size, "SelectedIndex", 1); formSetProperty(e_address_cb, "Checked", true); end end -- Format Textbox Values function pokeFormat() formSetText(value_hex, string.format("%08s", formGetText(value_hex))); end function pokeValue() -- Logic to read POKEFORM values and apply them. --print(formGetProperty(list, "SelectedItem")); --print(formGetText(list)); local address = tonumber(formGetText(value_address), 16); local value = tonumber(formGetText(value_dec)); local size = formGetText(value_size); if (size == "1 Byte") then writeByte(address, value); elseif (size == "2 Byte") then writeWord(address, value); elseif (size == "4 Byte") then writeDWord(address, value); end -- Destroy the Form formDestroy(POKEFORM); pokeFormState = true; gui.addmessage("Poked: 0x0000 to be 0x00"); end -- Only allow one option to be selected. function pokeOption(source) if (source == "e" and formCheckboxChecked(e_address_cb)) then formSetProperty(s_address_cb, "Checked", true); elseif (source == "e" and formCheckboxChecked(e_address_cb) == false) then formSetProperty(s_address_cb, "Checked", false); elseif (source == "s" and formCheckboxChecked(s_address_cb)) then formSetProperty(e_address_cb, "Checked", true); elseif (source == "s" and formCheckboxChecked(s_address_cb) == false) then formSetProperty(e_address_cb, "Checked", false); end end function updateData() formSetText(level_value, string.format("%d", readWord(addrs.general.level))); formSetText(stars_l_value, string.format("%d", readWord(addrs.general.bonus_stars.level))); formSetText(stars_t_value, string.format("%d", readSWord(addrs.general.bonus_stars.total))); formSetText(stars_c_value, string.format("%d", currentStars())); formSetText(woody_x_value, string.format("%d", readWord(addrs.woody.position.x))); formSetText(woody_y_value, string.format("%d", readWord(addrs.woody.position.y))); formSetText(woody_vx_value, string.format("%d", readSWord(addrs.woody.velocity.x))); formSetText(woody_vy_value, string.format("%d", (readSWord(addrs.woody.velocity.y) * -1))); formSetText(woody_hp_value, string.format("%d", readSWord(addrs.woody.health) + 1)); formSetText(woody_lives_value, string.format("%d", readSWord(addrs.woody.lives))); formSetText(woody_state_value, string.format("%s", values.woody_state[readWord(addrs.woody.state)])); formSetText(screen_x_value, string.format("%d", readWord(addrs.screen.position.x))); formSetText(screen_y_value, string.format("%d", readWord(addrs.screen.position.y))); formSetText(screen_vx_value, string.format("%d", readSWord(addrs.screen.velocity.x))); formSetText(screen_vy_value, string.format("%d", (readSWord(addrs.screen.velocity.y) * -1))); if (readWord(addrs.general.level) == 0x0008) then -- get tire data -- get buzz data elseif (readWord(addrs.general.level) == 0x000C) then formSetText(level1, "Buzz:"); formSetText(level1_1, "X:"); formSetText(level1_2, "Y:"); formSetText(level1_1_value, string.format("%d", readWord(addrs.level_data[12].buzz.position.x))); formSetText(level1_2_value, string.format("%d", readWord(addrs.level_data[12].buzz.position.y))); else formSetText(level1, ""); formSetText(level1_1, ""); formSetText(level1_2, ""); formSetText(level1_1_value, ""); formSetText(level1_2_value, ""); end end function currentStars() local starsLevel = readWord(addrs.general.bonus_stars.level); local starsTotal = readWord(addrs.general.bonus_stars.total); if (starsLevel < 50) then starsCurrent = starsLevel + starsTotal; elseif (starsLevel == 50) then if (readWord(addrs.general.level) == 16) then return starsCurrent + 2; else return starsCurrent + 1; end end return starsCurrent; end -- Initiate the Main Form Window. mainForm(); while true do updateData(); if (pokeFormState == false) then -- pokeFormat(); end emu.frameadvance(); end