Advertisement
Guest User

srm

a guest
Dec 7th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.07 KB | None | 0 0
  1. import numpy as np
  2.  
  3. ####### use remove() and insert() for lists to solve all of your problems
  4.  
  5. """
  6.  
  7. This script will be simplified in that it will not consider multiple loading planes in
  8. a given room (relevent to places like Deku Palace and Spring MV). However, this script
  9. will hopefully be easy to generalize to account for this once the loading planes are
  10. better understood.
  11.  
  12.  
  13. """
  14.  
  15. """
  16.  
  17. Note: Node size is 0x10 = 16 on English and 0x30 = 48 on JP
  18.  
  19. """
  20.  
  21. version = 'English'
  22.  
  23. if version == 'English':
  24.     node_size = 0x10
  25. elif version == 'JP':
  26.     nodesize = 0x30
  27. else:
  28.     print('Error: Invalid Version (choose "English" or "JP" )')
  29.  
  30.  
  31.  
  32. class Actor:
  33.    
  34.     """
  35.    
  36.    name: name of the actor, some string
  37.    
  38.    Id: Actor id, string of 4 integers
  39.    
  40.    size: the size of an actor instance for this actor (number of bytes, in decimal)
  41.    
  42.    category: the actor category (category 5 is treated differently than others)
  43.              For now, giving everything not category 5 a category of 0
  44.  
  45.    overlay_type: determines where the AF loads in the heap
  46.    
  47.    unloadable: a boolean for whether or not it is possible to deallocate this actor without changing rooms
  48.    
  49.    address: the memory address of the actor in decimal (can convert to a hex string for output)
  50.             Note: The earliest address we handle is 0x40B150 = 4239696. All addresses must be multiples of 16
  51.            
  52.    room_number: the number of the room these actors are associated with
  53.    
  54.    priority: an index to differentiate copies of the same instance
  55.    
  56.    from_spawner: True or False (True if it is from a spawner, like rupees from a cluster; False otherwise)
  57.    """
  58.    
  59.     def __init__(self, name, Id, size, category, overlay_type, unloadable, address, room_number, priority, from_spawner):
  60.         self.name = name
  61.         self.Id = Id
  62.         self.size = size
  63.         self.category = category
  64.         self.overlay_type = overlay_type
  65.         self.unloadable = unloadable
  66.         self.address = address
  67.         self.room_number = room_number
  68.         self.priority = priority
  69.         self.from_spawner = from_spawner
  70.  
  71. class Room:
  72.    
  73.     """
  74.    
  75.    number: the room number (i.e. Room 0 has number 0)
  76.    
  77.    priority_queue: this will be the list of actor instances of the room, in order
  78.    
  79.    clock_exists: boolean for whether or not the clock is an actor in the queue
  80.    
  81.    clock_priority: if clock_exists == False, then clock_priority will be a number
  82.                    to determine where in the queue the clock should be loaded, for
  83.                    example, if clock_priority is 2, then it means that the clock
  84.                    should be the 3rd actor to appear in the queue (first index is 0)
  85.    
  86.    """
  87.    
  88.     def __init__(self, number, priority_queue, clock_exists, clock_priority):
  89.         self.number = number
  90.         self.priority_queue = priority_queue
  91.         self.clock_exists = clock_exists
  92.         self.clock_priority = clock_priority
  93.  
  94. class Node:
  95.    
  96.     """
  97.    address: which address in memory the node is at (as a base-10 integer for now)
  98.    
  99.    size: nodes should be 16 bytes (english), so input 16
  100.    
  101.    """
  102.    
  103.     def __init__(self, address, size):
  104.         self.address = address
  105.         self.size = size
  106.  
  107. class Overlay:
  108.    
  109.     def __init__(self, address, Id, size):
  110.         self.address = address
  111.         self.Id = Id
  112.         self.size = size
  113.  
  114.  
  115. Clock = Actor(name='Clock', Id='015A', size=340, category=0, overlay_type='A', unloadable=False, address=0, room_number=9999, priority=0, from_spawner=False)
  116. Clock_Overlay = Overlay(address=0, Id='015A', size=6000)
  117.  
  118. Room0_scene_load_actor_list = [
  119.         Actor(name='Wooden Door', Id='0005', size=460, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False),
  120.         Actor(name='Loading Plane', Id='0018', size=332, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False),
  121.         Actor(name='Rupee Cluster', Id='00E8', size=360, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False),
  122.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
  123.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=1, from_spawner=False),
  124.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
  125.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=0, from_spawner=False),
  126.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=1, from_spawner=False),
  127.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=2, from_spawner=False),
  128.         Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False)
  129.         ]
  130.  
  131. # This does not include the loading plane
  132. Room0_actor_list = [
  133.         Actor(name='Wooden Door', Id='0005', size=460, category=0, overlay_type='B', unloadable=False, address=0, room_number=0, priority=0, from_spawner=False),
  134.         Actor(name='Rupee Cluster', Id='00E8', size=360, category=0, overlay_type='A', unloadable=True, address=0, room_number=0, priority=0, from_spawner=False),
  135.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
  136.         Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=1, from_spawner=False),
  137.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
  138.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=0, from_spawner=False),
  139.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=1, from_spawner=False),
  140.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=2, from_spawner=False),
  141.         Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False)
  142.         ]
  143.  
  144. # This does not include the loading plane
  145. Room1_actor_list = [
  146.         Actor(name='Door Shutter', Id='001E', size=360, category=0, overlay_type='B', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False),
  147.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False),
  148.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False),
  149.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False),
  150.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=3, from_spawner=False),
  151.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=4, from_spawner=False),
  152.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=5, from_spawner=False),
  153.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=6, from_spawner=False),
  154.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=7, from_spawner=False),
  155.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=8, from_spawner=False),
  156.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=9, from_spawner=False),
  157.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=10, from_spawner=False),
  158.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=11, from_spawner=False),
  159.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=12, from_spawner=False),
  160.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=13, from_spawner=False),
  161.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=14, from_spawner=False),
  162.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=15, from_spawner=False),
  163.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=16, from_spawner=False),
  164.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=17, from_spawner=False),
  165.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=18, from_spawner=False),
  166.         Actor(name='Bad Bat', Id='015B', size=476, category=5, overlay_type='A', unloadable=True, address=0, room_number=1, priority=19, from_spawner=False),
  167.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False),
  168.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=1, from_spawner=False),
  169.         Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=2, from_spawner=False),
  170.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False),
  171.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False),
  172.         Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False),
  173.         Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False)
  174.         ]
  175.  
  176. Room0_Scene_Load = Room(0, Room0_scene_load_actor_list, False, 2)
  177. Room0 = Room(0, Room0_actor_list, False, 2)
  178. Room1 = Room(1, Room1_actor_list, False, 2)
  179.  
  180. Overlay_dict = {
  181.         '015A' : Overlay(address=0, Id='015A', size=6000),
  182.         '00E8' : Overlay(address=0, Id='00E8', size=1984),
  183.         '0170' : Overlay(address=0, Id='0170', size=10688),
  184.         '0039' : Overlay(address=0, Id='0039', size=3552),
  185.         '0082' : Overlay(address=0, Id='0082', size=9040),
  186.         '0158' : Overlay(address=0, Id='0158', size=1104),
  187.         '015B' : Overlay(address=0, Id='015B', size=6048),
  188.         '0006' : Overlay(address=0, Id='0006', size=8640)
  189.             }
  190.  
  191. #Heap = np.zeros(1000).tolist()
  192.  
  193. #Heap = [Node(0x40B140, node_size)]
  194.  
  195. #### 0x40B140 = 4239680, this is the address of the first node in the heap
  196. #Heap = [Node(4239680, 16, 0), Node(idk; big number, 16, 1)]
  197.  
  198.  
  199. """
  200.  
  201. We initialize the Heap as a list, putting a node with address 0x40B140 in the 0th entry
  202. and we place a dummy node at the end of the Heap so that there will always exist two
  203. consecutive nodes for us to define a condition for which free space in the Heap exists
  204.  
  205. Keep in mind that the 0x5FFFFF address in the dummy node will not reflect the actual
  206. address of the corresponding node in-game, but it also isn't relevant to heap manipulation
  207. since it is so far down
  208.  
  209. """
  210.  
  211.  
  212. Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
  213.  
  214.  
  215.  
  216. def Overlay_In_Heap(Heap, Overlay):
  217.    
  218.     """
  219.    
  220.    Overlay is the overlay that we want to check whether or not it is in the Heap
  221.    
  222.    This function will return True if Overlay is in the Heap and False otherwise
  223.    
  224.    """
  225.    
  226.     overlay_in_heap = False
  227.    
  228.     for entry in Heap:
  229.        
  230.         if type(entry) == Overlay and entry.Id == Overlay.Id:
  231.            
  232.             overlay_in_heap = True
  233.        
  234.     return overlay_in_heap
  235.            
  236.  
  237.  
  238. def Find_Gaps(Heap):
  239.    
  240.     """
  241.    
  242.    This function will find all consecutive nodes and output a list of 4-tuples
  243.    where the first two entries correspond to the indices of each node in the list
  244.    and the last two entries correspond to the addresses of each node
  245.    
  246.    The list should be in order, from the start of the Heap to the end of the Heap
  247.    
  248.    """
  249.    
  250.     consecutive_node_count = 0
  251.    
  252.     node_1_address = 0
  253.     node_2_address = 0
  254.     node_1_index = 0
  255.     node_2_index = 0
  256.    
  257.     consecutive_node_list = []
  258.     for entry in Heap:
  259.         if type(entry) == Node and consecutive_node_count == 0:
  260.             node_1_address = entry.address
  261.             node_1_index = Heap.index(entry)
  262.             consecutive_node_count += 1
  263.         elif type(entry) == Node and consecutive_node_count == 1:
  264.             node_2_address = entry.address
  265.             node_2_index = Heap.index(entry)
  266.            
  267.             consecutive_node_list.append((node_1_index, node_2_index, node_1_address, node_2_address))
  268.            
  269.             consecutive_node_count += 1
  270.         elif type(entry) != Node:
  271.             consecutive_node_count = 0
  272.         elif type(entry) == Node and consecutive_node_count > 1:
  273.             consecutive_node_count += 1
  274.             print("ERROR: More than 2 consecutive nodes!! (Find_Gaps() Error Message)")
  275.        
  276.    
  277.     return consecutive_node_list
  278.    
  279.  
  280.  
  281.  
  282. def Allocate(Heap, Actor, Overlay_Dict):
  283.    
  284.     """
  285.    
  286.    Actor is the actor that we want to allocate into the Heap
  287.    
  288.    Overlay_Dict is a dictionary where the keys are the actor ids which point to the corresponding Overlays
  289.    
  290.    This function will account for placing nodes and overlays
  291.    
  292.    """
  293.    
  294.     Overlay = Overlay_Dict[Actor.Id]
  295.    
  296.     Overlay_Allocated = False
  297.    
  298.     if Overlay_In_Heap(Heap, Overlay) == True:
  299.         Overlay_Allocated = True
  300.    
  301.     Actor_Allocated = False
  302.    
  303.     """
  304.    ##### Not yet defined, not sure if I will bother; not really necessary. Probably should for debugging
  305.    if Actor_In_Heap == True:
  306.        print('Error: This Actor is already allocated!! (Error message from Allocate() function)')
  307.    """
  308.    
  309.     gap_list = Find_Gaps(Heap)
  310.    
  311.     # Because we initialize the Heap with 2 nodes, there should always be at least one gap
  312.     if len(gap_list) < 1:
  313.         print('ERROR: len(gap_list) < 1 in Allocate() function')
  314.    
  315.    
  316.     # If the Overlay is type A and the Overlay is not already in the Heap, then we want to allocate the overlay first
  317.     if Actor.overlay_type == 'A' and Overlay_In_Heap(Heap, Overlay) == False:
  318.        
  319.         for gap in gap_list:
  320.            
  321.             if Overlay_Allocated == True:
  322.                 break ##### This ensures we don't add in the same Overlay multiple times
  323.            
  324.             node_2_index = gap[1]
  325.             node_1_address = gap[2]
  326.             node_2_address = gap[3]
  327.            
  328.             gap_size = node_2_address - node_1_address - node_size
  329.            
  330.             ##### Case 1: the Overlay can fit, but there is NOT enough space for an extra node
  331.             # Note that gap_size is always a multiple of 16
  332.            
  333.             if Overlay.size <= gap_size and Overlay.size > gap_size - 2*node_size:
  334.                
  335.                 Overlay.address = node_1_address + node_size
  336.                 Heap.insert(node_2_index, Overlay)
  337.                 Overlay_Allocated = True
  338.                
  339.            
  340.             ##### Case 2: the Overlay can fit and a new node can also fit
  341.            
  342.             elif Overlay.size <= gap_size and Overlay.size <= gap_size - 2*node_size:
  343.                
  344.                 Overlay.address = node_1_address + node_size
  345.                 Heap.insert(node_2_index, Overlay)
  346.                
  347.                 ########### ADD IN THE NODE HERE
  348.                 if Overlay.size%16 > 0:
  349.                     Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size + (16 - Overlay.size%16), size=node_size))
  350.                 elif Overlay.size%16 == 0:
  351.                     Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size, size=node_size))
  352.                    
  353.                 Overlay_Allocated = True
  354.                
  355.     ############ Now the overlay (if applicable) has been allocated. Now we need to allocate the actor.
  356.        
  357.     for gap in gap_list:
  358.        
  359.         if Actor_Allocated == True:
  360.             break ##### This ensures we don't add in the same Actor multiple times
  361.        
  362.         node_2_index = gap[1]
  363.         node_1_address = gap[2]
  364.         node_2_address = gap[3]
  365.        
  366.         gap_size = node_2_address - node_1_address - node_size
  367.        
  368.         ##### Case 1: the Actor can fit, but there is NOT enough space for an extra node
  369.         # Note that gap_size is always a multiple of 16
  370.        
  371.         if Actor.size <= gap_size and Actor.size > gap_size - 2*node_size:
  372.            
  373.             Actor.address = node_1_address + node_size
  374.             Heap.insert(node_2_index, Actor)
  375.             Actor_Allocated = True
  376.            
  377.        
  378.         ##### Case 2: the Actor can fit and a new node can also fit
  379.        
  380.         elif Actor.size <= gap_size and Actor.size <= gap_size - 2*node_size:
  381.            
  382.             Actor.address = node_1_address + node_size
  383.             Heap.insert(node_2_index, Actor)
  384.            
  385.             ########### ADD IN THE NODE HERE
  386.             if Actor.size%16 > 0:
  387.                 Heap.insert(node_2_index + 1, Node(address=Actor.address + Actor.size + (16 - Actor.size%16), size=node_size))
  388.             elif Actor.size%16 == 0:
  389.                 Heap.insert(node_2_index + 1, Node(address=Actor.address + Actor.size, size=node_size))
  390.                    
  391.             Actor_Allocated = True
  392.  
  393.  
  394.  
  395.  
  396. def Deallocate(Heap, Actor):
  397.    
  398.    
  399.     """
  400.    
  401.    Actor is the actor that we want to be deallocated from the Heap
  402.    
  403.    This function will account for removing nodes and overlays
  404.    
  405.    """
  406.    
  407.     pass
  408.  
  409.  
  410. def Load_Scene(Heap, Room):
  411.    
  412.     pass
  413.  
  414.  
  415.  
  416. def Load_Room(Heap, Room):
  417.    
  418.     pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement