1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
//
// Utility to patch the character generator file to create
// font for MEGA65 native mode and possibly other uses
//
#include "common.h"
#include <unistd.h>
#include <fstream>
#include <vector>
//
// Command line settings
//
std::string CMD_inFile = "chargen.rom";
std::string CMD_outFile = "chargen-native.rom";
std::string CMD_name = "CHARGEN";
//
// Common helper functions
//
void printUsage()
{
std::cout << "\n" <<
"usage: patch_chargen [-i <in file>] [-o <out file>] [-n name]" << "\n\n";
}
void printBanner()
{
printBannerLineTop();
std::cout << "// Generating patched font '" << CMD_name << "'" << "\n";
printBannerLineBottom();
}
//
// Top-level functions
//
void parseCommandLine(int argc, char **argv)
{
int opt;
// Retrieve command line options
while ((opt = getopt(argc, argv, "i:o:n:")) != -1)
{
switch(opt)
{
case 'i': CMD_inFile = optarg; break;
case 'o': CMD_outFile = optarg; break;
case 'n': CMD_name = optarg; break;
default: printUsage(); ERROR();
}
}
}
//
// Font processing
//
void processFont()
{
std::vector<uint8_t> fileContent;
// Read the source file
std::ifstream srcFile;
srcFile.open(CMD_inFile, std::ios::in | std::ios::binary | std::ios::ate);
if (!srcFile.good()) ERROR(std::string("unable to open ROM file '") + CMD_inFile + "'");
auto srcSize = srcFile.tellg();
if (srcSize != 4096) ERROR(std::string("incorrect size of ROM file '") + CMD_inFile + "'");
std::vector<uint8_t> srcFileContent;
fileContent.resize(srcSize);
srcFile.seekg (0, srcFile.beg);
srcFile.read((char *) fileContent.data(), fileContent.size());
if (!srcFile.good()) ERROR(std::string("unable to read ROM file '") + CMD_inFile + "'");
srcFile.close();
// Patch the font
for (uint8_t idx = 0; idx < 8; idx++)
{
// VENDOR + M - 2px width on C64
fileContent[0x67 * 8 + 0 + idx] = 0b00000001; // normal
fileContent[0x67 * 8 + 2048 + idx] = 0b00000001; // upper/lower case
fileContent[0xE7 * 8 + 0 + idx] = 0b11111110; // inversed
fileContent[0xE7 * 8 + 2048 + idx] = 0b11111110; // upper/lower case, inversed
// VENDOR + G - 2px width on C64
fileContent[0x65 * 8 + 0 + idx] = 0b10000000; // normal
fileContent[0x65 * 8 + 2048 + idx] = 0b10000000; // upper/lower case
fileContent[0xE5 * 8 + 0 + idx] = 0b01111111; // inversed
fileContent[0xE5 * 8 + 2048 + idx] = 0b01111111; // upper/lower case, inversed
// PI character restoration for upper/lower case set
fileContent[0x5E * 8 + 2048 + idx] = fileContent[0x5E * 8 + idx];
fileContent[0xDE * 8 + 2048 + idx] = fileContent[0xDE * 8 + idx];
}
// Remove old file
unlink(CMD_outFile.c_str());
// Save the patched font
std::ofstream outFile(CMD_outFile, std::fstream::out | std::ios::binary | std::fstream::trunc);
if (!outFile.good()) ERROR(std::string("can't open oputput file '") + CMD_outFile + "'");
outFile.write((const char*) fileContent.data(), fileContent.size());
if (!outFile.good())
{
outFile.close();
unlink(CMD_outFile.c_str());
ERROR(std::string("can't write oputput file '") + CMD_outFile + "'");
}
outFile.close();
}
//
// Main function
//
int main(int argc, char **argv)
{
parseCommandLine(argc, argv);
printBanner();
processFont();
return 0;
}
|