Assets revision #1

This commit is contained in:
David Benepe
2020-08-24 19:56:30 -05:00
parent 0185984594
commit a398687ff8
57 changed files with 16679 additions and 9601 deletions
Executable → Regular
View File
Executable → Regular
View File
+126
View File
@@ -0,0 +1,126 @@
import sys
import json
import re
import os
from file_util import FileUtil
class GenerateAssets:
def __init__(self, rootDir, version):
self.ASSETS_FILENAME = rootDir + '/asm/assets/assets.s'
self.ASSETS_DIR = rootDir + '/assets/' + version
self.UCODE_DIR = rootDir + '/ucode/' + version
self.UCODE_TEXT_FILENAME = rootDir + '/asm/assets/ucode_text.s'
self.UCODE_DATA_FILENAME = rootDir + '/asm/assets/ucode_data.s'
self.BUILD_DIR = rootDir + '/build/' + version
self.generate_assets_file()
self.generate_ucode_files()
def generate_assets_file(self):
with open(self.ASSETS_DIR + '/assets.json') as jsonFile:
assetsJSON = json.load(jsonFile)
assets = assetsJSON['assets']
assetsTextFinal = '# This file was generated by generate_ld.py\n\n'
assetsTextFinal += '.include "globals.inc"\n.include "macros.inc"\n\n'
assetsText = 'glabel ASSETS_START\n\n'
assetSectionTexts = [''] * len(assets)
numAssets = len(assets)
self.numAssets = numAssets
for i in range(0, numAssets):
assetSectionTexts[i] = 'glabel ASSET_SECTION_' + str(i) + '\n'
for i in range(0, numAssets):
assetType = assets[i]['type']
if assetType == 'Table':
continue
if assetType == 'Empty':
assetSectionTexts[i] += '# Empty\n'
if 'table' in assets[i]:
tableIndex = assets[i]['table']
assetSectionTexts[tableIndex] += '# Empty table\n'
assetSectionTexts[tableIndex] += '.word ASSET_SECTION_' + str(i) + '_END - ASSET_SECTION_' + str(i) + '\n'
assetSectionTexts[tableIndex] += '.word 0xFFFFFFFF\n'
continue
folder = self.BUILD_DIR + '/' + assets[i]['folder']
numFiles = len(assets[i]['filenames'])
for j in range(0, numFiles):
assetSectionTexts[i] += 'glabel ASSET_' + str(i) + '_' + str(j) + '\n'
filename = folder + '/' + assets[i]['filenames'][j]
if not filename.endswith('.bin'):
filename = os.path.splitext(filename)[0] + '.bin'
assetSectionTexts[i] += '.incbin "' + filename + '"\n'
if 'table' in assets[i]:
assetSectionTexts[assets[i]['table']] += self.generate_asset_table(i, assets[i], assetType, numFiles)
for i in range(0, numAssets):
assetSectionTexts[i] += 'glabel ASSET_SECTION_' + str(i) + '_END\n'
for assetSectionText in assetSectionTexts:
assetsText += '.balign 16\n' + assetSectionText + '\n'
assetsText += '.balign 16\nglabel ASSETS_END\n'
assetsTextFinal += '.word ' + str(numAssets) + ' # Number of asset sections \n'
for i in range(0, numAssets):
assetsTextFinal += '.word ASSET_SECTION_' + str(i) + ' - ASSETS_START\n'
assetsTextFinal += '.word ASSETS_END - ASSETS_START\n\n'
assetsTextFinal += assetsText
with open(self.ASSETS_FILENAME, "w") as assetsFile:
assetsFile.write(assetsTextFinal)
def generate_asset_table(self, i, asset, assetType, numFiles):
outText = ''
if assetType == 'TTGhosts':
for j in range(0, numFiles):
outText += '.word 0x{:02X}{:02X}0000, '.format(asset['meta'][j]['levelID'], asset['meta'][j]['vehicleID'])
outText += 'ASSET_' + str(i) + '_' + str(j) + ' - ASSET_SECTION_' + str(i) + '\n'
outText += '.word 0xFFFF0000, ASSET_SECTION_' + str(i) + '_END - ASSET_SECTION_' + str(i) + '\n'
outText += '.word 0xFFFF0000, 0xFFFFFFFF\n'
else:
if assetType == 'MenuText':
outText += '.word ' + str(asset['text-entry-count']) + '# Number of text entries for each language\n'
for j in range(0, numFiles):
if j == 0 and assetType == 'Audio':
continue # The audio table skips the first entry (for some odd reason)
difference = 'ASSET_' + str(i) + '_' + str(j) + ' - ASSET_SECTION_' + str(i)
if assetType == 'GameText' and asset['textTypes'][j] == 1:
outText += '.word (' + difference + ') | 0x80000000\n'
elif assetType == 'Miscellaneous':
outText += '.word (' + difference + ') / 4\n'
else:
outText += '.word ' + difference + '\n'
if assetType == 'Miscellaneous':
outText += '.word (ASSET_SECTION_' + str(i) + '_END - ASSET_SECTION_' + str(i) + ') / 4\n'
else:
outText += '.word ASSET_SECTION_' + str(i) + '_END - ASSET_SECTION_' + str(i) + '\n'
outText += '.word 0xFFFFFFFF\n'
return outText
# Note: I am assuming that the order of microcodes did not change between versions.
# TODO: Will probably need to refactor this later.
def generate_ucode_files(self):
assetsUCodeText = '# This file was generated by generate_ld.py\n\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_unknown.bin"\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_boot.bin"\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_f3ddkr_dram.bin"\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_f3ddkr_fifo.bin"\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_f3ddkr_xbus.bin"\n'
assetsUCodeText += '.incbin "' + self.BUILD_DIR + '/ucode/ucode_unknown_2.bin"\n'
with open(self.UCODE_TEXT_FILENAME, "w") as assetsFile:
assetsFile.write(assetsUCodeText)
assetsUCodeData = '# This file was generated by generate_ld.py\n\n'
assetsUCodeData += '.incbin "' + self.BUILD_DIR + '/ucode/data_f3ddkr_dram.bin"\n'
assetsUCodeData += '.incbin "' + self.BUILD_DIR + '/ucode/data_f3ddkr_fifo.bin"\n'
assetsUCodeData += '.incbin "' + self.BUILD_DIR + '/ucode/data_f3ddkr_xbus.bin"\n'
assetsUCodeData += '.incbin "' + self.BUILD_DIR + '/ucode/data_unknown.bin"\n'
with open(self.UCODE_DATA_FILENAME, "w") as assetsFile:
assetsFile.write(assetsUCodeData)
Executable → Regular
+19 -114
View File
@@ -1,29 +1,28 @@
import re
import os
import json
import sys
from file_util import FileUtil
from generate_assets import GenerateAssets
VERSION = 'us_1.0'
LD_NAME = 'dkr.ld'
ASM_DIR = './asm'
SRC_DIR = './src'
LIB_ASM_DIR = './lib/asm'
LIB_SRC_DIR = './lib/src'
ASSETS_FILENAME = './asm/assets/assets.s'
ASSETS_LUT_FILENAME = './asm/assets/assets_lut.s'
ASSETS_DIR = './assets/' + VERSION
ASSETS_START = 0x0D8200
UCODE_DIR = './ucode/' + VERSION
UCODE_TEXT_FILENAME = './asm/assets/ucode_text.s'
UCODE_DATA_FILENAME = './asm/assets/ucode_data.s'
VERSION = sys.argv[1]
if VERSION != 'us_1.0':
print("generate_ld currently does not support " + sys.argv[1])
sys.exit(0)
ROOT_DIR = '.'
LD_NAME = ROOT_DIR + '/dkr.ld'
ASM_DIR = ROOT_DIR + '/asm'
SRC_DIR = ROOT_DIR + '/src'
LIB_ASM_DIR = ROOT_DIR + '/lib/asm'
LIB_SRC_DIR = ROOT_DIR + '/lib/src'
BUILD_DIR = 'build/' + VERSION
class LD:
class GenerateLD:
def __init__(self, file):
print('Generating linker file...')
self.generate_assets_file()
self.generate_ucode_files()
self.assets = GenerateAssets(ROOT_DIR, VERSION)
self.files = self.get_code_files()
self.indentLevel = 0
self.file = file
@@ -91,18 +90,8 @@ class LD:
def gen_assets_section(self):
self.gen_line('__ASSETS_LUT_START = romPos;');
self.gen_line('__ASSETS_LUT_END = __ASSETS_LUT_START + ' + hex((((self.assets.numAssets + 2) * 4) + 15) & 0xFFFFFFF0) + ';');
self.gen_newline()
self.gen_line('.assets_lut 0 : AT(romPos)')
self.gen_open_block()
self.gen_line(BUILD_DIR + '/asm/assets/assets_lut.o(.text);')
self.gen_close_block()
self.gen_line('romPos += SIZEOF(.assets_lut);')
self.gen_newline()
self.gen_line('__ASSETS_LUT_END = romPos;');
self.gen_newline()
self.gen_line('.assets 0 : AT(romPos)')
self.gen_open_block()
self.gen_line(BUILD_DIR + '/asm/assets/assets.o(.text);')
@@ -165,7 +154,7 @@ class LD:
matchedGroups = matches.groups()
files.append((outputDir + filename[:-2] + '.o', '', matchedGroups[0], 0))
break
def get_code_files(self):
files = []
self.append_files(files, ('.s',), ASM_DIR, BUILD_DIR + '/asm/')
@@ -174,90 +163,6 @@ class LD:
self.append_files(files, ('.c',), LIB_SRC_DIR, BUILD_DIR + '/lib/src/')
files.sort(key = lambda x: (x[2], x[3])) # Sort tuples by RAM address and prioritize src files first.
return files
def get_asset_files(self):
assetFiles = []
mainLUT = ''
with open(ASSETS_DIR + '/assets.json') as jsonFile:
data = json.load(jsonFile)
for asset in data['assets']:
if asset['category'] == 'main':
if mainLUT != '':
raise Exception('Category "main" was expected to only have 1 item. Please update generate_ld.py.')
mainLUT = BUILD_DIR + '/' + asset['filename']
continue
filename, extension = os.path.splitext(asset['filename'])
if extension == '.cbin' or extension == '.ebin':
filename += extension
else:
filename += '.bin'
assetFiles.append((BUILD_DIR + '/' + filename, extension))
return assetFiles, mainLUT
def generate_assets_file(self):
assets, mainLUT = self.get_asset_files()
assetsText = '# This file was generated by generate_ld.py\n\n'
assetsText += '.macro .incbinaligned filename\n .balign 16\n .incbin "\\filename"\n.endm\n\n'
prevAssetMadeAlignment = False
for asset in assets:
if 'lut' in asset[0]:
#assetsText += '.balign 16\n'
prevAssetMadeAlignment = True
if prevAssetMadeAlignment:
assetsText += '.incbinaligned "./' + asset[0] + '"\n'
else:
assetsText += '.incbin "./' + asset[0] + '"\n'
if asset[1] == '.png' or asset[1] == '.cbin' or 'lut' in asset[0]: # Make sure that compressed data ends on a 16-byte boundary
#assetsText += '.balign 16\n'
prevAssetMadeAlignment = True
else:
prevAssetMadeAlignment = False
with open(ASSETS_FILENAME, "w") as assetsFile:
assetsFile.write(assetsText)
assetsLutText = '# This file was generated by generate_ld.py\n\n'
assetsLutText += '.incbin "./' + mainLUT + '"\n'
with open(ASSETS_LUT_FILENAME, "w") as assetsLutFile:
assetsLutFile.write(assetsLutText)
def get_ucode_files(self):
ucode_files = [[], []]
assetFilenames = FileUtil.getListOfFiles(UCODE_DIR)
regex = r'[.][\/]ucode[\/][^\/]*[\/](([^\/]*[\/])?[^.]*)[.](([.]?[^.]*)+)([.][A-Za-z0-9_]*)'
for filename in assetFilenames:
matches = re.match(regex, filename)
if matches is None:
raise Exception('Invalid filename: \"' + filename + '"')
matchedGroups = matches.groups()
fileExtension = matchedGroups[4]
fileProperties = matchedGroups[2].split('.')
ramAddress = fileProperties[0]
outFilename = BUILD_DIR + '/ucode/' + matchedGroups[0] + '.' + matchedGroups[2] + '.bin'
if matchedGroups[0].startswith('ucode_'):
ucode_files[0].append((outFilename, ramAddress, fileExtension))
else:
ucode_files[1].append((outFilename, ramAddress, fileExtension))
ucode_files[0].sort(key = lambda x: x[1]) # Sort tuples by RAM address
ucode_files[1].sort(key = lambda x: x[1]) # Sort tuples by RAM address
return ucode_files
def generate_ucode_files(self):
ucodeFiles = self.get_ucode_files()
assetsUCodeText = '# This file was generated by generate_ld.py\n\n'
assetsUCodeData = '# This file was generated by generate_ld.py\n\n'
for file in ucodeFiles[0]:
assetsUCodeText += '.incbin "./' + file[0] + '"\n'
for file in ucodeFiles[1]:
assetsUCodeData += '.incbin "./' + file[0] + '"\n'
with open(UCODE_TEXT_FILENAME, "w") as assetsFile:
assetsFile.write(assetsUCodeText)
with open(UCODE_DATA_FILENAME, "w") as assetsFile:
assetsFile.write(assetsUCodeData)
with open(LD_NAME, 'w') as ldFile:
LD(ldFile)
GenerateLD(ldFile)
Executable → Regular
View File
Executable → Regular
View File