With PureBasic going Unicode-Exclusive, I've been looking into interesting ways to utilize the massive character set that is Unicode. While this a bit limited on Windows+Console as Unicode is kind of a gray-area there, there are quite a few possibilities from "Ascii"-Art to something like a game, which would rely only on unicode-glyphs and not any graphics if sticking to a custom font, or one that supports some or all of the unicode set.
Here's a little desktop toy app that uses some unicode box-drawing characters to form a retro-digital clock face. The sound lines are commented out so I don't need to transfer those, you can plug in your own if you want to use it that way. The only things used are a main window, and 5 Text Gadgets (No buttons, no graphics, etc.) https://streamable.com/icn9i9
Code: Select all
EnableExplicit
Enumeration Gadget_List
#MainWindow=0
#Clock_Face
#MenuBttn_1
#MenuBttn_2
#MenuBttn_3
#MenuBttn_4
#Gadget_Max
EndEnumeration
Enumeration Output_Font
#Thin=1
#Thick
#Double
EndEnumeration
Global Dim Gadgets.i(#Gadget_Max) : InitSound()
Global Font,h12=#False,CentiSecond=0,LastSecond$="",Quit=0,CurrentFont=#Thin
;Global S1=LoadSound(#PB_Any,"Tick1.wav")
;Global S2=LoadSound(#PB_Any,"Alarm.wav")
;Global S3=LoadSound(#PB_Any,"Exit.wav")
Global ActiveColor=RGB(255,0,0),InActiveCol=RGB(100,0,0)
Global AlarmTime.s="",AlarmMode.b=#False,Alarmed.b=#False
Global Dim AnalogDig_Sm.s(12,5)
Macro ThinFont()
AnalogDig_Sm(00,00)=" ── ":AnalogDig_Sm(01,00)=" ":AnalogDig_Sm(02,00)=" ── ":AnalogDig_Sm(03,00)=" ── ":AnalogDig_Sm(04,00)=" ":AnalogDig_Sm(05,00)=" ── "
AnalogDig_Sm(00,01)="│ │":AnalogDig_Sm(01,01)=" │":AnalogDig_Sm(02,01)=" │":AnalogDig_Sm(03,01)=" │":AnalogDig_Sm(04,01)="│ │":AnalogDig_Sm(05,01)="│ "
AnalogDig_Sm(00,02)=" ":AnalogDig_Sm(01,02)=" ":AnalogDig_Sm(02,02)=" ── ":AnalogDig_Sm(03,02)=" ── ":AnalogDig_Sm(04,02)=" ── ":AnalogDig_Sm(05,02)=" ── "
AnalogDig_Sm(00,03)="│ │":AnalogDig_Sm(01,03)=" │":AnalogDig_Sm(02,03)="│ ":AnalogDig_Sm(03,03)=" │":AnalogDig_Sm(04,03)=" │":AnalogDig_Sm(05,03)=" │"
AnalogDig_Sm(00,04)=" ── ":AnalogDig_Sm(01,04)=" ":AnalogDig_Sm(02,04)=" ── ":AnalogDig_Sm(03,04)=" ── ":AnalogDig_Sm(04,04)=" ":AnalogDig_Sm(05,04)=" ── "
AnalogDig_Sm(06,00)=" ── ":AnalogDig_Sm(07,00)=" ── ":AnalogDig_Sm(08,00)=" ── ":AnalogDig_Sm(09,00)=" ── ":AnalogDig_Sm(10,00)=" " :AnalogDig_Sm(11,00)=" "
AnalogDig_Sm(06,01)="│ ":AnalogDig_Sm(07,01)=" │":AnalogDig_Sm(08,01)="│ │":AnalogDig_Sm(09,01)="│ │":AnalogDig_Sm(10,01)="•" :AnalogDig_Sm(11,01)=" "
AnalogDig_Sm(06,02)=" ── ":AnalogDig_Sm(07,02)=" ":AnalogDig_Sm(08,02)=" ── ":AnalogDig_Sm(09,02)=" ── ":AnalogDig_Sm(10,02)=" " :AnalogDig_Sm(11,02)=" "
AnalogDig_Sm(06,03)="│ │":AnalogDig_Sm(07,03)=" │":AnalogDig_Sm(08,03)="│ │":AnalogDig_Sm(09,03)=" │":AnalogDig_Sm(10,03)="•" :AnalogDig_Sm(11,03)=" "
AnalogDig_Sm(06,04)=" ── ":AnalogDig_Sm(07,04)=" ":AnalogDig_Sm(08,04)=" ── ":AnalogDig_Sm(09,04)=" ── ":AnalogDig_Sm(10,04)=" " :AnalogDig_Sm(11,04)="•"
EndMacro
Macro ThickFont()
AnalogDig_Sm(00,00)=" ━━ ":AnalogDig_Sm(01,00)=" ":AnalogDig_Sm(02,00)=" ━━ ":AnalogDig_Sm(03,00)=" ━━ ":AnalogDig_Sm(04,00)=" ":AnalogDig_Sm(05,00)=" ━━ "
AnalogDig_Sm(00,01)="┃ ┃":AnalogDig_Sm(01,01)=" ┃":AnalogDig_Sm(02,01)=" ┃":AnalogDig_Sm(03,01)=" ┃":AnalogDig_Sm(04,01)="┃ ┃":AnalogDig_Sm(05,01)="┃ "
AnalogDig_Sm(00,02)=" ":AnalogDig_Sm(01,02)=" ":AnalogDig_Sm(02,02)=" ━━ ":AnalogDig_Sm(03,02)=" ━━ ":AnalogDig_Sm(04,02)=" ━━ ":AnalogDig_Sm(05,02)=" ━━ "
AnalogDig_Sm(00,03)="┃ ┃":AnalogDig_Sm(01,03)=" ┃":AnalogDig_Sm(02,03)="┃ ":AnalogDig_Sm(03,03)=" ┃":AnalogDig_Sm(04,03)=" ┃":AnalogDig_Sm(05,03)=" ┃"
AnalogDig_Sm(00,04)=" ━━ ":AnalogDig_Sm(01,04)=" ":AnalogDig_Sm(02,04)=" ━━ ":AnalogDig_Sm(03,04)=" ━━ ":AnalogDig_Sm(04,04)=" ":AnalogDig_Sm(05,04)=" ━━ "
AnalogDig_Sm(06,00)=" ━━ ":AnalogDig_Sm(07,00)=" ━━ ":AnalogDig_Sm(08,00)=" ━━ ":AnalogDig_Sm(09,00)=" ━━ ":AnalogDig_Sm(10,00)=" " :AnalogDig_Sm(11,00)=" "
AnalogDig_Sm(06,01)="┃ ":AnalogDig_Sm(07,01)=" ┃":AnalogDig_Sm(08,01)="┃ ┃":AnalogDig_Sm(09,01)="┃ ┃":AnalogDig_Sm(10,01)="•" :AnalogDig_Sm(11,01)=" "
AnalogDig_Sm(06,02)=" ━━ ":AnalogDig_Sm(07,02)=" ":AnalogDig_Sm(08,02)=" ━━ ":AnalogDig_Sm(09,02)=" ━━ ":AnalogDig_Sm(10,02)=" " :AnalogDig_Sm(11,02)=" "
AnalogDig_Sm(06,03)="┃ ┃":AnalogDig_Sm(07,03)=" ┃":AnalogDig_Sm(08,03)="┃ ┃":AnalogDig_Sm(09,03)=" ┃":AnalogDig_Sm(10,03)="•" :AnalogDig_Sm(11,03)=" "
AnalogDig_Sm(06,04)=" ━━ ":AnalogDig_Sm(07,04)=" ":AnalogDig_Sm(08,04)=" ━━ ":AnalogDig_Sm(09,04)=" ━━ ":AnalogDig_Sm(10,04)=" " :AnalogDig_Sm(11,04)="•"
EndMacro
Macro DoubleFont()
AnalogDig_Sm(00,00)=" ══ ":AnalogDig_Sm(01,00)=" ":AnalogDig_Sm(02,00)=" ══ ":AnalogDig_Sm(03,00)=" ══ ":AnalogDig_Sm(04,00)=" ":AnalogDig_Sm(05,00)=" ══ "
AnalogDig_Sm(00,01)="║ ║":AnalogDig_Sm(01,01)=" ║":AnalogDig_Sm(02,01)=" ║":AnalogDig_Sm(03,01)=" ║":AnalogDig_Sm(04,01)="║ ║":AnalogDig_Sm(05,01)="║ "
AnalogDig_Sm(00,02)=" ":AnalogDig_Sm(01,02)=" ":AnalogDig_Sm(02,02)=" ══ ":AnalogDig_Sm(03,02)=" ══ ":AnalogDig_Sm(04,02)=" ══ ":AnalogDig_Sm(05,02)=" ══ "
AnalogDig_Sm(00,03)="║ ║":AnalogDig_Sm(01,03)=" ║":AnalogDig_Sm(02,03)="║ ":AnalogDig_Sm(03,03)=" ║":AnalogDig_Sm(04,03)=" ║":AnalogDig_Sm(05,03)=" ║"
AnalogDig_Sm(00,04)=" ══ ":AnalogDig_Sm(01,04)=" ":AnalogDig_Sm(02,04)=" ══ ":AnalogDig_Sm(03,04)=" ══ ":AnalogDig_Sm(04,04)=" ":AnalogDig_Sm(05,04)=" ══ "
AnalogDig_Sm(06,00)=" ══ ":AnalogDig_Sm(07,00)=" ══ ":AnalogDig_Sm(08,00)=" ══ ":AnalogDig_Sm(09,00)=" ══ ":AnalogDig_Sm(10,00)=" " :AnalogDig_Sm(11,00)=" "
AnalogDig_Sm(06,01)="║ ":AnalogDig_Sm(07,01)=" ║":AnalogDig_Sm(08,01)="║ ║":AnalogDig_Sm(09,01)="║ ║":AnalogDig_Sm(10,01)="•" :AnalogDig_Sm(11,01)=" "
AnalogDig_Sm(06,02)=" ══ ":AnalogDig_Sm(07,02)=" ":AnalogDig_Sm(08,02)=" ══ ":AnalogDig_Sm(09,02)=" ══ ":AnalogDig_Sm(10,02)=" " :AnalogDig_Sm(11,02)=" "
AnalogDig_Sm(06,03)="║ ║":AnalogDig_Sm(07,03)=" ║":AnalogDig_Sm(08,03)="║ ║":AnalogDig_Sm(09,03)=" ║":AnalogDig_Sm(10,03)="•" :AnalogDig_Sm(11,03)=" "
AnalogDig_Sm(06,04)=" ══ ":AnalogDig_Sm(07,04)=" ":AnalogDig_Sm(08,04)=" ══ ":AnalogDig_Sm(09,04)=" ══ ":AnalogDig_Sm(10,04)=" " :AnalogDig_Sm(11,04)="•"
EndMacro
Procedure.s DigitPrintSM(ValAsStr.s,DateMode.b=#False)
Define DX,DY,Result$=" "
Dim Seq.i(Len(ValAsStr))
For DX=0 To Len(ValAsStr)-1
Define C$=Mid(ValAsStr,DX+1,1)
If (C$<>"") And
((Bool(Val(C$)<>0)) Or (C$="0"))
Seq(DX)=Val(C$)
ElseIf C$ = ":":Seq(DX)=10
ElseIf C$ = ".":Seq(DX)=11
EndIf
Next
For DY = 0 To ArraySize(AnalogDig_Sm(),2)-1
For DX=0 To Len(ValAsStr)-1
Result$+AnalogDig_Sm(Seq(DX),DY)+Space(1)
Next
Result$=Result$+#CRLF$+" "
Next
ProcedureReturn Result$
EndProcedure
Procedure AlarmGo(*Null)
AlarmMode=#True
While AlarmMode
;PlaySound(S2,#PB_Sound_MultiChannel,100)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,InActiveCol)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_BackColor,#Red)
SetGadgetColor(Gadgets(#Clock_Face),#PB_Gadget_FrontColor,InActiveCol)
Delay(1000)
;PlaySound(S2,#PB_Sound_MultiChannel,100)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,ActiveColor)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#Clock_Face),#PB_Gadget_FrontColor,#Red)
Delay(1000)
Wend
EndProcedure
Procedure AlarmSet(*Null)
AlarmTime=""
Protected CurrH$=FormatDate("%hh",Date()),
CurrM$=FormatDate("%ii",Date()),
DefAT$
If Val(CurrM$) <= 55
DefAT$=CurrH$+":"+RSet(Str(Val(CurrM$)+5),2,"0")
Else
DefAT$=RSet(Str(Val(CurrH$)+1),2,"0")+":05"
EndIf
AlarmTime=InputRequester("Choose Time For Alarm","Use 24-Hour Format (18:24 for 6:24pm etc)",DefAt$)
If Trim(AlarmTime)<>"":
Alarmed=#True
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,ActiveColor)
EndIf
EndProcedure
Procedure.s TimeSmall()
Define CS=0,CS$,Second$=FormatDate("%ss",Date())
If Second$ <> LastSecond$
LastSecond$=Second$
CentiSecond=ElapsedMilliseconds()
If Not AlarmMode
;PlaySound(S1,#PB_Sound_MultiChannel,40)
EndIf
EndIf
CS=ElapsedMilliseconds()-CentiSecond
Define Hour.s=FormatDate("%hh",Date())
If h12
Define iHr.i=Val(Hour)
If iHr > 12
iHr-12 : Hour=RSet(Str(iHr),2,"0")
EndIf
EndIf
CS$=RSet(Str((CS/10)*0.6),2,"0")
Define Result$=DigitPrintSM(Hour+FormatDate(":%ii:%ss:",Date())+CS$)
If Alarmed And AlarmTime=FormatDate("%hh:%ii",Date())
CreateThread(@AlarmGo(),#Null) : Alarmed=#False
EndIf
ProcedureReturn Left(Result$,Len(Result$)-2)
EndProcedure
Procedure TimeThread(*Null)
Repeat
If Not Quit
SetGadgetText(Gadgets(#Clock_Face),TimeSmall()):Delay(55)
EndIf
ForEver
EndProcedure
Procedure LoadArtFont(FontID)
Select FontID
Case #Thin
ThinFont()
Case #Thick
ThickFont()
Case #Double
DoubleFont()
EndSelect
EndProcedure
Procedure CycleDisplayFont(*Null)
Select CurrentFont
Case #Thin :CurrentFont=#Thick
Case #Thick :CurrentFont=#Double
Case #Double:CurrentFont=#Thin
EndSelect
LoadArtFont(CurrentFont)
EndProcedure
Procedure BrokenDissolve(*Null)
Protected X,Y,Z
Dim RS.s(5)
RS(0)="⚠⏳☏▒!"
RS(1)="=⛏∩░☔"
RS(2)="▒☣∑$&"
RS(3)="░☕⏏]☔"
RS(4)="☢*░☘↊"
Repeat
X=Random(9,0):Y=Random(4,0):Z=Random(4,0)
AnalogDig_Sm(X,Y)=RS(Z)
Delay(10)
ForEver
EndProcedure
Procedure QuitClean(*Null)
Protected Ct1
;PlaySound(S3,#PB_Sound_MultiChannel,100)
CreateThread(@BrokenDissolve(),#Null)
For Ct1=0 To 2
SetGadgetColor(Gadgets(#MenuBttn_4),#PB_Gadget_FrontColor,InactiveCol)
Delay(255)
SetGadgetColor(Gadgets(#MenuBttn_4),#PB_Gadget_FrontColor,ActiveColor)
Delay(255)
Next
Quit=1
EndProcedure
Procedure.i SetWindowTransparency(Window.i, transparency.i);0-255
If IsWindow(Window)
Protected WindowID = WindowID(Window)
SetWindowLongPtr_(WindowID,#GWL_EXSTYLE,#WS_EX_LAYERED)
SetLayeredWindowAttributes_(WindowID,0,transparency,#LWA_ALPHA)
EndIf
EndProcedure
ThinFont()
Gadgets(#MainWindow)=OpenWindow(#PB_Any, 200, 200, 500, 125,"",#PB_Window_BorderLess)
SetWindowColor(Gadgets(#MainWindow),#Black) : StickyWindow(Gadgets(#MainWindow),1) : SetWindowTransparency(Gadgets(#MainWindow),200)
Gadgets(#Clock_Face)=TextGadget(#PB_Any,5,0,480,100,TimeSmall())
Gadgets(#MenuBttn_1)=TextGadget(#PB_Any,000,100,120,20,"☀/☾",#PB_Text_Center|#SS_NOTIFY)
Gadgets(#MenuBttn_2)=TextGadget(#PB_Any,120,100,120,20,"⏰",#PB_Text_Center|#SS_NOTIFY)
Gadgets(#MenuBttn_3)=TextGadget(#PB_Any,240,100,120,20,"⚙",#PB_Text_Center|#SS_NOTIFY)
Gadgets(#MenuBttn_4)=TextGadget(#PB_Any,360,100,120,20,"☠",#PB_Text_Center|#SS_NOTIFY)
Font=LoadFont(#PB_Any,"Consolas",14)
SetGadgetFont(Gadgets(#Clock_Face),FontID(Font))
SetGadgetFont(Gadgets(#MenuBttn_1),FontID(Font))
SetGadgetFont(Gadgets(#MenuBttn_2),FontID(Font))
SetGadgetFont(Gadgets(#MenuBttn_3),FontID(Font))
SetGadgetFont(Gadgets(#MenuBttn_4),FontID(Font))
SetGadgetColor(Gadgets(#Clock_Face),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#Clock_Face),#PB_Gadget_FrontColor,ActiveColor)
SetGadgetColor(Gadgets(#MenuBttn_1),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#MenuBttn_1),#PB_Gadget_FrontColor,InActiveCol)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,InActiveCol)
SetGadgetColor(Gadgets(#MenuBttn_3),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#MenuBttn_3),#PB_Gadget_FrontColor,ActiveColor)
SetGadgetColor(Gadgets(#MenuBttn_4),#PB_Gadget_BackColor,#Black)
SetGadgetColor(Gadgets(#MenuBttn_4),#PB_Gadget_FrontColor,ActiveColor)
CreateThread(@TimeThread(),#Null)
Repeat
Select WaitWindowEvent()
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(Gadgets(#MainWindow)), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #PB_Event_Gadget
Select EventGadget()
Case Gadgets(#MenuBttn_1)
If h12 : h12=#False : SetGadgetColor(Gadgets(#MenuBttn_1),#PB_Gadget_FrontColor,InActiveCol)
Else : h12=#True : SetGadgetColor(Gadgets(#MenuBttn_1),#PB_Gadget_FrontColor,ActiveColor) : EndIf
Case Gadgets(#MenuBttn_2)
If AlarmMode
AlarmMode=#False
SetGadgetColor(Gadgets(#Clock_Face),#PB_Gadget_FrontColor,ActiveColor)
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,InActiveCol)
ElseIf Alarmed
Alarmed=#False
SetGadgetColor(Gadgets(#MenuBttn_2),#PB_Gadget_FrontColor,InActiveCol)
Else
CreateThread(@AlarmSet(),#Null)
EndIf
Case Gadgets(#MenuBttn_3)
CreateThread(@CycleDisplayFont(),#Null)
Case Gadgets(#MenuBttn_4)
CreateThread(@QuitClean(),#Null)
EndSelect
Case #PB_Event_CloseWindow
Quit=1
EndSelect
Until Quit
End
Anybody else have any ideas for making Unicode characters do things they weren't necessarily designed to?