|
|
0.34
/* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
/* plotter routines for user interfaces - used by console and gtk */
#include "generator.h"
#include "vdp.h"
#include "uiplot.h"
uint32 uiplot_palcache[192];
static int uiplot_redshift;
static int uiplot_greenshift;
static int uiplot_blueshift;
void uiplot_setshifts(int redshift, int greenshift, int blueshift)
{
uiplot_redshift = redshift;
uiplot_greenshift = greenshift;
uiplot_blueshift = blueshift;
}
/* uiplot_checkpalcache goes through the CRAM memory in the Genesis and
converts it to the uiplot_palcache table. The Genesis has 64 colours,
but we store three versions of the colour table into uiplot_palcache - a
normal, hilighted and dim version. The vdp_cramf buffer has 64
entries and is set to 1 when the game writes to CRAM, this means this
code skips entries that have not changed, unless 'flag' is set to 1 in
which case this updates all entries regardless. */
void uiplot_checkpalcache(int flag)
{
unsigned int col;
uint8 *p;
/* this code requires that there be at least 4 bits per colour, that
is, three bits that come from the console's palette, and one more bit
when we do a dim or bright colour, i.e. this code works with 12bpp
upwards */
/* the flag forces it to do the update despite the vdp_cramf buffer */
for (col = 0; col < 64; col++) { /* the CRAM has 64 colours */
if (!flag && !vdp_cramf[col])
continue;
vdp_cramf[col] = 0;
p = (uint8 *)vdp_cram + 2 * col; /* point p to the two-byte CRAM entry */
uiplot_palcache[col] = /* normal */
(p[0] & 0xE) << (uiplot_blueshift + 1) |
(p[1] & 0xE) << (uiplot_redshift + 1) |
((p[1] & 0xE0) >> 4) << (uiplot_greenshift + 1);
uiplot_palcache[col + 64] = /* hilight */
(p[0] & 0xE) << uiplot_blueshift |
(p[1] & 0xE) << uiplot_redshift |
((p[1] & 0xE0) >> 4) << uiplot_greenshift |
(16 << uiplot_blueshift) | (16 << uiplot_redshift) |
(16 << uiplot_greenshift);
uiplot_palcache[col + 128] = /* shadow */
(p[0] & 0xE) << uiplot_blueshift |
(p[1] & 0xE) << uiplot_redshift |
((p[1] & 0xE0) >> 4) << uiplot_greenshift;
}
}
/*** uiplot_convertdata - convert genesis data to 16 bit colour */
/* must call uiplot_checkpalcache first */
void uiplot_convertdata16(uint8 *indata, uint16 *outdata, unsigned int pixels)
{
unsigned int ui;
uint32 outdata1;
uint32 outdata2;
uint32 indata_val;
/* not scaled, 16bpp - we do 4 pixels at a time */
for (ui = 0; ui < (pixels >> 2); ui++) {
indata_val = ((uint32 *)indata)[ui]; /* 4 bytes of in data */
outdata1 = (uiplot_palcache[indata_val & 0xff] |
uiplot_palcache[(indata_val >> 8) & 0xff] << 16);
outdata2 = (uiplot_palcache[(indata_val >> 16) & 0xff] |
uiplot_palcache[(indata_val >> 24) & 0xff] << 16);
#ifdef WORDS_BIGENDIAN
((uint32 *)outdata)[(ui << 1)] = outdata2;
((uint32 *)outdata)[(ui << 1) + 1] = outdata1;
#else
((uint32 *)outdata)[(ui << 1)] = outdata1;
((uint32 *)outdata)[(ui << 1) + 1] = outdata2;
#endif
}
}
/*** uiplot_convertdata - convert genesis data to 32 bit colour ***/
/* must call uiplot_checkpalcache first */
void uiplot_convertdata32(uint8 *indata, uint32 *outdata, unsigned int pixels)
{
unsigned int ui;
uint32 outdata1;
uint32 outdata2;
uint32 outdata3;
uint32 outdata4;
uint32 indata_val;
/* not scaled, 32bpp - we do 4 pixels at a time */
for (ui = 0; ui < pixels >> 2; ui++) {
indata_val = ((uint32 *)indata)[ui]; /* 4 bytes of in data */
outdata1 = uiplot_palcache[indata_val & 0xff];
outdata2 = uiplot_palcache[(indata_val >> 8) & 0xff];
outdata3 = uiplot_palcache[(indata_val >> 16) & 0xff];
outdata4 = uiplot_palcache[(indata_val >> 24) & 0xff];
#ifdef WORDS_BIGENDIAN
((uint32 *)outdata)[(ui << 2)] = outdata4;
((uint32 *)outdata)[(ui << 2) + 1] = outdata3;
((uint32 *)outdata)[(ui << 2) + 2] = outdata2;
((uint32 *)outdata)[(ui << 2) + 3] = outdata1;
#else
((uint32 *)outdata)[(ui << 2)] = outdata1;
((uint32 *)outdata)[(ui << 2) + 1] = outdata2;
((uint32 *)outdata)[(ui << 2) + 2] = outdata3;
((uint32 *)outdata)[(ui << 2) + 3] = outdata4;
#endif
}
}
/*** uiplot_render16_x1 - copy to screen with delta changes (16 bit) ***/
void uiplot_render16_x1(uint16 *linedata, uint16 *olddata, uint8 *screen,
unsigned int pixels)
{
unsigned int ui;
uint32 inval;
for (ui = 0; ui < pixels >> 1; ui++) {
/* do two words of input data at a time */
inval = ((uint32 *)linedata)[ui];
if (inval != ((uint32 *)olddata)[ui])
((uint32 *)screen)[ui] = inval;
}
}
/*** uiplot_render32_x1 - copy to screen with delta changes (32 bit) ***/
void uiplot_render32_x1(uint32 *linedata, uint32 *olddata, uint8 *screen,
unsigned int pixels)
{
unsigned int ui;
uint32 inval;
for (ui = 0; ui < pixels; ui++) {
inval = linedata[ui];
if (inval != olddata[ui])
((uint32 *)screen)[ui] = inval;
}
}
/*** uiplot_render16_x2 - blow up screen image by two (16 bit) ***/
void uiplot_render16_x2(uint16 *linedata, uint16 *olddata, uint8 *screen,
unsigned int linewidth, unsigned int pixels)
{
unsigned int ui;
uint32 inval, outval, mask;
uint8 *screen2 = screen + linewidth;
mask = 0xffffffff;
for (ui = 0; ui < pixels >> 1; ui++) {
/* do two words of input data at a time */
inval = ((uint32 *)linedata)[ui];
if (olddata)
mask = inval ^ ((uint32 *)olddata)[ui]; /* check for changed data */
if (mask & 0xffff) {
/* write first two words */
outval = inval & 0xffff;
outval |= outval << 16;
#ifdef WORDS_BIGENDIAN
((uint32 *)screen)[(ui << 1) + 1] = outval;
((uint32 *)screen2)[(ui << 1) + 1] = outval;
#else
((uint32 *)screen)[(ui << 1)] = outval;
((uint32 *)screen2)[(ui << 1)] = outval;
#endif
}
if (mask & 0xffff0000) {
/* write second two words */
outval = inval & 0xffff0000;
outval |= outval >> 16;
#ifdef WORDS_BIGENDIAN
((uint32 *)screen)[(ui << 1)] = outval;
((uint32 *)screen2)[(ui << 1)] = outval;
#else
((uint32 *)screen)[(ui << 1) + 1] = outval;
((uint32 *)screen2)[(ui << 1) + 1] = outval;
#endif
}
}
}
/*** uiplot_render32_x2 - blow up screen image by two (32 bit) ***/
void uiplot_render32_x2(uint32 *linedata, uint32 *olddata, uint8 *screen,
unsigned int linewidth, unsigned int pixels)
{
unsigned int ui;
uint32 val;
uint8 *screen2 = screen + linewidth;
if (olddata) {
for (ui = 0; ui < pixels; ui++) {
val = linedata[ui];
/* check for changed data */
if (val != olddata[ui]) {
((uint32 *)screen)[(ui << 1) + 0] = val;
((uint32 *)screen)[(ui << 1) + 1] = val;
((uint32 *)screen2)[(ui << 1) + 0] = val;
((uint32 *)screen2)[(ui << 1) + 1] = val;
}
}
} else {
for (ui = 0; ui < pixels; ui++) {
val = linedata[ui];
((uint32 *)screen)[(ui << 1) + 0] = val;
((uint32 *)screen)[(ui << 1) + 1] = val;
((uint32 *)screen2)[(ui << 1) + 0] = val;
((uint32 *)screen2)[(ui << 1) + 1] = val;
}
}
}
/*** uiplot_render16_x2h - blow up by two in horizontal direction
only (16 bit) ***/
void uiplot_render16_x2h(uint16 *linedata, uint16 *olddata, uint8 *screen,
unsigned int pixels)
{
unsigned int ui;
uint32 inval, outval, mask;
mask = 0xffffffff;
for (ui = 0; ui < pixels >> 1; ui++) {
/* do two words of input data at a time */
inval = ((uint32 *)linedata)[ui];
if (olddata)
mask = inval ^ ((uint32 *)olddata)[ui]; /* check for changed data */
if (mask & 0xffff) {
/* write first two words */
outval = inval & 0xffff;
outval |= outval << 16;
#ifdef WORDS_BIGENDIAN
((uint32 *)screen)[(ui << 1) + 1] = outval;
#else
((uint32 *)screen)[(ui << 1)] = outval;
#endif
}
if (mask & 0xffff0000) {
/* write second two words */
outval = inval & 0xffff0000;
outval |= outval >> 16;
#ifdef WORDS_BIGENDIAN
((uint32 *)screen)[(ui << 1)] = outval;
#else
((uint32 *)screen)[(ui << 1) + 1] = outval;
#endif
}
}
}
/*** uiplot_render32_x2h - blow up by two in horizontal direction
only (32 bit) ***/
void uiplot_render32_x2h(uint32 *linedata, uint32 *olddata, uint8 *screen,
unsigned int pixels)
{
unsigned int ui;
uint32 val;
for (ui = 0; ui < pixels; ui++) {
val = linedata[ui];
/* check for changed data */
if (!olddata || val != olddata[ui]) {
((uint32 *)screen)[(ui << 1) + 0] = val;
((uint32 *)screen)[(ui << 1) + 1] = val;
}
}
}
/*** uiplot_irender16_weavefilter - take even and odd fields, filter and
plot (16 bit) ***/
void uiplot_irender16_weavefilter(uint16 *evendata, uint16 *odddata,
uint8 *screen, unsigned int pixels)
{
unsigned int ui;
uint32 evenval, oddval, e_r, e_g, e_b, o_r, o_g, o_b;
uint32 outval, w1, w2;
for (ui = 0; ui < pixels >> 1; ui++) {
evenval = ((uint32 *)evendata)[ui]; /* two words of input data */
oddval = ((uint32 *)odddata)[ui]; /* two words of input data */
e_r = (evenval >> uiplot_redshift) & 0x001f001f;
e_g = (evenval >> uiplot_greenshift) & 0x001f001f;
e_b = (evenval >> uiplot_blueshift) & 0x001f001f;
o_r = (oddval >> uiplot_redshift) & 0x001f001f;
o_g = (oddval >> uiplot_greenshift) & 0x001f001f;
o_b = (oddval >> uiplot_blueshift) & 0x001f001f;
outval = (((e_r + o_r) >> 1) & 0x001f001f) << uiplot_redshift |
(((e_g + o_g) >> 1) & 0x001f001f) << uiplot_greenshift |
(((e_b + o_b) >> 1) & 0x001f001f) << uiplot_blueshift;
w1 = (outval & 0xffff);
w1 |= w1 << 16;
w2 = outval & 0xffff0000;
w2 |= w2 >> 16;
#ifdef WORDS_BIGENDIAN
((uint32 *)screen)[(ui << 1)] = w2;
((uint32 *)screen)[(ui << 1) + 1] = w1;
#else
((uint32 *)screen)[(ui << 1)] = w1;
((uint32 *)screen)[(ui << 1) + 1] = w2;
#endif
}
}
/*** uiplot_irender32_weavefilter - take even and odd fields, filter and
plot (32 bit) ***/
void uiplot_irender32_weavefilter(uint32 *evendata, uint32 *odddata,
uint8 *screen, unsigned int pixels)
{
unsigned int ui;
uint32 evenval, oddval;
for (ui = 0; ui < pixels; ui++) {
evenval = evendata[ui];
oddval = odddata[ui];
/* with 32-bit data we know that there are no touching bits */
((uint32 *)screen)[(ui << 1) + 0] = (evenval >> 1) + (oddval >> 1);
((uint32 *)screen)[(ui << 1) + 1] = (evenval >> 1) + (oddval >> 1);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.