mirror of
https://github.com/izzy2lost/Diddy-Kong-Racing.git
synced 2026-06-19 01:16:26 -07:00
(8.08%) Overhauled assets & decompiled 5 functions in unknown_0777A0
This commit is contained in:
+98
-61
@@ -1,25 +1,29 @@
|
||||
import re
|
||||
import os
|
||||
import json
|
||||
|
||||
from file_util import FileUtil
|
||||
|
||||
# Possible TODO: Move generating assets.s into a seperate python script.
|
||||
|
||||
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_S_FILENAME = './asm/assets/assets.s'
|
||||
ASSETS_UCODE_S_FILENAME = './asm/assets/ucode.s'
|
||||
ASSETS_DIR = './assets/us_1.0'
|
||||
ASSETS_FILENAME = './asm/assets/assets.s'
|
||||
ASSETS_LUT_FILENAME = './asm/assets/assets_lut.s'
|
||||
ASSETS_DIR = './assets/' + VERSION
|
||||
ASSETS_START = 0x0D8200
|
||||
BUILD_DIR = 'build/us_1.0'
|
||||
UCODE_DIR = './ucode/' + VERSION
|
||||
UCODE_TEXT_FILENAME = './asm/assets/ucode_text.s'
|
||||
UCODE_DATA_FILENAME = './asm/assets/ucode_data.s'
|
||||
BUILD_DIR = 'build/' + VERSION
|
||||
|
||||
class LD:
|
||||
def __init__(self, file):
|
||||
print('Generating linker file...')
|
||||
self.generate_assets_file()
|
||||
self.generate_ucode_files()
|
||||
self.files = self.get_code_files()
|
||||
self.indentLevel = 0
|
||||
self.file = file
|
||||
@@ -27,25 +31,8 @@ class LD:
|
||||
self.gen_newline()
|
||||
self.gen_line('OUTPUT_ARCH (mips)')
|
||||
self.gen_newline()
|
||||
#self.gen_macros()
|
||||
self.gen_sections()
|
||||
print('New linker file created!')
|
||||
|
||||
def gen_macros(self):
|
||||
self.gen_line('#define BEGIN_SEG(name, addr) \\')
|
||||
self.increase_indent()
|
||||
self.gen_line('_##name##SegmentStart = ADDR(.name); \\')
|
||||
self.gen_line('_##name##SegmentRomStart = __romPos; \\')
|
||||
self.gen_line('.name addr : AT(__romPos)')
|
||||
self.decrease_indent()
|
||||
self.gen_newline()
|
||||
self.gen_line('#define END_SEG(name) \\')
|
||||
self.increase_indent()
|
||||
self.gen_line('_##name##SegmentEnd = ADDR(.name) + SIZEOF(.name); \\')
|
||||
self.gen_line('_##name##SegmentRomEnd = __romPos + SIZEOF(.name); \\')
|
||||
self.gen_line('__romPos += SIZEOF(.name);')
|
||||
self.decrease_indent()
|
||||
self.gen_newline()
|
||||
|
||||
def gen_sections(self):
|
||||
self.gen_line('SECTIONS')
|
||||
@@ -53,8 +40,9 @@ class LD:
|
||||
self.gen_line('romPos = 0x0;')
|
||||
self.gen_boot_section()
|
||||
self.gen_main_section()
|
||||
self.gen_ucode_section()
|
||||
self.gen_ucode_text_section()
|
||||
self.gen_data_section()
|
||||
self.gen_ucode_data_section()
|
||||
self.gen_assets_section()
|
||||
self.gen_discard()
|
||||
self.gen_close_block()
|
||||
@@ -77,12 +65,12 @@ class LD:
|
||||
self.gen_line('romPos += SIZEOF(.main);')
|
||||
self.gen_newline()
|
||||
|
||||
def gen_ucode_section(self):
|
||||
self.gen_line('.ucode 0 : AT(romPos)')
|
||||
def gen_ucode_text_section(self):
|
||||
self.gen_line('.ucodeText 0 : AT(romPos)')
|
||||
self.gen_open_block()
|
||||
self.gen_line(BUILD_DIR + '/asm/assets/ucode.o(.text);')
|
||||
self.gen_line(BUILD_DIR + '/asm/assets/ucode_text.o(.text);')
|
||||
self.gen_close_block()
|
||||
self.gen_line('romPos += SIZEOF(.ucode);')
|
||||
self.gen_line('romPos += SIZEOF(.ucodeText);')
|
||||
self.gen_newline()
|
||||
|
||||
def gen_data_section(self):
|
||||
@@ -93,7 +81,28 @@ class LD:
|
||||
self.gen_line('romPos += SIZEOF(.main_data);')
|
||||
self.gen_newline()
|
||||
|
||||
def gen_ucode_data_section(self):
|
||||
self.gen_line('.ucodeData 0 : AT(romPos)')
|
||||
self.gen_open_block()
|
||||
self.gen_line(BUILD_DIR + '/asm/assets/ucode_data.o(.text);')
|
||||
self.gen_close_block()
|
||||
self.gen_line('romPos += SIZEOF(.ucodeData);')
|
||||
self.gen_newline()
|
||||
|
||||
def gen_assets_section(self):
|
||||
self.gen_line('__ASSETS_LUT_START = romPos;');
|
||||
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);')
|
||||
@@ -141,7 +150,6 @@ class LD:
|
||||
def gen_newline(self):
|
||||
self.file.write('\n')
|
||||
|
||||
|
||||
def append_files(self, files, extensions, directory, outputDir):
|
||||
filenames = FileUtil.get_filenames_from_directory(directory, extensions)
|
||||
regex = r'[\/][*]+\s*RAM_POS:\s*0x([0-9a-fA-F]+)\s*[*]+[\/]'
|
||||
@@ -169,34 +177,27 @@ class LD:
|
||||
|
||||
def get_asset_files(self):
|
||||
assetFiles = []
|
||||
assetFilenames = FileUtil.getListOfFiles(ASSETS_DIR)
|
||||
regex = r'[.][\/]assets[\/][^\/]*[\/]([^\/]*[\/][^.]*)[.](([.]?[^.]*)+)([.][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()
|
||||
isMicrocode = False
|
||||
if matchedGroups[0].startswith('ucode/ucode_'):
|
||||
isMicrocode = True
|
||||
fileExtension = matchedGroups[3]
|
||||
fileProperties = matchedGroups[1].split('.')
|
||||
ramAddress = fileProperties[0]
|
||||
if fileExtension == '.cbin' or fileExtension == '.ebin':
|
||||
outFileExtension = fileExtension
|
||||
else:
|
||||
outFileExtension = '.bin'
|
||||
outFilename = BUILD_DIR + '/' + matchedGroups[0] + '.' + matchedGroups[1] + outFileExtension
|
||||
if int(ramAddress, 16) >= ASSETS_START:
|
||||
assetFiles.append((outFilename, ramAddress, fileExtension, isMicrocode))
|
||||
assetFiles.sort(key = lambda x: x[1]) # Sort tuples by RAM address
|
||||
return 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 = self.get_asset_files()
|
||||
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'
|
||||
assetsUCodeText = '# This file was generated by generate_ld.py\n\n'
|
||||
prevAssetMadeAlignment = False
|
||||
for asset in assets:
|
||||
if 'lut' in asset[0]:
|
||||
@@ -205,20 +206,56 @@ class LD:
|
||||
if prevAssetMadeAlignment:
|
||||
assetsText += '.incbinaligned "./' + asset[0] + '"\n'
|
||||
else:
|
||||
if asset[3]:
|
||||
assetsUCodeText += '.incbin "./' + asset[0] + '"\n'
|
||||
else:
|
||||
assetsText += '.incbin "./' + asset[0] + '"\n'
|
||||
|
||||
if asset[2] == '.png' or asset[2] == '.cbin' or 'lut' in asset[0]: # Make sure that compressed data ends on a 16-byte boundary
|
||||
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_S_FILENAME, "w") as assetsFile:
|
||||
with open(ASSETS_FILENAME, "w") as assetsFile:
|
||||
assetsFile.write(assetsText)
|
||||
with open(ASSETS_UCODE_S_FILENAME, "w") as assetsFile:
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user