summaryrefslogtreecommitdiff
path: root/apps/plugins/rockboy/lcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockboy/lcd.c')
-rw-r--r--apps/plugins/rockboy/lcd.c956
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 0000000000..6351cb93ed
--- /dev/null
+++ b/apps/plugins/rockboy/lcd.c
@@ -0,0 +1,956 @@
1
2
3#include "config.h"
4#include "rockmacros.h"
5#include "defs.h"
6#include "regs.h"
7#include "hw.h"
8#include "mem.h"
9#include "lcd.h"
10#include "rc.h"
11#include "fb.h"
12#include "palette.h"
13#ifdef USE_ASM
14#include "asm.h"
15#endif
16
17struct lcd lcd;
18
19struct scan scan;
20
21#define BG (scan.bg)
22#define WND (scan.wnd)
23#define BUF (scan.buf[scanline_ind])
24#define PRI (scan.pri)
25
26#define PAL1 (scan.pal1)
27#define PAL2 (scan.pal2)
28#define PAL4 (scan.pal4)
29
30#define VS (scan.vs) /* vissprites */
31#define NS (scan.ns)
32
33#define L (scan.l) /* line */
34#define X (scan.x) /* screen position */
35#define Y (scan.y)
36#define S (scan.s) /* tilemap position */
37#define T (scan.t)
38#define U (scan.u) /* position within tile */
39#define V (scan.v)
40#define WX (scan.wx)
41#define WY (scan.wy)
42#define WT (scan.wt)
43#define WV (scan.wv)
44
45byte patpix[4096][8][8];
46byte patdirty[1024];
47byte anydirty;
48
49// static int scale = 1;
50
51static int rgb332;
52
53static int sprsort = 1;
54static int sprdebug;
55static int scanline_ind=0;
56
57#define DEF_PAL { 0x98d0e0, 0x68a0b0, 0x60707C, 0x2C3C3C }
58
59static int dmg_pal[4][4] = { DEF_PAL, DEF_PAL, DEF_PAL, DEF_PAL };
60
61static int usefilter, filterdmg;
62static int filter[3][4] = {
63 { 195, 25, 0, 35 },
64 { 25, 170, 25, 35 },
65 { 25, 60, 125, 40 }
66 };
67
68rcvar_t lcd_exports[] =
69 {
70 RCV_BOOL("rgb332", &rgb332),
71 RCV_VECTOR("dmg_bgp", dmg_pal[0], 4),
72 RCV_VECTOR("dmg_wndp", dmg_pal[1], 4),
73 RCV_VECTOR("dmg_obp0", dmg_pal[2], 4),
74 RCV_VECTOR("dmg_obp1", dmg_pal[3], 4),
75 RCV_BOOL("sprsort", &sprsort),
76 RCV_BOOL("sprdebug", &sprdebug),
77 RCV_BOOL("colorfilter", &usefilter),
78 RCV_BOOL("filterdmg", &filterdmg),
79 RCV_VECTOR("red", filter[0], 4),
80 RCV_VECTOR("green", filter[1], 4),
81 RCV_VECTOR("blue", filter[2], 4),
82 RCV_END
83 };
84
85static byte *vdest;
86
87#ifdef ALLOW_UNALIGNED_IO /* long long is ok since this is i386-only anyway? */
88#define MEMCPY8(d, s) ((*(long long *)(d)) = (*(long long *)(s)))
89#else
90#define MEMCPY8(d, s) memcpy((d), (s), 8)
91#endif
92
93
94
95
96#ifndef ASM_UPDATEPATPIX
97void updatepatpix(void)
98{
99 int i, j;
100#if CONFIG_CPU != SH7034 || defined(SIMULATOR)
101 int k, a, c;
102#endif
103 byte *vram = lcd.vbank[0];
104
105 if (!anydirty) return;
106 for (i = 0; i < 1024; i++)
107 {
108 if (i == 384) i = 512;
109 if (i == 896) break;
110 if (!patdirty[i]) continue;
111 patdirty[i] = 0;
112 for (j = 0; j < 8; j++)
113 {
114#if CONFIG_CPU == SH7034 && !defined(SIMULATOR)
115 asm volatile (
116 "mov.w @%2,r1 \n"
117 "swap.b r1,r2 \n"
118
119 "mov #0,r0 \n"
120 "shlr r1 \n"
121 "rotcl r0 \n"
122 "shlr r2 \n"
123 "rotcl r0 \n"
124 "mov.b r0,@%0 \n"
125 "mov.b r0,@(7,%1) \n"
126 "mov #0,r0 \n"
127 "shlr r1 \n"
128 "rotcl r0 \n"
129 "shlr r2 \n"
130 "rotcl r0 \n"
131 "mov.b r0,@(1,%0) \n"
132 "mov.b r0,@(6,%1) \n"
133 "mov #0,r0 \n"
134 "shlr r1 \n"
135 "rotcl r0 \n"
136 "shlr r2 \n"
137 "rotcl r0 \n"
138 "mov.b r0,@(2,%0) \n"
139 "mov.b r0,@(5,%1) \n"
140 "mov #0,r0 \n"
141 "shlr r1 \n"
142 "rotcl r0 \n"
143 "shlr r2 \n"
144 "rotcl r0 \n"
145 "mov.b r0,@(3,%0) \n"
146 "mov.b r0,@(4,%1) \n"
147 "mov #0,r0 \n"
148 "shlr r1 \n"
149 "rotcl r0 \n"
150 "shlr r2 \n"
151 "rotcl r0 \n"
152 "mov.b r0,@(4,%0) \n"
153 "mov.b r0,@(3,%1) \n"
154 "mov #0,r0 \n"
155 "shlr r1 \n"
156 "rotcl r0 \n"
157 "shlr r2 \n"
158 "rotcl r0 \n"
159 "mov.b r0,@(5,%0) \n"
160 "mov.b r0,@(2,%1) \n"
161 "mov #0,r0 \n"
162 "shlr r1 \n"
163 "rotcl r0 \n"
164 "shlr r2 \n"
165 "rotcl r0 \n"
166 "mov.b r0,@(6,%0) \n"
167 "mov.b r0,@(1,%1) \n"
168 "mov #0,r0 \n"
169 "shlr r1 \n"
170 "rotcl r0 \n"
171 "shlr r2 \n"
172 "rotcl r0 \n"
173 "mov.b r0,@(7,%0) \n"
174 "mov.b r0,@%1 \n"
175 : /* outputs */
176 : /* inputs */
177 /* %0 */ "r"(patpix[i+1024][j]),
178 /* %1 */ "r"(patpix[i][j]),
179 /* %2 */ "r"(&vram[(i<<4)|(j<<1)])
180 : /* clobbers */
181 "r0", "r1", "r2"
182 );
183#else
184 a = ((i<<4) | (j<<1));
185 for (k = 0; k < 8; k++)
186 {
187 c = vram[a] & (1<<k) ? 1 : 0;
188 c |= vram[a+1] & (1<<k) ? 2 : 0;
189 patpix[i+1024][j][k] = c;
190 }
191 for (k = 0; k < 8; k++)
192 patpix[i][j][k] =
193 patpix[i+1024][j][7-k];
194#endif
195 }
196#if CONFIG_CPU == SH7034 && !defined(SIMULATOR)
197 asm volatile (
198 "mov.l @%0,r0 \n"
199 "mov.l @(4,%0),r1 \n"
200 "mov.l r0,@(56,%1) \n"
201 "mov.l r1,@(60,%1) \n"
202 "mov.l @(8,%0),r0 \n"
203 "mov.l @(12,%0),r1 \n"
204 "mov.l r0,@(48,%1) \n"
205 "mov.l r1,@(52,%1) \n"
206 "mov.l @(16,%0),r0 \n"
207 "mov.l @(20,%0),r1 \n"
208 "mov.l r0,@(40,%1) \n"
209 "mov.l r1,@(44,%1) \n"
210 "mov.l @(24,%0),r0 \n"
211 "mov.l @(28,%0),r1 \n"
212 "mov.l r0,@(32,%1) \n"
213 "mov.l r1,@(36,%1) \n"
214 "mov.l @(32,%0),r0 \n"
215 "mov.l @(36,%0),r1 \n"
216 "mov.l r0,@(24,%1) \n"
217 "mov.l r1,@(28,%1) \n"
218 "mov.l @(40,%0),r0 \n"
219 "mov.l @(44,%0),r1 \n"
220 "mov.l r0,@(16,%1) \n"
221 "mov.l r1,@(20,%1) \n"
222 "mov.l @(48,%0),r0 \n"
223 "mov.l @(52,%0),r1 \n"
224 "mov.l r0,@(8,%1) \n"
225 "mov.l r1,@(12,%1) \n"
226 "mov.l @(56,%0),r0 \n"
227 "mov.l @(60,%0),r1 \n"
228 "mov.l r0,@%1 \n"
229 "mov.l r1,@(4,%1) \n"
230
231 "add %2,%0 \n"
232 "add %2,%1 \n"
233
234 "mov.l @%0,r0 \n"
235 "mov.l @(4,%0),r1 \n"
236 "mov.l r0,@(56,%1) \n"
237 "mov.l r1,@(60,%1) \n"
238 "mov.l @(8,%0),r0 \n"
239 "mov.l @(12,%0),r1 \n"
240 "mov.l r0,@(48,%1) \n"
241 "mov.l r1,@(52,%1) \n"
242 "mov.l @(16,%0),r0 \n"
243 "mov.l @(20,%0),r1 \n"
244 "mov.l r0,@(40,%1) \n"
245 "mov.l r1,@(44,%1) \n"
246 "mov.l @(24,%0),r0 \n"
247 "mov.l @(28,%0),r1 \n"
248 "mov.l r0,@(32,%1) \n"
249 "mov.l r1,@(36,%1) \n"
250 "mov.l @(32,%0),r0 \n"
251 "mov.l @(36,%0),r1 \n"
252 "mov.l r0,@(24,%1) \n"
253 "mov.l r1,@(28,%1) \n"
254 "mov.l @(40,%0),r0 \n"
255 "mov.l @(44,%0),r1 \n"
256 "mov.l r0,@(16,%1) \n"
257 "mov.l r1,@(20,%1) \n"
258 "mov.l @(48,%0),r0 \n"
259 "mov.l @(52,%0),r1 \n"
260 "mov.l r0,@(8,%1) \n"
261 "mov.l r1,@(12,%1) \n"
262 "mov.l @(56,%0),r0 \n"
263 "mov.l @(60,%0),r1 \n"
264 "mov.l r0,@%1 \n"
265 "mov.l r1,@(4,%1) \n"
266 : /* outputs */
267 : /* inputs */
268 /* %0 */ "r"(patpix[i][0]),
269 /* %1 */ "r"(patpix[i+2048][0]),
270 /* %2 */ "r"(1024*64)
271 : /* clobbers */
272 "r0", "r1"
273 );
274#else
275 for (j = 0; j < 8; j++)
276 {
277 for (k = 0; k < 8; k++)
278 {
279 patpix[i+2048][j][k] =
280 patpix[i][7-j][k];
281 patpix[i+3072][j][k] =
282 patpix[i+1024][7-j][k];
283 }
284 }
285#endif
286 }
287 anydirty = 0;
288}
289#endif /* ASM_UPDATEPATPIX */
290
291
292
293void tilebuf(void)
294{
295 int i, cnt;
296 int base;
297 byte *tilemap, *attrmap;
298 int *tilebuf;
299 int *wrap;
300 static int wraptable[64] =
301 {
302 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
303 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,-32
304 };
305
306 base = ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5) + S;
307 tilemap = lcd.vbank[0] + base;
308 attrmap = lcd.vbank[1] + base;
309 tilebuf = BG;
310 wrap = wraptable + S;
311 cnt = ((WX + 7) >> 3) + 1;
312
313 if (hw.cgb) {
314 if (R_LCDC & 0x10)
315 for (i = cnt; i > 0; i--)
316 {
317 *(tilebuf++) = *tilemap
318 | (((int)*attrmap & 0x08) << 6)
319 | (((int)*attrmap & 0x60) << 5);
320 *(tilebuf++) = (((int)*attrmap & 0x07) << 2);
321 attrmap += *wrap + 1;
322 tilemap += *(wrap++) + 1;
323 }
324 else
325 for (i = cnt; i > 0; i--)
326 {
327 *(tilebuf++) = (256 + ((n8)*tilemap))
328 | (((int)*attrmap & 0x08) << 6)
329 | (((int)*attrmap & 0x60) << 5);
330 *(tilebuf++) = (((int)*attrmap & 0x07) << 2);
331 attrmap += *wrap + 1;
332 tilemap += *(wrap++) + 1;
333 }
334 }
335 else
336 {
337 if (R_LCDC & 0x10)
338 for (i = cnt; i > 0; i--)
339 {
340 *(tilebuf++) = *(tilemap++);
341 tilemap += *(wrap++);
342 }
343 else
344 for (i = cnt; i > 0; i--)
345 {
346 *(tilebuf++) = (256 + ((n8)*(tilemap++)));
347 tilemap += *(wrap++);
348 }
349 }
350
351 if (WX >= 160) return;
352
353 base = ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5);
354 tilemap = lcd.vbank[0] + base;
355 attrmap = lcd.vbank[1] + base;
356 tilebuf = WND;
357 cnt = ((160 - WX) >> 3) + 1;
358
359 if (hw.cgb)
360 {
361 if (R_LCDC & 0x10)
362 for (i = cnt; i > 0; i--)
363 {
364 *(tilebuf++) = *(tilemap++)
365 | (((int)*attrmap & 0x08) << 6)
366 | (((int)*attrmap & 0x60) << 5);
367 *(tilebuf++) = (((int)*(attrmap++)&7) << 2);
368 }
369 else
370 for (i = cnt; i > 0; i--)
371 {
372 *(tilebuf++) = (256 + ((n8)*(tilemap++)))
373 | (((int)*attrmap & 0x08) << 6)
374 | (((int)*attrmap & 0x60) << 5);
375 *(tilebuf++) = (((int)*(attrmap++)&7) << 2);
376 }
377 }
378 else
379
380 {
381 if (R_LCDC & 0x10)
382 for (i = cnt; i > 0; i--)
383 *(tilebuf++) = *(tilemap++);
384 else
385 for (i = cnt; i > 0; i--)
386 *(tilebuf++) = (256 + ((n8)*(tilemap++)));
387 }
388}
389
390
391// V = vertical line
392// WX = WND start (if 0, no need to do anything) -> WY
393// U = start...something...thingy... 7 at most
394void bg_scan(void)
395{
396 int cnt;
397 byte *src, *dest;
398 int *tile;
399
400 if (WX <= 0) return;
401 cnt = WX;
402 tile = BG;
403 dest = BUF;
404
405 src = patpix[*(tile++)][V] + U;
406 memcpy(dest, src, 8-U);
407 dest += 8-U;
408 cnt -= 8-U;
409 if (cnt <= 0) return;
410 while (cnt >= 8)
411 {
412 src = patpix[*(tile++)][V];
413 MEMCPY8(dest, src);
414 dest += 8;
415 cnt -= 8;
416 }
417 src = patpix[*tile][V];
418 while (cnt--)
419 *(dest++) = *(src++);
420}
421
422void wnd_scan(void)
423{
424 int cnt;
425 byte *src, *dest;
426 int *tile;
427
428 if (WX >= 160) return;
429 cnt = 160 - WX;
430 tile = WND;
431 dest = BUF + WX;
432
433 while (cnt >= 8)
434 {
435 src = patpix[*(tile++)][WV];
436 MEMCPY8(dest, src);
437 dest += 8;
438 cnt -= 8;
439 }
440 src = patpix[*tile][WV];
441 while (cnt--)
442 *(dest++) = *(src++);
443}
444
445static void blendcpy(byte *dest, byte *src, byte b, int cnt)
446{
447 while (cnt--) *(dest++) = *(src++) | b;
448}
449
450static int priused(void *attr)
451{
452 un32 *a = attr;
453 return (int)((a[0]|a[1]|a[2]|a[3]|a[4]|a[5]|a[6]|a[7])&0x80808080);
454}
455
456void bg_scan_pri(void)
457{
458 int cnt, i;
459 byte *src, *dest;
460
461 if (WX <= 0) return;
462 i = S;
463 cnt = WX;
464 dest = PRI;
465 src = lcd.vbank[1] + ((R_LCDC&0x08)?0x1C00:0x1800) + (T<<5);
466
467 if (!priused(src))
468 {
469 memset(dest, 0, cnt);
470 return;
471 }
472
473 memset(dest, src[i++&31]&128, 8-U);
474 dest += 8-U;
475 cnt -= 8-U;
476 if (cnt <= 0) return;
477 while (cnt >= 8)
478 {
479 memset(dest, src[i++&31]&128, 8);
480 dest += 8;
481 cnt -= 8;
482 }
483 memset(dest, src[i&31]&128, cnt);
484}
485
486void wnd_scan_pri(void)
487{
488 int cnt, i;
489 byte *src, *dest;
490
491 if (WX >= 160) return;
492 i = 0;
493 cnt = 160 - WX;
494 dest = PRI + WX;
495 src = lcd.vbank[1] + ((R_LCDC&0x40)?0x1C00:0x1800) + (WT<<5);
496
497 if (!priused(src))
498 {
499 memset(dest, 0, cnt);
500 return;
501 }
502
503 while (cnt >= 8)
504 {
505 memset(dest, src[i++]&128, 8);
506 dest += 8;
507 cnt -= 8;
508 }
509 memset(dest, src[i]&128, cnt);
510}
511
512void bg_scan_color(void)
513{
514 int cnt;
515 byte *src, *dest;
516 int *tile;
517
518 if (WX <= 0) return;
519 cnt = WX;
520 tile = BG;
521 dest = BUF;
522
523 src = patpix[*(tile++)][V] + U;
524 blendcpy(dest, src, *(tile++), 8-U);
525 dest += 8-U;
526 cnt -= 8-U;
527 if (cnt <= 0) return;
528 while (cnt >= 8)
529 {
530 src = patpix[*(tile++)][V];
531 blendcpy(dest, src, *(tile++), 8);
532 dest += 8;
533 cnt -= 8;
534 }
535 src = patpix[*(tile++)][V];
536 blendcpy(dest, src, *(tile++), cnt);
537}
538
539// blend in window source WND target BUF
540// WX = starting X in buf where WND starts
541// WV = vertical line selected for this scanline
542// reverse:
543// WY = starting y in buf where WND starts ?
544// W?? = horizontal line selected for this scanline
545void wnd_scan_color(void)
546{
547 int cnt;
548 byte *src, *dest;
549 int *tile;
550
551 if (WX >= 160) return;
552 cnt = 160 - WX;
553 tile = WND;
554 dest = BUF + WX;
555
556 while (cnt >= 8)
557 {
558 src = patpix[*(tile++)][WV];
559 blendcpy(dest, src, *(tile++), 8);
560 dest += 8;
561 cnt -= 8;
562 }
563 src = patpix[*(tile++)][WV];
564 blendcpy(dest, src, *(tile++), cnt);
565}
566
567static void recolor(byte *buf, byte fill, int cnt)
568{
569 while (cnt--) *(buf++) |= fill;
570}
571
572void spr_count(void)
573{
574 int i;
575 struct obj *o;
576
577 NS = 0;
578 if (!(R_LCDC & 0x02)) return;
579
580 o = lcd.oam.obj;
581
582 for (i = 40; i; i--, o++)
583 {
584 if (L >= o->y || L + 16 < o->y)
585 continue;
586 if (L + 8 >= o->y && !(R_LCDC & 0x04))
587 continue;
588 if (++NS == 10) break;
589 }
590}
591
592void spr_enum(void)
593{
594 int i, j;
595 struct obj *o;
596 struct vissprite ts[10];
597 int v, pat;
598 int l, x;
599
600 NS = 0;
601 if (!(R_LCDC & 0x02)) return;
602
603 o = lcd.oam.obj;
604
605 for (i = 40; i; i--, o++)
606 {
607 if (L >= o->y || L + 16 < o->y)
608 continue;
609 if (L + 8 >= o->y && !(R_LCDC & 0x04))
610 continue;
611 VS[NS].x = (int)o->x - 8;
612 v = L - (int)o->y + 16;
613 if (hw.cgb)
614 {
615 pat = o->pat | (((int)o->flags & 0x60) << 5)
616 | (((int)o->flags & 0x08) << 6);
617 VS[NS].pal = 32 + ((o->flags & 0x07) << 2);
618 }
619 else
620 {
621 pat = o->pat | (((int)o->flags & 0x60) << 5);
622 VS[NS].pal = 32 + ((o->flags & 0x10) >> 2);
623 }
624 VS[NS].pri = (o->flags & 0x80) >> 7;
625 if ((R_LCDC & 0x04))
626 {
627 pat &= ~1;
628 if (v >= 8)
629 {
630 v -= 8;
631 pat++;
632 }
633 if (o->flags & 0x40) pat ^= 1;
634 }
635 VS[NS].buf = patpix[pat][v];
636 if (++NS == 10) break;
637 }
638 if (!sprsort||hw.cgb) return;
639 /* not quite optimal but it finally works! */
640 for (i = 0; i < NS; i++)
641 {
642 l = 0;
643 x = VS[0].x;
644 for (j = 1; j < NS; j++)
645 {
646 if (VS[j].x < x)
647 {
648 l = j;
649 x = VS[j].x;
650 }
651 }
652 ts[i] = VS[l];
653 VS[l].x = 160;
654 }
655 memcpy(VS, ts, sizeof VS);
656}
657
658void spr_scan(void)
659{
660 int i, x;
661 byte pal, b, ns = NS;
662 byte *src, *dest, *bg, *pri;
663 struct vissprite *vs;
664 static byte bgdup[256];
665
666 if (!ns) return;
667
668 memcpy(bgdup, BUF, 256);
669 vs = &VS[ns-1];
670
671 for (; ns; ns--, vs--)
672 {
673 x = vs->x;
674 if (x >= 160) continue;
675 if (x <= -8) continue;
676 if (x < 0)
677 {
678 src = vs->buf - x;
679 dest = BUF;
680 i = 8 + x;
681 }
682 else
683 {
684 src = vs->buf;
685 dest = BUF + x;
686 if (x > 152) i = 160 - x;
687 else i = 8;
688 }
689 pal = vs->pal;
690 if (vs->pri)
691 {
692 bg = bgdup + (dest - BUF);
693 while (i--)
694 {
695 b = src[i];
696 if (b && !(bg[i]&3)) dest[i] = pal|b;
697 }
698 }
699 else if (hw.cgb)
700 {
701 bg = bgdup + (dest - BUF);
702 pri = PRI + (dest - BUF);
703 while (i--)
704 {
705 b = src[i];
706 if (b && (!pri[i] || !(bg[i]&3)))
707 dest[i] = pal|b;
708 }
709 }
710 else while (i--) if (src[i]) dest[i] = pal|src[i];
711 /* else while (i--) if (src[i]) dest[i] = 31 + ns; */
712 }
713// if (sprdebug) for (i = 0; i < NS; i++) BUF[i<<1] = 36;
714}
715
716
717
718
719
720
721void lcd_begin(void)
722{
723/* if (fb.indexed)
724 {
725 if (rgb332) pal_set332();
726 else pal_expire();
727 }
728 while (scale * 160 > fb.w || scale * 144 > fb.h) scale--; */
729 vdest = fb.ptr + ((fb.w*fb.pelsize)>>1)
730 - (80*fb.pelsize)
731 + ((fb.h>>1) - 72) * fb.pitch;
732 WY = R_WY;
733}
734
735void lcd_refreshline(void)
736{
737 if (!fb.enabled) return;
738
739 if (!(R_LCDC & 0x80))
740 return; /* should not happen... */
741
742#if LCD_HEIGHT == 64
743 if (R_LY >= 128 || R_LY & 1) /* calculate only even lines */
744#else
745 if (R_LY >= 128)
746#endif
747 return;
748
749 updatepatpix();
750
751 L = R_LY;
752#if LCD_HEIGHT == 64
753 scanline_ind = (L/2) % 8;
754#else
755 scanline_ind = L % 8;
756#endif
757 X = R_SCX;
758 Y = (R_SCY + L) & 0xff;
759 S = X >> 3;
760 T = Y >> 3;
761 U = X & 7;
762 V = Y & 7;
763
764 WX = R_WX - 7;
765 if (WY>L || WY<0 || WY>143 || WX<-7 || WX>159 || !(R_LCDC&0x20))
766 WX = 160;
767 WT = (L - WY) >> 3;
768 WV = (L - WY) & 7;
769
770 spr_enum();
771
772 tilebuf();
773 if (hw.cgb)
774 {
775 bg_scan_color();
776 wnd_scan_color();
777 if (NS)
778 {
779 bg_scan_pri();
780 wnd_scan_pri();
781 }
782 }
783 else
784 {
785
786 bg_scan();
787 wnd_scan();
788 recolor(BUF+WX, 0x04, 160-WX);
789 }
790 spr_scan();
791/*
792 if (fb.dirty) memset(fb.ptr, 0, fb.pitch * fb.h);
793 fb.dirty = 0;
794 if (density > scale) density = scale;
795 if (scale == 1) density = 1;
796 dest = vdest;
797*/
798 if (scanline_ind == 7)
799 vid_update(L);
800 // vdest += fb.pitch * scale;
801}
802
803
804
805
806
807
808/*
809static void updatepalette(int i)
810{
811 int c, r, g, b, y, u, v, rr, gg;
812
813 c = (lcd.pal[i<<1] | ((int)lcd.pal[(i<<1)|1] << 8)) & 0x7FFF;
814 r = (c & 0x001F) << 3;
815 g = (c & 0x03E0) >> 2;
816 b = (c & 0x7C00) >> 7;
817 r |= (r >> 5);
818 g |= (g >> 5);
819 b |= (b >> 5);
820
821 if (usefilter && (filterdmg||hw.cgb))
822 {
823 rr = ((r * filter[0][0] + g * filter[0][1] + b * filter[0][2]) >> 8) + filter[0][3];
824 gg = ((r * filter[1][0] + g * filter[1][1] + b * filter[1][2]) >> 8) + filter[1][3];
825 b = ((r * filter[2][0] + g * filter[2][1] + b * filter[2][2]) >> 8) + filter[2][3];
826 r = rr;
827 g = gg;
828 }
829
830 if (fb.yuv)
831 {
832 y = (((r * 263) + (g * 516) + (b * 100)) >> 10) + 16;
833 u = (((r * 450) - (g * 377) - (b * 73)) >> 10) + 128;
834 v = (((r * -152) - (g * 298) + (b * 450)) >> 10) + 128;
835 if (y < 0) y = 0; if (y > 255) y = 255;
836 if (u < 0) u = 0; if (u > 255) u = 255;
837 if (v < 0) v = 0; if (v > 255) v = 255;
838 PAL4[i] = (y<<fb.cc[0].l) | (y<<fb.cc[3].l)
839 | (u<<fb.cc[1].l) | (v<<fb.cc[2].l);
840 return;
841 }
842
843 if (fb.indexed)
844 {
845 pal_release(PAL1[i]);
846 c = pal_getcolor(c, r, g, b);
847 PAL1[i] = c;
848 PAL2[i] = (c<<8) | c;
849 PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
850 return;
851 }
852
853 r = (r >> fb.cc[0].r) << fb.cc[0].l;
854 g = (g >> fb.cc[1].r) << fb.cc[1].l;
855 b = (b >> fb.cc[2].r) << fb.cc[2].l;
856 c = r|g|b;
857
858 switch (fb.pelsize)
859 {
860 case 1:
861 PAL1[i] = c;
862 PAL2[i] = (c<<8) | c;
863 PAL4[i] = (c<<24) | (c<<16) | (c<<8) | c;
864 break;
865 case 2:
866 PAL2[i] = c;
867 PAL4[i] = (c<<16) | c;
868 break;
869 case 3:
870 case 4:
871 PAL4[i] = c;
872 break;
873 }
874}*/
875
876void pal_write(int i, byte b)
877{
878 if (lcd.pal[i] == b) return;
879 lcd.pal[i] = b;
880// updatepalette(i>>1);
881}
882
883void pal_write_dmg(int i, int mapnum, byte d)
884{
885 int j;
886 int *cmap = dmg_pal[mapnum];
887 int c, r, g, b;
888
889 if (hw.cgb) return;
890
891 /* if (mapnum >= 2) d = 0xe4; */
892 for (j = 0; j < 8; j += 2)
893 {
894 c = cmap[(d >> j) & 3];
895 r = (c & 0xf8) >> 3;
896 g = (c & 0xf800) >> 6;
897 b = (c & 0xf80000) >> 9;
898 c = r|g|b;
899 /* FIXME - handle directly without faking cgb */
900 pal_write(i+j, c & 0xff);
901 pal_write(i+j+1, c >> 8);
902 }
903}
904
905void vram_write(int a, byte b)
906{
907 lcd.vbank[R_VBK&1][a] = b;
908 if (a >= 0x1800) return;
909 patdirty[((R_VBK&1)<<9)+(a>>4)] = 1;
910 anydirty = 1;
911}
912
913void vram_dirty(void)
914{
915 anydirty = 1;
916 memset(patdirty, 1, sizeof patdirty);
917}
918
919void pal_dirty(void)
920{
921// int i;
922 if (!hw.cgb)
923 {
924
925 pal_write_dmg(0, 0, R_BGP);
926 pal_write_dmg(8, 1, R_BGP);
927 pal_write_dmg(64, 2, R_OBP0);
928 pal_write_dmg(72, 3, R_OBP1);
929 }
930// for (i = 0; i < 64; i++)
931// updatepalette(i);
932}
933
934void lcd_reset(void)
935{
936 memset(&lcd, 0, sizeof lcd);
937 lcd_begin();
938 vram_dirty();
939 pal_dirty();
940}
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956