Timers Times Two

Here you can link to screenshots and demos etc. of programs made using BBC BASIC
jinx100
Posts: 5
Joined: Mon 28 Apr 2025, 13:56

Timers Times Two

Post by jinx100 »

Good to see the forum back!

My microwave timer has a weak beep so I needed another kitchen timer. The dlglib method is pretty but difficult to get a larger text size in the same window. The second try does get a larger font for the timer. The WAIT 1 command must give time for other functions to run on the computer as the timer runs smoother and uses less cpu time with the statement in the REPEAT loop. I tried drawing a rectangle to clear the old time but VDU 127 works better. The nowait library doesn't seem to make a difference here.

In both versions, the clock may hang for a bit but that is just the ON TIME 0.25 second granularity. The total time is accurate. Wikipedia commons has a nice hourglass .png for an icon.

Code: Select all

      REM Full page dialog
      REM Mode$ is "Set" / "Count" / "Alarm"
      REM

      INSTALL @lib$+"dlglib"

      OSCLI "FONT """ + @lib$ + "DejaVuSans"",18"
      SYS "SDL_SetWindowSize", @hwnd%, 400, 250, @memhdc%
      VDU 26

      x=5 : y=5
      Mode$="Set" : Dummy%=0
      Sec%=0 : Min%=0
      TIME=0 : T1%=0

      DIM Click%(2)
      ON MOUSE Click%() = @msg%,@wparam%,@lparam% : RETURN
      ON TIME PROC_TimeCheck(Dummy%) : RETURN

      dlg% = FN_newdialog("", 0, 0)
      PROC_setdialogpalette

      but00% = FN_setproc(PROC_Key_but0())
      but01% = FN_setproc(PROC_Key_but1())
      but02% = FN_setproc(PROC_Key_but2())
      but03% = FN_setproc(PROC_Key_but3())
      but04% = FN_setproc(PROC_Key_but4())
      but05% = FN_setproc(PROC_Key_but5())
      but06% = FN_setproc(PROC_Key_but6())
      but07% = FN_setproc(PROC_Key_but7())
      but08% = FN_setproc(PROC_Key_but8())
      but09% = FN_setproc(PROC_Key_but9())
      but10% = FN_setproc(PROC_Start_Button())
      but11% = FN_setproc(PROC_Stop_Button())

      PROC_button(dlg%, "1", but01%, 20*x,40*y,20*x,14*y,0)
      PROC_button(dlg%, "2", but02%, 45*x,40*y,20*x,14*y,0)
      PROC_button(dlg%, "3", but03%, 70*x,40*y,20*x,14*y,0)
      PROC_button(dlg%, "4", but04%, 95*x,40*y,20*x,14*y,0)
      PROC_button(dlg%, "5", but05%, 120*x,40*y,20*x,14*y,0)
      PROC_button(dlg%, "6", but06%, 20*x,60*y,20*x,14*y,0)
      PROC_button(dlg%, "7", but07%, 45*x,60*y,20*x,14*y,0)
      PROC_button(dlg%, "8", but08%, 70*x,60*y,20*x,14*y,0)
      PROC_button(dlg%, "9", but09%, 95*x,60*y,20*x,14*y,0)
      PROC_button(dlg%, "0", but00%, 120*x,60*y,20*x,14*y,0)
      PROC_button(dlg%, "Start", but10%, 10*x,80*y,40*x,14*y,0)
      PROC_button(dlg%, "Stop", but11%, 60*x,80*y,40*x,14*y,0)
      PROC_button(dlg%, "Exit", 2, 110*x, 80*y, 40*x, 14*y, 0)

      PROC_static(dlg%,"00",21,55*x,15*y,15*x,12*y,1)
      PROC_static(dlg%,":",22,75*x,15*y,10*x,12*y,1)
      PROC_static(dlg%,"00",23,90*x,15*y,15*x,12*y,1)

      SYS "SDL_SetWindowTitle", @hwnd%, "Kitchen Timer", @memhdc%
      SYS "SDL_SetWindowResizable", @hwnd%, FALSE, @memhdc%
      OFF
      PROC_refreshdialog(dlg%)

      REPEAT
        REM Do anything that you need to do periodically here
        result% = FN_polldialog(dlg%, 13, Click%())
      UNTIL  result% = 2

      SOUND OFF
      PROC_closedialog(dlg%)
      *QUIT

      END

      DEF PROC_TimeCheck(Dummy%)
      LOCAL T0%
      T0%=TIME
      IF ((T0% > T1%+100) AND (Mode$="Count")) THEN
        T1%=T1%+100
        Sec%=Sec%-1
        IF Sec%=0 AND Min%=0 THEN
          Mode$="Alarm" : SOUND 1,-12,148,20
        ELSE
          IF (Sec%<0) AND (Min%>0) THEN
            Sec%=59 : Min%=Min%-1
          ENDIF
        ENDIF
        PROC_ShowTime(Dummy%)
      ENDIF
      IF (Mode$="Alarm" AND T0%>T1%+200) THEN
        T1%=T1%+200
        SOUND 1,-12,148,20
      ENDIF
      ENDPROC

      DEF PROC_ShiftIn(d1%)
      IF Mode$="Set" THEN
        Min%=(10*Min% + (Sec% DIV 10)) MOD 100
        Sec%=(10*Sec% + d1%) MOD 100
        PROC_ShowTime(Dummy%)
      ENDIF
      ENDPROC

      DEF PROC_ShowTime(Dummy%)
      LOCAL s1$,s2$
      s1$=STR$(Min%) : s2$=STR$(Sec%)
      IF LEN(s1$)<2 THEN s1$="0"+s1$
      IF LEN(s2$)<2 THEN s2$="0"+s2$
      PROC_setdlgitemtext(dlg%,21,s1$)
      PROC_setdlgitemtext(dlg%,23,s2$)
      PROC_refreshdialog(dlg%)
      ENDPROC

      DEF PROC_Start_Button(dlg%,but10%)
      IF (Mode$="Set")AND((Min% > 0)OR(Sec% > 0)) THEN
        Mode$="Count"
        TIME=0 : T1%=0
      ENDIF
      ENDPROC

      DEF PROC_Stop_Button(dlg%,but11%)
      Mode$="Set"
      Min%=0 : Sec%=0
      SOUND OFF
      PROC_ShowTime(Dummy%)
      ENDPROC

      DEF PROC_Key_but0(dlg%,but00%)
      PROC_ShiftIn(0)
      ENDPROC

      DEF PROC_Key_but1(dlg%,but01%)
      PROC_ShiftIn(1)
      ENDPROC

      DEF PROC_Key_but2(dlg%,but02%)
      PROC_ShiftIn(2)
      ENDPROC

      DEF PROC_Key_but3(dlg%,but03%)
      PROC_ShiftIn(3)
      ENDPROC

      DEF PROC_Key_but4(dlg%,but04%)
      PROC_ShiftIn(4)
      ENDPROC

      DEF PROC_Key_but5(dlg%,but05%)
      PROC_ShiftIn(5)
      ENDPROC

      DEF PROC_Key_but6(dlg%,but06%)
      PROC_ShiftIn(6)
      ENDPROC

      DEF PROC_Key_but7(dlg%,but07%)
      PROC_ShiftIn(7)
      ENDPROC

      DEF PROC_Key_but8(dlg%,but08%)
      PROC_ShiftIn(8)
      ENDPROC

      DEF PROC_Key_but9(dlg%,but09%)
      PROC_ShiftIn(9)
      ENDPROC

Code: Select all

      REM  How to remove old clock min : sec ?
      REM  Answer = VDU 127
      REM  This uses 25 - 30% of my CPU!
      REM  Adding the WAIT 1 drops usage to 1-2%
      REM  Semicolon end of time PRINT so only 7 VDU 127
      REM  Simplified PROC parameters

      OSCLI "FONT """ + @lib$ + "DejaVuSans"",18"
      SYS "SDL_SetWindowSize", @hwnd%, 330, 250, @memhdc%
      VDU 26 : VDU 5
      SYS "SDL_SetWindowTitle", @hwnd%, "Kitchen Timer", @memhdc%
      SYS "SDL_SetWindowResizable", @hwnd%, FALSE, @memhdc%

      MOVE 90,325 : PRINT "[1]  [2]  [3]  [4]  [5]"
      MOVE 90,225 : PRINT "[6]  [7]  [8]  [9]  [0]"
      MOVE 65,125 : PRINT "[Start]  [Stop ]  [Exit ]"

      OSCLI "FONT """ + @lib$ + "DejaVuSans"",32"

      xp1=170 : yp1=470
      MOVE xp1,yp1 : PRINT "00 : 00";

      Mode$="Set" : Dummy%=0
      Sec%=0 : Min%=0
      TIME=0 : T1%=0

      ON MOUSE PROC_MouseClick(@wparam%,@lparam%) : RETURN
      ON TIME PROC_TimeCheck(Dummy%) : RETURN

      REPEAT
        REM Do anything that you need to do periodically here
        WAIT 1
      UNTIL  Mode$ = "Exit"

      SOUND OFF
      *QUIT

      END

      DEF PROC_TimeCheck(Dummy%)
      LOCAL T0%
      T0%=TIME
      IF ((T0% > T1%+100) AND (Mode$="Count")) THEN
        T1%=T1%+100
        Sec%=Sec%-1
        IF Sec%=0 AND Min%=0 THEN
          Mode$="Alarm" : SOUND 1,-12,148,20
        ELSE
          IF (Sec%<0) AND (Min%>0) THEN
            Sec%=59 : Min%=Min%-1
          ENDIF
        ENDIF
        PROC_ShowTime(Dummy%)
      ENDIF
      IF (Mode$="Alarm" AND T0%>T1%+200) THEN
        T1%=T1%+200
        SOUND 1,-12,148,20
      ENDIF
      ENDPROC

      DEF PROC_ShiftIn(d1%)
      Min%=(10*Min% + (Sec% DIV 10)) MOD 100
      Sec%=(10*Sec% + d1%) MOD 100
      PROC_ShowTime(Dummy%)
      ENDPROC

      DEF PROC_ShowTime(Dummy%)
      LOCAL s1$,s2$
      s1$=STR$(Min%) : s2$=STR$(Sec%)
      IF LEN(s1$)<2 THEN s1$="0"+s1$
      IF LEN(s2$)<2 THEN s2$="0"+s2$
      *REFRESH OFF
      VDU 127:VDU 127:VDU 127:VDU 127
      VDU 127:VDU 127:VDU 127
      MOVE xp1,yp1 : PRINT s1$+" : "+s2$;
      *REFRESH ON
      ENDPROC

      DEF PROC_MouseClick(cw%,cl%)
      LOCAL xpos%,ypos%
      xpos% = (cl% AND &FFFF)*2 - @vdu.o.x%
      ypos% = (@vdu%!212-1-(cl% >>> 16))*2 - @vdu.o.y%
      IF cw%=1 THEN
        IF Mode$="Set" THEN
          IF (ypos%<320) AND (ypos%>270) THEN
            IF (xpos%>85) AND (xpos%<160) THEN : PROC_ShiftIn(1)
            IF (xpos%>185) AND (xpos%<260) THEN : PROC_ShiftIn(2)
            IF (xpos%>280) AND (xpos%<355) THEN : PROC_ShiftIn(3)
            IF (xpos%>380) AND (xpos%<455) THEN : PROC_ShiftIn(4)
            IF (xpos%>480) AND (xpos%<555) THEN : PROC_ShiftIn(5)
          ENDIF
          IF (ypos%<220) AND (ypos%>170) THEN
            IF (xpos%>85) AND (xpos%<160) THEN : PROC_ShiftIn(6)
            IF (xpos%>185) AND (xpos%<260) THEN : PROC_ShiftIn(7)
            IF (xpos%>280) AND (xpos%<355) THEN : PROC_ShiftIn(8)
            IF (xpos%>380) AND (xpos%<455) THEN : PROC_ShiftIn(9)
            IF (xpos%>480) AND (xpos%<555) THEN : PROC_ShiftIn(0)
          ENDIF
        ENDIF
        IF (ypos%<120) AND (ypos%>70) THEN
          IF xpos%>60 AND xpos%<225 AND (Min%>0 OR Sec%>0)THEN
            IF Mode$="Set" THEN Mode$="Count" : TIME=0 : T1%=0
          ENDIF
          IF xpos%>245 AND xpos%<415 THEN
            Mode$="Set" : Min%=0 : Sec%=0
            SOUND OFF : PROC_ShowTime(Dummy%)
          ENDIF
          IF xpos%>435 AND xpos%<590 THEN Mode$="Exit"
        ENDIF
      ENDIF
      ENDPROC

EDIT: Slight updates to both timers
EDIT2/3: Minor cleanup