new faster sprite priority and sh/hi hadling
authornotaz <notasas@gmail.com>
Tue, 17 Jun 2008 19:48:15 +0000 (19:48 +0000)
committernotaz <notasas@gmail.com>
Tue, 17 Jun 2008 19:48:15 +0000 (19:48 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@486 be3aeb3a-fb24-0410-a615-afba39da0efa

Pico/Draw.c
Pico/Draw.s
platform/gp2x/gp2x.c

index 7c092de..019fdc0 100644 (file)
@@ -36,6 +36,7 @@ static int  HighCacheA[41+1];   // caches for high layers
 static int  HighCacheB[41+1];\r
 static int  HighCacheS[80+1];   // and sprites\r
 static int  HighPreSpr[80*2+1]; // slightly preprocessed sprites\r
+int *HighCacheS_ptr;\r
 \r
 int rendstatus = 0;\r
 int Scanline = 0; // Scanline\r
@@ -62,7 +63,7 @@ struct TileStrip
 #ifdef _ASM_DRAW_C\r
 void DrawWindow(int tstart, int tend, int prio, int sh);\r
 void BackFill(int reg7, int sh);\r
-void DrawSprite(int *sprite, int **hc, int sh, int as);\r
+void DrawSprite(int *sprite, int sh, int as);\r
 void DrawTilesFromCache(int *hc, int sh, int rlim);\r
 void DrawSpritesFromCache(int *hc, int maxwidth, int prio, int sh);\r
 void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells);\r
@@ -82,202 +83,115 @@ void blockcpy_or(void *dst, void *src, size_t n, int pat)
 #endif\r
 \r
 \r
-#ifdef _ASM_DRAW_C_AMIPS\r
-int TileNorm(int sx,int addr,int pal);\r
-int TileFlip(int sx,int addr,int pal);\r
-#else\r
-static int TileNorm(int sx,int addr,int pal)\r
-{\r
-  unsigned char *pd = HighCol+sx;\r
-  unsigned int pack=0; unsigned int t=0;\r
-\r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=pack&0x0000f000; if (t) pd[0]=(unsigned char)(pal|(t>>12));\r
-    t=pack&0x00000f00; if (t) pd[1]=(unsigned char)(pal|(t>> 8));\r
-    t=pack&0x000000f0; if (t) pd[2]=(unsigned char)(pal|(t>> 4));\r
-    t=pack&0x0000000f; if (t) pd[3]=(unsigned char)(pal|(t    ));\r
-    t=pack&0xf0000000; if (t) pd[4]=(unsigned char)(pal|(t>>28));\r
-    t=pack&0x0f000000; if (t) pd[5]=(unsigned char)(pal|(t>>24));\r
-    t=pack&0x00f00000; if (t) pd[6]=(unsigned char)(pal|(t>>20));\r
-    t=pack&0x000f0000; if (t) pd[7]=(unsigned char)(pal|(t>>16));\r
-    return 0;\r
-  }\r
-\r
-  return 1; // Tile blank\r
+#define TileNormMaker(funcname,pix_func)                     \\r
+static int funcname(int sx,int addr,int pal)                 \\r
+{                                                            \\r
+  unsigned char *pd = HighCol+sx;                            \\r
+  unsigned int pack=0; unsigned int t=0;                     \\r
+                                                             \\r
+  pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
+  if (pack)                                                  \\r
+  {                                                          \\r
+    t=(pack&0x0000f000)>>12; pix_func(0);                    \\r
+    t=(pack&0x00000f00)>> 8; pix_func(1);                    \\r
+    t=(pack&0x000000f0)>> 4; pix_func(2);                    \\r
+    t=(pack&0x0000000f)    ; pix_func(3);                    \\r
+    t=(pack&0xf0000000)>>28; pix_func(4);                    \\r
+    t=(pack&0x0f000000)>>24; pix_func(5);                    \\r
+    t=(pack&0x00f00000)>>20; pix_func(6);                    \\r
+    t=(pack&0x000f0000)>>16; pix_func(7);                    \\r
+    return 0;                                                \\r
+  }                                                          \\r
+                                                             \\r
+  return 1; /* Tile blank */                                 \\r
 }\r
 \r
-static int TileFlip(int sx,int addr,int pal)\r
-{\r
-  unsigned char *pd = HighCol+sx;\r
-  unsigned int pack=0; unsigned int t=0;\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=pack&0x000f0000; if (t) pd[0]=(unsigned char)(pal|(t>>16));\r
-    t=pack&0x00f00000; if (t) pd[1]=(unsigned char)(pal|(t>>20));\r
-    t=pack&0x0f000000; if (t) pd[2]=(unsigned char)(pal|(t>>24));\r
-    t=pack&0xf0000000; if (t) pd[3]=(unsigned char)(pal|(t>>28));\r
-    t=pack&0x0000000f; if (t) pd[4]=(unsigned char)(pal|(t    ));\r
-    t=pack&0x000000f0; if (t) pd[5]=(unsigned char)(pal|(t>> 4));\r
-    t=pack&0x00000f00; if (t) pd[6]=(unsigned char)(pal|(t>> 8));\r
-    t=pack&0x0000f000; if (t) pd[7]=(unsigned char)(pal|(t>>12));\r
-    return 0;\r
-  }\r
-  return 1; // Tile blank\r
+#define TileFlipMaker(funcname,pix_func)                     \\r
+static int funcname(int sx,int addr,int pal)                 \\r
+{                                                            \\r
+  unsigned char *pd = HighCol+sx;                            \\r
+  unsigned int pack=0; unsigned int t=0;                     \\r
+                                                             \\r
+  pack=*(unsigned int *)(Pico.vram+addr); /* Get 8 pixels */ \\r
+  if (pack)                                                  \\r
+  {                                                          \\r
+    t=(pack&0x000f0000)>>16; pix_func(0);                    \\r
+    t=(pack&0x00f00000)>>20; pix_func(1);                    \\r
+    t=(pack&0x0f000000)>>24; pix_func(2);                    \\r
+    t=(pack&0xf0000000)>>28; pix_func(3);                    \\r
+    t=(pack&0x0000000f)    ; pix_func(4);                    \\r
+    t=(pack&0x000000f0)>> 4; pix_func(5);                    \\r
+    t=(pack&0x00000f00)>> 8; pix_func(6);                    \\r
+    t=(pack&0x0000f000)>>12; pix_func(7);                    \\r
+    return 0;                                                \\r
+  }                                                          \\r
+                                                             \\r
+  return 1; /* Tile blank */                                 \\r
 }\r
-#endif\r
 \r
-// tile renderers for hacky operator sprite support\r
-#define sh_pix(x) \\r
-  if(!t); \\r
-  else if(t==0xe) pd[x]=(unsigned char)((pd[x]&0x3f)|0x80); /* hilight */ \\r
-  else if(t==0xf) pd[x]=(unsigned char)( pd[x]      |0xc0); /* shadow  */ \\r
-  else pd[x]=(unsigned char)(pal|t)\r
 \r
-#ifndef _ASM_DRAW_C\r
-static int TileNormSH(int sx,int addr,int pal)\r
-{\r
-  unsigned int pack=0; unsigned int t=0;\r
-  unsigned char *pd = HighCol+sx;\r
-\r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=(pack&0x0000f000)>>12; sh_pix(0);\r
-    t=(pack&0x00000f00)>> 8; sh_pix(1);\r
-    t=(pack&0x000000f0)>> 4; sh_pix(2);\r
-    t=(pack&0x0000000f)    ; sh_pix(3);\r
-    t=(pack&0xf0000000)>>28; sh_pix(4);\r
-    t=(pack&0x0f000000)>>24; sh_pix(5);\r
-    t=(pack&0x00f00000)>>20; sh_pix(6);\r
-    t=(pack&0x000f0000)>>16; sh_pix(7);\r
-    return 0;\r
-  }\r
+#ifdef _ASM_DRAW_C_AMIPS\r
+int TileNorm(int sx,int addr,int pal);\r
+int TileFlip(int sx,int addr,int pal);\r
+#else\r
 \r
-  return 1; // Tile blank\r
-}\r
+#define pix_just_write(x) \\r
+  if (t) pd[x]=pal|t\r
 \r
-static int TileFlipSH(int sx,int addr,int pal)\r
-{\r
-  unsigned int pack=0; unsigned int t=0;\r
-  unsigned char *pd = HighCol+sx;\r
+TileNormMaker(TileNorm,pix_just_write)\r
+TileFlipMaker(TileFlip,pix_just_write)\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=(pack&0x000f0000)>>16; sh_pix(0);\r
-    t=(pack&0x00f00000)>>20; sh_pix(1);\r
-    t=(pack&0x0f000000)>>24; sh_pix(2);\r
-    t=(pack&0xf0000000)>>28; sh_pix(3);\r
-    t=(pack&0x0000000f)    ; sh_pix(4);\r
-    t=(pack&0x000000f0)>> 4; sh_pix(5);\r
-    t=(pack&0x00000f00)>> 8; sh_pix(6);\r
-    t=(pack&0x0000f000)>>12; sh_pix(7);\r
-    return 0;\r
-  }\r
-  return 1; // Tile blank\r
-}\r
 #endif\r
 \r
-#define tilepixelAS(mask,index,shift) \\r
-  if (!(pd[index]&0xc0)) { t=pack&mask; if (t) pd[index]=(pal|(t>>shift)); }\r
+// draw a sprite pixel, process operator colors\r
+#define pix_sh(x) \\r
+  if (!t); \\r
+  else if (t==0xe) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \\r
+  else if (t==0xf) pd[x]= pd[x]      |0xc0; /* shadow  */ \\r
+  else pd[x]=pal|t\r
 \r
-static int TileNormAS(int sx,int addr,int pal)\r
-{\r
-  unsigned char *pd = HighCol+sx;\r
-  unsigned int pack=0; unsigned int t=0;\r
+TileNormMaker(TileNormSH, pix_sh)\r
+TileFlipMaker(TileFlipSH, pix_sh)\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    tilepixelAS(0x0000f000, 0, 12);\r
-    tilepixelAS(0x00000f00, 1,  8);\r
-    tilepixelAS(0x000000f0, 2,  4);\r
-    tilepixelAS(0x0000000f, 3,  0);\r
-    tilepixelAS(0xf0000000, 4, 28);\r
-    tilepixelAS(0x0f000000, 5, 24);\r
-    tilepixelAS(0x00f00000, 6, 20);\r
-    tilepixelAS(0x000f0000, 7, 16);\r
-    return 0;\r
-  }\r
+#ifndef _ASM_DRAW_C\r
+// draw a sprite pixel ignoring operator colors\r
+#define pix_sh_noop(x) \\r
+  if (t && t < 0xe) \\r
+    pd[x]=pal|t\r
 \r
-  return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormSH_noop, pix_sh_noop)\r
+TileFlipMaker(TileFlipSH_noop, pix_sh_noop)\r
+#endif\r
 \r
-static int TileFlipAS(int sx,int addr,int pal)\r
-{\r
-  unsigned char *pd = HighCol+sx;\r
-  unsigned int pack=0; unsigned int t=0;\r
+// process operator pixels only, apply only on low pri tiles\r
+#define pix_sh_onlyop(x) \\r
+  if      (t==0xe && (pd[x]&0x40)) pd[x]=(pd[x]&0x3f)|0x80; /* hilight */ \\r
+  else if (t==0xf && (pd[x]&0x40)) pd[x]= pd[x]      |0xc0; /* shadow  */\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    tilepixelAS(0x000f0000, 0, 16);\r
-    tilepixelAS(0x00f00000, 1, 20);\r
-    tilepixelAS(0x0f000000, 2, 24);\r
-    tilepixelAS(0xf0000000, 3, 28);\r
-    tilepixelAS(0x0000000f, 4,  0);\r
-    tilepixelAS(0x000000f0, 5,  4);\r
-    tilepixelAS(0x00000f00, 6,  8);\r
-    tilepixelAS(0x0000f000, 7, 12);\r
-    return 0;\r
-  }\r
-  return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormSH_onlyop_lp, pix_sh_onlyop)\r
+TileFlipMaker(TileFlipSH_onlyop_lp, pix_sh_onlyop)\r
 \r
-// there is a problem with transparent hi pri tiles (on layer), it will clear high bits\r
-// and sprite tiles will be drawn needlessly. Hopefully that won't happen much..\r
-#define sh_pixAS(x) \\r
-  if(!t); \\r
-  else if(t==0xe) pd[x]=(unsigned char)((pd[x]&0x3f)|0x80); /* hilight */ \\r
-  else if(t==0xf) pd[x]=(unsigned char)( pd[x]      |0xc0); /* shadow  */ \\r
-  else if(!(pd[x]&0xc0)) pd[x]=(unsigned char)(pal|t)\r
+// draw a sprite pixel (AS)\r
+#define pix_as(x) \\r
+  if (t && !(pd[x]&0x80)) pd[x]=pal|t\r
 \r
-static int TileNormSHAS(int sx,int addr,int pal)\r
-{\r
-  unsigned int pack=0; unsigned int t=0;\r
-  unsigned char *pd = HighCol+sx;\r
+TileNormMaker(TileNormAS, pix_as)\r
+TileFlipMaker(TileFlipAS, pix_as)\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=(pack&0x0000f000)>>12; sh_pixAS(0);\r
-    t=(pack&0x00000f00)>> 8; sh_pixAS(1);\r
-    t=(pack&0x000000f0)>> 4; sh_pixAS(2);\r
-    t=(pack&0x0000000f)    ; sh_pixAS(3);\r
-    t=(pack&0xf0000000)>>28; sh_pixAS(4);\r
-    t=(pack&0x0f000000)>>24; sh_pixAS(5);\r
-    t=(pack&0x00f00000)>>20; sh_pixAS(6);\r
-    t=(pack&0x000f0000)>>16; sh_pixAS(7);\r
-    return 0;\r
-  }\r
+// draw a sprite pixel, skip operator colors (AS)\r
+#define pix_sh_as_noop(x) \\r
+  if (t && t < 0xe && !(pd[x]&0x80)) pd[x]=pal|t\r
 \r
-  return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormAS_noop, pix_sh_as_noop)\r
+TileFlipMaker(TileFlipAS_noop, pix_sh_as_noop)\r
 \r
-static int TileFlipSHAS(int sx,int addr,int pal)\r
-{\r
-  unsigned int pack=0; unsigned int t=0;\r
-  unsigned char *pd = HighCol+sx;\r
+// mark pixel as sprite pixel (AS)\r
+#define pix_sh_as_onlymark(x) \\r
+  if (t) pd[x]|=0x80\r
 \r
-  pack=*(unsigned int *)(Pico.vram+addr); // Get 8 pixels\r
-  if (pack)\r
-  {\r
-    t=(pack&0x000f0000)>>16; sh_pixAS(0);\r
-    t=(pack&0x00f00000)>>20; sh_pixAS(1);\r
-    t=(pack&0x0f000000)>>24; sh_pixAS(2);\r
-    t=(pack&0xf0000000)>>28; sh_pixAS(3);\r
-    t=(pack&0x0000000f)    ; sh_pixAS(4);\r
-    t=(pack&0x000000f0)>> 4; sh_pixAS(5);\r
-    t=(pack&0x00000f00)>> 8; sh_pixAS(6);\r
-    t=(pack&0x0000f000)>>12; sh_pixAS(7);\r
-    return 0;\r
-  }\r
-  return 1; // Tile blank\r
-}\r
+TileNormMaker(TileNormAS_onlymark, pix_sh_as_onlymark)\r
+TileFlipMaker(TileFlipAS_onlymark, pix_sh_as_onlymark)\r
 \r
 \r
 // --------------------------------------------\r
@@ -512,7 +426,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
 static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache\r
 {\r
   struct PicoVideo *pvid=&Pico.video;\r
-  int tilex=0,ty=0,nametab,code=0;\r
+  int tilex,ty,nametab,code=0;\r
   int blank=-1; // The tile we know is blank\r
 \r
   // Find name table line:\r
@@ -528,9 +442,6 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
   }\r
 \r
   tilex=tstart<<1;\r
-  tend<<=1;\r
-\r
-  ty=(Scanline&7)<<1; // Y-Offset into tile\r
 \r
   if (!(rendstatus & PDRAW_WND_DIFF_PRIO)) {\r
     // check the first tile code\r
@@ -539,6 +450,9 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
     if ((code>>15) != prio) return;\r
   }\r
 \r
+  tend<<=1;\r
+  ty=(Scanline&7)<<1; // Y-Offset into tile\r
+\r
   // Draw tiles across screen:\r
   if (!sh)\r
   {\r
@@ -571,7 +485,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
     for (; tilex < tend; tilex++)\r
     {\r
       int addr=0,zero=0;\r
-      int pal, tmp, *zb;\r
+      int pal;\r
 \r
       code=Pico.vram[nametab+tilex];\r
       if(code==blank) continue;\r
@@ -582,15 +496,10 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
 \r
       pal=((code>>9)&0x30);\r
 \r
-      zb = (int *)(HighCol+8+(tilex<<3));\r
-      if(prio) {\r
-        tmp = *zb;\r
-        if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
-        if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
-        *zb++=tmp; tmp = *zb;\r
-        if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
-        if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
-        *zb++=tmp;\r
+      if (prio) {\r
+        int *zb = (int *)(HighCol+8+(tilex<<3));\r
+        *zb++ &= 0x3f3f3f3f;\r
+        *zb   &= 0x3f3f3f3f;\r
       } else {\r
         pal |= 0x40;\r
       }\r
@@ -617,14 +526,7 @@ static void DrawTilesFromCacheShPrep(void)
   rendstatus |= PDRAW_SHHI_DONE;\r
   while (c--)\r
   {\r
-    int tmp = *zb;\r
-    if (!(tmp & 0x80808080)) *zb=tmp&0x3f3f3f3f;\r
-    else {\r
-      if(!(tmp&0x00000080)) tmp&=~0x000000c0; if(!(tmp&0x00008000)) tmp&=~0x0000c000;\r
-      if(!(tmp&0x00800000)) tmp&=~0x00c00000; if(!(tmp&0x80000000)) tmp&=~0xc0000000;\r
-      *zb=tmp;\r
-    }\r
-    zb++;\r
+    *zb++ &= 0x3f3f3f3f;\r
   }\r
 }\r
 \r
@@ -671,10 +573,8 @@ static void DrawTilesFromCache(int *hc, int sh, int rlim)
       addr+=(unsigned int)code>>25; // y offset into tile\r
       dx=(code>>16)&0x1ff;\r
       zb = HighCol+dx;\r
-      if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
-      if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
-      if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
-      if(!(*zb&0x80)) *zb&=0x3f; zb++; if(!(*zb&0x80)) *zb&=0x3f; zb++;\r
+      *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
+      *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f; *zb++ &= 0x3f;\r
 \r
       pal=((code>>9)&0x30);\r
       if (rlim-dx < 0) goto last_cut_tile;\r
@@ -726,7 +626,7 @@ last_cut_tile:
 // Index + 0  :    hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
 // Index + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
 \r
-static void DrawSprite(int *sprite, int **hc, int sh, int as)\r
+static void DrawSprite(int *sprite, int sh, int as)\r
 {\r
   int width=0,height=0;\r
   int row=0,code=0;\r
@@ -747,25 +647,27 @@ static void DrawSprite(int *sprite, int **hc, int sh, int as)
 \r
   if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
 \r
-  tile=code&0x7ff; // Tile number\r
-  tile+=row>>3; // Tile number increases going down\r
+  tile=code + (row>>3); // Tile number increases going down\r
   delta=height; // Delta to increase tile by going right\r
   if (code&0x0800) { tile+=delta*(width-1); delta=-delta; } // Flip X\r
 \r
-  tile<<=4; tile+=(row&7)<<1; // Tile address\r
+  tile &= 0x7ff; tile<<=4; tile+=(row&7)<<1; // Tile address\r
+\r
+  pal=(code>>9)&0x30;\r
 \r
-  if (code&0x8000) { // high priority - cache it\r
-    *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>16)&0xf);\r
-    // we need all for accurate sprites, cached will be used to recover ones overwritten by high layer\r
-    if (!as) return;\r
+  // assume there will be no sprites with both normal and operator pixels..\r
+  if ((code&0x8000) || (sh && pal == 0x30) || as) {\r
+    *HighCacheS_ptr++ = ((code&0x8000)<<16)|(tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|pal|((sprite[0]>>16)&0xf);\r
+    // we need all for accurate sprites, cached will be used to do proper priorities\r
+    if (!as && (code&0x8000)) return;\r
   }\r
 \r
   delta<<=4; // Delta of address\r
-  pal=((code>>9)&0x30)|((sh|as)<<6);\r
+  pal|=((sh|as)<<6);\r
 \r
   if (sh && (code&0x6000) == 0x6000) {\r
-    if(code&0x0800) fTileFunc=TileFlipSH;\r
-    else            fTileFunc=TileNormSH;\r
+    if(code&0x0800) fTileFunc=TileFlipSH_noop;\r
+    else            fTileFunc=TileNormSH_noop;\r
   } else {\r
     if(code&0x0800) fTileFunc=TileFlip;\r
     else            fTileFunc=TileNorm;\r
@@ -880,21 +782,29 @@ static void DrawSpritesFromCache(int *hc, int maxwidth, int prio, int sh)
   int pal;\r
   int (*fTileFunc)(int sx,int addr,int pal);\r
 \r
-  // *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+  // prio[31]:tile[30:17]:flipx[16]:sx[15:6]:pal[5:4]:delta_width[3:0]\r
 \r
-  while((code=*hc++)) {\r
+  while ((code=*hc++))\r
+  {\r
     pal=(code&0x30);\r
     delta=code&0xf;\r
     width=delta>>2; delta&=3;\r
     width++; delta++; // Width and height in tiles\r
     if (code&0x10000) delta=-delta; // Flip X\r
     delta<<=4;\r
-    tile=((unsigned int)code>>17)<<1;\r
+    tile=((unsigned int)code>>17)<<1; // also has prio\r
     sx=(code<<16)>>22; // sx can be negative (start offscreen), so sign extend\r
 \r
-    if(sh && pal == 0x30) { //\r
-      if(code&0x10000) fTileFunc=TileFlipSH;\r
-      else             fTileFunc=TileNormSH;\r
+    if (sh && pal == 0x30)\r
+    {\r
+      if (code & 0x80000000) // hi priority\r
+      {\r
+        if(code&0x10000) fTileFunc=TileFlipSH;\r
+        else             fTileFunc=TileNormSH;\r
+      } else {\r
+        if(code&0x10000) fTileFunc=TileFlipSH_onlyop_lp;\r
+        else             fTileFunc=TileNormSH_onlyop_lp;\r
+      }\r
     } else {\r
       if(code&0x10000) fTileFunc=TileFlip;\r
       else             fTileFunc=TileNorm;\r
@@ -915,12 +825,16 @@ static void DrawSpritesFromCache(int *hc, int maxwidth, int prio, int sh)
 static void DrawSpritesFromCacheAS(int *hc, int maxwidth, int prio, int sh)\r
 {\r
   int code, tile, sx, delta, width;\r
-  int pal;\r
+  int pal, *hce, *hco;\r
   int (*fTileFunc)(int sx,int addr,int pal);\r
 \r
-  // *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+  // prio[31]:tile[30:17]:flipx[16]:sx[15:6]:pal[5:4]:delta_width[3:0]\r
 \r
-  while((code=*hc++)) {\r
+  /* walk the sprite cache backwards.. */\r
+  hco = hce = HighCacheS_ptr;\r
+  while (hce > hc)\r
+  {\r
+    code=*(--hce);\r
     pal=(code&0x30);\r
     delta=code&0xf;\r
     width=delta>>2; delta&=3;\r
@@ -930,14 +844,67 @@ static void DrawSpritesFromCacheAS(int *hc, int maxwidth, int prio, int sh)
     tile=((unsigned int)code>>17)<<1;\r
     sx=(code<<16)>>22; // sx can be negative (start offscreen), so sign extend\r
 \r
-    if(sh && pal == 0x30) { //\r
-      if(code&0x10000) fTileFunc=TileFlipSHAS;\r
-      else             fTileFunc=TileNormSHAS;\r
+    if (code & 0x80000000) // hi priority\r
+    {\r
+      if (sh && pal == 0x30)\r
+      {\r
+        if(code&0x10000) fTileFunc=TileFlipAS_noop;\r
+        else             fTileFunc=TileNormAS_noop;\r
+        *(--hco) = code; /* save for later */\r
+      } else {\r
+        if(code&0x10000) fTileFunc=TileFlipAS;\r
+        else             fTileFunc=TileNormAS;\r
+      }\r
     } else {\r
-      if(code&0x10000) fTileFunc=TileFlipAS;\r
-      else             fTileFunc=TileNormAS;\r
+      if(code&0x10000) fTileFunc=TileFlipAS_onlymark;\r
+      else             fTileFunc=TileNormAS_onlymark;\r
     }\r
 \r
+    pal |= 0x80;\r
+    for (; width; width--,sx+=8,tile+=delta)\r
+    {\r
+      if(sx<=0)   continue;\r
+      if(sx>=328) break; // Offscreen\r
+\r
+      tile&=0x7fff; // Clip tile address\r
+      fTileFunc(sx,tile,pal);\r
+    }\r
+  }\r
+\r
+  if (!sh) return;\r
+\r
+  /* nasty 1: remove 'sprite' flags */\r
+  {\r
+    int c = 320/4, *zb = (int *)(HighCol+8);\r
+    while (c--)\r
+    {\r
+      *zb++ &= 0x7f7f7f7f;\r
+    }\r
+  }\r
+\r
+  /* nasty 2: loop once more and do operator colors */\r
+  while ((code=*hco++))\r
+  {\r
+    pal=(code&0x30);\r
+    if (pal != 0x30) continue;\r
+    delta=code&0xf;\r
+    width=delta>>2; delta&=3;\r
+    width++; delta++;\r
+    if (code&0x10000) delta=-delta; // Flip X\r
+    delta<<=4;\r
+    tile=((unsigned int)code>>17)<<1;\r
+    sx=(code<<16)>>22;\r
+\r
+    if (code & 0x80000000)\r
+    {\r
+      if(code&0x10000) fTileFunc=TileFlipSH;\r
+      else             fTileFunc=TileNormSH;\r
+    } else {\r
+      if(code&0x10000) fTileFunc=TileFlipSH_onlyop_lp;\r
+      else             fTileFunc=TileNormSH_onlyop_lp;\r
+    }\r
+\r
+    pal |= 0x80;\r
     for (; width; width--,sx+=8,tile+=delta)\r
     {\r
       if(sx<=0)   continue;\r
@@ -950,6 +917,7 @@ static void DrawSpritesFromCacheAS(int *hc, int maxwidth, int prio, int sh)
 }\r
 \r
 \r
+\r
 // Index + 0  :    ----hhvv -lllllll -------y yyyyyyyy\r
 // Index + 4  :    -------x xxxxxxxx pccvhnnn nnnnnnnn\r
 // v\r
@@ -1062,6 +1030,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
   if (PicoOpt & POPT_DIS_SPRITE_LIM)\r
     max_line_sprites = 80;\r
 \r
+  HighCacheS_ptr = hcache;\r
   ps = HighPreSpr;\r
 \r
   // Index + 0  :    hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
@@ -1108,10 +1077,10 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
 \r
   // Go through sprites backwards:\r
   for (i--; i>=0; i--)\r
-    DrawSprite(sprites[i],&hcache,sh,n);\r
+    DrawSprite(sprites[i],sh,n);\r
 \r
   // terminate cache list\r
-  *hcache = 0;\r
+  *HighCacheS_ptr = 0;\r
 }\r
 \r
 \r
@@ -1349,7 +1318,7 @@ static int DrawDisplay(int sh, int as)
     DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh);\r
   } else\r
     if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, 328);\r
-  DrawAllSpritesHiPri(HighCacheS, maxw, 1, sh);\r
+  if (HighCacheS[0]) DrawAllSpritesHiPri(HighCacheS, maxw, 1, sh);\r
 \r
 #if 0\r
   {\r
index 3cafde9..f310253 100644 (file)
@@ -1,9 +1,9 @@
 @ vim:filetype=armasm\r
 \r
-@ assembly "optimized" version of some funtions from draw.c\r
+@ ARM assembly versions of some funtions from draw.c\r
 @ this is highly specialized, be careful if changing related C code!\r
 \r
-@ (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
+@ (c) Copyright 2007-2008, Grazvydas "notaz" Ignotas\r
 @ All Rights Reserved\r
 \r
 .include "port_config.s"\r
@@ -16,6 +16,7 @@
 .extern rendstatus\r
 .extern DrawLineDest\r
 .extern DrawStripInterlace\r
+.extern HighCacheS_ptr\r
 \r
 \r
 @ helper\r
 .endif\r
     ldreqb  r4, [r1,#\offs]\r
     orrne   r4, r3, r4\r
-    strneb  r4, [r1,#\offs]\r
-    tsteq   r4, #0x80\r
     andeq   r4, r4, #0x3f\r
-    streqb  r4, [r1,#\offs]\r
+    strb    r4, [r1,#\offs]\r
 .endm\r
 \r
 @ TileNormShHP (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: register with helper pattern 0xf, touches r3 high bits\r
 .else\r
     ands    r4, r12, r2\r
 .endif\r
-    beq     3f\r
+    beq     0f\r
     cmp     r4, #0xe\r
-    beq     2f\r
-    bgt     1f\r
-    orr     r4, r3, r4\r
-    strb    r4, [r1,#\ofs]\r
-    b       3f\r
-1:\r
-    ldrb    r4, [r1,#\ofs]        @ 2ci\r
-    orr     r4, r4, #0xc0\r
-    strb    r4, [r1,#\ofs]\r
-    b       3f\r
-2:\r
-    ldrb    r4, [r1,#\ofs]        @ 2ci\r
-    bic     r4, r4, #0xc0\r
-    orr     r4, r4, #0x80\r
+    ldrgeb  r4, [r1,#\ofs]\r
+    orrlt   r4, r3, r4            @ normal\r
+\r
+    biceq   r4, r4, #0xc0         @ hilight\r
+    orreq   r4, r4, #0x80\r
+    orrgt   r4, r4, #0xc0         @ shadow\r
+\r
     strb    r4, [r1,#\ofs]\r
-3:\r
+0:\r
 .endm\r
 \r
 @ TileFlipSh (r1=pdest, r2=pixels8, r3=pal) r4,r7: scratch, r0=sx, r12: register with helper pattern 0xf\r
     TileDoShGenPixel 16,  7 @ #0x000f0000\r
 .endm\r
 \r
+.macro TileDoShGenPixel_noop shift ofs\r
+.if \shift\r
+    and     r4, r12, r2, lsr #\shift\r
+.else\r
+    and     r4, r12, r2\r
+.endif\r
+    sub     r7, r4, #1\r
+    cmp     r7, #0xd\r
+    orrcc   r4, r3, r4           @ 0-0xc (was 1-0xd)\r
+    strccb  r4, [r1,#\ofs]\r
+.endm\r
+\r
+.macro TileFlipSh_noop\r
+    TileDoShGenPixel_noop 16,  0 @ #0x000f0000\r
+    TileDoShGenPixel_noop 20,  1 @ #0x00f00000\r
+    TileDoShGenPixel_noop 24,  2 @ #0x0f000000\r
+    TileDoShGenPixel_noop 28,  3 @ #0xf0000000\r
+    TileDoShGenPixel_noop  0,  4 @ #0x0000000f\r
+    TileDoShGenPixel_noop  4,  5 @ #0x000000f0\r
+    TileDoShGenPixel_noop  8,  6 @ #0x00000f00\r
+    TileDoShGenPixel_noop 12,  7 @ #0x0000f000\r
+.endm\r
+\r
+.macro TileNormSh_noop\r
+    TileDoShGenPixel_noop 12,  0 @ #0x0000f000\r
+    TileDoShGenPixel_noop  8,  1 @ #0x00000f00\r
+    TileDoShGenPixel_noop  4,  2 @ #0x000000f0\r
+    TileDoShGenPixel_noop  0,  3 @ #0x0000000f\r
+    TileDoShGenPixel_noop 28,  4 @ #0xf0000000\r
+    TileDoShGenPixel_noop 24,  5 @ #0x0f000000\r
+    TileDoShGenPixel_noop 20,  6 @ #0x00f00000\r
+    TileDoShGenPixel_noop 16,  7 @ #0x000f0000\r
+.endm\r
+\r
+.macro TileDoShGenPixel_onlyop_lp shift ofs\r
+.if \shift\r
+    ands    r7, r12, r2, lsr #\shift\r
+.else\r
+    ands    r7, r12, r2\r
+.endif\r
+    ldrneb  r4, [r1,#\ofs]\r
+    tstne   r4, #0x40\r
+    beq     0f\r
+\r
+    cmp     r7, #0xe\r
+    biceq   r4, r4, #0xc0         @ hilight\r
+    orreq   r4, r4, #0x80\r
+    orrgt   r4, r4, #0xc0         @ shadow\r
+    strgeb  r4, [r1,#\ofs]\r
+0:\r
+.endm\r
+\r
+.macro TileFlipSh_onlyop_lp\r
+    TileDoShGenPixel_onlyop_lp 16,  0 @ #0x000f0000\r
+    TileDoShGenPixel_onlyop_lp 20,  1 @ #0x00f00000\r
+    TileDoShGenPixel_onlyop_lp 24,  2 @ #0x0f000000\r
+    TileDoShGenPixel_onlyop_lp 28,  3 @ #0xf0000000\r
+    TileDoShGenPixel_onlyop_lp  0,  4 @ #0x0000000f\r
+    TileDoShGenPixel_onlyop_lp  4,  5 @ #0x000000f0\r
+    TileDoShGenPixel_onlyop_lp  8,  6 @ #0x00000f00\r
+    TileDoShGenPixel_onlyop_lp 12,  7 @ #0x0000f000\r
+.endm\r
+\r
+.macro TileNormSh_onlyop_lp\r
+    TileDoShGenPixel_onlyop_lp 12,  0 @ #0x0000f000\r
+    TileDoShGenPixel_onlyop_lp  8,  1 @ #0x00000f00\r
+    TileDoShGenPixel_onlyop_lp  4,  2 @ #0x000000f0\r
+    TileDoShGenPixel_onlyop_lp  0,  3 @ #0x0000000f\r
+    TileDoShGenPixel_onlyop_lp 28,  4 @ #0xf0000000\r
+    TileDoShGenPixel_onlyop_lp 24,  5 @ #0x0f000000\r
+    TileDoShGenPixel_onlyop_lp 20,  6 @ #0x00f00000\r
+    TileDoShGenPixel_onlyop_lp 16,  7 @ #0x000f0000\r
+.endm\r
+\r
 \r
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
 \r
@@ -798,39 +864,25 @@ DrawTilesFromCache:
     b       .dtfc_loop\r
 \r
 .dtfc_shadow_blank:\r
-    ldrb    r4, [r1]        @ 1ci\r
-    ldrb    r12,[r1,#1]\r
-    tst     r4, #0x80\r
-    andeq   r4, r4,#0x3f\r
-    streqb  r4, [r1]\r
-    tst     r12,#0x80\r
-    ldrb    r4, [r1,#2]\r
-    andeq   r12,r12,#0x3f\r
-    streqb  r12,[r1,#1]\r
-    tst     r4, #0x80\r
-    ldrb    r12,[r1,#3]\r
-    andeq   r4, r4,#0x3f\r
-    streqb  r4, [r1,#2]\r
-    tst     r12,#0x80\r
-    ldrb    r4, [r1,#4]\r
-    andeq   r12,r12,#0x3f\r
-    streqb  r12,[r1,#3]\r
-    tst     r4, #0x80\r
-    ldrb    r12,[r1,#5]\r
-    andeq   r4, r4,#0x3f\r
-    streqb  r4, [r1,#4]\r
-    tst     r12,#0x80\r
-    ldrb    r4, [r1,#6]\r
-    andeq   r12,r12,#0x3f\r
-    streqb  r12,[r1,#5]\r
-    tst     r4, #0x80\r
-    ldrb    r12,[r1,#7]\r
-    andeq   r4, r4,#0x3f\r
-    streqb  r4, [r1,#6]\r
-    tst     r12,#0x80\r
-    andeq   r12,r12,#0x3f\r
-    streqb  r12,[r1,#7]\r
-    mov     r12, #0xf\r
+    tst     r1, #1\r
+    ldrneb  r4, [r1]\r
+    mov     r6, #0x3f\r
+    and     r4, r4, #0x3f\r
+    strneb  r4, [r1], #1\r
+    ldrh    r4, [r1]\r
+    orr     r6, r6, r6, lsl #8\r
+    and     r4, r4, r6\r
+    strh    r4, [r1], #2\r
+    ldrh    r4, [r1]\r
+    and     r4, r4, r6\r
+    strh    r4, [r1], #2\r
+    ldrh    r4, [r1]\r
+    and     r4, r4, r6\r
+    strh    r4, [r1], #2\r
+    ldrh    r4, [r1]\r
+    and     r4, r4, r6\r
+    streqh  r4, [r1]\r
+    strneb  r4, [r1]\r
     b       .dtfc_loop\r
 \r
 .dtfc_cut_tile:\r
@@ -865,31 +917,22 @@ DrawTilesFromCache:
     str     r2, [r1]\r
 \r
     add     r1, r11,#8\r
-    mov     r3, #320/4\r
-    mov     r7, #0x80\r
-    orr     r7, r7, r7, lsl #8\r
-    orr     r7, r7, r7, lsl #16\r
+    mov     r3, #320/4/4\r
     mov     r6, #0x3f\r
     orr     r6, r6, r6, lsl #8\r
     orr     r6, r6, r6, lsl #16\r
 .dtfc_loop_shprep:\r
+    ldmia   r1, {r2,r4,r5,r7}\r
     subs    r3, r3, #1\r
-    bmi     .dtfc_loop      @ done\r
-    ldr     r2, [r1]\r
-    tst     r2, r7\r
-    andeq   r2, r2, r6\r
-    streq   r2, [r1], #4\r
-    beq     .dtfc_loop_shprep\r
-    tst     r2,     #0x80000000\r
-    biceq   r2, r2, #0xc0000000\r
-    tst     r2,     #0x00800000\r
-    biceq   r2, r2, #0x00c00000\r
-    tst     r2,     #0x00008000\r
-    biceq   r2, r2, #0x0000c000\r
-    tst     r2,     #0x00000080\r
-    biceq   r2, r2, #0x000000c0\r
-    str     r2, [r1], #4\r
-    b       .dtfc_loop_shprep\r
+    and     r2, r2, r6\r
+    and     r4, r4, r6\r
+    and     r5, r5, r6\r
+    and     r7, r7, r6\r
+    stmia   r1!,{r2,r4,r5,r7}\r
+    bne     .dtfc_loop_shprep\r
+\r
+    mvn     r5, #0         @ r5=prevcode=-1\r
+    b       .dtfc_loop\r
 \r
 .pool\r
 \r
@@ -998,6 +1041,9 @@ DrawSpritesFromCache:
     b       .dsfc_inloop\r
 \r
 .dsfc_shadow:\r
+    tst     r9, #0x80000000\r
+    beq     .dsfc_shadow_lowpri\r
+\r
     cmp     r2, r2, ror #4\r
     beq     .dsfc_singlec_sh\r
 \r
@@ -1025,6 +1071,18 @@ DrawSpritesFromCache:
     TileSingleSh\r
     b       .dsfc_inloop\r
 \r
+.dsfc_shadow_lowpri:\r
+    tst     r9, #0x10000\r
+    bne     .dsfc_TileFlip_sh_lp\r
+\r
+.dsfc_TileNorm_sh_lp:\r
+    TileNormSh_onlyop_lp\r
+    b       .dsfc_inloop\r
+\r
+.dsfc_TileFlip_sh_lp:\r
+    TileFlipSh_onlyop_lp\r
+    b       .dsfc_inloop\r
+\r
 .pool\r
 \r
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
@@ -1032,12 +1090,12 @@ DrawSpritesFromCache:
 @ + 0  :    hhhhvvvv ab--hhvv yyyyyyyy yyyyyyyy // a: offscreen h, b: offs. v, h: horiz. size\r
 @ + 4  :    xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8\r
 \r
-.global DrawSprite @ unsigned int *sprite, int **hc, int sh, int acc_sprites\r
+.global DrawSprite @ unsigned int *sprite, int sh, int acc_sprites\r
 \r
 DrawSprite:\r
     stmfd   sp!, {r4-r9,r11,lr}\r
 \r
-    orr     r8, r3, r2, lsl #4\r
+    orr     r8, r2, r1, lsl #4\r
     ldr     r3, [r0]        @ sprite[0]\r
     ldr     r7, =Scanline\r
     mov     r6, r3, lsr #28\r
@@ -1061,20 +1119,23 @@ DrawSprite:
     subne   r4, r4, #1\r
     subne   r7, r4, r7      @ if (code&0x1000) row=(height<<3)-1-row; // Flip Y\r
 \r
-    mov     r8, r9, lsl #21\r
-    mov     r8, r8, lsr #21\r
-    add     r8, r8, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
-    \r
+    add     r8, r9, r7, lsr #3 @ tile+=row>>3; // Tile number increases going down\r
     tst     r9, #0x0800\r
     mlane   r8, r5, r6, r8  @ if (code&0x0800) { tile+=delta*(width-1);\r
     rsbne   r5, r5, #0      @ delta=-delta; } // r5=delta now\r
 \r
-    mov     r8, r8, lsl #4\r
+    mov     r8, r8, lsl #21\r
+    mov     r8, r8, lsr #17\r
     and     r7, r7, #7\r
     add     r8, r8, r7, lsl #1 @ tile+=(row&7)<<1; // Tile address\r
 \r
     tst     r9, #0x8000\r
-    bne     .dspr_cache       @ if(code&0x8000) // high priority - cache it\r
+    tsteq   r9, #(1<<27)\r
+    bne     .dspr_cache       @ if(code&0x8000) || as\r
+    tst     r6, #0x4000\r
+    tstne   r6, #0x2000\r
+    tstne   r9, #(1<<31)\r
+    bne     .dspr_cache       @ (sh && pal == 0x30)\r
 \r
 .dspr_continue:\r
     @ cache some stuff to avoid mem access\r
@@ -1138,6 +1199,10 @@ DrawSprite:
     TileFlip r12\r
     b       .dspr_loop\r
 \r
+.dspr_singlec_sh:\r
+    cmp     r2, #0xe0000000\r
+    bcs     .dspr_loop          @ operator tileline, ignore\r
+\r
 .dspr_SingleColor:\r
     and     r4, r2, #0xf\r
     orr     r4, r3, r4\r
@@ -1160,28 +1225,17 @@ DrawSprite:
 \r
     @ (r1=pdest, r2=pixels8, r3=pal) r4: scratch, r12: helper pattern\r
 .dspr_TileNorm_sh:\r
-    TileNormSh\r
+    TileNormSh_noop\r
     b       .dspr_loop\r
 \r
 .dspr_TileFlip_sh:\r
-    TileFlipSh\r
-    b       .dspr_loop\r
-\r
-.dspr_singlec_sh:\r
-    cmp     r2, #0xe0000000\r
-    bcc     .dspr_SingleColor   @ normal tileline\r
-    tst     r2, #0x10000000\r
-    bne     .dspr_sh_sh\r
-    TileSingleHi\r
-    b       .dspr_loop\r
-\r
-.dspr_sh_sh:\r
-    TileSingleSh\r
+    TileFlipSh_noop\r
     b       .dspr_loop\r
 \r
 \r
 .dspr_cache:\r
-    @ *(*hc)++ = (tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|((code>>9)&0x30)|((sprite[0]>>24)&0xf);\r
+    @ *HighCacheS_ptr++ = ((code&0x8000)<<16)|(tile<<16)|((code&0x0800)<<5)|((sx<<6)&0x0000ffc0)|pal|((sprite[0]>>16)&0xf);\r
+    ldr     r1, =HighCacheS_ptr\r
     mov     r4, r8, lsl #16     @ tile\r
     tst     r9, #0x0800\r
     orrne   r4, r4, #0x10000    @ code&0x0800\r
@@ -1190,16 +1244,19 @@ DrawSprite:
     and     r0, r9, #0x6000\r
     orr     r4, r4, r0, lsr #9  @ (code>>9)&0x30\r
     mov     r3, r3, lsl #12\r
-    ldr     r0, [r1]\r
     orr     r4, r4, r3, lsr #28 @ (sprite[0]>>24)&0xf\r
 \r
+    ldr     r0, [r1]\r
+    tst     r9, #0x8000\r
+    orrne   r4, r4, #0x80000000 @ prio\r
+\r
     str     r4, [r0], #4\r
     str     r0, [r1]\r
 \r
-    tst     r9, #(1<<27)\r
-    ldmeqfd sp!, {r4-r9,r11,lr}\r
-    bne     .dspr_continue      @ draw anyway if accurate sprites enabled\r
-    bxeq    lr\r
+    and     r0, r9, #(1<<27)    @ as\r
+    teqne   r0,     #(1<<27)    @ (code&0x8000) && !as\r
+    ldmnefd sp!, {r4-r9,r11,pc}\r
+    b       .dspr_continue      @ draw anyway if accurate sprites enabled\r
 \r
 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
 \r
@@ -1229,19 +1286,17 @@ DrawWindow:
 \r
     ldr     r6, =rendstatus\r
     ldr     lr, =(Pico+0x10000) @ lr=Pico.vram\r
-    ldrb    r6, [r6]\r
+    ldr     r6, [r6]\r
 \r
     @ fetch the first code now\r
     ldrh    r7, [lr, r12]\r
 \r
     ands    r6, r6, #2            @ we care about bit 1 only\r
     orr     r6, r6, r2\r
-    bne     .dw_no_sameprio\r
 \r
-    cmp     r2, r7, lsr #15\r
-    ldmnefd sp!, {r4-r11,pc}      @ assume that whole window uses same priority\r
+    teqne   r2, r7, lsr #15       @ do prio bits differ?\r
+    ldmnefd sp!, {r4-r11,pc}      @ yes, assume that whole window uses same priority\r
 \r
-.dw_no_sameprio:\r
     orr     r6, r6, r3, lsl #8    @ shadow mode\r
 \r
     sub     r8, r1, r0\r
@@ -1258,11 +1313,11 @@ DrawWindow:
     mov     r8, r8, lsl #1        @ cells\r
     mvn     r9, #0                @ r9=prevcode=-1\r
 .endif\r
-    add     r1, r11, r0, lsl #4 @ r1=pdest\r
+    add     r1, r11, r0, lsl #4   @ r1=pdest\r
     mov     r0, #0xf\r
     b       .dwloop_enter\r
 \r
-    @ r4,r5 & r7 are scratch in this loop\r
+    @ r4,r5 are scratch in this loop\r
 .dwloop:\r
     add     r1, r1, #8\r
 .dwloop_nor1:\r
@@ -1328,24 +1383,13 @@ DrawWindow:
     orreq   r3, r3, #0x40\r
     beq     .dw_shadow_done\r
     ldr     r4, [r1]\r
-    tst     r4, #0x00000080\r
-    biceq   r4, r4, #0x000000c0\r
-    tst     r4, #0x00008000\r
-    biceq   r4, r4, #0x0000c000\r
-    tst     r4, #0x00800000\r
-    biceq   r4, r4, #0x00c00000\r
-    tst     r4, #0x80000000\r
-    biceq   r4, r4, #0xc0000000\r
+    mov     r5, #0x3f\r
+    orr     r5, r5, r5, lsl #8\r
+    orr     r5, r5, r5, lsl #16\r
+    and     r4, r4, r5\r
     str     r4, [r1]\r
     ldr     r4, [r1,#4]\r
-    tst     r4, #0x00000080\r
-    biceq   r4, r4, #0x000000c0\r
-    tst     r4, #0x00008000\r
-    biceq   r4, r4, #0x0000c000\r
-    tst     r4, #0x00800000\r
-    biceq   r4, r4, #0x00c00000\r
-    tst     r4, #0x80000000\r
-    biceq   r4, r4, #0xc0000000\r
+    and     r4, r4, r5\r
     str     r4, [r1,#4]\r
     b       .dw_shadow_done\r
 \r
index 6db1d41..5f38314 100644 (file)
@@ -201,12 +201,12 @@ void gp2x_pd_clone_buffer2(void)
 unsigned long gp2x_joystick_read(int allow_usb_joy)\r
 {\r
        int i;\r
-       unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF);\r
+       unsigned long value=(gp2x_memregs[0x1198>>1] & 0x00FF); // GPIO M\r
        if(value==0xFD) value=0xFA;\r
        if(value==0xF7) value=0xEB;\r
        if(value==0xDF) value=0xAF;\r
        if(value==0x7F) value=0xBE;\r
-       value = ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16));\r
+       value = ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16)); // C D\r
 \r
        if (allow_usb_joy && num_of_joys > 0) {\r
                // check the usb joy as well..\r