/* TA2.C */ #include #include #include #include LOCAL_D TEXT *cmds[]= { "rReset score", "lLimits", "mMode", "tTiming", "xExit", NULL }; #define TABLES_ITEMS 5 LOCAL_D H_MENU_DATA mdata[]= { "Tables",TABLES_ITEMS, NULL }; GLDEF_D TEXT ** _cmds=(&cmds[0]); GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]); LOCAL_D UINT MainWid; typedef struct { UWORD TableEnd; UWORD MaxTable; UWORD Tested; UWORD Correct; UWORD Timing; UWORD Mode; } TSTATE; LOCAL_D TSTATE state={12,12,0,0,5,1}; LOCAL_D TEXT *EnvName="TABLES"; #define ENV_NAME_LEN 6 LOCAL_C VOID DrawLine(INT j,TEXT *pb) { P_RECT box; box.tl.x=4; box.br.x=189-4; box.tl.y=4+9*j; box.br.y=box.tl.y+9; gPrintBoxText(&box,8,G_TEXT_ALIGN_CENTRE,0,pb,p_slen(pb)); } LOCAL_C VOID DisplayScores(VOID) { TEXT buf[40]; p_atos(&buf[0],"Score: %u correct out of %u",state.Correct,state.Tested); DrawLine(0,&buf[0]); } LOCAL_C VOID DisplayMode(VOID) { TEXT *pb; TEXT buf[40]; if (state.Mode==1) pb="Testing all tables"; else { p_atos(&buf[0],"Testing %d times table",state.Mode); pb=(&buf[0]); } DrawLine(1,pb); } LOCAL_C VOID DisplayLimits(VOID) { TEXT buf[40]; p_atos(&buf[0],"(up to %d times %d)", (state.Mode==1? state.MaxTable: state.Mode),state.TableEnd); DrawLine(2,&buf[0]); } LOCAL_C VOID DrawButton(INT state) { P_RECT box; box.tl.x=34+36; box.br.x=34+36+38; box.tl.y=47; box.br.y=47+14; wDrawButton(&box,"Enter",state); } LOCAL_C VOID DisplayPressButton(VOID) { gPrintText(34,56,"Press",5); DrawButton(FALSE); gPrintText(34+36+38+6,56,"to test",7); } LOCAL_C VOID Display(VOID) { DisplayScores(); DisplayMode(); DisplayLimits(); DisplayPressButton(); } LOCAL_C VOID ResetScore(VOID) { if (!state.Tested) { wInfoMsg("No score to reset"); return; } if (uOpenDialog("Reset score to zero")) return; if (uAddButtonList("No",-'n',"Yes",'y',NULL)) return; if (uRunDialog()=='y') { state.Tested=0; state.Correct=0; DisplayScores(); } } LOCAL_C VOID ChangeLimits(VOID) { LONG lTableEnd; LONG lMaxTable; H_DI_NUMBER end; H_DI_NUMBER last; lTableEnd=state.TableEnd; lMaxTable=state.MaxTable; if (uOpenDialog("Limits for testing")) return; end.value=(&lTableEnd); end.low=10; end.high=99; if (uAddDialogItem(H_DIALOG_NUMBER,"Tables end at",&end)) return; last.value=(&lMaxTable); last.low=2; last.high=99; if (uAddDialogItem(H_DIALOG_NUMBER,"Highest table",&last)) return; if (uRunDialog()<=0) return; state.TableEnd=lTableEnd; state.MaxTable=lMaxTable; if (state.Mode>state.MaxTable) state.Mode=state.MaxTable; DisplayMode(); DisplayLimits(); } LOCAL_C VOID ChangeTiming(VOID) { LONG lTiming; H_DI_NUMBER tim; lTiming=state.Timing; if (uOpenDialog("Timing")) return; tim.value=(&lTiming); tim.low=1; tim.high=20; if (uAddDialogItem(H_DIALOG_NUMBER,"Number of seconds allowed",&tim)) return; if (uRunDialog()<=0) return; state.Timing=lTiming; } LOCAL_C VOID ChangeMode(VOID) { H_DI_CHOICE ch; INT j; TEXT buf[20]; if (uOpenDialog("Mode")) return; if (uBeginDCL(&ch)) return; if (uGrowDCL(&ch,"All tables")) return; for (j=2; j<=state.MaxTable; j++) { p_atos(&buf[0],"%d times table",j); if (uGrowDCL(&ch,&buf[0])) return; } if (uAddDCL("Test which tables",&state.Mode,&ch)) return; if (uRunDialog()<=0) return; DisplayMode(); DisplayLimits(); } LOCAL_C VOID ExitApplication(VOID) { uErrorValue(p_setenviron(EnvName,ENV_NAME_LEN,&state,sizeof(TSTATE))); p_exit(0); } LOCAL_C VOID ManageCommand(INT index) { switch (index) { case 0: ResetScore(); break; case 1: ChangeLimits(); break; case 2: ChangeMode(); break; case 3: ChangeTiming(); break; case 4: ExitApplication(); } } LOCAL_C VOID TryExecuteCommand(INT keycode) { keycode=uLocateCommand(keycode); if (keycode>=0) ManageCommand(keycode); } LOCAL_C VOID MakeButtonDance(VOID) { DrawButton(TRUE); wFlush(); p_sleep(2); DrawButton(FALSE); wFlush(); p_sleep(2); } LOCAL_C VOID DoTest(VOID) { MakeButtonDance(); state.Tested++; state.Correct++; DisplayScores(); } LOCAL_C VOID MainLoop(VOID) { INT ret; WMSG_KEY key; FOREVER { uGetKey(&key); if (key.keycode&W_EVENT_KEY) { if (key.keycode==CONS_EVENT_COMMAND) ExitApplication(); } else if (key.keycode&W_SPECIAL_KEY) TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY)); else if (key.keycode==W_KEY_MENU && !(key.modifiers&W_CTRL_MODIFIER)) { ret=uPresentMenus(); if (ret>0) TryExecuteCommand(ret); } else if (key.keycode==W_KEY_RETURN) DoTest(); } } LOCAL_C VOID ReadState(VOID) { INT len; UBYTE buf[P_ENVMAX]; len=p_getenviron(EnvName,ENV_NAME_LEN,&buf[0]); if (len<0 || len!=sizeof(TSTATE)) return; p_bcpy(&state,&buf[0],sizeof(TSTATE)); } LOCAL_C VOID ReduceScreenSize(VOID) { W_WINDATA wd; wd.extent.tl.x=wd.extent.tl.y=0; wd.extent.width=189; wd.extent.height=80; wSetWindow(MainWid,W_WIN_EXTENT,&wd); if (uErrorValue(wCheckPoint())) p_exit(0); } LOCAL_C VOID CreateGC(VOID) { INT hgc; hgc=gCreateGC0(uFindMainWid()); if (hgc<0) p_exit(hgc); } LOCAL_C VOID SpecificInit(VOID) { hCrackCommandLine(); MainWid=uFindMainWid(); ReduceScreenSize(); CreateGC(); gBorder(W_BORD_CORNER_4); wsEnable(); ReadState(); Display(); } GLDEF_C VOID main(VOID) { uCommonInit(); SpecificInit(); MainLoop(); }