After the relative successes of the last few days, it’s been a day of taking stock in my December Adventure and focusing exclusively on Thoughts—no ROM uploads today.

I started the day by creating a GitHub repository for Thoughts and committed the current version. Without native support for git on my Psion1, I suspect updates will be a little more sporadic than usual, but I’ll try to push each day’s additions.

Having the Thoughts source on my Mac for the first time since starting, I tried running it through Tom’s new Lua-based OPL compiler and was pleasantly surprised to see it worked perfectly. Perhaps tomorrow I’ll set up automated builds using GitHub Actions.

I also took a little time out over my morning coffee to improve my workflow—switching between running programs is a multi-step process in EPOC32 and I’m constantly bouncing back and forth between my source, OPL reference, and Thoughts itself. Thanks to a suggestion by Fabrice, I settled on nSwitcher which offers a NeXTSTEP-like dock and the Ctrl + Space global shortcut for cycling between programs.

nSwitcher makes me feel elite

With everything a little tidier, and the basic functionality in place, I went about setting up an application framework on which I can build other features—OPL apps commonly centered around a polling loop, and Thoughts will follow this pattern.

First up, the main: needs to watch for input events:

PROC main:
    GLOBAL CRLF$(2)
    LOCAL ev&(16), k&

    initglobals:
    clear:

    WHILE 1
        GETEVENT32 ev&()
        k& = ev&(1)
        IF k& = KKeyMenu% OR k& = KKeySidebarMenu%
            menu:
        ELSEIF k& < 32
            REM Key codes are modified if control is pressed. I don't know why.
            k& = k& + %a - 1
            IF k& = %n
                new:
            ELSEIF k& = %e AND ev&(4) = KKModControl%
                close:
            ELSEIF k& = %k AND ev&(4) = KKModControl%
                clear:
            ELSEIF k& = %a AND ev&(4) = (KKModControl% OR KKModShift%)
                about:
            ELSE
                PRINT k&
            ENDIF
        ELSEIF (ev&(1) AND &400) = 0
            PRINT ev&(1), ev&(2), ev&(3), ev&(4), ev&(5)
        ENDIF
    ENDWH

ENDP

Here, I’m using the synchronous, blocking GETEVENT32 call to poll for events. If you look at the event processing though, you’ll notice some pretty grim manipulation of the key code to handle keyboard shortcuts (things like Ctrl + N, etc). I’ve not found a good discussion of why yet, but hopefully I can figure it out over the next few days and update the code with an explanation at the very least; magic numbers make me incredibly nervous.

The original code is now pushed down into the new: procedure, and I’m able to add the other functionality.

A main menu:

PROC menu:
    LOCAL m%
    
    mINIT
    mCARD "File", "New", -%n, "Close", %e
    mCARD "View", "Clear", %k
    mCARD "Tools", "About Thoughts...", %A
    m% = MENU
    
    IF m% = %n
        new:
    ELSEIF m% = %e
        close:
    ELSEIF m% = %k
        clear:
    ELSEIF m% = %A
        about:
    ENDIF
ENDP

And an about screen:

PROC about:
    dINIT "About Thoughts"
    dTEXT "", "Copyright " + CHR$(169) + " Jason Morley 2024"
    dBUTTONS "OK", 13 + $100
    DIALOG
ENDP

Thankfully OPL provides dedicated structures and calls for presenting UI like menus and dialogs, making it incredibly easy to create programs with a native look and feel.


As Thoughts is starting to take shape, I find myself wanting to add some 90s-era graphics to give it character. I also need to add global hot key support, and build an installable app. Lots to keep me entertained.


  1. Yes, that would be an interesting side-quest. No, I’m not going to try it.