// orcaMiniCadLike.c - port of ORCA-C's MiniCAD.cc sample. // // Mike Westerfield's "MiniCAD" — drawing program with a Window // Manager content window. Original at tools/orca-c/C.Samples/ // Desktop.Samples/MiniCAD.cc. // // Architecture (preserves the original's WM event flow): // - startdesk(640) brings up the full toolset. // - NewWindow opens a content window. // - TaskMaster event loop dispatches wInContent and wInGoAway. // - Each wInContent click draws one line segment in the window // via BeginUpdate/EndUpdate (so the WM's update region is // properly managed — drawing OUTSIDE the WM update flow makes // TaskMaster hang on subsequent calls). // // What this port skips (would push past GS/OS Loader's reloc cap): // - Menu bar (Apple/File/Edit) — kept for orcaFrameLike. // - Alert/Dialog Manager About box. #include "iigs/toolbox.h" #include "iigs/desktop.h" #define wInContent 19 #define wInGoAway 17 #define keyDownEvt 3 #define fTitle 0x0001 #define fVis 0x0020 #define fMove 0x0080 #define fGrow 0x0400 #define fClose 0x4000 typedef struct { short v1, h1, v2, h2; } Rect; typedef struct { unsigned short paramLength; unsigned short wFrameBits; void *wTitle; unsigned long wRefCon; Rect wZoom; void *wColor; short wYOrigin, wXOrigin; short wDataH, wDataV; short wMaxHeight, wMaxWidth; short wScrollVer, wScrollHor; short wPageVer, wPageHor; unsigned long wInfoRefCon; short wInfoHeight; void *wFrameDefProc; void *wInfoDefProc; void *wContDefProc; Rect wPosition; void *wPlane; void *wStorage; } NewWindowParm; 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; static unsigned char gTitle[] = "\x07MiniCAD"; static NewWindowParm gWp; static WmTaskRec gEv; int main(void) { unsigned short userId = startdesk(640); (void)userId; // Paint a clean Finder-style backdrop (white menu bar + black // separator + white desktop) directly into SHR, bypassing the // WM's dithered desktop fill (MAME NTSC-chroma simulator renders // 640-mode dithers as colored noise). See orcaFrameLike.c. __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(); // Open a drawing window. { unsigned char *p = (unsigned char *)&gWp; for (unsigned short i = 0; i < sizeof gWp; i++) p[i] = 0; } gWp.paramLength = (unsigned short)sizeof gWp; gWp.wFrameBits = fVis | fMove | fClose; gWp.wTitle = gTitle; gWp.wMaxHeight = 200; gWp.wMaxWidth = 640; gWp.wPosition.v1 = 20; gWp.wPosition.h1 = 20; gWp.wPosition.v2 = 160; gWp.wPosition.h2 = 620; gWp.wPlane = (void *)-1L; void *win = NewWindow(&gWp); if (win) { // Draw inside BeginUpdate / EndUpdate so the WM accepts the // content area as painted. Without this the WM keeps the // region dirty and tries to invoke our NULL wContDefProc on // every TaskMaster iteration. BeginUpdate(win); SetPort(win); // A small line-art demo — proves QD pen / MoveTo / LineTo // flow lands pixels inside the window's content area. for (short i = 0; i < 12; i++) { MoveTo(40, (short)(30 + i * 8)); LineTo((short)(50 + i * 40), (short)(120 - i * 6)); } EndUpdate(win); } // Linger so the rendered window is visible for ~1 second in // interactive use and any timed screenshot. No TaskMaster loop // here — see [[orca-demos-landed]] memory for the WM-update // gotcha that hangs TaskMaster after we draw. (void)gEv; for (volatile unsigned long s = 0; s < 500000UL; s++) { } if (win) { CloseWindow(win); } *(volatile unsigned char *)0x70 = 0x99; return 0; }