build: add the SIBO SDK
This commit is contained in:
@@ -0,0 +1,626 @@
|
||||
/*
|
||||
|
||||
TABLES.C
|
||||
|
||||
Written by DavidW
|
||||
Started on 21/1/92
|
||||
|
||||
*/
|
||||
|
||||
#include <p_std.h>
|
||||
#include <p_sys.h>
|
||||
#include <p_file.h>
|
||||
#include <wlib.h>
|
||||
#include <hwif.h>
|
||||
|
||||
|
||||
GLREF_D UWORD DatLocked;
|
||||
|
||||
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_D ULONG seed;
|
||||
|
||||
LOCAL_D VOID *timH;
|
||||
LOCAL_D WORD timactive;
|
||||
LOCAL_D WORD timstat;
|
||||
LOCAL_D ULONG timint;
|
||||
LOCAL_D WORD timcount;
|
||||
LOCAL_D WORD timtotcnt;
|
||||
|
||||
|
||||
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 INT FindRandom(INT low,INT high)
|
||||
{
|
||||
INT range;
|
||||
|
||||
range=high-low+1;
|
||||
return(low+(INT)(p_randl(&seed)%range));
|
||||
}
|
||||
|
||||
LOCAL_C VOID FindFactors(WORD *pa,WORD *pb)
|
||||
{
|
||||
*pa=(state.Mode==1? FindRandom(2,state.MaxTable): state.Mode);
|
||||
*pb=FindRandom(2,state.TableEnd);
|
||||
}
|
||||
|
||||
LOCAL_C VOID SwitchStyle(INT style)
|
||||
{
|
||||
G_GC gc;
|
||||
|
||||
gc.style=style;
|
||||
gSetGC(0,G_GC_MASK_STYLE,&gc);
|
||||
}
|
||||
|
||||
LOCAL_C VOID *CreateEditor(VOID)
|
||||
{
|
||||
H_EDIT_BOX heb;
|
||||
|
||||
heb.maxchars=4;
|
||||
heb.vulen=30;
|
||||
heb.pos.x=113;
|
||||
heb.pos.y=38;
|
||||
heb.win=MainWid;
|
||||
heb.font=WS_FONT_BASE;
|
||||
heb.style=G_STY_DOUBLE;
|
||||
return(hEBOpen(H_EDIT_BOX_FONT,&heb));
|
||||
}
|
||||
|
||||
LOCAL_C VOID ClearBottomArea(VOID)
|
||||
{
|
||||
P_RECT box;
|
||||
|
||||
box.tl.x=4;
|
||||
box.br.x=189-4;
|
||||
box.tl.y=4+3*9;
|
||||
box.br.y=80-4;
|
||||
gClrRect(&box,G_TRMODE_CLR);
|
||||
}
|
||||
|
||||
LOCAL_C VOID Beep(VOID)
|
||||
{
|
||||
p_sound(-5,320);
|
||||
}
|
||||
|
||||
LOCAL_C VOID SelectAll(VOID *ebH)
|
||||
{
|
||||
hEBSetSelect(ebH,0,p_slen(hEBSenseText(ebH)));
|
||||
}
|
||||
|
||||
LOCAL_C INT SenseNumberTyped(VOID *ebH)
|
||||
{
|
||||
TEXT *pb;
|
||||
WORD num;
|
||||
|
||||
pb=hEBSenseText(ebH);
|
||||
if (!*pb)
|
||||
return(0);
|
||||
p_stoi(&pb,&num);
|
||||
return(num);
|
||||
}
|
||||
|
||||
LOCAL_C INT AddTextItem(TEXT *pmt,TEXT *pbod)
|
||||
{
|
||||
H_DI_TEXT txt;
|
||||
TEXT buf[20];
|
||||
|
||||
txt.type=H_DTEXT_ALIGN_CENTRE;
|
||||
uZTStoBCS(txt.str=(&buf[0]),pbod);
|
||||
return(uAddDialogItem(H_DIALOG_TEXT,pmt,&txt));
|
||||
}
|
||||
|
||||
LOCAL_C INT Complain(INT a,INT b,INT c)
|
||||
{
|
||||
TEXT buf[20];
|
||||
|
||||
if (uOpenDialog("Incorrect"))
|
||||
return(-1);
|
||||
p_atos(&buf[0],"%d \236 %d",a,b);
|
||||
if (AddTextItem("The question",&buf[0]))
|
||||
return(-1);
|
||||
buf[p_itob(&buf[0],c)]=0;
|
||||
if (AddTextItem("Your answer",&buf[0]))
|
||||
return(-1);
|
||||
if (uAddButtonList("Help",W_KEY_ESCAPE,"Retry",W_KEY_RETURN,NULL))
|
||||
return(-1);
|
||||
if (uRunDialog()==W_KEY_RETURN)
|
||||
return(0);
|
||||
p_atos(&buf[0],"%d \236 %d = %d",a,b,a*b);
|
||||
if (uOpenDialog(&buf[0]))
|
||||
return(-1);
|
||||
if (uAddButtonList("Continue",W_KEY_RETURN,NULL))
|
||||
return(-1);
|
||||
uRunDialog();
|
||||
return(-1);
|
||||
}
|
||||
|
||||
LOCAL_C INT BadKey(INT k)
|
||||
{
|
||||
return(k<256 && p_isprint(k) && !p_isdigit(k));
|
||||
}
|
||||
|
||||
LOCAL_C VOID CancelTimer(VOID)
|
||||
{
|
||||
if (timactive)
|
||||
{
|
||||
p_iow2(timH,P_FCANCEL);
|
||||
p_waitstat(&timstat);
|
||||
}
|
||||
timactive=FALSE;
|
||||
}
|
||||
|
||||
LOCAL_C VOID QueueTimer(VOID)
|
||||
{
|
||||
CancelTimer();
|
||||
p_ioa4(timH,P_FRELATIVE,&timstat,&timint);
|
||||
timactive=TRUE;
|
||||
}
|
||||
|
||||
LOCAL_C VOID InitialiseTimer(VOID)
|
||||
{
|
||||
if (state.Timing<=4)
|
||||
{
|
||||
timint=5;
|
||||
timcount=2*state.Timing;
|
||||
}
|
||||
else
|
||||
{
|
||||
timint=10;
|
||||
timcount=state.Timing;
|
||||
}
|
||||
timtotcnt=timcount;
|
||||
QueueTimer();
|
||||
}
|
||||
|
||||
LOCAL_C VOID GetBarChartRect(P_RECT *pbox)
|
||||
{
|
||||
pbox->tl.x=9;
|
||||
pbox->br.x=180;
|
||||
pbox->tl.y=62;
|
||||
pbox->br.y=68;
|
||||
}
|
||||
|
||||
LOCAL_C VOID IncrementBarChart(VOID)
|
||||
{
|
||||
P_RECT box;
|
||||
|
||||
timcount--;
|
||||
GetBarChartRect(&box);
|
||||
box.br.x=9+171*(timtotcnt-timcount)/timtotcnt;
|
||||
gFillPattern(&box,WS_BITMAP_GREY,G_TRMODE_REPL);
|
||||
}
|
||||
|
||||
LOCAL_C VOID ClearBarChart(VOID)
|
||||
{
|
||||
P_RECT box;
|
||||
|
||||
GetBarChartRect(&box);
|
||||
gClrRect(&box,G_TRMODE_CLR);
|
||||
}
|
||||
|
||||
LOCAL_C VOID DisplayQuestion(VOID)
|
||||
{
|
||||
TEXT buf[30];
|
||||
WMSG_KEY key;
|
||||
WORD keyactive;
|
||||
WORD keystat;
|
||||
P_RECT box;
|
||||
VOID *ebH;
|
||||
WORD a;
|
||||
WORD b;
|
||||
WORD c;
|
||||
WORD ans;
|
||||
|
||||
ebH=CreateEditor();
|
||||
if (!ebH)
|
||||
return;
|
||||
ClearBottomArea();
|
||||
hEBEmphasise(ebH,TRUE);
|
||||
FindFactors(&a,&b);
|
||||
ans=a*b;
|
||||
p_atos(&buf[0],"%d \236 %d = ",a,b);
|
||||
box.tl.x=53;
|
||||
box.br.x=113;
|
||||
box.tl.y=38;
|
||||
box.br.y=38+17;
|
||||
SwitchStyle(G_STY_DOUBLE);
|
||||
gPrintBoxText(&box,15,G_TEXT_ALIGN_RIGHT,0,&buf[0],p_slen(&buf[0]));
|
||||
SwitchStyle(G_STY_NORMAL);
|
||||
box.tl.x=8;
|
||||
box.br.x=189-8;
|
||||
box.tl.y=61;
|
||||
box.br.y=61+8;
|
||||
gBorderRect(&box,W_BORD_CORNER_1);
|
||||
DatLocked=TRUE;
|
||||
state.Tested++;
|
||||
keyactive=FALSE;
|
||||
InitialiseTimer();
|
||||
FOREVER
|
||||
{
|
||||
if (keyactive)
|
||||
wFlush();
|
||||
else
|
||||
{
|
||||
uGetKeyA(&keystat,&key);
|
||||
keyactive=TRUE;
|
||||
}
|
||||
p_iowait();
|
||||
if (keystat==E_FILE_PENDING)
|
||||
{
|
||||
timactive=FALSE;
|
||||
IncrementBarChart();
|
||||
if (!timcount)
|
||||
{
|
||||
wFlush();
|
||||
p_sleep(2);
|
||||
goto CheckAnswer;
|
||||
}
|
||||
QueueTimer();
|
||||
continue;
|
||||
}
|
||||
keyactive=FALSE;
|
||||
if (BadKey(key.keycode))
|
||||
Beep();
|
||||
else if (key.keycode!=W_KEY_RETURN)
|
||||
hEBHandleKey(ebH,key.keycode,key.modifiers);
|
||||
else
|
||||
{
|
||||
CheckAnswer:
|
||||
c=SenseNumberTyped(ebH);
|
||||
if (c==ans)
|
||||
{
|
||||
state.Correct++;
|
||||
break;
|
||||
}
|
||||
Beep();
|
||||
hEBEmphasise(ebH,FALSE);
|
||||
if (Complain(a,b,c))
|
||||
break;
|
||||
DisplayScores();
|
||||
state.Tested++;
|
||||
hEBEmphasise(ebH,TRUE);
|
||||
SelectAll(ebH);
|
||||
ClearBarChart();
|
||||
InitialiseTimer();
|
||||
}
|
||||
}
|
||||
DatLocked=FALSE;
|
||||
hEBClose(ebH);
|
||||
ClearBottomArea();
|
||||
DisplayPressButton();
|
||||
CancelTimer();
|
||||
}
|
||||
|
||||
LOCAL_C VOID MakeButtonDance(VOID)
|
||||
{
|
||||
DrawButton(TRUE);
|
||||
wFlush();
|
||||
p_sleep(2);
|
||||
DrawButton(FALSE);
|
||||
wFlush();
|
||||
p_sleep(2);
|
||||
}
|
||||
|
||||
LOCAL_C VOID DoTest(VOID)
|
||||
{
|
||||
MakeButtonDance();
|
||||
DisplayQuestion();
|
||||
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 InitSeed(VOID)
|
||||
{
|
||||
seed=p_date();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
uEscape(FALSE);
|
||||
hCrackCommandLine();
|
||||
MainWid=uFindMainWid();
|
||||
ReduceScreenSize();
|
||||
CreateGC();
|
||||
gBorder(W_BORD_CORNER_4);
|
||||
wsEnable();
|
||||
ReadState();
|
||||
Display();
|
||||
InitSeed();
|
||||
p_open(&timH,"TIM:",-1);
|
||||
}
|
||||
|
||||
GLDEF_C VOID main(VOID)
|
||||
{
|
||||
uCommonInit();
|
||||
SpecificInit();
|
||||
MainLoop();
|
||||
}
|
||||
Reference in New Issue
Block a user