File: patch_chargen.cc

package info (click to toggle)
open-roms 0.0~git20210824.e4e324c-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 10,184 kB
  • sloc: asm: 25,386; cpp: 3,333; ansic: 1,667; makefile: 709
file content (144 lines) | stat: -rw-r--r-- 3,496 bytes parent folder | download | duplicates (2)
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;
}