]> git.sur5r.net Git - cc65/blob - samples/mousedemo.c
Only for jumps, the lib uses named asm labels in branches
[cc65] / samples / mousedemo.c
1 /*
2 ** Demo program for mouse usage.
3 ** Supports the C64/C128/CBM510/Atari/Apple2.
4 **
5 ** 2001-09-13, Ullrich von Bassewitz
6 ** 2013-09-05, Greg King
7 **
8 */
9
10
11
12 #include <stdbool.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <mouse.h>
16 #include <pen.h>
17 #include <conio.h>
18 #include <ctype.h>
19 #include <dbg.h>
20 #include <cc65.h>
21
22 #define max(a,b)  (((a) > (b)) ? (a) : (b))
23 #define min(a,b)  (((a) < (b)) ? (a) : (b))
24
25
26
27 #ifdef MOUSE_DRIVER
28
29 /* A statically linked driver was named on the compiler's command line.
30 ** Make sure that it is used instead of a dynamic one.
31 */
32 #  undef DYN_DRV
33 #  define DYN_DRV       0
34 #else
35
36 /* Use a dynamically loaded driver, by default. */
37 #  ifndef DYN_DRV
38 #    define DYN_DRV     1
39 #  endif
40 #endif
41
42
43
44 #ifdef __CBM__
45
46 /* Set dark-on-light colors. */
47 const unsigned char mouse_def_pointercolor = COLOR_BLACK;
48
49 #endif
50
51
52
53 static void __fastcall__ CheckError (const char* S, unsigned char Error)
54 {
55     if (Error != MOUSE_ERR_OK) {
56         cprintf ("\n%s: %s(%u)\r\n", S, mouse_geterrormsg (Error), Error);
57
58         /* Wait for a key-press, so that some platforms can show the error
59         ** message before they remove the current screen.
60         */
61         if (doesclrscrafterexit ()) {
62             cgetc ();
63         }
64         exit (EXIT_FAILURE);
65     }
66 }
67
68
69
70 #if DYN_DRV
71
72 /* Points to the dynamic driver's name. */
73 static const char *mouse_name;
74
75
76
77 static void DoWarning (void)
78 /* Warn the user that a driver is needed for this program. */
79 {
80     cprintf ("Warning: This program needs\r\n"
81              "the driver with the name\r\n"
82              "    %s\r\n"
83              "on a disk! Press 'y' if you have it;\r\n"
84              "or, any other key to exit.\r\n", mouse_stddrv);
85     if (tolower (cgetc ()) != 'y') {
86         exit (EXIT_SUCCESS);
87     }
88     cprintf ("OK. Please wait patiently...\r\n");
89 }
90 #endif
91
92
93
94 static void __fastcall__ ShowState (unsigned char Jailed, unsigned char Invisible)
95 /* Display jail and cursor states. */
96 {
97     cclearxy (0, 7, 32);
98     gotoxy (0, 7);
99     cprintf ("Pointer is %svisible%s.", Invisible? "in" : "", Jailed? " and jailed" : "");
100 }
101
102
103
104 #if DYN_DRV
105 int main (int argc, char *argv[])
106 #else
107 int main (void)
108 #endif
109 {
110     struct mouse_info info;
111     struct mouse_box full_box, small_box;
112     unsigned char width, height;
113     char C;
114     bool Invisible = true, Done = false, Jailed = false;
115
116     /* Initialize the debugger */
117     DbgInit (0);
118
119     /* Set dark-on-light colors.  Clear the screen. */
120 #ifdef __CBM__
121     (void) bordercolor (COLOR_GRAY2);
122     (void) bgcolor (COLOR_WHITE);
123     (void) textcolor (COLOR_GRAY1);
124 #else
125     (void) bordercolor (COLOR_BLUE);
126     (void) bgcolor (COLOR_WHITE);
127     (void) textcolor (COLOR_BLACK);
128 #endif
129     cursor (0);
130     clrscr ();
131
132     /* If a lightpen driver is installed, then it can get a calibration value
133     ** from this file (if it exists).  Or, the user can adjust the pen; and,
134     ** the value will be put into this file, for the next time.
135     ** (Other drivers will ignore this.)
136     */
137 #if defined(__C64__) || defined(__C128__) || defined(__CBM510__)
138     pen_adjust ("pen.dat");
139 #endif
140
141 #if DYN_DRV
142     /* If a dynamically loadable driver is named on the command line,
143     ** then use that driver instead of the standard one.
144     */
145     if (argc > 1) {
146         mouse_name = argv[1];
147     } else {
148         /* Output a warning about the standard driver that is needed. */
149         DoWarning ();
150         mouse_name = mouse_stddrv;
151     }
152
153     /* Load and install the driver. */
154     CheckError ("mouse_load_driver",
155                 mouse_load_driver (&mouse_def_callbacks, mouse_name));
156 #else
157     /* Install the driver. */
158     CheckError ("mouse_install",
159                 mouse_install (&mouse_def_callbacks,
160 #  ifdef MOUSE_DRIVER
161                                MOUSE_DRIVER
162 #  else
163                                mouse_static_stddrv
164 #  endif
165                                ));
166 #endif
167
168     /* Get the initial bounding box. */
169     mouse_getbox (&full_box);
170
171     screensize (&width, &height);
172
173 top:
174     clrscr ();
175
176     /* Print a help line */
177     cputs (" d)ebug  h)ide   q)uit   s)how   j)ail");
178
179     /* Put a cross at the center of the screen. */
180     gotoxy (width / 2 - 3, height / 2 - 1);
181 #if defined(__CBM__)
182     cprintf ("%3u,%3u\r\n%*s\xDB", width / 2 * 8 + 4, height / 2 * 8 + 4,
183              width / 2, "");
184 #else
185     cprintf ("%3u,%3u\r\n%*s+", width / 2 * 8 + 4, height / 2 * 8 + 4,
186              width / 2, "");
187 #endif
188
189     /* Test loop */
190     ShowState (Jailed, Invisible);
191     do {
192         /* Get the current co-ordinates and button states; and, print them. */
193         mouse_info (&info);
194         gotoxy (0, 2);
195         cprintf (" X  = %3d\r\n", info.pos.x);
196         cprintf (" Y  = %3d\r\n", info.pos.y);
197         cprintf (" B1 = %c\r\n", (info.buttons & MOUSE_BTN_LEFT) ?
198 #ifdef __CBM__
199                  0x5F
200 #else
201                  'v'
202 #endif
203                  : '^');
204         cprintf (" B2 = %c", (info.buttons & MOUSE_BTN_RIGHT) ?
205 #ifdef __CBM__
206                  0x5F
207 #else
208                  'v'
209 #endif
210                  : '^');
211
212         /* Handle user input */
213         if (kbhit ()) {
214             cclearxy (1, 9, 23);
215             switch (tolower (C = cgetc ())) {
216                 case 'd':
217                     BREAK();
218
219                     /* The debugger might have changed the colors.
220                     ** Restore them.
221                     */
222 #ifdef __CBM__
223                     (void) bordercolor (COLOR_GRAY2);
224                     (void) bgcolor (COLOR_WHITE);
225                     (void) textcolor (COLOR_GRAY1);
226 #else
227                     (void) bordercolor (COLOR_BLUE);
228                     (void) bgcolor (COLOR_WHITE);
229                     (void) textcolor (COLOR_BLACK);
230 #endif
231
232                     /* The debugger changed the screen; restore it. */
233                     goto top;
234
235                 case 'h':
236                     mouse_hide ();
237                     ShowState (Jailed, ++Invisible);
238                     break;
239
240                 case 'j':
241                     if (Jailed) {
242                         mouse_setbox (&full_box);
243                         Jailed = false;
244                     } else {
245                         small_box.minx = max (info.pos.x - 10, full_box.minx);
246                         small_box.miny = max (info.pos.y - 10, full_box.miny);
247                         small_box.maxx = min (info.pos.x + 10, full_box.maxx);
248                         small_box.maxy = min (info.pos.y + 10, full_box.maxy);
249                         mouse_setbox (&small_box);
250                         Jailed = true;
251                     }
252                     ShowState (Jailed, Invisible);
253                     break;
254
255                 case 's':
256                     mouse_show ();
257                     if (Invisible) {
258                         ShowState (Jailed, --Invisible);
259                     }
260                     break;
261
262                 case 'q':
263                     Done = true;
264                     break;
265
266                 default:
267                     gotoxy (1, 9);
268                     cprintf ("Spurious character: $%02X", C);
269             }
270         }
271     } while (!Done);
272
273 #if DYN_DRV
274     /* Uninstall and unload the driver. */
275     CheckError ("mouse_unload", mouse_unload ());
276 #else
277     /* Uninstall the static driver. */
278     CheckError ("mouse_uninstall", mouse_uninstall ());
279 #endif
280
281     /* Say goodbye */
282     cputsxy (0, height / 2 + 3, "Goodbye!");
283     return EXIT_SUCCESS;
284 }