+/*\r
+** Calibrate lightpen drivers to the current video hardware.\r
+**\r
+** 2013-06-17, Greg King\r
+**\r
+*/\r
+\r
+\r
+#include <conio.h>\r
+#include <mouse.h>\r
+\r
+\r
+#define COMMAND1 "Adjust by clicking on line."\r
+#define COMMAND2 "Finish by clicking off bar."\r
+\r
+\r
+/*\r
+** There is a delay between when the VIC sends its signal, and when the display\r
+** shows that signal. There is another delay between the display and when\r
+** the lightpen says that it saw that signal. Each display and pen is different.\r
+** Therefore, the driver must be calibrated to them. A white bar is painted on\r
+** the screen; and, a line is drawn down the middle of it. When the user clicks\r
+** on that line, the difference between its position and where the VIC thinks\r
+** that the pen is pointing becomes an offset that is subtracted from what the\r
+** VIC sees.\r
+*/\r
+void __fastcall__ pen_calibrate (unsigned char *XOffset)\r
+{\r
+ unsigned char oldBg = bgcolor (COLOR_BLUE);\r
+ unsigned char oldText = textcolor (COLOR_GRAY3);\r
+ unsigned char oldRev = revers (1);\r
+ unsigned char sprite0Color = VIC.spr_color[0];\r
+ unsigned char width, width2, height, height4, height8;\r
+ struct mouse_info info;\r
+\r
+ screensize (&width, &height);\r
+ width2 = width / 2;\r
+ height4 = height / 4;\r
+ height8 = height4 * 8;\r
+\r
+ /* Draw a bar and line. */\r
+\r
+ clrscr ();\r
+ cclearxy (0, height4, height4 * width);\r
+ cvlinexy (width2, height4 + 1, height4 - 2);\r
+ revers (0);\r
+\r
+ /* Print instructions. */\r
+\r
+ cputsxy (width2 - (sizeof COMMAND1) / 2, height / 2 + 1, COMMAND1);\r
+ cputsxy (width2 - (sizeof COMMAND2) / 2, height / 2 + 3, COMMAND2);\r
+\r
+ VIC.spr_color[0] = COLOR_GRAY2;\r
+ mouse_show ();\r
+ mouse_move (width2 * 8, height8 / 2);\r
+\r
+ for (;;) {\r
+ /* Wait for the main button to be released. */\r
+\r
+ do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));\r
+\r
+ /* Wait for the main button to be pressed. */\r
+\r
+ do {\r
+ mouse_info (&info);\r
+ } while (!(info.buttons & MOUSE_BTN_LEFT));\r
+\r
+ /* Find out if the pen is on or off the bar. */\r
+\r
+ if (info.pos.y < height8 || info.pos.y >= height8 * 2) {\r
+ break;\r
+ }\r
+\r
+ /* On the bar; adjust the offset. */\r
+ /* Characters are eight pixels wide.\r
+ ** The VIC-II sees every other pixel;\r
+ ** so, we use half of the difference.\r
+ */\r
+\r
+ *XOffset += (info.pos.x - (width2 * 8 + 8/2)) / 2;\r
+ }\r
+\r
+ /* Off the bar; wait for the main button to be released. */\r
+\r
+ do ; while ((mouse_buttons () & MOUSE_BTN_LEFT));\r
+\r
+ mouse_hide ();\r
+ VIC.spr_color[0] = sprite0Color;\r
+ revers (oldRev);\r
+ textcolor (oldText);\r
+ bgcolor (oldBg);\r
+ clrscr ();\r
+}\r