equal
deleted
inserted
replaced
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; |