Advertisement
Guest User

Sonic1-Obj.lua

a guest
Jul 21st, 2017
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 38.29 KB | None | 0 0
  1. -- Configurable stuff
  2.  
  3. --[[
  4.     0 => Sonic 1 REV00
  5.     1 => Sonic 1 REV01
  6.     2 => Sonic 2 Nick Arcade
  7.     3 => Sonic 2 Simon Wai
  8.     4 => Sonic 2 REV00
  9. ]]--
  10. gameVersion = 0
  11.  
  12. buttondelay = 6 -- delay for holding navigation buttons (in frames)
  13. goat = false -- do not set unless you know how this script works
  14.  
  15. -- nonconfigurable stuff below
  16.  
  17. sonic1Rev0 = 0
  18. sonic1Rev1 = 1
  19. sonic2NAProto = 2
  20. sonic2SWProto = 3
  21. sonic2Rev0 = 4
  22.  
  23. -- SONIC 1 OBJECT LIST
  24. if gameVersion < sonic2NAProto then
  25. objects = {  
  26.  
  27. --[[    {0x53, 0x01, 0x04, 0x42B8, 0x0000, 0x8746, 0x00, 0x00, 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, ""},
  28.     {0x55, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ""},
  29.     {0x71, 0x31, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ""},
  30.     {0x73, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ""},
  31.     {0x74, 0x01, 0x86, 0x0345, 0x0000, 0xB36E, 0x08, 0x08, 0x05, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, ""},
  32.     ]]--
  33. --   Type SType
  34.     {0x01, 0x00, 0x84, 0x0780, 0x0002, 0x11E2, 0x13, 0x09, 0x02, 0x18, 0x01, 0x01, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, "Sonic"},
  35.     {0x02, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Null"},
  36.    
  37.     {0x09, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Sonic (Special Stage)"},
  38.     {0x0D, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Signpost"},
  39.     {0x0E, 0x00, 0x00, 0x2300, 0x0000, 0xA888, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Sonic (Title Screen)"},
  40.     {0x0F, 0x00, 0x80, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Title screen text"},
  41.  
  42.     {0x11, 0x0C, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "GHZ Bridge", "Number of logs"},
  43.     {0x13, 0x30, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Fireball Maker", "Fireball spawn delay"},
  44.     {0x14, 0x02, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Fireball"},
  45.     {0x15, 0x06, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Swinging Platform"},
  46.    
  47.     {0x17, 0x10, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Rotating spikes (GHZ)"},
  48.     {0x18, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Platform"},
  49.     {0x19, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Blank object"},
  50.     {0x1A, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Collapsing Ledge (GHZ)"},
  51.     {0x1C, 0x03, 0x01, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, "Zone Scenery"},
  52.     {0x1F, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Crabmeat"},
  53.    
  54.     {0x21, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "HUD"},
  55.     {0x22, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Buzz Bomber "},
  56.     {0x23, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Buzz Bomber Bomb"},
  57.     {0x25, 0x12, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Ring"},
  58.     {0x26, 0x06, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Monitor"},
  59.     {0x27, 0x00, 0x84, 0x05A0, 0x0000, 0x8EC6, 0x0E, 0x08, 0x01, 0x0C, 0x00, 0x03, 0x01, 0x00, 0x00, 0x80, 0x04, 0x02, "Explosion"},
  60.     {0x28, 0x00, 0x85, 0x0592, 0x0000, 0x947E, 0x0C, 0x00, 0x06, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Animals"},
  61.     {0x29, 0x00, 0x84, 0x2797, 0x0000, 0x94AE, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Points"},
  62.     {0x2B, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Chopper"},
  63.     {0x2E, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, "Monitor contents"},
  64.     {0x2F, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Large Platform (MZ)"},
  65.    
  66.     {0x30, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Large Glassy Block"},
  67.     {0x31, 0x80, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Chandelier (MZ)"},
  68.     {0x32, 0x80, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Switch"},  
  69.     {0x33, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Moveable block"},
  70.     {0x34, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Title card"},
  71.     {0x35, 0x00, 0x84, 0x0345, 0x0000, 0xB36E, 0x00, 0x00, 0x01, 0x08, 0x00, 0x01, 0x00, 0x8B, 0x00, 0x00, 0x02, 0x00, "Floor fireball"},
  72.     {0x36, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Spikes"},
  73.     {0x37, 0x00, 0x84, 0x27B2, 0x0000, 0x9F92, 0x08, 0x08, 0x03, 0x08, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x02, 0x00, "Rings (When hit)"},
  74.     {0x38, 0x00, 0x86, 0x055C, 0x0001, 0x43B2, 0x00, 0x00, 0x01, 0x10, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, "Invincibility Stars"},
  75.     {0x39, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Game Over/Time Over"},
  76.     {0x3A, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "End of level screen"},
  77.     {0x3B, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Purple rock (GHZ)"},
  78.     {0x3C, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Breakable wall"},
  79.     {0x3D, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Eggman (GHZ)"},
  80.     {0x3E, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Egg Prison"},
  81.     {0x3F, 0x05, 0x84, 0x046C, 0x0001, 0x8580, 0x00, 0x00, 0x06, 0x08, 0x01, 0x20, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, "Large Explosion"},
  82.  
  83.     {0x40, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Motobug"},
  84.     {0x41, 0x02, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Spring"},
  85.     {0x42, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Newtron"},
  86.     {0x44, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Wall Barrier (GHZ)"},
  87.     {0x46, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Solid block (MZ)"},
  88.     {0x48, 0x00, 0x04, 0x046C, 0x0001, 0x7DD4, 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Swinging Ball (GHZ Boss)"},
  89.     {0x49, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Waterfall SFX"},
  90.     {0x4A, 0x00, 0x00, 0x0000, 0x0001, 0x446C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Proto Special stage warp"},
  91.     {0x4B, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Giant Ring"},
  92.     {0x4C, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Lava"},
  93.     {0x4D, 0x00, 0x04, 0x63A8, 0x0000, 0xF24A, 0x00, 0x00, 0x01, 0x20, 0x06, 0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, "Lava falling from ceiling"},
  94.     {0x4E, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Wall of lava"},
  95.        
  96.     {0x50, 0x00, 0x84, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, "Yadrin"},
  97.     {0x51, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Smashable Green Block"},
  98.     {0x52, 0x41, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Moving Block (MZ)"},
  99.     {0x54, 0x01, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Invisible lava hurtbox (MZ)"},
  100.    
  101.     {0x78, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Caterkiller"}, 
  102.     {0x79, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Lamppost"},
  103.     {0x7C, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Giant ring flash"},
  104.     {0x7D, 0x03, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Hidden points"},
  105.     {0x7E, 0x00, 0x00, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, "Special stage results screen"},
  106.     {0x7F, 0x00, 0x00, 0x8541, 0x0000, 0xCDF4, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Emeralds (SS Results screen)"},
  107.    
  108.     {0x8A, 0x00, 0x80, 0x00A6, 0x0001, 0x72E2, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Credits text"},
  109.  
  110. }
  111. subtypes = {}
  112. subtypes[0x14] = {
  113.     {0x00, "Jumping (1)"},
  114.     {0x01, "Jumping (2)"},
  115.     {0x02, "Jumping (3)"},
  116.     {0x03, "Jumping (4)"},
  117.     {0x04, "Medium - Facing up"},
  118.     {0x05, "Medium - Facing down"},
  119.     {0x06, "Medium - Facing left"},
  120.     {0x07, "Medium - Facing right"},
  121.     -- glitchy stuff
  122.     {0x08, "Static - Facing right"},
  123.     {0x09, "10 Points"},
  124.     {0x0A, "Very Slow - Facing right"},
  125.     {0x0B, "Instant - Facing right"},
  126.     {0x0C, "Temp vertical wall"},
  127.     {0x0D, "Slow - Facing right"},
  128. }
  129.  
  130. subtypes[0x15] = {
  131.     {0x00, "Normal - 1"},
  132.     {0x01, "Normal - 2"},
  133.     {0x02, "Normal - 3"},
  134.     {0x03, "Normal - 4"},
  135.     {0x04, "Normal - 5"},
  136.     {0x05, "Normal - 6"},
  137.     {0x06, "Normal - 7"},
  138.     {0x07, "Normal - 8"},
  139.     {0x08, "Normal - 9"},
  140.     {0x09, "Normal - 10"},
  141.     {0x0A, "Normal - 11"},
  142.     {0x0B, "Normal - 12"},
  143.     {0x0C, "Normal - 13"},
  144.     {0x0D, "Normal - 14"},
  145.     {0x10, "Wrecking Ball - 1"},
  146.     {0x11, "Wrecking Ball - 2"},
  147.     {0x12, "Wrecking Ball - 3"},
  148.     {0x13, "Wrecking Ball - 4"},
  149.     {0x14, "Wrecking Ball - 5"},
  150.     {0x15, "Wrecking Ball - 6"},
  151.     {0x16, "Wrecking Ball - 7"},
  152.     {0x17, "Wrecking Ball - 8"},
  153.     {0x18, "Wrecking Ball - 9"},
  154.     {0x19, "Wrecking Ball - 10"},
  155.     {0x1A, "Wrecking Ball - 11"},
  156.     {0x1B, "Wrecking Ball - 12"},
  157.     {0x1C, "Wrecking Ball - 13"},
  158.     {0x1D, "Wrecking Ball - 14"},
  159. }
  160. subtypes[0x18] = {
  161.     {0x0, "Doesn't move"},
  162.     {0x1, "Moves side to side"},
  163.     {0x2, "Moves up and down"},
  164.     {0x3, "Falls when stood on"},
  165.     {0x4, "Falls immediately"},
  166.     {0x5, "Moves side to side"},
  167.     {0x6, "Moves up and down"},
  168.     {0x7, "Rises when switch is pressed"},
  169.     {0x8, "Rises immediately"},
  170.     {0x9, "Doesn't move"},
  171.     {0xA, "Large, moves up and down"},
  172.     {0xB, "Moves up and down slowly"},
  173.     {0xC, "Moves up and down slowly"},
  174. }
  175. --subtypes[0x1A] = {
  176. --  {0x00, "Style 1"},
  177. --  {0x01, "Style 2"},
  178. --}
  179. subtypes[0x1C] = {
  180.     {0x00, "Fireball launcher (SLZ)"},
  181.     {0x03, "Bridge Stump (GHZ)"},
  182. }
  183.  
  184. subtypes[0x26] = {
  185.     {0x00, "Blank"},
  186.     {0x01, "Robotnik"},
  187.     {0x02, "1-Up"},
  188.     {0x03, "Speed Up"},
  189.     {0x04, "Shield"},
  190.     {0x05, "Invincibility"},
  191.     {0x06, "Ring"},
  192.     {0x07, "S"},
  193.     {0x08, "Goggles"},
  194. }
  195.  
  196. subtypes[0x2F] = {
  197.     {0x00, "Large - Static"},
  198.     {0x01, "Large - Oscillation 1"},
  199.     {0x02, "Large - Oscillation 2"},
  200.     {0x03, "Large - Oscillation 3"},
  201.     {0x04, "Large - Oscillation 4"},
  202.     {0x05, "Large - Sinking into lava"},
  203.  
  204.     {0x10, "Diagonal - Static"},
  205.     {0x11, "Diagonal - Oscillation 1"},
  206.     {0x12, "Diagonal - Oscillation 2"},
  207.     {0x13, "Diagonal - Oscillation 3"},
  208.     {0x14, "Diagonal - Oscillation 4"},
  209.     {0x15, "Diagonal - Sinking into lava"},
  210.  
  211.     {0x20, "Flat - Static"},
  212.     {0x21, "Flat - Oscillation 1"},
  213.     {0x22, "Flat - Oscillation 2"},
  214.     {0x23, "Flat - Oscillation 3"},
  215.     {0x24, "Flat - Oscillation 4"},
  216.     {0x25, "Flat - Sinking into lava"},
  217. }
  218.  
  219. subtypes[0x30] = {
  220.     {0x00, "Big - Static"},
  221.     {0x02, "Big - Oscillating"},
  222.     {0x06, "[Glitch] Sets demo mode"},
  223.     {0x08, "Small - Static"},
  224.     {0x0A, "Small - Oscillating"},
  225.     {0x04, "Activated by switch 0"},
  226.     {0x14, "Activated by switch 1"},
  227.     {0x24, "Activated by switch 2"},
  228.     {0x34, "Activated by switch 3"},
  229.     {0x44, "Activated by switch 4"},
  230.     {0x54, "Activated by switch 5"},
  231.     {0x64, "Activated by switch 6"},
  232.     {0x74, "Activated by switch 7"},
  233.     {0x84, "Activated by switch 8"},
  234.     {0x94, "Activated by switch 9"},
  235.     {0xA4, "Activated by switch A"},
  236.     {0xB4, "Activated by switch B"},
  237.     {0xC4, "Activated by switch C"},
  238.     {0xD4, "Activated by switch D"},
  239.     {0xE4, "Activated by switch E"},
  240.     {0xF4, "Activated by switch F"},
  241. }
  242.  
  243. subtypes[0x31] = {
  244.     {0x00, "Spiked Large - Static"},
  245.     {0x01, "Spiked Large - Long chain"},
  246.     {0x03, "Spiked Large - Medium chain"},
  247.     {0x02, "Spiked Large - Short chain"},
  248.     {0x10, "Spiked Small - Static"},
  249.     {0x11, "Spiked Small - Long chain"},
  250.     {0x13, "Spiked Small - Medium chain"},
  251.     {0x12, "Spiked Small - Short chain"},
  252.     {0x20, "Block Small - Static"},
  253.     {0x21, "Block Small - Long chain"},
  254.     {0x23, "Block Small - Medium chain"},
  255.     {0x22, "Block Small - Short chain"},
  256.     {0x80, "Activated by switch 0"},
  257.     {0x81, "Activated by switch 1"},
  258.     {0x82, "Activated by switch 2"},
  259. }
  260.  
  261. subtypes[0x32] = {}
  262. for i = 0x01, 0x10 do
  263.     subtypes[0x32][i] = {i - 1, "Switch " .. i - 1}
  264. end
  265. for i = 0x21, 0x30 do
  266.     subtypes[0x32][i - 0x10] = {i - 1, "Flashing Switch " .. i - 0x21}
  267. end
  268.  
  269. subtypes[0x36] = {
  270.     {0x00, "Upright (3) - Still"},
  271.     {0x01, "Upright (3) - V Movement"},
  272.     {0x02, "Upright (3) - H Movement"},
  273.     {0x10, "Sideways (3) - Still"},
  274.     {0x11, "Sideways (3) - V Movement"},
  275.     {0x12, "Sideways (3) - H Movement"},
  276.     {0x20, "Upright (1) - Still"},
  277.     {0x21, "Upright (1) - V Movement"},
  278.     {0x22, "Upright (1) - H Movement"},
  279.     {0x30, "Upright (3; wide) - Still"},
  280.     {0x31, "Upright (3; wide) - V Movement"},
  281.     {0x32, "Upright (3; wide) - H Movement"},
  282.     {0x40, "Upright (6; wide) - Still"},
  283.     {0x41, "Upright (6; wide) - V Movement"},
  284.     {0x42, "Upright (6; wide) - H Movement"},
  285.     {0x50, "Sideways (1) - Still"},
  286.     {0x51, "Sideways (1) - V Movement"},
  287.     {0x52, "Sideways (1) - H Movement"},
  288. }
  289.  
  290. subtypes[0x3C] = {
  291.     {0x00, "Left edge"},
  292.     {0x01, "Main wall"},
  293.     {0x02, "Right edge"},
  294. }
  295.  
  296. subtypes[0x3E] = {
  297.     {0x00, "Prison"},
  298.     {0x01, "Button"},
  299.     {0x02, "Explosions"},
  300. }
  301.  
  302. subtypes[0x41] = {
  303.     {0x00, "Red vertical spring"},
  304.     {0x02, "Yellow vertical spring"},
  305.     {0x10, "Red spring facing left"},
  306.     {0x12, "Yellow spring facing left"},
  307. }
  308.  
  309. subtypes[0x42] = {
  310.     {0x00, "Flies along the ground"},
  311.     {0x01, "Fires missile, then disappears"},
  312. }
  313.  
  314. subtypes[0x44] = {
  315.     {0x00, "Shading at top"},
  316.     {0x01, "Regular platform"},
  317.     {0x02, "Fully shaded"},
  318. }
  319.  
  320. subtypes[0x46] = {
  321.     {0x00, "Static"},
  322.     {0x01, "Wobbling, doesn't fall"},
  323.     {0x02, "Wobbling, falls"},
  324.     {0x03, "Immediately falls"},
  325.     {0x04, "Wobbling, slow"},
  326. }
  327.  
  328. subtypes[0x4C] = {
  329.     {0x00, "Lava geyser"},
  330.     {0x01, "Falling from ceiling"},
  331.     {0x03, "[Glitch] Stream"},
  332.  
  333. }
  334.  
  335. subtypes[0x52] = {
  336.     {0x00, "Static"},
  337.     {0x01, "H moving block"},
  338.     {0x02, "Moves right when standing"},
  339.     {0x05, "Moves right, then falls"},
  340.     {0x06, "Immediately falls"},
  341.     {0x07, "Appears on switch 2"},
  342.     {0x08, "V moving block"},
  343.     {0x09, "Sliding block"},
  344.     {0x28, "V moving platform"},
  345.     {0x39, "Sliding platform"},
  346.     {0x41, "H moving platform"},
  347.     {0x03, "[Glitch] Moves right"},
  348.     {0x04, "[Glitch] Static"},
  349. }
  350.  
  351. subtypes[0x54] = {
  352.     {0x00, "Small"},
  353.     {0x01, "Medium"},
  354.     {0x02, "Big"},
  355. }
  356.  
  357. subtypes[0x79] = {
  358.     {0x00, ""},
  359.     {0x01, ""},
  360.     {0x02, ""},
  361.     {0x03, ""},
  362.     {0x04, ""},
  363.     {0x05, ""},
  364.     {0x06, ""},
  365.     {0x07, ""},
  366.     {0x08, ""},
  367.     {0x09, ""},
  368. }
  369.  
  370.  
  371.  
  372. subtypes[0x7D] = {
  373.     {0x01, "1000 points"},
  374.     {0x02, "100 points"},
  375.     {0x03, "10 points"},
  376. }
  377.  
  378.  
  379. -- for obj testing only
  380. if goat then
  381.     subtypes[goat] = {}
  382.     for i = 0x00, 0x100 do
  383.         subtypes[goat][i] = {i - 1, ""}
  384.     end
  385. end
  386.  
  387.  
  388. -- REV01 patch data
  389. if gameVersion == sonic1Rev1 then
  390.     objects[1] = {0x01, 0x00, 0x84, 0x0780, 0x0002, 0x1CF4, 0x13, 0x09, 0x02, 0x18, 0x01, 0x03, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, "Sonic"}
  391.     objects[2] = {0x0E, 0x00, 0x00, 0x2300, 0x0000, 0xAF12, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Sonic (Title Screen)"}
  392.     objects[2] = {0x27, 0x00, 0x84, 0x05A0, 0x0000, 0x9544, 0x00, 0x00, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, "Explosion"}
  393.     objects[2] = {0x28, 0x00, 0x85, 0x0592, 0x0000, 0x9AFC, 0x0C, 0x00, 0x06, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Freed Animals"}
  394.     objects[2] = {0x29, 0x00, 0x84, 0x2797, 0x0000, 0x9B2C, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Points"}
  395.     objects[2] = {0x2E, 0x00, 0xA4, 0x0680, 0x0000, 0xAC80, 0x00, 0x00, 0x03, 0x08, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, "Monitor contents"}
  396.     objects[2] = {0x48, 0x05, 0x04, 0x046C, 0x0001, 0x8580, 0x00, 0x00, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, ""}
  397.     objects[2] = {0x7F, 0x00, 0x00, 0x8541, 0x0000, 0xD482, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Emeralds (SS Results screen)"}
  398.     objects[2] = {0x8A, 0x00, 0x80, 0x00A6, 0x0001, 0x7A8E, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, "Credits text"}
  399. end
  400.  
  401. elseif gameVersion == sonic2NAProto then
  402.  
  403. elseif gameVersion == sonic2SWProto then
  404.  
  405. elseif gameVersion >= sonic2Rev0 then
  406.  
  407. end
  408.  
  409.  
  410. -- Addresses for object ram
  411. if gameVersion < sonic2NAProto then
  412.     -- Sonic 1
  413.     address = 0xFFD000
  414.     minaddr = 0xFFD000
  415.     maxaddr = 0xFFEFC0
  416. else
  417.     -- Sonic 2
  418.     address = 0xFFB000
  419.     minaddr = 0xFFB000
  420.     maxaddr = 0xFFCFC0
  421. end
  422.  
  423. function math.round(num, idp)
  424.     local mult = 10^(idp or 0)
  425.     if num >= 0 then return math.floor(num * mult + 0.5) / mult
  426.     else return math.ceil(num * mult - 0.5) / mult end
  427. end
  428.  
  429. function mouserange(x1, y1, x2, y2)
  430.     return (inpt.xmouse >= x1 and inpt.xmouse <= x2 and inpt.ymouse >= y1 and inpt.ymouse <= y2)
  431. end
  432.  
  433. -- to go with memory.print
  434. function memory.writeval(addr, value, len)
  435.     if len == 1 then
  436.         memory.writebyte(addr, value)
  437.     elseif len == 2 then
  438.         memory.writeword(addr, value)
  439.     else
  440.         memory.writelong(addr, value)
  441.     end
  442. end
  443.  
  444. function memory.readval(addr, len)
  445.     if len == 1 then
  446.         return memory.readbyte(addr)
  447.     elseif len == 2 then
  448.         return memory.readword(addr)
  449.     else
  450.         return memory.readlong(addr)
  451.     end
  452. end
  453.  
  454. --[[
  455.     THANKS GUYS FOR NOT IMPLEMENTING THESE FUNCTIONS!!11!!
  456. ]]--
  457. function memory.readlong(addr)
  458.     local a1 = memory.readword(addr)
  459.     local a2 = memory.readword(addr + 4)
  460.     --print (string.format("%04X", a1) .. " + " .. string.format("%04X", a2) .. " = " .. string.format("%04X", (a1 * 0x10000) + a2))
  461.     return (a1 * 0x10000) + a2
  462. end
  463. function memory.writelong(addr, val)
  464.     local v_upper = math.floor(val / 0x10000)
  465.     local v_lower = val % 0x10000
  466.     memory.writeword(addr, v_upper)
  467.     memory.writeword(addr + 4, v_lower)
  468.     --print (string.format("%04X", v_upper) .. " + " .. string.format("%04X", v_lower) .. " = " .. string.format("%04X", val))
  469. end
  470.  
  471.  
  472. function string.pad(str, val)
  473.     local l = string.len(str)
  474.    
  475.     if l >= val then -- the string is already big enough to fit
  476.         return str
  477.     else
  478.         local pad = val - l
  479.         return string.rep(" ", pad) .. str
  480.     end
  481. end
  482.  
  483. --[[
  484.     Searches the first free slot (obj 00) from the not-reserved ones
  485. ]]--
  486. function searchfree()
  487.     local i = minaddr + 0x800
  488.     local out
  489.     while (i < maxaddr) do
  490.         out = memory.readbyte(i)
  491.         if (out == 0) then
  492.             return i
  493.         else
  494.             i = i + 0x40
  495.         end
  496.     end
  497.     return nil
  498. end
  499.  
  500. function getkeyfromtype(id, subtype)
  501.     local sres = nil
  502.     for i in ipairs(objects) do
  503.         if objects[i][1] == id then
  504.             -- iterate over subtypes if they exist
  505.             if subtypes[id] ~= nil then
  506.                 for j in ipairs(subtypes) do
  507.                     if (subtypes[j][1] == subtype) then
  508.                         sres = j
  509.                         break
  510.                     end
  511.                 end
  512.             end
  513.             return {i, sres}
  514.         end
  515.     end
  516.     return {2, sres} -- null / unknown
  517. end
  518.  
  519. function getbit(value, pos)
  520.     if (pos == 1) then
  521.         offset = 1
  522.     else
  523.         offset = (2 ^ pos) - 2
  524.     end
  525.     return math.floor(value / offset) % 2
  526. end
  527. function setbit(value, pos, cached)
  528.     if cached == nil then
  529.         cached = getbit(value, pos)
  530.     end
  531.    
  532.    
  533.     if (pos == 1) then
  534.         offset = 1
  535.     else
  536.         offset = 2 ^ pos - 2
  537.     end
  538.    
  539.     if cached == 0 then
  540.         return value + offset
  541.     else
  542.         return value - offset
  543.     end
  544. end
  545. function getobjectpos(addr)
  546.     local out = {
  547.         x = memory.readword(addr + 0x08) - screen_x,
  548.         y = memory.readword(addr + 0x0C) - screen_y,
  549.         ry = memory.readbyte(addr + 0x16), -- radius x
  550.         rx = memory.readbyte(addr + 0x17), -- radius y
  551.     }
  552.     -- this bit forces the height to be 32 pixels
  553.     --local changer = getbit(memory.readbyte(addr + 0x01), 3)
  554.     if out['ry'] < 2 or out['rx'] < 2 then
  555.         out['ry'] = 0x8
  556.         out['rx'] = 0x8
  557.     end
  558.     return out
  559. end
  560.  
  561. -- search through non-null objects and render their hitbox
  562. function renderhitbox()
  563.     local i = minaddr
  564.     local stat
  565.     local color
  566.     while i < maxaddr do
  567.         if memory.readbyte(i) ~= 0 then
  568.             stat = getobjectpos(i)
  569.             if (mouserange(stat['x'] - stat['rx'], stat['y'] - stat['ry'], stat['x'] + stat['rx'], stat['y'] + stat['ry'])) then
  570.                 if (inpt.leftclick) then
  571.                     color = "green"
  572.                     moveobject(i)
  573.                     address = i -- also select it
  574.                 else
  575.                     color = "white"
  576.                 end
  577.             else
  578.                 color = "red"
  579.             end
  580.             gui.box(stat['x'] - stat['rx'], stat['y'] - stat['ry'], stat['x'] + stat['rx'], stat['y'] + stat['ry'], "#00000000", color)
  581.  
  582.         end
  583.         i = i + 0x40
  584.     end
  585. end
  586.  
  587. function moveobject(addr)
  588.     local x = screen_x + inpt.xmouse
  589.     local y = screen_y + inpt.ymouse
  590.     memory.writeword(addr + 0x08, x)
  591.     memory.writeword(addr + 0x0C, y)
  592. end
  593.  
  594. --[[
  595.     Debug scanning
  596.     Constantly scans the object list until it finds the object in its first state
  597.    
  598.     when it does it will return the address
  599. ]]--
  600. function scanobject(id, subtype)
  601.     if (id) then
  602.         local i = minaddr
  603.         local out
  604.         local checksub
  605.         -- if no subtype is specified, skip the subtype check
  606.         if (subtype == nil) then
  607.             checksub = subtype
  608.         end
  609.         while (i < maxaddr) do
  610.             checkid  = memory.readbyte(i)
  611.             if (subtype) then
  612.                 checksub = memory.readbyte(i+0x28)
  613.             end
  614.                
  615.             if (checkid == id and checksub == subtype) then
  616.                 return i
  617.             else
  618.                 i = i + 0x40
  619.             end
  620.         end
  621.     end
  622.     return nil
  623. end
  624.  
  625. function memory.print(addr, len, title, objecttitle, bit)
  626.     local color         -- table color
  627.     local print_val     -- value in hexadecimal form
  628.     local res
  629.     res = memory.readval(addr, len) -- output (read address)
  630.    
  631.     --local print_addr = title .. " (" .. string.format("%06X", addr) .. ")" -- address in hex form
  632.     local x2 = string.len(title)
  633.    
  634.    
  635.    
  636.     -- calculate a temporary offset for the buttons
  637.     local button_offset
  638.     if (bit == nil) then
  639.         button_offset = 4
  640.     else
  641.         button_offset = 0
  642.     end
  643.    
  644.     -- text padding
  645.     if len == 1 then
  646.         if objecttitle then
  647.             x2 = 31        
  648.             print_val = string.pad(string.format("%02X ", res) .. objecttitle, x2 + button_offset)
  649.         else
  650.             print_val = string.pad(string.format("%02X", res), x2 + button_offset)
  651.         end
  652.         if min == nil then
  653.             min = 0x00
  654.             max = 0xFF
  655.             jump = 1
  656.         end
  657.     elseif len == 2 then
  658.         print_val = string.pad(string.format("%04X", res), x2 + button_offset)
  659.         if min == nil then
  660.             min = 0x00
  661.             max = 0xFFFF
  662.             jump = 1
  663.         end
  664.     else
  665.         print_val = string.pad(string.format("%08X", res), x2 + button_offset)
  666.         if min == nil then
  667.             min = 0x00
  668.             max = 0xFFFFFFFF
  669.             jump = 1
  670.         end
  671.     end
  672.    
  673.     -- account for font size
  674.     x2 = x2 * 4
  675.    
  676.     if (bit == nil) then
  677.         navbuttons(addr, len, res, table_x + x2 + 1, table_y, min, max, jump) -- will take x + 16 + 1
  678.         button_offset = 18
  679.         --table_x = table_x + x2 + 19
  680.     else
  681.         --checkbox(addr, res, bit, table_x + x2 + 1, table_y) -- will take x + 8 + 1
  682.         button_offset = 10
  683.     end
  684.    
  685.     -- draw address
  686.     gui.box(table_x, table_y, table_x + x2, table_y + 8, "#000000f0", color)
  687.     gui.text(table_x + 1, table_y + 1, title, "white", "clear")
  688.  
  689.     -- and its value
  690.     gui.box(table_x, table_y + 9, table_x + x2 + button_offset, table_y + 16, "#000000f0", color)
  691.     gui.text(table_x + 1, table_y + 10, print_val, "white", "clear")
  692.    
  693.     table_x = table_x + x2 + button_offset + 1
  694.        
  695.     return res
  696. end
  697.  
  698. --[[
  699.     Render a checkbox
  700.    
  701.     addr: address to change
  702.     res: value of address
  703.     bit: bits to switch
  704.     x: x position
  705.     y: y position
  706. ]]--   
  707. function checkbox(addr, res, bit, title, x, y)
  708.     local bitvalue = getbit(res, bit)
  709.     local offset = (string.len(title) * 4)
  710.     -- selection color and hitbox
  711.     local color = "black"
  712.     if (buttondelaycur == 0 and mouserange(x + offset + 1, y, x + offset + 11, y + 8)) then
  713.         -- left selected: decrement
  714.         if inpt.leftclick then
  715.             color = "green"
  716.             memory.writebyte(addr, setbit(res, bit, bitvalue))
  717.             buttondelaycur = buttondelay
  718.         else
  719.             color = "white"
  720.         end
  721.     end
  722.    
  723.    
  724.     -- checkbox icon
  725.     local check = " X"
  726.     if bitvalue == 0 then
  727.         check = ""
  728.     end
  729.    
  730.  
  731.     gui.box(x, y, x + 10 + offset, y + 8, "#000000f0", "black")
  732.     gui.text(x + 1, y + 1, title, "white", "clear")
  733.     gui.box(x + offset + 1, y, x + 11 + offset, y + 8, "#000000f0", color)
  734.     gui.text(x + offset + 2, y + 1, check, "white", "clear")
  735.    
  736. end
  737.  
  738. --[[
  739.     Render two clickable buttons to respectively decrement / increment values
  740.    
  741.     addr: address to change
  742.     len: value length (1 - byte, 2 - word, 4 - long)
  743.     res: value of address
  744.     x: x position
  745.     y: y position
  746. ]]--   
  747. function navbuttons(addr, len, res, x, y,  min, max, jump)
  748.  
  749.     -- selection colors
  750.     local colors = {"black", "black"}
  751.     if (buttondelaycur == 0) then
  752.  
  753.         -- Selection ""hitbox""
  754.         local selectleft  = mouserange(x, y, x + 8, y + 8)
  755.         local selectright = mouserange(x + 9, y, x + 17, y + 8)
  756.        
  757.        
  758.        
  759.         if selectleft then
  760.             -- left selected: decrement
  761.             if inpt.leftclick then
  762.                 colors[1] = "green"
  763.                 if res > 0 then
  764.                     memory.writeval(addr, res - 1, len)
  765.                     buttondelaycur = buttondelay
  766.                 end
  767.             else
  768.                 colors[1] = "white"
  769.             end
  770.         elseif selectright then
  771.             -- right selected: increment
  772.             if inpt.leftclick then
  773.                 colors[2] = "green"
  774.                 memory.writeval(addr, res + 1, len)
  775.                 buttondelaycur = buttondelay
  776.             else
  777.                 colors[2] = "white"
  778.             end
  779.         end
  780.     end
  781.    
  782.     -- render the buttons
  783.     gui.box(x, y, x + 8, y + 8, "#000000f0", colors[1])
  784.     gui.text(x + 1, y + 1, "<", "white", "clear")
  785.    
  786.     gui.box(x + 9, y, x + 17, y + 8, "#000000f0", colors[2])
  787.     gui.text(x + 10, y + 1, ">", "white", "clear")
  788.    
  789.    
  790.    
  791. end
  792.  
  793.  
  794. --[[
  795.     Increment / Decrement the object id
  796. ]]--
  797. function objbuttons(addr, jump, min, max, x, y)
  798.  
  799.     -- selection colors
  800.     local colors = {"black", "black"}
  801.    
  802.     if (buttondelaycur == 0) then
  803.        
  804.         -- Selection ""hitbox""
  805.         local selectleft  = address > min and mouserange(x, y, x + 8, y + 8)
  806.         local selectright = address < max and mouserange(x + 9, y, x + 17, y + 8)
  807.        
  808.         -- selection colors
  809.         if address <= min then
  810.             colors[1] = "gray"
  811.         end
  812.         if address >= max then
  813.             colors[2] = "gray"
  814.         end
  815.        
  816.         if selectleft then
  817.             -- left selected: decrement
  818.             if inpt.leftclick then
  819.                 colors[1] = "green"
  820.                 address = address - jump
  821.                 buttondelaycur = buttondelay
  822.             else
  823.                 colors[1] = "white"
  824.             end
  825.         elseif selectright then
  826.             -- right selected: increment
  827.             if inpt.leftclick then
  828.                 colors[2] = "green"
  829.                 address = address + jump
  830.                 buttondelaycur = buttondelay
  831.             else
  832.                 colors[2] = "white"
  833.             end
  834.         end
  835.     end
  836.        
  837.     -- render the buttons
  838.     gui.box(x, y, x + 8, y + 8, "#000000f0", colors[1])
  839.     gui.text(x + 1, y + 1, "<", "white", "clear")
  840.    
  841.     gui.box(x + 9, y, x + 17, y + 8, "#000000f0", colors[2])
  842.     gui.text(x + 10, y + 1, ">", "white", "clear")
  843.    
  844. end
  845.  
  846. --[[
  847.     This table contains object information
  848. ]]--
  849. function rendertable()
  850.     local objstate = {}
  851.    
  852.     -- Draw table
  853.     table_x = 0;
  854.     table_y = 0;
  855.    
  856.     -- Print object status
  857.     -- (address, byte (1) or word (2)
  858.    
  859.     -- draw address
  860.    
  861.     -- Navigation buttons
  862.     objbuttons(address, 0x40, minaddr, maxaddr, 19 * 4 + 1, 0)
  863.    
  864.     -- Table title with address information
  865.     local id = math.floor((address - minaddr) / 0x40)
  866.     local addr_text = "Object " .. string.format("%02X", id) .. " (" .. string.format("%06X", address) .. ")";
  867.     local addr_len = 19 * 4 --string.len(addr_text) * 4
  868.     gui.box(0, 0, addr_len, 8, "#000000f0", color)
  869.     gui.text(1, 1, addr_text, "white", "clear")
  870.    
  871.  
  872.    
  873.     table_x = 0
  874.     table_y = 9
  875.     objectmarker = getkeyfromtype(memory.readbyte(address), memory.readbyte(address+0x28))
  876.     local typetitle
  877.     if objects[objectmarker[1]] == nil then
  878.         typetitle = nil
  879.     else
  880.         typetitle = objects[objectmarker[1]][19]
  881.     end
  882.    
  883.     local subtypetitle
  884.     if objectmarker[2] == nil then
  885.         subtypetitle = nil
  886.     else
  887.         subtypetitle = subtypes[objectmarker[1]][objectmarker[2]]
  888.     end
  889.    
  890.     memory.print(address, 1, "Object type", typetitle)
  891.     table_x = 0
  892.     table_y = table_y + 17
  893.     memory.print(address + 0x28, 1, "Object subtype", subtypetitle)
  894.     table_x = 0
  895.     table_y = table_y + 17
  896.     memory.print(address + 0x08, 2, "Object X")
  897.     --memory.print(address + 0x0A, 2, "Subpixel X")
  898.     memory.print(address + 0x0C, 2, "Object Y")
  899.     --memory.print(address + 0x0E, 2, "Subpixel Y")
  900.     --memory.print(address + 0x01, 1, "Rendering", nil, true)
  901.     local rendering = memory.readbyte(address + 0x01)
  902.     checkbox(address + 0x01, rendering, 1, "H Mirroring", table_x + 1, table_y)
  903.     checkbox(address + 0x01, rendering, 2, "V Mirroring", table_x + 1, table_y + 9)
  904.    
  905.     table_x = 0
  906.     table_y = table_y + 17 
  907.     memory.print(address + 0x24, 1, "Routine 1")
  908.     memory.print(address + 0x25, 1, "Routine 2")
  909.  
  910.     -- obj status dump
  911.     --[[
  912.     table_x = 0
  913.     table_y = 190
  914.     for i = 0x1, 0x10 do
  915.         memory.print(address - 1 + i, 1, "")
  916.     end
  917.     table_x = 0
  918.     table_y = table_y + 17 
  919.     for i = 0x11, 0x20 do
  920.         memory.print(address - 1 + i, 1, "")
  921.     end
  922.     ]]--
  923. end
  924.  
  925.  
  926.  
  927.  
  928.  
  929. function spawnobject(id, subtype, addr, x, y)
  930.  
  931.     local d
  932.     if subtypes[objects[id][1]] == nil or subtype == nil then -- if no subtype is specified use the default
  933.         d = objects[id][2]
  934.     else
  935.         d = subtypes[objects[id][1]][subtype][1]
  936.     end
  937.    
  938.     memory.writebyte(addr, objects[id][1]) -- object type
  939.     memory.writebyte(addr + 0x28, d) -- object subtype
  940.    
  941.     memory.writebyte(addr + 0x01, objects[id][3]) -- rendering
  942.     memory.writeword(addr + 0x02, objects[id][4]) -- art
  943.     memory.writeword(addr + 0x04, objects[id][5]) -- mappings offset
  944.     memory.writeword(addr + 0x06, objects[id][6]) -- mappings offset
  945.    
  946.     memory.writeword(addr + 0x08, x) -- x
  947.     memory.writeword(addr + 0x0A, 0) -- x subpixel
  948.     memory.writeword(addr + 0x0C, y) -- y
  949.     memory.writeword(addr + 0x0E, 0) -- y subpixel
  950.    
  951.     memory.writebyte(addr + 0x16, objects[id][7]) -- h radius hitbox
  952.     memory.writebyte(addr + 0x17, objects[id][8]) -- v radius hitbox
  953.     memory.writebyte(addr + 0x18, objects[id][9]) -- priority
  954.     memory.writebyte(addr + 0x19, objects[id][10]) -- h radius
  955.    
  956.     memory.writebyte(addr + 0x1A, objects[id][11]) -- animation
  957.     memory.writebyte(addr + 0x1B, objects[id][12]) -- frame
  958.     memory.writebyte(addr + 0x1C, objects[id][13]) -- anim id
  959.     memory.writebyte(addr + 0x1D, objects[id][13]) -- anim id
  960.     memory.writebyte(addr + 0x1E, 0x07) -- anim id
  961.    
  962.     memory.writebyte(addr + 0x20, objects[id][14]) -- collision response
  963.     memory.writebyte(addr + 0x21, objects[id][15]) -- custom collision response
  964.     memory.writebyte(addr + 0x22, objects[id][16]) -- status
  965.    
  966.     memory.writebyte(addr + 0x23, reference)
  967.     reference = reference - 1
  968.     memory.writebyte(addr + 0x24, objects[id][17]) -- routine 1
  969.     memory.writebyte(addr + 0x25, objects[id][18]) -- routine 2
  970.     memory.writebyte(addr + 0x26, 0x00) -- angle
  971.     print("Spawned object " .. id .. " - " .. d .. " at " .. string.format("%06X", addr))
  972.     --print (objectdebug(addr, "Sonic (Spawned)"))
  973. end
  974.  
  975. function objectdebug(addr, title)
  976.     return ("{" ..
  977.         string.format("0x%02X, ", memory.readbyte(addr)) ..
  978.         string.format("0x%02X, ", memory.readbyte(addr + 0x28)) ..
  979.         string.format("0x%02X, ", memory.readbyte(addr + 0x01)) ..
  980.         string.format("0x%04X, ", memory.readword(addr + 0x02)) ..
  981.         string.format("0x%04X, ", memory.readword(addr + 0x04)) ..
  982.         string.format("0x%04X, ", memory.readword(addr + 0x06)) ..
  983.         string.format("0x%02X, ", memory.readbyte(addr + 0x16)) ..
  984.         string.format("0x%02X, ", memory.readbyte(addr + 0x17)) ..
  985.         string.format("0x%02X, ", memory.readbyte(addr + 0x18)) ..
  986.         string.format("0x%02X, ", memory.readbyte(addr + 0x19)) ..
  987.         string.format("0x%02X, ", memory.readbyte(addr + 0x1A)) ..
  988.         string.format("0x%02X, ", memory.readbyte(addr + 0x1B)) ..
  989.         string.format("0x%02X, ", memory.readbyte(addr + 0x1C)) ..
  990.         string.format("0x%02X, ", memory.readbyte(addr + 0x20)) ..
  991.         string.format("0x%02X, ", memory.readbyte(addr + 0x21)) ..
  992.         string.format("0x%02X, ", memory.readbyte(addr + 0x22)) ..
  993.         string.format("0x%02X, ", memory.readbyte(addr + 0x24)) ..
  994.         string.format("0x%02X, ", memory.readbyte(addr + 0x25)) ..
  995.     "\"" .. title .. "\"},")
  996. end
  997.  
  998. --[[
  999.     Object editing list
  1000. ]]--
  1001.  
  1002. function rendermenu()
  1003.     local x = 180
  1004.     local y = 0
  1005.     local slot
  1006.     local screen -- screen x and y
  1007.     gui.box(x - 35, y, x + 90, y + 8, "#000000f0", "black")
  1008.     gui.text(x - 34, y + 1, string.format("%02X ", objects[selection][1]) .. objects[selection][19], "white", "clear")
  1009.    
  1010.     -- type selection
  1011.     local hhack
  1012.     local objectid
  1013.     if objects[selection + 1] == nil then
  1014.         hhack = 0
  1015.         objectid = 0
  1016.     else
  1017.         hhack = 0xFF
  1018.         objectid = objects[selection][1]
  1019.     end
  1020.     selection = selbuttons(selection, 1, hhack, x + 90 + 1, y)
  1021.    
  1022.     --subtype selection
  1023.     local subtypeid
  1024.     if (subtypes[objectid] ~= nil) then
  1025.         subtypeid = subtypes[objectid][subselection][1]
  1026.         gui.box(x - 35, y + 9, x + 90, y + 17, "#000000f0", "black")
  1027.         gui.text(x - 34, y + 10, string.format("%02X ", subtypeid) .. subtypes[objectid][subselection][2], "white", "clear")
  1028.         if subtypes[objectid][subselection + 1] == nil then
  1029.             hhack = 0
  1030.         else
  1031.             hhack = 0xFF
  1032.         end
  1033.         subselection = selbuttons(subselection, 1, hhack, x + 90 + 1, y + 9)       
  1034.     else
  1035.         subtypeid = nil
  1036.         -- subtype extra values
  1037.         if (objects[selection][20] ~= nil) then
  1038.             gui.box(x - 35, y + 9, x + 90, y + 17, "#000000f0", "black")
  1039.             gui.text(x - 34, y + 10, "Subtype: " .. objects[selection][20], "white", "clear")
  1040.         end
  1041.     end
  1042.    
  1043.     -- Pressing the "add object" button
  1044.     local setcolor = "black"
  1045.     if putobject == 1 then
  1046.         if inpt.leftclick and buttondelaycur == 0 then
  1047.             putobject = 0
  1048.             -- spawn the object
  1049.             slot = searchfree()
  1050.             if slot then
  1051.                 spawnobject(selection, subselection, slot, screen_x + inpt.xmouse, screen_y + inpt.ymouse)
  1052.             else
  1053.                 print("No more objects can be added.")
  1054.             end
  1055.         else
  1056.             local x_radius = objects[selection][8]
  1057.             local y_radius = objects[selection][7]
  1058.             if (x_radius == 0) then x_radius = 8 end
  1059.             if (y_radius == 0) then y_radius = 8 end
  1060.             gui.box(inpt.xmouse - x_radius, inpt.ymouse - y_radius, inpt.xmouse + x_radius, inpt.ymouse + y_radius, "#00000080", "black")
  1061.         end
  1062.     else
  1063.         if mouserange(x+110, y, x+140, y+8) then
  1064.             if inpt.leftclick then
  1065.                 putobject = 1
  1066.                 buttondelaycur = buttondelay -- prevent accidental inserts
  1067.             else
  1068.                 setcolor = "green"
  1069.             end
  1070.         end
  1071.     end
  1072.    
  1073.     gui.box(x + 110, y, x + 140, y + 8, "#000000f0", setcolor)
  1074.     gui.text(x + 114, y + 1, "Set", "white", "clear")
  1075.    
  1076.  
  1077.     -- Button to jump to first address with specified object
  1078.     local holdcolor = "black"
  1079.     if mouserange(x + 110, y + 9, x + 140, y + 17) then
  1080.         if inpt.leftclick then
  1081.             holdcolor = "white"
  1082.             -- todo: find first object with selection and subselection
  1083.             local search = scanobject(objectid, subtypeid)
  1084.             if search then
  1085.                 address = search
  1086.             end
  1087.         else
  1088.             holdcolor = "green"
  1089.         end
  1090.     end
  1091.     gui.box(x + 110, y + 9, x + 140, y + 17, "#000000f0", holdcolor)
  1092.     gui.text(x + 114, y + 10, "Find", "white", "clear")
  1093.        
  1094.    
  1095. end
  1096.  
  1097. function selbuttons(var, min, max, x, y)
  1098.  
  1099.     -- var colors
  1100.     local colors = {"black", "black"}
  1101.     if (buttondelaycur == 0) then
  1102.  
  1103.         -- Selection ""hitbox""
  1104.         local selectleft  = var > min and mouserange(x, y, x + 8, y + 8)
  1105.         local selectright = var < max and mouserange(x + 9, y, x + 17, y + 8)
  1106.        
  1107.         if var <= min then
  1108.             colors[1] = "gray"
  1109.         end
  1110.         if var >= max then
  1111.             colors[2] = "gray"
  1112.         end
  1113.        
  1114.        
  1115.         if selectleft then
  1116.             -- left selected: decrement
  1117.             if inpt.leftclick then
  1118.                 colors[1] = "green"
  1119.                 var = var - 1
  1120.                 subselection = 1 -- reset subtype selection
  1121.                 buttondelaycur = buttondelay
  1122.             else
  1123.                 colors[1] = "white"
  1124.             end
  1125.         elseif selectright then
  1126.             -- right selected: increment
  1127.             if inpt.leftclick then
  1128.                 colors[2] = "green"
  1129.                 var = var + 1
  1130.                 subselection = 1
  1131.                 buttondelaycur = buttondelay
  1132.             else
  1133.                 colors[2] = "white"
  1134.             end
  1135.         end
  1136.     end
  1137.    
  1138.     -- render the buttons
  1139.     gui.box(x, y, x + 8, y + 8, "#000000f0", colors[1])
  1140.     gui.text(x + 1, y + 1, "<", "white", "clear")
  1141.    
  1142.     gui.box(x + 9, y, x + 17, y + 8, "#000000f0", colors[2])
  1143.     gui.text(x + 10, y + 1, ">", "white", "clear")
  1144.        
  1145.        
  1146.  
  1147.    
  1148.     return var
  1149. end
  1150.  
  1151. function logobjects()
  1152.     local search
  1153.     local i
  1154.     for i = 1, 0xFF do
  1155.         if logobj[i] == nil then -- CHECK
  1156.             search = scanobject(i)
  1157.             if search then
  1158.                 print (objectdebug(search, ""))
  1159.                 logobj[i] = true
  1160.                 --emu.pause()
  1161.             end
  1162.         end
  1163.     end
  1164.  
  1165. end
  1166.  
  1167. selection = 1
  1168. subselection = 1
  1169.  
  1170. putobject = 0
  1171. reference = 0xFF
  1172. screen_x = 0
  1173. screen_y = 0
  1174. buttondelaycur = 0
  1175.  
  1176. -- LOGGING OBJECTS' FIRST STATE
  1177. logobj = {}
  1178. for i in ipairs(objects) do
  1179.     -- logobj[<obj id>] = true
  1180.     -- these are skipped by the logobj
  1181.     logobj[objects[i][1]] = true
  1182. end
  1183.  
  1184. while true do
  1185.  
  1186.     inpto   = inpt;
  1187.     inpt    = input.get()
  1188.    
  1189.     if gameVersion >= sonic2NAProto then
  1190.         screen_y = memory.readword(0xFFEE04)
  1191.         screen_x = memory.readword(0xFFEE00)
  1192.     else
  1193.         screen_y = memory.readword(0xFFF704)
  1194.         screen_x = memory.readword(0xFFF700)
  1195.     end
  1196.  
  1197.     logobjects()
  1198.     renderhitbox()
  1199.     rendertable()
  1200.     rendermenu()
  1201.     -- decrease frame limiter
  1202.     if (buttondelaycur > 0) then
  1203.         buttondelaycur = buttondelaycur - 1
  1204.     end
  1205.    
  1206.     emu.frameadvance()
  1207. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement