8bpp_optimized.cpp
Go to the documentation of this file.00001
00002
00005 #include "../stdafx.h"
00006 #include "../zoom_func.h"
00007 #include "../debug.h"
00008 #include "../core/alloc_func.hpp"
00009 #include "8bpp_optimized.hpp"
00010
00011 static FBlitter_8bppOptimized iFBlitter_8bppOptimized;
00012
00013 void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
00014 {
00015 const uint8 *src, *src_next;
00016 uint8 *dst, *dst_line;
00017 uint offset = 0;
00018
00019
00020 offset = ((const uint8 *)bp->sprite)[(int)(zoom - ZOOM_LVL_BEGIN) * 2] | ((const byte *)bp->sprite)[(int)(zoom - ZOOM_LVL_BEGIN) * 2 + 1] << 8;
00021
00022
00023 src = (const uint8 *)bp->sprite + offset;
00024 dst_line = (uint8 *)bp->dst + bp->top * bp->pitch + bp->left;
00025
00026
00027 for (int y = 0; y < bp->skip_top; y++) {
00028 uint trans, pixels;
00029 for (;;) {
00030 trans = *src++;
00031 pixels = *src++;
00032 if (trans == 0 && pixels == 0) break;
00033 src += pixels;
00034 }
00035 }
00036
00037 src_next = src;
00038
00039 for (int y = 0; y < bp->height; y++) {
00040 dst = dst_line;
00041 dst_line += bp->pitch;
00042
00043 uint skip_left = bp->skip_left;
00044 int width = bp->width;
00045
00046 for (;;) {
00047 src = src_next;
00048 uint8 trans = *src++;
00049 uint8 pixels = *src++;
00050 src_next = src + pixels;
00051 if (trans == 0 && pixels == 0) break;
00052 if (width <= 0) continue;
00053
00054 if (skip_left != 0) {
00055 if (skip_left < trans) {
00056 trans -= skip_left;
00057 skip_left = 0;
00058 } else {
00059 skip_left -= trans;
00060 trans = 0;
00061 }
00062 if (skip_left < pixels) {
00063 src += skip_left;
00064 pixels -= skip_left;
00065 skip_left = 0;
00066 } else {
00067 src += pixels;
00068 skip_left -= pixels;
00069 pixels = 0;
00070 }
00071 }
00072 if (skip_left != 0) continue;
00073
00074
00075 dst += trans;
00076 width -= trans;
00077 if (width <= 0) continue;
00078 if (pixels > width) pixels = width;
00079 width -= pixels;
00080
00081 switch (mode) {
00082 case BM_COLOUR_REMAP:
00083 for (uint x = 0; x < pixels; x++) {
00084 if (bp->remap[*src] != 0) *dst = bp->remap[*src];
00085 dst++; src++;
00086 }
00087 break;
00088
00089 case BM_TRANSPARENT:
00090 for (uint x = 0; x < pixels; x++) {
00091 *dst = bp->remap[*dst];
00092 dst++; src++;
00093 }
00094 break;
00095
00096 default:
00097 memcpy(dst, src, pixels);
00098 dst += pixels; src += pixels;
00099 break;
00100 }
00101 }
00102 }
00103 }
00104
00105 Sprite *Blitter_8bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
00106 {
00107 Sprite *dest_sprite;
00108 byte *temp_dst;
00109 uint memory = 0;
00110 uint index = 0;
00111
00112
00113 memory += (int)(ZOOM_LVL_END - ZOOM_LVL_BEGIN) * sizeof(uint16);
00114 for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
00115 memory += UnScaleByZoom(sprite->height, i) * UnScaleByZoom(sprite->width, i);
00116 index += 2;
00117 }
00118
00119
00120 memory *= 5;
00121 temp_dst = MallocT<byte>(memory);
00122
00123
00124 for (ZoomLevel i = ZOOM_LVL_BEGIN; i < ZOOM_LVL_END; i++) {
00125
00126 const SpriteLoader::CommonPixel *src;
00127
00128
00129 temp_dst[i * 2] = index & 0xFF;
00130 temp_dst[i * 2 + 1] = (index >> 8) & 0xFF;
00131
00132 byte *dst = &temp_dst[index];
00133
00134 for (int y = 0; y < UnScaleByZoom(sprite->height, i); y++) {
00135 uint trans = 0;
00136 uint pixels = 0;
00137 uint last_color = 0;
00138 uint count_index = 0;
00139 uint rx = 0;
00140 src = &sprite->data[ScaleByZoom(y, i) * sprite->width];
00141
00142 for (int x = 0; x < UnScaleByZoom(sprite->width, i); x++) {
00143 uint color = 0;
00144
00145
00146 for (int j = 0; j < ScaleByZoom(1, i); j++) {
00147 if (src->m != 0) color = src->m;
00148 src++;
00149 rx++;
00150
00151 if (rx == sprite->width) break;
00152 }
00153
00154 if (last_color == 0 || color == 0 || pixels == 255) {
00155 if (count_index != 0) {
00156
00157 temp_dst[count_index] = pixels;
00158 pixels = 0;
00159 count_index = 0;
00160 }
00161
00162 if (color == 0) {
00163 last_color = 0;
00164 trans++;
00165 continue;
00166 }
00167
00168 *dst = trans;
00169 dst++; index++;
00170 trans = 0;
00171
00172 count_index = index;
00173 dst++; index++;
00174 }
00175 last_color = color;
00176 pixels++;
00177 *dst = color;
00178 dst++; index++;
00179 }
00180
00181 if (count_index != 0) temp_dst[count_index] = pixels;
00182
00183
00184 *dst = 0; dst++; index++;
00185 *dst = 0; dst++; index++;
00186 }
00187 }
00188
00189
00190 assert(index < memory);
00191
00192
00193 dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + index);
00194
00195 dest_sprite->height = sprite->height;
00196 dest_sprite->width = sprite->width;
00197 dest_sprite->x_offs = sprite->x_offs;
00198 dest_sprite->y_offs = sprite->y_offs;
00199 memcpy(dest_sprite->data, temp_dst, index);
00200 free(temp_dst);
00201
00202 return dest_sprite;
00203 }