changed sh/hi handling for Pirates! Gold

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@594 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-10-07 16:16:14 +00:00
parent 16b0afd029
commit 40644bfedd

View file

@ -10,12 +10,16 @@
* The renderer has 4 modes now: * The renderer has 4 modes now:
* - normal * - normal
* - shadow/hilight (s/h) * - shadow/hilight (s/h)
* - "sonic mode" for midline palette changes * - "sonic mode" for midline palette changes (8bit mode only)
* - accurate sprites (AS) * - accurate sprites (AS) [+ s/h]
* *
* AS and s/h both use upper bits for both priority and shadow/hilight flags. * AS and s/h both use upper bits for both priority and shadow/hilight flags.
* "sonic mode" is autodetected, shadow/hilight is enabled by emulated game. * "sonic mode" is autodetected, shadow/hilight is enabled by emulated game.
* AS is enabled by user and takes priority over "sonic mode". * AS is enabled by user and takes priority over "sonic mode".
*
* not handled properly:
* - hilight op on shadow tile
* - AS + s/h (s/h sprite flag interferes with and cleared by AS code)
*/ */
#include "pico_int.h" #include "pico_int.h"
@ -150,25 +154,25 @@ TileFlipMaker(TileFlip,pix_just_write)
// draw a sprite pixel, process operator colors // draw a sprite pixel, process operator colors
#define pix_sh(x) \ #define pix_sh(x) \
if (!t); \ if (!t); \
else if (t==0xe) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \ else if (t>=0xe) pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \
else if (t==0xf) pd[x]= pd[x] |0xc0; /* shadow */ \
else pd[x]=pal|t else pd[x]=pal|t
TileNormMaker(TileNormSH, pix_sh) TileNormMaker(TileNormSH, pix_sh)
TileFlipMaker(TileFlipSH, pix_sh) TileFlipMaker(TileFlipSH, pix_sh)
// draw a sprite pixel ignoring operator colors // draw a sprite pixel, mark operator colors
#define pix_sh_noop(x) \ #define pix_sh_markop(x) \
if (t && t < 0xe) \ if (!t); \
pd[x]=pal|t else if (t>=0xe) pd[x]|=0x80; \
else pd[x]=pal|t
TileNormMaker(TileNormSH_noop, pix_sh_noop) TileNormMaker(TileNormSH_markop, pix_sh_markop)
TileFlipMaker(TileFlipSH_noop, pix_sh_noop) TileFlipMaker(TileFlipSH_markop, pix_sh_markop)
// process operator pixels only, apply only on low pri tiles // process operator pixels only, apply only on low pri tiles and other op pixels
#define pix_sh_onlyop(x) \ #define pix_sh_onlyop(x) \
if (t==0xe && (pd[x]&0x40)) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \ if (t>=0xe && (pd[x]&0xc0)) \
else if (t==0xf && (pd[x]&0x40)) pd[x]= pd[x] |0xc0; /* shadow */ pd[x]=(pd[x]&0x3f)|(t<<6); /* c0 shadow, 80 hilight */ \
TileNormMaker(TileNormSH_onlyop_lp, pix_sh_onlyop) TileNormMaker(TileNormSH_onlyop_lp, pix_sh_onlyop)
TileFlipMaker(TileFlipSH_onlyop_lp, pix_sh_onlyop) TileFlipMaker(TileFlipSH_onlyop_lp, pix_sh_onlyop)
@ -524,12 +528,13 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
static void DrawTilesFromCacheShPrep(void) static void DrawTilesFromCacheShPrep(void)
{ {
// as some layer has covered whole line with hi priority tiles, // as some layer has covered whole line with hi priority tiles,
// we can process whole line and then act as if sh/hi mode was off. // we can process whole line and then act as if sh/hi mode was off,
// but leave lo pri op sprite markers alone
int c = 320/4, *zb = (int *)(HighCol+8); int c = 320/4, *zb = (int *)(HighCol+8);
rendstatus |= PDRAW_SHHI_DONE; rendstatus |= PDRAW_SHHI_DONE;
while (c--) while (c--)
{ {
*zb++ &= 0x3f3f3f3f; *zb++ &= 0xbfbfbfbf;
} }
} }
@ -576,8 +581,8 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim)
addr+=(unsigned int)code>>25; // y offset into tile addr+=(unsigned int)code>>25; // y offset into tile
dx=(code>>16)&0x1ff; dx=(code>>16)&0x1ff;
zb = HighCol+dx; zb = HighCol+dx;
*zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;
*zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf; *zb++ &= 0xbf;
pal=((code>>9)&0x30); pal=((code>>9)&0x30);
if (rlim-dx < 0) goto last_cut_tile; if (rlim-dx < 0) goto last_cut_tile;
@ -661,8 +666,8 @@ static void DrawSprite(int *sprite, int sh)
pal|=sh<<6; pal|=sh<<6;
if (sh && (code&0x6000) == 0x6000) { if (sh && (code&0x6000) == 0x6000) {
if(code&0x0800) fTileFunc=TileFlipSH_noop; if(code&0x0800) fTileFunc=TileFlipSH_markop;
else fTileFunc=TileNormSH_noop; else fTileFunc=TileNormSH_markop;
} else { } else {
if(code&0x0800) fTileFunc=TileFlip; if(code&0x0800) fTileFunc=TileFlip;
else fTileFunc=TileNorm; else fTileFunc=TileNorm;
@ -771,8 +776,13 @@ static void DrawAllSpritesInterlace(int pri, int sh)
#ifndef _ASM_DRAW_C #ifndef _ASM_DRAW_C
// Index + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size /*
// Index + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8 * s/h drawing: lo_layers|40, lo_sprites|40 && mark_op,
* hi_layers&=~40, hi_sprites
*
* Index + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size
* Index + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8
*/
static void DrawSpritesSHi(unsigned char *sprited) static void DrawSpritesSHi(unsigned char *sprited)
{ {
int (*fTileFunc)(int sx,int addr,int pal); int (*fTileFunc)(int sx,int addr,int pal);