1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
import mmap
import math
def convertOffset(lo, hi, bank):
return lo + ((hi << 8) - 0x4000) + (bank * 0x4000 + 0x20 * 0x4000)
def signedByteToInt(uByte):
return (uByte, uByte - 0x100)[uByte >= 0x80]
def getOAMFlagStr(flags):
strings = []
if (flags == 0):
strings.append('$0')
if (flags & 0b111 != 0):
strings.append('%{:03b}'.format(flags & 0b111))
if (flags & (1 << 3) != 0):
strings.append('(1 << OAM_TILE_BANK)')
if (flags & (1 << 4) != 0):
strings.append('(1 << OAM_OBP_NUM)')
if (flags & (1 << 5) != 0):
strings.append('(1 << OAM_X_FLIP)')
if (flags & (1 << 6) != 0):
strings.append('(1 << OAM_Y_FLIP)')
if (flags & (1 << 7) != 0):
strings.append('(1 << OAM_PRIORITY)')
return ' | '.join(s for s in strings)
def getAnimData():
with open('baserom.gbc') as rom:
romMap = mmap.mmap(rom.fileno(), 0, access=mmap.ACCESS_READ)
offsets = []
for i in range(0xd9):
lineOffset = 0x81333 + 4*i
lo = romMap[lineOffset]
hi = romMap[lineOffset + 1]
bank = romMap[lineOffset + 2]
offsets.append([convertOffset(lo, hi, bank), i])
animData = {}
animFrameTables = {}
frameData = {}
for offset in offsets:
header = romMap[offset[0] : offset[0] + 3]
pos = offset[0] + 3
data = []
data.append(romMap[pos : pos + 4])
pos += 4
while (data[-1][0] != 0x00 or data[-1][1] != 0x00):
data.append(romMap[pos : pos + 4])
pos += 4
maxFrame = 0
for curFrameData in data:
if (curFrameData[0] != 0xff):
maxFrame = max(curFrameData[0], maxFrame)
frameOffset = convertOffset(header[1], header[2], header[0])
pointers = []
tableAlreadyExists = frameOffset in animFrameTables
for i in range(maxFrame + 1):
pointers.append(romMap[frameOffset + 2*i : frameOffset + 2*i + 2])
if tableAlreadyExists:
if len(pointers) > len(animFrameTables[frameOffset]):
if (frameOffset != 0xab066): # special case, seems this is wrong
animFrameTables[frameOffset] = pointers
else:
animFrameTables[frameOffset] = pointers
animData[offset[0]] = [header, data, offset[1]]
for offset in animFrameTables:
curFrameData = []
for ptr in animFrameTables[offset]:
curOffset = convertOffset(ptr[0], ptr[1], math.floor(offset / 0x4000 - 0x20))
numTiles = romMap[curOffset]
curFrameData.append([curOffset, romMap[curOffset : curOffset + numTiles*4 + 1]])
frameData[offset] = curFrameData
return animData, animFrameTables, frameData
animData, animFrameTables, frameData = getAnimData()
pointerIndices = {}
counter = 0
for offset in animFrameTables:
pointerIndices[offset] = counter
counter += 1
allOffsets = []
for offset in animData:
allOffsets.append(offset)
for offset in animFrameTables:
allOffsets.append(offset)
allOffsets = sorted(allOffsets)
for offset in allOffsets:
size = 0
if offset in animData:
header = animData[offset][0]
data = animData[offset][1]
print('AnimData' + str(animData[offset][2]) + ':: ; ' + "{:0x}".format(offset) + ' (' + "{:0x}".format((math.floor(offset / 0x4000))) + ':' + "{:04x}".format(offset % 0x4000 + 0x4000) + ')')
print('\tframe_table ' + 'AnimFrameTable' + str(pointerIndices[convertOffset(header[1], header[2], header[0])]))
for curData in data:
print('\tframe_data ' + ', '.join(str(signedByteToInt(x)) for x in curData))
size = len(header) + len(data) * 4
if offset in animFrameTables:
print('AnimFrameTable' + str(pointerIndices[offset]) + ':: ; ' + "{:0x}".format(offset) + ' (' + "{:0x}".format((math.floor(offset / 0x4000))) + ':' + "{:04x}".format(offset % 0x4000 + 0x4000) + ')')
for curFrameData in frameData[offset]:
print('\tdw .data_' + "{:0x}".format(curFrameData[0]))
size += 2
for curFrameData in frameData[offset]:
numTiles = curFrameData[1][0]
print()
print('.data_' + "{:0x}".format(curFrameData[0]))
print('\tdb ' + str(numTiles) + ' ; size')
size += 1
for i in range(numTiles):
print('\tdb ' + str(signedByteToInt(curFrameData[1][4*i + 1])) + ', ' + str(signedByteToInt(curFrameData[1][4*i + 2])) + ', ' + str(curFrameData[1][4*i + 3]) + ', ' + getOAMFlagStr(curFrameData[1][4*i + 4]))
size += 4
print('; ' + "0x{:0x}".format(offset + size))
print()
if (offset + size) not in allOffsets:
print('\tINCROM ' + "${:0x}".format(offset + size) + ', ')
print()
|