OSDN Git Service

wwww
[proj16/16.git] / 16 / v2 / source / verge / ENGINE / MODEX.C
1 /*\r
2 Copyright (C) 1998 BJ Eirich (aka vecna)\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7 This program is distributed in the hope that it will be useful,\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
10 See the GNU General Public Lic\r
11 See the GNU General Public License for more details.\r
12 You should have received a copy of the GNU General Public License\r
13 along with this program; if not, write to the Free Software\r
14 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
15 */\r
16 \r
17 \r
18 #include <dpmi.h>\r
19 #include <sys\nearptr.h>\r
20 #include "verge.h"\r
21 \r
22 // ================================= Data ====================================\r
23 \r
24 #define SEQU_ADDR               0x3c4\r
25 #define CRTC_ADDR               0x3d4\r
26 #define MISC_OUTPUT             0x3c2\r
27 \r
28 byte *screenbase;                   // ptr to A000:0000\r
29 int endcol,nextl;                   // end column number thingy | next line\r
30 int winofs;\r
31 \r
32 // ================================= Code ====================================\r
33 \r
34 void ModeXSetMode(int mode)\r
35 {\r
36   REGISTERS r;\r
37   SET_AX(r, mode);\r
38   INTERRUPT(0x10, r);\r
39 }\r
40 \r
41 void plane(byte p)\r
42 {\r
43   int hi=1<<p;\r
44   outpw(0x03c4, (hi<<8)|0x02);\r
45 }\r
46 \r
47 int ModeXShutdown()\r
48 {\r
49   ModeXSetMode(0x3);\r
50   vfree(screen);\r
51   return 0;\r
52 }\r
53 \r
54 void clearScreen()\r
55 {\r
56    // set write to ALL PLANES simultaneously for extra-quick clears.\r
57    asm("movw $0x3c4, %%dx              \n\t"\r
58        "movw $0x0f02, %%ax             \n\t"\r
59        "outw %%ax, %%dx                \n\t"\r
60        "movl _screenbase, %%edi        \n\t"\r
61        "movl $0, %%eax                 \n\t"\r
62        "movl $11264, %%ecx             \n\t"\r
63        "rep                            \n\t"\r
64        "stosl                          \n\t"\r
65        :\r
66        :\r
67        : "eax","edx","edi","ecx","cc" );\r
68 }\r
69 \r
70 void SetView(word offset)\r
71 {\r
72   while (inportb(0x3da) & 1);\r
73 \r
74   _disable();\r
75 \r
76   outportb(0x3d4, (offset >> 8) | 0x0c);\r
77   outportb(0x3d4, (offset & 0xff) | 0x0d);\r
78 \r
79   _enable();\r
80 }\r
81 \r
82 int ModeXShowPage()\r
83 {\r
84   byte *s,*d;\r
85   int x,y,k;\r
86   int sx2;\r
87   int b;\r
88 \r
89   RenderGUI();\r
90   cpubyte=PFLIP;\r
91 \r
92   //s=screen+(16*tsx)+16;\r
93   b=(16*tsx)+16;\r
94   d=screenbase;\r
95   sx2=sx>>2;\r
96 \r
97   //while (!(inp(986) & 8));\r
98 \r
99   for (y=0; y<sy; ++y,d+=sx2)\r
100   {\r
101     s=screen+(y*tsx)+b;\r
102     for (k=0; k<4; k++,s-=sx)\r
103     {\r
104       plane(k);\r
105       for (x=0; x<sx2; x++,s+=4)\r
106         d[x]=s[k];\r
107     }\r
108   }\r
109 \r
110   cpubyte=ETC;\r
111   return 0;\r
112 }\r
113 \r
114 int ModeXCopySprite(int x, int y, int width, int height, byte *src)\r
115 {\r
116   cpubyte=RENDER;\r
117 \r
118   asm("movl %3, %%edx                   \n\t"\r
119       "movl %4, %%esi                   \n\t"\r
120 "csl0:                                  \n\t"\r
121       "movl %1, %%eax                   \n\t"\r
122       "imul _tsx, %%eax                 \n\t"\r
123       "addl %0, %%eax                   \n\t"\r
124       "addl _screen, %%eax              \n\t"\r
125       "movl %%eax, %%edi                \n\t"\r
126       "movl %2, %%ecx                   \n\t"\r
127       "shrl $2, %%ecx                   \n\t"\r
128       "repz                             \n\t"\r
129       "movsl                            \n\t"\r
130       "incl %1                          \n\t"\r
131       "decl %%edx                       \n\t"\r
132       "jnz csl0                         \n\t"\r
133       :\r
134       : "m" (x), "m" (y), "m" (width), "m" (height), "m" (src)\r
135       : "eax","edx","esi","edi","ecx","cc" );\r
136   cpubyte=ETC;\r
137   return 0;\r
138 }\r
139 \r
140 int ModeXTCopySprite(int x, int y, int width, int height, byte *src)\r
141 {\r
142   cpubyte=RENDER;\r
143 \r
144   asm("movl %3, %%ecx                   \n\t"\r
145       "movl %4, %%esi                   \n\t"\r
146 "tcsl0:                                 \n\t"\r
147       "movl %1, %%eax                   \n\t"\r
148       "imul _tsx, %%eax                 \n\t"\r
149       "addl %0, %%eax                   \n\t"\r
150       "addl _screen, %%eax              \n\t"\r
151       "movl %%eax, %%edi                \n\t"\r
152       "movl %2, %%edx                   \n\t"\r
153 "drawloop:                              \n\t"\r
154       "lodsb                            \n\t"\r
155       "orb %%al, %%al                   \n\t"\r
156       "jz nodraw                        \n\t"\r
157       "stosb                            \n\t"\r
158       "decl %%edx                       \n\t"\r
159       "jz endline                       \n\t"\r
160       "jmp drawloop                     \n\t"\r
161 "nodraw:                                \n\t"\r
162       "incl %%edi                       \n\t"\r
163       "decl %%edx                       \n\t"\r
164       "jnz drawloop                     \n\t"\r
165 "endline:                               \n\t"\r
166       "incl %1                          \n\t"\r
167       "decl %%ecx                       \n\t"\r
168       "jnz tcsl0                        \n\t"\r
169       :\r
170       : "m" (x), "m" (y), "m" (width), "m" (height), "m" (src)\r
171       : "eax","edx","esi","edi","ecx","cc" );\r
172 \r
173   cpubyte=ETC;\r
174   return 0;\r
175 }\r
176 \r
177 int ModeXCopyTile(int x, int y, byte *spr)\r
178 {\r
179   cpubyte=RENDER;\r
180 \r
181   asm("movl $16, %%ecx                  \n\t"\r
182       "movl %2, %%esi                   \n\t"\r
183       "movl %1, %%edi                   \n\t"\r
184       "imul _tsx, %%edi                 \n\t"\r
185       "addl %0, %%edi                   \n\t"\r
186       "addl _screen, %%edi              \n\t"\r
187 " ctl0:                                 \n\t"\r
188       "movl (%%edi), %%eax              \n\t"\r
189       "andl $0, %%eax                   \n\t"\r
190       "orl  (%%esi), %%eax              \n\t"\r
191       "movl %%eax, (%%edi)              \n\t"\r
192       "movl 4(%%edi), %%eax             \n\t"\r
193       "andl $0, %%eax                   \n\t"\r
194       "orl  4(%%esi), %%eax             \n\t"\r
195       "movl %%eax, 4(%%edi)             \n\t"\r
196       "movl 8(%%edi), %%eax             \n\t"\r
197       "andl $0, %%eax                   \n\t"\r
198       "orl  8(%%esi), %%eax             \n\t"\r
199       "movl %%eax, 8(%%edi)             \n\t"\r
200       "movl 12(%%edi), %%eax            \n\t"\r
201       "andl $0, %%eax                   \n\t"\r
202       "orl  12(%%esi), %%eax            \n\t"\r
203       "movl %%eax, 12(%%edi)            \n\t"\r
204       "addl $16, %%esi                  \n\t"\r
205       "addl _tsx, %%edi                 \n\t"\r
206       "decl %%ecx                       \n\t"\r
207       "jnz ctl0                         \n\t"\r
208       :\r
209       : "m" (x), "m" (y), "m" (spr)\r
210       : "eax","ecx","esi","edi","cc" );\r
211   cpubyte=ETC;\r
212   return 0;\r
213 }\r
214 \r
215 int ModeXTCopyTile(int x, int y, byte *spr, byte *matte)\r
216 {\r
217   cpubyte=RENDER;\r
218   asm("movl $16, %%ecx                  \n\t"\r
219       "movl %2, %%esi                   \n\t"\r
220       "movl %1, %%edi                   \n\t"\r
221       "imul _tsx, %%edi                 \n\t"\r
222       "addl %0, %%edi                   \n\t"\r
223       "addl _screen, %%edi              \n\t"\r
224       "movl %3, %%edx                   \n\t"\r
225 "tctl0:                                 \n\t"\r
226       "movl (%%edi), %%eax              \n\t"\r
227       "andl (%%edx), %%eax              \n\t"\r
228       "orl  (%%esi), %%eax              \n\t"\r
229       "movl %%eax, (%%edi)              \n\t"\r
230       "movl 4(%%edi), %%eax             \n\t"\r
231       "andl 4(%%edx), %%eax             \n\t"\r
232       "orl  4(%%esi), %%eax             \n\t"\r
233       "movl %%eax, 4(%%edi)             \n\t"\r
234       "movl 8(%%edi), %%eax             \n\t"\r
235       "andl 8(%%edx), %%eax             \n\t"\r
236       "orl  8(%%esi), %%eax             \n\t"\r
237       "movl %%eax, 8(%%edi)             \n\t"\r
238       "movl 12(%%edi), %%eax            \n\t"\r
239       "andl 12(%%edx), %%eax            \n\t"\r
240       "orl  12(%%esi), %%eax            \n\t"\r
241       "movl %%eax, 12(%%edi)            \n\t"\r
242       "addl $16, %%esi                  \n\t"\r
243       "addl _tsx, %%edi                 \n\t"\r
244       "addl $16, %%edx                  \n\t"\r
245       "decl %%ecx                       \n\t"\r
246       "jnz tctl0                        \n\t"\r
247       :\r
248       : "m" (x), "m" (y), "m" (spr), "m" (matte)\r
249       : "eax","ecx","edx","esi","edi","cc" );\r
250 \r
251   cpubyte=ETC;\r
252   return 0;\r
253 }\r
254 \r
255 int ModeXCCopySprite(int x,int y,int width,int height,byte *src)\r
256 {\r
257   byte *s,*d;\r
258   int xl,yl,xs,ys;\r
259   int cx1=0, cy1=0, cx2=tsx-1, cy2=tsy-1;\r
260 \r
261   cpubyte=RENDER;\r
262 \r
263   xl=width;\r
264   yl=height;\r
265   xs=ys=0;\r
266 \r
267   if (x>cx2 || y>cy2 || x+xl<cx1 || y+yl<cy1)\r
268     return 0;\r
269 \r
270   if (x+xl > cx2) xl=cx2-x+1;\r
271   if (y+yl > cy2) yl=cy2-y+1;\r
272 \r
273   if (x<cx1) { xs=cx1-x; xl-=xs; x=cx1; }\r
274   if (y<cy1) { ys=cy1-y; yl-=ys; y=cy1; }\r
275 \r
276   s=src;\r
277   if (xs+ys) s+=(ys*width)+xs;\r
278   d=screen+(y*tsx)+x;\r
279 \r
280   for (; yl; yl--)\r
281   {\r
282     memcpy(d,s,xl);\r
283     s+=width;\r
284     d+=tsx;\r
285   }\r
286 \r
287   cpubyte=ETC;\r
288   return 0;\r
289 }\r
290 \r
291 int ModeXTCCopySprite(int x,int y,int width,int height,byte *src)\r
292 {\r
293   byte *s,*d,c;\r
294   int xl,yl,xs,ys;\r
295   int cx1=0, cy1=0, cx2=tsx-1, cy2=tsy-1;\r
296 \r
297   cpubyte=RENDER;\r
298 \r
299   xl=width;\r
300   yl=height;\r
301   xs=ys=0;\r
302 \r
303   if (x>cx2 || y>cy2 || x+xl<cx1 || y+yl<cy1)\r
304     return 0;\r
305 \r
306   if (x+xl > cx2) xl=cx2-x+1;\r
307   if (y+yl > cy2) yl=cy2-y+1;\r
308 \r
309   if (x<cx1) { xs=cx1-x; xl-=xs; x=cx1; }\r
310   if (y<cy1) { ys=cy1-y; yl-=ys; y=cy1; }\r
311 \r
312   s=src;\r
313   if (xs+ys) s+=(ys*width)+xs;\r
314   d=screen+(y*tsx)+x;\r
315 \r
316   for (; yl; yl--)\r
317   {\r
318     for (x=0; x<xl; x++)\r
319     {\r
320       c=s[x];\r
321       if (c)\r
322         d[x]=c;\r
323     }\r
324     s+=width;\r
325     d+=tsx;\r
326   }\r
327 \r
328   cpubyte=ETC;\r
329   return 0;\r
330 }\r
331 \r
332 int ModeXScaleSprite(int x, int y, int w, int h, int tw, int th, byte *s)\r
333 { int i,j,xm,ym,xd,yd,sx,sy=0,xs,ys,dys=0;\r
334   unsigned char *d;\r
335 \r
336   cpubyte=RENDER;\r
337 \r
338   if (!tw || !th) return 0;\r
339   tw += sgn(tw); th += sgn(th);\r
340   xm = abs(tw); ym = abs(th);\r
341   xs = (w<<16)/xm; ys = (h<<16)/ym;\r
342   xd = sgn(tw); yd = sgn(th);\r
343 \r
344   if (tw>0 && th>0) dys=tsx-xm;\r
345   else if (tw>0 && th<0) dys=(0-tsx)-xm;\r
346   else if (tw<0 && th>0) dys=tsx+xm;\r
347   else if (tw<0 && th<0) dys=(0-tsx)+xm;\r
348 \r
349   d = screen+(y*tsx)+x;\r
350   for (i=0;i<ym;++i) {\r
351     sx=0;\r
352     for (j=0;j<xm;++j) {\r
353       *d=s[(sx>>16)];\r
354       d+=xd;\r
355       sx+=xs;\r
356       }\r
357     d+=dys;\r
358     sy+=ys;\r
359     s+=(sy>>16)*w;\r
360     sy&=0xffff;\r
361     }\r
362   cpubyte=ETC;\r
363   return 0;\r
364 }\r
365 \r
366 int ModeXRenderMAPLine(int x, int y, int yofs, word *map)\r
367 {\r
368   cpubyte=RENDER;\r
369   asm("movl %1, %%edi                  \n\t"\r
370       "imul _tsx, %%edi                \n\t"\r
371       "addl %0, %%edi                  \n\t"\r
372       "addl _screen, %%edi             \n\t"\r
373       "movl _tx, %%ebx                 \n\t"\r
374       "incl %%ebx                      \n\t"\r
375       "movl %3, %%ecx                  \n\t"\r
376 "tileloop:                             \n\t"\r
377       "movw (%%ecx), %%ax              \n\t"\r
378       "movzwl %%ax, %%edx              \n\t"\r
379       "shll $1, %%edx                  \n\t"\r
380       "addl _tileidx, %%edx            \n\t"\r
381       "movw (%%edx), %%ax              \n\t"\r
382       "movzwl %%ax, %%esi              \n\t"\r
383       "shll $8, %%esi                  \n\t"\r
384       "addl _vsp, %%esi                \n\t"\r
385       "movl %2, %%eax                  \n\t"\r
386       "shll $4, %%eax                  \n\t"\r
387       "addl %%eax, %%esi               \n\t"\r
388       "movl (%%esi), %%eax             \n\t"\r
389       "movl %%eax, (%%edi)             \n\t"\r
390       "movl 4(%%esi), %%eax            \n\t"\r
391       "movl %%eax, 4(%%edi)            \n\t"\r
392       "movl 8(%%esi), %%eax            \n\t"\r
393       "movl %%eax, 8(%%edi)            \n\t"\r
394       "movl 12(%%esi), %%eax           \n\t"\r
395       "movl %%eax, 12(%%edi)           \n\t"\r
396       "addl $16, %%edi                 \n\t"\r
397       "addl $2, %%ecx                  \n\t"\r
398       "decl %%ebx                      \n\t"\r
399       "jnz tileloop                    \n\t"\r
400       :\r
401       : "m" (x), "m" (y), "m" (yofs), "m" (map)\r
402       : "eax","ebx","ecx","edx","esi","edi","cc" );\r
403 \r
404   cpubyte=ETC;\r
405   return 0;\r
406 }\r
407 \r
408 int ModeXTRenderMAPLine(int x, int y, int yofs, word *map)\r
409 {\r
410   cpubyte=RENDER;\r
411   asm("movl %1, %%edi                  \n\t"\r
412       "imul _tsx, %%edi                \n\t"\r
413       "addl %0, %%edi                  \n\t"\r
414       "addl _screen, %%edi             \n\t"\r
415       "movl _tx, %%ebx                 \n\t"\r
416       "incl %%ebx                      \n\t"\r
417       "movl %3, %%ecx                  \n\t"\r
418 "tileloop1:                            \n\t"\r
419       "movw (%%ecx), %%ax              \n\t"\r
420       "movzwl %%ax, %%edx              \n\t"\r
421       "shll $1, %%edx                  \n\t"\r
422       "addl _tileidx, %%edx            \n\t"\r
423       "movw (%%edx), %%ax              \n\t"\r
424       "orw %%ax, %%ax                  \n\t"\r
425       "jz next1                        \n\t"\r
426       "movzwl %%ax, %%esi              \n\t"\r
427       "shll $8, %%esi                  \n\t"\r
428       "movl %%esi, %%edx               \n\t"\r
429       "addl _vspmask, %%edx            \n\t"\r
430       "addl _vsp, %%esi                \n\t"\r
431       "movl %2, %%eax                  \n\t"\r
432       "shll $4, %%eax                  \n\t"\r
433       "addl %%eax, %%esi               \n\t"\r
434       "addl %%eax, %%edx               \n\t"\r
435       "movl (%%edi), %%eax             \n\t"\r
436       "andl (%%edx), %%eax             \n\t"\r
437       "orl  (%%esi), %%eax             \n\t"\r
438       "movl %%eax, (%%edi)             \n\t"\r
439       "movl 4(%%edi), %%eax            \n\t"\r
440       "andl 4(%%edx), %%eax            \n\t"\r
441       "orl  4(%%esi), %%eax            \n\t"\r
442       "movl %%eax, 4(%%edi)            \n\t"\r
443       "movl 8(%%edi), %%eax            \n\t"\r
444       "andl 8(%%edx), %%eax            \n\t"\r
445       "orl  8(%%esi), %%eax            \n\t"\r
446       "movl %%eax, 8(%%edi)            \n\t"\r
447       "movl 12(%%edi), %%eax           \n\t"\r
448       "andl 12(%%edx), %%eax           \n\t"\r
449       "orl  12(%%esi), %%eax           \n\t"\r
450       "movl %%eax, 12(%%edi)           \n\t"\r
451 "next1:                                \n\t"\r
452       "addl $16, %%edi                 \n\t"\r
453       "addl $2, %%ecx                  \n\t"\r
454       "decl %%ebx                      \n\t"\r
455       "jnz tileloop1                   \n\t"\r
456       :\r
457       : "m" (x), "m" (y), "m" (yofs), "m" (map)\r
458       : "eax","ebx","ecx","edx","esi","edi","cc" );\r
459 \r
460   cpubyte=ETC;\r
461   return 0;\r
462 }\r
463 \r
464 int ModeXColorField(int x, int y, byte c)\r
465 {\r
466   cpubyte=RENDER;\r
467   asm("movl %1, %%eax                   \n\t"\r
468       "imul _tsx, %%eax                 \n\t"\r
469       "addl %0, %%eax                   \n\t"\r
470       "addl _screen, %%eax              \n\t"\r
471       "movl %%eax, %%edi                \n\t"\r
472       "movl $8, %%ecx                   \n\t"\r
473       "movb %2, %%al                    \n\t"\r
474 "lineloop1:                             \n\t"\r
475       "stosb                            \n\t"\r
476       "incl %%edi                       \n\t"\r
477       "stosb                            \n\t"\r
478       "incl %%edi                       \n\t"\r
479       "stosb                            \n\t"\r
480       "incl %%edi                       \n\t"\r
481       "stosb                            \n\t"\r
482       "incl %%edi                       \n\t"\r
483       "stosb                            \n\t"\r
484       "incl %%edi                       \n\t"\r
485       "stosb                            \n\t"\r
486       "incl %%edi                       \n\t"\r
487       "stosb                            \n\t"\r
488       "incl %%edi                       \n\t"\r
489       "stosb                            \n\t"\r
490       "incl %%edi                       \n\t"\r
491       "addl _sx, %%edi                  \n\t"\r
492       "addl $16, %%edi                  \n\t"\r
493       "incl %%edi                       \n\t"\r
494       "stosb                            \n\t"\r
495       "incl %%edi                       \n\t"\r
496       "stosb                            \n\t"\r
497       "incl %%edi                       \n\t"\r
498       "stosb                            \n\t"\r
499       "incl %%edi                       \n\t"\r
500       "stosb                            \n\t"\r
501       "incl %%edi                       \n\t"\r
502       "stosb                            \n\t"\r
503       "incl %%edi                       \n\t"\r
504       "stosb                            \n\t"\r
505       "incl %%edi                       \n\t"\r
506       "stosb                            \n\t"\r
507       "incl %%edi                       \n\t"\r
508       "stosb                            \n\t"\r
509       "addl _sx, %%edi                  \n\t"\r
510       "addl $16, %%edi                  \n\t"\r
511       "decl %%ecx                       \n\t"\r
512       "jnz lineloop1                    \n\t"\r
513       :\r
514       : "m" (x), "m" (y), "m" (c)\r
515       : "eax","edi","ecx","cc" );\r
516   cpubyte=ETC;\r
517   return 0;\r
518 }\r
519 \r
520 int ModeXClearScreen()\r
521 {\r
522   cpubyte=RENDER;\r
523   memset(screen+(tsx*16)+16,0,(tsx*sy));\r
524   cpubyte=ETC;\r
525   return 0;\r
526 }\r
527 \r
528 int ModeXPutPixel(int x, int y, int color)\r
529 {\r
530   cpubyte=RENDER;\r
531 \r
532   if (x<cx1 || y<cy1 || x>cx2 || y>cy2)\r
533   {\r
534     cpubyte=ETC;\r
535     return 0;\r
536   }\r
537 \r
538   x+=16;\r
539   y+=16;\r
540 \r
541   screen[(y*tsx)+x]=color;\r
542 \r
543   cpubyte=ETC;\r
544   return 0;\r
545 }\r
546 \r
547 int ModeXGetPixel(int x, int y)\r
548 {\r
549   cpubyte=RENDER;\r
550 \r
551   if (x<cx1 || y<cy1 || x>cx2 || y>cy2)\r
552   {\r
553     cpubyte=ETC;\r
554     return 0;\r
555   }\r
556 \r
557   x+=16;\r
558   y+=16;\r
559 \r
560   cpubyte=ETC;\r
561   return screen[(y*tsx)+x];\r
562 }\r
563 \r
564 int ModeXHLine(int x, int y, int x2, int color)\r
565 { byte *d;\r
566   int width;\r
567 \r
568   cpubyte=RENDER;\r
569 \r
570   // swap?\r
571   if (x2<x) { int t=x2; x=x2; x2=t; }\r
572 \r
573   width=x2-x+1;\r
574   if (x>cx2 || y>cy2 || x+width<cx1 || y<cy1)\r
575     return 0;\r
576 \r
577   if (x+width > cx2) width=cx2-x+1;\r
578   if (x<cx1) { width-=(cx1-x); x=cx1; }\r
579 \r
580   x+=16;\r
581   y+=16;\r
582   x2+=16;\r
583 \r
584   d=screen+(y*tsx)+x;\r
585   memset(d,color,width);\r
586 \r
587   cpubyte=ETC;\r
588   return 0;\r
589 }\r
590 \r
591 int ModeXVLine(int x, int y, int y2, int color)\r
592 { byte *d;\r
593   int height;\r
594 \r
595   cpubyte=RENDER;\r
596 \r
597   // swap?\r
598   if (y2<y) { int t=y2; x=y2; y2=t; }\r
599 \r
600   height=y2-y+1;\r
601   if (x>cx2 || y>cy2 || x<cx1 || y+height<cy1)\r
602   {\r
603     cpubyte=ETC;\r
604     return 0;\r
605   }\r
606 \r
607   if (y+height > cy2) height=cy2-y+1;\r
608   if (y<cy1) { height-=(cy1-y); y=cy1; }\r
609 \r
610   x+=16;\r
611   y+=16;\r
612   y2+=16;\r
613 \r
614   d=screen+(y*tsx)+x;\r
615   for (; height; height--)\r
616   {\r
617     *d=color;\r
618     d+=tsx;\r
619   }\r
620 \r
621   cpubyte=ETC;\r
622   return 0;\r
623 }\r
624 \r
625 int ModeXLine(int x1, int y1, int x2, int y2, int color)\r
626 {\r
627   short i,xc,yc,er,n,m,xi,yi,xcxi,ycyi,xcyi;\r
628   unsigned dcy,dcx;\r
629 \r
630   cpubyte=RENDER;\r
631 \r
632   // check to see if the line is completly clipped off\r
633   if ((x1<cx1 && x2<cx1) || (x1>cx2 && x2>cx2)\r
634   || (y1<cy1 && y2<cy1) || (y1>cy2 && y2>cy2))\r
635   {\r
636     cpubyte=ETC;\r
637     return 0;\r
638   }\r
639 \r
640   if (x1>x2)\r
641   {\r
642     i=x1; x1=x2; x2=i;\r
643     i=y1; y1=y2; y2=i;\r
644   }\r
645 \r
646   // clip the left side\r
647   if (x1<cx1)\r
648   { int myy=(y2-y1);\r
649     int mxx=(x2-x1),b;\r
650     if (!mxx)\r
651     {\r
652       cpubyte=ETC;\r
653       return 0;\r
654     }\r
655     if (myy)\r
656     {\r
657       b=y1-(y2-y1)*x1/mxx;\r
658       y1=myy*cx1/mxx+b;\r
659       x1=cx1;\r
660     }\r
661     else x1=cx1;\r
662   }\r
663 \r
664   // clip the right side\r
665   if (x2>cx2)\r
666   { int myy=(y2-y1);\r
667     int mxx=(x2-x1),b;\r
668     if (!mxx)\r
669     {\r
670       cpubyte=ETC;\r
671       return 0;\r
672     }\r
673     if (myy)\r
674     {\r
675       b=y1-(y2-y1)*x1/mxx;\r
676       y2=myy*cx2/mxx+b;\r
677       x2=cx2;\r
678     }\r
679     else x2=cx2;\r
680   }\r
681 \r
682   if (y1>y2)\r
683   {\r
684     i=x1; x1=x2; x2=i;\r
685     i=y1; y1=y2; y2=i;\r
686   }\r
687 \r
688   // clip the bottom\r
689   if (y2>cy2)\r
690   { int mxx=(x2-x1);\r
691     int myy=(y2-y1),b;\r
692     if (!myy)\r
693     {\r
694       cpubyte=ETC;\r
695       return 0;\r
696     }\r
697     if (mxx)\r
698     {\r
699       b=y1-(y2-y1)*x1/mxx;\r
700       x2=(cy2-b)*mxx/myy;\r
701       y2=cy2;\r
702     }\r
703     else y2=cy2;\r
704   }\r
705 \r
706   // clip the top\r
707   if (y1<cy1)\r
708   { int mxx=(x2-x1);\r
709     int myy=(y2-y1),b;\r
710     if (!myy)\r
711     {\r
712       cpubyte=ETC;\r
713       return 0;\r
714     }\r
715     if (mxx)\r
716     {\r
717       b=y1-(y2-y1)*x1/mxx;\r
718       x1=(cy1-b)*mxx/myy;\r
719       y1=cy1;\r
720     }\r
721     else y1=cy1;\r
722   }\r
723 \r
724   // ???\r
725   // see if it got cliped into the box, out out\r
726   if (x1<cx1 || x2<cx1 || x1>cx2 || x2>cx2 || y1<cy1 || y2 <cy1 || y1>cy2 || y2>cy2)\r
727   {\r
728     cpubyte=ETC;\r
729     return 0;\r
730   }\r
731 \r
732   if (x1>x2)\r
733   { xc=x2; xi=x1; }\r
734   else { xi=x2; xc=x1; }\r
735 \r
736   x1+=16;y1+=16; // aen; adjust these here??\r
737   x2+=16;y2+=16;\r
738 \r
739   // assume y1<=y2 from above swap operation\r
740   yi=y2; yc=y1;\r
741 \r
742   dcx=x1; dcy=y1;\r
743   xc=(x2-x1); yc=(y2-y1);\r
744   if (xc<0) xi=-1; else xi=1;\r
745   if (yc<0) yi=-1; else yi=1;\r
746   n=abs(xc); m=abs(yc);\r
747   ycyi=abs(2*yc*xi);\r
748   er=0;\r
749 \r
750   if (n>m)\r
751   {\r
752     xcxi=abs(2*xc*xi);\r
753     for (i=0;i<=n;i++)\r
754     {\r
755       screen[(dcy*tsx)+dcx]=color;\r
756       if (er>0)\r
757       { dcy+=yi;\r
758         er-=xcxi;\r
759       }\r
760       er+=ycyi;\r
761       dcx+=xi;\r
762     }\r
763   }\r
764   else\r
765   {\r
766     xcyi=abs(2*xc*yi);\r
767     for (i=0;i<=m;i++)\r
768     {\r
769       screen[(dcy*tsx)+dcx]=color;\r
770       if (er>0)\r
771       { dcx+=xi;\r
772         er-=ycyi;\r
773       }\r
774       er+=xcyi;\r
775       dcy+=yi;\r
776     }\r
777   }\r
778 \r
779   cpubyte=ETC;\r
780   return 0;\r
781 }\r
782 \r
783 int ModeXCircle(int x, int y, int radius, int color)\r
784 { int cx=0;\r
785   int cy=radius;\r
786   int df=1-radius;\r
787   int d_e=3;\r
788   int d_se=-2*radius+5;\r
789 \r
790   cpubyte=RENDER;\r
791 \r
792   do {\r
793     ModeXPutPixel(x+cx,y+cy,color);\r
794     if (cx) ModeXPutPixel(x-cx,y+cy,color);\r
795     if (cy) ModeXPutPixel(x+cx,y-cy,color);\r
796     if ((cx) && (cy)) ModeXPutPixel(x-cx,y-cy,color);\r
797 \r
798     if (cx != cy)\r
799     {\r
800       ModeXPutPixel(x+cy,y+cx,color);\r
801       if (cx) ModeXPutPixel(x+cy,y-cx,color);\r
802       if (cy) ModeXPutPixel(x-cy,y+cx,color);\r
803       if (cx && cy) ModeXPutPixel(x-cy,y-cx,color);\r
804     }\r
805 \r
806     if (df<0)\r
807     {\r
808       df+=d_e;\r
809       d_e+=2;\r
810       d_se+=2;\r
811     }\r
812     else\r
813     {\r
814       df+=d_se;\r
815       d_e+=2;\r
816       d_se+=4;\r
817       cy--;\r
818     }\r
819 \r
820     cx++;\r
821 \r
822   } while (cx <= cy);\r
823 \r
824   cpubyte=ETC;\r
825   return 0;\r
826 }\r
827 \r
828 int ModeXCircleFill(int x, int y, int radius, int color)\r
829 { int cx=0;\r
830   int cy=radius;\r
831   int df=1-radius;\r
832   int d_e=3;\r
833   int d_se=-2*radius+5;\r
834 \r
835   cpubyte=RENDER;\r
836 \r
837   do {\r
838     ModeXHLine(x-cy,y-cx,x+cy,color);\r
839     if (cx) ModeXHLine(x-cy,y+cx,x+cy,color);\r
840 \r
841     if (df<0)\r
842     {\r
843       df+=d_e;\r
844       d_e+=2;\r
845       d_se+=2;\r
846     }\r
847     else\r
848     {\r
849       if (cx != cy)\r
850       {\r
851         ModeXHLine(x-cx,y-cy,x+cx,color);\r
852         if (cy) ModeXHLine(x-cx,y+cy,x+cx,color);\r
853       }\r
854 \r
855       df+=d_se;\r
856       d_e+=2;\r
857       d_se+=4;\r
858       cy--;\r
859     }\r
860 \r
861     cx++;\r
862 \r
863   } while (cx <= cy);\r
864 \r
865   cpubyte=ETC;\r
866   return 0;\r
867 }\r
868 \r
869 int ModeXRect(int x, int y, int x2, int y2, int color)\r
870 {\r
871   ModeXHLine(x,y,x2,color);\r
872   ModeXHLine(x,y2,x2,color);\r
873   ModeXVLine(x,y+1,y2-1,color);\r
874   ModeXVLine(x2,y+1,y2-1,color);\r
875   return 0;\r
876 }\r
877 \r
878 int ModeXRectFill(int x, int y, int x2, int y2, int color)\r
879 {\r
880   cpubyte=RENDER;\r
881 \r
882   if (y2<y) { int t=y2; y=y2; y2=t; }\r
883 \r
884   for (; y<=y2; y++)\r
885     ModeXHLine(x,y,x2,color);\r
886 \r
887   cpubyte=ETC;\r
888   return 0;\r
889 }\r
890 \r
891 void Set256x256()\r
892 // -- ric: 15/Jun/98 --\r
893 // My first attempt at graphics code :)\r
894 {\r
895   char in_byte;\r
896 \r
897   outportw(SEQU_ADDR, 0x0100);\r
898   outportb(CRTC_ADDR, 0x11);\r
899   in_byte = inportb((CRTC_ADDR+1));\r
900   in_byte = (in_byte && 0x7f);\r
901   outportb((CRTC_ADDR+1), in_byte);\r
902   outportw(SEQU_ADDR, 0x0604);\r
903   outportb(MISC_OUTPUT, 0xe3);\r
904 \r
905   outportb(CRTC_ADDR, 0x0); outportb(CRTC_ADDR+1, 0x5f);\r
906   outportb(CRTC_ADDR, 0x1); outportb(CRTC_ADDR+1, 0x3f);\r
907   outportb(CRTC_ADDR, 0x2); outportb(CRTC_ADDR+1, 0x40);\r
908   outportb(CRTC_ADDR, 0x3); outportb(CRTC_ADDR+1, 0x82);\r
909   outportb(CRTC_ADDR, 0x4); outportb(CRTC_ADDR+1, 0x4a);\r
910   outportb(CRTC_ADDR, 0x5); outportb(CRTC_ADDR+1, 0x9a);\r
911   outportb(CRTC_ADDR, 0x6); outportb(CRTC_ADDR+1, 0x23);\r
912   outportb(CRTC_ADDR, 0x7); outportb(CRTC_ADDR+1, 0xb2);\r
913   outportb(CRTC_ADDR, 0x8); outportb(CRTC_ADDR+1, 0x0);\r
914   outportb(CRTC_ADDR, 0x9); outportb(CRTC_ADDR+1, 0x61);\r
915   outportb(CRTC_ADDR, 0x10); outportb(CRTC_ADDR+1, 0xa);\r
916   outportb(CRTC_ADDR, 0x11); outportb(CRTC_ADDR+1, 0xac);\r
917   outportb(CRTC_ADDR, 0x12); outportb(CRTC_ADDR+1, 0xff);\r
918   outportb(CRTC_ADDR, 0x14); outportb(CRTC_ADDR+1, 0x0);\r
919   outportb(CRTC_ADDR, 0x15); outportb(CRTC_ADDR+1, 0x7);\r
920   outportb(CRTC_ADDR, 0x16); outportb(CRTC_ADDR+1, 0x1a);\r
921   outportb(CRTC_ADDR, 0x17); outportb(CRTC_ADDR+1, 0xe3);\r
922   outportb(SEQU_ADDR, 0x1);  outportw(SEQU_ADDR+1, 0x1);\r
923   outportb(0x3ce, 0x5); outportb(0x3cf, 0x40);\r
924   outportb(0x3ce, 0x6); outportb(0x3cf, 0x5);\r
925   inportb(0x3DA);\r
926   outportb(0x3C0, 0x1 | 0x20);\r
927   outportb(0x3C0, 0x41);\r
928   outportb(CRTC_ADDR, 0x13);\r
929   outportb(CRTC_ADDR+1, 0x20);\r
930 \r
931   outportw(SEQU_ADDR, 0x0300);\r
932 \r
933   sx=256;  sy=256;\r
934   tsx=288; tsy=288;\r
935   tx=17;   ty=16;\r
936   cx1=0;   cy1=0;\r
937   cx2=sx-1;cy2=sy-1;\r
938   endcol=272; nextl=64;\r
939   winofs=4608;\r
940   DriverDesc = "256x256 (ModeX, planar)";\r
941 }\r
942 \r
943 void Set320x240()\r
944 { char in_byte;\r
945 \r
946   outportw(SEQU_ADDR, 0x0604);\r
947   outportw(SEQU_ADDR, 0x0110);\r
948   outportb(MISC_OUTPUT, 0xe3);\r
949   outportw(SEQU_ADDR, 0x0300);\r
950   outportb(CRTC_ADDR, 0x11);\r
951   in_byte = inportb((CRTC_ADDR+1));\r
952   in_byte = (in_byte && 0x7f);\r
953   outportb((CRTC_ADDR+1), in_byte);\r
954   outportw(CRTC_ADDR, 0x0d06);\r
955   outportw(CRTC_ADDR, 0x3e07);\r
956   outportw(CRTC_ADDR, 0x4109);\r
957   outportw(CRTC_ADDR, 0xea10);\r
958   outportw(CRTC_ADDR, 0xac11);\r
959   outportw(CRTC_ADDR, 0xdf12);\r
960   outportw(CRTC_ADDR, 0x0014);\r
961   outportw(CRTC_ADDR, 0xe715);\r
962   outportw(CRTC_ADDR, 0x0616);\r
963   outportw(CRTC_ADDR, 0xe317);\r
964 \r
965   sx=320;  sy=240;\r
966   tsx=352; tsy=272;\r
967   tx=20;   ty=15;\r
968   cx1=0;   cy1=0;\r
969   cx2=sx-1;cy2=sy-1;\r
970   endcol=336; nextl=80;\r
971   winofs=5632;\r
972   DriverDesc = "320x240 (ModeX, planar)";\r
973 }\r
974 \r
975 void Set360x240()\r
976 { char in_byte;\r
977 \r
978   outportw(SEQU_ADDR, 0x0604);\r
979   outportw(SEQU_ADDR, 0x100);\r
980   outportb(MISC_OUTPUT, 0xe7);\r
981   outportw(SEQU_ADDR, 0x300);\r
982   outportb(CRTC_ADDR, 0x11);\r
983   in_byte = inportb((CRTC_ADDR+1));\r
984   in_byte = (in_byte && 0x7f);\r
985   outportb((CRTC_ADDR+1), in_byte);\r
986   outportw(CRTC_ADDR, 0x6b00);\r
987   outportw(CRTC_ADDR, 0x5901);\r
988   outportw(CRTC_ADDR, 0x5a02);\r
989   outportw(CRTC_ADDR, 0x8e03);\r
990   outportw(CRTC_ADDR, 0x5e04);\r
991   outportw(CRTC_ADDR, 0x8a05);\r
992   outportw(CRTC_ADDR, 0x0d06);\r
993   outportw(CRTC_ADDR, 0x3e07);\r
994   outportw(CRTC_ADDR, 0x4109);\r
995   outportw(CRTC_ADDR, 0xea10);\r
996   outportw(CRTC_ADDR, 0xac11);\r
997   outportw(CRTC_ADDR, 0xdf12);\r
998   outportw(CRTC_ADDR, 0x2d13);\r
999   outportw(CRTC_ADDR, 0x0014);\r
1000   outportw(CRTC_ADDR, 0xe715);\r
1001   outportw(CRTC_ADDR, 0x0616);\r
1002   outportw(CRTC_ADDR, 0xe317);\r
1003 \r
1004   sx=360;  sy=240;\r
1005   tsx=392; tsy=272;\r
1006   tx=23;   ty=15;\r
1007   cx1=0;   cy1=0;\r
1008   cx2=sx-1;cy2=sy-1;\r
1009   endcol=376; nextl=90;\r
1010   winofs=6272;\r
1011   DriverDesc = "360x240 (ModeX, planar)";\r
1012 }\r
1013 \r
1014 void InitModeX(int res)\r
1015 {\r
1016   ModeXSetMode(0x13);\r
1017 \r
1018   switch (res)\r
1019   {\r
1020     case 0: Set320x240(); break;\r
1021     case 1: Set360x240(); break;\r
1022     case 2: Set256x256(); break; /* -- ric: 15/Jun/98 -- */\r
1023     default: err("Internal error: unknown ModeX resolution code");\r
1024   }\r
1025 \r
1026   screenbase=(char *) 0xA0000+__djgpp_conventional_base;\r
1027   screen=(char *) malloc(107648);\r
1028   memset(screen,0,107648);\r
1029   clearScreen();\r
1030 \r
1031   // Mode successfuly set, now lets set up the driver.\r
1032 \r
1033   ShutdownVideo = ModeXShutdown;\r
1034   ShowPage = ModeXShowPage;\r
1035   CopySprite = ModeXCopySprite;\r
1036   TCopySprite = ModeXTCopySprite;\r
1037   CCopySprite = ModeXCCopySprite;\r
1038   TCCopySprite = ModeXTCCopySprite;\r
1039   CopyTile = ModeXCopyTile;\r
1040   TCopyTile = ModeXTCopyTile;\r
1041   ScaleSprite = ModeXScaleSprite;\r
1042   RenderMAPLine = ModeXRenderMAPLine;\r
1043   TRenderMAPLine = ModeXTRenderMAPLine;\r
1044   ColorField = ModeXColorField;\r
1045   ClearScreen = ModeXClearScreen;\r
1046   PutPixel = ModeXPutPixel;\r
1047   GetPixel = ModeXGetPixel;\r
1048   HLine = ModeXHLine;\r
1049   VLine = ModeXVLine;\r
1050   Line = ModeXLine;\r
1051   Circle = ModeXCircle;\r
1052   CircleFill = ModeXCircleFill;\r
1053   Rect = ModeXRect;\r
1054   RectFill = ModeXRectFill;\r
1055 }\r