src/gfx.cpp
changeset 10247 145d0458b685
parent 10241 4c95503096ac
child 10429 1b99254f9607
equal deleted inserted replaced
10246:707c09e2e42b 10247:145d0458b685
    15 #include "blitter/factory.hpp"
    15 #include "blitter/factory.hpp"
    16 #include "video/video_driver.hpp"
    16 #include "video/video_driver.hpp"
    17 #include "strings_func.h"
    17 #include "strings_func.h"
    18 #include "core/math_func.hpp"
    18 #include "core/math_func.hpp"
    19 #include "settings_type.h"
    19 #include "settings_type.h"
       
    20 #include "core/alloc_func.hpp"
    20 
    21 
    21 #include "table/palettes.h"
    22 #include "table/palettes.h"
    22 #include "table/sprites.h"
    23 #include "table/sprites.h"
    23 #include "table/control_codes.h"
    24 #include "table/control_codes.h"
    24 
    25 
    65 static byte _string_colorremap[3];
    66 static byte _string_colorremap[3];
    66 
    67 
    67 enum {
    68 enum {
    68 	DIRTY_BLOCK_HEIGHT   = 8,
    69 	DIRTY_BLOCK_HEIGHT   = 8,
    69 	DIRTY_BLOCK_WIDTH    = 64,
    70 	DIRTY_BLOCK_WIDTH    = 64,
    70 	DIRTY_BYTES_PER_LINE = MAX_SCREEN_WIDTH / DIRTY_BLOCK_WIDTH,
       
    71 };
    71 };
    72 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / DIRTY_BLOCK_HEIGHT];
    72 static uint _dirty_bytes_per_line = 0;
       
    73 static byte *_dirty_blocks = NULL;
    73 
    74 
    74 void GfxScroll(int left, int top, int width, int height, int xo, int yo)
    75 void GfxScroll(int left, int top, int width, int height, int xo, int yo)
    75 {
    76 {
    76 	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
    77 	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
    77 
    78 
   932 }
   933 }
   933 
   934 
   934 
   935 
   935 void ScreenSizeChanged()
   936 void ScreenSizeChanged()
   936 {
   937 {
       
   938 	_dirty_bytes_per_line = (_screen.width + DIRTY_BLOCK_WIDTH - 1) / DIRTY_BLOCK_WIDTH;
       
   939 	_dirty_blocks = ReallocT<byte>(_dirty_blocks, _dirty_bytes_per_line * ((_screen.height + DIRTY_BLOCK_HEIGHT - 1) / DIRTY_BLOCK_HEIGHT));
       
   940 
   937 	/* check the dirty rect */
   941 	/* check the dirty rect */
   938 	if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
   942 	if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
   939 	if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;
   943 	if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;
   940 
   944 
   941 	/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
   945 	/* screen size changed and the old bitmap is invalid now, so we don't want to undraw it */
  1057 				int h2;
  1061 				int h2;
  1058 
  1062 
  1059 				/* First try coalescing downwards */
  1063 				/* First try coalescing downwards */
  1060 				do {
  1064 				do {
  1061 					*p = 0;
  1065 					*p = 0;
  1062 					p += DIRTY_BYTES_PER_LINE;
  1066 					p += _dirty_bytes_per_line;
  1063 					bottom += DIRTY_BLOCK_HEIGHT;
  1067 					bottom += DIRTY_BLOCK_HEIGHT;
  1064 				} while (bottom != h && *p != 0);
  1068 				} while (bottom != h && *p != 0);
  1065 
  1069 
  1066 				/* Try coalescing to the right too. */
  1070 				/* Try coalescing to the right too. */
  1067 				h2 = (bottom - y) / DIRTY_BLOCK_HEIGHT;
  1071 				h2 = (bottom - y) / DIRTY_BLOCK_HEIGHT;
  1072 					byte *p2 = ++p;
  1076 					byte *p2 = ++p;
  1073 					int h = h2;
  1077 					int h = h2;
  1074 					/* Check if a full line of dirty flags is set. */
  1078 					/* Check if a full line of dirty flags is set. */
  1075 					do {
  1079 					do {
  1076 						if (!*p2) goto no_more_coalesc;
  1080 						if (!*p2) goto no_more_coalesc;
  1077 						p2 += DIRTY_BYTES_PER_LINE;
  1081 						p2 += _dirty_bytes_per_line;
  1078 					} while (--h != 0);
  1082 					} while (--h != 0);
  1079 
  1083 
  1080 					/* Wohoo, can combine it one step to the right!
  1084 					/* Wohoo, can combine it one step to the right!
  1081 					 * Do that, and clear the bits. */
  1085 					 * Do that, and clear the bits. */
  1082 					right += DIRTY_BLOCK_WIDTH;
  1086 					right += DIRTY_BLOCK_WIDTH;
  1083 
  1087 
  1084 					h = h2;
  1088 					h = h2;
  1085 					p2 = p;
  1089 					p2 = p;
  1086 					do {
  1090 					do {
  1087 						*p2 = 0;
  1091 						*p2 = 0;
  1088 						p2 += DIRTY_BYTES_PER_LINE;
  1092 						p2 += _dirty_bytes_per_line;
  1089 					} while (--h != 0);
  1093 					} while (--h != 0);
  1090 				}
  1094 				}
  1091 				no_more_coalesc:
  1095 				no_more_coalesc:
  1092 
  1096 
  1093 				left = x;
  1097 				left = x;
  1102 					RedrawScreenRect(left, top, right, bottom);
  1106 					RedrawScreenRect(left, top, right, bottom);
  1103 				}
  1107 				}
  1104 
  1108 
  1105 			}
  1109 			}
  1106 		} while (b++, (x += DIRTY_BLOCK_WIDTH) != w);
  1110 		} while (b++, (x += DIRTY_BLOCK_WIDTH) != w);
  1107 	} while (b += -(w / DIRTY_BLOCK_WIDTH) + DIRTY_BYTES_PER_LINE, (y += DIRTY_BLOCK_HEIGHT) != h);
  1111 	} while (b += -(w / DIRTY_BLOCK_WIDTH) + _dirty_bytes_per_line, (y += DIRTY_BLOCK_HEIGHT) != h);
  1108 
  1112 
  1109 	_invalid_rect.left = w;
  1113 	_invalid_rect.left = w;
  1110 	_invalid_rect.top = h;
  1114 	_invalid_rect.top = h;
  1111 	_invalid_rect.right = 0;
  1115 	_invalid_rect.right = 0;
  1112 	_invalid_rect.bottom = 0;
  1116 	_invalid_rect.bottom = 0;
  1152 	if (bottom > _invalid_rect.bottom) _invalid_rect.bottom = bottom;
  1156 	if (bottom > _invalid_rect.bottom) _invalid_rect.bottom = bottom;
  1153 
  1157 
  1154 	left /= DIRTY_BLOCK_WIDTH;
  1158 	left /= DIRTY_BLOCK_WIDTH;
  1155 	top  /= DIRTY_BLOCK_HEIGHT;
  1159 	top  /= DIRTY_BLOCK_HEIGHT;
  1156 
  1160 
  1157 	b = _dirty_blocks + top * DIRTY_BYTES_PER_LINE + left;
  1161 	b = _dirty_blocks + top * _dirty_bytes_per_line + left;
  1158 
  1162 
  1159 	width  = ((right  - 1) / DIRTY_BLOCK_WIDTH)  - left + 1;
  1163 	width  = ((right  - 1) / DIRTY_BLOCK_WIDTH)  - left + 1;
  1160 	height = ((bottom - 1) / DIRTY_BLOCK_HEIGHT) - top  + 1;
  1164 	height = ((bottom - 1) / DIRTY_BLOCK_HEIGHT) - top  + 1;
  1161 
  1165 
  1162 	assert(width > 0 && height > 0);
  1166 	assert(width > 0 && height > 0);
  1164 	do {
  1168 	do {
  1165 		int i = width;
  1169 		int i = width;
  1166 
  1170 
  1167 		do b[--i] = 0xFF; while (i);
  1171 		do b[--i] = 0xFF; while (i);
  1168 
  1172 
  1169 		b += DIRTY_BYTES_PER_LINE;
  1173 		b += _dirty_bytes_per_line;
  1170 	} while (--height != 0);
  1174 	} while (--height != 0);
  1171 }
  1175 }
  1172 
  1176 
  1173 /*!
  1177 /*!
  1174  * This function mark the whole screen as dirty. This results in repainting
  1178  * This function mark the whole screen as dirty. This results in repainting