Welcome to the programming guide of OPL, the programming language for EPOC and Symbian OS. I will explain things carefully for you, and therefore this tutorial is aimed at complete beginners in programming.
So you could start programming OPL, you must have an environment, where you can run your code. You have two choices: the device itself (e.g. Nokia 9300) or the device's emulator for Windows (comes with the SDK). The emulator on Windows doesn't run at the same speed as the device, so especially when making games, the results can vary very much between the emulator and the device.
1. Installing onto the device
- download the latest OPL programming kit from http://opl-dev.sourceforge.net/opldev.html
- read the readme file in the ZIP archive and follow the instructions
2. Installing onto the emulator
- get the device's SDK from Forum Nokia and install it
- download the latest OPL programming kit from http://opl-dev.sourceforge.net/opldev.html
- read the readme file in the ZIP archive and follow the instructions
Now your programming environment is ready, so you can start programming.
I'll give you little hint, which makes the programming on the emulator faster: don't write your code on the emulator, but open a text file and save it to "C:\Symbian\7.0s\S80_DP2_0\epoc32\wins\c\" or equivalent in your own SDK. Write or copy-paste your code into this file, and open it every time in the emulator's OPL text editor by pressing CTRL + SHIFT + I simultaneously. This trick shows to be very handy before long, because you can't copy-pastetext from Windows into the emulator.
Compiler, which I will be using universally in the text, is a "robot", which interprets the OPL language into machine code (...01101011100...), which the device understands.
I will be using the user interface Series 80 v2.0 in my examples, so the screenshots are taken from its emulator.
The word printing I use, when a code shows something on the screen, e.g. text.
The word procedure I will also use - don't get blurred from it - it means a basic element of the programming language - a PROC chunk (which can be used multiple times in the code), which ends in a ENDP command.
You can stop an OPL program running on the emulator by pressing CTRL + ESC buttons simultaneously, and SHIFT + ESC on the device.
Let our program be an easy and simple code block, which shows a text string "Hello, world!" on the screen (a classic programming example):
PROC HelloWorld:
PRINT "Hello, world!"
PAUSE 40
ENDP
To translate the program you must open a program called TextEd or Program on the emulator or phone, write the code into the text area and press the "Translate" button (or the button combination CTRL + L)
A screenshot of the program:

Let's examine the code.
Now you have seen how programming in OPL works in practice. That code chunk is still only a beginning of what you can do with OPL. So follow this guide.
Although the word variable may sound a little boring, it is one of the basic things in programming. A variable is a particle, which can be used to store data, and its value can be modified.
So this wouldn't go too theoretical, let's get our hands dirty: we'll do an addition calculation with variables and print it onto the screen.
PROC Variables:
LOCAL A%, B%, C%
A% = 10
B% = 8
C% = A% + B%
PRINT C%
PAUSE 40
ENDP
Screenshot:

Now we have somewhat more complex code in front of us, but it's nothing, as we will go through it carefully.
All %-ending variables are for storing integers between -32768 - 32767. But what if we want to store bigger values into the variables or even letters? Then we just use a different ending sign than %. Below is a table of all OPL's variable types.
| Variable | Marginal | Ending sign | Else |
|---|---|---|---|
| Small number | -32768 - 32767 | % | An integer |
| Large number | -2147483647 - 2147483648 | & | An integer |
| Floating point number | 2,2250738585072015E-308 - 1,7976931348623157E+308 | Nothing | A decimal number |
| Character string | All letters, numbers and special signs. | $ | Can hold up to 255 characters. |
But if a floating point number can be used to store integers also, then why shouldn't we use always floating point numbers. Well, because a floating point number uses a lot more memory than a small number. For example, if you want to store human age values into a variable, you should use small number variables. Let us look into this subject in the next code block. The program 2½ follows.
PROC Variables2:
LOCAL HouseAge%, HousePrice&, HouseHeight, HouseName$(5)
HouseAge% = 38
HousePrice& = 135000
HouseHeight = 5.5
HouseName$ = "Smith"
PRINT "House's age:",HouseAge%,"y"
PRINT "House's price:",HousePrice&,"$"
PRINT "House's height:",HouseHeight,"m"
PRINT "House's name:",HouseName$
PAUSE 40
ENDP
Screenshot:

This one left us a lot of information to analyse.
Now we have used all of OPL's variable types. I can quickly tell you that if you want to modify the variable's value, then just write a new row identical to those where the value is saved into the variable. You can change the variable's value as many times as you wish.
A vital part of a mature program is interactivity. What kind of e.g. a game would be if a user couldn't do nothing by pressing buttons or by moving mouse? The game would just go forward with its own pace or be stuck in one place all the time. The player would lose his interest in a short while.
Let's build a program where the user can input the data of his own house. Finally the program prints the data onto the screen.
PROC Interactivity:
LOCAL HouseAge%, HousePrice&, HouseHeight, HouseName$(50)
PRINT "House's age:",
INPUT HouseAge%
PRINT "House's price:",
INPUT HousePrice&
PRINT "House height:",
INPUT HouseHeight
PRINT "House's name:",
INPUT HouseName$
CLS
PRINT "House's age:",HouseAge%,"y"
PRINT "House's price:",HousePrice&,"$"
PRINT "House height:",HouseHeight,"m"
PRINT "House's name:",HouseName$
GET
ENDP
A screenshot of my own values:

Once again, we have some new commands in the code.
I'll have to tell you that the INPUT command doesn't work on S60 phones at all.
Now we have got very good knowledge on how to make interactive programs, but how about graphics? Let's move on.
One of the basic elements of today's programs is graphics. I can't name any Windows program that has no image file. So images are pretty important pieces of a program, although they are not compulsory.
I will load a 640 x 200 pixels large image file onto the S80 v2.0 emulator's screen. The image is in MBM format, which is the EPOC's and Symbian OS's native image format. You can download it here. A quick guide follows, which teaches you to convert images from BMP to MBM with a Windows command line tool called BMCONV.
PROC ImageLoad:
LOCAL Image%
Image% = gLOADBIT("C:\Image.mbm")
gUSE 1
gAT 0,0
gCOPY Image%,0,0,640,200,0
gCLOSE Image%
GET
ENDP
Screenshot:

This time we have some difficult commands - five of them! How could we figure these out?
Below is a help image for the gCOPY command. We ensuingly want to copy an area from the image, which starts from the pixels 120 x and 20 y, and stops at the pixels 463 x and 153 y. The image below shows the area inside a box. Your duty is to make a gCOPY command out of this, and the answer lies below the image.

The answer is: gCOPY Image%,120,20,463,153,0. If you knew this one, you're skilled. The boxed area looked like this when it would be copied onto the screen (and the gAT command's parameters were 0,0):

It might take some time for you to learn how to load an image, just like in my case. Finally you will learn it, when you have written the code a few dozen times.
Our fifth program deals with conditional statements - the basis of artificial intelligence. Conditional statements grant the possibility of choices for the program's user. The user might want e.g. go playing or read the instructions. This is where the conditional statements enter the stage.
The artificial intelligence works e.g. like this, written in pseudocode:
IF UserPressing = Game
StartGame:
BUT IF UserPressing = Instructions
Instructions:
ELSE
AskNewPressing:
Let's make an OPL program, which asks for your opinion about Coca-Cola and Pepsi.
PROC ConditionalStatements:
LOCAL Pressing%
PRINT "Which one do you prefer: Pepsi or Coca-Cola?"
PRINT "Press 1, if you like Pepsi more and 2, if Coca-Cola."
PRINT ""
Pressing% = GET
IF Pressing% = 49
PRINT "So Pepsi is for you."
ELSEIF Pressing% = 50
PRINT "Coca-Cola. Good choice."
ELSE
PRINT "Not selectable."
ENDIF
GET
ENDP
A screenshot of my Coca-Cola positive selection:

So, now we have managed to make a simple conditional statement program. It works like a charm. Let's analyse the code, shall we?
Here was the tutorial so far. I'm sure you will get started with this guide, and you might get some ideas from it. If this tutorial shows some popularity, I will gladly write more about this subject. Below are coincidental things about OPL.
| Character | SHIFT + character | Code (character) | Code (SHIFT + character) |
|---|---|---|---|
| Enter | (nothing) | 13 | (nothing) |
| Esc | (nothing) | 27 | (nothing) |
| Space | (nothing) | 32 | (nothing) |
| Backspace | (nothing) | 8 | (nothing) |
| 0 | = | 48 | 61 |
| 1 | ! | 49 | 33 |
| 2 | " | 50 | 34 |
| 3 | # | 51 | 35 |
| 4 | ¤ | 52 | 164 |
| 5 | % | 53 | 37 |
| 6 | & | 54 | 38 |
| 7 | / | 55 | 47 |
| 8 | ( | 56 | 40 |
| 9 | ) | 57 | 41 |
| . | : | 46 | 58 |
| , | ; | 44 | 59 |
| - | _ | 45 | 95 |
| + | ? | 43 | 63 |
| * | (nothing) | 42 | (nothing) |
| a | A | 97 | 65 |
| b | B | 98 | 66 |
| c | C | 99 | 67 |
| d | D | 100 | 68 |
| e | E | 101 | 69 |
| f | F | 102 | 70 |
| g | G | 103 | 71 |
| h | H | 104 | 72 |
| i | I | 105 | 73 |
| j | J | 106 | 74 |
| k | K | 107 | 75 |
| l | L | 108 | 76 |
| m | M | 109 | 77 |
| n | N | 110 | 78 |
| o | O | 111 | 79 |
| p | P | 112 | 80 |
| q | Q | 113 | 81 |
| r | R | 114 | 82 |
| s | S | 115 | 83 |
| t | T | 116 | 84 |
| u | U | 117 | 85 |
| v | V | 118 | 86 |
| w | W | 119 | 87 |
| x | X | 120 | 88 |
| y | Y | 121 | 89 |
| z | Z | 122 | 90 |
More character codes can be found with this piece of code (you can exit the program by pressing Esc).
PROC CharacterCodes:
LOCAL Pressing%
DO
Pressing% = GET
PRINT Pressing%
UNTIL Pressing% = 27
ENDP