def writeToRom(self, rom): map_ptrs_addr = \ EbModule.toRegAddr(rom.readMulti(self._MAP_PTRS_PTR_ADDR, 3)) map_addrs = map(lambda x: \ EbModule.toRegAddr(rom.readMulti(map_ptrs_addr+x*4,4)), \ range(8)) for i in range(self._MAP_HEIGHT): rom.write(map_addrs[i%8] + ((i>>3)<<8), map(lambda x: x & 0xff, self._tiles[i])) k = self._LOCAL_TSET_ADDR for i in range(self._MAP_HEIGHT>>3): for j in range(self._MAP_WIDTH): c = ((self._tiles[i<<3][j] >> 8) | ((self._tiles[(i<<3)|1][j] >> 8) << 2) | ((self._tiles[(i<<3)|2][j] >> 8) << 4) | ((self._tiles[(i<<3)|3][j] >> 8) << 6)) rom.write(k, c) c = ((self._tiles[(i<<3)|4][j] >> 8) | ((self._tiles[(i<<3)|5][j] >> 8) << 2) | ((self._tiles[(i<<3)|6][j] >> 8) << 4) | ((self._tiles[(i<<3)|7][j] >> 8) << 6)) rom.write(k+0x3000, c) k += 1 updateProgress(25) # Write sector data self._mapSecTsetPalsTbl.writeToRom(rom) updateProgress(25.0/4) self._mapSecMusicTbl.writeToRom(rom) updateProgress(25.0/4) self._mapSecMiscTbl.writeToRom(rom) updateProgress(25.0/4) self._mapSecTownMapTbl.writeToRom(rom) updateProgress(25.0/4)
def readFromRom(self, rom): # Read map tiles map_ptrs_addr = \ EbModule.toRegAddr(rom.readMulti(self._MAP_PTRS_PTR_ADDR, 3)) map_addrs = map(lambda x: \ EbModule.toRegAddr(rom.readMulti(map_ptrs_addr+x*4,4)), \ range(8)) self._tiles = map( lambda y: rom.readList(map_addrs[y%8] + ((y>>3)<<8), self._MAP_WIDTH).tolist(), range(self._MAP_HEIGHT)) k = self._LOCAL_TSET_ADDR for i in range(self._MAP_HEIGHT>>3): for j in range(self._MAP_WIDTH): self._tiles[i<<3][j] |= (rom[k] & 3) << 8 self._tiles[(i<<3)|1][j] |= ((rom[k] >> 2) & 3) << 8 self._tiles[(i<<3)|2][j] |= ((rom[k] >> 4) & 3) << 8 self._tiles[(i<<3)|3][j] |= ((rom[k] >> 6) & 3) << 8 self._tiles[(i<<3)|4][j] |= (rom[k+0x3000] & 3) << 8 self._tiles[(i<<3)|5][j] |= ((rom[k+0x3000] >> 2) & 3) << 8 self._tiles[(i<<3)|6][j] |= ((rom[k+0x3000] >> 4) & 3) << 8 self._tiles[(i<<3)|7][j] |= ((rom[k+0x3000] >> 6) & 3) << 8 k += 1 updateProgress(25) # Read sector data self._mapSecTsetPalsTbl.readFromRom(rom) updateProgress(25.0/4) self._mapSecMusicTbl.readFromRom(rom) updateProgress(25.0/4) self._mapSecMiscTbl.readFromRom(rom) updateProgress(25.0/4) self._mapSecTownMapTbl.readFromRom(rom) updateProgress(25.0/4)
def readGasFromRom(self, rom): with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_GAS_GFX))) self._gas_gfx.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_GAS_ARR))) self._gas_arr.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_GAS_PAL1))) self._gas_pal1.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_GAS_PAL2))) self._gas_pal2.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_GAS_PAL3))) self._gas_pal3.readFromBlock(cb)
def readFromProject(self, resourceOpener): # Clear the labels dict EbModule.labelsDict.clear() # Read the summary file sumFile = resourceOpener('ccscript/summary', 'txt') summary = sumFile.readlines() sumFile.close() # Only do anything if the summary file is not empty if len(summary) > 0: self._usedRange = (EbModule.toRegAddr(int(summary[7][30:36], 16)), EbModule.toRegAddr(int(summary[8][30:36], 16))) modName = None inModuleSection = False # False = before section, True = in section for line in summary: line = line.rstrip() if inModuleSection: if line.startswith('-'): inModuleSection = False else: labelKey = modName + "." + line.split(' ',1)[0] labelVal = int(line[-6:],16) EbModule.labelsDict[labelKey] = labelVal elif line.startswith("-") and modName != None: inModuleSection = True elif line.startswith("Labels in module "): modName = line[17:] updateProgress(50)
def readFromRom(self, rom): self._gfxPtrTbl.readFromRom(rom) updateProgress(2) self._arrPtrTbl.readFromRom(rom) updateProgress(2) self._colPtrTbl.readFromRom(rom) updateProgress(2) self._mapTsetTbl.readFromRom(rom) updateProgress(2) self._palPtrTbl.readFromRom(rom) updateProgress(2) # Read tilesets pct = 30.0/len(self._tsets) i=0 for tset in self._tsets: # Read data tset.readMinitilesFromRom(rom, EbModule.toRegAddr(self._gfxPtrTbl[i,0].val())) tset.readArrangementsFromRom(rom, EbModule.toRegAddr(self._arrPtrTbl[i,0].val())) tset.readCollisionsFromRom(rom, EbModule.toRegAddr(self._colPtrTbl[i,0].val())) i += 1 updateProgress(pct) # Read palettes pct = 10.0/self._mapTsetTbl.height() for i in range(self._mapTsetTbl.height()): drawTset = self._mapTsetTbl[i,0].val() # Each map tset has 8 maximum palettes # We'll just assume they all use 8 and read the garbage #romLoc = self._palPtrTbl[i,0].val() #for j in xrange(8): # # Read the palette # self._tsets[drawTset].readPaletteFromRom(rom, i, j, # EbModule.toRegAddr(romLoc)) # romLoc += 0xc0 # OK, as it turns out, all palettes need to be in the 1A bank # So we actually need to conserve space and not read garbage # Estimate the number of palettes for this map tileset if i == 31: #k = 0xDAFAA7 - self._palPtrTbl[i,0].val() k = 7 else: k = self._palPtrTbl[i+1,0].val() - self._palPtrTbl[i,0].val() k /= 0xc0 # Add the palettes romLoc = EbModule.toRegAddr(self._palPtrTbl[i,0].val()) for j in range(k): # Read the palette self._tsets[drawTset].readPaletteFromRom(rom, i, j, romLoc) romLoc += 0xc0 updateProgress(pct)
def readTownMapIconsFromRom(self, rom): self._townmap_icons_pal.readFromBlock(rom, loc=EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_TOWN_MAP_ICON_PAL))) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_TOWN_MAP_ICON_GFX))) self._townmap_icons.readFromBlock(cb)
def readFromRom(self, rom): with EbCompressedData() as block: block.readFromRom(rom, EbModule.toRegAddr( rom.readMulti(self._ptrLoc, 4))) self._arr.readFromBlock(block, 64) self._pals.readFromBlock(block, 0) self._gfx.readFromBlock(block, 2048+64)
def readCreditsFontFromRom(self, rom): self._cpal.readFromBlock(rom, loc=self._ADDR_CREDITS_PAL) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer( rom, self._ASMPTR_CREDITS_GFX))) self._cfont.readFromBlock(cb)
def readFromRom(self, rom): with EbCompressedData() as gb: gb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._gfxPtrLoc))) self._gfx.readFromBlock(gb) with EbCompressedData() as ab: ab.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._arrPtrLoc))) self._arr.readFromBlock(ab) with EbCompressedData() as pb: pb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._palPtrLoc))) self._pals.readFromBlock(pb) # The first color of every subpalette after subpal0 is ignored and # drawn as the first color of subpal0 instead c = self._pals[0,0] for i in range(1,len(self._pals)): self._pals[i,0] = c
def readFromRom(self, rom): map_ptrs_addr = EbModule.toRegAddr(rom.readMulti(self._MAP_PTRS_PTR_ADDR, 3)) map_addrs = map(lambda x: EbModule.toRegAddr(rom.readMulti(map_ptrs_addr + x * 4, 4)), range(8)) self._tiles = map( lambda y: rom.readList(map_addrs[y % 8] + ((y >> 3) << 8), self._MAP_WIDTH).tolist(), range(self._MAP_HEIGHT), ) k = self._LOCAL_TSET_ADDR for i in range(self._MAP_HEIGHT >> 3): for j in range(self._MAP_WIDTH): self._tiles[i << 3][j] |= (rom[k] & 3) << 8 self._tiles[(i << 3) | 1][j] |= ((rom[k] >> 2) & 3) << 8 self._tiles[(i << 3) | 2][j] |= ((rom[k] >> 4) & 3) << 8 self._tiles[(i << 3) | 3][j] |= ((rom[k] >> 6) & 3) << 8 self._tiles[(i << 3) | 4][j] |= (rom[k + 0x3000] & 3) << 8 self._tiles[(i << 3) | 5][j] |= ((rom[k + 0x3000] >> 2) & 3) << 8 self._tiles[(i << 3) | 6][j] |= ((rom[k + 0x3000] >> 4) & 3) << 8 self._tiles[(i << 3) | 7][j] |= ((rom[k + 0x3000] >> 6) & 3) << 8 k += 1
def readFromRom(self, rom): self._ptrTbl.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTR_PTR_TBL))) updateProgress(5) for i in range(self._ptrTbl.height()): loc = EbModule.toRegAddr(self._ptrTbl[i,0].val()) entry = [] while True: x = rom[loc] if x == 0xff: break y = rom[loc+1] icon = rom[loc+2] flag = rom.readMulti(loc+3, 2) entry.append((x, y, icon, flag)) loc += 5 self._entries.append(entry) i += 1 updateProgress(45)
def readFromRom(self, rom): self._bsPtrTbl.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTR_GFX))) self._bsPalsTable.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTR_PAL))) pct = 45.0/(self._bsPtrTbl.height() + self._bsPalsTable.height() + 1) self._enemyCfgTable.readFromRom(rom) updateProgress(pct) # Read the palettes for i in range(self._bsPalsTable.height()): pal = EbPalettes(1,16) pal.set(0, self._bsPalsTable[i,0].val()) self._bsPals.append(pal) updateProgress(pct) # Read the sprites for i in range(self._bsPtrTbl.height()): with EbCompressedData() as bsb: bsb.readFromRom(rom, EbModule.toRegAddr(self._bsPtrTbl[i,0].val())) bs = EbBattleSprite() bs.readFromBlock(bsb, self._bsPtrTbl[i,1].val()) self._bsprites.append(bs) updateProgress(pct) # Read the group data self._enemyGroupTbl.readFromRom(rom) self._enemyGroupBgTbl.readFromRom(rom) self._enemyGroups = [ ] pct = 5.0/self._enemyGroupTbl.height() for i in range(self._enemyGroupTbl.height()): group = [ ] ptr = EbModule.toRegAddr(self._enemyGroupTbl[i,0].val()) while(rom[ptr] != 0xff): group.append((rom.readMulti(ptr+1,2), rom[ptr])) ptr += 3 self._enemyGroups.append(group) updateProgress(pct)
def readFromRom(self, rom): with EbCompressedData() as tgb1: tgb1.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_1))) self._gfx1.readFromBlock(tgb1) updateProgress(20) with EbCompressedData() as tgb2: tgb2.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_2))) self._gfx2.readFromBlock(tgb2) updateProgress(20) # Read palettes loc = 0x201fc8 for pal in self._flavPals: pal.readFromBlock(rom, loc=loc) loc += 64 updateProgress(5) # Read names for ptr, field in self._flavNames: field.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, ptr))) updateProgress(5)
def __init__(self, addr): if EbTable.eb_table_map == None: #print "Loading eb.yml" with open("structures/eb.yml") as f: i=1 for doc in yaml.load_all(f, Loader=yaml.CSafeLoader): if i == 1: i += 1 elif i == 2: EbTable.eb_table_map = doc break #print "Done" Table.__init__(self,addr,EbTable.eb_table_map) self._addr = EbModule.toRegAddr(self._addr)
def writeToRom(self, rom): map_ptrs_addr = EbModule.toRegAddr(rom.readMulti(self._MAP_PTRS_PTR_ADDR, 3)) map_addrs = map(lambda x: EbModule.toRegAddr(rom.readMulti(map_ptrs_addr + x * 4, 4)), range(8)) for i in range(self._MAP_HEIGHT): rom.write(map_addrs[i % 8] + ((i >> 3) << 8), map(lambda x: x & 0xFF, self._tiles[i])) k = self._LOCAL_TSET_ADDR for i in range(self._MAP_HEIGHT >> 3): for j in range(self._MAP_WIDTH): c = ( (self._tiles[i << 3][j] >> 8) | ((self._tiles[(i << 3) | 1][j] >> 8) << 2) | ((self._tiles[(i << 3) | 2][j] >> 8) << 4) | ((self._tiles[(i << 3) | 3][j] >> 8) << 6) ) rom.write(k, c) c = ( (self._tiles[(i << 3) | 4][j] >> 8) | ((self._tiles[(i << 3) | 5][j] >> 8) << 2) | ((self._tiles[(i << 3) | 6][j] >> 8) << 4) | ((self._tiles[(i << 3) | 7][j] >> 8) << 6) ) rom.write(k + 0x3000, c) k += 1
def readFromRom(self, rom): self._ptrTbl.readFromRom(rom, EbModule.toRegAddr(rom.readMulti(self._ASMPTR, 3))) updateProgress(25) for i in range(self._ptrTbl.height()): loc = 0xf0000 | self._ptrTbl[i,0].val() entry = [ ] flag = 1 while flag != 0: flag = rom.readMulti(loc, 2) music = rom[loc+2] entry.append((flag, music)) loc += 4 self._entries.append(entry) updateProgress(25)
def readFromRom(self, rom, loc): self._sprites = [ [EbRegSprite(),False] for i in range(self._numSprites)] self._h = rom[loc] self._w = rom[loc+1] >> 4 self._unknownA = rom[loc+2] self._pal = (rom[loc+3] >> 1) & 0x7 self._unknownB = rom[loc+4:loc+8] bank = rom[loc+8] << 16 i = loc+9 for spff in self._sprites: ptr = bank | rom.readMulti(i, 2) spff[1] = (ptr & 2) != 0 spff[0].readFromBlock(rom, self._w*8, self._h*8, EbModule.toRegAddr(ptr&0xfffffc)) if (ptr & 1) != 0: spff[0].hflip() i += 2
def readFromRom(self, rom): self._bbgTbl.readFromRom(rom) pct = 50.0/(6+self._bbgTbl.height()) self._bbgGfxPtrTbl.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTRS_GFX[0]))) updateProgress(pct) self._bbgArrPtrTbl.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTRS_ARR[0]))) updateProgress(pct) self._bbgPalPtrTbl.readFromRom(rom, EbModule.toRegAddr(EbModule.readAsmPointer(rom, self._ASMPTRS_PAL[0]))) updateProgress(pct) self._bbgGfxArrs = [ None for i in range(self._bbgGfxPtrTbl.height()) ] self._bbgPals = [ None for i in range(self._bbgPalPtrTbl.height()) ] updateProgress(pct) self._bbgScrollTbl.readFromRom(rom) updateProgress(pct) self._bbgDistorTbl.readFromRom(rom) updateProgress(pct) for i in range(self._bbgTbl.height()): gfxNum = self._bbgTbl[i,0].val() colorDepth = self._bbgTbl[i,2].val() if (self._bbgGfxArrs[gfxNum] == None): # Max size used in rom: 421 (2bpp) 442 (4bpp) tg = EbTileGraphics(512, 8, colorDepth) with EbCompressedData() as tgb: tgb.readFromRom(rom, EbModule.toRegAddr( self._bbgGfxPtrTbl[gfxNum,0].val())) tg.readFromBlock(tgb) a = EbArrangement(32, 32) with EbCompressedData() as ab: ab.readFromRom(rom, EbModule.toRegAddr( self._bbgArrPtrTbl[gfxNum,0].val())) a.readFromBlock(ab) self._bbgGfxArrs[gfxNum] = (tg, a) palNum = self._bbgTbl[i,1].val() if (self._bbgPals[palNum] == None): with DataBlock(32) as pb: pb.readFromRom(rom, EbModule.toRegAddr(self._bbgPalPtrTbl[palNum,0].val())) p = EbPalettes(1, 16) p.readFromBlock(pb) self._bbgPals[palNum] = p updateProgress(pct)
def readFromRom(self, rom): self._grPtrTbl.readFromRom(rom) updateProgress(5) self._grPalTbl.readFromRom(rom) updateProgress(5) # Load the sprite groups self._groups = [] pct = 40.0/self._grPtrTbl.height() for i in range(self._grPtrTbl.height()): # Note: this assumes that the SPT is written contiguously numSprites = 8 # Assume that the last group only has 8 sprites if i < self._grPtrTbl.height()-1: numSprites = (self._grPtrTbl[i+1,0].val() - self._grPtrTbl[i,0].val() - 9) / 2 g = SpriteGroup(numSprites) g.readFromRom(rom, EbModule.toRegAddr(self._grPtrTbl[i,0].val())) self._groups.append(g) updateProgress(pct)
def readFromRom(self, rom): self._ptrTbl.readFromRom(rom, EbModule.toRegAddr(rom.readMulti(self._PTR_LOC, 3))) updateProgress(5) bank = (rom[self._PTR_BANK_LOC] - 0xc0) << 16 pct = 45.0/20 for i in range(20): addr = bank | self._ptrTbl[i,0].val() tsetEntry = [] while (rom.readMulti(addr, 2) != 0): flag = rom.readMulti(addr, 2) num = rom.readMulti(addr+2, 2) addr += 4 changes = [] for j in range(num): changes.append((rom.readMulti(addr, 2), rom.readMulti(addr+2, 2))) addr += 4 tsetEntry.append((flag, changes)) self._entries.append(tsetEntry) updateProgress(pct)
def readFromRom(self, rom): self._mapEnemyTbl.readFromRom(rom) updateProgress(2.5) self._mapGroupPtrTbl.readFromRom(rom) updateProgress(2.5) # Read the groups pct = 45.0 / (self._mapGroupPtrTbl.height()) self._mapGroups = [] for i in range(self._mapGroupPtrTbl.height()): loc = EbModule.toRegAddr(self._mapGroupPtrTbl[i, 0].val()) flag = rom.readMulti(loc, 2) rate1 = rom[loc + 2] rate2 = rom[loc + 3] loc += 4 # Read the enemies/probabilities group1 = [] if rate1 > 0: sum = 0 while sum < 8: prob = rom[loc] enemy = rom.readMulti(loc + 1, 2) sum += prob loc += 3 group1.append((prob, enemy)) group2 = [] if rate2 > 0: sum = 0 while sum < 8: prob = rom[loc] enemy = rom.readMulti(loc + 1, 2) sum += prob loc += 3 group2.append((prob, enemy)) # Add to the list self._mapGroups.append((flag, rate1, rate2, group1, group2)) updateProgress(pct)
def readFromRom(self, rom): self._ptrTbl.readFromRom(rom) updateProgress(5) pct = 45.0/(40*32) for i in range(self._ptrTbl.height()): loc = EbModule.toRegAddr(self._ptrTbl[i,0].val()) entry = [ ] numDoors = rom.readMulti(loc, 2) loc += 2 for j in range(numDoors): d = Door() try: d.readFromRom(rom, loc) except ValueError: # Invalid door entry. Some entries in EB are invalid. # When we encounter one, just assume we've reached the end # of this entry. break entry.append(d) loc += 5 self._entries.append(entry) i += 1 updateProgress(pct)
def readFromRom(self, rom): ptr = EbModule.toRegAddr(rom.readMulti(self._PTR_LOC, 3)) updateProgress(5) self._ptrTbl.readFromRom(rom, ptr) pct = 45.0/(40*32) for i in range(self._ptrTbl.height()): loc = self._ptrTbl[i,0].val() # Format: AA AA [BB BB YY XX] # AA = # of entries. BB = TPT. YY = y pos. XX = x pos. if loc != 0: loc |= 0x0F0000 entry = [ ] size = rom.readMulti(loc, 2) loc += 2 for i in range(size): entry.append(SpritePlacement( rom.readMulti(loc, 2), rom[loc+3], rom[loc+2])) loc += 4 self._entries.append(entry) else: self._entries.append(None) updateProgress(pct)
def readProducedPresentedFromRom(self, rom): with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRODUCED_PAL))) self._produced_pal.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRODUCED_GFX))) self._produced_gfx.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRODUCED_ARR))) self._produced_arr.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRESENTED_PAL))) self._presented_pal.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRESENTED_GFX))) self._presented_gfx.readFromBlock(cb) with EbCompressedData() as cb: cb.readFromRom(rom, EbModule.toRegAddr( EbModule.readAsmPointer(rom, self._ASMPTR_PRESENTED_ARR))) self._presented_arr.readFromBlock(cb)