OSDN Git Service

[VM][FMTOWNS][SPRITE][WIP] *Implementing* sprite rendering, this is strongly WIP.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 23 Sep 2018 07:23:58 +0000 (16:23 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 23 Sep 2018 07:23:58 +0000 (16:23 +0900)
source/src/vm/fmtowns/towns_sprite.cpp
source/src/vm/fmtowns/towns_sprite.h

index 892f95f..b27495e 100644 (file)
@@ -90,1084 +90,6 @@ void TOWNS_SPRITE::render_not_rotate(int num, uint16* dst_pixel, int width, int
        uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
        uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
        if(sprite_table[num].is_32768) {
        uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
        uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
        if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint8_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               for(int y = 0; y < 16; y += ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = &(qp[y << 4]);
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x << 1];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               for(int y = 0; y < 16; y += ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = (uint8_t*)qp;
-                       q = &q[y << 3];
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & 0xf0;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_hi[x] = pixels[x] & 0xf0;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_lo[x] = pixels[x] & 0x0f;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x << 1] = color_index[pixels_hi[x]];
-                                       p[(x << 1) + 1] = color_index[pixels_lo[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-}
-
-void TOWNS_SPRITE::render_mirror_180(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint8_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = &(qp[y << 4]);
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x << 1];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = (uint8_t*)qp;
-                       q = &q[y << 3];
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & 0xf0;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_hi[x] = pixels[x] & 0xf0;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_lo[x] = pixels[x] & 0x0f;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x << 1] = color_index[pixels_hi[x]];
-                                       p[(x << 1) + 1] = color_index[pixels_lo[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-
-void TOWNS_SPRITE::render_mirror_0(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint8_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = &(qp[y << 4]);
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x << 1];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = (uint8_t*)qp;
-                       q = &q[y << 3];
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & 0xf0;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_hi[x] = pixels[x] & 0xf0;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_lo[x] = pixels[x] & 0x0f;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x << 1] = color_index[pixels_hi[x]];
-                                       p[(x << 1) + 1] = color_index[pixels_lo[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-
-void TOWNS_SPRITE::render_rotate_180(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint8_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = &(qp[y << 4]);
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x << 1];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* q;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       q = (uint8_t*)qp;
-                       q = &q[y << 3];
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & 0xf0;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = q[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_hi[x] = pixels[x] & 0xf0;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels_lo[x] = pixels[x] & 0x0f;
-                               }
-                               
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x << 1] = color_index[pixels_hi[x]];
-                                       p[(x << 1) + 1] = color_index[pixels_lo[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-
-void TOWNS_SPRITE::render_mirror_270(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t pcache[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 16; x++) {
-                               pcache[x] = qp[(x << 4) + y];
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint8_t pcache[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 8; x++) {
-                               pcache[x << 1] = qp[(x << 4) + y] & 0xf0;
-                               pcache[(x << 1) + 1] = qp[(x << 4) + y] & 0x0f;
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-
-
-void TOWNS_SPRITE::render_rotate_90(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t pcache[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 16; x++) {
-                               pcache[x] = qp[(x << 4) + (15 - y)];
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint8_t pcache[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 8; x++) {
-                               pcache[x << 1] = qp[(x << 4) + (15 - y)] & 0xf0;
-                               pcache[(x << 1) + 1] = qp[(x << 4) + (15 - y)] & 0x0f;
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-
-void TOWNS_SPRITE::render_rotate_270(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t pcache[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 16; x++) {
-                               pcache[x] = qp[((15 - x) << 4) + y];
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
        } else {
                addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
                int ystep = (cache_index[num].is_halfy) ? 2 : 1;
        } else {
                addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
                int ystep = (cache_index[num].is_halfy) ? 2 : 1;
@@ -1180,6 +102,7 @@ void TOWNS_SPRITE::render_rotate_270(int num, uint16* dst_pixel, int width, int
                color = color - 256;
                uint16_t* p;
                uint16_t* m;
                color = color - 256;
                uint16_t* p;
                uint16_t* m;
+               uint16_t* q;
                uint16_t* dp;
                int yy = 0;
                uint8_t pixels[16];
                uint16_t* dp;
                int yy = 0;
                uint8_t pixels[16];
@@ -1188,106 +111,26 @@ void TOWNS_SPRITE::render_rotate_270(int num, uint16* dst_pixel, int width, int
                uint16_t masks[16];
                uint16_t tpixels[16];
                uint16_t t2pixels[16];
                uint16_t masks[16];
                uint16_t tpixels[16];
                uint16_t t2pixels[16];
-               uint8_t pcache[16];
                uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
                uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
+               for(int y = 0; y < 16; y += ystep) {
                        p = &(cache_pixel[yy << 4]);
                        m = &(cache_mask[yy << 4]);
                        p = &(cache_pixel[yy << 4]);
                        m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 8; x++) {
-                               pcache[x << 1] = qp[((7 - x) << 4) + y] & 0xf0;
-                               pcache[(x << 1) + 1] = qp[((7 - x) << 4) + y] & 0x0f;
-                       }
+                       q = (uint8_t*)qp;
+                       q = &q[y << 3];
                        dp = &(dst_pixel[yy * stride]);
                        if(cache_index[num].is_halfx) {
                                for(int x = 0; x < 8; x++) {
                        dp = &(dst_pixel[yy * stride]);
                        if(cache_index[num].is_halfx) {
                                for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
+                                       pixels[x] = q[x];
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
+                                       pixels[x] = pixels[x] & 0xf0;
                                }
                                }
+                               
                                for(int x = 0; x < 8; x++) {
                                for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
                                        masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
                                }
                                        masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
                                }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = color_index[pixels[x]];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       t2pixels[x] = p[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       }
-       
-}
-void TOWNS_SPRITE::render_mirror_90(int num, uint16* dst_pixel, int width, int height, int stride)
-{
-       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
-       uint8_t* addr;
-       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
-       uint16_t *cache_mask = &(cache_masks[last_put_cache_num][0]);
-       if(sprite_table[num].is_32768) {
-               addr = &(pattern_ram[(sprite_table[num].num - 32) << 5]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[8];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t pcache[16];
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 16; x++) {
-                               pcache[x] = qp[((15 - x) << 4) + (15 - y)];
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
-                               for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
                                for(int x = 0; x < 8; x++) {
                                for(int x = 0; x < 8; x++) {
-                                       p[x] = pixels[x];
+                                       p[x] = color_index[pixels[x]];
                                }
                                for(int x = 0; x < 8; x++) {
                                        m[x] = masks[x];
                                }
                                for(int x = 0; x < 8; x++) {
                                        m[x] = masks[x];
@@ -1297,100 +140,31 @@ void TOWNS_SPRITE::render_mirror_90(int num, uint16* dst_pixel, int width, int h
                                        tpixels[x] = dp[x] & masks[x];
                                }
                                for(int x = 0; x < 8; x++) {
                                        tpixels[x] = dp[x] & masks[x];
                                }
                                for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
+                                       pixels[x] = p[x] & ~masks[x];
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
+                                       dp[x] = pixels[x] | tpixels[x];
                                }
                        } else {
                                }
                        } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = pixels[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       m[x] = masks[x];
-                               }
-                               // Draw to buffer
-                               for(int x = 0; x < 16; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pixels[x] & ~masks[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = pixels[x] | tpixels[x];
-                               }
-                       }
-                       yy++;
-               }
-       } else {
-               addr = &(pattern_ram[(sprite_table[num].num - 128) << 3]);
-               int ystep = (cache_index[num].is_halfy) ? 2 : 1;
-               int xstep = (cache_index[num].is_halfx) ? 2 : 1;
-               int w = (cache_index[num].is_halfy) ? 8 : 16;
-               int h = (cache_index[num].is_halfx) ? 8 : 16;
-               int color = sprite_table[num].color;
-               if(color < 256) return;
-               if(color > 511) return;
-               color = color - 256;
-               uint16_t* p;
-               uint16_t* m;
-               uint16_t* dp;
-               int yy = 0;
-               uint8_t pixels[16];
-               uint8_t pixels_lo[16];
-               uint8_t pixels_hi[16];
-               uint16_t masks[16];
-               uint16_t tpixels[16];
-               uint16_t t2pixels[16];
-               uint8_t pcache[16];
-               uint16_t* color_index = (uint16_t*)(&color_index_ram[color << 5]);
-               int ybegin = (cache_index[num].is_halfy) ? 14 : 15;
-               for(int y = ybegin; y >= 0; y -= ystep) {
-                       p = &(cache_pixel[yy << 4]);
-                       m = &(cache_mask[yy << 4]);
-                       for(int x = 0; x < 8; x++) {
-                               pcache[x << 1] = qp[((7 - x) << 4) + (15 - y)] & 0xf0;
-                               pcache[(x << 1) + 1] = qp[((7 - x) << 4) + (15 - y)] & 0x0f;
-                       }
-                       dp = &(dst_pixel[yy * stride]);
-                       if(cache_index[num].is_halfx) {
                                for(int x = 0; x < 8; x++) {
                                for(int x = 0; x < 8; x++) {
-                                       pixels[x] = pcache[x << 1];
-                               }
-                               for(int x = 0; x < 8; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
+                                       pixels[x] = q[x];
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       p[x] = color_index[pixels[x]];
+                                       pixels_hi[x] = pixels[x] & 0xf0;
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       m[x] = masks[x];
+                                       pixels_lo[x] = pixels[x] & 0x0f;
                                }
                                }
-                               // Draw to buffer
+                               
                                for(int x = 0; x < 8; x++) {
                                for(int x = 0; x < 8; x++) {
-                                       tpixels[x] = dp[x] & masks[x];
+                                       masks[x << 1] = (pixels_hi[x] == 0) ? 0xffff : 0x0000;
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       pixels[x] = p[x] & ~masks[x];
+                                       masks[(x << 1) + 1] = (pixels_lo[x] == 0) ? 0xffff : 0x0000;
                                }
                                for(int x = 0; x < 8; x++) {
                                }
                                for(int x = 0; x < 8; x++) {
-                                       dp[7 - x] = pixels[x] | tpixels[x];
-                               }
-                       } else {
-                               for(int x = 0; x < 16; x++) {
-                                       pixels[x] = pcache[x];
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000;
-                               }
-                               for(int x = 0; x < 16; x++) {
-                                       p[x] = color_index[pixels[x]];
+                                       p[x << 1] = color_index[pixels_hi[x]];
+                                       p[(x << 1) + 1] = color_index[pixels_lo[x]];
                                }
                                for(int x = 0; x < 16; x++) {
                                        m[x] = masks[x];
                                }
                                for(int x = 0; x < 16; x++) {
                                        m[x] = masks[x];
@@ -1403,15 +177,15 @@ void TOWNS_SPRITE::render_mirror_90(int num, uint16* dst_pixel, int width, int h
                                        t2pixels[x] = p[x] & ~masks[x];
                                }
                                for(int x = 0; x < 16; x++) {
                                        t2pixels[x] = p[x] & ~masks[x];
                                }
                                for(int x = 0; x < 16; x++) {
-                                       dp[15 - x] = t2pixels[x] | tpixels[x];
+                                       dp[x] = t2pixels[x] | tpixels[x];
                                }
                        }
                        yy++;
                }
        }
                                }
                        }
                        yy++;
                }
        }
-       
 }
 
 }
 
+
 void TOWNS_SPRITE::render_sprite(int num, uint16* dst_pixel, int width, int height, int stride)
 {
        if(num < 0) return;
 void TOWNS_SPRITE::render_sprite(int num, uint16* dst_pixel, int width, int height, int stride)
 {
        if(num < 0) return;
@@ -1512,35 +286,8 @@ void TOWNS_SPRITE::render_sprite(int num, uint16* dst_pixel, int width, int heig
        cache_index[target_num].num = sprite_table[num].num;
        color_cached[(cache_index[target_num].color) & 0xff] = true;
        pattern_cached[sprite_table[num].num] = true; // OK?
        cache_index[target_num].num = sprite_table[num].num;
        color_cached[(cache_index[target_num].color) & 0xff] = true;
        pattern_cached[sprite_table[num].num] = true; // OK?
-       
-       switch(sprite_table[num].rotate){
-       case 0:
-               render_not_rotate(num, dst_pixel, width, height, stride);
-               break;
-       case 1:
-               render_mirror_180(num, dst_pixel, width, height, stride);
-               break;
-       case 2:
-               render_mirror_0(num, dst_pixel, width, height, stride);
-               break;
-       case 3:
-               render_rotate_180(num, dst_pixel, width, height, stride);
-               break;
-       case 4:
-               render_mirror_270(num, dst_pixel, width, height, stride);
-               break;
-       case 5:
-               render_rotate_90(num, dst_pixel, width, height, stride);
-               break;
-       case 6:
-               render_rotate_270(num, dst_pixel, width, height, stride);
-               break;
-       case 7:
-               render_mirror_90(num, dst_pixel, width, height, stride);
-               break;
-       default:
-               break;
-       }
+
+       render_base(num, dst_pixel, width, height, stride);
 }
 
 void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data)
 }
 
 void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data)
index 29fde75..26d0722 100644 (file)
 #define SIG_FMTOWNS_RENDER_SPRITE_SET_NUM     262
 #define SIG_FMTOWNS_RENDER_SPRITE_CLEAR_VRAM  263
 
 #define SIG_FMTOWNS_RENDER_SPRITE_SET_NUM     262
 #define SIG_FMTOWNS_RENDER_SPRITE_CLEAR_VRAM  263
 
+
+enum {
+       ROT_FMTOWNS_SPRITE_0 = 0,
+       ROT_FMTOWNS_SPRITE_90,
+       ROT_FMTOWNS_SPRITE_180,
+       ROT_FMTOWNS_SPRITE_270
+};
+
+
 class TOWNS_VRAM;
 
 #define TOWNS_SPRITE_CACHE_NUM 512
 class TOWNS_VRAM;
 
 #define TOWNS_SPRITE_CACHE_NUM 512
@@ -77,4 +86,1253 @@ public:
        bool load_stste(FILEIO *fio);
 };
 
        bool load_stste(FILEIO *fio);
 };
 
+inline void TOWNS_SPRITE::render_32768_x1_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(y - 15) << 5]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 5]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 15; i >= 0; i--) {
+                                       pixels[i] = p[15 - i];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 15; i++) {
+                                       pixels[i] = p[i];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - y]);
+                       } else {
+                               yaddr = &(qp[y]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 15; x >= 0; x--) {
+                                       p = &(yaddr[x << 5]);
+                                       pixels[x] = p[15 - y];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 15; x++) {
+                                       p = &(yaddr[x << 5]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 16; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+inline void TOWNS_SPRITE::render_32768_x05_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(y - 15) << 5]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 5]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 7; i >= 0; i--) {
+                                       pixels[i] = p[15 - (i << 1)];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 7; i++) {
+                                       pixels[i] = p[i << 1];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - y]);
+                       } else {
+                               yaddr = &(qp[y]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[15 - y];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+
+inline void TOWNS_SPRITE::render_32768_x1_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(7 - y) << 6]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 6]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 15; i >= 0; i--) {
+                                       pixels[i] = p[15 - i];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 15; i++) {
+                                       pixels[i] = p[i];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - (y << 1)]);
+                       } else {
+                               yaddr = &(qp[y << 1]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[7 - y];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+inline void TOWNS_SPRITE::render_32768_x05_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(7 - y) << 6]); // 1 line is 8 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 6]); // 1 line is 8 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 7; i >= 0; i--) {
+                                       pixels[i] = p[15 - (i << 1)];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 7; i++) {
+                                       pixels[i] = p[i << 1];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - (y << 1)]);
+                       } else {
+                               yaddr = &(qp[y << 1]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[7 - (y >> 1)];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+
+inline void TOWNS_SPRITE::render_16_x1_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint8_t* qp = (uint8_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint8_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t tpixels2[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint8_t* yaddr;
+       uint8_t* p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(y - 15) << 3]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 3]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 15; i >= 0; i--) {
+                                       pixels[i] = p[(15 - i) >> 1];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 15; i++) {
+                                       pixels[i] = p[i];
+                               }
+                       }
+__DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 16; i+= 2) {
+                               pixels[i] = pixels[i] >> 4;
+                       }
+__DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 16; i++) {
+                               pixels[i] = pixels[i] & 0x0f;
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[(15 - y) >> 1]);
+                       } else {
+                               yaddr = &(qp[(y >> 1)]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 15; x >= 0; x--) {
+                                       p = &(yaddr[x << 3]);
+                                       pixels[x] = p[(15 - y) >> 1];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 15; x++) {
+                                       p = &(yaddr[x << 3]);
+                                       pixels[x] = p[y >> 1];
+                               }
+                       }
+__DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 16; i++) {
+                               pixels[i] = pixels[i] >> 4;
+                               pixels[i] = pixels[i] & 0x0f;
+                       }
+                       
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 16; x++) {
+                       masks[x] = (pixels[x] == 0) ? 0xffff : 0x0000
+                       tpixel[x] = color_index[pixels[x]];
+                       cp[x] = tpixel;
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels2[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       tpixels[x] = tpixels[x] & masks[x];
+                       dp[x] = tpixels[x] | tpixels2[x];
+               }
+       }
+}
+
+inline void TOWNS_SPRITE::render_16_x05_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 2;
+                       ybegin = 0;
+                       yend = 16;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint8_t* yaddr;
+       uint8_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(y - 15) << 3]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 3]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 7; i >= 0; i--) {
+                                       pixels[i] = p[7 - i];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 7; i++) {
+                                       pixels[i] = p[i];
+                               }
+                       }
+__DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i+= 2) {
+                               pixels[i] = pixels[i] >> 4;
+                               pixels[i] = pixels[i] & 0x0f;
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[(15 - y) >> 1]);
+                       } else {
+                               yaddr = &(qp[y >> 1]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 4]);
+                                       pixels[x] = p[15 - y];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 4]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+__DECL_VECTORIZED_LOOP
+                       for(int i = 0; i < 8; i++) {
+                               pixels[i] = pixels[i] >> 4;
+                               pixels[i] = pixels[i] & 0x0f;
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+
+inline void TOWNS_SPRITE::render_16_x1_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 16;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(7 - y) << 6]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 6]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 15; i >= 0; i--) {
+                                       pixels[i] = p[15 - i];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 15; i++) {
+                                       pixels[i] = p[i];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - (y << 1)]);
+                       } else {
+                               yaddr = &(qp[y << 1]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[7 - y];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[y];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+inline void TOWNS_SPRITE::render_16_x05_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+{
+       uint16_t* qp = (uint16_t*)(sprite_table[num].pixels);
+       uint16_t *cache_pixel = &(cache_pixels[last_put_cache_num][0]);
+       uint16_t *cache_mask = cache_masks[last_put_cache_num][0];
+       int xbegin;
+       int xend;
+       int xstep;
+       int ybegin;
+       int yend;
+       int ystep;
+       int addr_base;
+       int addr_inc;
+       bool xreverse;
+       bool yreverse;
+       bool rotate = false;
+       switch(rot_type) {
+       case ROT_FMTOWNS_SPRITE_0:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = false;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = true;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_90:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = false;
+                       yreverse = true;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_180:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = true;
+                       rotate = false;
+                       if(is_mirror) {
+                               xreverse = false;
+                       }
+               }                       
+               break;
+       case ROT_FMTOWNS_SPRITE_270:
+                       xbegin = 0;
+                       xend = 8;
+                       xstep = 1;
+                       ybegin = 0;
+                       yend = 8;
+                       ystep = 1;
+                       xreverse = true;
+                       yreverse = false;
+                       rotate = true;
+                       if(is_mirror) {
+                               yreverse = true;
+                       }
+               }                       
+               break;
+       }
+       uint16_t pixels[16];
+       uint16_t masks[16];
+       uint16_t tpixels[16];
+       uint16_t* cp;
+       uint16_t* cm;
+       uint16* dp;
+       uint16_t* yaddr;
+       uint16_t*p;
+       for(y = ybegin; y != yend; y += ystep) {
+               cp = &(cache_pixel[y << 5]);
+               cm = &(cache_mask[y << 5]);
+               dp =  &(dst[stride * y]);
+               if(!rotate) {
+                       if(yreverse) {
+                               yaddr = &(qp[(7 - y) << 6]); // 1 line is 4 bytes (16pixels)
+                       } else {
+                               yaddr = &(qp[y << 6]); // 1 line is 4 bytes (16pixels)
+                       }
+                       p = &(yaddr[0]);
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 7; i >= 0; i--) {
+                                       pixels[i] = p[15 - (i << 1)];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP
+                               for(int i = 0; i <= 7; i++) {
+                                       pixels[i] = p[i << 1];
+                               }
+                       }
+               } else {
+                       // Rotate: Swap x, y
+                       if(yreverse) {
+                               yaddr = &(qp[15 - (y << 1)]);
+                       } else {
+                               yaddr = &(qp[y << 1]);
+                       }                       
+                       if(xreverse) {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 7; x >= 0; x--) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[7 - x];
+                               }
+                       } else {
+__DECL_VECTORIZED_LOOP                         
+                               for(int x = 0; x <= 7; x++) {
+                                       p = &(yaddr[x << 6]);
+                                       pixels[x] = p[x];
+                               }
+                       }
+               }
+__DECL_VECTORIZED_LOOP         
+               for(int x = 0; x < 8; x++) {
+                       masks[x] = ((pixels[x] & 0x8000) == 0) ? 0xffff : 0x0000;
+                       cp[x] = pixels[x];
+                       cm[x] = masks[x];
+                       // Draw to buffer
+                       tpixels[x] = dp[x] & masks[x];
+                       masks[x] = ~masks[x];
+                       pixels[x] = pixels[x] & masks[x];
+                       dp[x] = pixels[x] | tpixels[x];
+               }
+       }
+}
+
+
+inline void TOWNS_SPRITE::render_base(int num, uint16* dst_pixel, int width, int height, int stride)
+{
+       int half_type = 0;
+       int rot_type;
+       half_type = half_type | ((cache_index[num].is_halfx) ? 1 : 0);
+       half_type = half_type | ((cache_index[num].is_halfy) ? 2 : 0);
+
+       switch((sprite_table[num].rotate) & 7) {
+       case 0:
+               rot_type = ROT_FMTOWNS_SPRITE_0;
+               is_mirror = false;
+               break;
+       case 1:
+               rot_type = ROT_FMTOWNS_SPRITE_180;
+               is_mirror = true;
+               break;
+       case 2:
+               rot_type = ROT_FMTOWNS_SPRITE_180;
+               is_mirror = false;
+               break;
+       case 3:
+               rot_type = ROT_FMTOWNS_SPRITE_0;
+               is_mirror = true;
+               break;
+       case 4:
+               rot_type = ROT_FMTOWNS_SPRITE_270;
+               is_mirror = true;
+               break;
+       case 5:
+               rot_type = ROT_FMTOWNS_SPRITE_90;
+               is_mirror = false;
+               break;
+       case 6:
+               rotate = false;
+               rot_type = ROT_FMTOWNS_SPRITE_270;
+               is_mirror = false;
+               break;
+       case 7:
+               rot_type = ROT_FMTOWNS_SPRITE_90;
+               is_mirror = true;
+               break;
+       }
+       if(sprite_table[num].is_32768) {
+       switch(half_type & 3) {
+       case 0: // not rotate
+               render_32768_x1_x1(num, dst, rot_type, mirror, stride);
+               break;
+       case 1:
+               render_32768_x05_x1(num, dst, rot_type, mirror, stride);
+               break;
+       case 2:
+               render_32768_x1_x05(num, dst, rot_type, mirror, stride);
+               break;
+       case 3:
+               render_32768_x05_x05(num, dst, rot_type, mirror, stride);
+               break;
+       }
+       } else {
+       switch(half_type & 3) {
+       case 0: // not rotate
+               render_16_x1_x1(num, dst, rot_type, mirror, stride);
+               break;
+       case 1:
+               render_16_x05_x1(num, dst, rot_type, mirror, stride);
+               break;
+       case 2:
+               render_16_x1_x05(num, dst, rot_type, mirror, stride);
+               break;
+       case 3:
+               render_16_x05_x05(num, dst, rot_type, mirror, stride);
+               break;
+       }
+       }
+}
+
 #endif /* _TOWNS_SPRITE_H */
 #endif /* _TOWNS_SPRITE_H */