X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2Fdraw.c;h=ca9a140b00e24375a8cd4f9f2b7ecc26913ea93c;hb=bc38f4d24fcdbbefbda10ef023c0ffbab4b208b8;hp=712e86100878ae0fa63500fc377e93ebadcb7a7d;hpb=205bc4565ca1db7e2983f8fae2daa28a9a20d3cf;p=picodrive.git diff --git a/pico/draw.c b/pico/draw.c index 712e861..ca9a140 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -1,11 +1,11 @@ -// This is part of Pico Library - -// (c) Copyright 2004 Dave, All rights reserved. -// (c) Copyright 2006-2008 notaz, All rights reserved. -// Free for non-commercial use. - -// For commercial use, separate licencing terms must be obtained. - +/* + * line renderer + * (c) Copyright Dave, 2004 + * (C) notaz, 2006-2010 + * + * This work is licensed under the terms of MAME license. + * See COPYING file in the top-level directory. + */ /* * The renderer has 4 modes now: * - normal @@ -19,7 +19,7 @@ * * since renderer always draws line in 8bit mode, there are 2 spare bits: * b \ mode: s/h as sonic - * 00 normal - - + * 00 normal - pal index * 01 shadow - pal index * 10 hilight+op spr spr pal index * 11 shadow +op spr - pal index @@ -34,14 +34,15 @@ int (*PicoScanBegin)(unsigned int num) = NULL; int (*PicoScanEnd) (unsigned int num) = NULL; -#if OVERRIDE_HIGHCOL static unsigned char DefHighCol[8+320+8]; -unsigned char *HighCol=DefHighCol; -#else -unsigned char HighCol[8+320+8]; -#endif +unsigned char *HighCol = DefHighCol; +static unsigned char *HighColBase = DefHighCol; +static int HighColIncrement; + static unsigned int DefOutBuff[320*2/2]; -void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to +void *DrawLineDest = DefOutBuff; // pointer to dest buffer where to draw this line to +void *DrawLineDestBase = DefOutBuff; +int DrawLineDestIncrement; static int HighCacheA[41+1]; // caches for high layers static int HighCacheB[41+1]; @@ -1161,77 +1162,42 @@ unsigned short HighPal[0x100]; void PicoDoHighPal555(int sh) { unsigned int *spal, *dpal; - unsigned short *pal=HighPal; - int i, t; + unsigned int t, i; Pico.m.dirtyPal = 0; spal = (void *)Pico.cram; dpal = (void *)HighPal; - for (i = 0; i < 0x40; i++) { - unsigned int t = spal[i]; + for (i = 0; i < 0x40 / 2; i++) { + t = spal[i]; #ifdef USE_BGR555 t = ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)<<4); #else t = ((t & 0x000e000e)<<12) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)>>7); #endif - t |= (t >> 3) & 0x18e318e3; + // treat it like it was 4-bit per channel, since in s/h mode it somewhat is that. + // otherwise intensity difference between this and s/h will be wrong + t |= (t >> 4) & 0x08610861; // 0x18e318e3 dpal[i] = t; } + // norm: xxx0, sh: 0xxx, hi: 0xxx + 7 if (sh) { // shadowed pixels - for (i = 0x3f; i >= 0; i--) - pal[0x40|i] = pal[0xc0|i] = (unsigned short)((pal[i]>>1)&0x738e); + for (i = 0; i < 0x40 / 2; i++) + dpal[0x40/2 | i] = dpal[0xc0/2 | i] = (dpal[i] >> 1) & 0x738e738e; // hilighted pixels - for (i = 0x3f; i >= 0; i--) { - t=pal[i]&0xe71c;t+=0x4208;if(t&0x20)t|=0x1c;if(t&0x800)t|=0x700;if(t&0x10000)t|=0xe000;t&=0xe71c; - pal[0x80|i]=(unsigned short)t; - } - } -} - -static void FinalizeLineBGR444(int sh, int line) -{ - unsigned short *pd=DrawLineDest; - unsigned char *ps=HighCol+8; - unsigned short *pal=Pico.cram; - int len, i, t, mask=0xff; - - if (Pico.video.reg[12]&1) { - len = 320; - } else { - if(!(PicoOpt&POPT_DIS_32C_BORDER)) pd+=32; - len = 256; - } - - if(sh) { - pal=HighPal; - if(Pico.m.dirtyPal) { - blockcpy(pal, Pico.cram, 0x40*2); - // shadowed pixels - for(i = 0x3f; i >= 0; i--) - pal[0x40|i] = pal[0xc0|i] = (unsigned short)((pal[i]>>1)&0x0777); - // hilighted pixels - for(i = 0x3f; i >= 0; i--) { - t=pal[i]&0xeee;t+=0x444;if(t&0x10)t|=0xe;if(t&0x100)t|=0xe0;if(t&0x1000)t|=0xe00;t&=0xeee; - pal[0x80|i]=(unsigned short)t; - } - Pico.m.dirtyPal = 0; + for (i = 0; i < 0x40 / 2; i++) { + t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e; // 0x7bef7bef; + t |= (t >> 4) & 0x08610861; + dpal[0x80/2 | i] = t; } } - - if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) - mask=0x3f; // accurate sprites - - for(i = 0; i < len; i++) - pd[i] = pal[ps[i] & mask]; } - -void FinalizeLineRGB555(int sh, int line) +void FinalizeLine555(int sh, int line) { unsigned short *pd=DrawLineDest; unsigned char *ps=HighCol+8; @@ -1405,7 +1371,7 @@ static int DrawDisplay(int sh) // MUST be called every frame PICO_INTERNAL void PicoFrameStart(void) { - int lines = 224; + int offs = 8, lines = 224; // prepare to do this frame rendstatus = 0; @@ -1413,19 +1379,24 @@ PICO_INTERNAL void PicoFrameStart(void) rendstatus |= PDRAW_INTERLACE; // interlace mode if (!(Pico.video.reg[12] & 1)) rendstatus |= PDRAW_32_COLS; - if (Pico.video.reg[1] & 8) + if (Pico.video.reg[1] & 8) { + offs = 0; lines = 240; - - DrawScanline = 0; - skip_next_line = 0; + } if (rendstatus != rendstatus_old || lines != rendlines) { rendlines = lines; - rendstatus_old = rendstatus; + // mode_change() might reset rendstatus_old by calling SetColorFormat emu_video_mode_change((lines == 240) ? 0 : 8, lines, (Pico.video.reg[12] & 1) ? 0 : 1); + rendstatus_old = rendstatus; } + HighCol = HighColBase + offs * HighColIncrement; + DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement; + DrawScanline = 0; + skip_next_line = 0; + if (PicoOpt & POPT_ALT_RENDERER) return; @@ -1446,6 +1417,9 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc) if (PicoScanEnd != NULL) PicoScanEnd(line + offs); + + HighCol += HighColIncrement; + DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement; } static void PicoLine(int line, int offs, int sh, int bgc) @@ -1476,6 +1450,9 @@ static void PicoLine(int line, int offs, int sh, int bgc) if (PicoScanEnd != NULL) skip_next_line = PicoScanEnd(line + offs); + + HighCol += HighColIncrement; + DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement; } void PicoDrawSync(int to, int blank_last_line) @@ -1484,28 +1461,16 @@ void PicoDrawSync(int to, int blank_last_line) int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight? int bgc = Pico.video.reg[7]; + pprof_start(draw); + if (rendlines != 240) offs = 8; - // need to know which pixels are bg for 32x - if (PicoAHW & PAHW_32X) - bgc = 0; - for (line = DrawScanline; line < to; line++) { -#if !CAN_HANDLE_240_LINES - if (line >= 224) break; -#endif PicoLine(line, offs, sh, bgc); } -#if !CAN_HANDLE_240_LINES - if (line >= 224) { - DrawScanline = 240; - return; - } -#endif - // last line if (line <= to) { @@ -1515,22 +1480,83 @@ void PicoDrawSync(int to, int blank_last_line) line++; } DrawScanline = line; + + pprof_end(draw); } -void PicoDrawSetColorFormat(int which) +// also works for fast renderer +void PicoDrawUpdateHighPal(void) +{ + int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight? + if (PicoOpt & POPT_ALT_RENDERER) + sh = 0; // no s/h support + + PicoDoHighPal555(sh); + if (rendstatus & PDRAW_SONIC_MODE) { + // FIXME? + memcpy(HighPal + 0x40, HighPal, 0x40*2); + memcpy(HighPal + 0x80, HighPal, 0x40*2); + } +} + +void PicoDrawSetOutFormat(pdso_t which, int use_32x_line_mode) { switch (which) { - case 2: FinalizeLine = FinalizeLine8bit; break; - case 1: FinalizeLine = (PicoAHW & PAHW_32X) ? FinalizeLine32xRGB555 : FinalizeLineRGB555; break; - case 0: FinalizeLine = FinalizeLineBGR444; break; - default:FinalizeLine = NULL; break; + case PDF_8BIT: + FinalizeLine = FinalizeLine8bit; + break; + + case PDF_RGB555: + if ((PicoAHW & PAHW_32X) && use_32x_line_mode) + FinalizeLine = FinalizeLine32xRGB555; + else + FinalizeLine = FinalizeLine555; + break; + + default: + FinalizeLine = NULL; + break; } - PicoDrawSetColorFormatMode4(which); + PicoDrawSetOutFormat32x(which, use_32x_line_mode); + PicoDrawSetOutputMode4(which); rendstatus_old = -1; -#if OVERRIDE_HIGHCOL - if (which) - HighCol=DefHighCol; -#endif } +// note: may be called on the middle of frame +void PicoDrawSetOutBuf(void *dest, int increment) +{ + DrawLineDestBase = dest; + DrawLineDestIncrement = increment; + DrawLineDest = DrawLineDestBase + DrawScanline * increment; +} + +void PicoDrawSetInternalBuf(void *dest, int increment) +{ + if (dest != NULL) { + HighColBase = dest; + HighColIncrement = increment; + HighCol = HighColBase + DrawScanline * increment; + } + else { + HighColBase = DefHighCol; + HighColIncrement = 0; + } +} + +void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned int num)) +{ + PicoScanBegin = NULL; + PicoScanEnd = NULL; + PicoScan32xBegin = NULL; + PicoScan32xEnd = NULL; + + if ((PicoAHW & PAHW_32X) && FinalizeLine != FinalizeLine32xRGB555) { + PicoScan32xBegin = begin; + PicoScan32xEnd = end; + } + else { + PicoScanBegin = begin; + PicoScanEnd = end; + } +}