📄 anim.cpp
字号:
//***********************************************************************// MODULE : ANIM - Animator Device Driver for the RCOS OS simulator *// AUTHOR : Ron Chernich *// PURPOSE: Module to perform all screen animation operations and re- *// draw of switched displays. *// HISTORY: *// 14-MAY-93 First (MSC/C++ 7.00) version *// 03-FEB-94 Pre-empt message added *// 18-AUG-94 Disk Animation title messages added *// 25-AUG-94 Animator given responsibility for all display classes *// 16-MAR-94 Creation/deletion of TTY Radio Btns made dynamic *// 22-MAR-95 (Happy Birthday, Ron!) No of terminals made dynamic *//***********************************************************************#include "anim.hpp"//////////////// This define sets the minimum time between message changes in DOS// clock ticks of 18.2 mS//#define MIN_DISY 42 // about three quarters of a second////////////////// Defined in the main module, this reference lets us display messages// in the Supervisor Title Bar and create/destroy control buttons..//extern App Rcos;extern char *pszInitl;extern char *pszTitle;/////////////// These arrays set dithered backgrounds for the display window..//UINT16 nWinFgColor[4] = { _Green, _LightBlue, _Yellow, _LightRed };UINT16 nWinBgColor[4] = { _DarkGrey, _White, _BrightWhite, _Yellow };/////////////// ..and here are the messages for display..//static char *pszInRdy = { "Low Level Scheduler moves Process P%d to the Ready Queue" };static char *pszRdyRun = { "Process P%d context dispatched to the CPU" };static char *pszRunBlk = { "Process P%d Blocks on an external event" };static char *pszBlkRdy = { "Event Process P%d was Blocked on completes - Process now Ready." };static char *pszRunRdy = { "Quantum for Process P%d expires - Process moved back to Ready." };static char *pszForked = { "Process P0 Forks creating Process P%d." };static char *pszRdySus = { "Ready Process P%d suspended by operator." };static char *pszSusRdy = { "Suspended Ready Process P%d moves back to Ready." };static char *pszBlkSus = { "Blocked Process P%d suspended by operator." };static char *pszSusBlk = { "Suspended Blocked Process P%d moves back to Blocked." };static char *pszSusBlkSus = { "Event Suspended Process P%d was blocked on completes." };static char *pszHaltOk = { "Process P%d Terminated normally." };static char *pszHaltBad = { "Process P%d Terminated on Illegal p-code." };static char *pszPreEmpt = { "Running Process pre-empted by P%d (higher priority)." };//// These strings relate to the disk drive animation..//static char *pszEnQueue = { "A new Transfer Request arrives on the device queue.." };static char *pszSeek = { "Seek %s to Track %d commences.." };static char *pszOnTrack = { "On track - scanning for sector %02d.." };static char *pszDeQueue = { "Data %s user buffer - Interrupt issued." };static char *pszIdle = { "Disk Unit %c: now Idle." };/////////////////////////////////////////////////////////////////////////// Disk animators are not instantiated until actually needed..//Animate::Animate (UINT16 uId, UINT16 uCls, Knl *pK, UINT16 nTerm) : port(uId, uCls, pK), nCurWin(NIL){ nTermRb = nTerm; pDev = new TTyAnim(pK, nTerm); for (int idx = 0; idx < MAX_DRIVES; idx++) pDiskAnim[idx] = NULL;}///////////////// Kill off any disk animators..//Animate::~Animate (void){ if (pDev) delete pDev; for (int idx = 0; idx < MAX_DRIVES; idx++) if (pDiskAnim[idx]) delete pDiskAnim[idx];}///////////////////////// As the user pressed buttons, different components of the OS come into// "view" in the main animation window. This member registers the new// change and performs any clean-up required by the old one. If changing// from the Devices screen, we must destroy the Radio Buttons for the TTYs// to inhibit redirection of keyboard.//void Animate::SetCurWin (INT16 nWin, BOOL bReTitle){ if ((CPU_DISP <= (AniWin)nWin) && (NIL > (AniWin)nWin)) { Mickey.AutoPointer(WIN_X1, WIN_Y1, WIN_X2, WIN_Y2); if (bReTitle) Rcos.AppTitle(pszTitle); if ((nCurWin == TTY_DISP) && ((AniWin)nWin != TTY_DISP)) { pDev->DeActivate(); for (UINT16 i = 0; i < nTermRb; i++) { rect r = pDev->GetTTyPos(i); if (r.lr.x && r.lr.y) Rcos.AppDestroy(RC_RadioBtn, RB_TTY_BASE + i); } } GfxPattern(GFX_HalfTone); GfxTextColorBg(nWinBgColor[nWin]); GfxRect(WIN_X1, WIN_Y1+1, WIN_X2, WIN_Y2, GFX_Fill, nWinFgColor[nWin]); GfxPattern(GFX_Solid); switch ((AniWin)nWin) { case CPU_DISP: Cpu.Paint(); break; case MEM_DISP: break; case DSK_DISP: { for (int idx = 0; idx < MAX_DRIVES; idx++) if (NULL != pDiskAnim[idx]) pDiskAnim[idx]->Paint(); } break; case TTY_DISP: pDev->Paint(); if (nCurWin != TTY_DISP) { pDev->Activate(); for (UINT16 i = 0; i < nTermRb; i++) { rect r = pDev->GetTTyPos(i); if (r.lr.x && r.lr.y) { char szLab[8]; sprintf(szLab, "TTY &%d", i+1); Rcos.AppCreate(RC_RadioBtn, RB_TTY_BASE + i, szLab, r.ul.x + 8, r.ul.y + r.lr.y + 8, FALSE); } } } break; } Mickey.ShowPointer(); nCurWin = (AniWin)nWin; }}//////////////////// Provided the appropriate window is visible, perform graphix actions// as dictated by the message <wParam> to depict some internal change.// We suspend timing while this is taking place so that it takes no// time at all, at all..//void Animate::RxPort (PMSG pM){ if (0 == nCurWin) { MSG msg; MSG_ANIP pcby; MSG_ANIQ aniq; Clock.Stop(); switch (pM->wMsgType & ~MM_Sync) { case ANI_REFRESH: msg = message(ID_ANIM, ANI_GET_QUS, 0, &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.PaintAllQ(aniq); break; case ANI_UPDAT_PCB: msg = message(ID_ANIM, ANI_GET_PCB, 0, &pcby); pTx->SendMsg(ID_Kernel, &msg); Cpu.PaintBox(&pcby); break; case ANI_IN_RDY: PutTitle(pszInRdy, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, READY_Q+(INPUT_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(INPUT_Q, &aniq.arr[0][0]); Cpu.Anim(INPUT_Q, READY_Q); Cpu.RefreshQ(READY_Q, &aniq.arr[1][0]); break; case ANI_RDY_RUN: PutTitle(pszRdyRun, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, READY_Q, &aniq); pTx->SendMsg(ID_Kernel, &msg); msg = message(ID_ANIM, ANI_GET_PCB, 0, &pcby); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(READY_Q, &aniq.arr[1][0]); Cpu.Anim(READY_Q, CPROC_BOX); Cpu.PaintBox(&pcby); break; case ANI_RUN_RDY: PutTitle(pszRunRdy, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, READY_Q, &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.Anim(CPROC_BOX, READY_Q); Cpu.RefreshQ(READY_Q, &aniq.arr[1][0]); Cpu.PaintBox(NULL); break; case ANI_RUN_BLK: PutTitle(pszRunBlk, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, BLOKED_Q, &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.Anim(CPROC_BOX, BLOKED_Q); Cpu.RefreshQ(BLOKED_Q, &aniq.arr[1][0]); Cpu.PaintBox(NULL); break; case ANI_BLK_RDY: PutTitle(pszBlkRdy, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, BLOKED_Q+(READY_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(BLOKED_Q, &aniq.arr[1][0]); Cpu.Anim(BLOKED_Q, READY_Q); Cpu.RefreshQ(READY_Q, &aniq.arr[0][0]); break; case ANI_BLK_SBLK: PutTitle(pszSusBlk, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, BLOKED_Q+(SUSBLK_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(BLOKED_Q, &aniq.arr[1][0]); Cpu.Anim(BLOKED_Q, SUSBLK_Q); Cpu.RefreshQ(SUSBLK_Q, &aniq.arr[0][0]); break; case ANI_SBLK_BLK: PutTitle(pszSusBlk, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, SUSBLK_Q+(BLOKED_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(SUSBLK_Q, &aniq.arr[1][0]); Cpu.Anim(SUSBLK_Q, BLOKED_Q); Cpu.RefreshQ(BLOKED_Q, &aniq.arr[0][0]); break; case ANI_RDY_SRDY: PutTitle(pszRdySus, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, READY_Q+(SUSRDY_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(READY_Q, &aniq.arr[1][0]); Cpu.Anim(READY_Q, SUSRDY_Q); Cpu.RefreshQ(SUSRDY_Q, &aniq.arr[0][0]); break; case ANI_SBLK_SRDY: PutTitle(pszSusBlkSus, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, SUSBLK_Q+(SUSRDY_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(SUSBLK_Q, &aniq.arr[1][0]); Cpu.Anim(SUSBLK_Q, SUSRDY_Q); Cpu.RefreshQ(SUSRDY_Q, &aniq.arr[0][0]); break; case ANI_SRDY_RDY: PutTitle(pszSusRdy, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, SUSRDY_Q+(READY_Q<<8), &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(SUSRDY_Q, &aniq.arr[1][0]); Cpu.Anim(SUSRDY_Q, READY_Q); Cpu.RefreshQ(READY_Q, &aniq.arr[0][0]); break; case ANI_FORKS: PutTitle(pszForked, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, INPUT_Q, &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.RefreshQ(INPUT_Q, &aniq.arr[1][0]); break; case ANI_HALT_OK: PutTitle(pszHaltOk, pM->wParam); break; case ANI_HALT_BAD: PutTitle(pszHaltBad, pM->wParam); break; case ANI_PREEMPT: PutTitle(pszPreEmpt, pM->wParam); msg = message(ID_ANIM, ANI_GET_QUS, READY_Q, &aniq); pTx->SendMsg(ID_Kernel, &msg); Cpu.Anim(CPROC_BOX, READY_Q); Cpu.RefreshQ(READY_Q, &aniq.arr[1][0]); Cpu.PaintBox(NULL); break; } Clock.Start(); } else if (2 == nCurWin) { Clock.Stop(); switch (pM->wMsgType & ~MM_Sync) { case ANI_ONTRACK: PutTitle(pszOnTrack, pM->wParam); break; case ANI_CHAN_ENQ: if (pDiskAnim[pM->wParam]) pDiskAnim[pM->wParam]->RefreshTQ((TransQ*)pM->pBody, 0); PutTitle(pszEnQueue); break; case ANI_SPIN: if (pDiskAnim[pM->wParam]) pDiskAnim[pM->wParam]->DiskSpin(*(UINT16*)pM->pBody); break; case ANI_BEGIN_SEEK: { char str[8]; UINT16 nVal = *(UINT16*)pM->pBody; strcpy(str, (nVal & 0x8000) ? "out" : "in"); PutTitle(pszSeek, nVal & 0x7fff, str); } break; case ANI_SEEK: if (pDiskAnim[pM->wParam]) pDiskAnim[pM->wParam]->DiskSeek(*(UINT16*)pM->pBody); break; case ANI_RWOP: { char str[16]; strcpy(str, (pM->wParam) ? "written from" : "read into"); PutTitle(pszDeQueue, 0, str); if (pDiskAnim[pM->wParam]) pDiskAnim[pM->wParam]->RefreshTQ((TransQ*)pM->pBody, 1); TransQ *pTq = (TransQ*)pM->pBody; if (1 == pTq->GetLen()) PutTitle(pszIdle, pM->wParam + 'A'); } break; } Clock.Start(); } else if ((pM->wMsgType & ~MM_Sync) == ANI_DCREAT) { if (NULL == pDiskAnim[pM->wParam]) pDiskAnim[pM->wParam] = new DiskAnim(pM->wParam, *(UINT16*)pM->pBody); }}///////////////// Prepare a title message from the passed template and parameter(s)// and display it on the Application Title Bar. Make sure at least// MIN_DISY 18mS ticks have elapsed since the last message (gives// adequate time to read the damn things..)//void Animate::PutTitle (char *psz1, UINT16 uNr, char *psz2){ char sz[80]; static UINT32 uPrevTock = 0; if (psz2) sprintf(sz, psz1, psz2, uNr); else sprintf(sz, psz1, uNr); while (Clock.GetTocks() - uPrevTock < MIN_DISY) NULL; Rcos.AppTitle(sz); uPrevTock = Clock.GetTocks();}/********************************** eof **********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -