OPL-ohjelmointiopas

Tervetuloa ensimmäisen ja ainoan suomalaisen OPL-ohjelmointioppaan pariin oppimaan perusasioita tästä EPOC:ssa ja Symbian OS:ssa toimivasta ohjelmointikielestä.

Ohjelmointiympäristö

Jotta voisit aloittaa OPL:llä ohjelmoimisen, sinulla tulee olla ympäristö, jossa voit ajaa koodiasi. Sinulla on kaksi vaihtoehtoa, joista valita: laite itse (esim. Nokia 9300) tai Windowsissa toimiva laitteen emulaattori (SDK:ssa mukana). Windows-emulaattori ei toimi samalla nopeudella kuin puhelin, joten varsinkin pelejä tehdessä voivat tulokset vaihdella emulaattorin ja puhelimen välillä valtavasti.

1. Puhelimeen asentaminen
- lataa viimeisin OPL-ohjelmointipakkaus osoitteesta http://opl-dev.sourceforge.net/opldev.html
- lue ZIP-arkiston readme-tiedosto ja seuraa ohjeita

2. Tietokoneen emulaattorille asentaminen
- hae puhelimen SDK Forum Nokiasta ja asenna se
- lataa viimeisin OPL-ohjelmointipakkaus osoitteesta http://opl-dev.sourceforge.net/opldev.html
- lue ZIP-arkiston readme-tiedosto ja seuraa ohjeita

Nyt ohjelmointiympäristösi on valmiina, joten voit alkaa ohjelmoimaan.

Muutamia ohjeita

Annan pienen vinkin, jolla voit nopeuttaa emulaattorilla ohjelmoimista: älä kirjoita koodia emulaattorilla, vaan avaa Windowsissa tekstitiedosto ja tallenna se polkuun "C:\Symbian\7.0s\S80_DP2_0\epoc32\wins\c\" tai vastaavaan osoitteeseen omassa SDK:ssasi. Kirjoita tai copy-pasteta tähän tiedostoon koodisi ja avaa se joka kerta emulaattorin OPL-tekstieditorilla painamalla nappeja CTRL, SHIFT ja I yhtä aikaa. Tämä kikka osoittautuu ennen pitkää erittäin hyödylliseksi, sillä et voi copy-pastettaa Windows-ympäristöstä tekstiä puhelimen emulaattorille.

Kääntäjä, jota varmasti käytän yleisesti tekstissä, on "robotti", joka tulkkaa OPL-koodin konekieleksi (...01101011100...), jota laite ymmärtää.

Käytän esimerkeissäni Series 80 v2.0 -käyttöliittymää, joten näyttökaappaukset ovat otettu sen emulaattorissa.

Sanaa tulostaminen käytän, kun koodinpätkä tuo laitteen näytölle jotain materiaalia.

Sanaa proseduuria käytän myös - älä hämäänny siitä - se tarkoittaa yhtä ohjelman perusosasta - PROC-lohkoa (joita voi lähdetiedostossa voi olla useita), joka päättyy ENDP-komentoon.

OPL-ohjelman suorittamisen voi katkaista emulaattorilla näppäinyhdistelmällä CTRL + ESC ja laitteessa yhdistelmällä SHIFT + ESC.

Ensimmäinen ohjelma - tekstin tulostaminen näytölle

Olkoon ensimmäinen ohjelmamme helppo ja yksinkertainen koodinpätkä, joka näyttää ruudulla tekstin "Hello, world!" (klassinen ohjelmointiesimerkkiohjelma):

   PROC HelloWorld:
     PRINT "Hello, world!"
     PAUSE 40
   ENDP

Kääntääksesi ohjelman sinun tulee avata TextEd- tai Program-niminen ohjelma emulaattorilla tai puhelimessa, kirjoittaa ylläoleva koodi tekstikenttään ja painaa "Translate"-nappia (tai näppäinyhdistelmää CTRL + L).

Näyttökaappaus käännetystä ohjelmasta:

Käydään ohjelma läpi.

  • ensimmäisen rivin PROC kertoo kääntäjälle, että ohjelma alkaa tästä. HelloWorld: kertoo ohjelman nimen (kaksoispiste tulee aina ohjelman nimen loppuun).
  • toisen rivin PRINT on käsky, jolla saa tulostettua näytölle mitä tahansa tekstiä. Tekstin on oltava lainausmerkkien sisällä, jotta se näkyisi.
  • PAUSE 40 käskee ohjelmaa pysäyttämään sen suorituksen kahden sekunnin ajaksi. Yksi PAUSE-yksikkö vastaa 1/20 sekuntia.
  • ENDP kertoo kääntäjälle, että ohjelma loppuu tähän.
  • Nyt näit, miten OPL:n ohjelmointi toimii käytännössä. Tuo koodinpätkä on kuitenkin vasta alku sille, mitä kaikkea OPL:llä voi tehdä. Seuraa siis perässä.

    Toinen ohjelma - muuttujat

    Vaikka sana muuttuja voi kuulostaa tylsältä, on se yksi ohjelmoinnin perusasioista. Muuttuja on osanen, johon voidaan tallentaa tietoa ja sen arvoa voidaan muuttaa.

    Jottei tämä kävisi turhan teoreettiseksi, liatkaamme kätemme: teemme yhteenlaskun muuttujien avulla ja tulostamme sen näytölle.

       PROC Muuttujat:
         LOCAL A%, B%, C%
         A% = 10
         B% = 8
         C% = A% + B%
         PRINT C%
         PAUSE 40
       ENDP

    Näyttökaappaus:

    Nyt tuli vastaan vähän monimutkaisempaa koodia, mutta ei se mitään, käymme taas tutulla tavalla sen läpi.

  • ensimmäinen rivi on jo vanhaa kauraa.
  • toinen rivi käy kiintoisaksi. LOCAL kertoo kääntäjälle, että sitä seuraavat muuttujat (A%, B% ja C%) ovat tälle kyseiselle proseduurille paikallisia. Ne toimivat siis vain tässä proseduurissa, eivät muissa. LOCAL:n vastakohta on GLOBAL, jonka muuttujat toimivat kaikissa proseduureissa.
  • ihmettelet varmasti, mitä prosenttimerkki muuttujiemme A, B ja C edessä tekevät. Ne merkitsevät lukuhaarukkaa, jonka väliltä lukuja voidaan tallentaa muuttujaan. % tarkoittaa kokonaislukua (integer) väliltä -32768 - 32767. Voimme tallentaa %-merkillisiin muuttujiin siis suurimmillaan luvun 32767.
  • kolmas ja neljäs rivi ovat muuttujien lukuarvojen tallentamista varten. OPL:ssä muuttujien arvojen tallentaminen ja niiden muuttaminen on näin helppoa.
  • viides rivi tekee A%- ja B%-muuttujien yhteenlaskun ja tallentaa sen C%-muuttujaan.
  • kuudes rivi tulostaa C%-muuttujan arvon näytölle, eli luvun 18, jos laskin oikein. PRINT-komento voi siis tulostaa muuttujien arvoja myös, mutta ne eivät voi tällöin olla lainausmerkkien sisällä. Muut rivit kävimmekin jo läpi.
  • %-loppuiset muuttujat ovat siis lukuarvojen -32768 - 32767 tallentamista varten. Mutta mitä, jos halutaan tallentaa muuttujiin vaikkapa suurempia numeroita tai jopa kirjaimista muodostuvia nimiä? Siihen käytetään sitten erilaista loppumerkkiä kuin %. Alla on taulukko kaikista OPL:n muuttujatyypeistä.

    MuuttujaHaarukkaLoppumerkkiMuuta
    Pieni luku-32768 - 32767%Kokonaisluku
    Suuri luku-2147483647 - 2147483648&Kokonaisluku
    Liukuluku2,2250738585072015E-308 - 1,7976931348623157E+308Ei mitäänDesimaaliluku
    KirjainjonoKaikki kirjaimet, numerot ja erikoismerkit$Voi pitää sisällään vain 255:ttä kirjainta enimmillään.

    Mutta jos liukuluku voi ajaa saman asian kuin pienikin luku, niin miksei voisi käyttää joka kerta liukulukuja? No sen vuoksi, kun liukuluku vie paljon enemmän muistia kuin pieni luku. Esimerkiksi jos haluat tallentaa muuttujaan ikäarvoja, käytä pieniä lukuja. Tutkikaamme tätä käytännössä, joten tehdään ohjelma, joka tulostaa erilaisia muuttuja-arvoja näytölle. Seuraa ohjelma numero 2½.

       PROC Muuttujat2:
         LOCAL TalonIka%, TalonHinta&, TalonKorkeus, TalonNimi$(8)
         TalonIka% = 38
         TalonHinta& = 69900
         TalonKorkeus = 5.5
         TalonNimi$ = "Honkanen"
         PRINT "Talon ikä:",TalonIka%,"v"
         PRINT "Talon hinta:",TalonHinta&,"euroa"
         PRINT "Talon korkeus:",TalonKorkeus,"m"
         PRINT "Talon nimi:",TalonNimi$
         PAUSE 40
       ENDP

    Näyttökaappaus:

    Tässäpä tulikin asiaa melko lailla.

  • toisella rivillä määritellään paikalliset muuttujat. Viimeinen tuottaa hieman päänvaivaa: miksi suluissa on numero kahdeksan? Se kuuluu OPL:n muuttujamäärittelyihin, ja se täytyy olla jokaisen kirjainjonomuuttujan ($) perässä. Suluissa oleva numero kertoo, kuinka monta kirjainta voi olla enimmillään tuossa muuttujassa. Tässä se on kahdeksan eli Honkanen-nimen kirjainmäärä.
  • rivit 3-6 antavat muuttujille arvot.
  • rivit 7-10 tulostavat lainausmerkkien sisällä olevat tekstit sekä jokaisten muuttujien arvot näytölle. Loput ovatkin jo aiemmin selitettyjä.
  • Nyt olemme käyttäneet kaikkia OPL:n muuttujatyyppejä. Äkkiä voin tässä mainita, että jos haluat muuttaa muuttujan arvoa, niin senkun vain kirjoitat esimerkiksi uuden tuollaisen rivin, jolla määritellään muuttuja. Voit muuttaa muuttujan arvoa niin monta kertaa kuin haluat.

    Kolmas ohjelma - käyttäjän näppäinpainallus

    Elintärkeä osa käyttövalmista ohjelmaa on interaktiivisuus eli vuorovaikutteisuus. Minkälainen olisi esimerkiksi peli, jossa käyttäjä ei voisi tehdä mitään painamalla näppäimiä tai liikuttelemalla hiirtä? Peli vain menisi eteenpäin omaa tahtiaan tai junnaisi paikoillaan, ja käyttäjä menettäisi mielenkiintonsa melko nopeasti.

    Aloitetaan siis tekemään ohjelmaa, jossa käyttäjä saa itse syöttää talonsa tiedot ohjelmaan. Lopuksi ohjelma tulostaa tiedot näytölle.

       PROC Interaktiivisuus:
         LOCAL TalonIka%, TalonHinta&, Talonkorkeus, TalonNimi$(50)
         PRINT "Talon ikä:",
         INPUT TalonIka%
         PRINT "Talon hinta:",
         INPUT TalonHinta&
         PRINT "Talon korkeus:",
         INPUT TalonKorkeus
         PRINT "Talon nimi:",
         INPUT TalonNimi$
         CLS
         PRINT "Talon ikä:",TalonIka%,"v"
         PRINT "Talon hinta:",TalonHinta&,"euroa"
         PRINT "Talon korkeus:",TalonKorkeus,"m"
         PRINT "Talon nimi:",TalonNimi$
         GET
       ENDP

    Näyttökaappaus omista arvoistani:

    Taas uusia komentoja näkyy olevan koodissa.

  • laitoin TalonNimi$-muuttujan enimmäiskirjainmääräksi 50, sillä en usko, että sitä pidempää talon nimeä löytyy.
  • INPUT on tässä se osanen, jota haetaan. INPUT:n avulla käyttäjältä saadaan nyhdettyä tieto ulos näppäimistön avulla. Meillä on INPUT:ssa yksi muuttuja, jonka arvon antaa käyttäjä.
  • CLS on komento, joka pyyhkii kaiken pois ruudulta.
  • GET-komento odottaa käyttäjän painavan nappia, jolloin se jatkaa ohjelman suoritusta. Meillä ei ole nyt mitään GET:n alapuolella koodissa, joten kääntäjä menee ENDP-komentoon, joka lopettaa ohjelmamme.
  • Huomautan, että INPUT ei valitettavasti toimi S60-puhelimissa lainkaan.

    Olemme näin saaneet jo hyvät perusainekset interaktiivisten ohjelmien tekoon, mutta entä grafiikat? Mennään eteen päin.

    Neljäs ohjelma - kuvan lataaminen

    Yksi nykyajan ohjelmien peruspilareista on grafiikka. En osaa nimetä mitään Windows-ohjelmaa, jossa ei olisi käytetty vähintään yhtä kuvaa. Kuvat ovat siis melko tärkeitä ohjelman palasia, vaikka ne eivät olekaan pakollisia.

    Lataan seuraavalla koodinpätkällä 640 x 200 pikselin kokoisen kuvan S80 v2.0 -emulaattorin näytölle. Kuva on MBM-formaatissa eli EPOC:n ja Symbianin omassa kuvatyypissä. Voit ladata sen tästä. Seuraavassa on nopea ohje, miten muunnetaan BMP:stä MBM-tiedostoja BMCONV-nimisellä komentoriviohjelmalla.

  • lataa BMCONV tästä.
  • avaa Windowsissa komentorivi (Käynnistä -> Ohjelmat -> Apuohjelmat -> Komentorivi)
  • mene komentorivissä kansioon, jossa BMP-tiedostosi on (cd-komennolla, esim. cd Kuvat (cd.. menee yhden kansion takaisin)).
  • kirjoita BMCONV [kuvatiedosto].mbm /c[bittimäärä][kuvatiedosto].bmp.
    Esimerkiksi komento voisi olla tällainen: BMCONV Kuva.mbm /c12Kuva.bmp. Bittimäärä määrää, kuinka monta väriä haluat kuvassa olevan (esim. 12-bittinen on 2^12 eli 4096 väriä).
  • jos komento antaa tulokseksi "Success", muunnos on onnistunut ja sinulla on nyt MBM-kuva kansiossasi.
  •    PROC KuvanLataus:
         LOCAL Kuva%
         Kuva% = gLOADBIT("C:\Kuva.mbm")
         gUSE 1
         gAT 0,0
         gCOPY Kuva%,0,0,640,200,0
         gCLOSE Kuva%
         GET
       ENDP

    Näyttökaappaus:

    Tällä kertaa menikin vaikeaksi - mukaan tuli jopa viisi uutta komentoa. Miten näistä saisi selvän?

  • toinen rivi määrittelee Kuva%-muuttujan, johon tallennetaan kuva.
  • kolmas rivi tallentaa Kuva.mbm-kuvan muuttujaan Kuva%. gLOADBIT-komentoa käytetään lataamaan kuvan tiedot. Kuvan täytyy olla MBM-muotoisena, sillä se on OPL:n oletusformaatti. Lisää tästä formaatista oli ylempänä.
  • gUSE 1 tarkoittaa, että sitä seuraavat grafiikkakomennot kohdistuvat nykyiseen näytöllä näkyvään ikkunaan.
  • gAT 0,0 kertoo kääntäjälle, mistä kohtaa näytöltä aloitetaan kuvan piirtäminen: 0,0 antaa arvot x = 0 ja y = 0, eli näytön vasen yläkulma.
  • gCOPY Kuva% kopioi ladatun kuvan (Kuva%) näytölle. Perässä tulee joukko lukuja, joiden syvällisen merkityksen kerron alla.
    - 0,0 merkitsee, mistä kohdasta kuvaa aletaan kopioimaan kuvan sisällä. Haluamme aloittaa kuvan ylävasemmalta, joten annamme arvot x = 0 ja y = 0.
    - 640,200 kertoo, mihin kohtaan kuvan kopioiminen lopetetaan. Kuvamme on 640 x 200 pikselin kokoinen ja haluamme kopioida sen kokonaan, joten annamme x-arvon 640 ja y-arvon 200. Tällöin kuvan kopioiminen lopetetaan kohtaan 640 x ja 200 y.
    - Viimeinen numero, 0, kertoo, että kuva asetetaan näytölle (esim. 1 kertoisi, että kuva pyyhitään näytöltä).
    - Tämä komento voi olla melko vaikea hahmottaa, joten alla on pieni avustuskuva, joka saattaa valaista asiaa paremmin.
  • gCLOSE Kuva% sulkee kuvan, jotta se ei enää vie muistia. Se on kopioitu muistiin ja sitä kautta näytölle, eikä sitä enää tarvita. Tämän vuoksi se voidaan sulkea.
  • Alla on avustuskuva gCOPY-komentoa varten. Haluamme seuraavasti kopioida kuvasta alueen, joka alkaa pikseleistä 120 x ja 20 y ja loppuu pikseleihin 463 x ja 153 y. Kuvassa on siis tuo alue laatikoituna. Tee tästä gCOPY-komento. Vastaus on kuvan alla.

    Vastaus on: gCOPY Kuva%,120,20,463,153,0. Jos tiesit tämän, olet etevä. Näytölle kopioituna tuo alue näyttäisi tältä (kun gAT-komennon arvot olisivat 0,0):

    Sinulla voi mennä kuvan lataamisen oppimiseen jonkin aikaa, niin kuin minullakin meni, mutta lopuksi se luonnistuu, kun on muutaman kymmentä kertaa kirjoittanut sen koodiin.

    Viides ohjelma - ehtolauseet

    Viides ohjelmamme käy läpi ehtolauseet - tekoälyn perustan. Ehtolauseet tekevät mahdolliseksi sen, että käyttäjällä on ohjelmassa valintoja. Käyttäjä voi esimerkiksi haluta mennä joko pelaamaan tai ohjeisiin pelin päävalikossa. Tällöin ehtolauseet tulevat esiin.

    Tekoäly toimii siis tekokoodilla kirjoitettuna tällä tavalla:

    JOS KäyttäjänPainallus = Peli
    AloitaPeli:
    MUTTA JOS KäyttäjänPainallus = Ohje
    Ohje:
    MUUTOIN
    KysyPainallustaUudestaan:

    Tehdään tästä OPL:n kielinen ohjelma, joka kysyy mielipidettäsi Coca-Colasta ja Pepsistä.

       PROC Ehtolauseet:
         LOCAL Painallus%
         PRINT "Pidätkö enemmän Pepsistä vai Coca-Colasta?"
         PRINT "Paina 1, jos pidät Pepsistä enemmän ja 2, jos Coca-Colasta."
         PRINT ""
         Painallus% = GET
         IF Painallus% = 49
           PRINT "Pepsi on siis mieleesi enemmän."
         ELSEIF Painallus% = 50
           PRINT "Coca-Cola. Hyvä valinta."
         ELSE
           PRINT "Ei valittavissa."
         ENDIF
         GET
       ENDP

    Näyttökaappaus omasta Coca-Cola-myötäisestä valinnastani:

    Näin olemme tehneet yksinkertaisen ehtolauseohjelman. Se toimii kuin junan vessa. Käydään koodi läpi yksityiskohtaisesti.

  • paikalliseksi muuttujaksi esitellään Painallus%, johon tallennetaan painalluksen arvo eli 1 tai 2.
  • viides rivi toimii rivinvaihtajana.
  • kuudes rivi on tärkeä - siinä asetetaan Painallus%-muuttujaan näppäinpainalluksen arvo GET-komennolla. GET-komento voidaan siis valjastaa toimimaan myös tällä tavoin.
  • seitsemäs rivi aloittaa ehtolauseen. Eli jos Painallus%:n arvo on 49, tulostetaan näytölle teksti "Pepsi on siis mieleesi enemmän." 49 merkitsee numeronäppäin 1:n näppäinkoodia S80-puhelimissa.
  • yhdeksäs ja kymmenes rivi tarkoittavat: mutta jos Painallus%:n arvo on 50, niin tulosta: "Coca-Cola. Hyvä valinta." S80-puhelimissa numeronäppäin 2:n koodi on 50. Lisää näppäinkoodeja on tämän sivun alalaidassa.
  • rivit yksitoista ja kaksitoista ovat suomeksi: "muutoin tulosta "Ei valittavissa.""
  • kolmannentoista rivin ENDIF päättää ehtolauseen.

  • Muuta OPL:een liittyvää

    Tässä olivat ohjeeni tältä erää. Pääset varmasti alkuun näillä ohjeilla ja ehkä saat jonkinlaisia ideoita niistä. Mikäli tällä oppaalla on jonkinnäköistä suosiota, kirjoitan mielelläni lisää aiheesta. Alla on satunnaisia OPL:een liittyviä asioita.

  • sisennä koodia tarpeen mukaan. Yleensä ehto- ja silmukkalauseiden komentojen (IF, ELSEIF, ELSE, DO, WHILE) sekä PROC-komentojen jälkeiset rivit sisennetään.
  • ensimmäinen PROC-lohko ylhäältä suoritetaan aina ensin OPL:ssä.
  • OPL:ssa grafiikkaan liittyvät komennot alkavat g-kirjaimella, esim. gLOADBIT.
  • kun ohjelmoit OPL:llä ja opit enemmän asioita siitä, sinun on helppo opetella uutta kieltä - esim. C++:ssa on yhtä lailla muuttujia ja ehtolauseita. Vaikka OPL onkin ehkä kuoleva ohjelmointikieli, ei sen opettelu ole turhaa, eivätkä opetellut asiat mene hukkaan.
  • OPL-guru Ewan Spence on kirjoittanut kirjan OPL:stä. Sen nimi on Rapid Mobile Enterprise Development for Symbian OS: An Introduction to OPL Application Design and Programming.
  • OPL:lle on tehty erittäin hyvä tekstieditorikin nimeltä OPeLo. Sen saa ladattua täältä ilmaiseksi.
  • S80-laitteiden näppäinkoodit

    NäppäinSHIFT + näppäinKoodi (näppäin)Koodi (SHIFT + näppäin)
    Enter(ei mitään)13(ei mitään)
    Esc(ei mitään)27(ei mitään)
    Space(ei mitään)32(ei mitään)
    Backspace(ei mitään)8(ei mitään)
    0=4861
    1!4933
    2"5034
    3#5135
    4¤52164
    5%5337
    6&5438
    7/5547
    8(5640
    9)5741
    .:4658
    ,;4459
    -_4595
    +?4363
    *(ei mitään)42(ei mitään)
    aA9765
    bB9866
    cC9967
    dD10068
    eE10169
    fF10270
    gG10371
    hH10472
    iI10573
    jJ10674
    kK10775
    lL10876
    mM10977
    nN11078
    oO11179
    pP11280
    qQ11381
    rR11482
    sS11583
    tT11684
    uU11785
    vV11886
    wW11987
    xX12088
    yY12189
    zZ12290
    åÅ229197
    äÄ228196
    öÖ246214

    Lisää näppäinkoodeja voit itse löytää alla olevalla koodinpätkällä (painamalla Esciä pääset pois ohjelman suorituksesta).

       PROC NappainKoodit:
         LOCAL Painallus%
         DO
           Painallus% = GET
           PRINT Painallus%
         UNTIL Painallus% = 27
       ENDP