for(int i = 0; i < 256; i++) {
color_cached[i] = false;
}
+ use_cache = false; // ToDo: Enable cache.
}
void TOWNS_SPRITE::reset()
bool halfx = ((num_attr & 0x0400) != 0);
bool halfy = ((num_attr & 0x0800) != 0);
bool enable_offset = ((num_attr & 0x8000) != 0);
+
sprite_table[table_num].num = num;
sprite_table[table_num].rotate_type = rotate_type;
sprite_table[table_num].is_halfx = halfx;
sprite_table[table_num].is_disp = ((color_table_num & 0x2000) != 0);
}
-void TOWNS_SPRITE::render_not_rotate(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) {
- } 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_sprite(int num, uint16* dst_pixel, int width, int height, int stride)
{
+ uint16_t sprite_limit = reg_index & 0x3ff;
+ if(sprite_limit == 0) sprite_limit = 1024;
if(num < 0) return;
if(num >= sprite_limit) return;
if(num >= 1024) return;
if(stride <= 0) return;
if(stride > 512) return;
if(!(sprite_table[num].is_disp)) return;
-
+
+ if(use_cache) {
for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
if(!(cache_index[i].is_use)) continue;
if(cache_index[i].attribute == sprite_table[num].attribute) {
if(cache_index[i].is_32768 == sprite_table[num].is_32768) {
if(cache_index[i].is_32768) {
//
+ // ToDo: Integrate to not hitting cache.
int h = (cache_index[i].is_halfy) ? 8 : 16;
int w = (cache_index[i].is_halfx) ? 8 : 16;
if(height < h) h = height;
uint16_t* rp = &qp[y << 4];
uint16_t* rm = &qm[y << 4];
ppp = pp;
+__DECL_VECTORIZED_LOOP
for(x = 0; x < w; x++) {
uint16_t pixel = *rp;
uint16_t dpixel = *ppp;
}
}
}
+ }
// Cache Not hit
int target_num = -1;
for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
cache_index[target_num].masks = (uint16_t*)(&(cache_masks[target_num][0]));
cache_index[target_num].color = sprite_table[num].color;
cache_index[target_num].num = sprite_table[num].num;
- color_cached[(cache_index[target_num].color) & 0xff] = true;
+ if(!(cache_index[target_num].is_32768)) {
+ color_cached[(cache_index[target_num].color) & 0xff] = true;
+ }
pattern_cached[sprite_table[num].num] = true; // OK?
- render_base(num, dst_pixel, width, height, stride);
+ 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;
+ }
+ uint32_t index_num = cache_index[target_num].attribute & 0x3ff;
+ if(index_num < 128) return;
+
+ uint8_t* src = &(pattern_ram[index_num << 7]);
+ bool is_32768 = cache_index[target_num].is_32768;
+ bool is_halfx = cache_index[target_num].is_halfx;
+ bool is_halfy = cache_index[target_num].is_halfy;
+
+ switch(rot_type) {
+ case ROT_FMTOWNS_SPRITE_00:
+ rot_data_0(src, is_mirror, cache_index[target_num].pixels, cache_index[target_num].masks, is_32768, is_halfx, is_halfy);
+ break;
+ case ROT_FMTOWNS_SPRITE_90:
+ rot_data_0(src, is_mirror, cache_index[target_num].pixels, cache_index[target_num].masks, is_32768, is_halfx, is_halfy);
+ break;
+ case ROT_FMTOWNS_SPRITE_180:
+ rot_data_0(src, is_mirror, cache_index[target_num].pixels, cache_index[target_num].masks, is_32768, is_halfx, is_halfy);
+ break;
+ case ROT_FMTOWNS_SPRITE_270:
+ rot_data_0(src, is_mirror, cache_index[target_num].pixels, cache_index[target_num].masks, is_32768, is_halfx, is_halfy);
+ break;
+ }
+ // ToDo: wrap round.This is still bogus implement.
+ // ToDo: Separate writing buffer and integrate cache.
+ // copy cache to buffer
+ uint16_t* pp = cache_index[target_num].pixels;
+ uint16_t* pq = cache_index[target_num].masks;
+ uint16_t* pd = dst_pixel;
+ if(is_halfx) {
+ uint16_t cacheline[8];
+ uint16_t mcacheline[8];
+ uint16_t pcacheline[8];
+ int ysize = 16;
+ if(is_halfy) {
+ ysize = 8;
+ }
+ for(int y = 0; y < ysize; y++) {
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 8; x++) {
+ cacheline[x] = pp[x];
+ mcacheline[x] = pq[x];
+ }
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 8; x++) {
+ pcacheline[x] = pd[x] & mcacheline[x];
+ mcacheline[x] = ~mcacheline[x];
+ cacheline[x] = cacheline[x] & mcacheline[x];
+ }
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 8; x++) {
+ pd[x] = pcacheline[x] | mcacheline[x];
+ }
+ pd = pd + stride;
+ pp += 8;
+ pq += 8;
+ }
+ } else { // Not halfx
+ uint16_t cacheline[16];
+ uint16_t mcacheline[16];
+ uint16_t pcacheline[16];
+ int ysize = 16;
+ if(is_halfy) {
+ ysize = 8;
+ }
+ for(int y = 0; y < ysize; y++) {
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 16; x++) {
+ cacheline[x] = pp[x];
+ mcacheline[x] = pq[x];
+ }
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 16; x++) {
+ pcacheline[x] = pd[x] & mcacheline[x];
+ mcacheline[x] = ~mcacheline[x];
+ cacheline[x] = cacheline[x] & mcacheline[x];
+ }
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 16; x++) {
+ pd[x] = pcacheline[x] | mcacheline[x];
+ }
+ pd = pd + stride;
+ pp += 8;
+ pq += 8;
+ }
+ }
}
+void TOWNS_SPRITE::render(uint16_t *buffer, int w, int h, int stride)
+{
+ // ToDo: Implement Register #2-5
+ uint16_t lot = reg_index & 0x3ff;
+ if(lot == 0) lot = 1024;
+ if((w <= 0) || (h <= 0)) return;
+ if(stride <= 0) return;
+ // Clear buffer?
+ memset(buffer, 0x00, w * h * sizeof(uint16_t));
+
+ if(reg_spen) {
+ for(int i = 0; i < (int)lot; i++) {
+ uint16_t* index_base = &(index_ram[i << 2]);
+ uint16_t xaddr = index_base[0] & 0x1ff;
+ uint16_t yaddr = index_base[1] & 0x1ff;
+ if((xaddr < (uint16_t)w) && (yaddr < (uint16_t)h)) {
+ // ToDo: wrap round.This is still bogus implement.
+ uint16_t* addr = &(buffer[yaddr * w + xaddr]);
+ render_sprite(i, addr, width, height, stride);
+ }
+ }
+ }
+}
+// ToDo: Discard cache(s) if dirty color index and if used this cache at 16 colors.
+// ToDo: Discard cache(s) if dirty
void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data)
{
reg_addr = addr & 7;
void TOWNS_SPRITE::write_data8(uint32_t addr, uint32_t data)
{
uint32_t nbank;
+ uint32_t uaddr;
+ uint16_t tmp16;
+ uint8_t tmp8;
uint8_t* p8;
pair_t tval;
if((addr >= 0x81000000) && (addr < 0x81020000)) {
} else {
nbank = 0; // OK?
}
+
switch(nbank) {
case 0:
case 1:
- tval.w.l = index_ram[(addr & 0x1ffe) >> 1];
+ uaddr = (addr & 0x1ffe) >> 1;
+ tval.w.l = index_ram[uaddr];
+ tmp16 = tval.w.l;
if((addr & 1) == 0) { // Lo
tval.b.l = (uint8_t)(data & 0xff);
} else {
tval.b.h = (uint8_t)(data & 0xff);
}
- index_ram[(addr & 0x1ffe) >> 1] = tval.w.l;
+ if(use_cache) {
+ if(uaddr == 2) { // ATTR
+ if((tmp16 & 0x7c00) != (tval.w.l & 0x7c00)) {
+ // Search cache and Discard cache
+ }
+ } else if(uaddr == 3) {
+ if((tmp16 & 0x8fff) != (tval.w.l & 0x8fff)) {
+ // Search cache and Discard cache
+ }
+ }
+ }
+ index_ram[uaddr] = tval.w.l;
break;
case 2:
case 3:
// ToDO: Discard cache
- tval.w.l = color_ram[(addr & 0x1ffe) >> 1];
+ uaddr = (addr & 0x1ffe) >> 1;
+ tval.w.l = color_ram[uaddr];
+ tmp16 = tval.w.l;
if((addr & 1) == 0) { // Lo
tval.b.l = (uint8_t)(data & 0xff);
} else {
tval.b.h = (uint8_t)(data & 0xff);
}
- color_ram[(addr & 0x1ffe) >> 1] = tval.w.l;
- if(color_cached[(addr & 0x1ffe) >> 5]) {
- uint32_t nnum = (addr & 0x1ffe) >> 5;
- for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
- if(cache_index[i].color == (uint16_t)(nnum + 256)) {
- if(cache_index[i].is_use) {
- clear_cache(i);
+ if(use_cache) {
+ if(tmp16 != tval.w.l) { // Dirty color table
+ uint32_t nnum = uaddr >> 4;
+ color_ram[uaddr] = tval.w.l;
+ if(color_cached[nnum]) {
+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
+ if(cache_index[i].color == (uint16_t)(nnum + 256)) {
+ if((cache_index[i].is_use) && !(cache_index[i].is_32768)) {
+ clear_cache(i);
+ }
}
}
+ color_cached[nnum] = false;
+
}
- color_cached[nnum] = false;
+ } else {
+ color_ram[uaddr] = tval.w.l;
}
break;
default:
// ToDO: Discard cache
- p8 = &(pattern_ram[(addr & 0x1ffff) - 0x4000]);
- *p8 = (uint8_t)(data & 0xff);
- if(pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7]) {
- uint32_t nnum = ((addr & 0x1fffe) - 0x4000) >> 7;
- for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
- if(cache_index[i].num == (uint16_t)nnum) {
- if(cache_index[i].is_use) {
- clear_cache(i);
+ uaddr = (addr & 0x1ffff) - 0x4000;
+ p8 = &(pattern_ram[uaddr]);
+ tmp8 = *p8;
+ if(use_cache) {
+ if((uint8_t)(data & 0xff) != tmp8) { // Dirty pattern memory.
+ *p8 = (uint8_t)(data & 0xff);
+ uint32_t nnum = uaddr >> 7;
+ uint32_t nnum_bak = nnum;
+ if(pattern_cached[nnum]) { // ToDo: Search another number.
+ for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
+ if(cache_index[i].is_32768) {
+ if(cache_index[i].num == (uint16_t)nnum) {
+ if(cache_index[i].is_use) {
+ clear_cache(i);
+ }
+ }
+ } else {
+ uint32_t begin;
+ uint32_t end;
+ uint32_t clen = 0;
+ // OK?
+ begin = (nnum <= (128 + 3)) ? (128 + 3) : nnum - 3;
+ end = (nnum <= 128) ? 128 : nnum + 3;
+ if(begin < 1024) {
+ if(end > 1023) end = 1023;
+ if((cache_index[i].num >= begin) && (cache_index[i].num <= end)) {
+ clen = end - begin + 1;
+ for(uint32_t j = 0; j < clen; j++) {
+ if(cache_index[i].num == (uint16_t)(begin + j)) {
+ if(cache_index[i].is_use) {
+ clear_cache(i);
+ }
+ }
+ }
+ }
+ }
}
}
+ pattern_cached[nnum] = false;
+ }
}
- pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7] = false;
- }
+ } else {
+ *p8 = (uint8_t)(data & 0xff);
+ }
break;
}
return;
void TOWNS_SPRITE::write_data16(uint32_t addr, uint32_t data)
{
- uint32_t nbank;
- uint16_t* p;
- pair_t tval;
- if((addr >= 0x81000000) && (addr < 0x81020000)) {
- nbank = (addr & 0x1e000) >> 12;
- } else {
- nbank = 0; // OK?
- }
- switch(nbank) {
- case 0:
- case 1:
- index_ram[(addr & 0x1ffe) >> 1] = (uint16_t)(data & 0xffff);
- break;
- case 2:
- case 3:
- // ToDO: Discard cache
- color_ram[(addr & 0x1ffe) >> 1] = (uint16_t)(data & 0xffff);
- if(color_cached[(addr & 0x1ffe) >> 5]) {
- uint32_t nnum = (addr & 0x1ffe) >> 5;
- for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
- if(cache_index[i].color == (uint16_t)(nnum + 256)) {
- if(cache_index[i].is_use) {
- clear_cache(i);
- }
- }
- }
- color_cached[nnum] = false;
- }
- break;
- default:
- // ToDO: Discard cache
- tval.w.l = (uint16_t)data;
- pattern_ram[(addr & 0x1fffe) - 0x4000] = tval.b.l;
- pattern_ram[(addr & 0x1fffe) - 0x4000 + 1] = tval.b.h;
- if(pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7]) {
- uint32_t nnum = ((addr & 0x1fffe) - 0x4000) >> 7;
- for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) {
- if(cache_index[i].num == (uint16_t)nnum) {
- if(cache_index[i].is_use) {
- clear_cache(i);
- }
- }
- }
- pattern_cached[((addr & 0x1fffe) - 0x4000) >> 7] = false;
- }
- break;
- }
- return;
+ pair_t t;
+ t.d = data;
+ write_data8(addr, (uint32_t)(t.b.l));
+ write_data8(addr + 1, (uint32_t)(t.b.h));
}
-
+
void TOWNS_SPRITE::write_data32(uint32_t addr, uint32_t data)
{
pair_t t;
t.d = data;
- write_data16(addr, (uint32_t)(t.w.l));
- if(addr < 0x8101fffe) write_data16(addr + 2, (uint32_t)(t.w.h));
+ write_data8(addr, (uint32_t)(t.b.l));
+ write_data8(addr + 1, (uint32_t)(t.b.h));
+ if(addr < 0x8101fffe) {
+ write_data8(addr + 2, (uint32_t)(t.b.h2));
+ write_data8(addr + 3, (uint32_t)(t.b.h3));
+ }
}
-
+// Q: Is changing pages syncing to Frame?
+// ToDo: Implement VRAM.
+void FMTOWNS_SPRITE::write_signal(int id, uint32_t data, uint32_t mask)
+{
+ if(id == SIG_FMTOWNS_SPRITE_CACHE_ENABLE) {
+ cache_enabled = ((data & mask) != 0);
+ } else if(id == SIG_FMTOWNS_SPRITE_SWAP_BUFFER) {
+ write_page = display_page;
+ display_page = (displae_page + 1) & 1;
+ } else if(id == SIG_FMTOWNS_SPRITE_SET_DATA_VRAM) {
+ } else if(id == SIG_FMTOWNS_SPRITE_SET_MASK_VRAM) {
+ }
+
+}
#define STATE_VERSION 1
#include "../../statesub.h"
DECL_STATE_ENTRY_UINT16(reg_hoffset);
DECL_STATE_ENTRY_BOOL(disp_page0);
DECL_STATE_ENTRY_BOOL(disp_page1);
-
- DECL_STATE_ENTRY_INT32(sprite_limit);
+
+ DECL_STATE_ENTRY_BOOL(use_cache);
+
DECL_STATE_ENTRY_1D_ARRAY(index_ram, sizeof(index_ram) / sizeof(uint16_t));
DECL_STATE_ENTRY_1D_ARRAY(pattern_ram, sizeof(pattern_ram) / sizeof(uint8_t));
class TOWNS_SPRITE : public DEVICE
{
-private:
+
+protected:
TOWNS_VRAM *vram_head;
// REGISTERS
bool pattern_cached[((65536 - (4096 * 2)) * 2) / (8 * 16)];
bool color_cached[256];
-protected:
+
+ bool sprite_enabled;
+ bool use_cache;
+ inline void take_data_32768(uint16_t* src, uint16_t* dst, uint16_t* mask);
+ inline void take_data_32768_mirror(uint16_t* src, uint16_t* dst, uint16_t* mask);
+ inline void take_data_16(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask);
+ inline void take_data_16_mirror(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask);
+ inline void zoom_data(uint16_t* cache, uint16_t* maskcache, bool is_halfx, bool is_halfy, uint16_t* dstcache, uint16_t* dstmask);
+
+ void rotate_data_0(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy);
+ void rotate_data_90(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy);
+ void rotate_data_180(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy);
+ void rotate_data_270(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy);
public:
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)
+inline void TOWNS_SPRITE::take_data_32768(uint16_t* src, uint16_t* dst, uint16_t* mask)
{
- 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];
- }
- }
+ uint16_t* p = src;
+ uint16_t* q = dst;
+ uint16_t* r = mask;
+ for(int y = 0; y < 16; y++) {
+ for(int x = 0; x < 16; x++) {
+ q[x] = p[x];
}
-__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];
+ r[x] = ((q[x] & 0x8000) != 0) ? 0 : 0xffff;
}
+ r += 16;
+ q += 16;
+ p += 16;
}
}
-inline void TOWNS_SPRITE::render_32768_x05_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+inline void TOWNS_SPRITE::take_data_32768_mirror(uint16_t* src, uint16_t* dst, uint16_t* mask)
{
- 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];
- }
- }
+ uint16_t* p = src;
+ uint16_t* q = dst;
+ uint16_t* r = mask;
+ for(int y = 0; y < 16; y++) {
+ for(int x = 0; x < 16; x++) {
+ q[x] = p[15 - 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];
+ for(int x = 0; x < 16; x++) {
+ r[x] = ((q[x] & 0x8000) != 0) ? 0 : 0xffff;
}
+ r += 16;
+ q += 16;
+ p += 16;
}
}
-inline void TOWNS_SPRITE::render_32768_x1_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+inline void TOWNS_SPRITE::take_data_16(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask)
{
- 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];
- }
- }
+ uint8_t* p = src;
+ uint16_t* q = dst;
+ uint16_t* r = mask;
+ uint8_t cache[16];
+ for(int y = 0; y < 16; y++) {
+ for(int x = 0; x < 16; x += 2) {
+ cache[x] = p[x >> 1];
+ cache[x + 1] = cache[x];
+ }
+ for(int x = 0; x < 16; x += 2) {
+ cache[x] = cache[x] >> 4;
}
-__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];
+ for(int x = 0; x < 16; x++) {
+ cache[x] = cache[x] & 0x0f;
+ r[x] = (cache[x] == 0) ? 0x0000 : 0xffff;
+ q[x] = color_table[cache[x]];
}
+ r += 16;
+ q += 16;
+ p += 8;
}
}
-inline void TOWNS_SPRITE::render_32768_x05_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+inline void TOWNS_SPRITE::take_data_16_mirror(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask)
{
- 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];
- }
- }
+ uint8_t* p = src;
+ uint16_t* q = dst;
+ uint16_t* r = mask;
+ uint8_t cache[16];
+ for(int y = 0; y < 16; y++) {
+ for(int x = 0; x < 16; x += 2) {
+ cache[x] = p[(15 - x) >> 1];
+ cache[x + 1] = cache[x];
+ }
+ for(int x = 1; x < 16; x += 2) {
+ cache[x] = cache[x] >> 4;
}
-__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];
+ for(int x = 0; x < 16; x++) {
+ cache[x] = cache[x] & 0x0f;
+ r[x] = (cache[x] == 0) ? 0x0000 : 0xffff;
+ q[x] = color_table[cache[x]];
}
+ r += 16;
+ q += 16;
+ p += 8;
}
}
-inline void TOWNS_SPRITE::render_16_x1_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+void TOWNS_SPRITE::rotate_data_0(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy)
{
- 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;
- }
+ uint16_t cache[16 * 16];
+ if(!is_32768) {
+ if(is_mirror) {
+ take_data_16_mirror(src, color_table, cache, mask);
} 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;
- }
-
+ take_data_16(src, color_table, cache, mask);
}
-__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];
+
+ } else {
+ if(is_mirror) {
+ take_data_32768_mirror((uint16_t*)src, cache, mask);
+ } else {
+ take_data_16((uint16_t*)src, cache, mask);
}
}
+ // Rotate
+ // Zoom
+ uint16_t maskcache[16 * 16];
+ memcpy(maskcache, mask, sizeof(maskcache));
+ zoom_data(cache, maskcache, is_halfx, is_halfy, dstcache, mask);
}
-inline void TOWNS_SPRITE::render_16_x05_x1(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+void TOWNS_SPRITE::rotate_data_90(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy)
{
- 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;
- }
+ uint16_t cache[16 * 16];
+ if(!is_32768) {
+ if(is_mirror) {
+ take_data_16_mirror(src, color_table, cache, mask);
} 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;
- }
+ take_data_16(src, color_table, cache, mask);
}
-__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];
+
+ } else {
+ if(is_mirror) {
+ take_data_32768_mirror((uint16_t*)src, cache, mask);
+ } else {
+ take_data_16((uint16_t*)src, cache, mask);
}
}
+ // Rotate
+ uint16_t maskcache[16][16];
+ uint16_t cache2[16][16];
+ if(is_mirror) {
+ // q[x][y] = p[15 - y][15 - x]
+__DECL_VECTORIZED_LOOP
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[15 - y]);
+ uint16_t* q = &(mask[15 - y]);
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[(15 - x) << 4];
+ maskcache[y][x] = q[(15 - x) << 4];
+ }
+ }
+ } else {
+ // q[x][y] = p[15 - y][x]
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[15 - y]);
+ uint16_t* q = &(mask[15 - y]);
+__DECL_VECTORIZED_LOOP
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[x << 4];
+ maskcache[y][x] = q[x << 4];
+ }
+ }
+ }
+ zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask);
}
-
-inline void TOWNS_SPRITE::render_16_x1_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+void TOWNS_SPRITE::rotate_data_180(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy)
{
- 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 cache[16 * 16];
+ if(!is_32768) {
+ if(is_mirror) {
+ take_data_16_mirror(src, color_table, cache, mask);
+ } else {
+ take_data_16(src, color_table, cache, mask);
+ }
+
+ } else {
+ if(is_mirror) {
+ take_data_32768_mirror((uint16_t*)src, cache, mask);
+ } else {
+ take_data_16((uint16_t*)src, cache, mask);
+ }
}
- 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)
+ // Rotate
+ uint16_t maskcache[16][16];
+ uint16_t cache2[16][16];
+ if(is_mirror) {
+ // q[x][y] = p[x][15 - y]
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[(15 - y) << 4]);
+ uint16_t* q = &(mask[(15 - y) << 4]);
+__DECL_VECTORIZED_LOOP
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[x];
+ maskcache[y][x] = q[x];
}
- p = &(yaddr[0]);
- if(xreverse) {
-__DECL_VECTORIZED_LOOP
- for(int i = 15; i >= 0; i--) {
- pixels[i] = p[15 - i];
- }
- } else {
+ }
+ } else {
+ // q[x][y] = p[15 - x][15 - y]
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[15 - y] << 4);
+ uint16_t* q = &(mask[15 - y] << 4);
__DECL_VECTORIZED_LOOP
- for(int i = 0; i <= 15; i++) {
- pixels[i] = p[i];
- }
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[15 - x];
+ maskcache[y][x] = q[15 - x];
}
+ }
+ }
+ zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask);
+}
+
+void TOWNS_SPRITE::rotate_data_270(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768,bool is_halfx, bool is_halfy)
+{
+ uint16_t cache[16 * 16];
+ if(!is_32768) {
+ if(is_mirror) {
+ take_data_16_mirror(src, color_table, cache, mask);
} 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];
- }
- }
+ take_data_16(src, color_table, cache, mask);
}
-__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];
+
+ } else {
+ if(is_mirror) {
+ take_data_32768_mirror((uint16_t*)src, cache, mask);
+ } else {
+ take_data_16((uint16_t*)src, cache, mask);
}
}
+ // Rotate
+ uint16_t maskcache[16][16];
+ uint16_t cache2[16][16];
+ if(is_mirror) {
+ // q[x][y] = p[y][x]
+
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[y]);
+ uint16_t* q = &(mask[y]);
+__DECL_VECTORIZED_LOOP
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[x << 4];
+ maskcache[y][x] = q[x << 4];
+ }
+ }
+ } else {
+ // q[x][y] = p[y][15 - x]
+ for(y = 0; y < 16; y++) {
+ uint16_t* p = &(cache[15 - y]);
+ uint16_t* q = &(mask[15 - y]);
+__DECL_VECTORIZED_LOOP
+ for(x = 0; x < 16; x++) {
+ cache2[y][x] = p[x << 4];
+ maskcache[y][x] = q[x << 4];
+ }
+ }
+ }
+ zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask);
}
-inline void TOWNS_SPRITE::render_16_x05_x05(int num, uint16_t* dst, int rot_type, bool is_mirror, int stride)
+inline void TOWNS_SPRITE::zoom_data(uint16_t* cache, uint16_t* maskcache, bool is_halfx, bool is_halfy, uint16_t* dstcache, uint16_t* dstmask)
{
- 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];
+ if(is_halfx) {
+ if(is_halfy) {
+ uint16_t cache2[8][8];
+ uint16_t maskcache2[8][8];
+ for(int y = 0; y < 16; y += 2) {
+ uint16_t cacheline[8];
+ uint16_t *pp = &(cache[y << 4]);
+ uint16_t maskcacheline[8];
+ uint16_t *pq = &(maskcache[y << 4]);
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 8; x++) {
+ cacheline[x] = pp[x << 1];
+ maskcacheline[x] = pq[x << 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];
+ for(int x = 0; x < 8; x++) {
+ cache2[y >> 1][x] = cacheline[x];
+ maskcache2[y >> 1][x] = maskcacheline[x];
+ }
+ }
+ memcpy(dstcache, &(cache2[0][0]), 8 * 8 * sizeof(uint16_t));
+ memcpy(dstmask, &(maskcache2[0][0]), 8 * 8 * sizeof(uint16_t));
+ } else { // halfx only, not halfy
+ uint16_t cache2[16][8];
+ uint16_t maskcache2[16][8];
+ for(int y = 0; y < 16; y++) {
+ uint16_t cacheline[8];
+ uint16_t *pp = &(cache[y << 4]);
+ uint16_t maskcacheline[8];
+ uint16_t *pq = &(maskcache[y << 4]);
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 8; x++) {
+ cacheline[x] = pp[x << 1];
+ maskcacheline[x] = pq[x << 1];
}
- } else {
__DECL_VECTORIZED_LOOP
- for(int x = 0; x <= 7; x++) {
- p = &(yaddr[x << 6]);
- pixels[x] = p[x];
+ for(int x = 0; x < 8; x++) {
+ cache2[y][x] = cacheline[x];
+ maskcache2[y][x] = maskcacheline[x];
}
}
+ memcpy(dstcache, &(cache2[0][0]), 16 * 8 * sizeof(uint16_t));
+ memcpy(mask, &(maskcache2[0][0]), 16 * 8 * sizeof(uint16_t));
}
-__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;
- }
+ if(is_halfy) { // halfx only, not halfx
+ uint16_t cache2[16][8];
+ uint16_t maskcache2[16][8];
+ for(int y = 0; y < 16; y += 2) {
+ uint16_t cacheline[16];
+ uint16_t *pp = &(cache[y << 4]);
+ uint16_t maskcacheline[16];
+ uint16_t *pq = &(maskcache[y << 4]);
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 16; x++) {
+ cacheline[x] = pp[x];
+ maskcacheline[x] = pq[x];
+ }
+__DECL_VECTORIZED_LOOP
+ for(int x = 0; x < 16; x++) {
+ cache2[y >> 1][x] = cacheline[x];
+ maskcache2[y >> 1][x] = maskcacheline[x];
+ }
+ }
+ memcpy(dstcache, &(cache2[0][0]), 8 * 16 * sizeof(uint16_t));
+ memcpy(dstmask, &(maskcache2[0][0]), 8 * 16 * sizeof(uint16_t));
+ } else { // 1x1
+ memcpy(dstcache, cache, 16 * 16 * sizeof(uint16_t));
+ memcpy(dstmask, maskcache, 16 * 16 * sizeof(uint16_t));
+ }
}
}