src/gfx.cpp
changeset 8981 dd0cd0e54ac3
parent 8857 7593af4962e6
child 8985 6461e5c6d6e4
equal deleted inserted replaced
8980:3f434ded0a30 8981:dd0cd0e54ac3
    62  */
    62  */
    63 static Rect _invalid_rect;
    63 static Rect _invalid_rect;
    64 static const byte *_color_remap_ptr;
    64 static const byte *_color_remap_ptr;
    65 static byte _string_colorremap[3];
    65 static byte _string_colorremap[3];
    66 
    66 
    67 #define DIRTY_BYTES_PER_LINE (MAX_SCREEN_WIDTH / 64)
    67 enum {
    68 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8];
    68 	DIRTY_BLOCK_HEIGHT   = 8,
       
    69 	DIRTY_BLOCK_WIDTH    = 64,
       
    70 	DIRTY_BYTES_PER_LINE = MAX_SCREEN_WIDTH / DIRTY_BLOCK_WIDTH,
       
    71 };
       
    72 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / DIRTY_BLOCK_HEIGHT];
    69 
    73 
    70 void GfxScroll(int left, int top, int width, int height, int xo, int yo)
    74 void GfxScroll(int left, int top, int width, int height, int xo, int yo)
    71 {
    75 {
    72 	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
    76 	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
    73 
    77 
  1031  * @see SetDirtyBlocks
  1035  * @see SetDirtyBlocks
  1032  */
  1036  */
  1033 void DrawDirtyBlocks()
  1037 void DrawDirtyBlocks()
  1034 {
  1038 {
  1035 	byte *b = _dirty_blocks;
  1039 	byte *b = _dirty_blocks;
  1036 	const int w = Align(_screen.width, 64);
  1040 	const int w = Align(_screen.width,  DIRTY_BLOCK_WIDTH);
  1037 	const int h = Align(_screen.height, 8);
  1041 	const int h = Align(_screen.height, DIRTY_BLOCK_HEIGHT);
  1038 	int x;
  1042 	int x;
  1039 	int y;
  1043 	int y;
  1040 
  1044 
  1041 	if (IsGeneratingWorld() && !IsGeneratingWorldReadyForPaint()) return;
  1045 	if (IsGeneratingWorld() && !IsGeneratingWorldReadyForPaint()) return;
  1042 
  1046 
  1045 		x = 0;
  1049 		x = 0;
  1046 		do {
  1050 		do {
  1047 			if (*b != 0) {
  1051 			if (*b != 0) {
  1048 				int left;
  1052 				int left;
  1049 				int top;
  1053 				int top;
  1050 				int right = x + 64;
  1054 				int right = x + DIRTY_BLOCK_WIDTH;
  1051 				int bottom = y;
  1055 				int bottom = y;
  1052 				byte *p = b;
  1056 				byte *p = b;
  1053 				int h2;
  1057 				int h2;
  1054 
  1058 
  1055 				/* First try coalescing downwards */
  1059 				/* First try coalescing downwards */
  1056 				do {
  1060 				do {
  1057 					*p = 0;
  1061 					*p = 0;
  1058 					p += DIRTY_BYTES_PER_LINE;
  1062 					p += DIRTY_BYTES_PER_LINE;
  1059 					bottom += 8;
  1063 					bottom += DIRTY_BLOCK_HEIGHT;
  1060 				} while (bottom != h && *p != 0);
  1064 				} while (bottom != h && *p != 0);
  1061 
  1065 
  1062 				/* Try coalescing to the right too. */
  1066 				/* Try coalescing to the right too. */
  1063 				h2 = (bottom - y) >> 3;
  1067 				h2 = (bottom - y) / DIRTY_BLOCK_HEIGHT;
  1064 				assert(h2 > 0);
  1068 				assert(h2 > 0);
  1065 				p = b;
  1069 				p = b;
  1066 
  1070 
  1067 				while (right != w) {
  1071 				while (right != w) {
  1068 					byte *p2 = ++p;
  1072 					byte *p2 = ++p;
  1073 						p2 += DIRTY_BYTES_PER_LINE;
  1077 						p2 += DIRTY_BYTES_PER_LINE;
  1074 					} while (--h != 0);
  1078 					} while (--h != 0);
  1075 
  1079 
  1076 					/* Wohoo, can combine it one step to the right!
  1080 					/* Wohoo, can combine it one step to the right!
  1077 					 * Do that, and clear the bits. */
  1081 					 * Do that, and clear the bits. */
  1078 					right += 64;
  1082 					right += DIRTY_BLOCK_WIDTH;
  1079 
  1083 
  1080 					h = h2;
  1084 					h = h2;
  1081 					p2 = p;
  1085 					p2 = p;
  1082 					do {
  1086 					do {
  1083 						*p2 = 0;
  1087 						*p2 = 0;
  1097 				if (left < right && top < bottom) {
  1101 				if (left < right && top < bottom) {
  1098 					RedrawScreenRect(left, top, right, bottom);
  1102 					RedrawScreenRect(left, top, right, bottom);
  1099 				}
  1103 				}
  1100 
  1104 
  1101 			}
  1105 			}
  1102 		} while (b++, (x += 64) != w);
  1106 		} while (b++, (x += DIRTY_BLOCK_WIDTH) != w);
  1103 	} while (b += -(w >> 6) + DIRTY_BYTES_PER_LINE, (y += 8) != h);
  1107 	} while (b += -(w / DIRTY_BLOCK_WIDTH) + DIRTY_BYTES_PER_LINE, (y += DIRTY_BLOCK_HEIGHT) != h);
  1104 
  1108 
  1105 	_invalid_rect.left = w;
  1109 	_invalid_rect.left = w;
  1106 	_invalid_rect.top = h;
  1110 	_invalid_rect.top = h;
  1107 	_invalid_rect.right = 0;
  1111 	_invalid_rect.right = 0;
  1108 	_invalid_rect.bottom = 0;
  1112 	_invalid_rect.bottom = 0;
  1145 	if (left   < _invalid_rect.left  ) _invalid_rect.left   = left;
  1149 	if (left   < _invalid_rect.left  ) _invalid_rect.left   = left;
  1146 	if (top    < _invalid_rect.top   ) _invalid_rect.top    = top;
  1150 	if (top    < _invalid_rect.top   ) _invalid_rect.top    = top;
  1147 	if (right  > _invalid_rect.right ) _invalid_rect.right  = right;
  1151 	if (right  > _invalid_rect.right ) _invalid_rect.right  = right;
  1148 	if (bottom > _invalid_rect.bottom) _invalid_rect.bottom = bottom;
  1152 	if (bottom > _invalid_rect.bottom) _invalid_rect.bottom = bottom;
  1149 
  1153 
  1150 	left >>= 6;
  1154 	left /= DIRTY_BLOCK_WIDTH;
  1151 	top  >>= 3;
  1155 	top  /= DIRTY_BLOCK_HEIGHT;
  1152 
  1156 
  1153 	b = _dirty_blocks + top * DIRTY_BYTES_PER_LINE + left;
  1157 	b = _dirty_blocks + top * DIRTY_BYTES_PER_LINE + left;
  1154 
  1158 
  1155 	width  = ((right  - 1) >> 6) - left + 1;
  1159 	width  = ((right  - 1) / DIRTY_BLOCK_WIDTH)  - left + 1;
  1156 	height = ((bottom - 1) >> 3) - top  + 1;
  1160 	height = ((bottom - 1) / DIRTY_BLOCK_HEIGHT) - top  + 1;
  1157 
  1161 
  1158 	assert(width > 0 && height > 0);
  1162 	assert(width > 0 && height > 0);
  1159 
  1163 
  1160 	do {
  1164 	do {
  1161 		int i = width;
  1165 		int i = width;