diff options
author | Rafael Marçalo <public@rafaelmarcalo.xyz> | 2024-09-05 16:31:33 +0100 |
---|---|---|
committer | Rafael Marçalo <public@rafaelmarcalo.xyz> | 2024-09-05 16:31:33 +0100 |
commit | 8b67572ad7e1508341345dc46a2597e9fa170cbb (patch) | |
tree | 8f37c4d60ce0f07b9eaf30be34f39298da97b242 /src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java | |
parent | b65f4a80da28e7ec4de16c8b1abf906e8d7be2c5 (diff) |
Diffstat (limited to 'src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java')
-rw-r--r-- | src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java b/src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java new file mode 100644 index 0000000..897b6cd --- /dev/null +++ b/src/com/pkrandom/romhandlers/AbstractGBCRomHandler.java @@ -0,0 +1,224 @@ +package com.pkrandom.romhandlers; + +/*----------------------------------------------------------------------------*/ +/*-- AbstractGBCRomHandler.java - an extension of AbstractGBRomHandler --*/ +/*-- used for Gen 1 and Gen 2. --*/ +/*-- --*/ +/*-- Part of "Universal Pokemon Randomizer ZX" by the UPR-ZX team --*/ +/*-- Pokemon and any associated names and the like are --*/ +/*-- trademark and (C) Nintendo 1996-2020. --*/ +/*-- --*/ +/*-- The custom code written here is licensed under the terms of the GPL: --*/ +/*-- --*/ +/*-- This program is free software: you can redistribute it and/or modify --*/ +/*-- it under the terms of the GNU General Public License as published by --*/ +/*-- the Free Software Foundation, either version 3 of the License, or --*/ +/*-- (at your option) any later version. --*/ +/*-- --*/ +/*-- This program is distributed in the hope that it will be useful, --*/ +/*-- but WITHOUT ANY WARRANTY; without even the implied warranty of --*/ +/*-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --*/ +/*-- GNU General Public License for more details. --*/ +/*-- --*/ +/*-- You should have received a copy of the GNU General Public License --*/ +/*-- along with this program. If not, see <http://www.gnu.org/licenses/>. --*/ +/*----------------------------------------------------------------------------*/ + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.Scanner; + +import com.pkrandom.FileFunctions; +import com.pkrandom.constants.GBConstants; + +public abstract class AbstractGBCRomHandler extends AbstractGBRomHandler { + + private String[] tb; + private Map<String, Byte> d; + private int longestTableToken; + + public AbstractGBCRomHandler(Random random, PrintStream logStream) { + super(random, logStream); + } + + protected void clearTextTables() { + tb = new String[256]; + if (d != null) { + d.clear(); + } else { + d = new HashMap<String, Byte>(); + } + longestTableToken = 0; + } + + protected void readTextTable(String name) { + try { + Scanner sc = new Scanner(FileFunctions.openConfig(name + ".tbl"), "UTF-8"); + while (sc.hasNextLine()) { + String q = sc.nextLine(); + if (!q.trim().isEmpty()) { + String[] r = q.split("=", 2); + if (r[1].endsWith("\r\n")) { + r[1] = r[1].substring(0, r[1].length() - 2); + } + int hexcode = Integer.parseInt(r[0], 16); + if (tb[hexcode] != null) { + String oldMatch = tb[hexcode]; + tb[hexcode] = null; + if (d.get(oldMatch) == hexcode) { + d.remove(oldMatch); + } + } + tb[hexcode] = r[1]; + longestTableToken = Math.max(longestTableToken, r[1].length()); + d.put(r[1], (byte) hexcode); + } + } + sc.close(); + } catch (FileNotFoundException e) { + } + + } + + protected String readString(int offset, int maxLength, boolean textEngineMode) { + StringBuilder string = new StringBuilder(); + for (int c = 0; c < maxLength; c++) { + int currChar = rom[offset + c] & 0xFF; + if (tb[currChar] != null) { + string.append(tb[currChar]); + if (textEngineMode && (tb[currChar].equals("\\r") || tb[currChar].equals("\\e"))) { + break; + } + } else { + if (currChar == GBConstants.stringTerminator) { + break; + } else { + string.append("\\x" + String.format("%02X", currChar)); + } + } + } + return string.toString(); + } + + protected int lengthOfStringAt(int offset, boolean textEngineMode) { + int len = 0; + while (rom[offset + len] != GBConstants.stringTerminator + && (!textEngineMode || (rom[offset + len] != GBConstants.stringPrintedTextEnd && rom[offset + len] != GBConstants.stringPrintedTextPromptEnd))) { + len++; + } + + if (textEngineMode + && (rom[offset + len] == GBConstants.stringPrintedTextEnd || rom[offset + len] == GBConstants.stringPrintedTextPromptEnd)) { + len++; + } + return len; + } + + protected byte[] translateString(String text) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (text.length() != 0) { + int i = Math.max(0, longestTableToken - text.length()); + if (text.charAt(0) == '\\' && text.charAt(1) == 'x') { + baos.write(Integer.parseInt(text.substring(2, 4), 16)); + text = text.substring(4); + } else { + while (!(d.containsKey(text.substring(0, longestTableToken - i)) || (i == longestTableToken))) { + i++; + } + if (i == longestTableToken) { + text = text.substring(1); + } else { + baos.write(d.get(text.substring(0, longestTableToken - i)) & 0xFF); + text = text.substring(longestTableToken - i); + } + } + } + return baos.toByteArray(); + } + + protected String readFixedLengthString(int offset, int length) { + return readString(offset, length, false); + } + + // pads the length with terminators, so length should be at least str's len + // + 1 + protected void writeFixedLengthString(String str, int offset, int length) { + byte[] translated = translateString(str); + int len = Math.min(translated.length, length); + System.arraycopy(translated, 0, rom, offset, len); + while (len < length) { + rom[offset + len] = GBConstants.stringTerminator; + len++; + } + } + + protected void writeVariableLengthString(String str, int offset, boolean alreadyTerminated) { + byte[] translated = translateString(str); + System.arraycopy(translated, 0, rom, offset, translated.length); + if (!alreadyTerminated) { + rom[offset + translated.length] = GBConstants.stringTerminator; + } + } + + protected int makeGBPointer(int offset) { + if (offset < GBConstants.bankSize) { + return offset; + } else { + return (offset % GBConstants.bankSize) + GBConstants.bankSize; + } + } + + protected int bankOf(int offset) { + return (offset / GBConstants.bankSize); + } + + protected int calculateOffset(int bank, int pointer) { + if (pointer < GBConstants.bankSize) { + return pointer; + } else { + return (pointer % GBConstants.bankSize) + bank * GBConstants.bankSize; + } + } + + protected String readVariableLengthString(int offset, boolean textEngineMode) { + return readString(offset, Integer.MAX_VALUE, textEngineMode); + } + + protected static boolean romSig(byte[] rom, String sig) { + try { + int sigOffset = GBConstants.romSigOffset; + byte[] sigBytes = sig.getBytes("US-ASCII"); + for (int i = 0; i < sigBytes.length; i++) { + if (rom[sigOffset + i] != sigBytes[i]) { + return false; + } + } + return true; + } catch (UnsupportedEncodingException ex) { + return false; + } + + } + + protected static boolean romCode(byte[] rom, String code) { + try { + int sigOffset = GBConstants.romCodeOffset; + byte[] sigBytes = code.getBytes("US-ASCII"); + for (int i = 0; i < sigBytes.length; i++) { + if (rom[sigOffset + i] != sigBytes[i]) { + return false; + } + } + return true; + } catch (UnsupportedEncodingException ex) { + return false; + } + + } + +} |