mem2scr: Make resolution-agnostic by reading OS X/Y resolution

This tool can now take screenshots of non-standard screen resolution builds by
reading the screen res from OS variables.
This commit is contained in:
Matt Evans 2024-12-14 17:54:10 +00:00
parent a9be35c7b3
commit 59109b5f6a

View file

@ -29,19 +29,47 @@
#include <unistd.h>
#include <inttypes.h>
#include <fcntl.h>
#include <getopt.h>
#include <arpa/inet.h> // for ntohl etc.
#define MACVAR_scrnBase 0x824 // u32
#define MACVAR_scrnXres 0x83a // u16
#define MACVAR_scrnYres 0x838 // u16
static void help(char *me)
{
printf("Syntax: %s [-i] <ram image>\n"
"\t-i\tInfer screen base from RAM size (512x342 only)\n"
, me);
}
int main(int argc, char *argv[])
{
int fd;
struct stat sb;
int ch;
int infer = 0;
unsigned int xres = 512;
unsigned int yres = 342;
if (argc != 2) {
printf("Syntax: %s <ram image>\n", argv[0]);
return 1;
while ((ch = getopt(argc, argv, "hi")) != -1) {
switch (ch) {
case 'i':
infer = 1;
break;
case 'h':
default:
help(argv[0]);
return 1;
}
}
if (optind >= argc) {
help(argv[0]);
return 1;
}
fd = open(argv[1], O_RDONLY);
fd = open(argv[optind], O_RDONLY);
if (fd < 0) {
printf("Can't open %s!\n", argv[1]);
return 1;
@ -56,16 +84,25 @@ int main(int argc, char *argv[])
}
uint8_t *scr_base = ram_base;
// ScrnBase = 0x01A700 (128K) or 0x07A700 (512K)
// OK so.... check RAM is expected size:
if (sb.st_size == 0x20000) {
scr_base += 0x1a700;
} else if (sb.st_size == 0x80000) {
scr_base += 0x7a700;
} else {
printf("RAM size (%" PRId64 ") should be 128 or 512K! Trying to continue...\n", sb.st_size);
scr_base += sb.st_size - 0x5900;
}
if (infer) {
// Old-style, for fixed 512x342 res
// ScrnBase = 0x01A700 (128K) or 0x07A700 (512K)
// OK so.... check RAM is expected size:
if (sb.st_size == 0x20000) {
scr_base += 0x1a700;
} else if (sb.st_size == 0x80000) {
scr_base += 0x7a700;
} else {
printf("RAM size (%" PRId64 ") should be 128 or 512K! Trying to continue...\n", sb.st_size);
scr_base += sb.st_size - 0x5900;
}
} else {
uint32_t mb = ntohl(*(uint32_t *)(ram_base + MACVAR_scrnBase));
xres = ntohs(*(uint16_t *)(ram_base + MACVAR_scrnXres));
yres = ntohs(*(uint16_t *)(ram_base + MACVAR_scrnYres));
printf("Read screenbase at %x, %dx%d\n", mb, xres, yres);
scr_base += mb;
}
// Open out.xbm:
const char *outfname = "out.xbm";
@ -75,15 +112,15 @@ int main(int argc, char *argv[])
return 1;
}
fprintf(outf, "#define out_width 512\n"
"#define out_height 342\n"
"static char out_bits[] = {\n");
fprintf(outf, "#define out_width %d\n"
"#define out_height %d\n"
"static char out_bits[] = {\n", xres, yres);
// Output L-R, big-endian shorts, with bits in MSB-LSB order:
for (int y = 0; y < 342; y++) {
for (int x = 0; x < 512; x += 16) {
uint8_t plo = scr_base[x/8 + (y * 512/8) + 0];
uint8_t phi = scr_base[x/8 + (y * 512/8) + 1];
for (int y = 0; y < yres; y++) {
for (int x = 0; x < xres; x += 16) {
uint8_t plo = scr_base[x/8 + (y * xres/8) + 0];
uint8_t phi = scr_base[x/8 + (y * xres/8) + 1];
uint8_t ob = 0;
for (int i = 0; i < 8; i++) {
ob |= (plo & (1 << i)) ? (0x80 >> i) : 0;