156 lines
4.5 KiB
Java
156 lines
4.5 KiB
Java
/*
|
|
*
|
|
* Copyright (C) 2003 Kent Hansen.
|
|
*
|
|
* This file is part of Tile Mangler.
|
|
*
|
|
* Tile Mangler 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 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Tile Mangler 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.
|
|
*
|
|
*/
|
|
|
|
package tm.filelistener;
|
|
|
|
/**
|
|
*
|
|
* Listener for Game Boy (*.gb, *.gbc) files.
|
|
*
|
|
**/
|
|
|
|
public class GameBoyFileListener extends TMFileListener {
|
|
|
|
private static final int[] scrollingNintendoGraphic = {
|
|
0xCE,0xED,0x66,0x66,0xCC,0x0D,0x00,0x0B,0x03,0x73,0x00,0x83,0x00,0x0C,0x00,0x0D,
|
|
0x00,0x08,0x11,0x1F,0x88,0x89,0x00,0x0E,0xDC,0xCC,0x6E,0xE6,0xDD,0xDD,0xD9,0x99,
|
|
0xBB,0xBB,0x67,0x63,0x6E,0x0E,0xEC,0xCC,0xDD,0xDC,0x99,0x9F,0xBB,0xB9,0x33,0x3E
|
|
};
|
|
|
|
// cartridge types (TODO: add more types)
|
|
private static final int ROM_ONLY = 0x00;
|
|
private static final int ROM_MBC1 = 0x01;
|
|
private static final int ROM_MBC1_RAM = 0x02;
|
|
private static final int ROM_MBC1_RAM_BATTERY = 0x03;
|
|
private static final int ROM_MBC2 = 0x05;
|
|
private static final int ROM_MBC2_BATTERY = 0x06;
|
|
private static final int ROM_RAM = 0x08;
|
|
private static final int ROM_RAM_BATTERY = 0x09;
|
|
private static final int ROM_HUC1_RAM_BATTERY = 0xFF;
|
|
|
|
// cartridge sizes
|
|
private static final int SIZE_256K = 0x00;
|
|
private static final int SIZE_512K = 0x01;
|
|
private static final int SIZE_1M = 0x02;
|
|
private static final int SIZE_2M = 0x03;
|
|
private static final int SIZE_4M = 0x04;
|
|
private static final int SIZE_8M = 0x05;
|
|
private static final int SIZE_16M = 0x06;
|
|
private static final int SIZE_9M = 0x52;
|
|
private static final int SIZE_10M = 0x53;
|
|
private static final int SIZE_12M = 0x54;
|
|
|
|
/**
|
|
*
|
|
* Detects if this is a GameBoy file.
|
|
* The criteria is that the extension is either gb, gbc or sgb and that
|
|
* the scrolling Nintendo graphic data is correct.
|
|
*
|
|
**/
|
|
|
|
public boolean doFormatDetect(final byte[] data, String extension) {
|
|
// verify extension
|
|
if (!(extension.equals("gb")
|
|
|| extension.equals("gbc")
|
|
|| extension.equals("sgb"))) {
|
|
return false;
|
|
}
|
|
|
|
// verify scrolling Nintendo graphic
|
|
for (int i=0; i<scrollingNintendoGraphic.length; i++) {
|
|
if ((data[0x104+i] & 0xFF) != scrollingNintendoGraphic[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// verify cartridge type
|
|
/* int ct = data[0x147] & 0xFF;
|
|
switch (ct) {
|
|
case ROM_ONLY:
|
|
case ROM_MBC1:
|
|
case ROM_MBC1_RAM:
|
|
case ROM_MBC1_RAM_BATTERY:
|
|
case ROM_MBC2:
|
|
case ROM_MBC2_BATTERY:
|
|
case ROM_RAM:
|
|
case ROM_RAM_BATTERY:
|
|
case ROM_HUC1_RAM_BATTERY:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
*/
|
|
// verify ROM size in header
|
|
int rs = data[0x148] & 0xFF;
|
|
switch (rs) {
|
|
case SIZE_256K:
|
|
case SIZE_512K:
|
|
case SIZE_1M:
|
|
case SIZE_2M:
|
|
case SIZE_4M:
|
|
case SIZE_8M:
|
|
case SIZE_16M:
|
|
case SIZE_9M:
|
|
case SIZE_10M:
|
|
case SIZE_12M:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
// TODO: verify actual file size
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Does nothing on file load.
|
|
*
|
|
**/
|
|
|
|
public void fileLoaded(byte[] data, String extension) {
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Recalculates the complement check and checksum on file save.
|
|
*
|
|
**/
|
|
|
|
public void fileSaving(byte[] data, String extension) {
|
|
// update complement check
|
|
int r = 25;
|
|
for(int i=0x134; i<0x14D; i++) {
|
|
r += data[i] & 0xFF;
|
|
}
|
|
data[0x14D] = (byte)(0x100-r);
|
|
|
|
// update checksum
|
|
int checkSum = 0;
|
|
data[0x14E] = 0;
|
|
data[0x14F] = 0;
|
|
int len = data.length & 0x0FFF8000;
|
|
for (int i=0; i<len; i++) {
|
|
checkSum += data[i] & 0xFF;
|
|
}
|
|
data[0x14E] = (byte)((checkSum >> 8) & 0xFF);
|
|
data[0x14F] = (byte)(checkSum & 0xFF);
|
|
}
|
|
|
|
} |