예제 #1
0
 def load(self, input):
     self._x = input["X"]
     self._y = input["Y"]
     self.setTypeFromString(input["Type"])
     if (self._type == 3) or (self._type == 4): # Stairs/Escalator
         self._stairDir = ValuedIntTableEntry(None, None,
                 ["NW", "NE", "SW", "SE", "Nowhere"])
         self._stairDir.load(input["Direction"])
     elif self._type == 2: # Door
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.load(input["Text Pointer"])
         self._destFlag = input["Event Flag"]
         self._destX = input["Destination X"]
         self._destY = input["Destination Y"]
         self._destDir = ValuedIntTableEntry(None, None,
                 ["Down", "Up", "Right", "Left"])
         self._destDir.load(input["Direction"])
         self._destStyle = input["Style"]
     elif self._type == 0: # Switch
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.load(input["Text Pointer"])
         self._destFlag = input["Event Flag"]
     elif (self._type == 5) or (self._type == 6):
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.load(input["Text Pointer"])
예제 #2
0
 def readFromRom(self, rom, addr):
     self._y = rom[addr]
     self._x = rom[addr+1]
     self._type = rom[addr+2]
     ptr = rom.readMulti(addr+3, 2)
     if self._type == 1: # Rope/Ladder
         self._isRope = (ptr == 0x8000)
     elif (self._type == 3) or (self._type == 4): # Escalator and Stairs
         if ptr == 0x8000:
             stairDir = 4
         else:
             stairDir = ptr / 0x100
         self._stairDir = ValuedIntTableEntry(None, None,
                 ["NW", "NE", "SW", "SE", "Nowhere"])
         self._stairDir.setVal(stairDir)
     elif self._type == 2: # Door
         ptr |= 0xF0000
         #self._destTextPtr = rom.readMulti(ptr, 4)
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.setVal(rom.readMulti(ptr, 4))
         if ((self._destTextPtr.val() != 0) and 
                 ((self._destTextPtr.val() < 0xc00000)
                     or (self._destTextPtr.val() > 0xffffff))):
             raise ValueError("Invalid Door")
         self._destFlag = rom.readMulti(ptr+4, 2)
         self._destY = rom[ptr+6]
         self._destY |= (rom[ptr+7] & 0x3f) << 8
         #self._destDir = (rom[ptr+7] & 0xc0) >> 6
         self._destDir = ValuedIntTableEntry(None, None,
                 ["Down", "Up", "Right", "Left"])
         self._destDir.setVal((rom[ptr+7] & 0xc0) >> 6)
         self._destX = rom.readMulti(ptr+8, 2)
         self._destStyle = rom[ptr+10]
     elif self._type == 0: # Switch
         ptr |= 0xF0000
         self._destFlag = rom.readMulti(ptr, 2)
         #self._destTextPtr = rom.readMulti(ptr+2, 4)
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.setVal(rom.readMulti(ptr+2, 4))
         if ((self._destTextPtr.val() != 0) and 
                 ((self._destTextPtr.val() < 0xc00000)
                     or (self._destTextPtr.val() > 0xffffff))):
             raise ValueError("Invalid Switch")
     elif (self._type == 5) or (self._type == 6): # Object and Person
         ptr |= 0xF0000
         #self._destTextPtr = rom.readmulti(ptr, 4)
         self._destTextPtr = PointerTableEntry(None, 4)
         self._destTextPtr.setVal(rom.readMulti(ptr, 4))
     else:
         raise ValueError("Unknown type " + str(self._type))
예제 #3
0
class Door:
    # Types: Switch, Rope/Ladder, Door, Escalator, Stairway, Object, Person
    _TYPE_NAMES = ["switch", "rope/ladder", "door", "escalator", "stairway",
            "object", "person"]
    def readFromRom(self, rom, addr):
        self._y = rom[addr]
        self._x = rom[addr+1]
        self._type = rom[addr+2]
        ptr = rom.readMulti(addr+3, 2)
        if self._type == 1: # Rope/Ladder
            self._isRope = (ptr == 0x8000)
        elif (self._type == 3) or (self._type == 4): # Escalator and Stairs
            if ptr == 0x8000:
                stairDir = 4
            else:
                stairDir = ptr / 0x100
            self._stairDir = ValuedIntTableEntry(None, None,
                    ["NW", "NE", "SW", "SE", "Nowhere"])
            self._stairDir.setVal(stairDir)
        elif self._type == 2: # Door
            ptr |= 0xF0000
            #self._destTextPtr = rom.readMulti(ptr, 4)
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.setVal(rom.readMulti(ptr, 4))
            if ((self._destTextPtr.val() != 0) and 
                    ((self._destTextPtr.val() < 0xc00000)
                        or (self._destTextPtr.val() > 0xffffff))):
                raise ValueError("Invalid Door")
            self._destFlag = rom.readMulti(ptr+4, 2)
            self._destY = rom[ptr+6]
            self._destY |= (rom[ptr+7] & 0x3f) << 8
            #self._destDir = (rom[ptr+7] & 0xc0) >> 6
            self._destDir = ValuedIntTableEntry(None, None,
                    ["Down", "Up", "Right", "Left"])
            self._destDir.setVal((rom[ptr+7] & 0xc0) >> 6)
            self._destX = rom.readMulti(ptr+8, 2)
            self._destStyle = rom[ptr+10]
        elif self._type == 0: # Switch
            ptr |= 0xF0000
            self._destFlag = rom.readMulti(ptr, 2)
            #self._destTextPtr = rom.readMulti(ptr+2, 4)
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.setVal(rom.readMulti(ptr+2, 4))
            if ((self._destTextPtr.val() != 0) and 
                    ((self._destTextPtr.val() < 0xc00000)
                        or (self._destTextPtr.val() > 0xffffff))):
                raise ValueError("Invalid Switch")
        elif (self._type == 5) or (self._type == 6): # Object and Person
            ptr |= 0xF0000
            #self._destTextPtr = rom.readmulti(ptr, 4)
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.setVal(rom.readMulti(ptr, 4))
        else:
            raise ValueError("Unknown type " + str(self._type))
    def getTypeAsString(self):
        if self._type == 1:
            if self._isRope:
                return "rope"
            else:
                return "ladder"
        else:
            return Door._TYPE_NAMES[self._type]
    def setTypeFromString(self, str):
        str = str.lower()
        if str == "rope":
            self._type = 1
            self._isRope = True
        elif str == "ladder":
            self._type = 1
            self._isRope = False
        else:
            self._type = Door._TYPE_NAMES.index(str)
    def dump(self):
        out = { "X": self._x,
                "Y": self._y,
                "Type": self.getTypeAsString() }
        if (self._type == 3) or (self._type == 4): # Stairs/Escalator
            out["Direction"] = self._stairDir.dump()
        elif self._type == 2: # Door
            out["Text Pointer"] = self._destTextPtr.dump()
            out["Event Flag"] = self._destFlag
            out["Destination X"] = self._destX
            out["Destination Y"] = self._destY
            out["Direction"] = self._destDir.dump()
            out["Style"] = self._destStyle
        elif self._type == 0: # Switch
            out["Text Pointer"] = self._destTextPtr.dump()
            out["Event Flag"] = self._destFlag
        elif (self._type == 5) or (self._type == 6):
            out["Text Pointer"] = self._destTextPtr.dump()
        return out
    def load(self, input):
        self._x = input["X"]
        self._y = input["Y"]
        self.setTypeFromString(input["Type"])
        if (self._type == 3) or (self._type == 4): # Stairs/Escalator
            self._stairDir = ValuedIntTableEntry(None, None,
                    ["NW", "NE", "SW", "SE", "Nowhere"])
            self._stairDir.load(input["Direction"])
        elif self._type == 2: # Door
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.load(input["Text Pointer"])
            self._destFlag = input["Event Flag"]
            self._destX = input["Destination X"]
            self._destY = input["Destination Y"]
            self._destDir = ValuedIntTableEntry(None, None,
                    ["Down", "Up", "Right", "Left"])
            self._destDir.load(input["Direction"])
            self._destStyle = input["Style"]
        elif self._type == 0: # Switch
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.load(input["Text Pointer"])
            self._destFlag = input["Event Flag"]
        elif (self._type == 5) or (self._type == 6):
            self._destTextPtr = PointerTableEntry(None, 4)
            self._destTextPtr.load(input["Text Pointer"])
    def writeToRom(self, rom, addr, destWriteLoc, destRangeEnd, destLocs):
        rom[addr] = self._y
        rom[addr+1] = self._x
        rom[addr+2] = self._type
        if self._type == 1: # Rope/Ladder
            rom[addr+3] = 0
            rom[addr+4] = (0x80 if self._isRope else 0)
            return 0
        elif (self._type == 3) or (self._type == 4): # Escalator and Stairs
            rom[addr+3] = 0
            rom[addr+4] = (0x80 if (self._stairDir.val() == 4) else
                    self._stairDir.val())
            return 0
        elif self._type == 2: # Door
            with DataBlock(11) as destBlock:
                # Write data to block
                destTextPtr = self._destTextPtr.val()
                destBlock[0] = destTextPtr & 0xff
                destBlock[1] = (destTextPtr>>8) & 0xff
                destBlock[2] = (destTextPtr>>16) & 0xff
                destBlock[3] = (destTextPtr>>24) & 0xff
                destBlock[4] = self._destFlag & 0xff
                destBlock[5] = (self._destFlag >> 8) & 0xff
                destBlock[6] = self._destY & 0xff
                destBlock[7] = (self._destY >> 8) | (self._destDir.val() << 6)
                destBlock[8] = self._destX & 0xff
                destBlock[9] = self._destX >> 8
                destBlock[10] = self._destStyle
                # Check for any pre-existing matching destinations
                destHash = destBlock.hash()
                try:
                    destAddr = destLocs[destHash]
                    rom[addr+3] = destAddr & 0xff
                    rom[addr+4] = destAddr >> 8
                    return 0
                except KeyError:
                    # Need to write a new destination
                    if (destWriteLoc + 11) > destRangeEnd:
                        # TODO Error, not enough space
                        raise RunetimeError("Not enough door destination space")
                    destBlock.writeToRom(rom, destWriteLoc)
                    destLocs[destHash] = destWriteLoc & 0xffff
                    rom[addr+3] = destWriteLoc & 0xff
                    rom[addr+4] = (destWriteLoc >> 8) & 0xff
                    return 11
        elif self._type == 0: # Switch
            with DataBlock(6) as destBlock:
                # Write the data to block
                destBlock[0] = self._destFlag & 0xff
                destBlock[1] = self._destFlag >> 8
                destTextPtr = self._destTextPtr.val()
                destBlock[2] = destTextPtr & 0xff
                destBlock[3] = (destTextPtr>>8) & 0xff
                destBlock[4] = (destTextPtr>>16) & 0xff
                destBlock[5] = (destTextPtr>>24) & 0xff
                # Check for any pre-existing matching destinations
                destHash = destBlock.hash()
                try:
                    destAddr = destLocs[destHash]
                    rom[addr+3] = destAddr & 0xff
                    rom[addr+4] = destAddr >> 8
                    return 0
                except KeyError:
                    # Need to write a new destination
                    if (destWriteLoc + 6) > destRangeEnd:
                        # TODO Error, not enough space
                        raise RunetimeError("Not enough door destination space")
                    destBlock.writeToRom(rom, destWriteLoc)
                    destLocs[destHash] = destWriteLoc & 0xffff
                    rom[addr+3] = destWriteLoc & 0xff
                    rom[addr+4] = (destWriteLoc >> 8) & 0xff
                    return 6
        elif (self._type == 5) or (self._type == 6): # Switch
            with DataBlock(4) as destBlock:
                # Write the data to block
                destTextPtr = self._destTextPtr.val()
                destBlock[0] = destTextPtr & 0xff
                destBlock[1] = (destTextPtr>>8) & 0xff
                destBlock[2] = (destTextPtr>>16) & 0xff
                destBlock[3] = (destTextPtr>>24) & 0xff
                # Check for any pre-existing matching destinations
                destHash = destBlock.hash()
                try:
                    destAddr = destLocs[destHash]
                    rom[addr+3] = destAddr & 0xff
                    rom[addr+4] = destAddr >> 8
                    return 0
                except KeyError:
                    # Need to write a new destination
                    if (destWriteLoc + 4) > destRangeEnd:
                        # TODO Error, not enough space
                        raise RunetimeError("Not enough door destination space")
                    destBlock.writeToRom(rom, destWriteLoc)
                    destLocs[destHash] = destWriteLoc & 0xffff
                    rom[addr+3] = destWriteLoc & 0xff
                    rom[addr+4] = (destWriteLoc >> 8) & 0xff
                    return 4