/* sputoppm.c - read an uncompressed Spectrum file and produce a PPM ** ** Copyright (C) 1991 by Steve Belczyk and Jef Poskanzer ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ #include "ppm.h" #define ROWS 200 #define COLS 320 #define MAXVAL 7 typedef struct { pixel pal[ROWS][48]; /* Spectrum palettes, three per row */ } Pal; static void readPalettes(FILE * const ifP, Pal * const palP) { unsigned int row; /* Clear the first palette line. */ { unsigned int j; for (j = 0; j < 48; ++j) PPM_ASSIGN(palP->pal[0][j], 0, 0, 0); } /* Read the palettes. */ for (row = 1; row < ROWS; ++row) { unsigned int j; for (j = 0; j < 48; ++j) { short k; pm_readbigshort(ifP, &k); PPM_ASSIGN(palP->pal[row][j], (k & 0x700) >> 8, (k & 0x070) >> 4, (k & 0x007) >> 0); } } } int main(int argc, const char ** argv) { FILE * ifP; unsigned int i; pixel * pixelrow; unsigned int row; Pal pal; short screen[ROWS*COLS/4]; /* simulates the Atari's video RAM */ pm_proginit(&argc, argv); /* Check args. */ if ( argc > 2 ) pm_usage( "[spufile]" ); if ( argc == 2 ) ifP = pm_openr( argv[1] ); else ifP = stdin; /* Read the SPU file */ /* Read the screen data. */ for (i = 0; i < ROWS*COLS/4; ++i) pm_readbigshort(ifP, &screen[i]); readPalettes(ifP, &pal); pm_close(ifP); /* Ok, get set for writing PPM. */ ppm_writeppminit(stdout, COLS, ROWS, MAXVAL, 0); pixelrow = ppm_allocrow(COLS); /* Now do the conversion. */ for (row = 0; row < ROWS; ++row) { unsigned int col; for (col = 0; col < COLS; ++col) { /* Compute pixel value. */ unsigned int const ind = 80 * row + ((col >> 4) << 2); unsigned int const b = 0x8000 >> (col & 0xf); unsigned int c; unsigned int plane; unsigned int x1; c = 0; /* initial value */ for (plane = 0; plane < 4; ++plane) { if (b & screen[ind + plane]) c |= (1 << plane); } /* Compute palette index. */ x1 = 10 * c; if ((c & 1) != 0) x1 -= 5; else ++x1; if ((col >= x1 ) && (col < (x1 + 160))) c += 16; if (col >= (x1 + 160)) c += 32; /* Set the proper color. */ pixelrow[col] = pal.pal[row][c]; } ppm_writeppmrow(stdout, pixelrow, COLS, MAXVAL, 0); } ppm_freerow(pixelrow); pm_close(stdout); return 0; }