LICENSE.Author: Add license file to permit per-author *additional* permissions
[AROS.git] / test / areatest2.c
blobd31f3612c455cbf1d37defb26889dd39634579e7
1 #include <intuition/intuition.h>
2 #include <graphics/gfxmacros.h>
3 #include <graphics/gfx.h>
4 #include <devices/rawkeycodes.h>
6 #include <proto/exec.h>
7 #include <proto/dos.h>
8 #include <proto/intuition.h>
9 #include <proto/graphics.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
15 #include <aros/debug.h>
17 #define MAX_POINTS 50
19 #define MODE_ADDPOINTS 1
20 #define MODE_MOVEPOINTS 2
22 #define MSGMOUSEX ( ((msg->MouseX - win->BorderLeft) < 0) ? 0 : \
23 ((msg->MouseX - win->BorderLeft) >= win->GZZWidth) ? win->GZZWidth - 1 : \
24 (msg->MouseX - win->BorderLeft) )
26 #define MSGMOUSEY ( ((msg->MouseY - win->BorderTop) < 0) ? 0 : \
27 ((msg->MouseY - win->BorderTop) >= win->GZZHeight) ? win->GZZHeight - 1 : \
28 (msg->MouseY - win->BorderTop) )
30 static struct Window *win;
31 static struct RastPort *winrp, *drawrp;
32 static struct BitMap *drawbm;
33 static struct AreaInfo ai;
34 static struct TmpRas tr;
35 static void *trbuf;
36 static UBYTE aibuf[(MAX_POINTS + 1) * 5];
37 static WORD mode, actpoint, hipoint, numpoints;
38 static WORD outlinepen = -1, testfillpen = -1;
39 static BOOL outlinemode, testfill;
40 static WORD points[MAX_POINTS + 1][2];
41 static char wintitle[256];
43 #include "areatest2_fillpoly.h"
45 static void cleanup(char *msg)
47 if (msg) printf("areatest2: %s\n", msg);
49 if (outlinepen != -1) ReleasePen(win->WScreen->ViewPort.ColorMap, outlinepen);
50 if (testfillpen != -1) ReleasePen(win->WScreen->ViewPort.ColorMap, testfillpen);
51 if (drawbm) FreeBitMap(drawbm);
52 if (drawrp) FreeRastPort(drawrp);
54 if (trbuf)
56 FreeRaster(trbuf, win->GZZWidth, win->GZZHeight);
59 if (win) CloseWindow(win);
60 exit(0);
63 static void updatetitle(void)
65 char *title = "AreaTest2";
67 switch(mode)
69 case MODE_ADDPOINTS:
70 snprintf(wintitle,
71 sizeof(wintitle),
72 "Create points [%2d/%2d]. Press RETURN when done.",
73 actpoint + 1, MAX_POINTS);
74 title = wintitle;
75 break;
77 case MODE_MOVEPOINTS:
78 snprintf(wintitle,
79 sizeof(wintitle),
80 "Move points. Press RETURN to make new shape.");
81 title = wintitle;
82 break;
86 SetWindowTitles(win, title, (char *)~0);
90 static void makewin(void)
92 win = OpenWindowTags(0, WA_Title, (IPTR)"AreaTest2",
93 WA_InnerWidth, 320,
94 WA_InnerHeight, 256,
95 WA_GimmeZeroZero, TRUE,
96 WA_CloseGadget, TRUE,
97 WA_DepthGadget, TRUE,
98 WA_DragBar, TRUE,
99 WA_IDCMP, IDCMP_MOUSEBUTTONS |
100 IDCMP_MOUSEMOVE |
101 IDCMP_CLOSEWINDOW |
102 IDCMP_VANILLAKEY |
103 IDCMP_RAWKEY,
104 WA_Activate, TRUE,
105 WA_ReportMouse, TRUE,
106 TAG_DONE);
107 if (!win) cleanup("Can't open window!");
109 winrp = win->RPort;
111 InitArea(&ai, aibuf, sizeof(aibuf) / 5);
112 trbuf = AllocRaster(win->GZZWidth, win->GZZHeight);
113 if (!trbuf) cleanup("TmpRas buffer allocation failed!");
114 InitTmpRas(&tr, trbuf, RASSIZE(win->GZZWidth, win->GZZHeight));
116 drawbm = AllocBitMap(win->GZZWidth, win->GZZHeight, 0, BMF_MINPLANES, win->RPort->BitMap);
117 if (!drawbm) cleanup("Can't allocate draw bitmap!");
119 drawrp = CreateRastPort();
120 if (!drawrp) cleanup("Can't allocate draw rastport!");
121 drawrp->BitMap = drawbm;
123 drawrp->AreaInfo = &ai;
124 drawrp->TmpRas = &tr;
126 outlinepen = ObtainBestPen(win->WScreen->ViewPort.ColorMap, 0xFFFFFFFF,
127 0x00000000,
128 0x00000000,
129 OBP_FailIfBad, FALSE,
130 TAG_DONE);
132 testfillpen = ObtainBestPen(win->WScreen->ViewPort.ColorMap, 0x44444444,
133 0x44444444,
134 0x44444444,
135 OBP_FailIfBad, FALSE,
136 TAG_DONE);
140 static void hilightpoint(WORD point)
142 WORD x = points[point][0];
143 WORD y = points[point][1];
145 //kprintf("hilightpoint %d,%d\n", x, y);
147 SetABPenDrMd(winrp, 2, 0, COMPLEMENT);
148 Move(winrp, x - 3, y - 3);
149 Draw(winrp, x + 3, y - 3),
150 Draw(winrp, x + 3, y + 3);
151 Draw(winrp, x - 3, y + 3),
152 Draw(winrp, x - 3, y - 3);
155 static void clear(struct RastPort *rp)
157 SetABPenDrMd(rp, 2, 0, JAM1);
158 RectFill(rp, 0, 0, win->GZZWidth - 1, win->GZZHeight - 1);
161 static void paint(void)
163 int i;
165 if (numpoints == 0) return;
167 switch(mode)
169 case MODE_ADDPOINTS:
170 SetABPenDrMd(winrp, 1, 0, JAM1);
171 Move(winrp, points[0][0], points[0][1]);
172 PolyDraw(winrp, numpoints, (WORD *)points);
173 break;
175 case MODE_MOVEPOINTS:
176 clear(drawrp);
177 SetABPenDrMd(drawrp, testfill ? testfillpen : 1, 0, JAM1);
178 if (outlinemode)
180 SetOutlinePen(drawrp, outlinepen);
182 else
184 drawrp->Flags &= ~AREAOUTLINE;
187 if (!testfill)
189 AreaMove(drawrp, points[0][0], points[0][1]);
190 for(i = 1; i < numpoints; i++)
192 AreaDraw(drawrp, points[i][0], points[i][1]);
194 AreaEnd(drawrp);
196 else
198 MyFillPolygon(drawrp, points, numpoints);
201 BltBitMapRastPort(drawbm, 0, 0, winrp, 0, 0, win->GZZWidth, win->GZZHeight, 192);
202 break;
206 static WORD pointundermouse(LONG x, LONG y)
208 LONG i, dist;
209 LONG best_i = 0, best_dist = 0x7fffffff;
211 for(i = 0; i < numpoints; i++)
213 dist = (points[i][0] - x) * (points[i][0] - x) +
214 (points[i][1] - y) * (points[i][1] - y);
216 if (dist < best_dist)
218 best_dist = dist;
219 best_i = i;
223 return (best_dist < 200) ? best_i : -1;
226 static void savepoly(WORD n)
228 char s[200];
229 BPTR fh;
230 BOOL ok = FALSE;
231 LONG err;
233 snprintf(s, sizeof(s), "PROGDIR:polygon%d.dat", n);
235 if ((fh = Open(s, MODE_NEWFILE)))
237 WORD i = numpoints;
239 if (Write(fh, &i, sizeof(i)) == sizeof(i))
241 for(n = 0; n < numpoints; n++)
243 i = points[n][0];
244 if (Write(fh, &i, sizeof(i)) != sizeof(i)) break;
246 i = points[n][1];
247 if (Write(fh, &i, sizeof(i)) != sizeof(i)) break;
251 if (n == numpoints) ok = TRUE;
254 err = IoErr();
256 Close(fh);
258 else
260 err = IoErr();
263 if (!ok)
265 Fault(err, "Saving failed", s, sizeof(s));
267 else
269 strcpy(s, "Saved polygon");
272 SetWindowTitles(win, s, (char *)~0);
273 Delay(75);
274 updatetitle();
278 static BOOL loadpoly(WORD n)
280 char s[200];
281 BPTR fh;
282 BOOL ok = FALSE;
283 LONG err;
284 WORD *temppoints;
286 snprintf(s, sizeof(s), "PROGDIR:polygon%d.dat", n);
288 if ((fh = Open(s, MODE_OLDFILE)))
290 WORD i;
292 if (Read(fh, &i, sizeof(i)) == sizeof(i))
294 if ((temppoints = malloc(sizeof(WORD) * 2 * i)))
296 for(n = 0; n < i; n++)
298 if (Read(fh, &temppoints[n * 2], sizeof(WORD)) != sizeof(WORD)) break;
299 if (Read(fh, &temppoints[n * 2 + 1], sizeof(WORD)) != sizeof(WORD)) break;
303 if (n == i)
305 numpoints = i;
306 for(i = 0; i < n; i++)
308 points[i][0] = temppoints[i * 2];
309 points[i][1] = temppoints[i * 2 + 1];
312 ok = TRUE;
315 free(temppoints);
320 err = IoErr();
322 Close(fh);
324 else
326 err = IoErr();
329 if (!ok)
331 Fault(err, "Loading failed", s, sizeof(s));
332 SetWindowTitles(win, s, (char *)~0);
333 Delay(75);
334 updatetitle();
337 return ok;
341 static void handleall(void)
343 struct IntuiMessage *msg;
344 WORD i;
345 BOOL quitme = FALSE, lmbdown = FALSE;
347 mode = MODE_ADDPOINTS;
348 updatetitle();
349 clear(winrp);
351 while(!quitme)
353 WaitPort(win->UserPort);
354 while((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
356 switch(msg->Class)
358 case IDCMP_CLOSEWINDOW:
359 quitme = TRUE;
360 break;
362 case IDCMP_MOUSEBUTTONS:
363 if (msg->Code == SELECTDOWN)
365 lmbdown = TRUE;
367 switch(mode)
369 case MODE_ADDPOINTS:
370 points[actpoint][0] = MSGMOUSEX;
371 points[actpoint][1] = MSGMOUSEY;
372 actpoint++;
373 numpoints++;
374 if (numpoints == MAX_POINTS)
376 mode = MODE_MOVEPOINTS;
377 actpoint = -1;
378 hipoint = -1;
380 paint();
381 updatetitle();
382 break;
384 case MODE_MOVEPOINTS:
385 actpoint = pointundermouse(MSGMOUSEX, MSGMOUSEY);
386 break;
390 else if (msg->Code == SELECTUP)
392 lmbdown = FALSE;
394 switch(mode)
396 case MODE_MOVEPOINTS:
397 actpoint = -1;
398 hipoint = -1;
399 break;
403 break;
405 case IDCMP_MOUSEMOVE:
406 switch(mode)
408 case MODE_MOVEPOINTS:
409 if ((actpoint >= 0) && lmbdown)
411 points[actpoint][0] = MSGMOUSEX;
412 points[actpoint][1] = MSGMOUSEY;
413 paint();
415 else if (!lmbdown)
417 WORD new_hipoint = pointundermouse(MSGMOUSEX, MSGMOUSEY);
419 if (new_hipoint != hipoint)
421 if (hipoint >= 0) hilightpoint(hipoint);
422 hipoint = new_hipoint;
423 if (hipoint >= 0) hilightpoint(hipoint);
427 break;
429 break;
431 case IDCMP_VANILLAKEY:
432 switch(msg->Code)
434 case 27:
435 quitme = TRUE;
436 break;
438 case 13:
439 switch(mode)
441 case MODE_ADDPOINTS:
442 if (numpoints >= 2)
444 mode = MODE_MOVEPOINTS;
445 actpoint = -1;
446 hipoint = -1;
447 paint();
448 updatetitle();
450 break;
452 case MODE_MOVEPOINTS:
453 actpoint = numpoints = 0;
454 mode = MODE_ADDPOINTS;
455 clear(winrp);
456 updatetitle();
457 break;
459 break;
461 case '4':
462 if (mode == MODE_MOVEPOINTS)
464 for(i = 0; i < numpoints; i++)
466 if (points[i][0] > 0) points[i][0]--;
468 hipoint = -1;
469 paint();
471 break;
473 case '6':
474 if (mode == MODE_MOVEPOINTS)
476 for(i = 0; i < numpoints; i++)
478 if (points[i][0] < win->GZZWidth - 1) points[i][0]++;
480 hipoint = -1;
481 paint();
483 break;
485 case '8':
486 if (mode == MODE_MOVEPOINTS)
488 for(i = 0; i < numpoints; i++)
490 if (points[i][1] > 0) points[i][1]--;
492 hipoint = -1;
493 paint();
495 break;
497 case '2':
498 if (mode == MODE_MOVEPOINTS)
500 for(i = 0; i < numpoints; i++)
502 if (points[i][1] < win->GZZHeight - 1) points[i][1]++;
504 hipoint = -1;
505 paint();
507 break;
509 case 'o':
510 case 'O':
511 outlinemode = !outlinemode;
512 if (mode == MODE_MOVEPOINTS)
514 hipoint = -1;
515 paint();
516 SetWindowTitles(win, outlinemode ? "Outline Mode: ON" : "Outline Mode: OFF", (char *)~0);
517 Delay(30);
518 updatetitle();
520 break;
522 case 'f':
523 case 'F':
524 case 'R':
525 case 'r':
526 testfill = !testfill;
527 if (mode == MODE_MOVEPOINTS)
529 hipoint = -1;
530 paint();
531 SetWindowTitles(win, testfill ? "Test Fillroutine: ON" : "Test Fillroutine: OFF", (char *)~0);
532 Delay(30);
533 updatetitle();
535 break;
537 break;
539 case IDCMP_RAWKEY:
540 switch(mode)
542 case MODE_MOVEPOINTS:
543 if (lmbdown && actpoint >= 0)
545 BOOL changed = FALSE;
547 switch(msg->Code)
549 case CURSORLEFT:
550 if (points[actpoint][0] > 0)
552 points[actpoint][0]--;
553 changed = TRUE;
555 break;
557 case CURSORRIGHT:
558 if (points[actpoint][0] < win->GZZWidth - 1)
560 points[actpoint][0]++;
561 changed = TRUE;
563 break;
565 case CURSORUP:
566 if (points[actpoint][1] > 0)
568 points[actpoint][1]--;
569 changed = TRUE;
571 break;
573 case CURSORDOWN:
574 if (points[actpoint][1] < win->GZZHeight - 1)
576 points[actpoint][1]++;
577 changed = TRUE;
579 break;
581 } /* switch(msg->Code) */
583 if (changed) paint();
585 } /* if (!lmbdown && hipoint >= 0) */
586 else
588 switch(msg->Code)
590 case RAWKEY_F1:
591 case RAWKEY_F2:
592 case RAWKEY_F3:
593 case RAWKEY_F4:
594 case RAWKEY_F5:
595 case RAWKEY_F6:
596 case RAWKEY_F7:
597 case RAWKEY_F8:
598 case RAWKEY_F9:
599 case RAWKEY_F10:
600 if (msg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
602 savepoly(msg->Code - RAWKEY_F1 + 1);
604 else
606 loadpoly(msg->Code - RAWKEY_F1 + 1);
607 hipoint = -1;
608 paint();
610 break;
614 break;
616 case MODE_ADDPOINTS:
617 switch(msg->Code)
619 case RAWKEY_F1:
620 case RAWKEY_F2:
621 case RAWKEY_F3:
622 case RAWKEY_F4:
623 case RAWKEY_F5:
624 case RAWKEY_F6:
625 case RAWKEY_F7:
626 case RAWKEY_F8:
627 case RAWKEY_F9:
628 case RAWKEY_F10:
629 if (!(msg->Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
631 if (loadpoly(msg->Code - RAWKEY_F1 + 1))
633 hipoint = -1;
634 actpoint = -1;
635 mode = MODE_MOVEPOINTS;
636 paint();
639 break;
641 break;
643 } /* switch(mode) */
644 break;
646 } /* switch(msg->Class) */
647 ReplyMsg((struct Message *)msg);
649 } /* while((msg = (struct IntuiMessage *)GetMsg(win->UserPort))) */
651 } /*while(!quitme) */
655 int main(void)
657 makewin();
658 handleall();
659 cleanup(0);
660 return 0;