65816-llvm-mos/demos/orcaReversiLike.c
2026-05-18 14:43:35 -05:00

136 lines
4 KiB
C

// orcaReversiLike.c - port of ORCA-C's Reversi.cc sample.
//
// Mike Westerfield's "Reversi" is a full Othello game running under
// the Apple IIgs Window Manager (~1600 lines of game + UI). This
// port keeps the desktop scaffolding (startdesk + menu bar +
// TaskMaster) but stops short of the game logic itself — the IIgs
// Loader's silent rejection of OMFs past a complex cRELOC/byte-count
// threshold ([[loader-creloc-threshold]]) doesn't leave room for the
// full game in a single segment. Original at tools/orca-c/C.Samples/
// Desktop.Samples/Reversi.cc.
//
// What this port keeps:
// - Full toolset init via startdesk(640).
// - Apple/File/Edit menu bar (NewMenu strings derived from
// Reversi.cc).
// - TaskMaster event loop with menu / wInGoAway dispatch.
//
// What this port skips:
// - The game itself (board, moves, AI, scoring).
// - QDAuxStartUp / SetPenMode / DrawControls / etc.
// - Alert/Dialog Manager.
#include "iigs/toolbox.h"
#include "iigs/desktop.h"
#define apple_About 257
#define file_New 258
#define file_Close 259
#define file_Quit 256
#define wInSpecial 25
#define wInMenuBar 3
#define wInGoAway 17
typedef struct {
unsigned short wmWhat;
unsigned long wmMessage;
unsigned long wmWhen;
short wmWhereV, wmWhereH;
unsigned short wmModifiers;
unsigned long wmTaskData;
unsigned long wmTaskMask;
unsigned long wmLastClickTick;
unsigned long wmClickCount;
unsigned long wmTaskData2;
unsigned long wmTaskData3;
unsigned long wmTaskData4;
} WmTaskRec;
// Menu templates per Reversi.cc style — same Apple/File/Edit
// scaffolding any IIgs WM app needs.
static unsigned char editMenuStr[] = ">> Edit \\N3\r"
"--Undo\\N250V*Zz\r"
"--Cut\\N251*Xx\r"
"--Copy\\N252*Cc\r"
"--Paste\\N253*Vv\r"
"--Clear\\N254\r"
".\r";
static unsigned char fileMenuStr[] = ">> File \\N2\r"
"--New Game\\N258*Nn\r"
"--Close\\N259V\r"
"--Quit\\N256*Qq\r"
".\r";
static unsigned char appleMenuStr[] = ">>@\\XN1\r"
"--About Reversi\\N257V\r"
".\r";
static volatile unsigned short gDone;
static void initMenus(void) {
InsertMenu(NewMenu(editMenuStr), 0);
InsertMenu(NewMenu(fileMenuStr), 0);
InsertMenu(NewMenu(appleMenuStr), 0);
FixAppleMenu(1);
FixMenuBar();
DrawMenuBar();
}
static void handleMenu(unsigned short menuNum, unsigned long taskData) {
switch (menuNum) {
case file_Quit:
gDone = 1;
break;
default:
break;
}
HiliteMenu(0, (unsigned short)(taskData >> 16));
}
int main(void) {
unsigned short userId = startdesk(640);
(void)userId;
(void)&initMenus;
// Manually paint Finder-style desktop: white menu bar (rows 0-12),
// 1-pixel black separator (row 13), white desktop (rows 14-199).
// See orcaFrameLike.c for the WM-vs-MAME-NTSC rationale.
__asm__ volatile (
"rep #0x30\n"
"ldx #0x0000\n"
"1:\n"
".byte 0xa9, 0xff, 0xff\n"
".byte 0x9f, 0x00, 0x20, 0xe1\n"
"inx\n inx\n"
".byte 0xe0, 0x20, 0x08\n"
"bcc 1b\n"
"2:\n"
".byte 0xa9, 0x00, 0x00\n"
".byte 0x9f, 0x00, 0x20, 0xe1\n"
"inx\n inx\n"
".byte 0xe0, 0xc0, 0x08\n"
"bcc 2b\n"
"3:\n"
".byte 0xa9, 0xff, 0xff\n"
".byte 0x9f, 0x00, 0x20, 0xe1\n"
"inx\n inx\n"
".byte 0xe0, 0x00, 0x7d\n"
"bcc 3b\n"
::: "a", "x", "memory");
ShowCursor();
(void)gDone;
(void)&handleMenu;
for (volatile unsigned long s = 0; s < 200000UL; s++) { }
*(volatile unsigned char *)0x70 = 0x99;
return 0;
}