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