Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- ####### use remove() and insert() for lists to solve all of your problems
- """
- This script will be simplified in that it will not consider multiple loading planes in
- a given room (relevent to places like Deku Palace and Spring MV). However, this script
- will hopefully be easy to generalize to account for this once the loading planes are
- better understood.
- """
- """
- Note: Node size is 0x10 = 16 on English and 0x30 = 48 on JP
- """
- version = 'English'
- if version == 'English':
- node_size = 0x10
- elif version == 'JP':
- nodesize = 0x30
- else:
- print('Error: Invalid Version (choose "English" or "JP" )')
- class Actor:
- """
- name: name of the actor, some string
- Id: Actor id, string of 4 integers
- size: the size of an actor instance for this actor (number of bytes, in decimal)
- category: the actor category (category 5 is treated differently than others)
- For now, giving everything not category 5 a category of 0
- overlay_type: determines where the AF loads in the heap
- unloadable: a boolean for whether or not it is possible to deallocate this actor without changing rooms
- address: the memory address of the actor in decimal (can convert to a hex string for output)
- Note: The earliest address we handle is 0x40B150 = 4239696. All addresses must be multiples of 16
- room_number: the number of the room these actors are associated with
- priority: an index to differentiate copies of the same instance
- from_spawner: True or False (True if it is from a spawner, like rupees from a cluster; False otherwise)
- """
- def __init__(self, name, Id, size, category, overlay_type, unloadable, address, room_number, priority, from_spawner):
- self.name = name
- self.Id = Id
- self.size = size
- self.category = category
- self.overlay_type = overlay_type
- self.unloadable = unloadable
- self.address = address
- self.room_number = room_number
- self.priority = priority
- self.from_spawner = from_spawner
- class Room:
- """
- number: the room number (i.e. Room 0 has number 0)
- priority_queue: this will be the list of actor instances of the room, in order
- clock_exists: boolean for whether or not the clock is an actor in the queue
- clock_priority: if clock_exists == False, then clock_priority will be a number
- to determine where in the queue the clock should be loaded, for
- example, if clock_priority is 2, then it means that the clock
- should be the 3rd actor to appear in the queue (first index is 0)
- """
- def __init__(self, number, priority_queue, clock_exists, clock_priority):
- self.number = number
- self.priority_queue = priority_queue
- self.clock_exists = clock_exists
- self.clock_priority = clock_priority
- class Node:
- """
- address: which address in memory the node is at (as a base-10 integer for now)
- size: nodes should be 16 bytes (english), so input 16
- """
- def __init__(self, address, size):
- self.address = address
- self.size = size
- class Overlay:
- def __init__(self, address, Id, size):
- self.address = address
- self.Id = Id
- self.size = size
- 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)
- Clock_Overlay = Overlay(address=0, Id='015A', size=6000)
- Room0_scene_load_actor_list = [
- 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),
- 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),
- 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),
- Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
- Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=1, from_spawner=False),
- Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=0, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=1, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=2, from_spawner=False),
- Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False)
- ]
- # This does not include the loading plane
- Room0_actor_list = [
- 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),
- 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),
- Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
- Actor(name='Dripping Water Effect', Id='0170', size=3644, category=0, overlay_type='A', unloadable=False, room_number=0, priority=1, from_spawner=False),
- Actor(name='Torch Stand (Generic)', Id='0039', size=500, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=0, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=1, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, room_number=0, priority=2, from_spawner=False),
- Actor(name='???0158', Id='0158', size=328, category=0, overlay_type='A', unloadable=False, room_number=0, priority=0, from_spawner=False)
- ]
- # This does not include the loading plane
- Room1_actor_list = [
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- 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),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=0, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=1, from_spawner=False),
- Actor(name='Pot', Id='0082', size=412, category=0, overlay_type='A', unloadable=True, address=0, room_number=1, priority=2, from_spawner=False),
- Actor(name='Chest', Id='0006', size=548, category=0, overlay_type='A', unloadable=False, address=0, room_number=1, priority=0, from_spawner=False)
- ]
- Room0_Scene_Load = Room(0, Room0_scene_load_actor_list, False, 2)
- Room0 = Room(0, Room0_actor_list, False, 2)
- Room1 = Room(1, Room1_actor_list, False, 2)
- Overlay_dict = {
- '015A' : Overlay(address=0, Id='015A', size=6000),
- '00E8' : Overlay(address=0, Id='00E8', size=1984),
- '0170' : Overlay(address=0, Id='0170', size=10688),
- '0039' : Overlay(address=0, Id='0039', size=3552),
- '0082' : Overlay(address=0, Id='0082', size=9040),
- '0158' : Overlay(address=0, Id='0158', size=1104),
- '015B' : Overlay(address=0, Id='015B', size=6048),
- '0006' : Overlay(address=0, Id='0006', size=8640)
- }
- #Heap = np.zeros(1000).tolist()
- #Heap = [Node(0x40B140, node_size)]
- #### 0x40B140 = 4239680, this is the address of the first node in the heap
- #Heap = [Node(4239680, 16, 0), Node(idk; big number, 16, 1)]
- """
- We initialize the Heap as a list, putting a node with address 0x40B140 in the 0th entry
- and we place a dummy node at the end of the Heap so that there will always exist two
- consecutive nodes for us to define a condition for which free space in the Heap exists
- Keep in mind that the 0x5FFFFF address in the dummy node will not reflect the actual
- address of the corresponding node in-game, but it also isn't relevant to heap manipulation
- since it is so far down
- """
- Heap = [Node(0x40B140, node_size), Node(0x5FFFFF, node_size)]
- def Overlay_In_Heap(Heap, Overlay):
- """
- Overlay is the overlay that we want to check whether or not it is in the Heap
- This function will return True if Overlay is in the Heap and False otherwise
- """
- overlay_in_heap = False
- for entry in Heap:
- if type(entry) == Overlay and entry.Id == Overlay.Id:
- overlay_in_heap = True
- return overlay_in_heap
- def Find_Gaps(Heap):
- """
- This function will find all consecutive nodes and output a list of 4-tuples
- where the first two entries correspond to the indices of each node in the list
- and the last two entries correspond to the addresses of each node
- The list should be in order, from the start of the Heap to the end of the Heap
- """
- consecutive_node_count = 0
- node_1_address = 0
- node_2_address = 0
- node_1_index = 0
- node_2_index = 0
- consecutive_node_list = []
- for entry in Heap:
- if type(entry) == Node and consecutive_node_count == 0:
- node_1_address = entry.address
- node_1_index = Heap.index(entry)
- consecutive_node_count += 1
- elif type(entry) == Node and consecutive_node_count == 1:
- node_2_address = entry.address
- node_2_index = Heap.index(entry)
- consecutive_node_list.append((node_1_index, node_2_index, node_1_address, node_2_address))
- consecutive_node_count += 1
- elif type(entry) != Node:
- consecutive_node_count = 0
- elif type(entry) == Node and consecutive_node_count > 1:
- consecutive_node_count += 1
- print("ERROR: More than 2 consecutive nodes!! (Find_Gaps() Error Message)")
- return consecutive_node_list
- def Allocate(Heap, Actor, Overlay_Dict):
- """
- Actor is the actor that we want to allocate into the Heap
- Overlay_Dict is a dictionary where the keys are the actor ids which point to the corresponding Overlays
- This function will account for placing nodes and overlays
- """
- Overlay = Overlay_Dict[Actor.Id]
- Overlay_Allocated = False
- if Overlay_In_Heap(Heap, Overlay) == True:
- Overlay_Allocated = True
- Actor_Allocated = False
- """
- ##### Not yet defined, not sure if I will bother; not really necessary. Probably should for debugging
- if Actor_In_Heap == True:
- print('Error: This Actor is already allocated!! (Error message from Allocate() function)')
- """
- gap_list = Find_Gaps(Heap)
- # Because we initialize the Heap with 2 nodes, there should always be at least one gap
- if len(gap_list) < 1:
- print('ERROR: len(gap_list) < 1 in Allocate() function')
- # If the Overlay is type A and the Overlay is not already in the Heap, then we want to allocate the overlay first
- if Actor.overlay_type == 'A' and Overlay_In_Heap(Heap, Overlay) == False:
- for gap in gap_list:
- if Overlay_Allocated == True:
- break ##### This ensures we don't add in the same Overlay multiple times
- node_2_index = gap[1]
- node_1_address = gap[2]
- node_2_address = gap[3]
- gap_size = node_2_address - node_1_address - node_size
- ##### Case 1: the Overlay can fit, but there is NOT enough space for an extra node
- # Note that gap_size is always a multiple of 16
- if Overlay.size <= gap_size and Overlay.size > gap_size - 2*node_size:
- Overlay.address = node_1_address + node_size
- Heap.insert(node_2_index, Overlay)
- Overlay_Allocated = True
- ##### Case 2: the Overlay can fit and a new node can also fit
- elif Overlay.size <= gap_size and Overlay.size <= gap_size - 2*node_size:
- Overlay.address = node_1_address + node_size
- Heap.insert(node_2_index, Overlay)
- ########### ADD IN THE NODE HERE
- if Overlay.size%16 > 0:
- Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size + (16 - Overlay.size%16), size=node_size))
- elif Overlay.size%16 == 0:
- Heap.insert(node_2_index + 1, Node(address=Overlay.address + Overlay.size, size=node_size))
- Overlay_Allocated = True
- ############ Now the overlay (if applicable) has been allocated. Now we need to allocate the actor.
- for gap in gap_list:
- if Actor_Allocated == True:
- break ##### This ensures we don't add in the same Actor multiple times
- node_2_index = gap[1]
- node_1_address = gap[2]
- node_2_address = gap[3]
- gap_size = node_2_address - node_1_address - node_size
- ##### Case 1: the Actor can fit, but there is NOT enough space for an extra node
- # Note that gap_size is always a multiple of 16
- if Actor.size <= gap_size and Actor.size > gap_size - 2*node_size:
- Actor.address = node_1_address + node_size
- Heap.insert(node_2_index, Actor)
- Actor_Allocated = True
- ##### Case 2: the Actor can fit and a new node can also fit
- elif Actor.size <= gap_size and Actor.size <= gap_size - 2*node_size:
- Actor.address = node_1_address + node_size
- Heap.insert(node_2_index, Actor)
- ########### ADD IN THE NODE HERE
- if Actor.size%16 > 0:
- Heap.insert(node_2_index + 1, Node(address=Actor.address + Actor.size + (16 - Actor.size%16), size=node_size))
- elif Actor.size%16 == 0:
- Heap.insert(node_2_index + 1, Node(address=Actor.address + Actor.size, size=node_size))
- Actor_Allocated = True
- def Deallocate(Heap, Actor):
- """
- Actor is the actor that we want to be deallocated from the Heap
- This function will account for removing nodes and overlays
- """
- pass
- def Load_Scene(Heap, Room):
- pass
- def Load_Room(Heap, Room):
- pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement