2012-06-23 14:38:19 +00:00
|
|
|
#include <stdlib.h>
|
2012-06-23 12:16:37 +00:00
|
|
|
|
|
|
|
#include "defs.h"
|
|
|
|
#include "fb.h"
|
2012-06-23 14:38:19 +00:00
|
|
|
#include "sys.h"
|
2012-06-23 12:16:37 +00:00
|
|
|
|
|
|
|
static byte palmap[32768];
|
|
|
|
static byte pallock[256];
|
|
|
|
static int palrev[256];
|
|
|
|
|
|
|
|
/* Course color mapping, for when palette is exhausted. */
|
|
|
|
static byte crsmap[4][32768];
|
|
|
|
static int crsrev[4][256];
|
|
|
|
static const int crsmask[4] = { 0x7BDE, 0x739C, 0x6318, 0x4210 };
|
|
|
|
|
|
|
|
enum plstatus
|
|
|
|
{
|
|
|
|
pl_unused = 0,
|
|
|
|
pl_linger,
|
|
|
|
pl_active,
|
|
|
|
pl_locked
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static byte bestmatch(int c)
|
|
|
|
{
|
|
|
|
byte n, best;
|
|
|
|
int r, g, b;
|
|
|
|
int r2, g2, b2, c2;
|
|
|
|
int err, besterr;
|
|
|
|
|
|
|
|
r = (c & 0x001F) << 3;
|
|
|
|
g = (c & 0x03E0) >> 2;
|
|
|
|
b = (c & 0x7C00) >> 7;
|
|
|
|
|
|
|
|
best = 0;
|
|
|
|
besterr = 1024;
|
|
|
|
for (n = 1; n; n++)
|
|
|
|
{
|
|
|
|
c2 = palrev[n];
|
|
|
|
r2 = (c2 & 0x001F) << 3;
|
|
|
|
g2 = (c2 & 0x03E0) >> 2;
|
|
|
|
b2 = (c2 & 0x7C00) >> 7;
|
|
|
|
err = abs(r-r2) + abs(b-b2) + abs(g-g2);
|
|
|
|
if (err < besterr)
|
|
|
|
{
|
|
|
|
besterr = err;
|
|
|
|
best = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return best;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void makecourse(int c, byte n)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
c &= crsmask[i];
|
|
|
|
crsmap[i][c] = n;
|
|
|
|
crsrev[i][n] = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static byte findcourse(int c)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
byte n;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
c &= crsmask[i];
|
|
|
|
n = crsmap[i][c];
|
|
|
|
if (crsrev[i][n] == c)
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pal_lock(byte n)
|
|
|
|
{
|
|
|
|
if (!n) return;
|
|
|
|
if (pallock[n] >= pl_locked)
|
|
|
|
pallock[n]++;
|
|
|
|
else pallock[n] = pl_locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
byte pal_getcolor(int c, int r, int g, int b)
|
|
|
|
{
|
|
|
|
byte n;
|
|
|
|
static byte l;
|
|
|
|
n = palmap[c];
|
|
|
|
if (n && pallock[n] && palrev[n] == c)
|
|
|
|
{
|
|
|
|
pal_lock(n);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
for (n = l+1; n != l; n++)
|
|
|
|
{
|
|
|
|
if (!n || pallock[n] /* || n < 16 */) continue;
|
|
|
|
pal_lock(n);
|
|
|
|
palmap[c] = n;
|
|
|
|
palrev[n] = c;
|
|
|
|
makecourse(c, n);
|
|
|
|
vid_setpal(n, r, g, b);
|
|
|
|
return (l = n);
|
|
|
|
}
|
|
|
|
n = findcourse(c);
|
|
|
|
pal_lock(n);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pal_release(byte n)
|
|
|
|
{
|
|
|
|
if (pallock[n] >= pl_locked)
|
|
|
|
pallock[n]--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pal_expire()
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
if (pallock[i] && pallock[i] < pl_locked)
|
|
|
|
pallock[i]--;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void pal_set332()
|
|
|
|
{
|
|
|
|
int i, r, g, b;
|
|
|
|
|
|
|
|
fb.indexed = 0;
|
|
|
|
fb.cc[0].r = 5;
|
|
|
|
fb.cc[1].r = 5;
|
|
|
|
fb.cc[2].r = 6;
|
|
|
|
fb.cc[0].l = 0;
|
|
|
|
fb.cc[1].l = 3;
|
|
|
|
fb.cc[2].l = 6;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
for (b = 0; b < 4; b++) for (g = 0; g < 8; g++) for (r = 0; r < 8; r++)
|
|
|
|
vid_setpal(i++, (r<<5)|(r<<2)|(r>>1),
|
|
|
|
(g<<5)|(g<<2)|(g>>1), (b<<6)|(b<<4)|(b<<2)|b);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|