This adds support to most of Varia's 20221101 update. Notably, added Options for: - Objectives - Tourian - RelaxedRoundRobinCF As well as previously unsupported Options: - EscapeRando - RemoveEscapeEnemies - HideItems
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import base64
 | 
						|
 | 
						|
from ..rom.ips import IPS_Patch
 | 
						|
 | 
						|
def pc_to_snes(pcaddress):
 | 
						|
    snesaddress=(((pcaddress<<1)&0x7F0000)|(pcaddress&0x7FFF)|0x8000)|0x800000
 | 
						|
    return snesaddress
 | 
						|
 | 
						|
def snes_to_pc(B):
 | 
						|
    B_1 = B >> 16
 | 
						|
    B_2 = B & 0xFFFF
 | 
						|
    # return 0 if invalid LoROM address
 | 
						|
    if B_1 < 0x80 or B_1 > 0xFFFFFF or B_2 < 0x8000:
 | 
						|
        return 0
 | 
						|
    A_1 = (B_1 - 0x80) >> 1
 | 
						|
    # if B_1 is even, remove most significant bit
 | 
						|
    A_2 = B_2 & 0x7FFF if (B_1 & 1) == 0 else B_2
 | 
						|
 | 
						|
    return (A_1 << 16) | A_2
 | 
						|
 | 
						|
VANILLA_ROM_SIZE = 3145728
 | 
						|
BANK_SIZE = 0x8000
 | 
						|
 | 
						|
class ROM(object):
 | 
						|
    def __init__(self, data={}):
 | 
						|
        self.address = 0
 | 
						|
        self.maxAddress = VANILLA_ROM_SIZE
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        pass
 | 
						|
 | 
						|
    def seek(self, address):
 | 
						|
        if address > self.maxAddress:
 | 
						|
            self.maxAddress = address
 | 
						|
        self.address = address
 | 
						|
 | 
						|
    def tell(self):
 | 
						|
        if self.address > self.maxAddress:
 | 
						|
            self.maxAddress = self.address
 | 
						|
        return self.address
 | 
						|
 | 
						|
    def inc(self, n=1):
 | 
						|
        self.address += n
 | 
						|
        self.tell()
 | 
						|
 | 
						|
    def read(self, byteCount):
 | 
						|
        pass
 | 
						|
 | 
						|
    def readWord(self, address=None):
 | 
						|
        return self.readBytes(2, address)
 | 
						|
 | 
						|
    def readByte(self, address=None):
 | 
						|
        return self.readBytes(1, address)
 | 
						|
 | 
						|
    def readLong(self, address=None):
 | 
						|
        return self.readBytes(3, address)
 | 
						|
 | 
						|
    def readBytes(self, size, address=None):
 | 
						|
        if address != None:
 | 
						|
            self.seek(address)
 | 
						|
        return int.from_bytes(self.read(size), byteorder='little')
 | 
						|
    
 | 
						|
    def write(self, bytes):
 | 
						|
        pass
 | 
						|
 | 
						|
    def writeWord(self, word, address=None):
 | 
						|
        self.writeBytes(word, 2, address)
 | 
						|
 | 
						|
    def writeByte(self, byte, address=None):
 | 
						|
        self.writeBytes(byte, 1, address)
 | 
						|
 | 
						|
    def writeLong(self, lng, address=None):
 | 
						|
        self.writeBytes(lng, 3, address)
 | 
						|
 | 
						|
    def writeBytes(self, value, size, address=None):
 | 
						|
        if address != None:
 | 
						|
            self.seek(address)
 | 
						|
        self.write(value.to_bytes(size, byteorder='little'))
 | 
						|
 | 
						|
    def ipsPatch(self, ipsPatches):
 | 
						|
        pass
 | 
						|
 | 
						|
    def fillToNextBank(self):
 | 
						|
        off = self.maxAddress % BANK_SIZE
 | 
						|
        if off > 0:
 | 
						|
            self.seek(self.maxAddress + BANK_SIZE - off - 1)
 | 
						|
            self.writeByte(0xff)
 | 
						|
        assert (self.maxAddress % BANK_SIZE) == 0
 | 
						|
        
 | 
						|
class RealROM(ROM):
 | 
						|
    def __init__(self, name):
 | 
						|
        super(RealROM, self).__init__()
 | 
						|
        self.romFile = open(name, "rb+")
 | 
						|
 | 
						|
    def seek(self, address):
 | 
						|
        super(RealROM, self).seek(address)
 | 
						|
        self.romFile.seek(address)
 | 
						|
 | 
						|
    def tell(self):
 | 
						|
        self.address = self.romFile.tell()
 | 
						|
        return super(RealROM, self).tell()
 | 
						|
    
 | 
						|
    def write(self, bytes):
 | 
						|
        self.romFile.write(bytes)
 | 
						|
        self.tell()
 | 
						|
 | 
						|
    def read(self, byteCount):
 | 
						|
        ret = self.romFile.read(byteCount)
 | 
						|
        self.tell()
 | 
						|
        return ret
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        self.romFile.close()
 | 
						|
 | 
						|
    def ipsPatch(self, ipsPatches):
 | 
						|
        for ips in ipsPatches:
 | 
						|
            ips.applyFile(self)
 |