static void DrawLayer(int plane_sh, u32 *hcache, int cellskip, int maxcells,\r
struct PicoEState *est)\r
{\r
- struct PicoVideo *pvid=&Pico.video;\r
+ struct PicoVideo *pvid=&est->Pico->video;\r
const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
struct TileStrip ts;\r
int width, height, ymask;\r
static void DrawWindow(int tstart, int tend, int prio, int sh,\r
struct PicoEState *est)\r
{\r
- unsigned char *pd = Pico.est.HighCol;\r
- struct PicoVideo *pvid = &Pico.video;\r
+ unsigned char *pd = est->HighCol;\r
+ struct PicoVideo *pvid = &est->Pico->video;\r
int tilex,ty,nametab,code=0;\r
int blank=-1; // The tile we know is blank\r
\r
\r
static void DrawTilesFromCache(u32 *hc, int sh, int rlim, struct PicoEState *est)\r
{\r
- unsigned char *pd = Pico.est.HighCol;\r
+ unsigned char *pd = est->HighCol;\r
u32 code, dx;\r
u32 pack;\r
int pal;\r
struct PicoVideo *pvid=&Pico.video;\r
int i,u,table,link=0,sline=Pico.est.DrawScanline<<1;\r
u32 *sprites[80]; // Sprite index\r
- int max_sprites = Pico.video.reg[12]&1 ? 80 : 64;\r
+ int max_sprites = pvid->reg[12]&1 ? 80 : 64;\r
\r
table=pvid->reg[5]&0x7f;\r
if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode\r
static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,\r
struct PicoEState *est)\r
{\r
- struct PicoVideo *pvid=&Pico.video;\r
+ struct PicoVideo *pvid=&est->Pico->video;\r
const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid)\r
struct TileStrip ts;\r
int width, height, ymask;\r
// Sprite parsing 1 line in advance: determine sprites on line by Y pos\r
static NOINLINE void ParseSprites(int max_lines, int limit)\r
{\r
- const struct PicoVideo *pvid=&Pico.video;\r
const struct PicoEState *est=&Pico.est;\r
+ const struct PicoVideo *pvid=&est->Pico->video;\r
int u,link=0,sh;\r
int table=0;\r
s32 *pd = HighPreSpr + HighPreSprBank*2;\r
// line are limited if display was disabled during HBLANK before current line\r
if (limit) limit = 16; // max sprites/pixels processed\r
\r
- if (!(Pico.video.reg[12]&1))\r
+ if (!(pvid->reg[12]&1))\r
max_sprites = 64, max_line_sprites = 16, max_width = 264;\r
if (*est->PicoOpt & POPT_DIS_SPRITE_LIM)\r
max_line_sprites = MAX_LINE_SPRITES;\r
\r
- sh = Pico.video.reg[0xC]&8; // shadow/hilight?\r
+ sh = pvid->reg[0xC]&8; // shadow/hilight?\r
\r
table=pvid->reg[5]&0x7f;\r
if (pvid->reg[12]&1) table&=0x7e; // Lowest bit 0 in 40-cell mode\r
unsigned int t, i;\r
\r
// reset dirty only if there are no outstanding changes\r
- if (Pico.m.dirtyPal == 2)\r
- Pico.m.dirtyPal = 0;\r
+ if (est->Pico->m.dirtyPal == 2)\r
+ est->Pico->m.dirtyPal = 0;\r
\r
// In Sonic render mode palettes were backuped in SonicPal\r
spal = (void *)est->SonicPal;\r
unsigned int *spal, *dpal;\r
unsigned int t, i;\r
\r
- Pico.m.dirtyPal = 0;\r
+ est->Pico->m.dirtyPal = 0;\r
\r
spal = (void *)PicoMem.cram;\r
dpal = (void *)est->HighPal;\r
PicoDrawUpdateHighPal();\r
\r
len = 256;\r
- if (!(PicoIn.AHW & PAHW_8BIT) && (Pico.video.reg[12]&1))\r
+ if (!(PicoIn.AHW & PAHW_8BIT) && (est->Pico->video.reg[12]&1))\r
len = 320;\r
- else if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
+ else if ((PicoIn.AHW & PAHW_GG) && (est->Pico->m.hardware & PMS_HW_LCD))\r
len = 160;\r
- else if ((PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[0] & 0x20))\r
+ else if ((PicoIn.AHW & PAHW_SMS) && (est->Pico->video.reg[0] & 0x20))\r
len -= 8, ps += 8;\r
\r
- if ((*est->PicoOpt & POPT_EN_SOFTSCALE) && len < 320) {\r
+ if ((est->rendstatus & PDRAW_SOFTSCALE) && len < 320) {\r
if (len >= 240 && len <= 256) {\r
pd += (256-len)>>1;\r
switch (PicoIn.filter) {\r
default: h_upscale_nn_1_2(pd, 320, ps, 160, len, f_pal); break;\r
}\r
} else {\r
- if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)\r
+ if ((est->rendstatus & PDRAW_BORDER_32) && len < 320)\r
pd += (320-len) / 2;\r
#if 1\r
h_copy(pd, 320, ps, 320, len, f_pal);\r
static int dirty_line;\r
\r
// a hack for mid-frame palette changes\r
- if (Pico.m.dirtyPal == 1)\r
+ if (est->Pico->m.dirtyPal == 1)\r
{\r
// store a maximum of 3 additional palettes in SonicPal\r
if (est->SonicPalCount < 3 &&\r
est->rendstatus |= PDRAW_SONIC_MODE;\r
}\r
blockcpy(est->SonicPal+est->SonicPalCount*0x40, PicoMem.cram, 0x40*2);\r
- Pico.m.dirtyPal = 2;\r
+ est->Pico->m.dirtyPal = 2;\r
}\r
\r
len = 256;\r
- if (!(PicoIn.AHW & PAHW_8BIT) && (Pico.video.reg[12]&1))\r
+ if (!(PicoIn.AHW & PAHW_8BIT) && (est->Pico->video.reg[12]&1))\r
len = 320;\r
- else if ((PicoIn.AHW & PAHW_GG) && (Pico.m.hardware & PMS_HW_LCD))\r
+ else if ((PicoIn.AHW & PAHW_GG) && (est->Pico->m.hardware & PMS_HW_LCD))\r
len = 160;\r
- else if ((PicoIn.AHW & PAHW_SMS) && (Pico.video.reg[0] & 0x20))\r
+ else if ((PicoIn.AHW & PAHW_SMS) && (est->Pico->video.reg[0] & 0x20))\r
len -= 8, ps += 8;\r
\r
if (DrawLineDestIncrement == 0)\r
pd = est->HighCol+8;\r
\r
- if ((PicoIn.opt & POPT_EN_SOFTSCALE) && len < 320) {\r
+ if ((est->rendstatus & PDRAW_SOFTSCALE) && len < 320) {\r
unsigned char pal = 0;\r
\r
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))\r
else\r
rh_upscale_nn_1_2(pd, 320, ps, 256, len, f_or);\r
} else {\r
- if (!(*est->PicoOpt & POPT_DIS_32C_BORDER) && len < 320)\r
+ if ((est->rendstatus & PDRAW_BORDER_32) && len < 320)\r
pd += (320-len) / 2;\r
if (!sh && (est->rendstatus & PDRAW_SONIC_MODE))\r
// select active backup palette\r
{\r
struct PicoEState *est=&Pico.est;\r
unsigned char *sprited = &HighLnSpr[est->DrawScanline][0];\r
- struct PicoVideo *pvid=&Pico.video;\r
+ struct PicoVideo *pvid=&est->Pico->video;\r
int win=0, edge=0, hvwind=0, lflags;\r
int maxw, maxcells;\r
\r
else if (est->rendstatus & PDRAW_INTERLACE)\r
DrawAllSpritesInterlace(1, sh);\r
// have sprites without layer pri bit ontop of sprites with that bit\r
- else if ((sprited[1] & SPRL_LO_ABOVE_HI) && (PicoIn.opt & POPT_ACC_SPRITES))\r
+ else if ((sprited[1] & SPRL_LO_ABOVE_HI) && (*est->PicoOpt & POPT_ACC_SPRITES))\r
DrawSpritesHiAS(sprited, sh);\r
else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP))\r
DrawSpritesSHi(sprited, est);\r
\r
// prepare to do this frame\r
est->rendstatus = 0;\r
- if ((Pico.video.reg[12] & 6) == 6)\r
+\r
+ if ((PicoIn.AHW & PAHW_32X) && (*est->PicoOpt & POPT_ALT_RENDERER))\r
+ est->rendstatus |= PDRAW_BORDER_32; // no scaling for fastest\r
+ else if (PicoIn.AHW & PAHW_32X) // H32 upscaling, before mixing in 32X layer\r
+ est->rendstatus |= PDRAW_32X_SCALE|PDRAW_SOFTSCALE;\r
+ else if (PicoIn.opt & POPT_EN_SOFTSCALE)\r
+ est->rendstatus |= PDRAW_SOFTSCALE;\r
+ else if (!(PicoIn.opt & POPT_DIS_32C_BORDER))\r
+ est->rendstatus |= PDRAW_BORDER_32;\r
+\r
+ if ((est->Pico->video.reg[12] & 6) == 6)\r
est->rendstatus |= PDRAW_INTERLACE; // interlace mode\r
- if (!(Pico.video.reg[12] & 1)) {\r
+ if (!(est->Pico->video.reg[12] & 1)) {\r
est->rendstatus |= PDRAW_32_COLS;\r
- if (!(PicoIn.opt & POPT_EN_SOFTSCALE)) {\r
+ if (est->rendstatus & PDRAW_BORDER_32) {\r
columns = 256;\r
coffs = 32;\r
}\r
}\r
- if (Pico.video.reg[1] & 8) {\r
+ if (est->Pico->video.reg[1] & 8) {\r
est->rendstatus |= PDRAW_30_ROWS;\r
lines = 240;\r
loffs = 0;\r
}\r
- if (PicoIn.opt & POPT_DIS_32C_BORDER)\r
+ if (!(est->rendstatus & PDRAW_BORDER_32))\r
coffs = 0;\r
\r
if (est->rendstatus != rendstatus_old || lines != rendlines) {\r
est->rendstatus |= PDRAW_SKIP_FRAME;\r
if (sprep | skipped)\r
est->rendstatus |= PDRAW_PARSE_SPRITES;\r
- if (PicoIn.AHW & PAHW_32X)\r
- est->rendstatus |= PDRAW_32X_SCALE;\r
\r
est->HighCol = HighColBase + loffs * HighColIncrement;\r
est->DrawLineDest = (char *)DrawLineDestBase + loffs * DrawLineDestIncrement;\r
\r
if (FinalizeLine == FinalizeLine8bit) {\r
// make a backup of the current palette in case Sonic mode is detected later\r
- Pico.m.dirtyPal = (Pico.m.dirtyPal || est->SonicPalCount ? 2 : 0);\r
+ est->Pico->m.dirtyPal = (est->Pico->m.dirtyPal || est->SonicPalCount ? 2 : 0);\r
blockcpy(est->SonicPal, PicoMem.cram, 0x40*2);\r
}\r
est->SonicPalCount = 0;\r
return;\r
}\r
\r
- if (Pico.video.debug_p & (PVD_FORCE_A | PVD_FORCE_B | PVD_FORCE_S))\r
+ if (est->Pico->video.debug_p & (PVD_FORCE_A | PVD_FORCE_B | PVD_FORCE_S))\r
bgc = 0x3f;\r
\r
// Draw screen:\r
BackFill(bgc, sh, est);\r
- if (Pico.video.reg[1]&0x40) {\r
- int width = (Pico.video.reg[12]&1) ? 320 : 256;\r
+ if (est->Pico->video.reg[1]&0x40) {\r
+ int width = (est->Pico->video.reg[12]&1) ? 320 : 256;\r
DrawDisplay(sh);\r
// partial line blanking (display on or off inside the line)\r
if (unlikely(off|on)) {\r
{\r
struct PicoEState *est = &Pico.est;\r
int line, offs = 0;\r
- int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
- int bgc = Pico.video.reg[7] & 0x3f;\r
+ int sh = (est->Pico->video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+ int bgc = est->Pico->video.reg[7] & 0x3f;\r
\r
pprof_start(draw);\r
\r
// last line\r
if (line <= to)\r
{\r
- int width2 = (Pico.video.reg[12]&1) ? 160 : 128;\r
+ int width2 = (est->Pico->video.reg[12]&1) ? 160 : 128;\r
\r
// technically, VDP starts active display output at slot 12\r
if (unlikely(on|off) && (off >= width2 ||\r
void PicoDrawUpdateHighPal(void)\r
{\r
struct PicoEState *est = &Pico.est;\r
- if (Pico.m.dirtyPal) {\r
- int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
- if ((PicoIn.opt & POPT_ALT_RENDERER) | (est->rendstatus & PDRAW_SONIC_MODE))\r
+ if (est->Pico->m.dirtyPal) {\r
+ int sh = (est->Pico->video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+ if ((*est->PicoOpt & POPT_ALT_RENDERER) | (est->rendstatus & PDRAW_SONIC_MODE))\r
sh = 0; // no s/h support\r
\r
if (PicoIn.AHW & PAHW_SMS)\r
.equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
.equ PDRAW_PLANE_HI_PRIO, (1<<6)\r
.equ PDRAW_SHHI_DONE, (1<<7)\r
+.equ PDRAW_BORDER_32, (1<<9)\r
.equ PDRAW_32X_SCALE, (1<<12)\r
+.equ PDRAW_SOFTSCALE, (1<<15)\r
\r
@ helpers\r
.macro add_c24 d s c\r
ldr r5, [r11, #OFS_EST_PicoOpt]\r
ldr r1, [r11, #OFS_EST_HighCol]\r
ldr r0, [r11, #OFS_EST_DrawLineDest]\r
- ldr r4, [r5]\r
+ ldr r4, [r11, #OFS_EST_rendstatus]\r
ldr r7, [r5, #OFS_PicoIn_AHW-OFS_PicoIn_opt]\r
ldrb r12,[r8, #OFS_Pico_video_reg+12]\r
ldrb r6, [r8, #OFS_Pico_video_reg+0]\r
\r
.fl_gg20col:\r
mov r2, #160/8 @ len = 160\r
- tst r4, #0x4000 @ EN_SOFTSCALE?\r
+ tst r4, #PDRAW_SOFTSCALE\r
bne .fl_20scale_RGB555 @ scale 160->320\r
b .fl_checkborder\r
\r
mov r2, #256/8 @ len = 256\r
\r
.fl_check32scaling:\r
- tst r4, #0x4000 @ EN_SOFTSCALE?\r
+ tst r4, #PDRAW_SOFTSCALE\r
rsbne r7, r2, #256/8\r
addne r0, r0, r7, lsl #3 @ pd += (256-len)>>1\r
bne .fl_32scale_RGB555 @ scale 256->320\r
\r
.fl_checkborder:\r
- tst r4, #0x0100 @ DIS_32C_BORDER?\r
- rsbeq r7, r2, #320/8 @ pd += (320-len)/2\r
- addeq r0, r0, r7, lsl #3\r
+ tst r4, #PDRAW_BORDER_32\r
+ rsbne r7, r2, #320/8 @ pd += (320-len)/2\r
+ addne r0, r0, r7, lsl #3\r
\r
.fl_40colRGB555:\r
#ifdef UNALIGNED_DRAWLINEDEST\r