1 | #include "globals.hpp" |
---|
2 | #include "system.h" |
---|
3 | #include "video.hpp" |
---|
4 | #include "dos.h" |
---|
5 | #include "xinclude.h" |
---|
6 | #include "macs.hpp" |
---|
7 | #include "bitmap.h" |
---|
8 | #include "image.hpp" |
---|
9 | |
---|
10 | //#define DIRECT_SCREEN |
---|
11 | |
---|
12 | |
---|
13 | #define CGAY(y) ((y%2)?(y/2)*80:0x2000+((y-1)/2)*80) |
---|
14 | |
---|
15 | unsigned char current_background; |
---|
16 | extern unsigned int xres,yres; |
---|
17 | int xoff,yoff,vmode; |
---|
18 | image *screen; |
---|
19 | |
---|
20 | int get_vmode() |
---|
21 | { return vmode; } |
---|
22 | |
---|
23 | |
---|
24 | void set_mode(int mode, int argc, char **argv) |
---|
25 | { |
---|
26 | unsigned char *page; |
---|
27 | |
---|
28 | vmode=mode; |
---|
29 | int i,fail; |
---|
30 | for (i=1,fail=0;i<argc && !fail;i++) |
---|
31 | if (!strcmp(argv[i],"-vmode")) |
---|
32 | { |
---|
33 | if (i==argc-1) fail=1; |
---|
34 | else |
---|
35 | { if (!strcmp(argv[i+1],"VGA_320x200x256")) |
---|
36 | mode=19; |
---|
37 | else if (!strcmp(argv[i+1],"TRI_640x480x256")) |
---|
38 | mode=TRI_640x480x256; |
---|
39 | else if (!strcmp(argv[i+1],"TRI_800x600x256")) |
---|
40 | mode=TRI_800x600x256; |
---|
41 | else if (!strcmp(argv[i+1],"TRI_1024x768x256")) |
---|
42 | mode=TRI_1024x768x256; |
---|
43 | else if (!strcmp(argv[i+1],"CGA_640x200x2")) |
---|
44 | mode=CGA_640x200x2; |
---|
45 | else fail=1; |
---|
46 | } |
---|
47 | } |
---|
48 | if (fail) |
---|
49 | { |
---|
50 | printf("Expected one of the folloing video modes after -vmode switch\n" |
---|
51 | " CGA_640x200x2 CGA 2 color graphics (dithered imaging)\n" |
---|
52 | " VGA_320x200x256 Standard vga 256 color mode\n" |
---|
53 | " TRI_640x480x256 Trident super vga\n" |
---|
54 | " TRI_800x640x256 Trident super vga\n" |
---|
55 | " TRI_1024x768x256 Trident super vga (1 meg video memory needed)\n" |
---|
56 | "example : %s -vmode VGA_320x200x256\n",argv[0]); |
---|
57 | exit(0); |
---|
58 | } |
---|
59 | vmode=mode; |
---|
60 | switch (mode) |
---|
61 | { |
---|
62 | case TRI_1024x768x256 : xres=1023; yres=767; break; |
---|
63 | case TRI_800x600x256 : xres=799; yres=599; break; |
---|
64 | case TRI_640x480x256 : xres=639; yres=479; break; |
---|
65 | case VGA_320x200x256 : xres=319; yres=199; break; |
---|
66 | case CGA_640x200x2 : xres=639; yres=199; break; |
---|
67 | } |
---|
68 | asm { |
---|
69 | mov ax, mode |
---|
70 | int 0x10 |
---|
71 | } |
---|
72 | page=NULL; |
---|
73 | #ifdef DIRECT_SCREEN |
---|
74 | if (mode==19) |
---|
75 | page=(unsigned char *)MK_FP(0xa000,0); |
---|
76 | #endif |
---|
77 | screen=new image(xres+1,yres+1,page,2); |
---|
78 | screen->clear(); |
---|
79 | update_dirty(screen); |
---|
80 | } |
---|
81 | |
---|
82 | void close_graphics() |
---|
83 | { |
---|
84 | asm { |
---|
85 | mov ax, 3 |
---|
86 | int 0x10 |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | |
---|
91 | void put_image(image *im, int x, int y) |
---|
92 | { |
---|
93 | int ls,iy,i,w; |
---|
94 | unsigned int sp; |
---|
95 | long off; |
---|
96 | char *sl; |
---|
97 | ls=-1; |
---|
98 | iy=0; |
---|
99 | w=im->width(); |
---|
100 | while (iy<im->height()) |
---|
101 | { |
---|
102 | sl=im->scan_line(iy++); |
---|
103 | if (vmode==CGA_640x200x2) |
---|
104 | { |
---|
105 | int byte_off,bit_off; |
---|
106 | char compsl[80]; |
---|
107 | byte_off=0; |
---|
108 | |
---|
109 | compsl[0]=peekb(0xb800,CGAY(y)+x/8); |
---|
110 | compsl[(w-2)/8]=peekb(0xb800,CGAY(y)+(x+w-2)/8); |
---|
111 | bit_off=128>>(x%8); |
---|
112 | for (i=0;i<w;i++) |
---|
113 | { |
---|
114 | if (!sl[i]) |
---|
115 | compsl[byte_off]&=(0xff^bit_off); |
---|
116 | else compsl[byte_off]|=bit_off; |
---|
117 | bit_off>>=1; |
---|
118 | if (!bit_off) |
---|
119 | { byte_off++; bit_off=128; } |
---|
120 | |
---|
121 | } |
---|
122 | memcpy(MK_FP(0xb800,CGAY(y)+x/8),compsl,(w+7)/8); |
---|
123 | } |
---|
124 | else |
---|
125 | { |
---|
126 | sp=(long)(((long) y*(long)(xres+1)+(long)x)>>16); |
---|
127 | if (sp!=ls) |
---|
128 | { |
---|
129 | outportb(0x3c4,14); |
---|
130 | outportb(0x3c5,(sp)^2); |
---|
131 | ls=sp; |
---|
132 | } |
---|
133 | off=(((long)y*(long)(xres+1)+(long)x)&(long)0xffff); |
---|
134 | |
---|
135 | |
---|
136 | |
---|
137 | for (i=0;i<w;i++) |
---|
138 | { |
---|
139 | pokeb(0xa000,off&0xffff,sl[i]); |
---|
140 | if (off>=0xffff) |
---|
141 | { off=0; |
---|
142 | sp++; |
---|
143 | outportb(0x3c4,14); |
---|
144 | outportb(0x3c5,(sp)^2); |
---|
145 | } |
---|
146 | else |
---|
147 | off++; |
---|
148 | } |
---|
149 | } |
---|
150 | y++; |
---|
151 | } |
---|
152 | } |
---|
153 | |
---|
154 | void update_dirty(image *im, int xoff, int yoff) |
---|
155 | { |
---|
156 | |
---|
157 | int count,x1,y1,x2,y2; |
---|
158 | dirty_rect *dr,*q; |
---|
159 | image *Xim; |
---|
160 | #ifdef DIRECT_SCREEN |
---|
161 | if (im!=screen || vmode!=19) |
---|
162 | { |
---|
163 | #endif |
---|
164 | CHECK(im->special); // make sure the image has the ablity to contain dirty areas |
---|
165 | if (im->special->keep_dirt==0) |
---|
166 | put_image(im,xoff,yoff); |
---|
167 | else |
---|
168 | { |
---|
169 | count=im->special->dirties.number_nodes(); |
---|
170 | if (!count) return; // if nothing to update, return |
---|
171 | (linked_node *) dr=im->special->dirties.first(); |
---|
172 | while (count>0) |
---|
173 | { |
---|
174 | x1=dr->dx1; // update this area for this dirty rectangle |
---|
175 | y1=dr->dy1; |
---|
176 | x2=dr->dx2; |
---|
177 | y2=dr->dy2; |
---|
178 | |
---|
179 | int dt_matrix[]={0, 136,24, 170, |
---|
180 | 68, 204,102,238, |
---|
181 | 51, 187, 17,153, |
---|
182 | 119,255, 85,221}; |
---|
183 | |
---|
184 | |
---|
185 | int ls,iy,i; |
---|
186 | unsigned int sp; |
---|
187 | long off; |
---|
188 | char *sl; |
---|
189 | ls=-1; |
---|
190 | iy=y1; |
---|
191 | while (iy<=y2) |
---|
192 | { |
---|
193 | sl=im->scan_line(iy); |
---|
194 | if (vmode!=19 && vmode!=CGA_640x200x2) |
---|
195 | { |
---|
196 | sp=(long)(((long) (iy+yoff)*(long)(xres+1)+(long)x1+xoff)>>16); |
---|
197 | if (sp!=ls) |
---|
198 | { |
---|
199 | outportb(0x3c4,14); |
---|
200 | outportb(0x3c5,(sp)^2); |
---|
201 | ls=sp; |
---|
202 | } |
---|
203 | off=(((long)(iy+yoff)*(long)(xres+1)+(long)x1+xoff)&(long)0xffff); |
---|
204 | for (i=x1;i<=x2;i++) |
---|
205 | { |
---|
206 | pokeb(0xa000,off&0xffff,sl[i]); |
---|
207 | if (off>=0xffff) |
---|
208 | { off=0; |
---|
209 | sp++; |
---|
210 | outportb(0x3c4,14); |
---|
211 | outportb(0x3c5,(sp)^2); |
---|
212 | } |
---|
213 | else |
---|
214 | off++; |
---|
215 | } |
---|
216 | } |
---|
217 | else if (vmode!=CGA_640x200x2) |
---|
218 | memcpy(MK_FP(0xa000,(iy+yoff)*320+x1),&sl[x1+xoff],(x2-x1+1)); |
---|
219 | else |
---|
220 | { |
---|
221 | int byte_off,bit_off,w; |
---|
222 | char compsl[80]; |
---|
223 | byte_off=0; |
---|
224 | memcpy(compsl,MK_FP(0xb800,CGAY((iy+yoff))+(x1+xoff)/8),(x2+xoff)/8-(x1+xoff)/8+1); |
---|
225 | bit_off=128>>((x1+xoff)%8); |
---|
226 | for (i=(x1+xoff);i<=(x2+xoff);i++) |
---|
227 | { |
---|
228 | if (last_loaded()->red(sl[i])>dt_matrix[i%4+((iy+yoff)%4)*4]) |
---|
229 | compsl[byte_off]&=(0xff^bit_off); |
---|
230 | else |
---|
231 | compsl[byte_off]|=bit_off; |
---|
232 | bit_off>>=1; |
---|
233 | if (!bit_off) |
---|
234 | { byte_off++; |
---|
235 | bit_off=128; |
---|
236 | } |
---|
237 | |
---|
238 | } |
---|
239 | memcpy(MK_FP(0xb800,CGAY((iy+yoff))+(x1+xoff)/8),compsl,(xoff+x2)/8-(x1+xoff)/8+1); |
---|
240 | } |
---|
241 | iy++; |
---|
242 | |
---|
243 | } |
---|
244 | q=dr; |
---|
245 | (linked_node *)dr=dr->next(); |
---|
246 | im->special->dirties.unlink((linked_node *)q); |
---|
247 | delete q; |
---|
248 | count--; |
---|
249 | } |
---|
250 | } |
---|
251 | #ifdef DIRECT_SCREEN |
---|
252 | } |
---|
253 | #endif |
---|
254 | } |
---|
255 | |
---|
256 | extern palette *lastl; |
---|
257 | |
---|
258 | void palette::load() |
---|
259 | { |
---|
260 | if (lastl) |
---|
261 | delete lastl; |
---|
262 | lastl=copy(); |
---|
263 | unsigned s,o; |
---|
264 | if (get_vmode()!=CGA_640x200x2) |
---|
265 | { |
---|
266 | s=FP_SEG(pal); o=FP_OFF(pal); |
---|
267 | asm { |
---|
268 | mov ax, o |
---|
269 | mov si, ax |
---|
270 | push ds |
---|
271 | mov ax, s |
---|
272 | mov ds, ax |
---|
273 | mov cx, 128 |
---|
274 | mov dx, 986 |
---|
275 | } |
---|
276 | retrace_start : |
---|
277 | asm { |
---|
278 | in al,dx |
---|
279 | test al, 8 |
---|
280 | jnz retrace_start |
---|
281 | } |
---|
282 | vert_retrace : |
---|
283 | asm { |
---|
284 | in al, dx |
---|
285 | test al,8 |
---|
286 | jz vert_retrace |
---|
287 | xor al,al |
---|
288 | mov dx, 968 |
---|
289 | out dx, al |
---|
290 | mov dx, 969 |
---|
291 | cld |
---|
292 | } |
---|
293 | load_again : |
---|
294 | asm { |
---|
295 | lodsb |
---|
296 | shr al,1 |
---|
297 | shr al,1 |
---|
298 | out dx,al // ; {three bytes per color} |
---|
299 | jmp jadr1 |
---|
300 | } |
---|
301 | jadr1 : |
---|
302 | asm { |
---|
303 | lodsb |
---|
304 | shr al,1 |
---|
305 | shr al,1 |
---|
306 | out dx,al |
---|
307 | jmp jadr2 : |
---|
308 | } |
---|
309 | jadr2 : |
---|
310 | asm { |
---|
311 | lodsb |
---|
312 | shr al,1 |
---|
313 | shr al,1 |
---|
314 | out dx,al |
---|
315 | jmp jadr3 |
---|
316 | } |
---|
317 | jadr3 : |
---|
318 | asm { |
---|
319 | loop load_again |
---|
320 | mov dx, 986 |
---|
321 | } |
---|
322 | retrace_start2 : |
---|
323 | asm { |
---|
324 | in al,dx |
---|
325 | test al, 8 |
---|
326 | jnz retrace_start2 |
---|
327 | } |
---|
328 | vert_retrace2 : |
---|
329 | asm { |
---|
330 | in al, dx |
---|
331 | test al,8 |
---|
332 | jz vert_retrace2 |
---|
333 | xor al,al |
---|
334 | mov dx, 968 |
---|
335 | out dx, al |
---|
336 | mov dx, 969 |
---|
337 | mov cx,128 |
---|
338 | mov al, 128 |
---|
339 | mov dx, 968 |
---|
340 | out dx, al |
---|
341 | mov dx, 969 |
---|
342 | } |
---|
343 | load_again2 : |
---|
344 | asm { |
---|
345 | lodsb |
---|
346 | shr al,1 |
---|
347 | shr al,1 |
---|
348 | out dx,al |
---|
349 | lodsb |
---|
350 | shr al,1 |
---|
351 | shr al,1 |
---|
352 | out dx,al |
---|
353 | lodsb |
---|
354 | shr al,1 |
---|
355 | shr al,1 |
---|
356 | out dx,al |
---|
357 | loop load_again2 |
---|
358 | pop ds |
---|
359 | } |
---|
360 | } |
---|
361 | else lastl->black_white(); |
---|
362 | current_background=bg; |
---|
363 | } |
---|
364 | |
---|
365 | void palette::load_nice() |
---|
366 | { load(); } |
---|
367 | |
---|