pendulum68k/main.c

1 line
4.3 KiB
C
Raw Permalink Normal View History

2019-04-03 20:54:48 +00:00
#include <math.h> #include "common.h" #include "pendulum.h" #include "pendMenu.h" #include "pendDialog.h" #define SET_RECT(R,t,l,b,r) \ do { (R).top = (t); (R).left = (l); (R).bottom = (b); (R).right = (r); } while(0) #define THETA (M_PI / 3) #define D_THETA (0) #define MU 0.1 #define LEN 2 #define GRAV 9.8 extern Boolean running = true; extern Boolean resetting = true; extern Boolean paused = false; extern Boolean forceRedraw = false; extern struct dialog_prefs_t pendPrefs = { THETA, D_THETA, MU, LEN, GRAV }; Rect WINDOW_RECT = {50, 50, 250, 250}; char WINDOW_NAME[] = "\pPendulum"; WindowPtr pendWindow; struct pendulum_t thePend; static Rect dragRect; /* const */ static void InitMacintosh(void); static void ExitError(void); static long HandleEvent(int eventMask); static void HandleMouseDown(EventRecord *theEvent); static void WaitTicks(unsigned qty); static void WindowCreate(void); static void WindowDrawContent(WindowPtr theWin, double angle, Boolean force); static int iround(double n) { double ipart, fpart; int sign; fpart = modf(n, &ipart); sign = (n >= 0 ? 1 : -1); if(fabs(fpart) >= 0.5) return (int)(ipart) + sign; return (int) ipart; } void InitMacintosh(void) { MaxApplZone(); InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(0L); FlushEvents(everyEvent, 0); InitCursor(); } void ExitError(void) { SysBeep(1); ExitToShell(); } void WaitTicks(unsigned qty) { static long lastTick = 0; if(qty == 0) return; while(--qty) { while(lastTick == Ticks) { HandleEvent(updateMask); HandleEvent(everyEvent); } } lastTick = Ticks; } long HandleEvent(int eventMask) { int res; EventRecord theEvent; HiliteMenu(0); SystemTask(); /* Handle desk accessories */ if (!GetNextEvent(eventMask, &theEvent)) return; switch (theEvent.what) { case mouseDown: HandleMouseDown(&theEvent); break; case keyDown: if(theEvent.modifiers & cmdKey) { MenuEvent(MenuKey(theEvent.message & 0xFF)); } /* FALLTHROUGH */ case autoKey: break; case activateEvt: if(theEvent.modifiers & activeFlag) { MenuEditMode(false); paused = 0; } else { MenuEditMode(true); paused = 1; } break; case updateEvt: WindowDrawContent((WindowPtr) theEvent.message, thePend.theta, paused || forceRedraw); forceRedraw = false; break; } } void HandleMouseDown(EventRecord *theEvent) { WindowPtr theWindow; int windowCode = FindWindow(theEvent->where, &theWindow); switch (windowCode) { case inSysWindow: SystemClick (theEvent, theWindow); break; case inDrag: DragWindow(theWindow, theEvent->where, &dragRect); break; case inMenuBar: MenuEvent(MenuSelect(theEvent->where)); break; case inContent: if(theWindow != FrontWindow()) { SelectWindow(theWindow); } break; case inGoAway: if(TrackGoAway(theWindow, theEvent->where)) { HideWindow(theWindow); running = false; } break; } } void WindowCreate(void) { pendWindow = NewWindow(0L, &WINDOW_RECT, WINDOW_NAME, true, noGrowDocProc, (WindowPtr) -1L, true, 0); if(!pendWindow) ExitError(); } void WindowDrawContent(WindowPtr theWin, double angle, Boolean force) { static Point lastPoint = {0, 0}; Rect BallRect = {0, 0, 25, 25}; Point lineEnd; lineEnd.h = 100 + iround(75.0 * sin(angle)); lineEnd.v = 100 + iround(75.0 * cos(angle)); if(!force && lastPoint.h == lineEnd.h && lastPoint.v == lineEnd.v) { return; } /*HideCursor();*/ BeginUpdate(theWin); EraseRect(&theWin->portRect); MoveTo(100, 100); LineTo(lineEnd.h, lineEnd.v); OffsetRect(&BallRect, lineEnd.h - 12, lineEnd.v - 12); PaintRoundRect(&BallRect, 25, 25); EndUpdate(theWin); /*ShowCursor();*/ lastPoint.h = lineEnd.h; lastPoint.v = lineEnd.v; } int main(void) { InitMacintosh(); WindowCreate(); MenuCreate(); SetPort(pendWindow); SET_RECT(dragRect, 4, 24, screenBits.bounds.right-4, screenBits.bounds.bottom-4); thePend.timestep = 1.0/20.0; while(running) { if(resetting) { thePend.theta = pendPrefs.thet