X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2Fdraw.c;h=180045d26f736a53fafefd38542b324d8e8e8413;hb=3cf9570bacd8952713106a2a2e3176852d811d18;hp=b915514fdf1889b312d975ff094b5f349baf32d4;hpb=40644bfedd0b60d309dd23bc1e698ae3fa75375a;p=picodrive.git diff --git a/pico/draw.c b/pico/draw.c index b915514..180045d 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -17,6 +17,13 @@ * "sonic mode" is autodetected, shadow/hilight is enabled by emulated game. * AS is enabled by user and takes priority over "sonic mode". * + * since renderer always draws line in 8bit mode, there are 2 spare bits: + * b \ mode: s/h as sonic + * 00 normal - - + * 01 shadow - pal index + * 10 hilight+op spr spr pal index + * 11 shadow +op spr - pal index + * * not handled properly: * - hilight op on shadow tile * - AS + s/h (s/h sprite flag interferes with and cleared by AS code) @@ -33,7 +40,7 @@ unsigned char *HighCol=DefHighCol; #else unsigned char HighCol[8+320+8]; #endif -unsigned short DefOutBuff[320*2]; +static unsigned int DefOutBuff[320*2/2]; void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to static int HighCacheA[41+1]; // caches for high layers @@ -46,8 +53,8 @@ int HighPreSpr[80*2+1]; // slightly preprocessed sprites #define SPRL_LO_ABOVE_HI 0x10 // low priority sprites may be on top of hi unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]... -int rendstatus = 0; -int DrawScanline = 0; +int rendstatus, rendstatus_old; +int DrawScanline; int PicoDrawMask = -1; static int skip_next_line=0; @@ -67,13 +74,11 @@ struct TileStrip // stuff available in asm: #ifdef _ASM_DRAW_C void DrawWindow(int tstart, int tend, int prio, int sh); -void BackFill(int reg7, int sh); void DrawAllSprites(unsigned char *sprited, int prio, int sh); void DrawTilesFromCache(int *hc, int sh, int rlim); void DrawSpritesSHi(unsigned char *sprited); void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells); -void FinalizeLineBGR444(int sh); -void FinalizeLineRGB555(int sh); +void FinalizeLineBGR444(int sh, int line); void *blockcpy(void *dst, const void *src, size_t n); void blockcpy_or(void *dst, void *src, size_t n, int pat); #else @@ -505,8 +510,8 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache if (prio) { int *zb = (int *)(HighCol+8+(tilex<<3)); - *zb++ &= 0x3f3f3f3f; - *zb &= 0x3f3f3f3f; + *zb++ &= 0xbfbfbfbf; + *zb &= 0xbfbfbfbf; } else { pal |= 0x40; } @@ -925,10 +930,11 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) /* nasty 1: remove 'sprite' flags */ { - int c = 320/4, *zb = (int *)(HighCol+8); + int c = 320/4/4, *zb = (int *)(HighCol+8); while (c--) { - *zb++ &= 0x7f7f7f7f; + *zb++ &= 0x7f7f7f7f; *zb++ &= 0x7f7f7f7f; + *zb++ &= 0x7f7f7f7f; *zb++ &= 0x7f7f7f7f; } } @@ -1132,7 +1138,7 @@ static void DrawAllSprites(unsigned char *sprited, int prio, int sh) // -------------------------------------------- -static void BackFill(int reg7, int sh) +void BackFill(int reg7, int sh) { unsigned int back; @@ -1153,20 +1159,24 @@ unsigned short HighPal[0x100]; #ifndef _ASM_DRAW_C void PicoDoHighPal555(int sh) { + unsigned int *spal, *dpal; unsigned short *pal=HighPal; int i, t; Pico.m.dirtyPal = 0; - { - unsigned int *spal=(void *)Pico.cram; - unsigned int *dpal=(void *)HighPal; - for (i = 0x3f/2; i >= 0; i--) + spal = (void *)Pico.cram; + dpal = (void *)HighPal; + + for (i = 0; i < 0x40; i++) { + unsigned int t = spal[i]; #ifdef USE_BGR555 - dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4); + t = ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)<<4); #else - dpal[i] = ((spal[i]&0x000f000f)<<12)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)>>7); + t = ((t & 0x000e000e)<<12) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)>>7); #endif + t |= (t >> 3) & 0x18e318e3; + dpal[i] = t; } if (sh) @@ -1182,7 +1192,7 @@ void PicoDoHighPal555(int sh) } } -static void FinalizeLineBGR444(int sh) +static void FinalizeLineBGR444(int sh, int line) { unsigned short *pd=DrawLineDest; unsigned char *ps=HighCol+8; @@ -1220,7 +1230,7 @@ static void FinalizeLineBGR444(int sh) } -static void FinalizeLineRGB555(int sh) +void FinalizeLineRGB555(int sh, int line) { unsigned short *pd=DrawLineDest; unsigned char *ps=HighCol+8; @@ -1256,13 +1266,13 @@ static void FinalizeLineRGB555(int sh) } #endif -static void FinalizeLine8bit(int sh) +static void FinalizeLine8bit(int sh, int line) { - unsigned char *pd=DrawLineDest; + unsigned char *pd = DrawLineDest; int len, rs = rendstatus; static int dirty_count; - if (!sh && Pico.m.dirtyPal == 1 && DrawScanline < 222) + if (!sh && Pico.m.dirtyPal == 1) { // a hack for mid-frame palette changes if (!(rs & PDRAW_SONIC_MODE)) @@ -1280,7 +1290,8 @@ static void FinalizeLine8bit(int sh) if (Pico.video.reg[12]&1) { len = 320; } else { - if (!(PicoOpt&POPT_DIS_32C_BORDER)) pd+=32; + if (!(PicoOpt & POPT_DIS_32C_BORDER)) + pd += 32; len = 256; } @@ -1295,26 +1306,10 @@ static void FinalizeLine8bit(int sh) } } -static void (*FinalizeLine)(int sh) = FinalizeLineBGR444; +static void (*FinalizeLine)(int sh, int line); // -------------------------------------------- -static void DrawBlankedLine(void) -{ - int sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight? - - if (PicoScanBegin != NULL) - PicoScanBegin(DrawScanline); - - BackFill(Pico.video.reg[7], sh); - - if (FinalizeLine != NULL) - FinalizeLine(sh); - - if (PicoScanEnd != NULL) - PicoScanEnd(DrawScanline); -} - static int DrawDisplay(int sh) { unsigned char *sprited = &HighLnSpr[DrawScanline][0]; @@ -1413,58 +1408,101 @@ PICO_INTERNAL void PicoFrameStart(void) rendstatus = 0; if ((Pico.video.reg[12]&6) == 6) rendstatus |= PDRAW_INTERLACE; // interlace mode + if (Pico.video.reg[1] & 8) + rendstatus |= PDRAW_240LINES; - if (Pico.m.dirtyPal) Pico.m.dirtyPal = 2; // reset dirty if needed + DrawScanline = 0; + skip_next_line = 0; + + if (rendstatus != rendstatus_old) { + rendstatus_old = rendstatus; + emu_video_mode_change((rendstatus & PDRAW_240LINES) ? 0 : 8, + (rendstatus & PDRAW_240LINES) ? 240 : 224, + (Pico.video.reg[12] & 1) ? 0 : 1); + } - DrawScanline=0; + if (PicoOpt & POPT_ALT_RENDERER) + return; + + if (Pico.m.dirtyPal) + Pico.m.dirtyPal = 2; // reset dirty if needed PrepareSprites(1); - skip_next_line=0; } -static void PicoLine(void) +static void DrawBlankedLine(int line, int offs, int sh, int bgc) { - int sh; - if (skip_next_line>0) { skip_next_line--; return; } // skip rendering lines + if (PicoScanBegin != NULL) + PicoScanBegin(line + offs); + + BackFill(bgc, sh); - sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight? + if (FinalizeLine != NULL) + FinalizeLine(sh, line); + + if (PicoScanEnd != NULL) + PicoScanEnd(line + offs); +} +static void PicoLine(int line, int offs, int sh, int bgc) +{ + if (skip_next_line > 0) { + skip_next_line--; + return; + } + + DrawScanline = line; if (PicoScanBegin != NULL) - skip_next_line = PicoScanBegin(DrawScanline); + skip_next_line = PicoScanBegin(line + offs); // Draw screen: - BackFill(Pico.video.reg[7], sh); + BackFill(bgc, sh); if (Pico.video.reg[1]&0x40) DrawDisplay(sh); if (FinalizeLine != NULL) - FinalizeLine(sh); + FinalizeLine(sh, line); if (PicoScanEnd != NULL) - skip_next_line = PicoScanEnd(DrawScanline); + skip_next_line = PicoScanEnd(line + offs); } void PicoDrawSync(int to, int blank_last_line) { - for (; DrawScanline < to; DrawScanline++) + int line, offs = 0; + int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight? + int bgc = Pico.video.reg[7]; + + if (!(rendstatus & PDRAW_240LINES)) + 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 (DrawScanline >= 224) break; + if (line >= 224) break; #endif - PicoLine(); + PicoLine(line, offs, sh, bgc); } #if !CAN_HANDLE_240_LINES - if (DrawScanline >= 224) { DrawScanline = 240; return; } + if (line >= 224) { + DrawScanline = 240; + return; + } #endif // last line - if (DrawScanline <= to) + if (line <= to) { if (blank_last_line) - DrawBlankedLine(); - else PicoLine(); - DrawScanline++; + DrawBlankedLine(line, offs, sh, bgc); + else PicoLine(line, offs, sh, bgc); + line++; } + DrawScanline = line; } void PicoDrawSetColorFormat(int which) @@ -1472,12 +1510,14 @@ void PicoDrawSetColorFormat(int which) switch (which) { case 2: FinalizeLine = FinalizeLine8bit; break; - case 1: FinalizeLine = FinalizeLineRGB555; break; + case 1: FinalizeLine = (PicoAHW & PAHW_32X) ? FinalizeLine32xRGB555 : FinalizeLineRGB555; break; case 0: FinalizeLine = FinalizeLineBGR444; break; default:FinalizeLine = NULL; break; } + PicoDrawSetColorFormatMode4(which); #if OVERRIDE_HIGHCOL - if (which) HighCol=DefHighCol; + if (which) + HighCol=DefHighCol; #endif }