48 |
48 |
49 static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode); |
49 static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode); |
50 |
50 |
51 FontSize _cur_fontsize; |
51 FontSize _cur_fontsize; |
52 static FontSize _last_fontsize; |
52 static FontSize _last_fontsize; |
53 static Pixel _cursor_backup[64 * 64]; |
53 static uint8 _cursor_backup[64 * 64 * 4]; |
54 static Rect _invalid_rect; |
54 static Rect _invalid_rect; |
55 static const byte *_color_remap_ptr; |
55 static const byte *_color_remap_ptr; |
56 static byte _string_colorremap[3]; |
56 static byte _string_colorremap[3]; |
57 |
57 |
58 #define DIRTY_BYTES_PER_LINE (MAX_SCREEN_WIDTH / 64) |
58 #define DIRTY_BYTES_PER_LINE (MAX_SCREEN_WIDTH / 64) |
59 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8]; |
59 static byte _dirty_blocks[DIRTY_BYTES_PER_LINE * MAX_SCREEN_HEIGHT / 8]; |
60 |
60 |
61 void memcpy_pitch(void *dst, void *src, int w, int h, int srcpitch, int dstpitch) |
|
62 { |
|
63 Pixel *dstp = (Pixel *)dst; |
|
64 Pixel *srcp = (Pixel *)src; |
|
65 |
|
66 assert(h >= 0); |
|
67 for (; h != 0; --h) { |
|
68 memcpy(dstp, srcp, w * sizeof(Pixel)); |
|
69 dstp += dstpitch; |
|
70 srcp += srcpitch; |
|
71 } |
|
72 } |
|
73 |
|
74 void GfxScroll(int left, int top, int width, int height, int xo, int yo) |
61 void GfxScroll(int left, int top, int width, int height, int xo, int yo) |
75 { |
62 { |
76 const Pixel *src; |
63 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
77 Pixel *dst; |
64 const void *src; |
78 int p; |
65 void *dst; |
79 int ht; |
|
80 |
66 |
81 if (xo == 0 && yo == 0) return; |
67 if (xo == 0 && yo == 0) return; |
82 |
68 |
83 if (_cursor.visible) UndrawMouseCursor(); |
69 if (_cursor.visible) UndrawMouseCursor(); |
84 UndrawTextMessage(); |
70 UndrawTextMessage(); |
85 |
71 |
86 p = _screen.pitch; |
|
87 |
|
88 if (yo > 0) { |
72 if (yo > 0) { |
89 /*Calculate pointers */ |
73 /*Calculate pointers */ |
90 dst = _screen.dst_ptr + (top + height - 1) * p + left; |
74 dst = blitter->MoveTo(_screen.dst_ptr, left, top + height - 1); |
91 src = dst - yo * p; |
75 src = blitter->MoveTo(dst, 0, -yo); |
92 |
76 |
93 /* Decrease height and increase top */ |
77 /* Decrease height and increase top */ |
94 top += yo; |
78 top += yo; |
95 height -= yo; |
79 height -= yo; |
96 assert(height > 0); |
80 assert(height > 0); |
97 |
81 |
98 /* Adjust left & width */ |
82 /* Adjust left & width */ |
99 if (xo >= 0) { |
83 if (xo >= 0) { |
100 dst += xo; |
84 dst = blitter->MoveTo(dst, xo, 0); |
101 left += xo; |
85 left += xo; |
102 width -= xo; |
86 width -= xo; |
103 } else { |
87 } else { |
104 src -= xo; |
88 src = blitter->MoveTo(src, -xo, 0); |
105 width += xo; |
89 width += xo; |
106 } |
90 } |
107 |
91 |
108 for (ht = height; ht > 0; --ht) { |
92 /* Negative height as we want to copy from bottom to top */ |
109 memcpy(dst, src, width * sizeof(Pixel)); |
93 blitter->CopyFromBuffer(dst, src, width, -height, _screen.pitch); |
110 src -= p; |
|
111 dst -= p; |
|
112 } |
|
113 } else { |
94 } else { |
114 /* Calculate pointers */ |
95 /* Calculate pointers */ |
115 dst = _screen.dst_ptr + top * p + left; |
96 dst = blitter->MoveTo(_screen.dst_ptr, left, top); |
116 src = dst - yo * p; |
97 src = blitter->MoveTo(dst, 0, -yo); |
117 |
98 |
118 /* Decrese height. (yo is <=0). */ |
99 /* Decrese height. (yo is <=0). */ |
119 height += yo; |
100 height += yo; |
120 assert(height > 0); |
101 assert(height > 0); |
121 |
102 |
122 /* Adjust left & width */ |
103 /* Adjust left & width */ |
123 if (xo >= 0) { |
104 if (xo >= 0) { |
124 dst += xo; |
105 dst = blitter->MoveTo(dst, xo, 0); |
125 left += xo; |
106 left += xo; |
126 width -= xo; |
107 width -= xo; |
127 } else { |
108 } else { |
128 src -= xo; |
109 src = blitter->MoveTo(src, -xo, 0); |
129 width += xo; |
110 width += xo; |
130 } |
111 } |
131 |
112 |
132 /* the y-displacement may be 0 therefore we have to use memmove, |
113 /* the y-displacement may be 0 therefore we have to use memmove, |
133 * because source and destination may overlap */ |
114 * because source and destination may overlap */ |
134 for (ht = height; ht > 0; --ht) { |
115 blitter->MoveBuffer(dst, src, width, height); |
135 memmove(dst, src, width * sizeof(Pixel)); |
|
136 src += p; |
|
137 dst += p; |
|
138 } |
|
139 } |
116 } |
140 /* This part of the screen is now dirty. */ |
117 /* This part of the screen is now dirty. */ |
141 _video_driver->make_dirty(left, top, width, height); |
118 _video_driver->make_dirty(left, top, width, height); |
142 } |
119 } |
143 |
120 |
144 |
121 |
145 void GfxFillRect(int left, int top, int right, int bottom, int color) |
122 void GfxFillRect(int left, int top, int right, int bottom, int color) |
146 { |
123 { |
147 const DrawPixelInfo* dpi = _cur_dpi; |
124 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
148 Pixel *dst; |
125 const DrawPixelInfo *dpi = _cur_dpi; |
|
126 void *dst; |
149 const int otop = top; |
127 const int otop = top; |
150 const int oleft = left; |
128 const int oleft = left; |
151 |
129 |
152 if (dpi->zoom != ZOOM_LVL_NORMAL) return; |
130 if (dpi->zoom != ZOOM_LVL_NORMAL) return; |
153 if (left > right || top > bottom) return; |
131 if (left > right || top > bottom) return; |
164 bottom = bottom - dpi->top + 1; |
142 bottom = bottom - dpi->top + 1; |
165 if (bottom > dpi->height) bottom = dpi->height; |
143 if (bottom > dpi->height) bottom = dpi->height; |
166 bottom -= top; |
144 bottom -= top; |
167 assert(bottom > 0); |
145 assert(bottom > 0); |
168 |
146 |
169 dst = dpi->dst_ptr + top * dpi->pitch + left; |
147 dst = blitter->MoveTo(dpi->dst_ptr, left, top); |
170 |
148 |
171 if (!HASBIT(color, PALETTE_MODIFIER_GREYOUT)) { |
149 if (!HASBIT(color, PALETTE_MODIFIER_GREYOUT)) { |
172 if (!HASBIT(color, USE_COLORTABLE)) { |
150 if (!HASBIT(color, USE_COLORTABLE)) { |
173 do { |
151 do { |
174 memset(dst, color, right * sizeof(Pixel)); |
152 blitter->SetHorizontalLine(dst, right, (uint8)color); |
175 dst += dpi->pitch; |
153 dst = blitter->MoveTo(dst, 0, 1); |
176 } while (--bottom); |
154 } while (--bottom); |
177 } else { |
155 } else { |
178 /* use colortable mode */ |
156 blitter->DrawColorMappingRect(dst, right, bottom, GB(color, 0, PALETTE_WIDTH)); |
179 const byte* ctab = GetNonSprite(GB(color, 0, PALETTE_WIDTH)) + 1; |
|
180 |
|
181 do { |
|
182 int i; |
|
183 for (i = 0; i != right; i++) dst[i] = ctab[dst[i]]; |
|
184 dst += dpi->pitch; |
|
185 } while (--bottom); |
|
186 } |
157 } |
187 } else { |
158 } else { |
188 byte bo = (oleft - left + dpi->left + otop - top + dpi->top) & 1; |
159 byte bo = (oleft - left + dpi->left + otop - top + dpi->top) & 1; |
189 do { |
160 do { |
190 int i; |
161 for (int i = (bo ^= 1); i < right; i += 2) blitter->SetPixel(dst, i, 0, (uint8)color); |
191 for (i = (bo ^= 1); i < right; i += 2) dst[i] = (byte)color; |
162 dst = blitter->MoveTo(dst, 0, 1); |
192 dst += dpi->pitch; |
|
193 } while (--bottom > 0); |
163 } while (--bottom > 0); |
194 } |
164 } |
195 } |
165 } |
196 |
166 |
197 static void GfxSetPixel(int x, int y, int color) |
167 static void GfxSetPixel(int x, int y, int color) |
198 { |
168 { |
199 const DrawPixelInfo* dpi = _cur_dpi; |
169 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
200 if ((x -= dpi->left) < 0 || x >= dpi->width || (y -= dpi->top)<0 || y >= dpi->height) |
170 const DrawPixelInfo *dpi = _cur_dpi; |
201 return; |
171 |
202 dpi->dst_ptr[y * dpi->pitch + x] = color; |
172 if ((x -= dpi->left) < 0 || x >= dpi->width || (y -= dpi->top) < 0 || y >= dpi->height) return; |
|
173 blitter->SetPixel(dpi->dst_ptr, x, y, color); |
203 } |
174 } |
204 |
175 |
205 void GfxDrawLine(int x, int y, int x2, int y2, int color) |
176 void GfxDrawLine(int x, int y, int x2, int y2, int color) |
206 { |
177 { |
207 int dy; |
178 int dy; |
956 } |
936 } |
957 |
937 |
958 void UndrawMouseCursor() |
938 void UndrawMouseCursor() |
959 { |
939 { |
960 if (_cursor.visible) { |
940 if (_cursor.visible) { |
|
941 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
961 _cursor.visible = false; |
942 _cursor.visible = false; |
962 memcpy_pitch( |
943 blitter->CopyFromBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x); |
963 _screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch, |
|
964 _cursor_backup, |
|
965 _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x, _screen.pitch); |
|
966 |
|
967 _video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y); |
944 _video_driver->make_dirty(_cursor.draw_pos.x, _cursor.draw_pos.y, _cursor.draw_size.x, _cursor.draw_size.y); |
968 } |
945 } |
969 } |
946 } |
970 |
947 |
971 void DrawMouseCursor() |
948 void DrawMouseCursor() |
972 { |
949 { |
|
950 Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter(); |
973 int x; |
951 int x; |
974 int y; |
952 int y; |
975 int w; |
953 int w; |
976 int h; |
954 int h; |
977 |
955 |
1004 if (h > _screen.height - y) h = _screen.height - y; |
982 if (h > _screen.height - y) h = _screen.height - y; |
1005 if (h <= 0) return; |
983 if (h <= 0) return; |
1006 _cursor.draw_pos.y = y; |
984 _cursor.draw_pos.y = y; |
1007 _cursor.draw_size.y = h; |
985 _cursor.draw_size.y = h; |
1008 |
986 |
1009 assert(w * h < (int)sizeof(_cursor_backup)); |
987 assert(blitter->BufferSize(w, h) < (int)sizeof(_cursor_backup)); |
1010 |
988 |
1011 /* Make backup of stuff below cursor */ |
989 /* Make backup of stuff below cursor */ |
1012 memcpy_pitch( |
990 blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, _cursor.draw_pos.x, _cursor.draw_pos.y), _cursor_backup, _cursor.draw_size.x, _cursor.draw_size.y, _cursor.draw_size.x); |
1013 _cursor_backup, |
|
1014 _screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch, |
|
1015 _cursor.draw_size.x, _cursor.draw_size.y, _screen.pitch, _cursor.draw_size.x); |
|
1016 |
991 |
1017 /* Draw cursor on screen */ |
992 /* Draw cursor on screen */ |
1018 _cur_dpi = &_screen; |
993 _cur_dpi = &_screen; |
1019 DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x, _cursor.pos.y); |
994 DrawSprite(_cursor.sprite, _cursor.pal, _cursor.pos.x, _cursor.pos.y); |
1020 |
995 |