mirror of
https://github.com/ctm/executor.git
synced 2024-09-26 14:55:54 +00:00
384 lines
8.5 KiB
C
384 lines
8.5 KiB
C
|
/* Copyright 1995 by Abacus Research and
|
||
|
* Development, Inc. All rights reserved.
|
||
|
*/
|
||
|
|
||
|
#if !defined (OMIT_RCSID_STRINGS)
|
||
|
char ROMlib_rcsid_gensplash[] =
|
||
|
"$Id: gensplash.c 63 2004-12-24 18:19:43Z ctm $";
|
||
|
#endif
|
||
|
|
||
|
#include "rsys/common.h"
|
||
|
|
||
|
#include <stdarg.h>
|
||
|
|
||
|
#include "rsys/splash.h"
|
||
|
|
||
|
int bpp, log2_bpp;
|
||
|
|
||
|
struct splash_screen_color color_buf[256];
|
||
|
|
||
|
int alloc_pixel;
|
||
|
|
||
|
boolean_t pixmap_p;
|
||
|
|
||
|
void
|
||
|
_errno_fatal (const char *file, int line, const char *fn,
|
||
|
const char *fmt, ...)
|
||
|
{
|
||
|
va_list ap;
|
||
|
int save_errno = errno;
|
||
|
|
||
|
fprintf (stderr, "%s:%d; fatal error in `%s': ",
|
||
|
file, line, fn);
|
||
|
|
||
|
va_start (ap, fmt);
|
||
|
vfprintf (stderr, fmt, ap);
|
||
|
va_end (ap);
|
||
|
|
||
|
fprintf (stderr, ": %s\n", strerror (save_errno));
|
||
|
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
init_color_buf (void)
|
||
|
{
|
||
|
memset (color_buf, '\377', sizeof *color_buf);
|
||
|
color_buf[(1 << bpp) - 1].dummy_1 = -1;
|
||
|
alloc_pixel = 0;
|
||
|
}
|
||
|
|
||
|
uint8
|
||
|
color_pixel (struct splash_screen_color *color)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
color->dummy_1 = -1;
|
||
|
|
||
|
for (i = 0; i <= alloc_pixel; i ++)
|
||
|
{
|
||
|
if (! memcmp (&color_buf[i], color, sizeof *color))
|
||
|
return i;
|
||
|
}
|
||
|
|
||
|
if (! memcmp (&color_buf[(1 << bpp) - 1], color, sizeof *color))
|
||
|
return (1 << bpp) - 1;
|
||
|
|
||
|
alloc_pixel ++;
|
||
|
if (alloc_pixel == (1 << bpp) - 1)
|
||
|
{
|
||
|
fprintf (stderr, "unable to find mapping for color %d %d %d\n",
|
||
|
color->red, color->green, color->blue);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
color_buf[alloc_pixel] = *color;
|
||
|
return alloc_pixel;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ppm_read_write_bits (int height, int width, int row_bytes,
|
||
|
FILE *fp, uint8 *bits)
|
||
|
{
|
||
|
int max_cmp_value;
|
||
|
uint8 *dst;
|
||
|
|
||
|
if (pixmap_p)
|
||
|
fscanf (fp, "%d", &max_cmp_value);
|
||
|
|
||
|
{
|
||
|
int r, b, p;
|
||
|
|
||
|
for (dst = bits, r = 0; r < height; r ++)
|
||
|
{
|
||
|
for (b = 0; b < row_bytes; b ++)
|
||
|
{
|
||
|
uint8 pixel = 0;
|
||
|
|
||
|
for (p = 1 << (3 - log2_bpp); p; p --)
|
||
|
{
|
||
|
if (pixmap_p)
|
||
|
{
|
||
|
uint32 red, green, blue;
|
||
|
struct splash_screen_color color;
|
||
|
|
||
|
fscanf (fp, "%d %d %d", &red, &green, &blue);
|
||
|
|
||
|
color.red = CW ((red * 65535) / max_cmp_value);
|
||
|
color.green = CW ((green * 65535) / max_cmp_value);
|
||
|
color.blue = CW ((blue * 65535) / max_cmp_value);
|
||
|
|
||
|
pixel = (pixel << bpp) | color_pixel (&color);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int bit;
|
||
|
|
||
|
#if 0
|
||
|
/* this didn't work on beaut */
|
||
|
fscanf (fp, "%1d", &bit);
|
||
|
#else
|
||
|
{
|
||
|
int c;
|
||
|
|
||
|
do
|
||
|
c = fgetc (fp);
|
||
|
while (c != EOF && c != '0' && c != '1');
|
||
|
switch (c)
|
||
|
{
|
||
|
case '0':
|
||
|
bit = 0;
|
||
|
break;
|
||
|
case '1':
|
||
|
bit = 1;
|
||
|
break;
|
||
|
default:
|
||
|
abort ();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
if (bpp != 1)
|
||
|
abort ();
|
||
|
|
||
|
switch (bit)
|
||
|
{
|
||
|
case 0:
|
||
|
pixel = pixel << 1; break;
|
||
|
case 1:
|
||
|
pixel = (pixel << 1) | bit; break;
|
||
|
default:
|
||
|
abort ();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*dst++ = pixel;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main (int argc, char *argv[])
|
||
|
{
|
||
|
char *paramfile;
|
||
|
char splashfile[1024], buttonfile[1024], outfile[1024];
|
||
|
int splashfd, buttonfd, outfd, paramfd;
|
||
|
FILE *splashfp, *buttonfp, *paramfp;
|
||
|
char buf[1024];
|
||
|
|
||
|
int splash_width, splash_height;
|
||
|
int button_width, button_height;
|
||
|
|
||
|
struct splash_screen_header header;
|
||
|
|
||
|
int splash_row_bytes, button_row_bytes;
|
||
|
uint8 *splash_bits, *button_bits;
|
||
|
|
||
|
int retval, i;
|
||
|
|
||
|
if (argc != 2)
|
||
|
{
|
||
|
fprintf (stderr, "usage: %s paramfile\n", *argv);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
paramfile = argv[1];
|
||
|
|
||
|
paramfd = open (paramfile, O_RDONLY);
|
||
|
if (paramfd == -1)
|
||
|
errno_fatal ("open %s", paramfile);
|
||
|
paramfp = fdopen (paramfd, "r");
|
||
|
if (paramfp == NULL)
|
||
|
errno_fatal ("fdopen");
|
||
|
|
||
|
fscanf (paramfp, "splash %s\n", splashfile);
|
||
|
fscanf (paramfp, "button %s\n", buttonfile);
|
||
|
fscanf (paramfp, "out %s\n", outfile);
|
||
|
|
||
|
fprintf (stderr, "\
|
||
|
splash file `%s'\n\
|
||
|
button file `%s'\n\
|
||
|
output file `%s'\n",
|
||
|
splashfile, buttonfile, outfile);
|
||
|
|
||
|
splashfd = open (splashfile, O_RDONLY);
|
||
|
if (splashfd == -1)
|
||
|
errno_fatal ("open %s", splashfile);
|
||
|
splashfp = fdopen (splashfd, "r");
|
||
|
if (splashfp == NULL)
|
||
|
errno_fatal ("fdopen");
|
||
|
|
||
|
buttonfd = open (buttonfile, O_RDONLY);
|
||
|
if (buttonfd == -1)
|
||
|
errno_fatal ("open %s", buttonfile);
|
||
|
buttonfp = fdopen (buttonfd, "r");
|
||
|
if (buttonfp == NULL)
|
||
|
errno_fatal ("fdopen");
|
||
|
|
||
|
outfd = open (outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||
|
if (outfd == -1)
|
||
|
errno_fatal ("open %s", outfile);
|
||
|
|
||
|
fscanf (paramfp, "bpp %d\n", &bpp);
|
||
|
switch (bpp)
|
||
|
{
|
||
|
case 8: log2_bpp = 3; break;
|
||
|
case 4: log2_bpp = 2; break;
|
||
|
case 2: log2_bpp = 1; break;
|
||
|
case 1: log2_bpp = 0; break;
|
||
|
default:
|
||
|
abort ();
|
||
|
}
|
||
|
|
||
|
{
|
||
|
int16 n_buttons;
|
||
|
|
||
|
fscanf (paramfp, "n_buttons %hd\n", &n_buttons);
|
||
|
|
||
|
for (i = 0; i < n_buttons; i ++)
|
||
|
{
|
||
|
int16 top, left, bottom, right;
|
||
|
struct splash_screen_rect *rect;
|
||
|
|
||
|
fscanf (paramfp, "rect %hd %hd %hd %hd\n",
|
||
|
&top, &left, &bottom, &right);
|
||
|
rect = &header.button_rects[i];
|
||
|
|
||
|
rect->top = CW (top);
|
||
|
rect->left = CW (left);
|
||
|
rect->bottom = CW (bottom);
|
||
|
rect->right = CW (right);
|
||
|
}
|
||
|
|
||
|
header.n_buttons = CW (n_buttons);
|
||
|
}
|
||
|
|
||
|
init_color_buf ();
|
||
|
|
||
|
{
|
||
|
uint32 red, green, blue;
|
||
|
struct splash_screen_color color;
|
||
|
|
||
|
fscanf (paramfp, "bk_color %d %d %d", &red, &green, &blue);
|
||
|
|
||
|
color.red = CW (red);
|
||
|
color.green = CW (green);
|
||
|
color.blue = CW (blue);
|
||
|
|
||
|
header.bg_pixel = color_pixel (&color);
|
||
|
}
|
||
|
|
||
|
fscanf (splashfp, "%s", buf);
|
||
|
if (! strcmp (buf, "P3"))
|
||
|
pixmap_p = TRUE;
|
||
|
else if (! strcmp (buf, "P1"))
|
||
|
pixmap_p = FALSE;
|
||
|
else
|
||
|
{
|
||
|
fprintf (stderr, "ppm type must be `P3' or `P1'\n");
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
fscanf (splashfp, "%d %d", &splash_width, &splash_height);
|
||
|
|
||
|
if (splash_width != SPLASH_SCREEN_WIDTH
|
||
|
|| splash_height != SPLASH_SCREEN_HEIGHT)
|
||
|
{
|
||
|
fprintf (stderr,
|
||
|
"ppm width and height must be %d and %d, respectively\n",
|
||
|
SPLASH_SCREEN_WIDTH, SPLASH_SCREEN_HEIGHT);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
splash_row_bytes = splash_width >> (3 - log2_bpp);
|
||
|
splash_bits = malloc (splash_row_bytes * splash_height);
|
||
|
if (splash_bits == NULL)
|
||
|
{
|
||
|
fprintf (stderr, "unable to allocate `%d' bytes for bits buffer\n",
|
||
|
splash_row_bytes * splash_height);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
ppm_read_write_bits (splash_height, splash_width, splash_row_bytes,
|
||
|
splashfp, splash_bits);
|
||
|
|
||
|
fscanf (buttonfp, "%s", buf);
|
||
|
if (! strcmp (buf, "P3"))
|
||
|
pixmap_p = TRUE;
|
||
|
else if (! strcmp (buf, "P1"))
|
||
|
pixmap_p = FALSE;
|
||
|
else
|
||
|
{
|
||
|
fprintf (stderr, "ppm type must be `P3' or `P1'\n");
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
fscanf (buttonfp, "%d %d", &button_width, &button_height);
|
||
|
|
||
|
if (button_width > splash_width || button_height > splash_height)
|
||
|
{
|
||
|
fprintf (stderr, "button image cannot be larger than splash image\n");
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
if (button_width & ((1 << (3 - log2_bpp)) - 1))
|
||
|
{
|
||
|
fprintf (stderr, "button but be intergral number of bytes wide");
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
button_row_bytes = button_width >> (3 - log2_bpp);
|
||
|
button_bits = malloc (button_row_bytes * button_height);
|
||
|
if (button_bits == NULL)
|
||
|
{
|
||
|
fprintf (stderr, "unable to allocate `%d' bytes for bits buffer\n",
|
||
|
button_row_bytes * button_height);
|
||
|
exit (-1);
|
||
|
}
|
||
|
|
||
|
ppm_read_write_bits (button_height, button_width, button_row_bytes,
|
||
|
buttonfp, button_bits);
|
||
|
|
||
|
header.button_height = CW (button_height);
|
||
|
header.button_y = CW (splash_height - 12 - button_height);
|
||
|
header.button_x_byte = CW ((splash_width - 16 - button_width)
|
||
|
>> (3 - log2_bpp));
|
||
|
header.button_row_bytes = CL (button_row_bytes);
|
||
|
|
||
|
header.bpp = CL (bpp);
|
||
|
header.log2_bpp = CL (log2_bpp);
|
||
|
|
||
|
header.color_count = CL (1 << bpp);
|
||
|
|
||
|
header.color_offset = CL (sizeof header);
|
||
|
header.splash_bits_offset = CL (sizeof header + (sizeof *color_buf << bpp));
|
||
|
header.button_bits_offset = CL (CL (header.splash_bits_offset)
|
||
|
+ splash_row_bytes * splash_height);
|
||
|
|
||
|
retval = write (outfd, &header, sizeof header);
|
||
|
if (retval != sizeof header)
|
||
|
errno_fatal ("write");
|
||
|
|
||
|
retval = write (outfd, color_buf, sizeof *color_buf << bpp);
|
||
|
if (retval != sizeof *color_buf << bpp)
|
||
|
errno_fatal ("write");
|
||
|
|
||
|
retval = write (outfd, splash_bits, splash_row_bytes * splash_height);
|
||
|
if (retval != splash_row_bytes * splash_height)
|
||
|
errno_fatal ("%d = write", retval);
|
||
|
|
||
|
retval = write (outfd, button_bits, button_row_bytes * button_height);
|
||
|
if (retval != button_row_bytes * button_height)
|
||
|
errno_fatal ("%d = write", retval);
|
||
|
|
||
|
fclose (splashfp);
|
||
|
fclose (buttonfp);
|
||
|
close (splashfd);
|
||
|
close (buttonfd);
|
||
|
close (outfd);
|
||
|
|
||
|
exit (EXIT_SUCCESS);
|
||
|
}
|