typo..
[AROS.git] / test / graphics / areatest2.c
blob7ade3d565a081e64f1d15e4c0112c2895336f99d
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <intuition/intuition.h>
7 #include <graphics/gfxmacros.h>
8 #include <graphics/gfx.h>
9 #include <devices/rawkeycodes.h>
11 #include <proto/exec.h>
12 #include <proto/dos.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdio.h>
20 #include <aros/debug.h>
22 #define MAX_POINTS 50
24 #define MODE_ADDPOINTS 1
25 #define MODE_MOVEPOINTS 2
27 #define MSGMOUSEX ( ((msg->MouseX - win->BorderLeft) < 0) ? 0 : \
28 ((msg->MouseX - win->BorderLeft) >= win->GZZWidth) ? win->GZZWidth - 1 : \
29 (msg->MouseX - win->BorderLeft) )
31 #define MSGMOUSEY ( ((msg->MouseY - win->BorderTop) < 0) ? 0 : \
32 ((msg->MouseY - win->BorderTop) >= win->GZZHeight) ? win->GZZHeight - 1 : \
33 (msg->MouseY - win->BorderTop) )
35 static struct Window *win;
36 static struct RastPort *winrp, *drawrp;
37 static struct BitMap *drawbm;
38 static struct AreaInfo ai;
39 static struct TmpRas tr;
40 static void *trbuf;
41 static UBYTE aibuf[(MAX_POINTS + 1) * 5];
42 static WORD mode, actpoint, hipoint, numpoints;
43 static WORD outlinepen = -1, testfillpen = -1;
44 static BOOL outlinemode, testfill;
45 static WORD points[MAX_POINTS + 1][2];
46 static char wintitle[256];
48 #include "areatest2_fillpoly.h"
50 static void cleanup(char *msg)
52 if (msg) printf("areatest2: %s\n", msg);
54 if (outlinepen != -1) ReleasePen(win->WScreen->ViewPort.ColorMap, outlinepen);
55 if (testfillpen != -1) ReleasePen(win->WScreen->ViewPort.ColorMap, testfillpen);
56 if (drawbm) FreeBitMap(drawbm);
57 if (drawrp) FreeRastPort(drawrp);
59 if (trbuf)
61 FreeRaster(trbuf, win->GZZWidth, win->GZZHeight);
64 if (win) CloseWindow(win);
65 exit(0);
68 static void updatetitle(void)
70 char *title = "AreaTest2";
72 switch(mode)
74 case MODE_ADDPOINTS:
75 snprintf(wintitle,
76 sizeof(wintitle),
77 "Create points [%2d/%2d]. Press RETURN when done.",
78 actpoint + 1, MAX_POINTS);
79 title = wintitle;
80 break;
82 case MODE_MOVEPOINTS:
83 snprintf(wintitle,
84 sizeof(wintitle),
85 "Move points. Press RETURN to make new shape.");
86 title = wintitle;
87 break;
91 SetWindowTitles(win, title, (char *)~0);
95 static void makewin(void)
97 win = OpenWindowTags(0, WA_Title, (IPTR)"AreaTest2",
98 WA_InnerWidth, 320,
99 WA_InnerHeight, 256,
100 WA_GimmeZeroZero, TRUE,
101 WA_CloseGadget, TRUE,
102 WA_DepthGadget, TRUE,
103 WA_DragBar, TRUE,
104 WA_IDCMP, IDCMP_MOUSEBUTTONS |
105 IDCMP_MOUSEMOVE |
106 IDCMP_CLOSEWINDOW |
107 IDCMP_VANILLAKEY |
108 IDCMP_RAWKEY,
109 WA_Activate, TRUE,
110 WA_ReportMouse, TRUE,
111 TAG_DONE);
112 if (!win) cleanup("Can't open window!");
114 winrp = win->RPort;
116 InitArea(&ai, aibuf, sizeof(aibuf) / 5);
117 trbuf = AllocRaster(win->GZZWidth, win->GZZHeight);
118 if (!trbuf) cleanup("TmpRas buffer allocation failed!");
119 InitTmpRas(&tr, trbuf, RASSIZE(win->GZZWidth, win->GZZHeight));
121 drawbm = AllocBitMap(win->GZZWidth, win->GZZHeight, 0, BMF_MINPLANES, win->RPort->BitMap);
122 if (!drawbm) cleanup("Can't allocate draw bitmap!");
124 drawrp = CreateRastPort();
125 if (!drawrp) cleanup("Can't allocate draw rastport!");
126 drawrp->BitMap = drawbm;
128 drawrp->AreaInfo = &ai;
129 drawrp->TmpRas = &tr;
131 outlinepen = ObtainBestPen(win->WScreen->ViewPort.ColorMap, 0xFFFFFFFF,
132 0x00000000,
133 0x00000000,
134 OBP_FailIfBad, FALSE,
135 TAG_DONE);
137 testfillpen = ObtainBestPen(win->WScreen->ViewPort.ColorMap, 0x44444444,
138 0x44444444,
139 0x44444444,
140 OBP_FailIfBad, FALSE,
141 TAG_DONE);
145 static void hilightpoint(WORD point)
147 WORD x = points[point][0];
148 WORD y = points[point][1];
150 //kprintf("hilightpoint %d,%d\n", x, y);
152 SetABPenDrMd(winrp, 2, 0, COMPLEMENT);
153 Move(winrp, x - 3, y - 3);
154 Draw(winrp, x + 3, y - 3),
155 Draw(winrp, x + 3, y + 3);
156 Draw(winrp, x - 3, y + 3),
157 Draw(winrp, x - 3, y - 3);
160 static void clear(struct RastPort *rp)
162 SetABPenDrMd(rp, 2, 0, JAM1);
163 RectFill(rp, 0, 0, win->GZZWidth - 1, win->GZZHeight - 1);
166 static void paint(void)
168 int i;
170 if (numpoints == 0) return;
172 switch(mode)
174 case MODE_ADDPOINTS:
175 SetABPenDrMd(winrp, 1, 0, JAM1);
176 Move(winrp, points[0][0], points[0][1]);
177 PolyDraw(winrp, numpoints, (WORD *)points);
178 break;
180 case MODE_MOVEPOINTS:
181 clear(drawrp);
182 SetABPenDrMd(drawrp, testfill ? testfillpen : 1, 0, JAM1);
183 if (outlinemode)
185 SetOutlinePen(drawrp, outlinepen);
187 else
189 drawrp->Flags &= ~AREAOUTLINE;
192 if (!testfill)
194 AreaMove(drawrp, points[0][0], points[0][1]);
195 for(i = 1; i < numpoints; i++)
197 AreaDraw(drawrp, points[i][0], points[i][1]);
199 AreaEnd(drawrp);
201 else
203 MyFillPolygon(drawrp, points, numpoints);
206 BltBitMapRastPort(drawbm, 0, 0, winrp, 0, 0, win->GZZWidth, win->GZZHeight, 192);
207 break;
211 static WORD pointundermouse(LONG x, LONG y)
213 LONG i, dist;
214 LONG best_i = 0, best_dist = 0x7fffffff;
216 for(i = 0; i < numpoints; i++)
218 dist = (points[i][0] - x) * (points[i][0] - x) +
219 (points[i][1] - y) * (points[i][1] - y);
221 if (dist < best_dist)
223 best_dist = dist;
224 best_i = i;
228 return (best_dist < 200) ? best_i : -1;
231 static void savepoly(WORD n)
233 char s[200];
234 BPTR fh;
235 BOOL ok = FALSE;
236 LONG err;
238 snprintf(s, sizeof(s), "PROGDIR:polygon%d.dat", n);
240 if ((fh = Open(s, MODE_NEWFILE)))
242 WORD i = numpoints;
244 if (Write(fh, &i, sizeof(i)) == sizeof(i))
246 for(n = 0; n < numpoints; n++)
248 i = points[n][0];
249 if (Write(fh, &i, sizeof(i)) != sizeof(i)) break;
251 i = points[n][1];
252 if (Write(fh, &i, sizeof(i)) != sizeof(i)) break;
256 if (n == numpoints) ok = TRUE;
259 err = IoErr();
261 Close(fh);
263 else
265 err = IoErr();
268 if (!ok)
270 Fault(err, "Saving failed", s, sizeof(s));
272 else
274 strcpy(s, "Saved polygon");
277 SetWindowTitles(win, s, (char *)~0);
278 Delay(75);
279 updatetitle();
283 static BOOL loadpoly(WORD n)
285 char s[200];
286 BPTR fh;
287 BOOL ok = FALSE;
288 LONG err;
289 WORD *temppoints;
291 snprintf(s, sizeof(s), "PROGDIR:polygon%d.dat", n);
293 if ((fh = Open(s, MODE_OLDFILE)))
295 WORD i;
297 if (Read(fh, &i, sizeof(i)) == sizeof(i))
299 if ((temppoints = malloc(sizeof(WORD) * 2 * i)))
301 for(n = 0; n < i; n++)
303 if (Read(fh, &temppoints[n * 2], sizeof(WORD)) != sizeof(WORD)) break;
304 if (Read(fh, &temppoints[n * 2 + 1], sizeof(WORD)) != sizeof(WORD)) break;
308 if (n == i)
310 numpoints = i;
311 for(i = 0; i < n; i++)
313 points[i][0] = temppoints[i * 2];
314 points[i][1] = temppoints[i * 2 + 1];
317 ok = TRUE;
320 free(temppoints);
325 err = IoErr();
327 Close(fh);
329 else
331 err = IoErr();
334 if (!ok)
336 Fault(err, "Loading failed", s, sizeof(s));
337 SetWindowTitles(win, s, (char *)~0);
338 Delay(75);
339 updatetitle();
342 return ok;
346 static void handleall(void)
348 struct IntuiMessage *msg;
349 WORD i;
350 BOOL quitme = FALSE, lmbdown = FALSE;
352 mode = MODE_ADDPOINTS;
353 updatetitle();
354 clear(winrp);
356 while(!quitme)
358 WaitPort(win->UserPort);
359 while((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
361 switch(msg->Class)
363 case IDCMP_CLOSEWINDOW:
364 quitme = TRUE;
365 break;
367 case IDCMP_MOUSEBUTTONS:
368 if (msg->Code == SELECTDOWN)
370 lmbdown = TRUE;
372 switch(mode)
374 case MODE_ADDPOINTS:
375 points[actpoint][0] = MSGMOUSEX;
376 points[actpoint][1] = MSGMOUSEY;
377 actpoint++;
378 numpoints++;
379 if (numpoints == MAX_POINTS)
381 mode = MODE_MOVEPOINTS;
382 actpoint = -1;
383 hipoint = -1;
385 paint();
386 updatetitle();
387 break;
389 case MODE_MOVEPOINTS:
390 actpoint = pointundermouse(MSGMOUSEX, MSGMOUSEY);
391 break;
395 else if (msg->Code == SELECTUP)
397 lmbdown = FALSE;
399 switch(mode)
401 case MODE_MOVEPOINTS:
402 actpoint = -1;
403 hipoint = -1;
404 break;
408 break;
410 case IDCMP_MOUSEMOVE:
411 switch(mode)
413 case MODE_MOVEPOINTS:
414 if ((actpoint >= 0) && lmbdown)
416 points[actpoint][0] = MSGMOUSEX;
417 points[actpoint][1] = MSGMOUSEY;
418 paint();
420 else if (!lmbdown)
422 WORD new_hipoint = pointundermouse(MSGMOUSEX, MSGMOUSEY);
424 if (new_hipoint != hipoint)
426 if (hipoint >= 0) hilightpoint(hipoint);
427 hipoint = new_hipoint;
428 if (hipoint >= 0) hilightpoint(hipoint);
432 break;
434 break;
436 case IDCMP_VANILLAKEY:
437 switch(msg->Code)
439 case 27:
440 quitme = TRUE;
441 break;
443 case 13:
444 switch(mode)
446 case MODE_ADDPOINTS:
447 if (numpoints >= 2)
449 mode = MODE_MOVEPOINTS;
450 actpoint = -1;
451 hipoint = -1;
452 paint();
453 updatetitle();
455 break;
457 case MODE_MOVEPOINTS:
458 actpoint = numpoints = 0;
459 mode = MODE_ADDPOINTS;
460 clear(winrp);
461 updatetitle();
462 break;
464 break;
466 case '4':
467 if (mode == MODE_MOVEPOINTS)
469 for(i = 0; i < numpoints; i++)
471 if (points[i][0] > 0) points[i][0]--;
473 hipoint = -1;
474 paint();
476 break;
478 case '6':
479 if (mode == MODE_MOVEPOINTS)
481 for(i = 0; i < numpoints; i++)
483 if (points[i][0] < win->GZZWidth - 1) points[i][0]++;
485 hipoint = -1;
486 paint();
488 break;
490 case '8':
491 if (mode == MODE_MOVEPOINTS)
493 for(i = 0; i < numpoints; i++)
495 if (points[i][1] > 0) points[i][1]--;
497 hipoint = -1;
498 paint();
500 break;
502 case '2':
503 if (mode == MODE_MOVEPOINTS)
505 for(i = 0; i < numpoints; i++)
507 if (points[i][1] < win->GZZHeight - 1) points[i][1]++;
509 hipoint = -1;
510 paint();
512 break;
514 case 'o':
515 case 'O':
516 outlinemode = !outlinemode;
517 if (mode == MODE_MOVEPOINTS)
519 hipoint = -1;
520 paint();
521 SetWindowTitles(win, outlinemode ? "Outline Mode: ON" : "Outline Mode: OFF", (char *)~0);
522 Delay(30);
523 updatetitle();
525 break;
527 case 'f':
528 case 'F':
529 case 'R':
530 case 'r':
531 testfill = !testfill;
532 if (mode == MODE_MOVEPOINTS)
534 hipoint = -1;
535 paint();
536 SetWindowTitles(win, testfill ? "Test Fillroutine: ON" : "Test Fillroutine: OFF", (char *)~0);
537 Delay(30);
538 updatetitle();
540 break;
542 break;
544 case IDCMP_RAWKEY:
545 switch(mode)
547 case MODE_MOVEPOINTS:
548 if (lmbdown && actpoint >= 0)
550 BOOL changed = FALSE;
552 switch(msg->Code)
554 case CURSORLEFT:
555 if (points[actpoint][0] > 0)
557 points[actpoint][0]--;
558 changed = TRUE;
560 break;
562 case CURSORRIGHT:
563 if (points[actpoint][0] < win->GZZWidth - 1)
565 points[actpoint][0]++;
566 changed = TRUE;
568 break;
570 case CURSORUP:
571 if (points[actpoint][1] > 0)
573 points[actpoint][1]--;
574 changed = TRUE;
576 break;
578 case CURSORDOWN:
579 if (points[actpoint][1] < win->GZZHeight - 1)
581 points[actpoint][1]++;
582 changed = TRUE;
584 break;
586 } /* switch(msg->Code) */
588 if (changed) paint();
590 } /* if (!lmbdown && hipoint >= 0) */
591 else
593 switch(msg->Code)
595 case RAWKEY_F1:
596 case RAWKEY_F2:
597 case RAWKEY_F3:
598 case RAWKEY_F4:
599 case RAWKEY_F5:
600 case RAWKEY_F6:
601 case RAWKEY_F7:
602 case RAWKEY_F8:
603 case RAWKEY_F9:
604 case RAWKEY_F10:
605 if (msg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
607 savepoly(msg->Code - RAWKEY_F1 + 1);
609 else
611 loadpoly(msg->Code - RAWKEY_F1 + 1);
612 hipoint = -1;
613 paint();
615 break;
619 break;
621 case MODE_ADDPOINTS:
622 switch(msg->Code)
624 case RAWKEY_F1:
625 case RAWKEY_F2:
626 case RAWKEY_F3:
627 case RAWKEY_F4:
628 case RAWKEY_F5:
629 case RAWKEY_F6:
630 case RAWKEY_F7:
631 case RAWKEY_F8:
632 case RAWKEY_F9:
633 case RAWKEY_F10:
634 if (!(msg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
636 if (loadpoly(msg->Code - RAWKEY_F1 + 1))
638 hipoint = -1;
639 actpoint = -1;
640 mode = MODE_MOVEPOINTS;
641 paint();
644 break;
646 break;
648 } /* switch(mode) */
649 break;
651 } /* switch(msg->Class) */
652 ReplyMsg((struct Message *)msg);
654 } /* while((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
656 } /*while(!quitme) */
660 int main(void)
662 makewin();
663 handleall();
664 cleanup(0);
665 return 0;