Kevin's Research Blog

RISC-OS: Hello World Applications

In computer programming one of the hallmark programs to build in a new language and/or framework is the titular Hello World application. The idea to display the simple message on the screen, of Hello World using that preferred language and/or frameworks common methods as a way to learn the ropes. I decided to sit down, and read various RISC-OS development documentations, and determine how such an application can be created in various common development systems in RISC-OS.

I will be going through each one from the most difficult, to the absolute easiest. The first one will be using raw BBC BASIC and the various WIMP system calls, so the only requirement for it to run is RISC-OS 2.00, the earliest version of the operating system after Arthur.

Plain BBC BASIC WIMP

This version of a Hello World program I was able to learn through the A Beginner's Guide to WIMP Programming: Second Edition. The first edition was written while Martyn Fox was still among us, and was originally written to aid his own son in learning WIMP programming on their family RISC-OS machine. Martyn Fox later published the book, and later he did begin working on this second edition, but unfortunately passed away before he could finish it himself. As a result, it was completed, along with various notes from Martyn by Richard Hallas. I highly recommend reading it, as it is included in the RISC-OS Direct distribution you can easily place onto a Raspberry Pi.

This version of a Hello World application does not use any external libraries, and only requires the RISC-OS built-in BBC BASIC language to run. There were two different ways to creating a basic Hello World application, one which doesn't use any Templates, and only performs various system calls to create the Window, and another one which does use Templates.

For those who aren't familiar with RISC-OS development, a Template is a special file format on RISC-OS. These can be created using either !WinEd or !TemplEd. The file is usually named just Templates inside the application directory. A lot of RISC-OS applications use this. This file contains one or more Window definition templates, which the application can use during runtime. It is more or less similar to what you may have seen in a Windows Resource for many Windows applications which had their windows created from a resource. If you create or open a template file, you can then design a window using similar tools to what you might find in Visual Basic or Delphi, minus the ability to directly add code for the components. The actual code needs to be written in the applications themselves, along with the loading of these templates. Here is a sample routine in BBC BASIC which can load in several templates:

DEF PROCload_templates
SYS "Wimp_OpenTemplate",,"<Hello$Dir>.Templates"
SYS "Wimp_LoadTemplate",,b%,ws%,wsend%,-1,"Main",0 TO ,,ws%
SYS "Wimp_CreateWindow",,b% TO main%
SYS "Wimp_LoadTemplate",,b%,ws%,wsend%,-1,"progInfo",0 TO ,,ws%
SYS "Wimp_CreateWindow",,b% TO info%
SYS "Wimp_CloseTemplate"
ENDPROC

As you can see, it's a fair amount of code still. However, it is much more complicated to actually create an entire window from scratch using online code, so this is still better than having to design the window manually. Of course, this isn't a complete program either, there is still a lot of code to say show an Icon Bar icon, and to generate and show the menu when the user clicks onto it. Least to say, I wouldn't recommend making a program in this manner on RISC-OS, unless you really needed to do something very custom, or to create a simple wrapper launcher for a full-screen application. It does have it's uses.

Speaking of a launcher for a full-screen application. I did mention in a previous post about creating an updated Adventure Kernel which would be loaded into the Icon Bar and be-able to start, suspend, and even result a game in progress. I was able to do this, and will post the code shortly to my GitHub. This version of the Adventure Kernel uses this method to create a RISC-OS application over the next ones I will bring up. I did need to figure out how to change the screen mode back to the Wimp when suspending the game. This can be done using this sample code:

DEF PROCStartGame
SYS "OS_ScreenMode",1 TO ,mode%
MODE 3
......
PROCGameLoop
......
SYS "Wimp_SetMode",mode%
ENDPROC

This only seems to work in RISC-OS 3.60 or higher though, making it more difficult to switch the screen mode back after returning to the desktop in earlier versions of RISC-OS.

DrWimp Hello World

Using a library on any operating system makes creating application much much more easier. DrWimp is a fairly easy to use library which makes performing all the tedium of using Templates a snap. While not the entire program, I will show some of the most important event callbacks here from the library to show how much simpler it is to use this over the previous BBC BASIC only approach:

DEF PROCuser_initialise
hellowin%=FNwimp_loadwindow("<DrHello$Dir>.Templates", "HelloWin", 0)
iconbar%=FNwimp_iconbar("!DrHello","",1,1)
iconbarmenu%=FNwimp_createmenu("DrHello/Quit",0)
ENDPROC

This does a similar thing to what we saw in the BBC example above, where it will load in the named template file, and load the named template from that file into a handle variable. Unlike the other example, this one also initialises the Icon Bar icon and it's menu.

DEF PROCuser_mouseclick(window%,icon%,button%,workx%,worky%)
CASE window% OF
  WHEN iconbar%: PROCwimp_openwindow(hellowin%,1,-1)
ENDCASE
ENDPROC

DEF FNuser_menu(window%,icon%,screenx%,screeny%)
return%=0
CASE window% OF
  WHEN iconbar%: return%=iconbarmenu%
ENDCASE
=return%

DEF PROCuser_menuselection(menu%,item%,font$)
CASE menu% OF
  WHEN iconbarmenu%
    CASE item% OF
      WHEN FNwimp_menusize(iconbarmenu%): PROCwimp_quit(0)
    ENDCASE
ENDCASE
ENDPROC

That is almost all the code you actually need to make a DrWimp RISC-OS GUI Hello World application actually work! The actual text of Hello World is set inside the Templates, if you were curious. It's fairly simple overall, and not too much code. Now, what if I told you that you can actually create a Hello World application in RISC-OS with absolutely zero code? Well, in the next section, I'll discuss what makes the RISC-OS Toolbox so great! From what I've seen, it is possible to run most DrWimp made programs in at least RISC-OS 3.10.

AppBasic Hello World

With AppBasic, most of the heavy lifting is actually done by both AppBasic, and the RISC-OS Toolbox. This ToolBox is a recent addition to RISC-OS, well, recent as in RISC-OS 3.10, and in theory should actually supersede the use of Templates. ToolBox applications instead use what are called Resource files, and are loaded alongside the application with the ToolBox system calls. This actually can make your application more efficient, as a majority of the applications code for handling the WIMP/GUI is entirely run from within the ToolBox modules, which are written in machine code. This can allow for frameworks like AppBasic to be much more faster than it may at first appear on the surface. As this Hello World only uses Resource files, I won't be-able to show any code snippets, as there won't be any. However, I will try to explain how it's put together using a Resource file, and perhaps paste in the textual version of the Resource file below for completeness.

Firstly, you'll of course need a Resource Editor, currently the main one used with RISC-OS development is !ResEd. At first it might seem similar to the above !WinEd, but it can manage more than just Window templates, it can manage a lot of ToolBox components. You'll first start by creating a new app in AppBasic, then opening up it's Res file using your Resource Editor. It will already contain some pre-made resources, such as the Iconbar, ibarmenu, and ProgInfo. The IconBar should be obvious on what it represents, and actually has a link to open the ibarmenu without needing to use any code. The ibarmenu is the menu which pops up when you middle-click onto the icon itself, which contains a few items right away, namely Info and Quit. The Info item is linked in the resource to open the ProgInfo without using any code, and the Quit is set to quit the application, again, without any needed code to be written.

In here, all you need to do now is create a new Window via pressing the middle mouse button to open the menu, and choose Prototypes.... This will open a new window which lists a bunch of ToolBox components, find and drag in the Window to the main resource window where all the other resources are. This will create a new Window resource. If you open it, you'll be-able to set various properties via the middle click menu, along with opening another window for Gadgets.... Go ahead and set up the various window properties, such as the title and such, I'll patiently wait here for your return.

In the Gadgets window, you should drag for example a Label into your new window and place some nice Hello World text into it. Once you are done creating your Hello World window, open up the Iconbar resource. In here you will see several options, look for Select button, and click in the Show object toggle switch. This will enable the field right next to it. For this field, find your Window resource you previous made, and drag it's icon from the resource list window into this textbox, and it should populate with the name. You can now press Okay to confirm the changes to the Iconbar resource.

The next thing you'll want to do is save the resource file back to disc using the right mouse button to select Save. Okay, that's it, we're done! Now, just run your Hello World program. If you click onto the icon in the Icon Bar, your Hello World window you just designed in the resource editor should just appear, and the other options in the menu will work as well.

That is how easy and quickly you can create a Hello World application using AppBasic. To make buttons and other gadgets actually do things, then you will need to code those parts yourself, but AppBasic actually makes all these event callbacks fairly easy to understand and use from what I've been seeing by going through it's various documentation and trying out a few things myself.

One last thing I should note, is if you want to be-able to run your AppBasic program without AppBasic itself being present on the machine, you'll have to use the Compress option from the application's main toolbar to turn off the debugging components that will make the application require that AppBasic is present.

RESF:1.01

iconbar_object {
  header_flags:toolbox_OBJECT_CREATE_ON_LOAD | toolbox_OBJECT_SHOW_ON_CREATE
  version:100
  object_name:"Iconbar"
  iconbar_flags:iconbar_GENERATE_SELECT_CLICKED | iconbar_GENERATE_ADJUST_CLICKED
  position:wimp_ICON_BAR_RIGHT
  priority:0
  sprite_name:"!BasicApp"
  sprite_limit:*
  text:""
  text_limit:*
  menu:"ibarmenu"
  select_action:&0
  adjust_action:&0
  select_show:"HelloWin"
  adjust_show:""
  help_message:""
  help_limit:*
}

menu_object {
  header_flags:
  version:102
  object_name:"ibarmenu"
  menu_flags:
  title:"BasicApp"
  title_limit:*
  help:""
  help_limit:*
  show_action:
  hide_action:
  Entry {
    cmp:0
    flags:menu_ENTRY_SUB_MENU
    cmp:&0
    text:"Info"
    text_limit:*
    click_object_name:""
    sub_menu_object_name:"ProgInfo"
    sub_menu_action:&0
    click_action:&0
    help:""
    help_limit:*
  }
  Entry {
    cmp:1
    flags:
    cmp:&1
    text:"Quit"
    text_limit:*
    click_object_name:""
    sub_menu_object_name:""
    sub_menu_action:&0
    click_action:&82a91
    help:""
    help_limit:*
  }
}

proginfo_object {
  header_flags:
  version:100
  object_name:"ProgInfo"
  proginfo_flags:proginfo_GENERATE_ABOUT_TO_BE_SHOWN
  title:""
  title_limit:*
  purpose:"Riscos Application"
  author:"© Kevin Veroneau"
  licence_type:None
  prog_version:"0.01 (20-Apr-26)"
  alternative_window_name:""
}

window_object {
  header_flags:
  version:102
  object_name:"HelloWin"
  window_flags:window_AUTO_OPEN | window_AUTO_CLOSE
  help_message:""
  help_limit:*
  sprite_name:""
  pointer_limit:0
  hotspot:0,0
  menu_name:"ibarmenu"
  default_focus:toolbox_NULL_COMPONENT
  show_action:
  hide_action:
  toolbar_ibl:""
  toolbar_itl:""
  toolbar_ebl:""
  toolbar_etl:""
  window.visible:316,1172,1008,1596
  window.xscroll:0
  window.yscroll:0
  window.next:wimp_TOP
  window.flags:wimp_WINDOW_MOVEABLE | wimp_WINDOW_AUTO_REDRAW | wimp_WINDOW_BACK_ICON | wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_SIZE_ICON | wimp_WINDOW_NEW_FORMAT
  window.title_fg:wimp_COLOUR_BLACK
  window.title_bg:wimp_COLOUR_LIGHT_GREY
  window.work_fg:wimp_COLOUR_BLACK
  window.work_bg:wimp_COLOUR_VERY_LIGHT_GREY
  window.scroll_outer:wimp_COLOUR_MID_LIGHT_GREY
  window.scroll_inner:wimp_COLOUR_VERY_LIGHT_GREY
  window.highlight_bg:wimp_COLOUR_CREAM
  window.extra_flags:
  window.extent:0,-1024,1280,0
  window.title_flags:wimp_ICON_TEXT | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | wimp_ICON_INDIRECTED
  window.work_flags:
  window.sprite_area:&ffffffff
  window.xmin:100
  window.ymin:100
  window.title_text:"Hello Window"
  window.title_text_limit:*
  window.title_valid:""
  label_object {
    cmp:&0
    bbox:144,-220,560,-168
    help_message:""
    help_limit:*
    flags:label_NO_BOX | label_HCENTRED
    label:"Hello world from AppBasic!"
  }
}

What's Next?

Well, as I did mention in a previous post, I'd love to bring Adventure Kernel onto the RISC-OS desktop, and now with what I've learned, I should now be-able to perform that feat. In a future post, I will be going through how I created both the game player and the game editor as a native RISC-OS application.

#bbcbasic #riscos