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:
parent
a9be35c7b3
commit
59109b5f6a
1 changed files with 58 additions and 21 deletions
|
|
@ -29,19 +29,47 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <fcntl.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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int ch;
|
||||||
|
int infer = 0;
|
||||||
|
unsigned int xres = 512;
|
||||||
|
unsigned int yres = 342;
|
||||||
|
|
||||||
if (argc != 2) {
|
while ((ch = getopt(argc, argv, "hi")) != -1) {
|
||||||
printf("Syntax: %s <ram image>\n", argv[0]);
|
switch (ch) {
|
||||||
return 1;
|
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) {
|
if (fd < 0) {
|
||||||
printf("Can't open %s!\n", argv[1]);
|
printf("Can't open %s!\n", argv[1]);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -56,16 +84,25 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
uint8_t *scr_base = ram_base;
|
uint8_t *scr_base = ram_base;
|
||||||
|
|
||||||
// ScrnBase = 0x01A700 (128K) or 0x07A700 (512K)
|
if (infer) {
|
||||||
// OK so.... check RAM is expected size:
|
// Old-style, for fixed 512x342 res
|
||||||
if (sb.st_size == 0x20000) {
|
// ScrnBase = 0x01A700 (128K) or 0x07A700 (512K)
|
||||||
scr_base += 0x1a700;
|
// OK so.... check RAM is expected size:
|
||||||
} else if (sb.st_size == 0x80000) {
|
if (sb.st_size == 0x20000) {
|
||||||
scr_base += 0x7a700;
|
scr_base += 0x1a700;
|
||||||
} else {
|
} else if (sb.st_size == 0x80000) {
|
||||||
printf("RAM size (%" PRId64 ") should be 128 or 512K! Trying to continue...\n", sb.st_size);
|
scr_base += 0x7a700;
|
||||||
scr_base += sb.st_size - 0x5900;
|
} 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:
|
// Open out.xbm:
|
||||||
const char *outfname = "out.xbm";
|
const char *outfname = "out.xbm";
|
||||||
|
|
@ -75,15 +112,15 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(outf, "#define out_width 512\n"
|
fprintf(outf, "#define out_width %d\n"
|
||||||
"#define out_height 342\n"
|
"#define out_height %d\n"
|
||||||
"static char out_bits[] = {\n");
|
"static char out_bits[] = {\n", xres, yres);
|
||||||
|
|
||||||
// Output L-R, big-endian shorts, with bits in MSB-LSB order:
|
// Output L-R, big-endian shorts, with bits in MSB-LSB order:
|
||||||
for (int y = 0; y < 342; y++) {
|
for (int y = 0; y < yres; y++) {
|
||||||
for (int x = 0; x < 512; x += 16) {
|
for (int x = 0; x < xres; x += 16) {
|
||||||
uint8_t plo = scr_base[x/8 + (y * 512/8) + 0];
|
uint8_t plo = scr_base[x/8 + (y * xres/8) + 0];
|
||||||
uint8_t phi = scr_base[x/8 + (y * 512/8) + 1];
|
uint8_t phi = scr_base[x/8 + (y * xres/8) + 1];
|
||||||
uint8_t ob = 0;
|
uint8_t ob = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
ob |= (plo & (1 << i)) ? (0x80 >> i) : 0;
|
ob |= (plo & (1 << i)) ? (0x80 >> i) : 0;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue