mirror of
https://github.com/Skeli789/Dynamic-Pokemon-Expansion.git
synced 2026-03-23 02:04:28 -05:00
198 lines
6.8 KiB
Python
198 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: cp437 -*-
|
||
|
||
import sys
|
||
from insert import TryProcessFileInclusion, TryProcessConditionalCompilation
|
||
|
||
CharMap = "charmap.tbl"
|
||
|
||
SpecialBuffers = {
|
||
".": ["B0"],
|
||
"BUFFER": ["FD"],
|
||
"ATTACKER": ["FD", "0F"],
|
||
"TARGET": ["FD", "10"],
|
||
"EFFECT_BANK": ["FD", "11"],
|
||
"SCRIPTING_BANK": ["FD", "13"],
|
||
"CURRENT_MOVE": ["FD", "14"],
|
||
"LAST_ITEM": ["FD", "16"],
|
||
"LAST_ABILITY": ["FD", "17"],
|
||
"ATTACKER_ABILITY": ["FD", "18"],
|
||
"TARGET_ABILITY": ["FD", "19"],
|
||
"SCRIPTING_BANK_ABILITY": ["FD", "1A"],
|
||
"PLAYER_NAME": ["FD", "23"],
|
||
|
||
"PLAYER": ["FD", "01"],
|
||
"BUFFER1": ["FD", "02"],
|
||
"BUFFER2": ["FD", "03"],
|
||
"BUFFER3": ["FD", "04"],
|
||
"RIVAL": ["FD", "06"],
|
||
"WHITE": ["FC", "01", "01"],
|
||
"BLACK": ["FC", "01", "02"],
|
||
"GRAY": ["FC", "01", "03"],
|
||
"RED": ["FC", "01", "04"],
|
||
"ORANGE": ["FC", "01", "05"],
|
||
"GREEN": ["FC", "01", "06"],
|
||
"LIGHT_GREEN": ["FC", "01", "07"],
|
||
"BLUE": ["FC", "01", "08"],
|
||
"LIGHT_BLUE": ["FC", "01", "09"],
|
||
|
||
"ARROW_UP": ["79"],
|
||
"ARROW_DOWN": ["7A"],
|
||
"ARROW_LEFT": ["7B"],
|
||
"ARROW_RIGHT": ["7C"],
|
||
|
||
"ALIGN": ["FC", "13"],
|
||
"SHRINK": ["FC", "06", "00"]
|
||
}
|
||
|
||
|
||
def StringFileConverter(fileName: str):
|
||
stringToWrite = ".thumb\n.text\n.align 2\n\n"
|
||
with open(fileName, 'r') as file:
|
||
maxLength = 0
|
||
fillFF = False
|
||
readingState = 0
|
||
lineNum = 0
|
||
definesDict = {}
|
||
conditionals = []
|
||
|
||
for line in file:
|
||
lineNum += 1
|
||
line = line.rstrip("\n\r") # Remove only newline characters
|
||
if TryProcessFileInclusion(line, definesDict):
|
||
continue
|
||
if TryProcessConditionalCompilation(line, definesDict, conditionals):
|
||
continue
|
||
if line.strip() == "" or line[:2] == "//": # Ignore blank lines and comment lines
|
||
continue
|
||
|
||
if readingState == 0: # Only when the file starts
|
||
line = line.strip()
|
||
if line[:6].upper() == "#ORG @" and line[6:] != "":
|
||
title = line[6:]
|
||
stringToWrite += ".global " + title + "\n" + title + ":\n"
|
||
readingState = 1
|
||
elif "MAX_LENGTH" in line and "=" in line:
|
||
try:
|
||
maxLength = int(line.split("=")[1])
|
||
except:
|
||
print('Error reading max length on line ' + str(lineNum) + ' in file: "' + fileName + '"')
|
||
sys.exit(0)
|
||
elif "FILL_FF" in line and "=" in line:
|
||
try:
|
||
fillFF = bool(line.split("=")[1])
|
||
except:
|
||
print('Error reading FF fill on line ' + str(lineNum) + ' in file: "' + fileName + '"')
|
||
sys.exit(0)
|
||
else:
|
||
print('Warning! Error on line ' + str(lineNum) + ' in file: "' + fileName + '"')
|
||
|
||
elif readingState == 1:
|
||
if line[:6].upper() == "#ORG @" and line[6:] != "":
|
||
line = line.strip()
|
||
title = line[6:]
|
||
stringToWrite += ".global " + title + "\n" + title + ":\n"
|
||
else:
|
||
stringToWrite += ProcessString(line, lineNum, maxLength, fillFF)
|
||
stringToWrite += "0xFF\n\n" # Only print line in everything went alright
|
||
|
||
output = open(fileName.split(".string")[0] + '.s', 'w') # Only open file once we know everything went okay.
|
||
output.write(stringToWrite)
|
||
output.close()
|
||
|
||
|
||
def ProcessString(string: str, lineNum: int, maxLength=0, fillWithFF=False) -> str:
|
||
charMap = PokeByteTableMaker()
|
||
stringToWrite = ".byte "
|
||
buffer = False
|
||
escapeChar = False
|
||
bufferChars = ""
|
||
strLen = 0
|
||
|
||
for char in string:
|
||
if 0 < maxLength <= strLen:
|
||
print('Warning: The string "' + string + '" has exceeded the maximum length of '
|
||
+ str(maxLength) + ' and has been truncated!')
|
||
break
|
||
|
||
if buffer is True:
|
||
if char == ']':
|
||
buffer = False
|
||
|
||
if bufferChars in SpecialBuffers:
|
||
for bufferChar in SpecialBuffers[bufferChars]:
|
||
if 0 < maxLength <= strLen: # End buffer in middle
|
||
print('Warning: The string buffer "' + bufferChars + '" has exceeded the maximum length of '
|
||
+ str(maxLength) + ' and has been truncated!')
|
||
break
|
||
|
||
stringToWrite += ("0x" + bufferChar + ", ")
|
||
strLen += 1
|
||
|
||
elif len(bufferChars) > 2: # Unrecognized buffer
|
||
print('Warning: The string buffer "' + bufferChars + '" is not recognized!')
|
||
stringToWrite += "0x0, " # Place whitespace where the buffer should have gone
|
||
strLen += 1
|
||
else:
|
||
stringToWrite += ("0x" + bufferChars + ", ")
|
||
strLen += 1
|
||
|
||
bufferChars = ""
|
||
else:
|
||
bufferChars += char
|
||
|
||
elif escapeChar is True:
|
||
escapeChar = False
|
||
try:
|
||
stringToWrite += hex(charMap["\\" + char]) + ", "
|
||
strLen += 1
|
||
|
||
except KeyError:
|
||
print('Error parsing string: "' + string + '" (Line ' + str(lineNum) + ')')
|
||
sys.exit(0)
|
||
|
||
else:
|
||
try:
|
||
stringToWrite += hex(charMap[char]) + ", "
|
||
strLen += 1
|
||
|
||
except KeyError:
|
||
if char == '[':
|
||
buffer = True
|
||
elif char == '\\':
|
||
escapeChar = True
|
||
elif char == '"':
|
||
stringToWrite += hex(charMap["\\" + char])
|
||
strLen += 1
|
||
else:
|
||
print('Error parsing string on line ' + str(lineNum) + ' at character "' + char + '".')
|
||
sys.exit(1)
|
||
|
||
if strLen < maxLength and fillWithFF:
|
||
while strLen < maxLength:
|
||
stringToWrite += "0xFF, "
|
||
strLen += 1
|
||
|
||
return stringToWrite
|
||
|
||
|
||
def PokeByteTableMaker():
|
||
dictionary = {}
|
||
with open(CharMap) as file:
|
||
for line in file:
|
||
if line.strip() != "/FF" and line.strip() != "":
|
||
if line[2] == '=' and line[3] != "":
|
||
try:
|
||
if line[3] == '\\':
|
||
dictionary[line[3] + line[4]] = int(line.split('=')[0], 16)
|
||
else:
|
||
dictionary[line[3]] = int(line.split('=')[0], 16)
|
||
except:
|
||
pass
|
||
dictionary[' '] = 0
|
||
|
||
dictionary["<EFBFBD>"] = 0xB4
|
||
dictionary["<EFBFBD>"] = 0xB0
|
||
dictionary["<EFBFBD>"] = 0xB1
|
||
return dictionary
|