Add support for a mouse. Add a license.

This commit is contained in:
Jeremy Rand 2018-06-24 23:42:40 -04:00
parent e24a32f86a
commit ccf77c65f1
8 changed files with 342 additions and 186 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 Jeremy Rand
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
9D3B394020E082580055431C /* mouseWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D3B393E20E082580055431C /* mouseWrapper.c */; };
9D3FF4AF20DA05C2006A5F8A /* AppleCommander.jar in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D3FF4AE20DA05C2006A5F8A /* AppleCommander.jar */; };
9D3FF4B120DA05C2006A5F8A /* createDiskImage in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9D3FF4B020DA05C2006A5F8A /* createDiskImage */; };
9D3FF4B320DA05C2006A5F8A /* DevApple.vii in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9D3FF4B220DA05C2006A5F8A /* DevApple.vii */; };
@ -44,6 +45,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
9D3B393D20E0821B0055431C /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
9D3B393E20E082580055431C /* mouseWrapper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mouseWrapper.c; sourceTree = "<group>"; };
9D3B393F20E082580055431C /* mouseWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mouseWrapper.h; sourceTree = "<group>"; };
9D3FF4A620DA05C2006A5F8A /* doNotBuild */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = doNotBuild; sourceTree = BUILT_PRODUCTS_DIR; };
9D3FF4AE20DA05C2006A5F8A /* AppleCommander.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; name = AppleCommander.jar; path = make/AppleCommander.jar; sourceTree = "<group>"; };
9D3FF4B020DA05C2006A5F8A /* createDiskImage */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = createDiskImage; path = make/createDiskImage; sourceTree = "<group>"; };
@ -85,6 +89,7 @@
children = (
9D3FF4CA20DA05E4006A5F8A /* a2sudoku.png */,
9D3FF4C920DA05E3006A5F8A /* README.md */,
9D3B393D20E0821B0055431C /* LICENSE */,
9D3FF4A820DA05C2006A5F8A /* a2sudoku */,
9D3FF4A720DA05C2006A5F8A /* Products */,
);
@ -107,6 +112,8 @@
9D3FF4CC20DA05F2006A5F8A /* main.c */,
9D3FF4CF20DA05F3006A5F8A /* ui.c */,
9D3FF4D420DA05F3006A5F8A /* ui.h */,
9D3B393E20E082580055431C /* mouseWrapper.c */,
9D3B393F20E082580055431C /* mouseWrapper.h */,
9D3FF4DA20DA0622006A5F8A /* puzzles */,
9D3FF4AD20DA05C2006A5F8A /* make */,
9D3FF4BE20DA05C2006A5F8A /* Supporting Files */,
@ -227,6 +234,7 @@
9D3FF4D920DA05F3006A5F8A /* Makefile in Sources */,
9D3FF4D620DA05F3006A5F8A /* main.c in Sources */,
9D3FF4D820DA05F3006A5F8A /* game.c in Sources */,
9D3B394020E082580055431C /* mouseWrapper.c in Sources */,
9D3FF4D720DA05F3006A5F8A /* ui.c in Sources */,
9D3FF4D520DA05F3006A5F8A /* puzzles.c in Sources */,
);

View File

@ -151,7 +151,7 @@ DRIVERS += hiresgr
# If you want to link the mouse driver with your executable,
# uncomment the next line.
# DRIVERS += mouse
DRIVERS += mouse
#
# To use the mouse driver, add code which looks like this to your
# project:

Binary file not shown.

79
a2sudoku/mouseWrapper.c Normal file
View File

@ -0,0 +1,79 @@
//
// mouseWrapper.c
// a2sudoku
//
// Created by Jeremy Rand on 2018-06-24.
// Copyright © 2018 Jeremy Rand. All rights reserved.
//
#include "mouseWrapper.h"
#include "drivers/a2_mouse_drv.h"
// Defines and macros
#define MOUSE_POS_SHIFT 4
#define MOUSE_GRID_SIZE (BOARD_SIZE << MOUSE_POS_SHIFT)
// Globals
static tMouseCallback gCursorPosCallback = NULL;
static bool gMouseInstalled = false;
static bool gMouseInPoll = false;
static struct mouse_box gMouseBox = { 0, 0, MOUSE_GRID_SIZE - 1, MOUSE_GRID_SIZE - 1 };
// Implementation
bool initMouse(tMouseCallback callback)
{
if (!gMouseInstalled) {
if (mouse_install(&mouse_def_callbacks, &a2_mouse_drv) == 0) {
gMouseInstalled = true;
mouse_setbox(&gMouseBox);
moveMouseToPos(0, 0);
}
}
gCursorPosCallback = callback;
return gMouseInstalled;
}
void shutdownMouse(void)
{
if (gMouseInstalled) {
mouse_uninstall();
gMouseInstalled = false;
}
}
void pollMouse(void)
{
struct mouse_info mouseInfo;
if (!gMouseInstalled)
return;
mouse_info(&mouseInfo);
gMouseInPoll = true;
gCursorPosCallback(mouseInfo.pos.x >> MOUSE_POS_SHIFT,
mouseInfo.pos.y >> MOUSE_POS_SHIFT);
gMouseInPoll = false;
}
void moveMouseToPos(tPos newX, tPos newY)
{
if (!gMouseInstalled)
return;
if (gMouseInPoll)
return;
mouse_move(newX << MOUSE_POS_SHIFT, newY << MOUSE_POS_SHIFT);
}

30
a2sudoku/mouseWrapper.h Normal file
View File

@ -0,0 +1,30 @@
//
// mouseWrapper.h
// a2sudoku
//
// Created by Jeremy Rand on 2018-06-24.
// Copyright © 2018 Jeremy Rand. All rights reserved.
//
#ifndef _GUARD_PROJECTa2sudoku_FILEmouseWrapper_
#define _GUARD_PROJECTa2sudoku_FILEmouseWrapper_
#include <stdbool.h>
#include "puzzles.h"
// Typedefs
typedef void (*tMouseCallback)(tPos newX, tPos newY);
// API
extern bool initMouse(tMouseCallback callback);
extern void shutdownMouse(void);
extern void pollMouse(void);
extern void moveMouseToPos(tPos newX, tPos newY);
#endif /* define _GUARD_PROJECTa2sudoku_FILEmouseWrapper_ */

View File

@ -16,6 +16,7 @@
#include "game.h"
#include "ui.h"
#include "mouseWrapper.h"
#include "drivers/a2_hires_drv.h"
@ -118,6 +119,31 @@ void drawGrid(void)
}
void setCursorPos(tPos newX, tPos newY)
{
tPos oldX = cursorX;
tPos oldY = cursorY;
if (newX >= BOARD_SIZE)
newX = BOARD_SIZE - 1;
if (newY >= BOARD_SIZE)
newY = BOARD_SIZE - 1;
if ((cursorX == newX) &&
(cursorY == newY))
return;
cursorX = newX;
cursorY = newY;
refreshPos(cursorX, cursorY);
refreshPos(oldX, oldY);
moveMouseToPos(cursorX, cursorY);
}
void initUI(void)
{
static bool tgi_inited = false;
@ -131,6 +157,8 @@ void initUI(void)
tgi_init();
tgi_inited = true;
initMouse(setCursorPos);
}
@ -166,6 +194,7 @@ void shutdownUI(void)
{
// Uninstall drivers
tgi_uninstall();
shutdownMouse();
}
@ -269,8 +298,8 @@ void displayInstructions(void)
"\n"
"The goal is to get the numbers from 1 to"
"9 uniquely in each column, row and 3x3\n"
"subsquare. Move the cursor with I-J-K-L"
"or the arrow keys. Press a number key\n"
"subsquare. Move the cursor with arrow\n"
"keys, IJKM or mouse. Press a number key"
"to enter a value. Press a number key\n"
"while holding shift or open apple to\n"
"toggle a scratch value. Press 0 to\n"
@ -592,191 +621,180 @@ bool playGame(void)
graphicsMode();
while (true) {
bool shouldNotBeep = true;
pollMouse();
if (isPuzzleSolved()) {
youWon();
return true;
}
ch = cgetc();
switch (ch) {
case 'h':
case 'H':
textMode();
displayInstructions();
graphicsMode();
break;
case 'o':
case 'O':
textMode();
if (setOptions())
refreshAllPos();
graphicsMode();
break;
case 'r':
case 'R':
shouldSave = false;
restartGame();
break;
case 'n':
case 'N':
if (kbhit()) {
bool shouldNotBeep = true;
ch = cgetc();
switch (ch) {
case 'h':
case 'H':
textMode();
displayInstructions();
graphicsMode();
break;
case 'o':
case 'O':
textMode();
if (setOptions())
refreshAllPos();
graphicsMode();
break;
case 'r':
case 'R':
shouldSave = false;
restartGame();
break;
case 'n':
case 'N':
return true;
case 'q':
case 'Q':
case CH_ESC:
shutdownUI();
if (shouldSave) {
clrscr();
printf("\n\nSaving your puzzle so you can continue\n later...");
saveGame();
}
return false;
case 'i':
case 'I':
case 0x0B: // Only defined with apple2enh targts, CH_CURS_UP:
if (cursorY != 0) {
setCursorPos(cursorX, cursorY - 1);
} else {
setCursorPos(cursorX, BOARD_SIZE - 1);
}
break;
case 'j':
case 'J':
case CH_CURS_LEFT:
if (cursorX != 0) {
setCursorPos(cursorX - 1, cursorY);
} else {
setCursorPos(BOARD_SIZE - 1, cursorY);
}
break;
case 'k':
case 'K':
case CH_CURS_RIGHT:
if (cursorX < BOARD_SIZE - 1) {
setCursorPos(cursorX + 1, cursorY);
} else {
setCursorPos(0, cursorY);
}
break;
case 'm':
case 'M':
case 0x0A: // Only defined with apple2enh targts, CH_CURS_DOWN:
if (cursorY < BOARD_SIZE - 1) {
setCursorPos(cursorX, cursorY + 1);
} else {
setCursorPos(cursorX, 0);
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (*button0 > 127)
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, ch - '0');
else
shouldNotBeep = setValueAtPos(cursorX, cursorY, ch - '0');
if (shouldNotBeep)
shouldSave = true;
break;
case '!':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 1);
if (shouldNotBeep)
shouldSave = true;
break;
case '@':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 2);
if (shouldNotBeep)
shouldSave = true;
break;
case '#':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 3);
if (shouldNotBeep)
shouldSave = true;
break;
case '$':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 4);
if (shouldNotBeep)
shouldSave = true;
break;
case '%':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 5);
if (shouldNotBeep)
shouldSave = true;
break;
case '^':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 6);
if (shouldNotBeep)
shouldSave = true;
break;
case '&':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 7);
if (shouldNotBeep)
shouldSave = true;
break;
case '*':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 8);
if (shouldNotBeep)
shouldSave = true;
break;
case '(':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 9);
if (shouldNotBeep)
shouldSave = true;
break;
case 'u':
case 'U':
shouldNotBeep = undoLastMove();
break;
default:
shouldNotBeep = false;
break;
}
if (!shouldNotBeep) {
printf("\007");
}
if (isPuzzleSolved()) {
youWon();
return true;
case 'q':
case 'Q':
case CH_ESC:
shutdownUI();
if (shouldSave) {
clrscr();
printf("\n\nSaving your puzzle so you can continue\n later...");
saveGame();
}
return false;
case 'i':
case 'I':
case 0x0B: // Only defined with apple2enh targts, CH_CURS_UP:
if (cursorY != 0) {
cursorY--;
refreshPos(cursorX, cursorY);
refreshPos(cursorX, cursorY + 1);
} else {
cursorY = BOARD_SIZE - 1;
refreshPos(cursorX, cursorY);
refreshPos(cursorX, 0);
}
break;
case 'j':
case 'J':
case CH_CURS_LEFT:
if (cursorX != 0) {
cursorX--;
refreshPos(cursorX, cursorY);
refreshPos(cursorX + 1, cursorY);
} else {
cursorX = BOARD_SIZE - 1;
refreshPos(cursorX, cursorY);
refreshPos(0, cursorY);
}
break;
case 'k':
case 'K':
case CH_CURS_RIGHT:
if (cursorX < BOARD_SIZE - 1) {
cursorX++;
refreshPos(cursorX, cursorY);
refreshPos(cursorX - 1, cursorY);
} else {
cursorX = 0;
refreshPos(cursorX, cursorY);
refreshPos(BOARD_SIZE - 1, cursorY);
}
break;
case 'm':
case 'M':
case 0x0A: // Only defined with apple2enh targts, CH_CURS_DOWN:
if (cursorY < BOARD_SIZE - 1) {
cursorY++;
refreshPos(cursorX, cursorY);
refreshPos(cursorX, cursorY - 1);
} else {
cursorY = 0;
refreshPos(cursorX, cursorY);
refreshPos(cursorX, BOARD_SIZE - 1);
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (*button0 > 127)
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, ch - '0');
else
shouldNotBeep = setValueAtPos(cursorX, cursorY, ch - '0');
if (shouldNotBeep)
shouldSave = true;
break;
case '!':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 1);
if (shouldNotBeep)
shouldSave = true;
break;
case '@':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 2);
if (shouldNotBeep)
shouldSave = true;
break;
case '#':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 3);
if (shouldNotBeep)
shouldSave = true;
break;
case '$':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 4);
if (shouldNotBeep)
shouldSave = true;
break;
case '%':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 5);
if (shouldNotBeep)
shouldSave = true;
break;
case '^':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 6);
if (shouldNotBeep)
shouldSave = true;
break;
case '&':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 7);
if (shouldNotBeep)
shouldSave = true;
break;
case '*':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 8);
if (shouldNotBeep)
shouldSave = true;
break;
case '(':
shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 9);
if (shouldNotBeep)
shouldSave = true;
break;
case 'u':
case 'U':
shouldNotBeep = undoLastMove();
break;
default:
shouldNotBeep = false;
break;
}
if (!shouldNotBeep) {
printf("\007");
}
}
}