1 /* pMARS -- a portable Memory Array Redcode Simulator
2  * Copyright (C) 1993-1996 Albert Ma, Na'ndor Sieben, Stefan Strack and Mintardjo Wangsawidjaja
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18 
19 /*
20  * grxdisp.c: DOS graphics mode (DJGPP/GRX) display
21  * $Id: grxdisp.c,v 1.1.1.1 2000/08/20 13:29:36 iltzu Exp $
22  *
23  * graphics coreviewer should work on any display supported by go32
24  * include this file into sim.c to replace the DISPLAY_? macros */
25 
26 #include <grx.h>
27 #include <conio.h>
28 #include <mousex.h>
29 
30 int     mouse_or_key(char *);
31 void    grclear(void);
32 void    bgi_clear_arena(void);
33 
34 /* extern string */
35 extern char *pressAnyKey;
36 
37 GrTextOption groption;
38 GrFont *grfont;
39 GR_graphics_modes graphdriver = GR_width_height_graphics;
40 int     graphmode = 0;
41 #define setcolor(color) groption.txo_fgcolor.v=(color)
42 #define outtextxy(x,y,s) GrDrawString(s,strlen(s),x,y,&groption)
43 
44 #define WHITE GrWhite()
45 #define BLACK GrBlack()
46 
47 /* to be implemented */
48 #define display_push(val)
49 #define display_die(warnum)
50 
51 int     colors[MAXWARRIOR];        /* colors of the two warriors */
52 int     datcolors[MAXWARRIOR];        /* death colors */
53 int     clearColor;
54 int     writeColor;
55 
56 #include "xgraphio.c"
57 
58 #define MAXSTR 80
59 #define BORDER_WIDTH 3                /* arena border */
60 #define LEFT_UPPER_X 3                /* location of the arena */
61 #define LEFT_UPPER_Y 30                /* 20 */
62 #define CYCLE_Y 25 /* 15 */        /* location of the cycle meter */
63 
64 int     cycle_Y = CYCLE_Y;        /* location of cycle meter */
65 int     splY[MAXWARRIOR];        /* location of the process meters */
66 
67 int     VERTICAL_SIZE;                /* # of core locations in a line in the arena */
68 int     SIZE;                        /* size of one core location */
69 int     CYCLE_RATIO;
70 int     PROCESS_RATIO;
71 
72 int     step;                        /* are we in single step mode ? */
73 int     i;
74 int     mouseOK;
75 int     mouseLocation;
76 int     newMouseLoc;
77 int     x, y;
78 int     xsize, ysize;
79 int     col;
80 
81 extern int stepping;
82 extern ADDR_T curAddr;
83 extern int curPanel;
84 
85 void    display_init();
86 
87 void
88         open_graphics(void);
89 
90 int
xkoord(int addr)91 xkoord(int addr)
92 {
93   return
94   (LEFT_UPPER_X + ((addr) % VERTICAL_SIZE) * (SIZE + 1));
95 }
96 
97 int
ykoord(int addr)98 ykoord(int addr)
99 {
100   return
101   (LEFT_UPPER_Y + ((addr) / VERTICAL_SIZE) * (SIZE + 1));
102 }
103 void
findplace(int addr)104 findplace(int addr)
105 {
106   x = xkoord(addr);
107   y = ykoord(addr);
108   col = colors[W - warrior];
109 }
110 
111 /*************************************************************************/
112 
113 #define bgi_update_cycle_meter()\
114  GrPlotNC(cycle / CYCLE_RATIO, CYCLE_Y, clearColor)
115 
116 #define bgi_display_init() open_graphics()
117 
118 #define bgi_display_read(addr)\
119   GrPlotNC(xkoord(addr),ykoord(addr),colors[W-warrior])
120 
121 #define bgi_display_dec(addr)\
122 do { \
123   findplace(addr);\
124   GrPlotNC(x  ,y,col);\
125   GrPlotNC(x+1,y,col);  \
126 } while (0)
127 
128 #define bgi_display_inc(addr)\
129 do { \
130   findplace(addr);\
131   GrPlotNC(x,y  ,col); \
132   GrPlotNC(x,y+1,col); \
133 } while(0)
134 
135 #define bgi_display_write(addr)\
136 do { \
137   findplace(addr);\
138   GrPlotNC(x+1,y,col);\
139   GrPlotNC(x  ,y+1,col);\
140 } while(0)
141 
142 #define bgi_display_exec(addr)\
143 do {\
144     GrBoxNC(xkoord(addr),ykoord(addr),\
145     xkoord(addr)+1,ykoord(addr)+1,colors[W-warrior]);\
146 } while(0)
147 
148 
149 #define bgi_display_spl(warrior,tasks) \
150   GrPlotNC(tasks/PROCESS_RATIO,splY[warrior],colors[warrior])
151 
152 #define bgi_display_dat(addr,warNum,tasks) \
153   do {\
154     if (displayLevel>0) {\
155         GrBoxNC(xkoord(addr),ykoord(addr),\
156         xkoord(addr)+1,ykoord(addr)+1,datcolors[warNum]);\
157     }\
158     GrPlotNC(tasks/PROCESS_RATIO,splY[warNum],clearColor);\
159   } while(0)
160 
161 void
bgi_clear_arena()162 bgi_clear_arena()
163 {
164   GrFilledBox(
165               LEFT_UPPER_X - BORDER_WIDTH + 1,
166               LEFT_UPPER_Y - BORDER_WIDTH + 1,
167               xkoord(VERTICAL_SIZE - 1) + BORDER_WIDTH - 1,
168               ykoord(coreSize) + BORDER_WIDTH - 1, GrBlack());
169 }
170 
171 void
bgi_display_clear()172 bgi_display_clear()
173 {
174   int     dummy;
175   bgi_clear_arena();
176   for (dummy = 0; dummy < warriors; dummy++) {
177     GrLine(0, splY[dummy], GrMaxX(), splY[dummy], clearColor);
178     GrPlot(1 + taskNum / PROCESS_RATIO, splY[dummy], colors[dummy]);
179     GrLine(1, splY[dummy], warrior[dummy].tasks / PROCESS_RATIO,
180            splY[dummy], colors[dummy]);
181   }
182   GrLine(1, CYCLE_Y, GrMaxX(), CYCLE_Y, clearColor);
183   GrLine(1, CYCLE_Y, cycle / CYCLE_RATIO - 1, CYCLE_Y, writeColor);
184 }
185 
186 void
bgi_display_close(int wait)187 bgi_display_close(int wait)
188 {
189   MouseUnInit();
190   if (wait == WAIT && displayLevel) {
191     grputs(pressAnyKey);
192     if (inputRedirection)
193       while (!kbhit());
194     else
195       getch();
196   }
197   textmode(LASTMODE);
198   displayMode = TEXT;                /* to display results in textmode */
199 #ifdef DOSTXTGRAPHX
200   ScreenUpdate(Screen[DEF_PAGE]);        /* restore text screen */
201   show_cursor();
202   gotoxy(1, defPageY);
203 #endif
204 }
205 
206 /**************************************************************************/
207 /* this function is called by grgets() in xgraphio to handle mouse events */
208 
209 int
mouse_or_key(char * result)210 mouse_or_key(char *result)
211 {
212   int     x, y, hi, lo;
213   MouseEvent evt;
214   MouseWarp(xkoord(curAddr) + 1, ykoord(curAddr) + 1);
215   MouseDisplayCursor();
216   while (!kbhit()) {
217     if (mouseOK == mouseOK) {        /* check if there is a mouse on the system */
218       MouseGetEvent(M_BUTTON_DOWN | M_POLL, &evt);
219       if (evt.flags & M_BUTTON_DOWN) {
220         x = evt.x - LEFT_UPPER_X + (SIZE) / 2;
221         y = evt.y - LEFT_UPPER_Y + (SIZE) / 2;
222         newMouseLoc = x / (SIZE + 1) + (y / (SIZE + 1)) * VERTICAL_SIZE;
223         if ((newMouseLoc >= 0) && (newMouseLoc < coreSize)) {
224           curAddr = newMouseLoc;
225           if (evt.flags & M_LEFT_DOWN)
226             strcpy(result, " m mousel\n");
227           else if (evt.flags & M_MIDDLE_DOWN)
228             strcpy(result, " m mousem\n");
229           else if (evt.flags & M_RIGHT_DOWN)
230             strcpy(result, " m mouser\n");
231           MouseEraseCursor();
232           return 1;
233         }
234       }
235     }
236   }
237   MouseEraseCursor();
238   return 0;
239 }
240 
241 
242 #define draw_border do {            \
243   GrBox(                                          \
244   LEFT_UPPER_X-BORDER_WIDTH,                          \
245   LEFT_UPPER_Y-BORDER_WIDTH,                          \
246   xkoord(VERTICAL_SIZE-1)+BORDER_WIDTH,               \
247   ykoord(coreSize)+BORDER_WIDTH,writeColor ); } while (0)
248 
249 void
write_menu(void)250 write_menu(void)
251 {
252   int     y;
253   int     i, j;
254 #define BUTTON RED
255   char    s[7];
256   y = ykoord(coreSize) + BORDER_WIDTH + 2;
257   setcolor(writeColor);
258   outtextxy(10, y, "<");
259   setcolor(BUTTON);
260   s[0] = CLEAR;
261   s[1] = 0;
262   for (i = 0; i < SPEEDLEVELS - displaySpeed; i++)
263     outtextxy(20 + i * 10, y, s);
264   setcolor(YELLOW);
265   for (j = 0; j < displaySpeed; j++)
266     outtextxy(20 + i * 10 + j * 10, y, s);
267   setcolor(writeColor);
268   outtextxy(20 + i * 10 + j * 10, y, "> ");
269   for (i = 0; i < 5; i++) {
270     sprintf(s, "%d ", i);
271     if (displayLevel == i)
272       setcolor(BUTTON);
273     else
274       setcolor(writeColor);
275     outtextxy(170 + i * 10, y, s);
276   }
277   if (inCdb)
278     setcolor(BUTTON);
279   else
280     setcolor(writeColor);
281   outtextxy(260, y, "Debug ");
282   setcolor(writeColor);
283   if (xsize > 320) {
284     if (inCdb) {
285       setcolor(clearColor);
286     }
287 #if defined(DOSALLGRAPHX)
288     outtextxy(310, y, "space textVideo Quit");
289 #else
290     outtextxy(310, y, "space Quit");
291 #endif
292   }
293   setcolor(writeColor);
294 }
295 
296 void
write_names(void)297 write_names(void)
298 {
299   GrFilledBox(0, 0, 30, 10, GrBlack());        /* clear unwanted ctrl-c */
300   if (warriors <= 2) {
301     setcolor(colors[0]);
302     outtextxy(1, 0, warrior[0].name);
303     if (warriors == 2) {
304       setcolor(colors[1]);
305       outtextxy(140, 0, warrior[1].name);
306     }
307   }
308 }
309 
310 void
open_graphics(void)311 open_graphics(void)
312 {
313   int     i;
314 
315 #ifdef DOSTXTGRAPHX
316   if (!Screen[DEF_PAGE])
317     text_display_init();        /* to save DOS text screen for later restore */
318 #endif
319 
320   switch (displayMode) {
321   case 1:
322     xsize = 640;
323     ysize = 480;
324     break;
325   case 2:
326     xsize = 800;
327     ysize = 600;
328     break;
329   case 3:
330     xsize = 1024;
331     ysize = 768;
332     break;
333   case 4:
334     xsize = 640;
335     ysize = 200;
336     break;
337   case 5:
338     xsize = 640;
339     ysize = 350;
340     break;
341   case 6:
342     xsize = 320;
343     ysize = 200;
344     break;
345   default:
346     xsize = 640;
347     ysize = 480;
348     break;
349   }
350 
351   GrSetMode(graphdriver, xsize, ysize);
352 
353   grfont = GrLoadFont("@:pc8x8.fnt");
354 
355   memset(&groption, 0, sizeof(groption));
356   groption.txo_font = grfont;
357   groption.txo_xalign = GR_ALIGN_LEFT;
358   groption.txo_yalign = GR_ALIGN_TOP;
359   groption.txo_xmag = 1;
360   groption.txo_ymag = 1;
361   groption.txo_direct = GR_TEXT_RIGHT;
362   groption.txo_fgcolor.v = GrWhite();
363   groption.txo_bgcolor.v = GrBlack();
364 
365   clearColor = BLACK;
366   writeColor = WHITE;
367 
368   SIZE = 4;                        /* Size of a given location, feel free to
369                                  * make it bigger */
370   do {
371     --SIZE;                        /* decrease the size to fit */
372     VERTICAL_SIZE = (GrMaxX() - 2 * LEFT_UPPER_X) / (SIZE + 1);
373   } while ((ykoord(coreSize) > GrMaxY() - 20) && SIZE > 0);
374 
375   if ((CYCLE_RATIO = 2 * warriors * cycles / GrMaxY()) == 0)
376     CYCLE_RATIO = 1;
377   if ((PROCESS_RATIO = taskNum / GrMaxY()) == 0)
378     PROCESS_RATIO = 1;
379 
380   draw_border;
381 
382   setcolor(writeColor);
383   write_menu();
384   bgi_display_clear();
385 
386 /* initializing corelist variables and mouse */
387 
388   step = 0;
389   MouseInit();
390   mouseLocation = -1;
391   newMouseLoc = 0;
392 
393 /* initializing graphio parameters */
394 
395   grwindy0 = ykoord(coreSize) + 2 * BORDER_WIDTH + 6;
396   grwindy1 = GrMaxY() - verspace;
397 
398   curPanel = -1;                /* one panel only */
399   grupdate(0);
400   graphio_init();
401   grclear();
402 
403 /* initializing meter locations and colors */
404 
405   if (warriors <= 2) {
406     splY[0] = 9;
407     splY[1] = 11;
408     colors[0] = GREEN;
409     colors[1] = LIGHTRED;
410     datcolors[0] = GREEN + 1;
411     datcolors[1] = LIGHTRED + 1;
412   } else {
413     for (i = 0; i < 21; i++) {
414       if (warriors <= 10) {
415         splY[i] = 2 * i + 1;
416       } else {
417         splY[i] = i + 1;
418       }
419     }
420     for (i = 0; i < MAXWARRIOR; i++) {
421       datcolors[i] = colors[i] = i % 15 + 1;
422     }
423   }
424 
425   write_names();
426 
427 }
428 
429 #if ! defined(DOSTXTGRAPHX)
430 #define display_init()      bgi_display_init()
431 #define display_clear()     bgi_display_clear()
432 #define display_read(addr) do { if (displayLevel > 3)\
433   bgi_display_read(addr); } while(0)
434 #define display_write(addr) do { if (displayLevel > 1)\
435   bgi_display_write(addr); } while(0)
436 #define display_dec(addr) do { if (displayLevel > 2)\
437   bgi_display_dec(addr); } while (0)
438 #define display_inc(addr)  do { if (displayLevel > 2)\
439   bgi_display_inc(addr); } while(0)
440 #define display_exec(addr) do { if (displayLevel > 0)\
441   bgi_display_exec(addr); } while(0)
442 #define display_spl(warrior,tasks) bgi_display_spl(warrior,tasks)
443 #define display_dat(addr,warnum,tasks) bgi_display_dat(addr,warnum,tasks)
444 #define display_close()     bgi_display_close(WAIT)
445 #endif
446