new 32x renderers, auto fskip change, massive refactoring
authornotaz <notasas@gmail.com>
Sun, 10 Jan 2010 17:07:28 +0000 (17:07 +0000)
committernotaz <notasas@gmail.com>
Sun, 10 Jan 2010 17:07:28 +0000 (17:07 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@855 be3aeb3a-fb24-0410-a615-afba39da0efa

35 files changed:
pico/32x/32x.c
pico/32x/draw.c
pico/32x/draw_arm.s [new file with mode: 0644]
pico/draw.c
pico/draw_arm.s
pico/mode4.c
pico/pico.h
pico/pico_int.h
platform/common/common_arm.mak
platform/common/config.c
platform/common/emu.c
platform/common/emu.h
platform/common/menu.c
platform/common/menu.h
platform/common/plat.h
platform/gizmondo/emu.c
platform/gizmondo/port_config.h
platform/gizmondo/port_config.s
platform/gp2x/Makefile
platform/gp2x/emu.c
platform/gp2x/menu.c
platform/gp2x/port_config.h
platform/gp2x/port_config.s
platform/linux/emu.c
platform/linux/port_config.h
platform/pandora/emu.c
platform/pandora/menu.c
platform/pandora/port_config.h
platform/pandora/port_config.s
platform/psp/emu.c
platform/psp/port_config.h
platform/uiq3/port_config.h
platform/uiq3/port_config.s
platform/win32/plat.c
platform/win32/port_config.h

index 94e696b..b631a30 100644 (file)
@@ -148,6 +148,26 @@ void PicoReset32x(void)
 
 static void p32x_start_blank(void)
 {
+  if (Pico32xDrawMode != 0) {
+    if ((Pico32x.vdp_regs[0] & P32XV_Mx) != 0 && // 32x not blanking
+        (Pico.video.reg[12] & 1) && // 40col mode
+        (PicoDrawMask & PDRAW_32X_ON))
+    {
+      int md_bg = Pico.video.reg[7] & 0x3f;
+      int offs = 8, lines = 224;
+      if (Pico.video.reg[1] & 8) {
+        offs = 0;
+        lines = 240;
+      }
+
+      // we draw full layer (not line-by-line)
+      PicoDraw32xLayer(offs, lines, md_bg);
+    }
+    else {
+      // TODO: MD layer only?
+    }
+  }
+
   // enter vblank
   Pico32x.vdp_regs[0x0a/2] |= P32XV_VBLK|P32XV_PEN;
 
index e59fabb..027b963 100644 (file)
@@ -1,5 +1,9 @@
 #include "../pico_int.h"
 
+int (*PicoScan32xBegin)(unsigned int num);
+int (*PicoScan32xEnd)(unsigned int num);
+int Pico32xDrawMode;
+
 static void convert_pal555(int invert_prio)
 {
   unsigned int *ps = (void *)Pico32xMem->pal;
@@ -22,49 +26,87 @@ static void convert_pal555(int invert_prio)
   Pico32x.dirty_pal = 0;
 }
 
+// direct color mode
+#define do_line_dc(pd, p32x, pmd, inv, pmd_draw_code)             \
+{                                                                 \
+  const unsigned int m1 = 0x001f;                                 \
+  const unsigned int m2 = 0x03e0;                                 \
+  const unsigned int m3 = 0x7c00;                                 \
+  int i;                                                          \
+                                                                  \
+  for (i = 320; i > 0; i--, pd++, p32x++, pmd++) {                \
+    unsigned short t = *p32x;                                     \
+    if (*pmd != mdbg && !((t ^ inv) & 0x8000)) {                  \
+      pmd_draw_code;                                              \
+      continue;                                                   \
+    }                                                             \
+                                                                  \
+    *pd = ((t & m1) << 11) | ((t & m2) << 1) | ((t & m3) >> 10);  \
+  }                                                               \
+}
+
+// packed pixel mode
+#define do_line_pp(pd, p32x, pmd, pmd_draw_code)                  \
+{                                                                 \
+  unsigned short t;                                               \
+  int i;                                                          \
+  for (i = 320/2; i > 0; i--, p32x++) {                           \
+    t = pal[*p32x >> 8];                                          \
+    if (*pmd == mdbg || (t & 0x20))                               \
+      *pd = t;                                                    \
+    else                                                          \
+      pmd_draw_code;                                              \
+    pd++; pmd++;                                                  \
+    t = pal[*p32x & 0xff];                                        \
+    if (*pmd == mdbg || (t & 0x20))                               \
+      *pd = t;                                                    \
+    else                                                          \
+      pmd_draw_code;                                              \
+    pd++; pmd++;                                                  \
+  }                                                               \
+} 
+
+// run length mode
+#define do_line_rl(pd, p32x, pmd, pmd_draw_code)                  \
+{                                                                 \
+  unsigned short len, t;                                          \
+  int i;                                                          \
+  for (i = 320; i > 0; p32x++) {                                  \
+    t = pal[*p32x & 0xff];                                        \
+    for (len = (*p32x >> 8) + 1; len > 0 && i > 0; len--, i--, pd++, pmd++) { \
+      if (*pmd == mdbg || (t & 0x20))                             \
+        *pd = t;                                                  \
+      else                                                        \
+        pmd_draw_code;                                            \
+    }                                                             \
+  }                                                               \
+}
+
 void FinalizeLine32xRGB555(int sh, int line)
 {
   unsigned short *pd = DrawLineDest;
   unsigned short *pal = Pico32xMem->pal_native;
-  unsigned char *pb = HighCol + 8;
-  unsigned short *dram, *ps, cram0;
-  int i;
-
-  // this is a bit hackish:
-  // we swap cram color 0 with color that is used for background,
-  // as bg is forced to 0 when we do 32X
-  cram0 = Pico.cram[0];
-  Pico.cram[0] = Pico.cram[Pico.video.reg[7] & 0x3f];
-
-  FinalizeLineRGB555(sh, line);
-  Pico.cram[0] = cram0;
+  unsigned char  *pmd = HighCol + 8;
+  unsigned short *dram, *p32x;
+  unsigned char   mdbg;
 
-  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 0)
-    return; // blanking
-
-  // XXX: how is 32col mode hadled by real hardware?
-  if (!(Pico.video.reg[12] & 1))
-    return;
+  FinalizeLine555(sh, line);
 
-  if (!(PicoDrawMask & PDRAW_32X_ON))
+  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 0 || // 32x blanking
+      // XXX: how is 32col mode hadled by real hardware?
+      !(Pico.video.reg[12] & 1) || // 32col mode
+      !(PicoDrawMask & PDRAW_32X_ON))
+  {
     return;
+  }
 
   dram = (void *)Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
-  ps = dram + dram[line];
+  p32x = dram + dram[line];
+  mdbg = Pico.video.reg[7] & 0x3f;
 
   if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 2) { // Direct Color Mode
-    int inv = (Pico32x.vdp_regs[0] & P32XV_PRI) ? 0x8000 : 0;
-    unsigned int m1 = 0x001f001f;
-    unsigned int m2 = 0x03e003e0;
-    unsigned int m3 = 0xfc00fc00;
-
-    for (i = 320; i > 0; i--, ps++, pd++, pb++) {
-      unsigned short t = *ps;
-      if (*pb != 0 && !((t ^ inv) & 0x8000))
-        continue;
-
-      *pd = ((t & m1) << 11) | ((t & m2) << 1) | ((t & m3) >> 10);
-    }
+    int inv_bit = (Pico32x.vdp_regs[0] & P32XV_PRI) ? 0x8000 : 0;
+    do_line_dc(pd, p32x, pmd, inv_bit,);
     return;
   }
 
@@ -72,24 +114,163 @@ void FinalizeLine32xRGB555(int sh, int line)
     convert_pal555(Pico32x.vdp_regs[0] & P32XV_PRI);
 
   if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 1) { // Packed Pixel Mode
-    unsigned short t;
-    for (i = 320/2; i > 0; i--, ps++, pd += 2, pb += 2) {
-      t = pal[*ps >> 8];
-      if (pb[0] == 0 || (t & 0x20))
-        pd[0] = t;
-      t = pal[*ps & 0xff];
-      if (pb[1] == 0 || (t & 0x20))
-        pd[1] = t;
-    }
+    do_line_pp(pd, p32x, pmd,);
   }
   else { // Run Length Mode
-    unsigned short len, t;
-    for (i = 320; i > 0; ps++) {
-      t = pal[*ps & 0xff];
-      for (len = (*ps >> 8) + 1; len > 0 && i > 0; len--, i--, pd++, pb++)
-        if (*pb == 0 || (t & 0x20))
-          *pd = t;
-    }
+    do_line_rl(pd, p32x, pmd,);
+  }
+}
+
+#define MD_LAYER_CODE \
+  *dst = palmd[*pmd]
+
+#define PICOSCAN_PRE \
+  PicoScan32xBegin(l + (lines_offs & 0xff)); \
+  dst = DrawLineDest; \
+
+#define PICOSCAN_POST \
+  PicoScan32xEnd(l + (lines_offs & 0xff)); \
+
+#define make_do_loop(name, pre_code, post_code, md_code)        \
+/* Direct Color Mode */                                         \
+static void do_loop_dc##name(unsigned short *dst,               \
+    unsigned short *dram, int lines_offs, int mdbg)             \
+{                                                               \
+  int inv_bit = (Pico32x.vdp_regs[0] & P32XV_PRI) ? 0x8000 : 0; \
+  unsigned char  *pmd = PicoDraw2FB + 328 * 8 + 8;              \
+  unsigned short *palmd = HighPal;                              \
+  unsigned short *p32x;                                         \
+  int lines = lines_offs >> 16;                                 \
+  int l;                                                        \
+  (void)palmd;                                                  \
+  for (l = 0; l < lines; l++, pmd += 8) {                       \
+    pre_code;                                                   \
+    p32x = dram + dram[l];                                      \
+    do_line_dc(dst, p32x, pmd, inv_bit, md_code);               \
+    post_code;                                                  \
+  }                                                             \
+}                                                               \
+                                                                \
+/* Packed Pixel Mode */                                         \
+static void do_loop_pp##name(unsigned short *dst,               \
+    unsigned short *dram, int lines_offs, int mdbg)             \
+{                                                               \
+  unsigned short *pal = Pico32xMem->pal_native;                 \
+  unsigned char  *pmd = PicoDraw2FB + 328 * 8 + 8;              \
+  unsigned short *palmd = HighPal;                              \
+  unsigned short *p32x;                                         \
+  int lines = lines_offs >> 16;                                 \
+  int l;                                                        \
+  (void)palmd;                                                  \
+  for (l = 0; l < lines; l++, pmd += 8) {                       \
+    pre_code;                                                   \
+    p32x = dram + dram[l];                                      \
+    do_line_pp(dst, p32x, pmd, md_code);                        \
+    post_code;                                                  \
+  }                                                             \
+}                                                               \
+                                                                \
+/* Run Length Mode */                                           \
+static void do_loop_rl##name(unsigned short *dst,               \
+    unsigned short *dram, int lines_offs, int mdbg)             \
+{                                                               \
+  unsigned short *pal = Pico32xMem->pal_native;                 \
+  unsigned char  *pmd = PicoDraw2FB + 328 * 8 + 8;              \
+  unsigned short *palmd = HighPal;                              \
+  unsigned short *p32x;                                         \
+  int lines = lines_offs >> 16;                                 \
+  int l;                                                        \
+  (void)palmd;                                                  \
+  for (l = 0; l < lines; l++, pmd += 8) {                       \
+    pre_code;                                                   \
+    p32x = dram + dram[l];                                      \
+    do_line_rl(dst, p32x, pmd, md_code);                        \
+    post_code;                                                  \
+  }                                                             \
+}
+
+#ifdef _ASM_32X_DRAW
+#undef make_do_loop
+#define make_do_loop(name, pre_code, post_code, md_code) \
+extern void do_loop_dc##name(unsigned short *dst,        \
+    unsigned short *dram, int lines_offs, int mdbg);     \
+extern void do_loop_pp##name(unsigned short *dst,        \
+    unsigned short *dram, int lines_offs, int mdbg);     \
+extern void do_loop_rl##name(unsigned short *dst,        \
+    unsigned short *dram, int lines_offs, int mdbg);
+#endif
+
+make_do_loop(,,,)
+make_do_loop(_md, , , MD_LAYER_CODE)
+make_do_loop(_scan, PICOSCAN_PRE, PICOSCAN_POST, )
+make_do_loop(_scan_md, PICOSCAN_PRE, PICOSCAN_POST, MD_LAYER_CODE)
+
+typedef void (*do_loop_func)(unsigned short *dst, unsigned short *dram, int lines, int mdbg);
+enum { DO_LOOP, DO_LOOP_MD, DO_LOOP_SCAN, DO_LOOP_MD_SCAN };
+
+static const do_loop_func do_loop_dc_f[] = { do_loop_dc, do_loop_dc_md, do_loop_dc_scan, do_loop_dc_scan_md };
+static const do_loop_func do_loop_pp_f[] = { do_loop_pp, do_loop_pp_md, do_loop_pp_scan, do_loop_pp_scan_md };
+static const do_loop_func do_loop_rl_f[] = { do_loop_rl, do_loop_rl_md, do_loop_rl_scan, do_loop_rl_scan_md };
+
+void PicoDraw32xLayer(int offs, int lines, int md_bg)
+{
+  int have_scan = PicoScan32xBegin != NULL && PicoScan32xEnd != NULL;
+  const do_loop_func *do_loop;
+  unsigned short *dram;
+  int which_func;
+
+  DrawLineDest = DrawLineDestBase + offs * DrawLineDestIncrement;
+  dram = Pico32xMem->dram[Pico32x.vdp_regs[0x0a/2] & P32XV_FS];
+
+  if (Pico32xDrawMode == 2) {
+    if (Pico.m.dirtyPal)
+      PicoDrawUpdateHighPal();
+  }
+
+  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 2)
+  {
+    // Direct Color Mode
+    do_loop = do_loop_dc_f;
+    goto do_it;
+  }
+
+  if (Pico32x.dirty_pal)
+    convert_pal555(Pico32x.vdp_regs[0] & P32XV_PRI);
+
+  if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 1)
+  {
+    // Packed Pixel Mode
+    do_loop = do_loop_pp_f;
+  }
+  else
+  {
+    // Run Length Mode
+    do_loop = do_loop_rl_f;
+  }
+
+do_it:
+  if (Pico32xDrawMode == 2)
+    which_func = have_scan ? DO_LOOP_MD_SCAN : DO_LOOP_MD;
+  else
+    which_func = have_scan ? DO_LOOP_SCAN : DO_LOOP;
+
+  do_loop[which_func](DrawLineDest, dram, (lines << 16) | offs, md_bg);
+}
+
+void PicoDraw32xSetFrameMode(int is_on, int only_32x)
+{
+#ifdef _ASM_32X_DRAW
+  extern void *Pico32xNativePal;
+  Pico32xNativePal = Pico32xMem->pal_native;
+#endif
+
+  if (is_on) {
+    // use the same layout as alt renderer
+    PicoDrawSetInternalBuf(PicoDraw2FB + 328*8, 328);
+    Pico32xDrawMode = only_32x ? 1 : 2;
+  } else {
+    PicoDrawSetInternalBuf(NULL, 0);
+    Pico32xDrawMode = 0;
   }
 }
 
diff --git a/pico/32x/draw_arm.s b/pico/32x/draw_arm.s
new file mode 100644 (file)
index 0000000..4cafd2a
--- /dev/null
@@ -0,0 +1,263 @@
+@ vim:filetype=armasm
+
+.extern Pico32x
+.extern PicoDraw2FB
+.extern HighPal
+
+.equiv P32XV_PRI,  (1<< 7)
+
+.bss
+.align 2
+.global Pico32xNativePal
+Pico32xNativePal:
+    .word 0
+
+.text
+.align 2
+
+
+.macro call_scan_prep cond
+.if \cond
+    ldr     r4, =PicoScan32xBegin
+    ldr     r5, =PicoScan32xEnd
+    ldr     r6, =DrawLineDest
+    ldr     r4, [r4]
+    ldr     r5, [r5]
+    stmfd   sp!, {r4,r5,r6}
+.endif
+.endm
+
+.macro call_scan_fin_ge cond
+.if \cond
+    addge   sp, sp, #4*3
+.endif
+.endm
+
+.macro call_scan_begin cond
+.if \cond
+    stmfd   sp!, {r1-r3}
+    and     r0, r2, #0xff
+    add     r0, r0, r4
+    mov     lr, pc
+    ldr     pc, [sp, #(3+0)*4]
+    ldr     r0, [sp, #(3+2)*4] @ &DrawLineDest
+    ldmfd   sp!, {r1-r3}
+    ldr     r0, [r0]
+.endif
+.endm
+
+.macro call_scan_end cond
+.if \cond
+    stmfd   sp!, {r0-r3}
+    and     r0, r2, #0xff
+    add     r0, r0, r4
+    mov     lr, pc
+    ldr     pc, [sp, #(4+1)*4]
+    ldmfd   sp!, {r0-r3}
+.endif
+.endm
+
+@ direct color
+@ unsigned short *dst, unsigned short *dram, int lines_offs, int mdbg
+.macro make_do_loop_dc name call_scan do_md
+.global \name
+\name:
+    stmfd   sp!, {r4-r11,lr}
+
+    ldr     r10,=Pico32x
+    ldr     r11,=PicoDraw2FB
+    ldr     r10,[r10, #0x40] @ Pico32x.vdp_regs[0]
+    ldr     r11,[r11]
+    ldr     r9, =HighPal     @ palmd
+    add     r11,r11,#(328*8) @ r11 = pmd: md data
+    tst     r10,#P32XV_PRI
+    moveq   r10,#0
+    movne   r10,#0x8000      @ r10 = inv_bit
+    call_scan_prep \call_scan
+
+    mov     r4, #0           @ line
+    b       1f @ loop_outer_entry
+
+0: @ loop_outer:
+    call_scan_end \call_scan
+    add     r4, r4, #1
+    sub     r11,r11,#1       @ adjust for prev read
+    cmp     r4, r2, lsr #16
+    call_scan_fin_ge \call_scan
+    ldmgefd sp!, {r4-r11,pc}
+
+1: @ loop_outer_entry:
+    call_scan_begin \call_scan
+    mov     r12,r4, lsl #1
+    ldrh    r12,[r1, r12]
+    add     r11,r11,#8
+    mov     r6, #320
+    add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
+
+2: @ loop_inner:
+    ldrb    r7, [r11], #1    @ MD pixel
+    subs    r6, r6, #1
+    blt     0b @ loop_outer
+    ldrh    r8, [r5], #2     @ 32x pixel
+    cmp     r7, r3           @ MD has bg pixel?
+    beq     3f @ draw32x
+    eor     r12,r8, r10
+    ands    r12,r12,#0x8000  @ !((t ^ inv) & 0x8000)
+.if \do_md
+    mov     r7, r7, lsl #1
+    ldreqh  r12,[r9, r7]
+    streqh  r12,[r0], #2     @ *dst++ = palmd[*pmd]
+.endif
+    beq     2b @ loop_inner
+
+3: @ draw32x:
+    and     r12,r8, #0x03e0
+    mov     r8, r8, lsl #11
+    orr     r8, r8, r8, lsr #(10+11)
+    orr     r8, r8, r12,lsl #1
+    bic     r8, r8, #0x0020  @ kill prio bit
+    strh    r8, [r0], #2     @ *dst++ = bgr2rgb(*p32x++)
+    b       2b @ loop_inner
+.endm
+
+
+@ packed pixel
+.macro do_pixel_pp do_md
+    ldrb    r7, [r11], #1    @ MD pixel
+    eor     r12,r5, #1
+    ldrb    r8, [r12]        @ palette index
+    cmp     r7, r3           @ MD has bg pixel?
+    mov     r12,r8,lsl #1
+    ldrh    r8, [r10,r12]    @ t = 32x pixel
+    mov     r7, r7, lsl #1
+    add     r5, r5, #1
+    eorne   r12,r8, #0x20
+    tstne   r12, #0x20
+.if \do_md
+    ldrneh  r8, [r9, r7]     @ t = palmd[*pmd]
+    subs    r6, r6, #1
+    strh    r8, [r0], #2     @ *dst++ = t
+.else
+    streqh  r8, [r0], #2
+    addne   r0, r0, #2
+    subs    r6, r6, #1
+.endif
+.endm
+
+@ unsigned short *dst, unsigned short *dram, int lines_offs, int mdbg
+.macro make_do_loop_pp name call_scan do_md
+.global \name
+\name:
+    stmfd   sp!, {r4-r11,lr}
+
+    ldr     r11,=PicoDraw2FB
+    ldr     r10,=Pico32xNativePal
+    ldr     r11,[r11]
+    ldr     r10,[r10]
+    ldr     r9, =HighPal     @ palmd
+    add     r11,r11,#(328*8) @ r11 = pmd: md data
+    call_scan_prep \call_scan
+
+    mov     r4, #0           @ line
+    b       1f @ loop_outer_entry
+
+0: @ loop_outer:
+    call_scan_end \call_scan
+    add     r4, r4, #1
+    cmp     r4, r2, lsr #16
+    call_scan_fin_ge \call_scan
+    ldmgefd sp!, {r4-r11,pc}
+
+1: @ loop_outer_entry:
+    call_scan_begin \call_scan
+    mov     r12,r4, lsl #1
+    ldrh    r12,[r1, r12]
+    add     r11,r11,#8
+    mov     r6, #320
+    add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
+
+2: @ loop_inner:
+    do_pixel_pp \do_md
+    do_pixel_pp \do_md
+    bgt     2b @ loop_inner
+    b       0b @ loop_outer
+.endm
+
+
+@ run length
+@ unsigned short *dst, unsigned short *dram, int lines_offs, int mdbg
+.macro make_do_loop_rl name call_scan do_md
+.global \name
+\name:
+    stmfd   sp!, {r4-r11,lr}
+
+    ldr     r11,=PicoDraw2FB
+    ldr     r10,=Pico32xNativePal
+    ldr     r11,[r11]
+    ldr     r10,[r10]
+    ldr     r9, =HighPal     @ palmd
+    add     r11,r11,#(328*8) @ r11 = pmd: md data
+    call_scan_prep \call_scan
+
+    mov     r4, #0           @ line
+    b       1f @ loop_outer_entry
+
+0: @ loop_outer:
+    call_scan_end \call_scan
+    add     r4, r4, #1
+    sub     r11,r11,#1       @ adjust for prev read
+    cmp     r4, r2, lsr #16
+    call_scan_fin_ge \call_scan
+    ldmgefd sp!, {r4-r11,pc}
+
+1: @ loop_outer_entry:
+    call_scan_begin \call_scan
+    mov     r12,r4, lsl #1
+    ldrh    r12,[r1, r12]
+    add     r11,r11,#8
+    mov     r6, #320
+    add     r5, r1, r12, lsl #1 @ p32x = dram + dram[l]
+
+2: @ loop_inner:
+    ldrh    r8, [r5], #2     @ control word
+    and     r12,r8, #0xff
+    mov     r12,r12,lsl #1
+    ldrh    lr, [r10,r12]    @ t = 32x pixel
+    eor     lr, lr, #0x20
+
+3: @ loop_innermost:
+    ldrb    r7, [r11], #1    @ MD pixel
+    subs    r6, r6, #1
+    blt     0b @ loop_outer
+    cmp     r7, r3           @ MD has bg pixel?
+    mov     r7, r7, lsl #1
+    tstne   lr, #0x20
+.if \do_md
+    ldrneh  r12,[r9, r7]     @ t = palmd[*pmd]
+    streqh  lr, [r0], #2
+    strneh  r12,[r0], #2     @ *dst++ = t
+.else
+    streqh  lr, [r0]
+    add     r0, r0, #2
+.endif
+    subs    r8, r8, #0x100
+    bge     3b @ loop_innermost
+    b       2b @ loop_inner
+.endm
+
+
+make_do_loop_dc do_loop_dc,         0, 0
+make_do_loop_dc do_loop_dc_md,      0, 1
+make_do_loop_dc do_loop_dc_scan,    1, 0
+make_do_loop_dc do_loop_dc_scan_md, 1, 1
+
+make_do_loop_pp do_loop_pp,         0, 0
+make_do_loop_pp do_loop_pp_md,      0, 1
+make_do_loop_pp do_loop_pp_scan,    1, 0
+make_do_loop_pp do_loop_pp_scan_md, 1, 1
+
+make_do_loop_rl do_loop_rl,         0, 0
+make_do_loop_rl do_loop_rl_md,      0, 1
+make_do_loop_rl do_loop_rl_scan,    1, 0
+make_do_loop_rl do_loop_rl_scan_md, 1, 1
+
index 6670ba3..168a6ea 100644 (file)
 int (*PicoScanBegin)(unsigned int num) = NULL;\r
 int (*PicoScanEnd)  (unsigned int num) = NULL;\r
 \r
-#if OVERRIDE_HIGHCOL\r
 static unsigned char DefHighCol[8+320+8];\r
-unsigned char *HighCol=DefHighCol;\r
-#else\r
-unsigned char  HighCol[8+320+8];\r
-#endif\r
+unsigned char *HighCol = DefHighCol;\r
+static unsigned char *HighColBase = DefHighCol;\r
+static int HighColIncrement;\r
+\r
 static unsigned int DefOutBuff[320*2/2];\r
-void *DrawLineDest=DefOutBuff; // pointer to dest buffer where to draw this line to\r
+void *DrawLineDest = DefOutBuff; // pointer to dest buffer where to draw this line to\r
+void *DrawLineDestBase = DefOutBuff;\r
+int DrawLineDestIncrement;\r
 \r
 static int  HighCacheA[41+1];   // caches for high layers\r
 static int  HighCacheB[41+1];\r
@@ -1193,6 +1194,7 @@ void PicoDoHighPal555(int sh)
   }\r
 }\r
 \r
+#if 0\r
 static void FinalizeLineBGR444(int sh, int line)\r
 {\r
   unsigned short *pd=DrawLineDest;\r
@@ -1229,9 +1231,10 @@ static void FinalizeLineBGR444(int sh, int line)
   for(i = 0; i < len; i++)\r
     pd[i] = pal[ps[i] & mask];\r
 }\r
+#endif\r
 \r
 \r
-void FinalizeLineRGB555(int sh, int line)\r
+void FinalizeLine555(int sh, int line)\r
 {\r
   unsigned short *pd=DrawLineDest;\r
   unsigned char  *ps=HighCol+8;\r
@@ -1405,7 +1408,7 @@ static int DrawDisplay(int sh)
 // MUST be called every frame\r
 PICO_INTERNAL void PicoFrameStart(void)\r
 {\r
-  int lines = 224;\r
+  int offs = 8, lines = 224;\r
 \r
   // prepare to do this frame\r
   rendstatus = 0;\r
@@ -1413,9 +1416,13 @@ PICO_INTERNAL void PicoFrameStart(void)
     rendstatus |= PDRAW_INTERLACE; // interlace mode\r
   if (!(Pico.video.reg[12] & 1))\r
     rendstatus |= PDRAW_32_COLS;\r
-  if (Pico.video.reg[1] & 8)\r
+  if (Pico.video.reg[1] & 8) {\r
+    offs = 0;\r
     lines = 240;\r
+  }\r
 \r
+  HighCol = HighColBase;\r
+  DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement;\r
   DrawScanline = 0;\r
   skip_next_line = 0;\r
 \r
@@ -1477,6 +1484,9 @@ static void PicoLine(int line, int offs, int sh, int bgc)
 \r
   if (PicoScanEnd != NULL)\r
     skip_next_line = PicoScanEnd(line + offs);\r
+\r
+  HighCol += HighColIncrement;\r
+  DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement;\r
 }\r
 \r
 void PicoDrawSync(int to, int blank_last_line)\r
@@ -1490,10 +1500,6 @@ void PicoDrawSync(int to, int blank_last_line)
   if (rendlines != 240)\r
     offs = 8;\r
 \r
-  // need to know which pixels are bg for 32x\r
-  if (PicoAHW & PAHW_32X)\r
-    bgc = 0;\r
-\r
   for (line = DrawScanline; line < to; line++)\r
   {\r
 #if !CAN_HANDLE_240_LINES\r
@@ -1522,20 +1528,59 @@ void PicoDrawSync(int to, int blank_last_line)
   pprof_end(draw);\r
 }\r
 \r
-void PicoDrawSetColorFormat(int which)\r
+// also works for fast renderer\r
+void PicoDrawUpdateHighPal(void)\r
+{\r
+  int sh = (Pico.video.reg[0xC] & 8) >> 3; // shadow/hilight?\r
+  if (PicoOpt & POPT_ALT_RENDERER)\r
+    sh = 0; // no s/h support\r
+\r
+  PicoDoHighPal555(sh);\r
+  if (rendstatus & PDRAW_SONIC_MODE) {\r
+    // FIXME?\r
+    memcpy(HighPal + 0x40, HighPal, 0x40*2);\r
+    memcpy(HighPal + 0x80, HighPal, 0x40*2);\r
+  }\r
+}\r
+\r
+void PicoDrawSetOutFormat(pdso_t which, int allow_32x)\r
 {\r
   switch (which)\r
   {\r
-    case 2: FinalizeLine = FinalizeLine8bit;   break;\r
-    case 1: FinalizeLine = (PicoAHW & PAHW_32X) ? FinalizeLine32xRGB555 : FinalizeLineRGB555; break;\r
-    case 0: FinalizeLine = FinalizeLineBGR444; break;\r
-    default:FinalizeLine = NULL; break;\r
+    case PDF_8BIT:\r
+      FinalizeLine = FinalizeLine8bit;\r
+      break;\r
+\r
+    case PDF_RGB555:\r
+      if ((PicoAHW & PAHW_32X) && allow_32x)\r
+        FinalizeLine = FinalizeLine32xRGB555;\r
+      else\r
+        FinalizeLine = FinalizeLine555;\r
+      break;\r
+\r
+    default:\r
+      FinalizeLine = NULL;\r
+      break;\r
   }\r
-  PicoDrawSetColorFormatMode4(which);\r
+  PicoDrawSetOutputMode4(which);\r
   rendstatus_old = -1;\r
-#if OVERRIDE_HIGHCOL\r
-  if (which)\r
-    HighCol=DefHighCol;\r
-#endif\r
+}\r
+\r
+void PicoDrawSetOutBuf(void *dest, int increment)\r
+{\r
+  DrawLineDestBase = dest;\r
+  DrawLineDestIncrement = increment;\r
+}\r
+\r
+void PicoDrawSetInternalBuf(void *dest, int increment)\r
+{\r
+  if (dest != NULL) {\r
+    HighColBase = dest;\r
+    HighColIncrement = increment;\r
+  }\r
+  else {\r
+    HighColBase = DefHighCol;\r
+    HighColIncrement = 0;\r
+  }\r
 }\r
 \r
index 9ca1f57..de40eaa 100644 (file)
@@ -19,6 +19,8 @@
 .extern DrawStripInterlace\r
 .extern HighCacheS_ptr\r
 \r
+.equiv OVERRIDE_HIGHCOL,  1\r
+\r
 .equ PDRAW_SPRITES_MOVED, (1<<0)\r
 .equ PDRAW_WND_DIFF_PRIO, (1<<1)\r
 .equ PDRAW_ACC_SPRITES,   (1<<2)\r
@@ -1674,7 +1676,7 @@ PicoDoHighPal555:
     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
 \r
 PicoDoHighPal555_nopush:\r
-    str     r1, [sp, #-8]        @ is called from FinalizeLineRGB555?\r
+    str     r1, [sp, #-8]        @ is called from FinalizeLine555?\r
 \r
     str     r0, [sp, #-4]\r
     ldr     r0, =HighPal\r
@@ -1728,9 +1730,9 @@ PicoDoHighPal555_end:
     b       FinalizeLineRGB555_pal_done\r
 \r
 \r
-.global FinalizeLineRGB555 @ int sh\r
+.global FinalizeLine555 @ int sh\r
 \r
-FinalizeLineRGB555:\r
+FinalizeLine555:\r
     stmfd   sp!, {r4-r9,lr}\r
     ldr     r8, =(Pico+0x22228)  @ Pico.video\r
 \r
index 1462dde..4588a9a 100644 (file)
@@ -211,6 +211,8 @@ void PicoFrameStartMode4(void)
     rendlines = lines;
     emu_video_mode_change(screen_offset, lines, 1);
   }
+
+  DrawLineDest = (char *)DrawLineDestBase + screen_offset * DrawLineDestIncrement;
 }
 
 void PicoLineMode4(int line)
@@ -233,6 +235,8 @@ void PicoLineMode4(int line)
 
   if (PicoScanEnd != NULL)
     skip_next_line = PicoScanEnd(line + screen_offset);
+
+  DrawLineDest = (char *)DrawLineDest + DrawLineDestIncrement;
 }
 
 void PicoDoHighPal555M4(void)
@@ -265,7 +269,7 @@ static void FinalizeLineRGB555M4(int line)
 
   // standard FinalizeLine can finish it for us,
   // with features like scaling and such
-  FinalizeLineRGB555(0, line);
+  FinalizeLine555(0, line);
 }
 
 static void FinalizeLine8bitM4(int line)
@@ -278,13 +282,13 @@ static void FinalizeLine8bitM4(int line)
   memcpy32((int *)pd, (int *)(HighCol+8), 256/4);
 }
 
-void PicoDrawSetColorFormatMode4(int which)
+void PicoDrawSetOutputMode4(pdso_t which)
 {
   switch (which)
   {
-    case 2: FinalizeLineM4 = FinalizeLine8bitM4; break;
-    case 1: FinalizeLineM4 = FinalizeLineRGB555M4; break;
-    default:FinalizeLineM4 = NULL; break;
+    case PDF_8BIT:   FinalizeLineM4 = FinalizeLine8bitM4; break;
+    case PDF_RGB555: FinalizeLineM4 = FinalizeLineRGB555M4; break;
+    default:         FinalizeLineM4 = NULL; break;
   }
 }
 
index 033ed6f..c614aa9 100644 (file)
@@ -160,13 +160,18 @@ extern void (*PicoCartLoadProgressCB)(int percent);
 extern void (*PicoCDLoadProgressCB)(const char *fname, int percent);\r
 \r
 // Draw.c\r
-void PicoDrawSetColorFormat(int which); // 0=BGR444, 1=RGB555, 2=8bit(HighPal pal)\r
+// for line-based renderer, set conversion\r
+// from internal 8 bit representation in 'HighCol' to:\r
+typedef enum\r
+{\r
+       PDF_NONE = 0,    // no conversion\r
+       PDF_RGB555,      // RGB/BGR output, depends on compile options\r
+       PDF_8BIT,        // 8-bit out (handles shadow/hilight mode, sonic water)\r
+} pdso_t;\r
+void PicoDrawSetOutFormat(pdso_t which, int allow_32x);\r
+void PicoDrawSetOutBuf(void *dest, int increment);\r
 extern void *DrawLineDest;\r
-#if OVERRIDE_HIGHCOL\r
 extern unsigned char *HighCol;\r
-#else\r
-extern unsigned char  HighCol[8+320+8];\r
-#endif\r
 extern int (*PicoScanBegin)(unsigned int num);\r
 extern int (*PicoScanEnd)(unsigned int num);\r
 // utility\r
@@ -194,12 +199,21 @@ extern int rendstatus, rendstatus_old;
 extern int rendlines;\r
 extern unsigned short HighPal[0x100];\r
 \r
-// Draw2.c\r
+// draw.c\r
+void PicoDrawUpdateHighPal(void);\r
+void PicoDrawSetInternalBuf(void *dest, int line_increment);\r
+\r
+// draw2.c\r
 // stuff below is optional\r
 extern unsigned char  *PicoDraw2FB;  // buffer for fast renderer in format (8+320)x(8+224+8) (eights for borders)\r
 extern unsigned short *PicoCramHigh; // pointer to CRAM buff (0x40 shorts), converted to native device color (works only with 16bit for now)\r
 extern void (*PicoPrepareCram)();    // prepares PicoCramHigh for renderer to use\r
 \r
+// 32x/draw.c\r
+void PicoDraw32xSetFrameMode(int is_on, int only_32x);\r
+extern int (*PicoScan32xBegin)(unsigned int num);\r
+extern int (*PicoScan32xEnd)(unsigned int num);\r
+\r
 // sound.c\r
 extern int PsndRate,PsndLen;\r
 extern short *PsndOut;\r
index f5481fc..3f50b4f 100644 (file)
@@ -474,8 +474,8 @@ typedef struct
 struct Pico32x\r
 {\r
   unsigned short regs[0x20];\r
-  unsigned short vdp_regs[0x10];\r
-  unsigned short sh2_regs[3];\r
+  unsigned short vdp_regs[0x10]; // 0x40\r
+  unsigned short sh2_regs[3];    // 0x60\r
   unsigned char pending_fb;\r
   unsigned char dirty_pal;\r
   unsigned int emu_flags;\r
@@ -547,10 +547,12 @@ int CM_compareRun(int cyc, int is_sub);
 PICO_INTERNAL void PicoFrameStart(void);\r
 void PicoDrawSync(int to, int blank_last_line);\r
 void BackFill(int reg7, int sh);\r
-void FinalizeLineRGB555(int sh, int line);\r
+void FinalizeLine555(int sh, int line);\r
 extern int DrawScanline;\r
 #define MAX_LINE_SPRITES 29\r
 extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES];\r
+extern void *DrawLineDestBase;\r
+extern int DrawLineDestIncrement;\r
 \r
 // draw2.c\r
 PICO_INTERNAL void PicoFrameFull();\r
@@ -559,7 +561,7 @@ PICO_INTERNAL void PicoFrameFull();
 void PicoFrameStartMode4(void);\r
 void PicoLineMode4(int line);\r
 void PicoDoHighPal555M4(void);\r
-void PicoDrawSetColorFormatMode4(int which);\r
+void PicoDrawSetOutputMode4(pdso_t which);\r
 \r
 // memory.c\r
 PICO_INTERNAL void PicoMemSetup(void);\r
@@ -717,6 +719,8 @@ void p32x_poll_event(int cpu_mask, int is_vdp);
 \r
 // 32x/draw.c\r
 void FinalizeLine32xRGB555(int sh, int line);\r
+void PicoDraw32xLayer(int offs, int lines, int mdbg);\r
+extern int Pico32xDrawMode;\r
 \r
 // 32x/pwm.c\r
 unsigned int p32x_pwm_read16(unsigned int a);\r
index ce6d711..c14df93 100644 (file)
@@ -24,6 +24,10 @@ ifeq "$(asm_cdmemory)" "1"
 DEFINES += _ASM_CD_MEMORY_C
 OBJS += pico/cd/memory_arm.o
 endif
+ifeq "$(asm_32xdraw)" "1"
+DEFINES += _ASM_32X_DRAW
+OBJS += pico/32x/draw_arm.o
+endif
 
 
 DIRS += cpu/Cyclone cpu/Cyclone/proj cpu/Cyclone/tools cpu/DrZ80
index a6d4f1d..4292000 100644 (file)
@@ -10,6 +10,7 @@
 #include <unistd.h>
 #endif
 #include "config.h"
+#include "plat.h"
 #include "input.h"
 #include "lprintf.h"
 
@@ -197,6 +198,7 @@ static int default_var(const menu_entry *me)
                case MA_OPT2_GAMMA:      return defaultConfig.gamma;
                case MA_OPT_FRAMESKIP:   return defaultConfig.Frameskip;
                case MA_OPT_CPU_CLOCKS:  return defaultConfig.CPUclock;
+               case MA_OPT_RENDERER:    return defaultConfig.renderer;
 
                case MA_OPT_SAVE_SLOT:
                default:
@@ -217,9 +219,6 @@ static int is_cust_val_default(const menu_entry *me)
                case MA_OPT_CONFIRM_STATES:
                        return !((defaultConfig.EmuOpt ^ currentConfig.EmuOpt) &
                                (EOPT_CONFIRM_LOAD|EOPT_CONFIRM_SAVE)) == 0;
-               case MA_OPT_RENDERER:
-                       return ((defaultConfig.s_PicoOpt ^ PicoOpt) & POPT_ALT_RENDERER) == 0 &&
-                               ((defaultConfig.EmuOpt ^ currentConfig.EmuOpt) & EOPT_16BPP) == 0;
                case MA_CDOPT_READAHEAD:
                        return defaultConfig.s_PicoCDBuffers == PicoCDBuffers;
                default:break;
@@ -468,26 +467,21 @@ int config_readlrom(const char *fname)
 static int custom_read(menu_entry *me, const char *var, const char *val)
 {
        char *tmp;
-       int tmpi;
+       int i;
 
        switch (me->id)
        {
                case MA_OPT_RENDERER:
-                       if (strcasecmp(var, "Renderer") != 0) return 0;
-                       if      (strcasecmp(val, "8bit fast") == 0 || strcasecmp(val, "fast") == 0) {
-                               PicoOpt |=  POPT_ALT_RENDERER;
-                       }
-                       else if (strcasecmp(val, "16bit accurate") == 0 || strcasecmp(val, "accurate") == 0) {
-                               PicoOpt &= ~POPT_ALT_RENDERER;
-                               currentConfig.EmuOpt |=  0x80;
-                       }
-                       else if (strcasecmp(val, "8bit accurate") == 0) {
-                               PicoOpt &= ~POPT_ALT_RENDERER;
-                               currentConfig.EmuOpt &= ~0x80;
-                       }
-                       else
+                       if (strcasecmp(var, "Renderer") != 0 || renderer_names == NULL)
                                return 0;
-                       return 1;
+
+                       for (i = 0; renderer_names[i] != NULL; i++) {
+                               if (strcasecmp(val, renderer_names[i]) == 0) {
+                                       currentConfig.renderer = i;
+                                       return 1;
+                               }
+                       }
+                       return 0;
 
                case MA_OPT_SCALING:
 #ifdef __GP2X__
@@ -589,9 +583,9 @@ static int custom_read(menu_entry *me, const char *var, const char *val)
 
                case MA_OPT2_SQUIDGEHACK:
                        if (strcasecmp(var, "Squidgehack") != 0) return 0;
-                       tmpi = atoi(val);
-                       if (tmpi) *(int *)me->var |=  me->mask;
-                       else      *(int *)me->var &= ~me->mask;
+                       i = atoi(val);
+                       if (i) *(int *)me->var |=  me->mask;
+                       else   *(int *)me->var &= ~me->mask;
                        return 1;
 
                case MA_CDOPT_READAHEAD:
index f86526c..786a026 100644 (file)
@@ -1116,7 +1116,7 @@ static void emu_tray_close(void)
 \r
 void emu_32x_startup(void)\r
 {\r
-       plat_video_toggle_renderer(0, 1, 0);\r
+       plat_video_toggle_renderer(0, 0);\r
        system_announce();\r
 }\r
 \r
@@ -1247,9 +1247,9 @@ static void run_events_ui(unsigned int which)
                        PicoStateProgressCB = NULL;\r
                }\r
        }\r
-       if ((which & PEV_SWITCH_RND) && !(PicoAHW & PAHW_32X))\r
+       if (which & PEV_SWITCH_RND)\r
        {\r
-               plat_video_toggle_renderer(1, 0, 0);\r
+               plat_video_toggle_renderer(1, 0);\r
        }\r
        if (which & (PEV_SSLOT_PREV|PEV_SSLOT_NEXT))\r
        {\r
@@ -1493,17 +1493,15 @@ void emu_loop(void)
                {\r
                        if ((currentConfig.EmuOpt & EOPT_NO_FRMLIMIT) && currentConfig.Frameskip >= 0)\r
                                pframes_done = 0;\r
-                       else {\r
+                       else\r
                                pframes_done -= target_fps;\r
-                               /* don't allow it to drift during heavy slowdowns */\r
-                               if (pframes_done < -5) {\r
-                                       reset_timing = 1;\r
-                                       continue;\r
-                               }\r
-                               if (pframes_done < -2)\r
-                                       pframes_done = -2;\r
+                       if (pframes_done < -2) {\r
+                               /* don't drag more than 2 frames behind */\r
+                               pframes_done = -2;\r
+                               timestamp_base = timestamp - 2 * target_frametime;\r
                        }\r
-                       timestamp_base += ms_to_ticks(1000);\r
+                       else\r
+                               timestamp_base += ms_to_ticks(1000);\r
                }\r
 \r
                diff = timestamp - timestamp_base;\r
@@ -1528,15 +1526,13 @@ void emu_loop(void)
                else if (diff > diff_lim)\r
                {\r
                        /* no time left for this frame - skip */\r
-                       if (diff - diff_lim >= ms_to_ticks(200)) {\r
-                               /* if too much behind, reset instead */\r
-                               reset_timing = 1;\r
+                       /* limit auto frameskip to 8 */\r
+                       if (frames_done / 8 <= frames_shown) {\r
+                               emu_update_input();\r
+                               skip_frame(diff < diff_lim + target_frametime * 16);\r
+                               pframes_done++; frames_done++;\r
                                continue;\r
                        }\r
-                       emu_update_input();\r
-                       skip_frame(diff < diff_lim + target_frametime * 2);\r
-                       pframes_done++; frames_done++;\r
-                       continue;\r
                }\r
 \r
                emu_update_input();\r
index 1f23742..518d5fd 100644 (file)
@@ -28,7 +28,7 @@ extern int g_screen_height;
 #define EOPT_GZIP_SAVES   (1<<3)
 #define EOPT_MMUHACK      (1<<4)
 #define EOPT_NO_AUTOSVCFG (1<<5)
-#define EOPT_16BPP        (1<<7)
+#define EOPT_16BPP        (1<<7)  // depreceted for .renderer
 #define EOPT_RAM_TIMINGS  (1<<8)
 #define EOPT_CONFIRM_SAVE (1<<9)
 #define EOPT_EN_CD_LEDS   (1<<10)
@@ -67,6 +67,8 @@ typedef struct _currentConfig_t {
        float hscale32, hscale40; // psp: horizontal scale
        int gamma2;  // psp: black level
        int turbo_rate;
+       int renderer;
+       int renderer32x;
 } currentConfig_t;
 
 extern currentConfig_t currentConfig, defaultConfig;
index 8accc25..34d5b49 100644 (file)
@@ -603,7 +603,6 @@ static void me_loop(menu_entry *menu, int *menu_sel, void (*draw_more)(void))
 #else\r
 #define MENU_OPTIONS_GFX\r
 #define MENU_OPTIONS_ADV\r
-#define mgn_opt_renderer NULL /* TODO */\r
 #define menu_main_plat_draw NULL\r
 #endif\r
 \r
@@ -1494,16 +1493,47 @@ static int menu_loop_cd_options(menu_id id, int keys)
 \r
 // ------------ 32X options menu ------------\r
 \r
+static const char *get_rname(const char **rn, int val, int *offs)\r
+{\r
+       int i, len, found = -1, maxlen = 0;\r
+\r
+       for (i = 0; rn[i] != NULL; i++) {\r
+               len = strlen(rn[i]);\r
+               if (len > maxlen)\r
+                       maxlen = len;\r
+               if (i == val)\r
+                       found = i;\r
+       }\r
+\r
+       *offs = 3 - maxlen;\r
+       if (found >= 0)\r
+               return rn[found];\r
+       return "???";\r
+}\r
+\r
+static const char *mgn_opt_renderer32x(menu_id id, int *offs)\r
+{\r
+       return get_rname(renderer_names32x, currentConfig.renderer32x, offs);\r
+}\r
+\r
 static menu_entry e_menu_32x_options[] =\r
 {\r
-       mee_onoff("32X enabled",          MA_32XOPT_ENABLE_32X,   PicoOpt, POPT_EN_32X),\r
-       mee_onoff("PWM sound",            MA_32XOPT_PWM,          PicoOpt, POPT_EN_PWM),\r
+       mee_onoff     ("32X enabled",  MA_32XOPT_ENABLE_32X, PicoOpt, POPT_EN_32X),\r
+       mee_range_cust("32X renderer", MA_32XOPT_RENDERER,   currentConfig.renderer32x, 0, 0, mgn_opt_renderer32x),\r
+       mee_onoff     ("PWM sound",    MA_32XOPT_PWM,        PicoOpt, POPT_EN_PWM),\r
        mee_end,\r
 };\r
 \r
 static int menu_loop_32x_options(menu_id id, int keys)\r
 {\r
        static int sel = 0;\r
+       int i, c;\r
+\r
+       for (c = 0; renderer_names32x != NULL && renderer_names32x[c] != NULL; )\r
+               c++;\r
+       i = me_id2offset(e_menu_32x_options, MA_32XOPT_RENDERER);\r
+       e_menu_32x_options[i].max = c > 0 ? (c - 1) : 0;\r
+\r
        me_loop(e_menu_32x_options, &sel, NULL);\r
        return 0;\r
 }\r
@@ -1534,15 +1564,14 @@ static int menu_loop_adv_options(menu_id id, int keys)
 \r
 // ------------ gfx options menu ------------\r
 \r
-static int mh_opt_render(menu_id id, int keys)\r
+static const char *mgn_opt_renderer(menu_id id, int *offs)\r
 {\r
-       plat_video_toggle_renderer((keys & PBTN_RIGHT) ? 1 : 0, 0, 1);\r
-       return 0;\r
+       return get_rname(renderer_names, currentConfig.renderer, offs);\r
 }\r
 \r
 static menu_entry e_menu_gfx_options[] =\r
 {\r
-       mee_cust      ("Renderer",                 MA_OPT_RENDERER,       mh_opt_render, mgn_opt_renderer),\r
+       mee_range_cust("Renderer", MA_OPT_RENDERER,   currentConfig.renderer, 0, 0, mgn_opt_renderer),\r
        MENU_OPTIONS_GFX\r
        mee_end,\r
 };\r
@@ -1550,6 +1579,14 @@ static menu_entry e_menu_gfx_options[] =
 static int menu_loop_gfx_options(menu_id id, int keys)\r
 {\r
        static int sel = 0;\r
+       int i, c;\r
+\r
+       for (c = 0; renderer_names != NULL && renderer_names[c] != NULL; )\r
+               c++;\r
+       i = me_id2offset(e_menu_gfx_options, MA_OPT_RENDERER);\r
+       e_menu_gfx_options[i].max = c > 0 ? (c - 1) : 0;\r
+       me_enable(e_menu_gfx_options, MA_OPT_RENDERER, renderer_names != NULL);\r
+\r
        me_loop(e_menu_gfx_options, &sel, NULL);\r
        return 0;\r
 }\r
index c9be9f2..83cb9c2 100644 (file)
@@ -86,6 +86,7 @@ typedef enum
        MA_CDOPT_BETTER_SYNC,
        MA_CDOPT_DONE,
        MA_32XOPT_ENABLE_32X,
+       MA_32XOPT_RENDERER,
        MA_32XOPT_PWM,
        MA_CTRL_PLAYER1,
        MA_CTRL_PLAYER2,
index 46725bf..4f89b2c 100644 (file)
@@ -4,6 +4,8 @@ extern "C" {
 
 /* stuff to be implemented by platform code */
 extern char cpu_clk_name[];
+extern const char **renderer_names;
+extern const char **renderer_names32x;
 
 void pemu_prep_defconfig(void);
 void pemu_validate_config(void);
@@ -35,7 +37,7 @@ void plat_video_menu_end(void);
 
 void plat_video_flip(void);
 void plat_video_wait_vsync(void);
-void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu);
+void plat_video_toggle_renderer(int change, int menu_call);
 
 void plat_update_volume(int has_changed, int is_up);
 
index fd83eb9..2dfcf96 100644 (file)
@@ -230,10 +230,10 @@ static void vidResetMode(void)
 
        if (PicoOpt&0x10) {
        } else if (currentConfig.EmuOpt&0x80) {
-               PicoDrawSetColorFormat(1);
+               PicoDrawSetOutFormat(PDF_RGB555, 0);
                PicoScanBegin = EmuScanBegin16;
        } else {
-               PicoDrawSetColorFormat(-1);
+               PicoDrawSetOutFormat(PDF_NONE, 0);
                PicoScanBegin = EmuScanBegin8;
        }
        if ((PicoOpt&0x10) || !(currentConfig.EmuOpt&0x80)) {
@@ -306,7 +306,7 @@ void pemu_forced_frame(int opts)
        if (giz_screen == NULL)
                giz_screen = fb_lock(1);
 
-       PicoDrawSetColorFormat(1);
+       PicoDrawSetOutFormat(PDF_RGB555, 0);
        PicoScanBegin = EmuScanBegin16;
        Pico.m.dirtyPal = 1;
        PicoFrameDrawOnly();
index 0f89e50..4bb0b13 100644 (file)
@@ -12,9 +12,6 @@
 #define SCREEN_WIDTH  321\r
 #define SCREEN_HEIGHT 240\r
 \r
-// draw.c\r
-#define OVERRIDE_HIGHCOL 1\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
index 4a2366e..833cb38 100644 (file)
@@ -6,7 +6,6 @@
 .equiv START_ROW,               0\r
 .equiv END_ROW,                28\r
 \r
-.equiv OVERRIDE_HIGHCOL,        1\r
 .equiv UNALIGNED_DRAWLINEDEST,  1\r
 \r
 @ this should be set to one only for GP2X port\r
index 9d8aa6a..431a357 100644 (file)
@@ -13,6 +13,7 @@ asm_ym2612 = 1
 asm_misc = 1\r
 asm_cdpico = 1\r
 asm_cdmemory = 1\r
+asm_32xdraw = 1\r
 #profile = 1\r
 #drc_debug = 3\r
 \r
index 2994fdb..a15ff89 100644 (file)
@@ -1,7 +1,15 @@
-// (c) Copyright 2006-2009 notaz, All rights reserved.\r
-// Free for non-commercial use.\r
-\r
-// For commercial use, separate licencing terms must be obtained.\r
+/*\r
+ * (c) Copyright 2006-2010 notaz, All rights reserved.\r
+ *\r
+ * For performance reasons 3 renderers are exported for both MD and 32x modes:\r
+ * - 16bpp line renderer\r
+ * - 8bpp line renderer (slightly faster)\r
+ * - 8bpp tile renderer\r
+ * In 32x mode:\r
+ * - 32x layer is overlayed on top of 16bpp one\r
+ * - line internal one done on PicoDraw2FB, then mixed with 32x\r
+ * - tile internal one done on PicoDraw2FB, then mixed with 32x\r
+ */\r
 \r
 #include <stdio.h>\r
 #include <stdlib.h>\r
@@ -37,6 +45,11 @@ static short __attribute__((aligned(4))) sndBuffer[2*(44100+100)/50];
 static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];\r
 unsigned char *PicoDraw2FB = PicoDraw2FB_;\r
 static int osd_fps_x, osd_y;\r
+const char *renderer_names_[] = { "16bit accurate", " 8bit accurate", "     8bit fast", NULL };\r
+const char *renderer_names32x_[] = { "accurate", "faster  ", "fastest ", NULL };\r
+const char **renderer_names = renderer_names_;\r
+const char **renderer_names32x = renderer_names32x_;\r
+enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
 \r
 extern void *gp2x_screens[4];\r
 \r
@@ -62,6 +75,7 @@ void pemu_prep_defconfig(void)
        gp2x_soc_t soc;\r
 \r
        defaultConfig.CPUclock = default_cpu_clock;\r
+       defaultConfig.renderer32x = RT_8BIT_FAST;\r
 \r
        soc = soc_detect();\r
        if (soc == SOCID_MMSP2)\r
@@ -87,6 +101,31 @@ void pemu_validate_config(void)
                currentConfig.CPUclock = default_cpu_clock;\r
 }\r
 \r
+static int get_renderer(void)\r
+{\r
+       if (PicoAHW & PAHW_32X)\r
+               return currentConfig.renderer32x;\r
+       else\r
+               return currentConfig.renderer;\r
+}\r
+\r
+static void change_renderer(int diff)\r
+{\r
+       int *r;\r
+       if (PicoAHW & PAHW_32X)\r
+               r = &currentConfig.renderer32x;\r
+       else\r
+               r = &currentConfig.renderer;\r
+       *r += diff;\r
+       if      (*r >= RT_COUNT)\r
+               *r = 0;\r
+       else if (*r < 0)\r
+               *r = RT_COUNT - 1;\r
+}\r
+\r
+#define is_16bit_mode() \\r
+       (get_renderer() == RT_16BIT || (PicoAHW & PAHW_32X))\r
+\r
 static void (*osd_text)(int x, int y, const char *text);\r
 \r
 static void osd_text8(int x, int y, const char *text)\r
@@ -160,7 +199,7 @@ static void draw_cd_leds(void)
                scr_offs = pitch * 2 + 4;\r
        }\r
 \r
-       if ((PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP)) {\r
+       if (!is_16bit_mode()) {\r
        #define p(x) px[(x) >> 2]\r
                // 8-bit modes\r
                unsigned int *px = (unsigned int *)((char *)g_screen_ptr + scr_offs);\r
@@ -187,7 +226,7 @@ static void draw_pico_ptr(void)
        int x, y, pitch = 320;\r
 \r
        // only if pen enabled and for 16bit modes\r
-       if (pico_inp_mode == 0 || (PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP))\r
+       if (pico_inp_mode == 0 || currentConfig.EmuOpt != RT_16BIT)\r
                return;\r
 \r
        x = pico_pen_x + PICO_PEN_ADJUST_X;\r
@@ -208,20 +247,6 @@ static void draw_pico_ptr(void)
        p[pitch*2] ^= 0xffff;\r
 }\r
 \r
-static int EmuScanBegin16(unsigned int num)\r
-{\r
-       DrawLineDest = (unsigned short *) g_screen_ptr + g_screen_width * num;\r
-\r
-       return 0;\r
-}\r
-\r
-static int EmuScanBegin8(unsigned int num)\r
-{\r
-       DrawLineDest = (unsigned char *)  g_screen_ptr + g_screen_width * num;\r
-\r
-       return 0;\r
-}\r
-\r
 /* rot thing for Wiz */\r
 static unsigned char __attribute__((aligned(4))) rot_buff[320*4*2];\r
 \r
@@ -307,7 +332,9 @@ void pemu_finalize_frame(const char *fps, const char *notice)
        int emu_opt = currentConfig.EmuOpt;\r
        int ret;\r
 \r
-       if (PicoOpt & POPT_ALT_RENDERER)\r
+       if (PicoAHW & PAHW_32X)\r
+               ; // nothing to do\r
+       else if (get_renderer() == RT_8BIT_FAST)\r
        {\r
                // 8bit fast renderer\r
                if (Pico.m.dirtyPal) {\r
@@ -323,7 +350,7 @@ void pemu_finalize_frame(const char *fps, const char *notice)
                vidcpyM2(g_screen_ptr, PicoDraw2FB+328*8,\r
                        !(Pico.video.reg[12] & 1), !(PicoOpt & POPT_DIS_32C_BORDER));\r
        }\r
-       else if (!(emu_opt & EOPT_16BPP))\r
+       else if (get_renderer() == RT_8BIT_ACC)\r
        {\r
                // 8bit accurate renderer\r
                if (Pico.m.dirtyPal)\r
@@ -348,7 +375,12 @@ void pemu_finalize_frame(const char *fps, const char *notice)
 \r
 void plat_video_flip(void)\r
 {\r
+       int stride = g_screen_width;\r
        gp2x_video_flip();\r
+\r
+       if (is_16bit_mode())\r
+               stride *= 2;\r
+       PicoDrawSetOutBuf(g_screen_ptr, stride);\r
 }\r
 \r
 /* XXX */\r
@@ -385,7 +417,7 @@ void plat_video_wait_vsync(void)
 \r
 void plat_status_msg_clear(void)\r
 {\r
-       int is_8bit = (PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP);\r
+       int is_8bit = !is_16bit_mode();\r
        if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
                /* ugh.. */\r
                int i, u, *p;\r
@@ -431,47 +463,78 @@ void plat_status_msg_busy_first(const char *msg)
 \r
 static void vidResetMode(void)\r
 {\r
+       int gp2x_mode = 16;\r
+       int renderer = get_renderer();\r
+\r
+       PicoScanBegin = NULL;\r
        PicoScanEnd = NULL;\r
 \r
-       if (PicoOpt & POPT_ALT_RENDERER) {\r
-               if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
-                       gp2x_video_changemode(-8);\r
-                       vidcpyM2 = vidcpy_m2_rot;\r
-                       osd_text = osd_text8_rot;\r
-               } else {\r
-                       gp2x_video_changemode(8);\r
-                       vidcpyM2 = vidcpy_m2;\r
-                       osd_text = osd_text8;\r
-               }\r
-       }\r
-       else if (currentConfig.EmuOpt & EOPT_16BPP) {\r
-               PicoDrawSetColorFormat(1);\r
+       switch (renderer) {\r
+       case RT_16BIT:\r
+               PicoOpt &= ~POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_RGB555, 0);\r
+               PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
                if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
-                       gp2x_video_changemode(-16);\r
                        PicoScanBegin = EmuScanBegin16_rot;\r
                        PicoScanEnd = EmuScanEnd16_rot;\r
-                       osd_text = osd_text16_rot;\r
-               } else {\r
-                       gp2x_video_changemode(16);\r
-                       PicoScanBegin = EmuScanBegin16;\r
-                       osd_text = osd_text16;\r
                }\r
-       }\r
-       else {\r
-               PicoDrawSetColorFormat(2);\r
+               break;\r
+       case RT_8BIT_ACC:\r
+               PicoOpt &= ~POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_8BIT, 0);\r
+               PicoDrawSetOutBuf(g_screen_ptr, g_screen_width);\r
                if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
-                       gp2x_video_changemode(-8);\r
                        PicoScanBegin = EmuScanBegin8_rot;\r
                        PicoScanEnd = EmuScanEnd8_rot;\r
-                       osd_text = osd_text8_rot;\r
-               } else {\r
-                       gp2x_video_changemode(8);\r
-                       PicoScanBegin = EmuScanBegin8;\r
-                       osd_text = osd_text8;\r
                }\r
+               gp2x_mode = 8;\r
+               break;\r
+       case RT_8BIT_FAST:\r
+               PicoOpt |=  POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_NONE, 0);\r
+               if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
+                       vidcpyM2 = vidcpy_m2_rot;\r
+               else\r
+                       vidcpyM2 = vidcpy_m2;\r
+               gp2x_mode = 8;\r
+               break;\r
        }\r
 \r
-       if ((PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP)) {\r
+       if (is_16bit_mode())\r
+               osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text16_rot : osd_text16;\r
+       else\r
+               osd_text = (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) ? osd_text8_rot : osd_text8;\r
+\r
+       if (PicoAHW & PAHW_32X) {\r
+               // rules change in 32X world\r
+               if (renderer != RT_16BIT) {\r
+                       PicoDrawSetOutFormat(PDF_NONE, 0);\r
+                       PicoScanBegin = NULL;\r
+                       PicoScanEnd = NULL;\r
+               }\r
+               PicoScan32xBegin = NULL;\r
+               PicoScan32xEnd = NULL;\r
+               if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX) {\r
+                       PicoScan32xBegin = EmuScanBegin16_rot;\r
+                       PicoScan32xEnd = EmuScanEnd16_rot;\r
+               }\r
+               // Wiz 16bit is an exception, uses line rendering due to rotation mess\r
+               if (renderer == RT_16BIT && (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)) {\r
+                       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
+                       PicoDraw32xSetFrameMode(0, 0);\r
+               }\r
+               else {\r
+                       PicoDraw32xSetFrameMode(1, (renderer == RT_16BIT) ? 1 : 0);\r
+               }\r
+               PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
+               gp2x_mode = 16;\r
+       }\r
+\r
+       if (currentConfig.EmuOpt & EOPT_WIZ_TEAR_FIX)\r
+               gp2x_mode = -gp2x_mode;\r
+       gp2x_video_changemode(gp2x_mode);\r
+\r
+       if (!is_16bit_mode()) {\r
                // setup pal for 8-bit modes\r
                localPal[0xc0] = 0x0000c000; // MCD LEDs\r
                localPal[0xd0] = 0x00c00000;\r
@@ -492,41 +555,20 @@ static void vidResetMode(void)
        make_local_pal = (PicoAHW & PAHW_SMS) ? make_local_pal_sms : make_local_pal_md;\r
 }\r
 \r
-void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu)\r
+void plat_video_toggle_renderer(int change, int is_menu_call)\r
 {\r
-       if (force_16bpp) {\r
-               PicoOpt &= ~POPT_ALT_RENDERER;\r
-               currentConfig.EmuOpt |= EOPT_16BPP;\r
-       }\r
-       /* alt, 16bpp, 8bpp */\r
-       else if (PicoOpt & POPT_ALT_RENDERER) {\r
-               PicoOpt &= ~POPT_ALT_RENDERER;\r
-               if (is_next)\r
-                       currentConfig.EmuOpt |= EOPT_16BPP;\r
-       } else if (!(currentConfig.EmuOpt & EOPT_16BPP)) {\r
-               if (is_next)\r
-                       PicoOpt |= POPT_ALT_RENDERER;\r
-               else\r
-                       currentConfig.EmuOpt |= EOPT_16BPP;\r
-       } else {\r
-               currentConfig.EmuOpt &= ~EOPT_16BPP;\r
-               if (!is_next)\r
-                       PicoOpt |= POPT_ALT_RENDERER;\r
-       }\r
+       change_renderer(change);\r
 \r
-       if (is_menu)\r
+       if (is_menu_call)\r
                return;\r
 \r
        vidResetMode();\r
        rendstatus_old = -1;\r
 \r
-       if (PicoOpt & POPT_ALT_RENDERER) {\r
-               emu_status_msg(" 8bit fast renderer");\r
-       } else if (currentConfig.EmuOpt & EOPT_16BPP) {\r
-               emu_status_msg("16bit accurate renderer");\r
-       } else {\r
-               emu_status_msg(" 8bit accurate renderer");\r
-       }\r
+       if (PicoAHW & PAHW_32X)\r
+               emu_status_msg(renderer_names32x[get_renderer()]);\r
+       else\r
+               emu_status_msg(renderer_names[get_renderer()]);\r
 }\r
 \r
 #if 0 // TODO\r
@@ -695,20 +737,19 @@ void pemu_sound_wait(void)
 void pemu_forced_frame(int opts)\r
 {\r
        int po_old = PicoOpt;\r
-       int eo_old = currentConfig.EmuOpt;\r
 \r
        PicoOpt &= ~POPT_ALT_RENDERER;\r
        PicoOpt |= opts|POPT_ACC_SPRITES;\r
-       currentConfig.EmuOpt |= EOPT_16BPP;\r
 \r
-       PicoDrawSetColorFormat(1);\r
-       PicoScanBegin = EmuScanBegin16;\r
+       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
+       PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
+       PicoDraw32xSetFrameMode(0, 0);\r
+       PicoScanBegin = NULL;\r
        PicoScanEnd = NULL;\r
        Pico.m.dirtyPal = 1;\r
        PicoFrameDrawOnly();\r
 \r
        PicoOpt = po_old;\r
-       currentConfig.EmuOpt = eo_old;\r
 }\r
 \r
 void plat_debug_cat(char *str)\r
@@ -733,7 +774,7 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols)
                gp2x_video_RGB_setscaling(0, scalex, 240);\r
 \r
        // clear whole screen in all buffers\r
-       if ((PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP))\r
+       if (!is_16bit_mode())\r
                gp2x_memset_all_buffers(0, 0xe0, 320*240);\r
        else\r
                gp2x_memset_all_buffers(0, 0, 320*240*2);\r
@@ -848,11 +889,12 @@ void pemu_loop_end(void)
        /* do one more frame for menu bg */\r
        PicoOpt &= ~POPT_ALT_RENDERER;\r
        PicoOpt |= POPT_EN_SOFTSCALE|POPT_ACC_SPRITES;\r
-       currentConfig.EmuOpt |= EOPT_16BPP;\r
 \r
-       PicoScanBegin = EmuScanBegin16;\r
+       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
+       PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
+       PicoDraw32xSetFrameMode(0, 0);\r
+       PicoScanBegin = NULL;\r
        PicoScanEnd = NULL;\r
-       PicoDrawSetColorFormat(1);\r
        Pico.m.dirtyPal = 1;\r
        PicoFrame();\r
 \r
index da94d05..fb9d24a 100644 (file)
@@ -53,17 +53,6 @@ static void menu_main_plat_draw(void)
 
 // ------------ gfx options menu ------------
 
-static const char *mgn_opt_renderer(menu_id id, int *offs)
-{
-       *offs = -11;
-       if (PicoOpt & POPT_ALT_RENDERER)
-               return "     8bit fast";
-       else if (currentConfig.EmuOpt & EOPT_16BPP)
-               return "16bit accurate";
-       else
-               return " 8bit accurate";
-}
-
 static const char *mgn_opt_scaling(menu_id id, int *offs)
 {
        *offs = -13;
index 5480ae8..1f4fdd0 100644 (file)
@@ -12,9 +12,6 @@
 #define SCREEN_WIDTH  320\r
 #define SCREEN_HEIGHT 240\r
 \r
-// draw.c\r
-#define OVERRIDE_HIGHCOL 0\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
index 5a41036..10d53ac 100644 (file)
@@ -6,7 +6,6 @@
 .equiv START_ROW,               0\r
 .equiv END_ROW,                28\r
 \r
-.equiv OVERRIDE_HIGHCOL,        0\r
 .equiv UNALIGNED_DRAWLINEDEST,  0\r
 \r
 @ this should be set to one only for GP2X port\r
index 98e2b72..7dc2c14 100644 (file)
 \r
 static short __attribute__((aligned(4))) sndBuffer[2*44100/50];\r
 char cpu_clk_name[] = "unused";\r
+const char *renderer_names_[] = { "16bit accurate", " 8bit accurate", "     8bit fast", NULL };\r
+const char *renderer_names32x_[] = { "accurate", "faster  ", "fastest ", NULL };\r
+const char **renderer_names = renderer_names_;\r
+const char **renderer_names32x = renderer_names32x_;\r
+enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };\r
 \r
 \r
 void pemu_prep_defconfig(void)\r
@@ -75,7 +80,7 @@ static void draw_cd_leds(void)
        led_offs = 4;\r
        scr_offs = pitch * 2 + 4;\r
 \r
-       if ((PicoOpt & POPT_ALT_RENDERER) || !(currentConfig.EmuOpt & EOPT_16BPP)) {\r
+       if (currentConfig.renderer != RT_16BIT) {\r
        #define p(x) px[(x) >> 2]\r
                // 8-bit modes\r
                unsigned int *px = (unsigned int *)((char *)g_screen_ptr + scr_offs);\r
@@ -96,15 +101,20 @@ static void draw_cd_leds(void)
        }\r
 }\r
 \r
-static int EmuScanBegin16(unsigned int num)\r
-{\r
-       DrawLineDest = (unsigned short *)g_screen_ptr + num * g_screen_width;\r
-\r
-       return 0;\r
-}\r
-\r
 void pemu_finalize_frame(const char *fps, const char *notice)\r
 {\r
+       if (currentConfig.renderer != RT_16BIT && !(PicoAHW & PAHW_32X)) {\r
+               unsigned short *pd = (unsigned short *)g_screen_ptr + 8 * g_screen_width;\r
+               unsigned char *ps = PicoDraw2FB + 328*8 + 8;\r
+               unsigned short *pal = HighPal;\r
+               int i, x;\r
+               if (Pico.m.dirtyPal)\r
+                       PicoDrawUpdateHighPal();\r
+               for (i = 0; i < 224; i++, ps += 8)\r
+                       for (x = 0; x < 320; x++)\r
+                               *pd++ = pal[*ps++];\r
+       }\r
+\r
        if (notice || (currentConfig.EmuOpt & EOPT_SHOW_FPS)) {\r
                if (notice)\r
                        osd_text(4, g_screen_height - 8, notice);\r
@@ -115,10 +125,51 @@ void pemu_finalize_frame(const char *fps, const char *notice)
                draw_cd_leds();\r
 }\r
 \r
-void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu)\r
+static void apply_renderer(void)\r
+{\r
+       PicoScanBegin = NULL;\r
+       PicoScanEnd = NULL;\r
+\r
+       switch (currentConfig.renderer) {\r
+       case RT_16BIT:\r
+               PicoOpt &= ~POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_RGB555, 0);\r
+               PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
+               break;\r
+       case RT_8BIT_ACC:\r
+               PicoOpt &= ~POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_8BIT, 0);\r
+               PicoDrawSetOutBuf(PicoDraw2FB + 8, 328);\r
+               break;\r
+       case RT_8BIT_FAST:\r
+               PicoOpt |=  POPT_ALT_RENDERER;\r
+               PicoDrawSetOutFormat(PDF_NONE, 0);\r
+               break;\r
+       }\r
+\r
+       if (PicoAHW & PAHW_32X) {\r
+               int only_32x = 0;\r
+               if (currentConfig.renderer == RT_16BIT)\r
+                       only_32x = 1;\r
+               else\r
+                       PicoDrawSetOutFormat(PDF_NONE, 0);\r
+               PicoDraw32xSetFrameMode(1, only_32x);\r
+               PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);\r
+       }\r
+}\r
+\r
+void plat_video_toggle_renderer(int change, int is_menu)\r
 {\r
-       // this will auto-select SMS/32X renderers\r
-       PicoDrawSetColorFormat(1);\r
+       currentConfig.renderer += change;\r
+       if      (currentConfig.renderer >= RT_COUNT)\r
+               currentConfig.renderer = 0;\r
+       else if (currentConfig.renderer < 0)\r
+               currentConfig.renderer = RT_COUNT - 1;\r
+\r
+       if (!is_menu)\r
+               apply_renderer();\r
+\r
+       emu_status_msg(renderer_names[currentConfig.renderer]);\r
 }\r
 \r
 void plat_video_menu_enter(int is_rom_loaded)\r
@@ -168,10 +219,8 @@ void pemu_forced_frame(int opts)
 \r
        PicoOpt &= ~POPT_ALT_RENDERER;\r
        PicoOpt |= opts|POPT_ACC_SPRITES; // acc_sprites\r
-       currentConfig.EmuOpt |= EOPT_16BPP;\r
 \r
-       PicoDrawSetColorFormat(1);\r
-       PicoScanBegin = EmuScanBegin16;\r
+       PicoDrawSetOutFormat(PDF_RGB555, 0);\r
 \r
        Pico.m.dirtyPal = 1;\r
        PicoFrameDrawOnly();\r
@@ -244,8 +293,7 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols)
 \r
 void pemu_loop_prep(void)\r
 {\r
-       PicoDrawSetColorFormat(1);\r
-       PicoScanBegin = EmuScanBegin16;\r
+       apply_renderer();\r
        osd_text = osd_text16;\r
 \r
        pemu_sound_start();\r
@@ -262,9 +310,8 @@ void pemu_loop_end(void)
        /* do one more frame for menu bg */\r
        PicoOpt &= ~POPT_ALT_RENDERER;\r
        PicoOpt |= POPT_EN_SOFTSCALE|POPT_ACC_SPRITES;\r
-       currentConfig.EmuOpt |= EOPT_16BPP;\r
 \r
-       PicoDrawSetColorFormat(1);\r
+       PicoDrawSetOutFormat(PDF_RGB555, 0);\r
        Pico.m.dirtyPal = 1;\r
        PicoFrame();\r
 \r
index f576048..7e05d7d 100644 (file)
@@ -13,9 +13,6 @@
 #define SCREEN_WIDTH  320
 #define SCREEN_HEIGHT 240
 
-// draw.c
-#define OVERRIDE_HIGHCOL 0
-
 // draw2.c
 #define START_ROW  0 // which row of tiles to start rendering at?
 #define END_ROW   28 // ..end
index f7c2a2e..2bd8be8 100644 (file)
@@ -23,6 +23,8 @@
 static short __attribute__((aligned(4))) sndBuffer[2*44100/50];\r
 static unsigned char temp_frame[g_screen_width * g_screen_height * 2];\r
 unsigned char *PicoDraw2FB = temp_frame;\r
+const char **renderer_names = NULL;\r
+const char **renderer_names32x = NULL;\r
 char cpu_clk_name[] = "unused";\r
 \r
 \r
@@ -43,7 +45,7 @@ static void osd_text(int x, int y, const char *text)
 {\r
        int len = strlen(text)*8;\r
 \r
-       if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) {\r
+       if (0) {\r
                int *p, i, h;\r
                x &= ~3; // align x\r
                len = (len+3) >> 2;\r
@@ -71,7 +73,7 @@ static void draw_cd_leds(void)
 //     if (!((Pico_mcd->s68k_regs[0] ^ old_reg) & 3)) return; // no change // mmu hack problems?\r
        old_reg = Pico_mcd->s68k_regs[0];\r
 \r
-       if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) {\r
+       if (0) {\r
                // 8-bit modes\r
                unsigned int col_g = (old_reg & 2) ? 0xc0c0c0c0 : 0xe0e0e0e0;\r
                unsigned int col_r = (old_reg & 1) ? 0xd0d0d0d0 : 0xe0e0e0e0;\r
@@ -183,10 +185,10 @@ void pemu_finalize_frame(const char *fps, const char *notice)
                draw_cd_leds();\r
 }\r
 \r
-void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu)\r
+void plat_video_toggle_renderer(int change, int is_menu)\r
 {\r
        // this will auto-select SMS/32X renderers\r
-       PicoDrawSetColorFormat(1);\r
+       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
 }\r
 \r
 void plat_video_menu_enter(int is_rom_loaded)\r
@@ -251,17 +253,14 @@ void plat_update_volume(int has_changed, int is_up)
 void pemu_forced_frame(int opts)\r
 {\r
        int po_old = PicoOpt;\r
-       int eo_old = currentConfig.EmuOpt;\r
 \r
        PicoOpt &= ~0x10;\r
        PicoOpt |= opts|POPT_ACC_SPRITES; // acc_sprites\r
-       currentConfig.EmuOpt |= 0x80;\r
 \r
        Pico.m.dirtyPal = 1;\r
        PicoFrameDrawOnly();\r
 \r
        PicoOpt = po_old;\r
-       currentConfig.EmuOpt = eo_old;\r
 }\r
 \r
 static void updateSound(int len)\r
@@ -339,16 +338,16 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols)
                memset32(fbdev_buffers[i], 0, g_screen_width * g_screen_height * 2 / 4);\r
 \r
 #ifdef USE_320_SCREEN\r
-       PicoDrawSetColorFormat(1);\r
+       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
        PicoScanBegin = EmuScanBegin16;\r
 #else\r
        if (PicoAHW & PAHW_32X) {\r
                DrawLineDest = (unsigned short *)temp_frame;\r
-               PicoDrawSetColorFormat(1);\r
+               PicoDrawSetOutFormat(PDF_RGB555, 1);\r
                PicoScanBegin = NULL;\r
                PicoScanEnd = EmuScanEnd16_32x;\r
        } else {\r
-               PicoDrawSetColorFormat(-1);\r
+               PicoDrawSetOutFormat(PDF_NONE, 0);\r
                PicoScanBegin = NULL;\r
                PicoScanEnd = EmuScanEnd16;\r
        }\r
@@ -374,7 +373,7 @@ void pemu_loop_end(void)
        PicoOpt |= POPT_EN_SOFTSCALE|POPT_ACC_SPRITES;\r
        currentConfig.EmuOpt |= EOPT_16BPP;\r
 \r
-       PicoDrawSetColorFormat(1);\r
+       PicoDrawSetOutFormat(PDF_RGB555, 1);\r
        Pico.m.dirtyPal = 1;\r
        PicoFrame();\r
 \r
index fa33f3d..5b7b9f7 100644 (file)
@@ -6,4 +6,3 @@
        mee_onoff     ("Status line in main menu", MA_OPT2_STATUS_LINE,   currentConfig.EmuOpt, EOPT_SHOW_RTC),
 
 #define menu_main_plat_draw NULL
-#define mgn_opt_renderer NULL
index 0c071bd..a670c1c 100644 (file)
@@ -11,9 +11,6 @@
 #define SCREEN_WIDTH  800\r
 #define SCREEN_HEIGHT 480\r
 \r
-// draw.c\r
-#define OVERRIDE_HIGHCOL 0\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
index 5a41036..10d53ac 100644 (file)
@@ -6,7 +6,6 @@
 .equiv START_ROW,               0\r
 .equiv END_ROW,                28\r
 \r
-.equiv OVERRIDE_HIGHCOL,        0\r
 .equiv UNALIGNED_DRAWLINEDEST,  0\r
 \r
 @ this should be set to one only for GP2X port\r
index 9af4fe5..6169940 100644 (file)
@@ -465,7 +465,7 @@ static void vidResetMode(void)
        sceGuTexImage(0,512,512,512,(char *)VRAM_STUFF + 16);
 
        // slow rend.
-       PicoDrawSetColorFormat(-1);
+       PicoDrawSetOutFormat(PDF_NONE, 0);
        PicoScanBegin = EmuScanSlowBegin;
        PicoScanEnd = EmuScanSlowEnd;
 
@@ -682,7 +682,7 @@ void pemu_forced_frame(int opts)
        memset32((int *)VRAM_CACHED_STUFF + 512*232/4, 0xe0e0e0e0, 512*8/4);
        memset32_uncached((int *)psp_screen + 512*264*2/4, 0, 512*8*2/4);
 
-       PicoDrawSetColorFormat(-1);
+       PicoDrawSetOutFormat(PDF_NONE, 0);
        PicoScanBegin = EmuScanSlowBegin;
        PicoScanEnd = EmuScanSlowEnd;
        EmuScanPrepare();
index cc42e6c..d07c9f4 100644 (file)
@@ -14,7 +14,6 @@
 \r
 // draw.c\r
 #define USE_BGR555 1\r
-#define OVERRIDE_HIGHCOL 1\r
 \r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
index 6785d25..2eea033 100644 (file)
@@ -8,9 +8,6 @@
 #define REDUCE_IO_CALLS 0\r
 #define SIMPLE_WRITE_SOUND 0\r
 \r
-// draw.c\r
-#define OVERRIDE_HIGHCOL 0\r
-\r
 // draw2.c\r
 #define START_ROW  0 // which row of tiles to start rendering at?\r
 #define END_ROW   28 // ..end\r
index 59fd9aa..e0b359a 100644 (file)
@@ -6,7 +6,6 @@
 .equiv START_ROW,               0\r
 .equiv END_ROW,                28\r
 \r
-.equiv OVERRIDE_HIGHCOL,        0\r
 .equiv UNALIGNED_DRAWLINEDEST,  0\r
 \r
 @ this should be set to one only for GP2X port\r
index e5e2f7e..4173da3 100644 (file)
@@ -13,6 +13,8 @@
 static unsigned short screen_buff[320 * 240];
 static unsigned char PicoDraw2FB_[(8+320) * (8+240+8)];
 unsigned char *PicoDraw2FB = PicoDraw2FB_;
+const char **renderer_names = NULL;
+const char **renderer_names32x = NULL;
 
 char cpu_clk_name[] = "unused";
 
@@ -68,17 +70,10 @@ void pemu_validate_config(void)
 {
 }
 
-static int EmuScanBegin16(unsigned int num)
-{
-       DrawLineDest = (unsigned short *) g_screen_ptr + g_screen_width * num;
-
-       return 0;
-}
-
 void pemu_loop_prep(void)
 {
-       PicoDrawSetColorFormat(1);
-       PicoScanBegin = EmuScanBegin16;
+       PicoDrawSetOutFormat(PDF_RGB555, 1);
+       PicoDrawSetOutBuf(g_screen_ptr, g_screen_width * 2);
        pemu_sound_start();
 }
 
@@ -105,10 +100,10 @@ void plat_video_wait_vsync(void)
 {
 }
 
-void plat_video_toggle_renderer(int is_next, int force_16bpp, int is_menu)
+void plat_video_toggle_renderer(int change, int is_menu)
 {
        // this will auto-select SMS/32X renderers
-       PicoDrawSetColorFormat(1);
+       PicoDrawSetOutFormat(PDF_RGB555, 1);
 }
 
 void emu_video_mode_change(int start_line, int line_count, int is_32cols)
index 04b4c93..d6a09cc 100644 (file)
@@ -13,9 +13,6 @@
 #define SCREEN_WIDTH  320
 #define SCREEN_HEIGHT 240
 
-// draw.c
-#define OVERRIDE_HIGHCOL 0
-
 // draw2.c
 #define START_ROW  0 // which row of tiles to start rendering at?
 #define END_ROW   28 // ..end