rem *** remove the next two lines to create an OPO file APP GuitarDiapason, &10200eb0 ENDA INCLUDE "Const.oph" include "MediaServerOPX.oxh" rem *** Constants for application over all devices CONST KMainViewWindow%=1 CONST KMenuWindow%=2 rem Menu Window Workaround for possible UIQ Bug rem *** Constants for Command Buttons / Jog Dial CONST KButtonOne&=63554 rem Left Soft Key (Series 60), Button One (Series 80) CONST KButtonTwo&=63555 rem Right Soft Key (Series 60), Button Two (Series 80) CONST KButtonThree&=63556 rem Not used under Series 60, Button Three (Series 80) CONST KButtonFour&=63557 rem Cursor Press In (Series 60), Button Four (Series 80) CONST KButtonC&=8 rem The (C)lear button (Series 60), Not Used (Series 80) rem *** Constants for UIQ CONST KMenubarOffset%=24 rem Top of Menu Bar CONST KMainViewWindowOffset%=44 rem Bottom of Menu Bar CONST KStatusBarHeight%=18 rem *** Change the following constants for your own application! CONST KAuthorEmail$="" CONST KAuthorName$="L.Cassioli,P.Sardella,M.Agazzi" CONST KAppName$="GuitarDiapason" CONST KAppNameShort$="GDiap" CONST KAppVer$="2.0" CONST KMaxWindows%=16 PROC Main: rem *** Set up for windows and graphics GLOBAL Id%(KMaxWindows%) rem Id% used to reference the graphics windows GLOBAL ScreenWidth%,ScreenHeight% rem These store dimensions of the actual screen GLOBAL CanvasWidth%,CanvasHeight% rem These store dimensions of the screen area used (ignoring title bar for example) rem *** Will be used to set paths to files GLOBAL Path$(255),Drive$(2),Data$(255),MbmFile$(16) global Piano$(255), Guitar$(255) global chord%(12),chord2%(12),num% global NoteName$(6,255),tasti% global rep%,nota% rem Path$ is where application files are stored (System\Apps\AppName\ normally) rem Drive$ is the drive the application is stored on (e.g. C:) rem Data$ is the pathname without the drive letter rem *** Used to exit the main program loop GLOBAL Breakout% rem Used as a boolean flag, when Breakout%=1, time to exit! rem *** Reads in input from keyboard and the Operating System GLOBAL EventStatus%,Event&(16) rem EventStatus% and Event&(16) array used to store system events rem *** Used to illustrate handling of .ini fies GLOBAL SoundVol% rem We save SoundVol% between closing and running the application rem and it can be used pratically in your app when sound works global corda(6),drw%,cordaulx(6),cordauly(6),cordabrx(6),cordabry(6) global conta% LOCAL E, Command$(255) E=ERR : ONERR OFF ONERR Error:: Init: InitApp: InitNotes: top:: DO GETEVENT32 Event&() Command$=GETCMD$ rem GETCMD$ is the 255 character-long string "command" the system can send rem to us. The first letter is the action, the rest is a filename (if required). rem You should respond to these commands in any publicly released OPL application! rem *** If the system sends an "X", exit the application IF LEFT$(Command$,1)=KGetCmdLetterExit$ Exit: rem *** If the system sends an "?", the machine is being backed up, so exit too ELSEIF LEFT$(Command$,1)=KGetCmdLetterBackup$ Exit: rem *** If the application has been called to the foreground, react if required ELSEIF LEFT$(Command$,1)=KGetCmdLetterBroughtToFGround$ rem Do something here if needed ENDIF IF Event&(KEvAType%)=KEvPtr& rem *** Is there a pen tap (either onto, dragged over, or removed from the screen) PointerDriver: ELSEIF (Event&(KEvAType%)<>KEvKeyDown& AND Event&(KEvAType%)<>KEvKeyUp&) rem *** Is a key being pressed? Jump to KeyboardDriver: passing correct variables. rep%=0 KeyboardDriver:(Event&(KEvAType%),Event&(KEvAKMod%),Event&(KEvAScan%)) ELSEIF Event&(KEvAType%)=KEvFocusLost& rem *** Program has moved to the background, another app is called. rem *** You may want to add specific code here. ENDIF UNTIL (ERR<>E) OR (Breakout%) rem *** Any Error will display the error to bug reporting IF Breakout% Breakout%=0 rem *** Set back to zero, just in case ;-) Exit: ENDIF GOTO top:: rem *** Only show the error dialog if an error has rem happened. This is good defensive programming Error:: rem *** This is a lable, only for GOTO statemens rem *** Show What The Error Is dINIT "Error" dTEXT "",ERRX$,KDTextCenter% dTEXT "",ERR$(ERR),KDTextCenter% dBUTTONS "OK",KdBUTTONEnter% LOCK ON :DIALOG :LOCK OFF GOTO top:: ENDP PROC Init: rem *** Set up global variables, data paths, initialise graphics windows and load bitmaps LOCAL FirstRun%,Drive$(1),Foo% tasti%=1 SetFlags &10000 rem Used to allow Auto Switch off rem GIPRINT KAppName$+", "+KAuthorName$+" 2002,3,4, ver "+KAppVer$ rem *** Set some names and paths Data$="\system\apps\GuitarDiapason\data\" Piano$="piano.mbm" Guitar$="guitar.mbm" rem Set drive application is installed on by searching for the MBM file of graphics rem *** Scan through all availabe drives (from y: to a:, then z: (the ROM) ) for the MBM File rem *** You can change MbmFile$ to any other known file if no graphics are used. Foo%=ASC("y") DO Drive$=UPPER$(CHR$(Foo%)) IF EXIST(Drive$+":"+Data$+piano$) Path$=Drive$+":"+Data$ BREAK ENDIF Foo%=Foo%-1 UNTIL CHR$(Foo%)="Y" IF Path$="" ALERT ("Support mbm file not found","Please re-install "+KAppName$) STOP ENDIF rem *** INI File Handling rem FirstRun%=LoadIniFile%: rem If the application has never been run, an .ini file will rem no be present, and FirstRun% will be set to 1 rem *** Screen dimensions, color fixed across all devices ScreenWidth%=gWIDTH ScreenHeight%=gHEIGHT gsetwin 0,0,0,0 CanvasWidth%=ScreenWidth% : CanvasHeight%=ScreenHeight%-KMainViewWindowOffset%-KStatusBarHeight% rem *** Create initial windows Id%(KMenuWindow%)=gCREATE (0,KMenubarOffset%,CanvasWidth%,KMainViewWindowOffset%-KMenubarOffset%,1,KDefaultWin4kMode%) Id%(KMainViewWindow%)=gCREATE(0,KMainViewWindowOffset%,CanvasWidth%,CanvasHeight%,1,KDefaultWin4kMode%) gAT -1,0 gBOX CanvasWidth%+2,CanvasHeight% rem gSETWIN 0,25,208,275 rem Resize default text window to be unseen rem *** Load initial graphics num% = 1 while num%<=12 chord%(num%)=gLOADBIT(Path$+piano$,0,num%-1) num%=num%+1 endwh num% = 1 while num%<=12 chord2%(num%)=gLOADBIT(Path$+guitar$,0,num%-1) num%=num%+1 endwh ENDP PROC LoadIniFile%: IF EXIST ("C:"+Data$+"Core.ini") OPEN "C:"+Data$+"Core.ini",A,SoundVol% SoundVol%=A.SoundVol% CLOSE RETURN 0 ELSE rem *** Set initial values here, then save to disk SoundVol%=0 SaveIniFile%: RETURN 1 ENDIF ENDP PROC SaveIniFile%: rem *** TRAP will hide any error message and continue running rem *** the application if an error occurs in the command following TRAP TRAP MKDIR "C:"+Data$ TRAP DELETE "C:"+Data$+"Core.ini" CREATE "C:"+Data$+"Core.ini",A,SoundVol% A.SoundVol%=SoundVol% APPEND CLOSE ENDP PROC InitApp: rem *** For the core application, this shows a text string and displays a graphic gUSE Id%(KMainViewWindow%) rem the graphics window previously defined rem *** Using one BOLD font (when it works in the UIQ Runtime!) rem *** gFONT KOplFontLatinBold12& rem gAT 2,(CanvasHeight%)/2 rem gPRINTB "OPL Event Core",CanvasWidth%-4,3 rem *** Using one STANDARD font (when it works in the UIQ Runtime!) rem *** gFONT KOplFontLatinPlain12& rem gAT 2,(CanvasHeight%/2)+15 rem gPRINTB KAuthorName$+", March 2004, "+KAppVer$,CanvasWidth%-4,3 rem IF CanvasWidth%=176 rem Series 60 rem gAT 2,(CanvasHeight%-10) rem gPRINTB "LEFT: Menu (C):Exit RIGHT:Exit",CanvasWidth%-4,3 rem ELSEIF CanvasWidth%=208 rem UIQ rem gAT 2,(CanvasHeight%-10) rem gPRINTB "Push joystick/jogdial for Menu",CanvasWidth%-4,3 rem ELSEIF CanvasWidth%=640 rem Series 80 Communicator rem gAT 2,(CanvasHeight%-10) rem gPRINTB "Menu Key and Hot Keys Active",CanvasWidth%-4,3 rem ENDIF rem *** Displaying an MBM (loaded in PROC Init:) rem gAT (CanvasWidth%-127)/2,(CanvasHeight%-65) rem gCOPY Id%(9),0,0,127,41,3 ENDP proc InitNotes: corda(6)=440*2**(7/12.0) corda(5)=440*2**(12/12.0) corda(4)=440*2**(17/12.0) corda(3)=440*2**(22/12.0) corda(2)=440*2**(26/12.0) corda(1)=440*2**(31/12.0) cordaulx(1)=30:cordauly(1)=30 cordabrx(1)=140:cordabry(1)=50 NoteName$(1)="E (MI)" cordaulx(2)=30:cordauly(2)=60 cordabrx(2)=140:cordabry(2)=80 NoteName$(2)="B (SI)" cordaulx(3)=30:cordauly(3)=90 cordabrx(3)=140:cordabry(3)=110 NoteName$(3)="G (SOL)" cordaulx(4)=30:cordauly(4)=120 cordabrx(4)=140:cordabry(4)=140 NoteName$(4)="D (RE)" cordaulx(5)=30:cordauly(5)=150 cordabrx(5)=140:cordabry(5)=170 NoteName$(5)="A (LA)" cordaulx(6)=30:cordauly(6)=180 cordabrx(6)=140:cordabry(6)=200 NoteName$(6)="E (MI)" gUSE id%(1) gCLS gAT 2,253 gPRINTB "Push joystick/jogdial for Menu",CanvasWidth%-4,3 drw%=1 while drw%<7 gAT cordaulx(drw%)+30,cordauly(drw%)+17 gPRINTB NoteName$(drw%),cordaulx(drw%)+30,3 gAT cordaulx(drw%),cordauly(drw%) gBOX cordabrx(drw%)-cordaulx(drw%),cordabry(drw%)-cordauly(drw%) drw%=drw%+1 endwh endp PROC KeyboardDriver:(aKey&,aMod&,aScanCode&) LOCAL Key&,Foo$(20) Key&=aKey& rem You can't change a constant argument passed to a procedure, so copy it to a local variable Foo$="" rem *** Handle system keys (mainly the menu key). We capture the jog dial as a Menu press, but it is not rem *** always needed for that. We also capture two MENU buttons, which will be used in a future runtime rem *** in place of the 'check pen tap location currently used on the menu. IF Key&=KButtonOne& OR (Key&=KKeySidebarMenu32&) OR (Key&=KKeyMenu32&) Key&=ShowMenu: ELSEIF Key&=KButtonTwo& Foo$="Button 2" ELSEIF Key&=KButtonThree& Foo$="Button 3" ELSEIF Key&=KButtonFour& Foo$="Button 4" ELSEIF Key&=KButtonC& Foo$="(C)lear" : Exit: ELSE Foo$=NUM$(Key&,5) rem Show up Any Other Event. This is where you start adding rem your own procedure calls for events. ENDIF rem *** Print the key value of the key pressed. This is Event Core Specific IF Foo$<>"" rem gUSE Id%(1) rem gFONT KOplFontLatinBold13& rem gAT 3,40 rem gPRINTB "Key Press: "+Foo$,170,3 ENDIF ENDP PROC PointerDriver: LOCAL Foo%,FooX%,FooY% FooX%=Event&(6) FooY%=Event&(7) rep%=0 REM *** Handle pointer events. IF Event&(KEvAPtrWindowId%)=Id%(KMainViewWindow%) IF Event&(4)=0 rem GIPRINT "Pen Down ("+NUM$(FooX%,3)+","+NUM$(FooY%,3)+") Id%:"+NUM$(Event&(3),6) ELSEIF Event&(4)=1 rem GIPRINT "Pen Up ("+NUM$(FooX%,3)+","+NUM$(FooY%,3)+") Id%:"+NUM$(Event&(3),6) conta%=1 while conta%<7 if foox%>cordaulx(conta%) and foox%cordauly(conta%) and fooy%=1 and menuvalue%<=14 tasti% = 0 else tasti%=1 endif IF MenuValue%=%a DialogAbout: ELSEIF MenuValue%=%f InitNotes: ELSEIF MenuValue%=%c Exit: ELSEIF MenuValue%=1 gAT 0,0 gCOPY chord%(1),0,0,208,270,3 ELSEIF MenuValue%=2 gAT 0,0 gCOPY chord%(2),0,0,208,270,3 ELSEIF MenuValue%=3 gAT 0,0 gCOPY chord%(3),0,0,208,270,3 ELSEIF MenuValue%=4 gAT 0,0 gCOPY chord%(4),0,0,208,270,3 ELSEIF MenuValue%=5 gAT 0,0 gCOPY chord%(5),0,0,208,270,3 ELSEIF MenuValue%=6 gAT 0,0 gCOPY chord%(6),0,0,208,270,3 ELSEIF MenuValue%=7 gAT 0,0 gCOPY chord%(7),0,0,208,270,3 ELSEIF MenuValue%=8 gAT 0,0 gCOPY chord%(8),0,0,208,270,3 ELSEIF MenuValue%=9 gAT 0,0 gCOPY chord%(9),0,0,208,270,3 ELSEIF MenuValue%=10 gAT 0,0 gCOPY chord%(10),0,0,208,270,3 ELSEIF MenuValue%=11 gAT 0,0 gCOPY chord%(11),0,0,208,270,3 ELSEIF MenuValue%=12 gAT 0,0 gCOPY chord%(12),0,0,208,270,3 ELSEIF MenuValue%=13 gAT 0,0 gCOPY chord2%(1),0,0,208,270,3 ELSEIF MenuValue%=14 gAT 0,0 gCOPY chord2%(2),0,0,208,270,3 ELSEIF MenuValue%=15 gAT 0,0 gCOPY chord2%(3),0,0,208,270,3 ELSEIF MenuValue%=16 gAT 0,0 gCOPY chord2%(4),0,0,208,270,3 ELSEIF MenuValue%=17 gAT 0,0 gCOPY chord2%(5),0,0,208,270,3 ELSEIF MenuValue%=18 gAT 0,0 gCOPY chord2%(6),0,0,208,270,3 ELSEIF MenuValue%=19 gAT 0,0 gCOPY chord2%(7),0,0,208,270,3 ELSEIF MenuValue%=20 gAT 0,0 gCOPY chord2%(8),0,0,208,270,3 ELSEIF MenuValue%=21 gAT 0,0 gCOPY chord2%(9),0,0,208,270,3 ELSEIF MenuValue%=22 gAT 0,0 gCOPY chord2%(10),0,0,208,270,3 ELSEIF MenuValue%=23 gAT 0,0 gCOPY chord2%(11),0,0,208,270,3 ELSEIF MenuValue%=24 gAT 0,0 gCOPY chord2%(12),0,0,208,270,3 ENDIF ENDP PROC DialogChangePrefs: LOCK ON dINIT "Preferences",KDPositionBottom% dCHOICE SoundVol%,"Sound:","Off,Quiet,Medium,Loud" DIALOG LOCK OFF ENDP PROC DialogAbout: LOCK ON dINIT "About "+KAppNameShort$,KDPositionBottom% dTEXT "",KAppName$,2 dTEXT "","By "+KAuthorName$,2 dTEXT "","Version "+KAppVer$,2 DIALOG LOCK OFF ENDP PROC Exit: rem *** Rather than just stop, there are a few things to do to rem *** exit the application gracefully. LOCAL Foo% rem *** If an error does a occur, supress the message and jump to the JustStop label ONERR JustStop:: rem *** Save any variable changes as needed in the ini SaveIniFile%: rem *** Close all windows and graphics Foo%=0 DO Foo%=Foo%+1 IF Id%(Foo%) : gCLOSE Id%(Foo%) ENDIF UNTIL Foo%=KMaxWindows% JustStop:: ONERR OFF STOP ENDP PROC scale:(n%) LOCAL freq,status%,ev&(6) freq=corda(n%) BEEP 30,512000/freq-1.0 ENDP