diff options
| author | Jens Arnold <amiconn@rockbox.org> | 2005-03-02 23:49:38 +0000 |
|---|---|---|
| committer | Jens Arnold <amiconn@rockbox.org> | 2005-03-02 23:49:38 +0000 |
| commit | 384de102469fee4e0792df8fe38586d3206774ed (patch) | |
| tree | ee5342103e17738acfb8421328ea7c57433f55e6 /apps/plugins/rockboy/lcd.c | |
| parent | 48dad47df98bdec632e8930b6a97359dc2c428f5 (diff) | |
| download | rockbox-384de102469fee4e0792df8fe38586d3206774ed.zip rockbox-384de102469fee4e0792df8fe38586d3206774ed.tar.gz rockbox-384de102469fee4e0792df8fe38586d3206774ed.tar.bz2 rockbox-384de102469fee4e0792df8fe38586d3206774ed.tar.xz | |
Rockboy - gameboy emulation for rockbox, based on gnuboy. Still a bit early, but already playable on iRiver H1xx and the simulators. The archos recorder version is currently rather slow...
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6104 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/rockboy/lcd.c')
| -rw-r--r-- | apps/plugins/rockboy/lcd.c | 956 |
1 files changed, 956 insertions, 0 deletions
diff --git a/apps/plugins/rockboy/lcd.c b/apps/plugins/rockboy/lcd.c new file mode 100644 index 0000000..6351cb9 --- /dev/null +++ b/apps/plugins/rockboy/lcd.c @@ -0,0 +1,956 @@ + + +#include "config.h" +#include "rockmacros.h" +#include "defs.h" +#include "regs.h" +#include "hw.h" +#include "mem.h" +#include "lcd.h" +#include "rc.h" +#include "fb.h" +#include "palette.h" +#ifdef USE_ASM +#include "asm.h" +#endif + +struct lcd lcd; + +struct scan scan; + +#define BG (scan.bg) +#define WND (scan.wnd) +#define BUF (scan.buf[scanline_ind]) +#define PRI (scan.pri) + +#define PAL1 (scan.pal1) +#define PAL2 (scan.pal2) +#define PAL4 (scan.pal4) + +#define VS (scan.vs) /* vissprites */ +#define NS (scan.ns) + +#define L (scan.l) /* line */ +#define X (scan.x) /* screen position */ +#define Y (scan.y) +#define S (scan.s) /* tilemap position */ +#define T (scan.t) +#define U (scan.u) /* position within tile */ +#define V (scan.v) +#define WX (scan.wx) +#define WY (scan.wy) +#define WT (scan.wt) +#define WV (scan.wv) + +byte patpix[4096][8][8]; +byte patdirty[1024]; +byte anydirty; + +// static int scale = 1; + +static int rgb332; + +static int sprsort = 1; +static int sprdebug; +static int scanline_ind=0; + +#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C } + +static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL }; + +static int usefilter, filterdmg; +static int filter[3][4] = { + { 195, 25, 0, 35 }, + { 25, 170, 25, 35 }, + { 25, 60, 125, 40 } + }; + +rcvar_t lcd_exports[] = + { + RCV_BOOL("rgb332", &rgb332), + RCV_VECTOR("dmg_bgp", dmg_pal[0], 4), + RCV_VECTOR("dmg_wndp", dmg_pal[1], 4), + RCV_VECTOR("dmg_obp0", dmg_pal[2], 4), + RCV_VECTOR("dmg_obp1", dmg_pal[3], 4), + RCV_BOOL("sprsort", &sprsort), + RCV_BOOL("sprdebug", &sprdebug), + RCV_BOOL("colorfilter", &usefilter), + RCV_BOOL("filterdmg", &filterdmg), + RCV_VECTOR("red", filter[0], 4), + RCV_VECTOR("green", filter[1], 4), + RCV_VECTOR("blue", filter[2], 4), + RCV_END + }; + +static byte *vdest; + +#ifdef ALLOW_UNALIGNED_IO /* long long is ok since this is i386-only anyway? */ +#define MEMCPY8(d, s) ((*(long long *)(d)) = (*(long long *)(s))) +#else +#define MEMCPY8(d, s) memcpy((d), (s), 8) +#endif + + + + +#ifndef ASM_UPDATEPATPIX +void updatepatpix(void) +{ + int i, j; +#if CONFIG_CPU != SH7034 || defined(SIMULATOR) + int k, a, c; +#endif + byte *vram = lcd.vbank[0]; + + if (!anydirty) return; + for (i = 0; i < 1024; i++) + { + if (i == 384) i = 512; + if (i == 896) break; + if (!patdirty[i]) continue; + patdirty[i] = 0; + for (j = 0; j < 8; j++) + { +#if CONFIG_CPU == SH7034 && !defined(SIMULATOR) + asm volatile ( + "mov.w @%2,r1 \n" + "swap.b r1,r2 \n" + + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@%0 \n" + "mov.b r0,@(7,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(1,%0) \n" + "mov.b r0,@(6,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(2,%0) \n" + "mov.b r0,@(5,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(3,%0) \n" + "mov.b r0,@(4,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(4,%0) \n" + "mov.b r0,@(3,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(5,%0) \n" + "mov.b r0,@(2,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(6,%0) \n" + "mov.b r0,@(1,%1) \n" + "mov #0,r0 \n" + "shlr r1 \n" + "rotcl r0 \n" + "shlr r2 \n" + "rotcl r0 \n" + "mov.b r0,@(7,%0) \n" + "mov.b r0,@%1 \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(patpix[i+1024][j]), + /* %1 */ "r"(patpix[i][j]), + /* %2 */ "r"(&vram[(i<<4)|(j<<1)]) + : /* clobbers */ + "r0", "r1", "r2" + ); +#else + a = ((i<<4) | (j<<1)); + for (k = 0; k < 8; k++) + { + c = vram[a] & (1<<k) ? 1 : 0; + c |= vram[a+1] & (1<<k) ? 2 : 0; + patpix[i+1024][j][k] = c; + } + for (k = 0; k < 8; k++) + patpix[i][j][k] = + patpix[i+1024][j][7-k]; +#endif + } +#if CONFIG_CPU == SH7034 && !defined(SIMULATOR) + asm volatile ( + "mov.l @%0,r0 \n" + "mov.l @(4,%0),r1 \n" + "mov.l r0,@(56,%1) \n" + "mov.l r1,@(60,%1) \n" + "mov.l @(8,%0),r0 \n" + "mov.l @(12,%0),r1 \n" + "mov.l r0,@(48,%1) \n" + "mov.l r1,@(52,%1) \n" + "mov.l @(16,%0),r0 \n" + "mov.l @(20,%0),r1 \n" + "mov.l r0,@(40,%1) \n" + "mov.l r1,@(44,%1) \n" + "mov.l @(24,%0),r0 \n" + "mov.l @(28,%0),r1 \n" + "mov.l r0,@(32,%1) \n" + "mov.l r1,@(36,%1) \n" + "mov.l @(32,%0),r0 \n" + "mov.l @(36,%0),r1 \n" + "mov.l r0,@(24,%1) \n" + "mov.l r1,@(28,%1) \n" + "mov.l @(40,%0),r0 \n" + "mov.l @(44,%0),r1 \n" + "mov.l r0,@(16,%1) \n" + "mov.l r1,@(20,%1) \n" + "mov.l @(48,%0),r0 \n" + "mov.l @(52,%0),r1 \n" + "mov.l r0,@(8,%1) \n" + "mov.l r1,@(12,%1) \n" + "mov.l @(56,%0),r0 \n" + "mov.l @(60,%0),r1 \n" + "mov.l r0,@%1 \n" + "mov.l r1,@(4,%1) \n" + + "add %2,%0 \n" + "add %2,%1 \n" + + "mov.l @%0,r0 \n" + "mov.l @(4,%0),r1 \n" + "mov.l r0,@(56,%1) \n" + "mov.l r1,@(60,%1) \n" + "mov.l @(8,%0),r0 \n" + "mov.l @(12,%0),r1 \n" + "mov.l r0,@(48,%1) \n" + "mov.l r1,@(52,%1) \n" + "mov.l @(16,%0),r0 \n" + "mov.l @(20,%0),r1 \n" + "mov.l r0,@(40,%1) \n" + "mov.l r1,@(44,%1) \n" + "mov.l @(24,%0),r0 \n" + "mov.l @(28,%0),r1 \n" + "mov.l r0,@(32,%1) \n" + "mov.l r1,@(36,%1) \n" + "mov.l @(32,%0),r0 \n" + "mov.l @(36,%0),r1 \n" + "mov.l r0,@(24,%1) \n" + "mov.l r1,@(28,%1) \n" + "mov.l @(40,%0),r0 \n" + "mov.l @(44,%0),r1 \n" + "mov.l r0,@(16,%1) \n" + "mov.l r1,@(20,%1) \n" + "mov.l @(48,%0),r0 \n" + "mov.l @(52,%0),r1 \n" + "mov.l r0,@(8,%1) \n" + "mov.l r1,@(12,%1) \n" + "mov.l @(56,%0),r0 \n" + "mov.l @(60,%0),r1 \n" + "mov.l r0,@%1 \n" + "mov.l r1,@(4,%1) \n" + : /* outputs */ + : /* inputs */ + /* %0 */ "r"(patpix[i][0]), + /* %1 */ "r"(patpix[i+2048][0]), + /* %2 */ "r"(1024*64) + : /* clobbers */ + "r0", "r1" + ); +#else + for (j = 0; j < 8; j++) + { + for (k = 0; k < 8; k++) + { + patpix[i+2048][j][k] = + patpix[i][7-j][k]; + patpix[i+3072][j][k] = + patpix[i+1024][7-j][k]; + } + } +#endif + } + anydirty = 0; +} +#endif /* ASM_UPDATEPATPIX */ + + + +void tilebuf(void) +{ + int i, cnt; + int base; + byte *tilemap, *attrmap; + int *tilebuf; + int *wrap; + static int wraptable[64] = + { + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,-32 + }; + + base = ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5) + S; + tilemap = lcd.vbank[0] + base; + attrmap = lcd.vbank[1] + base; + tilebuf = BG; + wrap = wraptable + S; + cnt = ((WX + 7) >> 3) + 1; + + if (hw.cgb) { + if (R_LCDC & 0x10) + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = *tilemap + | (((int)*attrmap & 0x08) << 6) + | (((int)*attrmap & 0x60) << 5); + *(tilebuf++) = (((int)*attrmap & 0x07) << 2); + attrmap += *wrap + 1; + tilemap += *(wrap++) + 1; + } + else + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = (256 + ((n8)*tilemap)) + | (((int)*attrmap & 0x08) << 6) + | (((int)*attrmap & 0x60) << 5); + *(tilebuf++) = (((int)*attrmap & 0x07) << 2); + attrmap += *wrap + 1; + tilemap += *(wrap++) + 1; + } + } + else + { + if (R_LCDC & 0x10) + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = *(tilemap++); + tilemap += *(wrap++); + } + else + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = (256 + ((n8)*(tilemap++))); + tilemap += *(wrap++); + } + } + + if (WX >= 160) return; + + base = ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5); + tilemap = lcd.vbank[0] + base; + attrmap = lcd.vbank[1] + base; + tilebuf = WND; + cnt = ((160 - WX) >> 3) + 1; + + if (hw.cgb) + { + if (R_LCDC & 0x10) + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = *(tilemap++) + | (((int)*attrmap & 0x08) << 6) + | (((int)*attrmap & 0x60) << 5); + *(tilebuf++) = (((int)*(attrmap++)&7) << 2); + } + else + for (i = cnt; i > 0; i--) + { + *(tilebuf++) = (256 + ((n8)*(tilemap++))) + | (((int)*attrmap & 0x08) << 6) + | (((int)*attrmap & 0x60) << 5); + *(tilebuf++) = (((int)*(attrmap++)&7) << 2); + } + } + else + + { + if (R_LCDC & 0x10) + for (i = cnt; i > 0; i--) + *(tilebuf++) = *(tilemap++); + else + for (i = cnt; i > 0; i--) + *(tilebuf++) = (256 + ((n8)*(tilemap++))); + } +} + + +// V = vertical line +// WX = WND start (if 0, no need to do anything) -> WY +// U = start...something...thingy... 7 at most +void bg_scan(void) +{ + int cnt; + byte *src, *dest; + int *tile; + + if (WX <= 0) return; + cnt = WX; + tile = BG; + dest = BUF; + + src = patpix[*(tile++)][V] + U; + memcpy(dest, src, 8-U); + dest += 8-U; + cnt -= 8-U; + if (cnt <= 0) return; + while (cnt >= 8) + { + src = patpix[*(tile++)][V]; + MEMCPY8(dest, src); + dest += 8; + cnt -= 8; + } + src = patpix[*tile][V]; + while (cnt--) + *(dest++) = *(src++); +} + +void wnd_scan(void) +{ + int cnt; + byte *src, *dest; + int *tile; + + if (WX >= 160) return; + cnt = 160 - WX; + tile = WND; + dest = BUF + WX; + + while (cnt >= 8) + { + src = patpix[*(tile++)][WV]; + MEMCPY8(dest, src); + dest += 8; + cnt -= 8; + } + src = patpix[*tile][WV]; + while (cnt--) + *(dest++) = *(src++); +} + +static void blendcpy(byte *dest, byte *src, byte b, int cnt) +{ + while (cnt--) *(dest++) = *(src++) | b; +} + +static int priused(void *attr) +{ + un32 *a = attr; + return (int)((a[0]|a[1]|a[2]|a[3]|a[4]|a[5]|a[6]|a[7])&0x80808080); +} + +void bg_scan_pri(void) +{ + int cnt, i; + byte *src, *dest; + + if (WX <= 0) return; + i = S; + cnt = WX; + dest = PRI; + src = lcd.vbank[1] + ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5); + + if (!priused(src)) + { + memset(dest, 0, cnt); + return; + } + + memset(dest, src[i++&31]&128, 8-U); + dest += 8-U; + cnt -= 8-U; + if (cnt <= 0) return; + while (cnt >= 8) + { + memset(dest, src[i++&31]&128, 8); + dest += 8; + cnt -= 8; + } + memset(dest, src[i&31]&128, cnt); +} + +void wnd_scan_pri(void) +{ + int cnt, i; + byte *src, *dest; + + if (WX >= 160) return; + i = 0; + cnt = 160 - WX; + dest = PRI + WX; + src = lcd.vbank[1] + ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5); + + if (!priused(src)) + { + memset(dest, 0, cnt); + return; + } + + while (cnt >= 8) + { + memset(dest, src[i++]&128, 8); + dest += 8; + cnt -= 8; + } + memset(dest, src[i]&128, cnt); +} + +void bg_scan_color(void) +{ + int cnt; + byte *src, *dest; + int *tile; + + if (WX <= 0) return; + cnt = WX; + tile = BG; + dest = BUF; + + src = patpix[*(tile++)][V] + U; + blendcpy(dest, src, *(tile++), 8-U); + dest += 8-U; + cnt -= 8-U; + if (cnt <= 0) return; + while (cnt >= 8) + { + src = patpix[*(tile++)][V]; + blendcpy(dest, src, *(tile++), 8); + dest += 8; + cnt -= 8; + } + src = patpix[*(tile++)][V]; + blendcpy(dest, src, *(tile++), cnt); +} + +// blend in window source WND target BUF +// WX = starting X in buf where WND starts +// WV = vertical line selected for this scanline +// reverse: +// WY = starting y in buf where WND starts ? +// W?? = horizontal line selected for this scanline +void wnd_scan_color(void) +{ + int cnt; + byte *src, *dest; + int *tile; + + if (WX >= 160) return; + cnt = 160 - WX; + tile = WND; + dest = BUF + WX; + + while (cnt >= 8) + { + src = patpix[*(tile++)][WV]; + blendcpy(dest, src, *(tile++), 8); + dest += 8; + cnt -= 8; + } + src = patpix[*(tile++)][WV]; + blendcpy(dest, src, *(tile++), cnt); +} + +static void recolor(byte *buf, byte fill, int cnt) +{ + while (cnt--) *(buf++) |= fill; +} + +void spr_count(void) +{ + int i; + struct obj *o; + + NS = 0; + if (!(R_LCDC & 0x02)) return; + + o = lcd.oam.obj; + + for (i = 40; i; i--, o++) + { + if (L >= o->y || L + 16 < o->y) + continue; + if (L + 8 >= o->y && !(R_LCDC & 0x04)) + continue; + if (++NS == 10) break; + } +} + +void spr_enum(void) +{ + int i, j; + struct obj *o; + struct vissprite ts[10]; + int v, pat; + int l, x; + + NS = 0; + if (!(R_LCDC & 0x02)) return; + + o = lcd.oam.obj; + + for (i = 40; i; i--, o++) + { + if (L >= o->y || L + 16 < o->y) + continue; + if (L + 8 >= o->y && !(R_LCDC & 0x04)) + continue; + VS[NS].x = (int)o->x - 8; + v = L - (int)o->y + 16; + if (hw.cgb) + { + pat = o->pat | (((int)o->flags & 0x60) << 5) + | (((int)o->flags & 0x08) << 6); + VS[NS].pal = 32 + ((o->flags & 0x07) << 2); + } + else + { + pat = o->pat | (((int)o->flags & 0x60) << 5); + VS[NS].pal = 32 + ((o->flags & 0x10) >> 2); + } + VS[NS].pri = (o->flags & 0x80) >> 7; + if ((R_LCDC & 0x04)) + { + pat &= ~1; + if (v >= 8) + { + v -= 8; + pat++; + } + if (o->flags & 0x40) pat ^= 1; + } + VS[NS].buf = patpix[pat][v]; + if (++NS == 10) break; + } + if (!sprsort||hw.cgb) return; + /* not quite optimal but it finally works! */ + for (i = 0; i < NS; i++) + { + l = 0; + x = VS[0].x; + for (j = 1; j < NS; j++) + { + if (VS[j].x < x) + { + l = j; + x = VS[j].x; + } + } + ts[i] = VS[l]; + VS[l].x = 160; + } + memcpy(VS, ts, sizeof VS); +} + +void spr_scan(void) +{ + int i, x; + byte pal, b, ns = NS; + byte *src, *dest, *bg, *pri; + struct vissprite *vs; + static byte bgdup[256]; + + if (!ns) return; + + memcpy(bgdup, BUF, 256); + vs = &VS[ns-1]; + + for (; ns; ns--, vs--) + { + x = vs->x; + if (x >= 160) continue; + if (x <= -8) continue; + if (x < 0) + { + src = vs->buf - x; + dest = BUF; + i = 8 + x; + } + else + { + src = vs->buf; + dest = BUF + x; + if (x > 152) i = 160 - x; + else i = 8; + } + pal = vs->pal; + if (vs->pri) + { + bg = bgdup + (dest - BUF); + while (i--) + { + b = src[i]; + if (b && !(bg[i]&3)) dest[i] = pal|b; + } + } + else if (hw.cgb) + { + bg = bgdup + (dest - BUF); + pri = PRI + (dest - BUF); + while (i--) + { + b = src[i]; + if (b && (!pri[i] || !(bg[i]&3))) + dest[i] = pal|b; + } + } + else while (i--) if (src[i]) dest[i] = pal|src[i]; + /* else while (i--) if (src[i]) dest[i] = 31 + ns; */ + } +// if (sprdebug) for (i = 0; i < NS; i++) BUF[i<<1] = 36; +} + + + + + + +void lcd_begin(void) +{ +/* if (fb.indexed) + { + if (rgb332) pal_set332(); + else pal_expire(); + } + while (scale * 160 > fb.w || scale * 144 > fb.h) scale--; */ + vdest = fb.ptr + ((fb.w*fb.pelsize)>>1) + - (80*fb.pelsize) + + ((fb.h>>1) - 72) * fb.pitch; + WY = R_WY; +} + +void lcd_refreshline(void) +{ + if (!fb.enabled) return; + + if (!(R_LCDC & 0x80)) + return; /* should not happen... */ + +#if LCD_HEIGHT == 64 + if (R_LY >= 128 || R_LY & 1) /* calculate only even lines */ +#else + if (R_LY >= 128) +#endif + return; + + updatepatpix(); + + L = R_LY; +#if LCD_HEIGHT == 64 + scanline_ind = (L/2) % 8; +#else + scanline_ind = L % 8; +#endif + X = R_SCX; + Y = (R_SCY + L) & 0xff; + S = X >> 3; + T = Y >> 3; + U = X & 7; + V = Y & 7; + + WX = R_WX - 7; + if (WY>L || WY<0 || WY>143 || WX<-7 || WX>159 || !(R_LCDC&0x20)) + WX = 160; + WT = (L - WY) >> 3; + WV = (L - WY) & 7; + + spr_enum(); + + tilebuf(); + if (hw.cgb) + { + bg_scan_color(); + wnd_scan_color(); + if (NS) + { + bg_scan_pri(); + wnd_scan_pri(); + } + } + else + { + + bg_scan(); + wnd_scan(); + recolor(BUF+WX, 0x04, 160-WX); + } + spr_scan(); +/* + if (fb.dirty) memset(fb.ptr, 0, fb.pitch * fb.h); + fb.dirty = 0; + if (density > scale) density = scale; + if (scale == 1) density = 1; + dest = vdest; +*/ + if (scanline_ind == 7) + vid_update(L); + // vdest += fb.pitch * scale; +} + + + + + + +/* +static void updatepalette(int i) +{ + int c, r, g, b, y, u, v, rr, gg; + + c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF; + r = (c & 0x001F) << 3; + g = (c & 0x03E0) >> 2; + b = (c & 0x7C00) >> 7; + r |= (r >> 5); + g |= (g >> 5); + b |= (b >> 5); + + if (usefilter && (filterdmg||hw.cgb)) + { + rr = ((r * filter[0][0] + g * filter[0][1] + b * filter[0][2]) >> 8) + filter[0][3]; + gg = ((r * filter[1][0] + g * filter[1][1] + b * filter[1][2]) >> 8) + filter[1][3]; + b = ((r * filter[2][0] + g * filter[2][1] + b * filter[2][2]) >> 8) + filter[2][3]; + r = rr; + g = gg; + } + + if (fb.yuv) + { + y = (((r * 263) + (g * 516) + (b * 100)) >> 10) + 16; + u = (((r * 450) - (g * 377) - (b * 73)) >> 10) + 128; + v = (((r * -152) - (g * 298) + (b * 450)) >> 10) + 128; + if (y < 0) y = 0; if (y > 255) y = 255; + if (u < 0) u = 0; if (u > 255) u = 255; + if (v < 0) v = 0; if (v > 255) v = 255; + PAL4[i] = (y<<fb.cc[0].l) | (y<<fb.cc[3].l) + | (u<<fb.cc[1].l) | (v<<fb.cc[2].l); + return; + } + + if (fb.indexed) + { + pal_release(PAL1[i]); + c = pal_getcolor(c, r, g, b); + PAL1[i] = c; + PAL2[i] = (c<<8) | c; + PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c; + return; + } + + r = (r >> fb.cc[0].r) << fb.cc[0].l; + g = (g >> fb.cc[1].r) << fb.cc[1].l; + b = (b >> fb.cc[2].r) << fb.cc[2].l; + c = r|g|b; + + switch (fb.pelsize) + { + case 1: + PAL1[i] = c; + PAL2[i] = (c<<8) | c; + PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c; + break; + case 2: + PAL2[i] = c; + PAL4[i] = (c<<16) | c; + break; + case 3: + case 4: + PAL4[i] = c; + break; + } +}*/ + +void pal_write(int i, byte b) +{ + if (lcd.pal[i] == b) return; + lcd.pal[i] = b; +// updatepalette(i>>1); +} + +void pal_write_dmg(int i, int mapnum, byte d) +{ + int j; + int *cmap = dmg_pal[mapnum]; + int c, r, g, b; + + if (hw.cgb) return; + + /* if (mapnum >= 2) d = 0xe4; */ + for (j = 0; j < 8; j += 2) + { + c = cmap[(d >> j) & 3]; + r = (c & 0xf8) >> 3; + g = (c & 0xf800) >> 6; + b = (c & 0xf80000) >> 9; + c = r|g|b; + /* FIXME - handle directly without faking cgb */ + pal_write(i+j, c & 0xff); + pal_write(i+j+1, c >> 8); + } +} + +void vram_write(int a, byte b) +{ + lcd.vbank[R_VBK&1][a] = b; + if (a >= 0x1800) return; + patdirty[((R_VBK&1)<<9)+(a>>4)] = 1; + anydirty = 1; +} + +void vram_dirty(void) +{ + anydirty = 1; + memset(patdirty, 1, sizeof patdirty); +} + +void pal_dirty(void) +{ +// int i; + if (!hw.cgb) + { + + pal_write_dmg(0, 0, R_BGP); + pal_write_dmg(8, 1, R_BGP); + pal_write_dmg(64, 2, R_OBP0); + pal_write_dmg(72, 3, R_OBP1); + } +// for (i = 0; i < 64; i++) +// updatepalette(i); +} + +void lcd_reset(void) +{ + memset(&lcd, 0, sizeof lcd); + lcd_begin(); + vram_dirty(); + pal_dirty(); +} + + + + + + + + + + + + + + + + |