int (*PicoScan32xEnd)(unsigned int num);
int Pico32xDrawMode;
+void *DrawLineDestBase32x;
+int DrawLineDestIncrement32x;
+
static void convert_pal555(int invert_prio)
{
unsigned int *ps = (void *)Pico32xMem->pal;
int lines_sft_offs;
int which_func;
- Pico.est.DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;
+ Pico.est.DrawLineDest = (char *)DrawLineDestBase32x + offs * DrawLineDestIncrement32x;
dram = Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
- if (Pico32xDrawMode == PDM32X_BOTH) {
- if (Pico.m.dirtyPal)
- PicoDrawUpdateHighPal();
- }
+ if (Pico32xDrawMode == PDM32X_BOTH)
+ PicoDrawUpdateHighPal();
if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 2)
{
void PicoDraw32xLayerMdOnly(int offs, int lines)
{
int have_scan = PicoScan32xBegin != NULL && PicoScan32xEnd != NULL;
- unsigned short *dst = (void *)((char *)DrawLineDestBase + offs * DrawLineDestIncrement);
+ unsigned short *dst = (void *)((char *)DrawLineDestBase32x + offs * DrawLineDestIncrement32x);
unsigned char *pmd = Pico.est.Draw2FB + 328 * offs + 8;
unsigned short *pal = Pico.est.HighPal;
int poffs = 0, plen = 320;
int l, p;
if (!(Pico.video.reg[12] & 1)) {
- // 32col mode
+ // 32col mode. for some render modes MD pixel data carries an offset
+ if (!(PicoIn.opt & (POPT_ALT_RENDERER|POPT_DIS_32C_BORDER)))
+ pmd += 32;
poffs = 32;
plen = 256;
}
- if (Pico.m.dirtyPal)
- PicoDrawUpdateHighPal();
+ PicoDrawUpdateHighPal();
dst += poffs;
for (l = 0; l < lines; l++) {
dst[p + 2] = pal[*pmd++];
dst[p + 3] = pal[*pmd++];
}
- dst = (void *)((char *)dst + DrawLineDestIncrement);
+ dst = (void *)((char *)dst + DrawLineDestIncrement32x);
pmd += 328 - plen;
if (have_scan)
PicoScan32xEnd(l + offs);
Pico32xNativePal = Pico32xMem->pal_native;
#endif
- if (which == PDF_RGB555 && use_32x_line_mode) {
- // we'll draw via FinalizeLine32xRGB555 (rare)
+ if (which == PDF_RGB555) {
+ // need CLUT pixels in PicoDraw2FB for layer transparency
+ PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328);
+ PicoDrawSetOutBufMD(DrawLineDestBase32x, DrawLineDestIncrement32x);
+ } else {
+ // use the same layout as alt renderer
PicoDrawSetInternalBuf(NULL, 0);
- Pico32xDrawMode = PDM32X_OFF;
- return;
+ PicoDrawSetOutBufMD(Pico.est.Draw2FB + 8, 328);
}
- // use the same layout as alt renderer
- PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328);
- Pico32xDrawMode = (which == PDF_RGB555) ? PDM32X_32X_ONLY : PDM32X_BOTH;
+ if (use_32x_line_mode)
+ // we'll draw via FinalizeLine32xRGB555 (rare)
+ Pico32xDrawMode = PDM32X_OFF;
+ else
+ // in RGB555 mode the 32x layer is drawn over the MD layer, in the other
+ // modes 32x and MD layer are merged together by the 32x renderer
+ Pico32xDrawMode = (which == PDF_RGB555) ? PDM32X_32X_ONLY : PDM32X_BOTH;
+}
+
+void PicoDrawSetOutBuf32X(void *dest, int increment)
+{
+ DrawLineDestBase32x = dest;
+ DrawLineDestIncrement32x = increment;
+ // in RGB555 mode this buffer is also used by the MD renderer
+ if (Pico32xDrawMode != PDM32X_BOTH)
+ PicoDrawSetOutBufMD(DrawLineDestBase32x, DrawLineDestIncrement32x);
}
// vim:shiftwidth=2:ts=2:expandtab
\r
// --------------------------------------------\r
\r
+void PicoDoHighPal555_8bit(int sh, int line, struct PicoEState *est)\r
+{\r
+ unsigned int *spal, *dpal;\r
+ unsigned int cnt = (sh ? 1 : est->SonicPalCount+1);\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
+\r
+ // In Sonic render mode palettes were backuped in SonicPal\r
+ spal = (void *)est->SonicPal;\r
+ dpal = (void *)est->HighPal;\r
+\r
+ // additional palettes stored after in-frame changes\r
+ for (i = 0; i < cnt * 0x40 / 2; i++) {\r
+ t = spal[i];\r
+#ifdef USE_BGR555\r
+ t = ((t & 0x000e000e)<< 1) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)<<4);\r
+#else\r
+ t = ((t & 0x000e000e)<<12) | ((t & 0x00e000e0)<<3) | ((t & 0x0e000e00)>>7);\r
+#endif\r
+ // treat it like it was 4-bit per channel, since in s/h mode it somewhat is that.\r
+ // otherwise intensity difference between this and s/h will be wrong\r
+ t |= (t >> 4) & 0x08610861; // 0x18e318e3\r
+ dpal[i] = t;\r
+ }\r
+\r
+ // norm: xxx0, sh: 0xxx, hi: 0xxx + 7\r
+ if (sh)\r
+ {\r
+ // shadowed pixels\r
+ for (i = 0; i < 0x40 / 2; i++)\r
+ dpal[0x40/2 | i] = dpal[0xc0/2 | i] = (dpal[i] >> 1) & 0x738e738e;\r
+ // hilighted pixels\r
+ for (i = 0; i < 0x40 / 2; i++) {\r
+ t = ((dpal[i] >> 1) & 0x738e738e) + 0x738e738e; // 0x7bef7bef;\r
+ t |= (t >> 4) & 0x08610861;\r
+ dpal[0x80/2 | i] = t;\r
+ }\r
+ }\r
+}\r
+\r
#ifndef _ASM_DRAW_C\r
void PicoDoHighPal555(int sh, int line, struct PicoEState *est)\r
{\r
unsigned short *pal=est->HighPal;\r
int len;\r
\r
- if (Pico.m.dirtyPal)\r
- PicoDoHighPal555(sh, line, est);\r
+ PicoDrawUpdateHighPal();\r
\r
if (Pico.video.reg[12]&1) {\r
len = 320;\r
static void FinalizeLine8bit(int sh, int line, struct PicoEState *est)\r
{\r
unsigned char *pd = est->DrawLineDest;\r
- int len, rs = est->rendstatus;\r
- static int dirty_count;\r
+ int len;\r
+ static int dirty_line;\r
\r
- if (!sh && Pico.m.dirtyPal == 1)\r
+ if (Pico.m.dirtyPal == 1)\r
{\r
// a hack for mid-frame palette changes\r
- if (!(rs & PDRAW_SONIC_MODE))\r
- dirty_count = 1;\r
- else dirty_count++;\r
- rs |= PDRAW_SONIC_MODE;\r
- est->rendstatus = rs;\r
- if (dirty_count == 3) {\r
- blockcpy(est->HighPal, PicoMem.cram, 0x40*2);\r
- } else if (dirty_count == 11) {\r
- blockcpy(est->HighPal+0x40, PicoMem.cram, 0x40*2);\r
+ if (!(est->rendstatus & PDRAW_SONIC_MODE) || line - dirty_line > 4) {\r
+ // store a maximum of 3 additional palettes in SonicPal\r
+ if (est->SonicPalCount < 3)\r
+ est->SonicPalCount ++;\r
+ dirty_line = line;\r
+ est->rendstatus |= PDRAW_SONIC_MODE;\r
}\r
+ blockcpy(est->SonicPal+est->SonicPalCount*0x40, PicoMem.cram, 0x40*2);\r
+ Pico.m.dirtyPal = 2;\r
}\r
\r
if (Pico.video.reg[12]&1) {\r
len = 256;\r
}\r
\r
- if (!sh && (rs & PDRAW_SONIC_MODE)) {\r
- if (dirty_count >= 11) {\r
- blockcpy_or(pd, est->HighCol+8, len, 0x80);\r
- } else {\r
- blockcpy_or(pd, est->HighCol+8, len, 0x40);\r
- }\r
+ if (!sh && (est->rendstatus & PDRAW_SONIC_MODE)) {\r
+ // select active backup palette\r
+ blockcpy_or(pd, est->HighCol+8, len, est->SonicPalCount*0x40);\r
} else {\r
blockcpy(pd, est->HighCol+8, len);\r
}\r
PICO_INTERNAL void PicoFrameStart(void)\r
{\r
int offs = 8, lines = 224;\r
+ int dirty = ((Pico.est.rendstatus & PDRAW_SONIC_MODE) || Pico.m.dirtyPal);\r
\r
// prepare to do this frame\r
Pico.est.rendstatus = 0;\r
Pico.est.DrawScanline = 0;\r
skip_next_line = 0;\r
\r
+ if (FinalizeLine == FinalizeLine8bit) {\r
+ // make a backup of the current palette in case Sonic mode is detected later\r
+ Pico.est.SonicPalCount = 0;\r
+ Pico.m.dirtyPal = (dirty ? 2 : 0); // mark as dirty but already copied\r
+ blockcpy(Pico.est.SonicPal, PicoMem.cram, 0x40*2);\r
+ }\r
+\r
if (PicoIn.opt & POPT_ALT_RENDERER)\r
return;\r
\r
- if (Pico.m.dirtyPal)\r
- Pico.m.dirtyPal = 2; // reset dirty if needed\r
PrepareSprites(1);\r
}\r
\r
void PicoDrawUpdateHighPal(void)\r
{\r
struct PicoEState *est = &Pico.est;\r
- int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
- if (PicoIn.opt & POPT_ALT_RENDERER)\r
- sh = 0; // no s/h support\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
+ sh = 0; // no s/h support\r
+\r
+ if (FinalizeLine == FinalizeLine8bit)\r
+ PicoDoHighPal555_8bit(sh, 0, est);\r
+ else\r
+ PicoDoHighPal555(sh, 0, est);\r
\r
- PicoDoHighPal555(sh, 0, &Pico.est);\r
- if (est->rendstatus & PDRAW_SONIC_MODE) {\r
- // FIXME?\r
- memcpy(est->HighPal + 0x40, est->HighPal, 0x40*2);\r
- memcpy(est->HighPal + 0x80, est->HighPal, 0x40*2);\r
+ // cover for sprite priority bits if not in s/h or sonic mode\r
+ if (!sh && !(est->rendstatus & PDRAW_SONIC_MODE)) {\r
+ blockcpy(est->HighPal+0x40, est->HighPal, 0x40*2);\r
+ blockcpy(est->HighPal+0x80, est->HighPal, 0x80*2);\r
+ }\r
}\r
}\r
\r
FinalizeLine = NULL;\r
break;\r
}\r
- PicoDrawSetOutFormat32x(which, use_32x_line_mode);\r
+ if (PicoIn.AHW & PAHW_32X)\r
+ PicoDrawSetOutFormat32x(which, use_32x_line_mode);\r
PicoDrawSetOutputMode4(which);\r
rendstatus_old = -1;\r
}\r
\r
+void PicoDrawSetOutBufMD(void *dest, int increment)\r
+{\r
+ if (dest != NULL) {\r
+ DrawLineDestBase = dest;\r
+ DrawLineDestIncrement = increment;\r
+ Pico.est.DrawLineDest = DrawLineDestBase + Pico.est.DrawScanline * increment;\r
+ }\r
+ else {\r
+ DrawLineDestBase = DefOutBuff;\r
+ DrawLineDestIncrement = 0;\r
+ Pico.est.DrawLineDest = DefOutBuff;\r
+ }\r
+}\r
+\r
// note: may be called on the middle of frame\r
void PicoDrawSetOutBuf(void *dest, int increment)\r
{\r
- DrawLineDestBase = dest;\r
- DrawLineDestIncrement = increment;\r
- Pico.est.DrawLineDest = (char *)DrawLineDestBase + Pico.est.DrawScanline * increment;\r
+ if (PicoIn.AHW & PAHW_32X)\r
+ PicoDrawSetOutBuf32X(dest, increment);\r
+ else\r
+ PicoDrawSetOutBufMD(dest, increment);\r
}\r
\r
void PicoDrawSetInternalBuf(void *dest, int increment)\r
else {\r
HighColBase = DefHighCol;\r
HighColIncrement = 0;\r
+ Pico.est.HighCol = DefHighCol;\r
}\r
}\r
\r
PicoDoHighPal555:\r
stmfd sp!, {r4-r10,lr}\r
mov r10,r2 @ est\r
- mov r1, #0\r
ldr r8, [r10, #OFS_EST_Pico]\r
\r
-PicoDoHighPal555_nopush:\r
- orr r9, r1, r0, lsl #31 @ 0:called from FinalizeLine555, 31: s/h\r
+ mov r9, r0\r
\r
add r0, r10, #OFS_EST_HighPal\r
\r
\r
vidConvCpyRGB565_local\r
\r
- tst r9, #(1<<31)\r
+ cmp r9, #0\r
beq PicoDoHighPal555_end\r
\r
add r3, r10, #OFS_EST_HighPal\r
mov r0, #1\r
\r
PicoDoHighPal555_end:\r
- tst r9, #1\r
- ldmeqfd sp!, {r4-r10,pc}\r
-\r
- ldr r8, [r10, #OFS_EST_Pico]\r
- b FinalizeLineRGB555_pal_done\r
+ ldmfd sp!, {r4-r10,pc}\r
\r
\r
@ void FinalizeLine555(int sh, int line, struct PicoEState *est)\r
mov r10,r2 @ est\r
ldr r8, [r10, #OFS_EST_Pico]\r
\r
- ldrb r2, [r8, #OFS_Pico_m_dirtyPal]\r
- mov r1, #1\r
- tst r2, r2\r
- bne PicoDoHighPal555_nopush\r
+ bl PicoDrawUpdateHighPal\r
\r
-FinalizeLineRGB555_pal_done:\r
add r3, r10, #OFS_EST_HighPal\r
\r
- ldr r12, [r10, #OFS_EST_rendstatus]\r
- eors r0, r0, #1 @ sh is 0\r
mov lr, #0xff\r
- tstne r12,#PDRAW_ACC_SPRITES\r
- movne lr, #0x3f\r
\r
ldr r1, [r10, #OFS_EST_HighCol]\r
ldr r0, [r10, #OFS_EST_DrawLineDest]\r
unsigned int *PicoOpt;\r
unsigned char *Draw2FB;\r
unsigned short HighPal[0x100];\r
+ unsigned short SonicPal[0x100];\r
+ int SonicPalCount;\r
};\r
\r
struct PicoMem\r
\r
// 32x/draw.c\r
void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode);\r
+void PicoDrawSetOutBuf32X(void *dest, int increment);\r
void FinalizeLine32xRGB555(int sh, int line, struct PicoEState *est);\r
void PicoDraw32xLayer(int offs, int lines, int mdbg);\r
void PicoDraw32xLayerMdOnly(int offs, int lines);\r
if (a - ((unsigned)(Pico.video.reg[5]&0x7f) << 9) < 0x400)\r
Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES;\r
break;\r
- case 3: Pico.m.dirtyPal = 1;\r
+ case 3: if (PicoMem.cram [(a >> 1) & 0x3f] != d) Pico.m.dirtyPal = 1;\r
PicoMem.cram [(a >> 1) & 0x3f] = d; break;\r
case 5: PicoMem.vsram[(a >> 1) & 0x3f] = d; break;\r
case 0x81:\r
break;\r
case 0x0c:\r
// renderers should update their palettes if sh/hi mode is changed\r
- if ((d^dold)&8) Pico.m.dirtyPal = 2;\r
+ if ((d^dold)&8) Pico.m.dirtyPal = 1;\r
break;\r
}\r
return;\r
endif
ifeq "$(asm_32xdraw)" "1"
DEFINES += _ASM_32X_DRAW
-SRCS_COMMON += $(R)pico/32x/draw_arm.s
+SRCS_COMMON += $(R)pico/32x/draw_arm.S
endif
ifeq "$(asm_mix)" "1"
SRCS_COMMON += $(R)pico/sound/mix_arm.S
{\r
notice_msg_time = 0;\r
plat_status_msg_clear();\r
+#ifndef __GP2X__\r
plat_video_flip();\r
plat_status_msg_clear(); /* Do it again in case of double buffering */\r
+#endif\r
notice_msg = NULL;\r
}\r
else {\r
}
// a hack for VR
if (PicoIn.AHW & PAHW_SVP)
- memset32((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328);
+ memset((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328*4);
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
if (currentConfig.EmuOpt&0x4000)
lines_flags|=0x40000; // (Pico.m.frame_count&1)?0x20000:0x40000;
int lines_flags;
// 8bit accurate renderer
if (Pico.m.dirtyPal) {
- Pico.m.dirtyPal = 0;
- vidConvCpyRGB565(localPal, Pico.cram, 0x40);
+ if (Pico.m.dirtyPal == 2)
+ Pico.m.dirtyPal = 0;
+ /* no support
+ switch (Pico.est.SonicPalCount) {
+ case 3: vidConvCpyRGB565(localPal+0xc0, Pico.est.SonicPal+0xc0, 0x40);
+ case 2: vidConvCpyRGB565(localPal+0x80, Pico.est.SonicPal+0x80, 0x40);
+ case 1: vidConvCpyRGB565(localPal+0x40, Pico.est.SonicPal+0x40, 0x40);
+ default://vidConvCpyRGB565(localPal, Pico.est.SonicPal, 0x40);
+ } */
+ vidConvCpyRGB565(localPal, Pico.est.SonicPal, 0x40);
if (Pico.video.reg[0xC]&8) { // shadow/hilight mode
- //vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40);
- //vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); // TODO?
- memcpy32((void *)(localPal+0xc0), (void *)(localPal+0x40), 0x40*2/4);
+ //vidConvCpyRGB32sh(localPal+0x40, Pico.est.SonicPal, 0x40);
+ //vidConvCpyRGB32hi(localPal+0x80, Pico.est.SonicPal, 0x40); // TODO?
+ memcpy((void *)(localPal+0xc0), (void *)(localPal+0x40), 0x40*2);
localPal[0xc0] = 0x0600;
localPal[0xd0] = 0xc000;
localPal[0xe0] = 0x0000; // reserved pixels for OSD
localPal[0xf0] = 0xffff;
}
- /* no support
- else if (rendstatus & 0x20) { // mid-frame palette changes
- vidConvCpyRGB565(localPal+0x40, HighPal, 0x40);
- vidConvCpyRGB565(localPal+0x80, HighPal+0x40, 0x40);
- } */
}
lines_flags = (Pico.video.reg[1]&8) ? 240 : 224;
if (!(Pico.video.reg[12]&1)) lines_flags|=0x10000;
void menu_draw_begin(int use_bgbuff)\r
{\r
if (use_bgbuff)\r
- memcpy32((int *)menu_screen, (int *)bg_buffer, 321*240*2/4);\r
+ memcpy((int *)menu_screen, (int *)bg_buffer, 321*240*2);\r
}\r
\r
\r
lprintf("%s: Framework2D_LockBuffer() returned NULL\n", __FUNCTION__);\r
return;\r
}\r
- memcpy32(giz_screen, (int *)menu_screen, 321*240*2/4);\r
+ memcpy(giz_screen, (int *)menu_screen, 321*240*2);\r
fb_unlock();\r
giz_screen = NULL;\r
fb_flip();\r
}\r
\r
static int localPal[0x100];\r
+static int localPalSize;\r
+\r
static void (*vidcpyM2)(void *dest, void *src, int m32col, int with_32c_border);\r
static int (*make_local_pal)(int fast_mode);\r
\r
static int make_local_pal_md(int fast_mode)\r
{\r
- int pallen = 0xc0;\r
-\r
- bgr444_to_rgb32(localPal, PicoMem.cram);\r
- if (fast_mode)\r
- return 0x40;\r
+ int pallen = 0x100;\r
\r
- if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode\r
- bgr444_to_rgb32_sh(localPal, PicoMem.cram);\r
- localPal[0xc0] = 0x0000c000;\r
- localPal[0xd0] = 0x00c00000;\r
- localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
- localPal[0xf0] = 0x00ffffff;\r
- pallen = 0x100;\r
+ if (fast_mode) {\r
+ bgr444_to_rgb32(localPal, PicoMem.cram);\r
+ pallen = 0x40;\r
+ Pico.m.dirtyPal = 0;\r
}\r
else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes\r
- bgr444_to_rgb32(localPal+0x40, Pico.est.HighPal);\r
- bgr444_to_rgb32(localPal+0x80, Pico.est.HighPal+0x40);\r
+ switch (Pico.est.SonicPalCount) {\r
+ case 3: bgr444_to_rgb32(localPal+0xc0, Pico.est.SonicPal+0xc0);\r
+ case 2: bgr444_to_rgb32(localPal+0x80, Pico.est.SonicPal+0x80);\r
+ case 1: bgr444_to_rgb32(localPal+0x40, Pico.est.SonicPal+0x40);\r
+ default:bgr444_to_rgb32(localPal, Pico.est.SonicPal);\r
+ }\r
+ pallen = (Pico.est.SonicPalCount+1)*0x40;\r
}\r
- else\r
- memcpy(localPal + 0x80, localPal, 0x40 * 4); // for spr prio mess\r
+ else if (Pico.video.reg[0xC] & 8) { // shadow/hilight mode\r
+ bgr444_to_rgb32(localPal, Pico.est.SonicPal);\r
+ bgr444_to_rgb32_sh(localPal, Pico.est.SonicPal);\r
+ }\r
+ else {\r
+ bgr444_to_rgb32(localPal, Pico.est.SonicPal);\r
+ memcpy(localPal+0x40, localPal, 0x40*4); // for spr prio mess\r
+ memcpy(localPal+0x80, localPal, 0x80*4); // for spr prio mess\r
+ }\r
+ localPal[0xc0] = 0x0000c000;\r
+ localPal[0xd0] = 0x00c00000;\r
+ localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
+ localPal[0xf0] = 0x00ffffff;\r
\r
+ if (Pico.m.dirtyPal == 2)\r
+ Pico.m.dirtyPal = 0;\r
return pallen;\r
}\r
\r
*dpal++ = t;\r
}\r
\r
+ Pico.m.dirtyPal = 0;\r
return 0x40;\r
}\r
\r
void pemu_finalize_frame(const char *fps, const char *notice)\r
{\r
int emu_opt = currentConfig.EmuOpt;\r
- int ret;\r
\r
if (PicoIn.AHW & PAHW_32X)\r
- ; // nothing to do\r
+ localPalSize = 0; // nothing to do\r
else if (get_renderer() == RT_8BIT_FAST)\r
{\r
// 8bit fast renderer\r
- if (Pico.m.dirtyPal) {\r
- Pico.m.dirtyPal = 0;\r
- ret = make_local_pal(1);\r
- // feed new palette to our device\r
- gp2x_video_setpalette(localPal, ret);\r
- }\r
+ if (Pico.m.dirtyPal)\r
+ localPalSize = make_local_pal(1);\r
// a hack for VR\r
if (PicoIn.AHW & PAHW_SVP)\r
memset32((int *)(Pico.est.Draw2FB+328*8+328*223), 0xe0e0e0e0, 328);\r
{\r
// 8bit accurate renderer\r
if (Pico.m.dirtyPal)\r
- {\r
- Pico.m.dirtyPal = 0;\r
- ret = make_local_pal(0);\r
- gp2x_video_setpalette(localPal, ret);\r
- }\r
+ localPalSize = make_local_pal(0);\r
}\r
+ else localPalSize = 0; // no palette in 16bit mode\r
\r
if (notice)\r
osd_text(4, osd_y, notice);\r
{\r
int stride = g_screen_width;\r
gp2x_video_flip();\r
+ // switching the palette takes immediate effect, whilst flipping only\r
+ // takes effect with the next vsync; unavoidable flicker may occur!\r
+ if (localPalSize)\r
+ gp2x_video_setpalette(localPal, localPalSize);\r
\r
if (is_16bit_mode())\r
stride *= 2;\r
if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) {\r
PicoDrawSetOutFormat(PDF_RGB555, 1);\r
}\r
- else {\r
- PicoDrawSetOutFormat(PDF_NONE, 0);\r
- }\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
gp2x_mode = 16;\r
}\r
localPal[0xe0] = 0x00000000; // reserved pixels for OSD\r
localPal[0xf0] = 0x00ffffff;\r
gp2x_video_setpalette(localPal, 0x100);\r
- gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
}\r
- else\r
- gp2x_memset_all_buffers(0, 0, 320*240*2);\r
\r
if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
gp2x_mode = -gp2x_mode;\r
PicoDrawSetCallbacks(NULL, NULL);\r
Pico.m.dirtyPal = 1;\r
\r
+ if (!no_scale)\r
+ no_scale = currentConfig.scaling == EOPT_SCALE_NONE;\r
emu_cmn_forced_frame(no_scale, do_emu);\r
\r
g_menubg_src_ptr = g_screen_ptr;\r
unsigned char *ps = Pico.est.Draw2FB + 328*8 + 8;\r
unsigned short *pal = Pico.est.HighPal;\r
int i, x;\r
- if (Pico.m.dirtyPal)\r
- PicoDrawUpdateHighPal();\r
+\r
+ PicoDrawUpdateHighPal();\r
for (i = 0; i < 224; i++, ps += 8)\r
for (x = 0; x < 320; x++)\r
*pd++ = pal[*ps++];\r
\r
if (PicoIn.AHW & PAHW_32X)\r
PicoDrawSetOutBuf(g_screen_ptr, g_screen_ppitch * 2);\r
+\r
+ Pico.m.dirtyPal = 1;\r
}\r
\r
void plat_video_toggle_renderer(int change, int is_menu)\r
//for (i = 0x3f/2; i >= 0; i--)
// dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
- do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
-
- Pico.m.dirtyPal = 0;
- need_pal_upload = 1;
-
- if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
+ if ((currentConfig.EmuOpt&0x80) || (PicoOpt&0x10)) {
+ do_pal_convert(localPal, Pico.cram, currentConfig.gamma, currentConfig.gamma2);
+ Pico.m.dirtyPal = 0;
+ }
+ else if (Pico.est.rendstatus&0x20)
+ {
+ switch (Pico.est.SonicPalCount) {
+ case 3: do_pal_convert(localPal+0xc0, Pico.est.SonicPal+0xc0, currentConfig.gamma, currentConfig.gamma2);
+ case 2: do_pal_convert(localPal+0x80, Pico.est.SonicPal+0x80, currentConfig.gamma, currentConfig.gamma2);
+ case 1: do_pal_convert(localPal+0x40, Pico.est.SonicPal+0x40, currentConfig.gamma, currentConfig.gamma2);
+ default:do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
+ }
+ }
+ else if (allow_sh && (Pico.video.reg[0xC]&8)) // shadow/hilight?
{
+ do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
// shadowed pixels
for (i = 0x3f/2; i >= 0; i--)
dpal[0x20|i] = dpal[0x60|i] = (dpal[i]>>1)&0x7bcf7bcf;
localPal[0xe0] = 0;
localPal[0xf0] = 0x001f;
}
+ else if (allow_as && (Pico.est.rendstatus & PDRAW_SPR_LO_ON_HI))
+ {
+ do_pal_convert(localPal, Pico.est.SonicPal, currentConfig.gamma, currentConfig.gamma2);
+ memcpy((int *)dpal+0x40/2, (void *)localPal, 0x40*2);
+ memcpy((int *)dpal+0x80/2, (void *)localPal, 0x80*2);
+ }
+
+ if (Pico.m.dirtyPal == 2)
+ Pico.m.dirtyPal = 0;
+ need_pal_upload = 1;
}
static void do_slowmode_lines(int line_to)
PicoIn.sndOut += len / 2;
/*if (PicoIn.sndOut > sndBuffer_endptr) {
- memcpy32((int *)(void *)sndBuffer, (int *)endptr, (PicoIn.sndOut - endptr + 1) / 2);
+ memcpy((int *)(void *)sndBuffer, (int *)endptr, (PicoIn.sndOut - endptr + 1) * 2);
PicoIn.sndOut = &sndBuffer[PicoIn.sndOut - endptr];
lprintf("mov\n");
}
// int i;
// for (i = 272; i >= 0; i--, dst += 512, src += 480)
- // memcpy32((int *)dst, (int *)src, 480*2/4);
+ // memcpy((int *)dst, (int *)src, 480*2);
sceGuSync(0,0); // sync with prev
sceGuStart(GU_DIRECT, guCmdList);