]> git.sur5r.net Git - cc65/blob - testcode/lib/pen-test.c
aa3992635be3f5f6bcce8ab356b85f6d04694442
[cc65] / testcode / lib / pen-test.c
1 /*
2 ** Test program for lightpen drivers. Will work for the C64/C128.
3 **
4 ** 2001-09-13, Ullrich von Bassewitz
5 ** 2013-06-21, Greg King
6 **
7 */
8
9
10
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <mouse.h>
15 #include <conio.h>
16 #include <ctype.h>
17 #include <dbg.h>
18
19 #define max(a,b)  (((a) > (b)) ? (a) : (b))
20 #define min(a,b)  (((a) < (b)) ? (a) : (b))
21
22
23
24 /* Statically linked driver */
25 #define DYN_DRV         0
26
27
28
29 #ifdef __C64__
30 #  if DYN_DRV
31 #    define mouse_stddrv "c64-inkwell.mou"
32 #  else
33 #    define mouse_static_stddrv c64_inkwell_mou
34 #  endif
35 #endif
36
37 #ifdef __C128__
38 #  if DYN_DRV
39 #    define mouse_stddrv "c128-inkwell.mou"
40 #  else
41 #    define mouse_static_stddrv c128_inkwell_mou
42 #  endif
43 #endif
44
45
46
47 #if defined(__C64__) || defined(__C128__)
48
49 /* Addresses of data for sprite 0 */
50 #if defined(__C64__)
51 #  define SPRITE0_DATA  ((unsigned char[64])0x0340)
52 #  define SPRITE0_PTR   ((unsigned char *)0x07F8)
53 #elif defined(__C128__)
54 #  define SPRITE0_DATA  ((unsigned char[64])0x0E00)
55 #  define SPRITE0_PTR   ((unsigned char *)0x07F8)
56 #endif
57
58 /* An arrow sprite */
59 static const unsigned char PenSprite[64] = {
60     0xFF, 0xFF, 0xFF,
61     0xFC, 0x00, 0x00,
62     0xF8, 0x00, 0x00,
63     0xFC, 0x00, 0x00,
64     0xDE, 0x00, 0x00,
65     0x8F, 0x00, 0x00,
66     0x87, 0x80, 0x00,
67     0x83, 0xC0, 0x00,
68     0x81, 0xE0, 0x00,
69     0x80, 0xF0, 0x00,
70     0x80, 0x78, 0x00,
71     0x80, 0x38, 0x00,
72     0x80, 0x00, 0x00,
73     0x80, 0x00, 0x00,
74     0x80, 0x00, 0x00,
75     0x80, 0x00, 0x00,
76     0x80, 0x00, 0x00,
77     0x80, 0x00, 0x00,
78     0x80, 0x00, 0x00,
79     0x80, 0x00, 0x00,
80     0x80, 0x00, 0x00
81 };
82
83 #endif  /* __C64__ or __C128__ */
84
85
86
87 static void __fastcall__ CheckError (const char* S, unsigned char Error)
88 {
89     if (Error != MOUSE_ERR_OK) {
90         cprintf ("%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error);
91         exit (EXIT_FAILURE);
92     }
93 }
94
95 #if DYN_DRV
96 static void DoWarning (void)
97 /* Warn the user that a lightpen driver is needed for this program. */
98 {
99     cprintf ("Warning: This program needs a lightpen\r\n"
100              "driver with the name\r\n"
101              "    %s\r\n"
102              "on disk! Press 'y' if you have it; or,\r\n"
103              "any other key to exit.\r\n", mouse_stddrv);
104     if (tolower (cgetc ()) != 'y') {
105         exit (EXIT_SUCCESS);
106     }
107     cprintf ("OK. Please wait patiently...\r\n");
108 }
109 #endif
110
111
112
113 static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible)
114 /* Display jail and cursor states. */
115 {
116     cclearxy (0, 7, 32);
117     gotoxy (0, 7);
118     cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : "");
119 }
120
121
122
123 int main (void)
124 {
125     struct mouse_info info;
126     struct mouse_box full_box, small_box;
127     char C;
128     unsigned char width, height;
129     bool Invisible = false, Done = false, Jailed = false;
130
131 #ifdef __C128__
132     /* Only the VIC-IIe has a lightpen connection. */
133     videomode (VIDEOMODE_40x25);
134 #endif
135
136     /* Initiate the debugger. */
137     DbgInit (0);
138
139     /* Set dark-on-light colors.  Clear the screen. */
140 #ifdef __CBM__
141     (void) bordercolor (COLOR_GRAY2);
142     (void) bgcolor (COLOR_WHITE);
143     (void) textcolor (COLOR_GRAY1);
144 #else
145     (void) bordercolor (COLOR_BLUE);
146     (void) bgcolor (COLOR_WHITE);
147     (void) textcolor (COLOR_BLACK);
148 #endif
149     cursor (0);
150     clrscr ();
151
152 #if defined(__C64__) || defined(__C128__)
153     /* Copy the sprite data. */
154     memcpy (SPRITE0_DATA, PenSprite, sizeof PenSprite);
155
156     /* Set the VIC-II sprite pointer. */
157     *SPRITE0_PTR = ((unsigned) SPRITE0_DATA & 0x3FFF) / sizeof SPRITE0_DATA;
158
159     /* Set the color of sprite 0. */
160     VIC.spr0_color = COLOR_BLACK;
161
162     pen_adjust ("inkwell.dat");
163 #endif
164
165 #if DYN_DRV
166     /* Output a warning about the driver that is needed. */
167     DoWarning ();
168
169     /* Load and install the lightpen driver. */
170     CheckError ("mouse_load_driver",
171                 mouse_load_driver (&mouse_def_callbacks, mouse_stddrv));
172 #else
173     /* Install the lightpen driver. */
174     CheckError ("mouse_install",
175                 mouse_install (&mouse_def_callbacks, mouse_static_stddrv));
176 #endif
177
178     /* Get the initial lightpen bounding box. */
179     mouse_getbox (&full_box);
180
181     screensize (&width, &height);
182
183 top:
184     clrscr ();
185
186     /* Print a help line. */
187     cputs (" d)ebug  h)ide   q)uit   s)how   j)ail");
188
189     /* Put a cross at the center of the screen. */
190     gotoxy (width / 2 - 3, height / 2 - 1);
191     cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4,
192              width / 2, "");
193
194     /* Expose the arrow. */
195     mouse_show ();
196     ShowState (Jailed, Invisible);
197
198     /* Test loop */
199     do {
200         /* Get the current lightpen co-ordinates and button states;
201         ** and, print them.
202         */
203         mouse_info (&info);
204         gotoxy (0, 2);
205         cprintf (" X  = %3d\r\n", info.pos.x);
206         cprintf (" Y  = %3d\r\n", info.pos.y);
207         cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ?
208 #ifdef __CBM__
209                  0x5F
210 #else
211                  'v'
212 #endif
213                  : '^');
214         cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ?
215 #ifdef __CBM__
216                  0x5F
217 #else
218                  'v'
219 #endif
220                  : '^');
221
222         /* Handle user input. */
223         if (kbhit ()) {
224             cclearxy (1, 9, 23);
225             switch (tolower (C = cgetc ())) {
226                 case 'd':
227                     BREAK();
228
229                     /* The debugger might have changed the colors.
230                     ** Restore them.
231                     */
232 #ifdef __CBM__
233                     (void) bordercolor (COLOR_GRAY2);
234                     (void) bgcolor (COLOR_WHITE);
235                     (void) textcolor (COLOR_GRAY1);
236 #else
237                     (void) bordercolor (COLOR_BLUE);
238                     (void) bgcolor (COLOR_WHITE);
239                     (void) textcolor (COLOR_BLACK);
240 #endif
241                     goto top;
242
243                 case 'h':
244                     mouse_hide ();
245                     ShowState (Jailed, ++Invisible);
246                     break;
247
248                 case 'j':
249                     if (Jailed) {
250                         mouse_setbox (&full_box);
251                         Jailed = false;
252                     } else {
253                         small_box.minx = max (info.pos.x - 10, full_box.minx);
254                         small_box.miny = max (info.pos.y - 10, full_box.miny);
255                         small_box.maxx = min (info.pos.x + 10, full_box.maxx);
256                         small_box.maxy = min (info.pos.y + 10, full_box.maxy);
257                         mouse_setbox (&small_box);
258                         Jailed = true;
259                     }
260                     ShowState (Jailed, Invisible);
261                     break;
262
263                 case 's':
264                     mouse_show ();
265                     if (Invisible) {
266                         ShowState (Jailed, --Invisible);
267                     }
268                     break;
269
270                 case 'q':
271                     Done = true;
272                     break;
273
274                 default:
275                     gotoxy (1, 9);
276                     cprintf ("Spurious character: $%02X", C);
277             }
278         }
279     } while (!Done);
280
281 #if DYN_DRV
282     /* Uninstall and unload the lightpen driver. */
283     CheckError ("mouse_unload", mouse_unload ());
284 #else
285     /* Uninstall the lightpen driver. */
286     CheckError ("mouse_uninstall", mouse_uninstall ());
287 #endif
288
289     /* Say goodbye. */
290     cputsxy (0, height / 2 + 3, "Goodbye!");
291     return EXIT_SUCCESS;
292 }