Reorganized functions.

Split additional functions to separate classes for better organization.
main
Nes370 2024-07-27 11:17:19 -07:00
parent 50ca7a7d7e
commit 51be8d2190
3 changed files with 2143 additions and 2042 deletions

View File

@ -0,0 +1,550 @@
package goblincave.gitea.nes;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.util.LinkedHashMap;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
public class Analyzer {
/**
* Hex value for the ASCII sequence "RIFF".
* Indicates the start of a RIFF header in WAV files.
*/
final static int ASCII_RIFF = 0x5249_4646;
/**
* Hex value for the ASCII sequence "RIFF".
* Indicates the start of a RIFF header in WAV files.
*/
final static int ASCII_WAVE = 0x5741_5645;
/**
* Hex value for the ASCII sequence "fmt ".
* Indicates the start of a format chunk in WAV files.
*/
final static int ASCII_fmt = 0x666D_7420;
/**
* Hex value for the ASCII sequence "smpl".
* Indicates the start of a sample chunk in WAV files.
*/
final static int ASCII_smpl = 0x736D_706C;
/**
* Hex value for the ASCII sequence "data".
* Indicates the start of a data chunk in WAV files.
*/
final static int ASCII_data = 0x6461_7461;
/**
* Hex value for the ASCII sequence "ALIG".
* Indicates the start of an alignment chunk in WAV files.
*/
final static int ASCII_ALIG = 0x414C_4947;
/**
* Hex value for the ASCII sequence "x2st".
* Indicates the start of an XMA stream chunk in WAV files.
*/
final static int ASCII_x2st = 0x7832_7374;
/**
* Hex value for the ASCII sequence "seek".
* Indicates the start of an XMA stream chunk in WAV files.
*/
final static int ASCII_seek = 0x7365_656B;
/**
* Hex value for the ASCII sequence "fLaC".
* Indicates the start of an FLAC file.
*/
final static int ASCII_fLaC = 0x664C_6143;
/**
* Creates a map of audio tracks within provided file.
*
* @param file
* @return Tracklist containing address-length pairs
* @throws IOException
*/
static LinkedHashMap<Integer, Integer> findAudioTracks(RandomAccessFile file) throws IOException {
LinkedHashMap<Integer, Integer> tracklist = new LinkedHashMap<Integer, Integer>();
// Files start on addresses divisible by 0x800
for(int a = 0; a + 0x800 < file.length(); a += 0x800) {
file.seek(a);
// File header starts with "RIFF" sequence
if(file.readInt() == ASCII_RIFF) {
// Next 4 bytes specify file length beyond first 8 bytes, in little-endian representation
int length = 8;
// Calculate remaining length of file
for(int d = 0; d < 4; d++) {
file.seek(a + 4 + d);
length += file.readUnsignedByte() * ((int) Math.pow(16, 2 * d));
}
// Record file position in map
tracklist.put(a, length);
}
}
return tracklist;
}
/**
* Helper method to read a little-endian byte field and print its contents.
*
* @param file
* @param address
* @param size
* @param message
* @return value
* @throws IOException
*/
static int parseField(RandomAccessFile file, int address, int size, String message) throws IOException {
byte[] bytes = new byte[size];
file.seek(address);
file.read(bytes);
int value = littleEndianToInt(bytes);
System.out.println(formatAddress(address, file.length()) + ":\t" + value + message);
return value;
}
static String formatAddress(long address, long size) {
int digits = (int) Math.ceil(Math.log(size) / Math.log(16));
return String.format("%0" + digits + "X", address);
}
/**
* Formats a file address with leading zeroes.
*
* @param address
* @return padded address
*/
static String formatAddress(long address) {
return String.format("%08X", address);
}
/**
* Helper function to read RIFF header information.
*
* @param file
* @param offset
* @return file end address
* @throws IOException
*/
static int readRIFFChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tRIFF (Resource Interchange File Format) file");
int size = -1;
if(offset + 8 < file.length()) {
size = readChunkSize(file, offset);
System.out.println(formatAddress(offset + 4, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
if(offset + 12 < file.length()) {
file.seek(offset + 8);
if(file.readInt() == ASCII_WAVE)
System.out.println(formatAddress(offset + 8, file.length()) + ":\tWAVE (Waveform Audio File Format) type");
offset += 8;
}
System.out.println();
return offset + size;
}
/**
* Helper function to read the size of a file chunk.
*
* @param file
* @param chunkAddress
* @return chunk size
* @throws IOException
*/
static int readChunkSize(File file, int chunkAddress) throws IOException {
RandomAccessFile accessedFile = new RandomAccessFile(file, "r");
return readChunkSize(accessedFile, chunkAddress);
}
/**
* Helper function to read the size of a file chunk.
*
* @param accessedFile
* @param chunkAddress
* @return chunk size
* @throws IOException
*/
static int readChunkSize(RandomAccessFile file, int chunkAddress) throws IOException {
byte[] buffer = new byte[4];
file.seek(chunkAddress + 4);
file.read(buffer);
return 8 // size offset
+ (buffer[0] & 0xFF) // 256^0
+ (buffer[1] & 0xFF) * 256 // 256^1
+ (buffer[2] & 0xFF) * 65_536 // 256^2
+ (buffer[3] & 0xFF) * 16_777_216; // 256^3
}
/**
* Helper method to read format chunk information.
*
* @param file
* @param offset from start of file to start of format chunk
* @return offset from start of file to end of format chunk
* @throws IOException
*/
static int readFormatChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tfmt (Format) chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
if(offset + size < file.length()) {
byte[] LEBytes = new byte[2];
file.seek(offset + 0x08);
file.read(LEBytes);
int encoding = littleEndianToInt(LEBytes);
System.out.print(formatAddress(offset + 0x08, file.length()) + ":\t");
if(encoding == 0x0001)
System.out.print("PCM (Pulse-Code Modulation)");
else if(encoding == 0x0002)
System.out.print("ADPCM (Adaptive Differential Pulse-Code Modulation)");
else if(encoding == 0x0165)
System.out.print("XMA (Xbox Media Audio)");
else if(encoding == 0x0166)
System.out.print("XMA2 (Xbox Media Audio 2)");
else {
boolean found = false;
InputStream filestream = AudioExtractor.class.getResourceAsStream("/encoding.csv");
InputStreamReader streamReader = new InputStreamReader(filestream);
Reader in = streamReader;
String[] headers = { "Decimal value", "Hexadecimal value", "Description" };
Iterable<CSVRecord> records = CSVFormat.EXCEL.builder().setHeader(headers).setSkipHeaderRecord(true).build().parse(in);
for (CSVRecord record : records) {
String dec = record.get("Decimal value");
String desc = record.get("Description");
if(encoding == Integer.parseInt(dec)) {
System.out.print(desc);
found = true;
break;
}
}
if(!found)
System.out.print("Unknown (" + encoding + ")");
}
System.out.println(" encoding");
if(encoding == 0x0165) {
LEBytes = new byte[2];
file.seek(offset + 0x10);
file.read(LEBytes);
int streams = littleEndianToInt(LEBytes);
System.out.println(formatAddress(offset + 0x10, file.length()) + ":\t" + streams + (streams == 1 ? " stream" : " streams"));
parseField(file, offset + 0x12, 1, " loop flag");
// unknown 5 bytes ?
parseField(file, offset + 0x18, 4, " Hz sampling rate");
parseField(file, offset + 0x1C, 4, " loop start");
parseField(file, offset + 0x20, 4, " loop end");
parseField(file, offset + 0x24, 1, " loop subframe");
// unknown 3 bytes ?
// int channels = 0;
// for(int i = 0; i < streams; i++)
// channels += parseField(file, offset + 0x08 + 0x0C + 0x14 * i + 0x11, 1, " channel");
// System.out.println(channels + " channels");
} else {
parseField(file, offset + 0x0A, 2, " channels");
parseField(file, offset + 0x0C, 4, " Hz sampling rate");
parseField(file, offset + 0x10, 4, " average bytes per second");
parseField(file, offset + 0x14, 2, "-byte sample block size");
parseField(file, offset + 0x16, 2, " significant bits per sample");
LEBytes = new byte[2];
file.seek(offset + 0x18);
file.read(LEBytes);
int extra = littleEndianToInt(LEBytes);
if(extra != ASCII_smpl)
parseField(file, offset + 0x18, 2, " extra format bytes");
}
}
System.out.println();
return offset + size;
}
static int readDataChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tdata (Data) chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
System.out.println();
return offset + size;
}
static int readSampleChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tsmpl (Sample) chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
// 0x08 4 bytes manufacturer code
byte[] bytes = new byte[4];
file.seek(offset + 0x08);
file.read(bytes);
int relevantBytes = bytes[0];
String code;
if(relevantBytes == 3)
code = String.format("%02XH %02XH %02XH", bytes[1], bytes[2], bytes[3]);
else code = String.format("%02XH", bytes[3]);
System.out.print(formatAddress(offset + 0x08, file.length()) + ":\t");
boolean found = false;
InputStream filestream = AudioExtractor.class.getResourceAsStream("/manufacturer.csv");
InputStreamReader streamReader = new InputStreamReader(filestream);
Reader in = streamReader;
String[] headers = { "SysEx ID Number", "Company Name" };
Iterable<CSVRecord> records = CSVFormat.EXCEL.builder().setHeader(headers).setSkipHeaderRecord(true).build().parse(in);
for (CSVRecord record : records) {
String ID = record.get("SysEx ID Number");
String manufacturer = record.get("Company Name");
if(code.equalsIgnoreCase(ID)) {
System.out.print(manufacturer + " (" + code + ")");
found = true;
break;
}
}
if(!found)
System.out.print("Unknown (" + code + ")");
System.out.println(" manufacturer");
parseField(file, offset + 0x0C, 4, " product code");
parseField(file, offset + 0x10, 4, "-nanosecond sample period");
parseField(file, offset + 0x14, 4, " MIDI unity note");
parseField(file, offset + 0x18, 4, " MIDI pitch fraction");
parseField(file, offset + 0x1C, 4, " SMPTE format");
parseField(file, offset + 0x20, 4, " SMPTE offset");
int loops = parseField(file, offset + 0x24, 4, " sample loops");
parseField(file, offset + 0x28, 4, " sample data");
for(int i = 0; i < loops; i++) {
int loopOffset = offset + 0x2C + i * 0x18;
parseField(file, loopOffset, 4, " loop ID");
bytes = new byte[4];
file.seek(loopOffset + 0x04);
file.read(bytes);
int loopType = littleEndianToInt(bytes);
System.out.print(formatAddress(loopOffset + 0x04, file.length()) + ":\t");
String type;
switch(loopType) {
case 0:
type = "Forward";
break;
case 1:
type = "Alternating";
break;
case 2:
type = "Backward";
break;
default:
type = "Unknown";
break;
}
type += " (" + loopType + ") loop type";
System.out.println(type);
file.seek(loopOffset + 0x08);
file.read(bytes);
int loopStart = littleEndianToInt(bytes);
System.out.println(formatAddress(loopOffset + 0x08, file.length()) + ":\tLoop start @ sample " + loopStart);
file.seek(loopOffset + 0x0C);
file.read(bytes);
int loopEnd = littleEndianToInt(bytes);
System.out.println(formatAddress(loopOffset + 0x08, file.length()) + ":\tLoop end @ sample " + loopEnd);
parseField(file, loopOffset + 0x10, 4, " loop fraction");
file.seek(loopOffset + 0x14);
file.read(bytes);
int repeat = littleEndianToInt(bytes);
if(repeat == 0)
System.out.println(formatAddress(loopOffset + 0x14, file.length()) + ":\tRepeat indefinitely");
else System.out.println(formatAddress(loopOffset + 0x14, file.length()) + ":\t" + repeat + "repeat count");
}
System.out.println();
return offset + size;
}
/**
* Helper function to read the size of a x2st chunk.
*
* @param file
* @param offset
* @return chunk end address
* @throws IOException
*/
static int readx2stChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tx2st chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
System.out.println();
return offset + size;
}
/**
* Helper function to read the size of an alignment chunk.
*
* @param file
* @param offset
* @return chunk end address
* @throws IOException
*/
static int readAlignmentChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tALIG (Alignment) chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
System.out.println();
return offset + size;
}
/**
* Helper function to read the size of an seek chunk.
*
* @param file
* @param offset
* @return chunk end address
* @throws IOException
*/
static int readSeekChunk(RandomAccessFile file, int offset) throws IOException {
System.out.println(formatAddress(offset, file.length()) + ":\tseek (Seek) chunk");
int size = 8;
if(offset + 8 < file.length()) {
size = readChunkSize(file, (int) offset);
System.out.println(formatAddress(offset + 0x04, file.length()) + ":\t" + size + " Bytes" + (size > 1024 ? " (" + convertBytes(size) + ")" : ""));
}
System.out.println();
return offset + size;
}
/**
* Get the name of a WAVE encoding from its value.
*
* @param encoding
* @return
*/
static String identifyEncoding(int encoding) {
// TODO Auto-generated method stub
System.out.println("identifyEncoding(" + encoding + ") is not yet implemented.");
return null;
}
/**
* Helper method to convert a number of bytes to a more readable form.
*
* @param bytes
* @return legible form
*/
static String convertBytes(long bytes) {
final String[] units = new String[] {"B", "KB", "MB", "GB", "TB"};
int i = (int) (Math.log10(bytes) / Math.log10(1024));
double value = bytes / Math.pow(1024, i);
return String.format("%.2f %s", value, units[i]);
}
/**
* Helper method that converts a little-endian byte array into a long value.
*
* @param bytes (up to 8 bytes)
* @return value
*/
static long littleEndianToLong(byte[] bytes) {
if(bytes.length > 8)
throw new IllegalArgumentException("Byte array must be 8 bytes or shorter.");
long value = 0;
for(int i = 0; i < bytes.length; i++)
value |= (long) (bytes[i] & 0xFF) << (8 * i);
return value;
}
/**
* Helper method that converts a little-endian byte array into a long value.
*
* @param bytes (up to 8 bytes)
* @return value
*/
static int littleEndianToInt(byte[] bytes) {
if(bytes.length > 8)
throw new IllegalArgumentException("Byte array must be 4 bytes or shorter.");
int value = 0;
for(int i = 0; i < bytes.length; i++)
value |= (int) (bytes[i] & 0xFF) << (8 * i);
return value;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,871 @@
package goblincave.gitea.nes;
public class Logo {
/**
* Creates an ASCII logo in RR6 style using the provided text.
* Supports alphanumeric text with spaces only.
*
* @param text
* @return logo formatted text
*/
public static String format(String text) {
return format(text, true, 10);
}
/**
* Creates an ASCII logo in RR6 style using the provided text.
* Supports alphanumeric text with spaces only.
*
* @param string
* @param italicize logo
* @return logo formatted text
*/
public static String format(String string, boolean italic) {
return format(string, italic, 10);
}
/**
* Creates an ASCII logo in RR6 style using the provided text.
* Supports alphanumeric text with spaces only.
*
* @param text
* @param height
* @param italicize logo
* @return logo formatted text
*/
public static String format(String text, boolean italic, int height) {
// Initialize logo lines
String[] logo = new String[10];
for(int i = 0; i < logo.length; i++)
logo[i] = new String();
boolean spaced = false;
for(int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
// Add space from previous character
if(i > 0) {
if(c != ' ' && c!= ':' && !spaced) {
for(int line = 0; line < logo.length - 1; line++)
logo[line] += " ";
logo[9] += "███";
}
spaced = false;
}
// Add character to logo
switch(c) {
// Space
case ':':
case ' ':
for(int line = 0; line < logo.length; line++)
logo[line] += " ";
spaced = true;
break;
// Numbers
case '0':
if(logo[0].length() > 0)
for(int x = 0; x < logo.length; x++)
logo[x] = logo[x].substring(0, logo[x].length() - 1);
logo[0] += " ██████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += "████████ ████████ ";
logo[4] += "████████ ████████ ";
logo[5] += "████████ ████████ ";
logo[6] += "████████ ████████ ";
logo[7] += "████████ ████████ ";
logo[8] += "████████████████████████ ";
logo[9] += " ██████████████████████ ";
spaced = true;
break;
case '1':
logo[0] += " ███████████████ ";
logo[1] += "████████████████ ";
logo[2] += " ████████ ";
logo[3] += " ████████ ";
logo[4] += " ████████ ";
logo[5] += " ████████ ";
logo[6] += " ████████ ";
logo[7] += " ████████ ";
logo[8] += " ████████ ";
logo[9] += " ████████ ";
spaced = true;
break;
case '2':
logo[0] += " ███████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += " ████████ ";
logo[4] += " ██████████████████████ ";
logo[5] += "████████████████████████ ";
logo[6] += "████████ ";
logo[7] += "████████ ";
logo[8] += "████████████████████████ ";
logo[9] += "███████████████████████ ";
spaced = true;
break;
case '3':
logo[0] += " ██████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += " ████████ ";
logo[4] += " ███████████████ ";
logo[5] += " ██████████████ ";
logo[6] += " ████████ ";
logo[7] += "████████ ████████ ";
logo[8] += "████████████████████████ ";
logo[9] += " ██████████████████████ ";
spaced = true;
break;
case '4':
logo[0] += " █████████████ ";
logo[1] += " ███████████████ ";
logo[2] += " ████ ██████ ";
logo[3] += " ██████ ██████ ";
logo[4] += " ███████████████████████ ";
logo[5] += "████████████████████████ ";
logo[6] += " ██████ ";
logo[7] += " ██████ ";
logo[8] += " ██████ ";
logo[9] += " ██████ ";
spaced = true;
break;
case '5':
logo[0] += " ███████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ";
logo[3] += "████████ ";
logo[4] += "████████████████████████ ";
logo[5] += "████████████████████████ ";
logo[6] += " ████████ ";
logo[7] += " ████████ ";
logo[8] += "████████████████████████ ";
logo[9] += "███████████████████████ ";
spaced = true;
break;
case '6':
logo[0] += " ███████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ";
logo[3] += "████████ ";
logo[4] += "████████████████████████ ";
logo[5] += "████████████████████████ ";
logo[6] += "████████ ████████ ";
logo[7] += "████████ ████████ ";
logo[8] += "████████████████████████ ";
logo[9] += "███████████████████████ ";
spaced = true;
break;
case '7':
logo[0] += " ███████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += " ████████ ";
logo[4] += " ████████ ";
logo[5] += " ████████ ";
logo[6] += " ████████ ";
logo[7] += " ████████ ";
logo[8] += " ████████ ";
logo[9] += " ████████ ";
spaced = true;
break;
case '8':
logo[0] += " ██████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += "████████ ████████ ";
logo[4] += " █████████████████████ ";
logo[5] += " █████████████████████ ";
logo[6] += "████████ ████████ ";
logo[7] += "████████ ████████ ";
logo[8] += "████████████████████████ ";
logo[9] += " ██████████████████████ ";
spaced = true;
break;
case '9':
logo[0] += " ██████████████████████ ";
logo[1] += "████████████████████████ ";
logo[2] += "████████ ████████ ";
logo[3] += "████████ ████████ ";
logo[4] += " ███████████████████████ ";
logo[5] += " █████████████████████ ";
logo[6] += " ████████ ";
logo[7] += " ████████ ";
logo[8] += " ████████ ";
logo[9] += " ████████ ";
spaced = true;
break;
// Capital letters
case 'A':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████████████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'B':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "███████████ ";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'C':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████ ";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'D':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'E':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████████████";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'F':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████████████";
logo[6] += "████ ";
logo[7] += "████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'G':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████ ██████";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'H':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████████████";
logo[6] += "████ ████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'I':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████";
logo[3] += "████";
logo[4] += "████";
logo[5] += "████";
logo[6] += "████";
logo[7] += "████";
logo[8] += " ";
logo[9] += "████";
break;
case 'J':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ██████";
logo[3] += " ████";
logo[4] += " ████";
logo[5] += " ████";
logo[6] += " ████";
logo[7] += "████████";
logo[8] += " ";
logo[9] += "████████";
break;
case 'K':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████ ";
logo[3] += "████ ████ ";
logo[4] += "████ ████ ";
logo[5] += "████ ████ ";
logo[6] += "████████ ";
logo[7] += "████ █████ ";
logo[8] += " █████";
logo[9] += "███████ ███";
spaced = true;
break;
case 'L':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████ ";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'M':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "██████ ██████";
logo[4] += "████ ████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "██████████████";
break;
case 'N':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████ ";
logo[3] += "██████ ████ ";
logo[4] += "███████ ████ ";
logo[5] += "████ ███████ ";
logo[6] += "████ ██████ ";
logo[7] += "████ ████ ";
logo[8] += " ████ ";
logo[9] += "█████████ ███";
spaced = true;
break;
case 'O':
if(logo[0].length() > 0)
for(int x = 0; x < logo.length; x++)
logo[x] = logo[x].substring(0, logo[x].length() - 1);
logo[0] += " ";
logo[1] += " ";
logo[2] += " ██████████ ";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += " ██████████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'P':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████████████";
logo[7] += "████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'Q':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ███████████ ";
logo[3] += "████ ████ ";
logo[4] += "████ ████ ";
logo[5] += "████ ████ ";
logo[6] += "████ ████ ";
logo[7] += "████████████ ";
logo[8] += " ████ ";
logo[9] += "█████████ ███";
spaced = true;
break;
case 'R':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████ ";
logo[3] += "████ ████ ";
logo[4] += "████ ████ ";
logo[5] += "████ ████ ";
logo[6] += "███████████ ";
logo[7] += "█████ █████ ";
logo[8] += " █████";
logo[9] += "█████████ ███";
spaced = true;
break;
case 'S':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += "████ ████";
logo[4] += " ████ ";
logo[5] += " ████ ";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'T':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += " ████ ";
logo[4] += " ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ";
logo[7] += " ████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'U':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'V':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += " ████████ ";
logo[7] += " ████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'W':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████ ████";
logo[6] += "██████ ██████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "██████████████";
break;
case 'X':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████ ";
logo[3] += "████ ████ ";
logo[4] += " ████ ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ████ ";
logo[7] += "████ ████ ";
logo[8] += " █████";
logo[9] += "█████████ ███";
spaced = true;
break;
case 'Y':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████ ████";
logo[3] += "████ ████";
logo[4] += " ████ ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ";
logo[7] += " ████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'Z':
logo[0] += " ";
logo[1] += " ";
logo[2] += "████████████";
logo[3] += " ████";
logo[4] += " ████ ";
logo[5] += " ████ ";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
// Lowercase letters
case 'a':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████████████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'b':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += "████ ████";
logo[5] += "██████████ ";
logo[6] += "████ ████";
logo[7] += "███████████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'c':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ";
logo[5] += "████ ";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'd':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "███████████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'e':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ";
logo[5] += "████████████";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'f':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ";
logo[5] += "████████████";
logo[6] += "████ ";
logo[7] += "████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'g':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "███████████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'h':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████████████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'i':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████";
logo[4] += "████";
logo[5] += "████";
logo[6] += "████";
logo[7] += "████";
logo[8] += " ";
logo[9] += "████";
break;
case 'j':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ██████";
logo[4] += " ████";
logo[5] += " ████";
logo[6] += " ████";
logo[7] += "████████";
logo[8] += " ";
logo[9] += "████████";
break;
case 'k':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += "████ ████ ";
logo[5] += "████████ ";
logo[6] += "████ ████ ";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'l':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ";
logo[4] += "████ ";
logo[5] += "████ ";
logo[6] += "████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'm':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ █████";
logo[4] += "█████ ██████";
logo[5] += "████ ██ ████";
logo[6] += "████ ████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'n':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += "█████ ████";
logo[5] += "████ ██ ████";
logo[6] += "████ █████";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'o':
if(logo[0].length() > 0)
for(int x = 0; x < logo.length; x++)
logo[x] = logo[x].substring(0, logo[x].length() - 1);
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ██████████ ";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += " ██████████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'p':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "██████████ ";
logo[7] += "████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'q':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += " ███████████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += " ██████████";
logo[7] += " ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'r':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "██████████ ";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 's':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += "████ ";
logo[5] += " ████ ";
logo[6] += " ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 't':
if(logo[0].length() > 0)
for(int x = 0; x < logo.length; x++)
logo[x] = logo[x].substring(0, logo[x].length() - 1);
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += " ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ";
logo[7] += " ████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'u':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += "████ ████";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'v':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += "████ ████";
logo[5] += "████ ████";
logo[6] += " ████ ████";
logo[7] += " █████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'w':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "███ ███ ███";
logo[4] += "███ ███ ███";
logo[5] += "███ ███ ███";
logo[6] += " ██ ████ ███";
logo[7] += " ████ ████ ";
logo[8] += " ";
logo[9] += "███████████████";
break;
case 'x':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += " ████ ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ████ ";
logo[7] += "████ ████";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'y':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████ ████";
logo[4] += " ████ ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ";
logo[7] += " ████ ";
logo[8] += " ";
logo[9] += "████████████";
break;
case 'z':
logo[0] += " ";
logo[1] += " ";
logo[2] += " ";
logo[3] += "████████████";
logo[4] += " ████ ";
logo[5] += " ████ ";
logo[6] += " ████ ";
logo[7] += "████████████";
logo[8] += " ";
logo[9] += "████████████";
break;
default:
System.out.println("Unable to convert character '" + c + "'");
break;
}
}
// Italicize logo
if(italic) {
for(int i = 0; i < logo.length; i++) {
// i = 0 -> 9
for(int x = logo.length - (i + 1); x > 0; x--)
// x = 10 - (i + 1)
logo[i] = " " + logo[i]; // line 0 gets 10 spaces, line 1 gets 9 spaces... line 9 gets 0 spaces
}
}
// Compile logo into single text element
StringBuilder logoText = new StringBuilder();
for(int i = logo.length - height; i < logo.length; i++) {
logoText.append(logo[i] + "\n");
}
return logoText.toString();
}
}