SlideShare a Scribd company logo
1 of 176
Download to read offline
mopoid

    Symbian OS Workshop




1        Andreas Jakl, 2009   v2.4.1 – 19 April 2009
Disclaimer
●   These slides are provided free of charge at http://www.symbianresources.com and are used
    during Symbian OS courses at the University of Applied Sciences in Hagenberg, Austria
    ( http://www.fh-hagenberg.at/ )
●   Respecting the copyright laws, you are allowed to use them:
         for your own, personal, non-commercial use
         in the academic environment
●   In all other cases (e.g. for commercial training), please contact andreas.jakl@fh-hagenberg.at
●   The correctness of the contents of these materials cannot be guaranteed. Andreas Jakl is not liable
    for incorrect information or damage that may arise from using the materials.
●   Parts of these materials are based on information from Symbian Press-books published by John
    Wiley & Sons, Ltd. This document contains copyright materials which are proprietary to Symbian,
    UIQ, Nokia and SonyEricsson. “S60™” is a trademark of Nokia. “UIQ™” is a trademark of UIQ
    Technology. Pictures of mobile phones or applications are copyright their respective manufacturers /
    developers. “Symbian ™”, “Symbian OS ™” and all other Symbian-based marks and logos are
    trademarks of Symbian Software Limited and are used under license. © Symbian Software Limited
    2006.




        2                                   Andreas Jakl, 2009
Motivation

●   Why C++ for Symbian OS / S60?


      High performance
      (Nearly) unlimited possibilities


       Ideal platform for innovative projects!


●   Bonus: increase your value on the market with Symbian
    OS knowledge
      3                     Andreas Jakl, 2009
Schedule

●   Instead of theory, we’ll do a practical project




      4                    Andreas Jakl, 2009
Mopoid

●   Tasks                                           Defining and displaying text,
                                                    fonts, descriptors
      Create your own application
      using the UI designer                         Using vector graphics
      Define a menu and an about                    Scalable UI
      box                                           Asynchronous events,
      Leaves, Panics and Cleanup                    timers
      Stack                                         Key handling
      Project structure, libraries                  Files, data caging (platform
      Class types, naming                           security)
      conventions                                   Foreground / background
                                                    Dynamic menu
      5                        Andreas Jakl, 2009
Conventions

●   Slides are a mixture of explanations and tasks you have
    to do
      TODOs are marked on the left side of the slides
      After the game framework is imported, source code edits
      are also marked with a // TODO: comment
          // TODO: Refresh back light timer

      Slides with explanations of specific Symbian OS
      concepts are marked in the upper right corner


      6                     Andreas Jakl, 2009
IDEs – Carbide.c++

             ●   Carbide.c++ (based on Eclipse)
                    New main development platform
                    Integrates Eclipse with required tools
             ●   Editions:
                    Express: basic
                    Developer: UI-designer,
                    on-device debugging
                    Professional: Performance tools
                    OEM: ROM and JTAG support
                    (all free starting with Carbide.c++ 2.0)
7                      Andreas Jakl, 2009
Carbide.c++




8                 Andreas Jakl, 2009
S60 SDKs
                                            SDK            OS version   Devices
                                            1st Ed.        v6.0         7650
●   Choose SDK depending on                 1st Ed, FP 1   v6.1         N-Gage, SX1,
                                                                        3650, Sendo-
    required compatibility and                                          X, …
    features                                2nd Ed         v7.0s        6600, …
                                            2nd Ed, FP 1 v7.0s          7610, 6670,
●   Binary compatibility break                                          6260, …
    with Symbian OS 9                       2nd Ed, FP 2 v8.0           6630, 6680,
                                                                        6681, …
●   www.forum.nokia.com                     2nd Ed, FP 3 v8.1           N70, N90, …
                                            3rd Ed         v9.1         E61, N73,
                                                                        N75, …
                Commonly used for
                                            3rd Ed, FP 1   v9.2         N95, E90, …
               maximum compatibility
                                            3rd Ed, FP 2   v9.3         N96, N78, …
                                            5th Ed         v9.4         5800, N97, …
                 Introduces touch
                                            5th Ed, FP1    v9.5?        ?
                   screens to S60
      9                       Andreas Jakl, 2009
Installation

1.     Carbide.c++ 2.0 Developer Edition (or later)
       http://www.forum.nokia.com/main/resources/tools_and_sdks/car
       bide/index.html

2.     Perl 5.6.x (Set the path variable!) – not 5.8 / 5.10!
       http://downloads.activestate.com/ActivePerl/Windows/5.6/Active
       Perl-5.6.1.638-MSWin32-x86.msi

3.     SDK(s) (S60 3rd Ed. MR + newer)
       http://www.forum.nokia.com/Resources_and_Information/Tools/
       Platforms/S60_Platform_SDKs/

      Install all tools on the same drive (recommended: C:, no network drive!)

        10                         Andreas Jakl, 2009
Updating Carbide.c++
●   Go to:
       Help  Software Updates  Find and Install ...
       Search for new features to install
●   Only install updates from the Carbide.c++ update site!
       Updating other components might overwrite Carbide.c++ settings!




      11                             Andreas Jakl, 2009
Workspace

●   Workspace location:
      Has to be on the same drive as the SDK (   C:)
      Must not contain space characters
      Example: C:Symbiandev




     12                   Andreas Jakl, 2009
Create new project

●   File  New  C++ Application for S60 Project




     13                  Andreas Jakl, 2009
Create new project

●   Call it: Mopoid
●   Check again if the path is really on the SDK drive (C:)
    and does not contain space characters!




     14                   Andreas Jakl, 2009
Phone Build

                            ●   Build configurations:
                                        WINSCW: Build for the
                                        windows-based emulator
                                        ARMV5: Optimized builds for
                                        the device using the ARM
                                        RealView-compiler
                                        (commercial)
                                        GCCE: Standard builds for the
                                        device using the free GCC(E)
                                        compiler. Comes with the
                                        SDK

15                 Andreas Jakl, 2009
Choose UI-Design

●   Select the empty design
      We’ll do low level graphics
      on an empty canvas




     16                       Andreas Jakl, 2009
Application UID (UID3)

●   Development for v9:
    0xE0000000 - 0xEFFFFFFF
       Development UID automatically
       assigned by Carbide
●   Get UIDs for public
    applications:                            Range                     Purpose

       Different range for signed /          0x00000000 – 0x0FFFFFFF   Development use (< v9)

       unsigned                              0x10000000 – 0x1FFFFFFF   Legacy UID (pre-v9)
                                             0x20000000 – 0x2FFFFFFF   v9 protected UIDs
       Get one for free at:
                                             0xA0000000 – 0xAFFFFFFF   v9 unprotected UIDs
       http://www.symbiansigned.com/
                                             0xE0000000 – 0xEFFFFFFF   Development use (v9)
                                             0xF0000000 – 0xFFFFFFFF   Legacy UID (pre-v9)

      17                         Andreas Jakl, 2009
Our Project




18                 Andreas Jakl, 2009
UI-Components

●   Window
      Sub-component of the device screen
      Principal window filling up entire screen
      Not used for display
      Can contain many panes
●   Pane
      Sub-component of a window
      Can contain many sub-panes

     19                      Andreas Jakl, 2009
S60 UI

                               ●    Status Pane
              Status Pane                Information about running
                                         application & device (e.g.
              Main Pane                  battery strength)
                               ●    Main Pane
              Control Pane
                                         Application content
                               ●    Control Pane
                                         Softkey labels


20                           Andreas Jakl, 2009
First tests

Compile


    21        Andreas Jakl, 2009
Choose Build Target

●   Active Build Configuration  Emulator




     22                  Andreas Jakl, 2009
You can only use the
                                               mouse to navigate on the
          Compile Project                       screen on touch-enabled
                                               emulators! Otherwise, use
                                                   the buttons below.
●   (optional) Project  Build Project
●   Run  Run
●   Or:




     23                   Andreas Jakl, 2009
Launch Configuration

●   Launch: Mopoid.exe
       Game is directly started in the
       emulator
       Emulator shuts down when
       app exits
●   Launch: Emulator
       Start game manually from the
       menu
       Adv.: recompile without closing
       the emulator, error messages
       on app shutdown more visible
●   Available from:
    Carbide.c++ 1.3.1+
    with SDKs > S60 3rd MR
      24                          Andreas Jakl, 2009
Possible Problems
                            ***Generating makefiles.
                            bldmake.bat bldfiles WINSCW UDEB
                            WARNING: EPOCROOT does not specify an existing directory
●   Compilation error:      BLDMAKE ERROR: Directory "Symbian9.1S60_3rd_MREPOC32" does not exist

                            Total Time: 0 sec
                            ===Build Command = build WINSCW UDEB -v===
                            Exec error:Launching failed***build returned with exit value = -1
                            ***Stopping. Check the Problems view or Console output for errors.
                            -1




     your workspace / project is not on the same drive as
    the Symbian OS SDK (usually C:)
    (told you to put it there several times )

     25                  Andreas Jakl, 2009
Emulator

●   Application added to the end of the list in the “Installat.”
    folder
●   Can be moved with “Options  Move *to folder+”
●   Useful when working on the same project for some time




      26                     Andreas Jakl, 2009
Building for the Device

●   Change build configuration to Phone Release (GCCE)
●   .sisx-file created in /sis/-folder of your project
●   Send to device using PC Suite or Bluetooth




      27                    Andreas Jakl, 2009
.sis vs .sisx

●   Both have been created, installing .sis:
●   .sisx = signed version of the .sis
●   Without a valid certificate: self-signed
    with automatically generated
    certificate
●   Installation of self-signed applications
    not allowed by default on some
    devices
       Change: Application manager 
       Software installation  change from
       “Signed only” to “All”
      28                     Andreas Jakl, 2009
Own Build Configurations for Devices

●   When importing a project or adding a build
    configuration (= SDK) later on:
      Right-click the project  Properties  Carbide.c++ 
      Carbide Build Configurations
      Check that the current configuration is “Phone Release
      (GCCE)” for the S60 3rd Ed. MR-SDK
      Go to the “SIS Builder”-tab
      Click on “Add” to bring up
      “SIS Properties” dialog
      Choose the .pkg file

     29                   Andreas Jakl, 2009
Automatic Building

●   You might be used to
    Eclipse displaying errors as
    you type...
●   ... but this is for Java, not
    for C++!
●   You can still enable
    automatic compilation on
    resource change – might be
    useful for smaller projects
     Window  Preferences...  General  Workspace  Build automatically
     or: Project  Build automatically
      30                          Andreas Jakl, 2009
Application structure

                               Application class
                               ●   Entry point for OS
                               ●   Defines application UID
                               ●   Creates Document class
                               ●   Normally no changes
                                   required here.




31                  Andreas Jakl, 2009
Application structure (2)

                               Document class
                               ●   Takes care of data model
                               ●   Creates Application UI
                                   (AppUI-class)
                               ●   Usually no changes required
                                   in this class either.




32                  Andreas Jakl, 2009
Application structure (3)

                               AppUI class
                               ●   “Controller” of the app.
                               ●   Not visible itself
                               ●   Manages views (container)
                               ●   General, application-wide
                                   event handling
                                   (exit, pause, ...)



33                  Andreas Jakl, 2009
Application structure (4)

                               View class
                               ●   Manages title- and status
                                   pane
                               ●   Command handling
                                   (for this view)




34                  Andreas Jakl, 2009
Application structure (5)

                               Container class
                               ●   Handling of UI components
                               ●   Manages “what is visible” in
                                   the main pane (= main part
                                   of the screen)




35                  Andreas Jakl, 2009
App Startup (S60 Views)
RunApplication     CreateDocumentL()   CreateAppUiL()        ConstructL()          DoActivateL()

     Avkon View Switching Application
         CMyApplication       CMyDocument          CMyAppUi             CMyView1            CMyContainer1

     Avkon
                                                CAknViewAppUi


        CAknApplication      CAknDocument         CAknAppUi                 CAknView


                                                CAknAppUiBase

     Uikon
         CEikApplication      CEikDocument         CEikAppUi

     AppArc                                    Cone
        CApaApplication      CApaDocument         CCoeAppUi                                  CCoeControl

             36                                 Andreas Jakl, 2009
UI-Design

Menu, About Boxes and Leaves


   37          Andreas Jakl, 2009
Hint: the UI designer creates source code when you
                                         save the design. This can be problematic when you
          Menu Definition                change or rename something.
                                         Therefore, only save when you’re finished!


●   Open the UI design (MopoidContainer.uidesign)




●   Create 3 menu items:
      Start new game
      About
      Exit

     38                    Andreas Jakl, 2009
Exit Command

●   Change the command id of the “Exit” command to
    EAknCmdExit




                                          Optional: Change the title




     39                  Andreas Jakl, 2009
About Box

●   Add a “Standard Note” dialog




●   Modify its properties:
       Type: “information” (actually not 100% correct, should give
       information about an unexpected situation according to UI
       guidelines. But it’s fine for this demo)
       Text: your about message...
       Name: “noteAbout”
      40                     Andreas Jakl, 2009
Connection: Menu  Dialog

●   Open the options menu




●   Right click  “Handle ‘Selected’ Event” for the “About”
    menu item




     41                   Andreas Jakl, 2009
Connection: Menu  Dialog

●    UI-Designer created:
         RunNoteAboutL() – to display the note dialog
         HandleAboutMenuItemSelectedL() – called when the
         menu item is selected
●    Our task:
         Run the note when the menu item is selected
    TBool CMopoidContainerView::HandleAboutMenuItemSelectedL( TInt aCommand )
             {
             RunNoteAboutL();
             return ETrue;
             }


        42                         Andreas Jakl, 2009
Result




43            Andreas Jakl, 2009
Exceptions – Java

●       Try & Catch for handling exceptions
●       Functions can throw “Exceptions”

                      Calling function                                      Integer Class
    Try {                                                        …
            int x = Integer.parseInt(“1234”);                    static int parseInt throws
                                                                 NumberFormatException {
    } catch (NumberFormatException e) {
                                                                 …
            System.out.println(“Unable to convert
            this String to a number.”);                          }
    }                                                            …




            44                                  Andreas Jakl, 2009
The TRAP(D) macros are
             Leave – Symbian                                defined in e32cmn.h



●   TRAP(D) catches exceptions (“Leave”)
●   Functions send out leave
●   Function name marked by an L-suffix
                Main-Function                                   DoExampleL()-Function
    TRAPD(err, DoExampleL());                   void DoExampleL()
    if (err)                                      {
       {                                          RFs fsSession; // Connect to the file
       console->Printf(KTxtFailed, err);        server
       }                                          User::LeaveIfError(fsSession.Connect());
                                                   // …
             TRAPD-Makro declares
                                                   fsSession.Close();
                err as TInt and =                                     Leaves if the Connect()
                                                   }
                    KErrNone                                            function does not
                                                                         return KErrNone
        45                                 Andreas Jakl, 2009
Central Exception Handling

                                                      New (ELeave) …
                                                      … NewL() …
                                                        … User::Leave() …
                                                      … ConstructL() …


                                                     F5L() …
                                                     … F6L() ….
                                                     … F8L() ….


                                         … F3L() …
                                         F4L() …


                                        TRAPD(err, F2L());
                                        if (err) …
46                 Andreas Jakl, 2009
Handling Leaves

●   Try to implement central
    leave-handling
●   If leave not handled by your
    code
    error-message shown by
    the UI-framework!
●   Therefore: Only handle
    leaves yourself if they
    influence your application


      47                    Andreas Jakl, 2009
S60 Framework                   Leave is passed on until
(traps the leave                a TRAP statement is reached
  somewhere)
  void CMopoidContainerView::HandleCommandL( TInt aCommand )
  {
      TBool commandHandled = EFalse;
      switch ( aCommand )
          {
          case EMopoidContainerViewAboutMenuItemCommand:
              commandHandled = HandleAboutMenuItemSelectedL( aCommand );
              break;
  // ... TBool CMopoidContainerView::HandleAboutMenuItemSelectedL( TInt aCommand )
              {
              RunNoteAboutL();
              return ETrue;
              }
                                                        No memory left to
            void CMopoidContainerView::RunNoteAboutL( const TDesC* aOverrideText )
                {                                       allocate the object
                   CAknInformationNote* note = new ( ELeave ) CAknInformationNote();
                   if ( aOverrideText == NULL )
                        {
                        HBufC* noteText = StringLoader::LoadLC(R_MOPOID_CONTAINER_NOTE_ABOUT);
                        note->ExecuteLD( *noteText );
                        CleanupStack::PopAndDestroy( noteText );
                        }
                   else
                        {
                        note->ExecuteLD( *aOverrideText );
                        }
       48          }                      Andreas Jakl, 2009
Add the pre-implemented framework to your project

Game Engine


   49                           Andreas Jakl, 2009
Extraction and Sources

1.   Close Carbide.c++
2.   Unzip Mopoid.Update.zip to c:Symbiandev
          Keep the directory structure
          Overwrite all files (if there is no warning, the directory is
          wrong)
3.   Start Carbide.c++
4.   Click on the project, press F5 (Refresh)
5.   Open mopoid.mmp (project definition file)
          Switch to the “Sources”-tab
          Make sure all files in the “src”-dir are ticked. The header
          files do not have to be included here
     50                         Andreas Jakl, 2009
Libraries

5.   Switch to the “Libraries”-tab and add:
          bitgdi.lib
          mediaclientaudio.lib
          mediaclientimage.lib
●    How to find out which libraries you need?
           SDK documentation for the APIs that you use.
          Otherwise, you’ll get C++ linker errors.



     51                     Andreas Jakl, 2009
Text in Symbian OS

●   Mobile phones are global  localization is vital!
●   Text is defined in C++ resource files
      One resource file per language
      Separate UI elements from source code!
      Easier to maintain
      Only appropriate language is loaded




     52                    Andreas Jakl, 2009
Localization – Overview
                                                                                  If using .rls-files instead of .loc,
                                                                                  use rls_string instead of #define
  <AppName>.l01            <AppName>.l02                   <AppName>.l03
      UK English                 French                         German
#define STR_hi “Hello”   #define STR_hi “Salut”          #define STR_hi “Hallo”




                             <AppName>.loc
                         Include currently active                                        <AppName>.r01
                                 language                                               UK English compiled
                         #ifdef LANGUAGE_01...                                             resource file




                            <AppName>.rss
                                                                                          <AppName>.r02
                          Strings replaced with
                                                              Resource Compiler           French compiled
                         #defines from currently
                                                                                            resource file
                                active .lxx




                                                                                         <AppName>.r03
                                                                                         German compiled
                                                                                           resource file


        53                                          Andreas Jakl, 2009
String Resources

●   Define text in one place – and not in the source code
●   Easy to modify, easy to localize
<AppName>.l01 / .rls ... (Text only!)                       <Program>.cpp             (C++ Source Code)
#define STR_Loading “Loading...”                            #include <stringloader.h>
#define STR_Caption “Hello World”                           #include <<AppName>.rsg>

<AppName>.rss           (UI Definition)                     void C<AppName>AppUi::DisplayInfo()
#include “<AppName>.l01”                                    {
RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info          HBufC* buf = StringLoader::LoadLC ( R_LOADING );
{                                                             [...]
   short_caption = STR_Caption; }                             CleanupStack::PopAndDestroy(buf);
RESOURCE TBUF r_loading { buf = STR_Loading; }              }
[...]
                             <AppName>.rsg (Generated by resource compiler)
                             #define R_LOCALISABLE_APP_INFO      0x66a61005
                             #define R_LOADING                   0x66a61006



       54                                     Andreas Jakl, 2009
Additional Game Text
●   Define strings like explained on the previous slide                       Add an additional
                                                                               space char after
        MopoidContainer.l01 / MopoidContainer.rssi                                 the “:”

    Resource name               String name                  Text
    r_score                     STR_score                    Score:
    r_level                     STR_level                    Level:
    r_pause                     STR_pause                    Game Paused
    r_gameover                  STR_gameover                 Game Over
    r_finished                  STR_finished                 You made it!
    r_enterlevel                STR_enterlevel               Entering Level:
    r_lifelost                  STR_lifelost                 Live Lost!
    r_lives                     STR_lives                    Lives:
    r_pressjoystick             STR_pressjoystick            Press Joystick
    r_highscore                 STR_highscore                High Score:
    r_title                     STR_title                    mopoid
       55                               Andreas Jakl, 2009
New Game

●   In the UI designer, create a new event handler for the
    “Start new game” menu item
    CMopoidContainerView::HandleStart_new_gameMenuItemSelectedL()
    if (iMopoidContainer->iGameEngine)
        iMopoidContainer->iGameEngine->StartNewGameL();




     56                             Andreas Jakl, 2009
Graphics

●   Today’s phones: screen orientation / size changes
●   Mopoid uses vector graphics
●   S60: support for SVG-T




     57                  Andreas Jakl, 2009
Adding Game Graphics

●   Add a multi image file (.mif) to the
    icons-makefile:
    groupIcons_aif_scalable_dc.mk
●   Target directory:
    resourceappsMopoidGraphics.mif
●   Header generation: Header
●   Header file:
    epoc32includeMopoidGraphics.mbg



      58                    Andreas Jakl, 2009
Adding Game Graphics

●   Choose images: bricks, panel and ball
●   Set the mask depth for the bricks to n/a




     59                   Andreas Jakl, 2009
Copying Data to the Emulator

●    C:-drive of the phone is emulated in
       <EPOCROOT>winscwc
       e.g.: C:Symbian9.1S60_3rd_MREpoc32winscwc
●    Additional game resources required during runtime:
     sounds and level definition file
1.    Open Mopoid.mmp and
      write down the UID3



      60                  Andreas Jakl, 2009
Copying Data to the Emulator

●   Open groupbld.inf
      Lists which project definition & make files belong to the
      project and which files to export
●   Export the files to the private directory




                                                  The makefile will
                                                automatically create
                                                 the .mif-file in the
     61                    Andreas Jakl, 2009
                                                      right dir
Copying Data – Carbide.c++ 1.2

●   Bug in Carbide.c++ 1.2: directories saved with wrong
    slashes, resulting in this error:



●   Solution: Correct slashes in bld.inf-file (not needed for 1.3+)
       Find & replace: “/”  “”




      62                     Andreas Jakl, 2009
Phone Release

●   Copy additional data files to the phone
●   Contents of the SIS-file defined in sisMopoid.pkg
    Mopoid.pkg
    ; The icon-file
    "$(EPOCROOT)epoc32datazresourceappsMopoidGraphics.mif"
        -"!:resourceappsMopoidGraphics.mif"

    ; Sound files
    "..gfxhit.wav"
        -"!:privateE2C4F75Bhit.wav"                              Adapt the UID to
    "..gfxbounce.wav"                                               your own!
        -"!:privateE2C4F75Bbounce.wav“

    ; Levels definition file
    "..gfxlevels.dat"
        -"!:privateE2C4F75Blevels.dat"

    ; Required for the application to be covered by backup/restore facility
    "..sisbackup_registration.xml" -"!:privateE2C4F75Bbackup_registration.xml"




     63                                Andreas Jakl, 2009
Sound Bug-Fix

●   Error in the S60 3rd Ed., MR-SDK – includes are not set
    correctly for the sound API, resulting in this error:




●   Solution: add a system
    include to Mopoid.mmp:
      <EPOCROOT>/
      include/mmf/plugin


     64                    Andreas Jakl, 2009
Testing

●   Before building, choose “Project”  “Clean”
●   This is what Mopoid should look like now (white,
    empty):




●   ... if there are serious problems, use Mopoid.Merged.zip
     65                   Andreas Jakl, 2009
Troubleshooting

●   When encountering problems,
    clean your project
      Toolchain might not detect some
      changes in files, resulting in compile errors
      Cleaning is always a good idea, with any language on any
      platform!
●   Frequent problem in this step:
      MopoidGraphics.mbg is not found when compiling
      Next slides: how to make sure everything is cleaned to
      solve this issue
     66                   Andreas Jakl, 2009
Background Info: Build Toolchain

  ●   Involved files and commands in a command-line build:

Input files in <projectdir>         Command                            Outputs

                                                               Intermediate build files in
                                                            epoc32build<projectdir>
          bld.inf               > bldmake bldfiles

                                                              abld.bat in <projectdir>




                                                                 Intermediate files in
                                                            epoc32build<projectdir>
       project.mmp            > abld build wins udeb
                                                                     Binary files in
                                                           eopc32releasewinscwudeb




          67                          Andreas Jakl, 2009
Clean Everything

●   Clean Levels
      Level 0 (abld clean): Removes
      everything built by abld <target>.
      This includes: all intermediate files
      created during compilation and all
      the executables and import libraries created by the linker.
      Level 1 (abld reallyclean): As clean, but additionally removes
      exported files and makefiles.
      Level 2 (abld reallyclean, bldmake clean): Removes all files
      created by bldmake.
●   Change to Level 2:
      Window  Preferences  Carbide.c++  Build  SBSv1-tab

     68                      Andreas Jakl, 2009
Manual Cleaning

●   In case cleaning alone doesn’t help - manually delete all
    files created by your project:
       Make sure the emulator isn’t running
       Search for “mopoid” in <SDK-dir>epoc32
       Delete all files (not folders, problematic with Windows)




      69                     Andreas Jakl, 2009
Getting the images out of the .mif-file

Loading Images


    70                             Andreas Jakl, 2009
Class Types

●   CSpriteHandler loads, scales and provides images
             Why the “C”?                                          Draw the
                                                                    image
                                                    Set vector
                                                   image size in
                                                      pixels
                                  Load image
                                (CAknIconUtils)

                    .mif-File

      SVG-Images


     71                           Andreas Jakl, 2009
Fundamental Types

●   Defined in <SDK-path>epoc32includee32def.h
          Standard ANSI Symbian OS                  Description
          int            TInt                       Signed (32-bit) Integer
          unsigend int   TUint                      Unsigned (32-bit) Integer
          float          TReal32                    Single-precision IEEE 754
                                                    floating-point
          double         TReal, TReal64             Double-precision IEEE 754
                                                    floating-point
          long long      TInt64                     Uses native 64-bit support
          bool           TBool (ETrue, False)       Equates to int due to early
                                                    compilers
          void*          TAny*                      “Pointer to anything”
                         also available: TText[8|16], TInt[8|16|32], TUint[8|16|32], TUint64
     72                               Andreas Jakl, 2009
Examples
Example: TInt, TReal
TInt x = 5;
TReal y = (TReal)x + 0.5;

Example: TBool
TBool b = ETrue;
// Bad style: ETrue = 1, but any non-zero number should be interpreted
as true!
if (b == ETrue) { ... }
// Good style:
if (b) { ... }
Example: void / TAny*
// Symbian OS uses ‘void’ for ‘nothing’ and ‘TAny*’ for ‘pointer to
anyting’
void Foo();        // Returns no result
TAny* p;           // Pointer to anything
73                            Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


          T Classes

●   Remember the fundamental types (TInt, ...)?
●   T classes  similar behaviour
      Do not have a destructor
          –   Therefore, no member data that has a destructor
      Contain all data internally
          –   No pointers, references or handles (“has-a” relation)
●   Can be created on the stack and the heap
●   Also usually used instead of a traditional C struct

     74                                    Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


     T Classes – Example
TPoint definition from e32cmn.h
class TPoint
               {
public:
               enum TUninitialized { EUninitialized };
               /** Constructs default point, initialising its iX and iY members to zero. */
               TPoint(TUninitialized) {}
               inline TPoint();
               inline TPoint(TInt aX, TInt aY);
               IMPORT_C TBool operator==(const TPoint& aPoint) const;
               // [...]
               IMPORT_C TPoint operator-() const;
               IMPORT_C void SetXY(TInt aX, TInt aY);
               IMPORT_C TSize AsSize() const;
public:                                              Usage example
               /** The x coordinate. */
                                                     void CMyControl::Draw(const TRect &aRect)
               TInt iX;
                                                     const
               /** The y coordinate. */
                                                       {
               TInt iY;
                                                       CWindowGc& gc = SystemGc ();
               };
                                                       gc.DrawLine (TPoint (0, 0), iLastPoint);
                                                       }
75                                        Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


           C Classes

●   Properties of C classes (‘C’ for ‘cleanup’)
       Usually created on the heap
       (they’re often too large for stack themselves)
       Usually own pointers to large objects, resources, ...
●   Derive from CBase (directly or indirectly)
       Safe construction / Destruction
       Zero initialization



      76                                  Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


           C Classes – Characteristics

●   Safe construction / destruction
       CBase defines virtual destructor
           –   C++ therefore calls destructor in correct order
           –   Also required for the cleanup stack (later module)
       Declares a private copy constructor and assignment operator
           –   Prevents errors
           –   If required: derived class has to declare it
●   Zero initialization
       CBase overloads new-operator
       Zero-initializes all member data

      77                                    Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


       C Classes – Example
class CSprite : public CBase
  {
  public:         // Constructors and destructors
     static CSprite* NewL( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap*
aMask);
     static CSprite* NewLC( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap*
aMask);
     virtual ~CSprite();

  public:         // New methods (omitted for clarity)

  private:       // Constructors
    CSprite( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap* aMask);
    void ConstructL();

  private:        // Data
     TPoint iPosition;
     const CFbsBitmap * const iImage;
     const CFbsBitmap * const iMask;
  };
  78                                     Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


           R Classes

●   Own an external resource handle, e.g.:
       Server session (RFs – file server session)
       Memory (RArray, RBuf)
●   Initialization:
       Open(), Create() or Initialize()
       Close() or Reset() instead of destructor
       No automated Close() through the destructor!



      79                                  Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


      R Classes – Example

void CMyClass::SendCachedDataL()
  {
  RSocketServ socketServer;

 // Connect to the SocketServer
 User::LeaveIfError( socketServer.Connect() );
 // Make sure Close() is called at the end
 CleanupClosePushL( socketServer );

 // …

 CleanupStack::PopAndDestroy(); // Calls Close() on the socket server object
 }




 80                                  Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


          M Classes

●   M class
      M is for “mixin”
      Used for defining interface classes
      Declares pure virtual functions
      Should not contain members or constructors
●   Implementing class
      Usually derives from CBase and the interface
      Only form of multiple inheritance encouraged on
      Symbian OS
     81                                 Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


         M Classes – Example
// Interface definition
class MMdaAudioPlayerCallback
     {
public:
     virtual void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) =
0;
     virtual void MapcPlayComplete(TInt aError) = 0;
     };                    The CBase-derivation always
                                 has to be first!
// Implementing class
class CSoundPlayer : public CBase, public MMdaAudioPlayerCallback
     {
     // [...]
protected: // Functions from base classes
     void MapcInitComplete( TInt aError, const TTimeIntervalMicroSeconds& aDuration );
     void MapcPlayComplete( TInt aError );
     // [...]
     }



    82                                  Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


              Static Classes

●     Static classes provide utility code
●     Can not be instantiated
●     No prefix letter
    Examples
     TInt computerMoveX = Math::Rand(iSeed) % iGridSize.iWidth;
     User::After(1000);            // Suspends the current thread for 1000 microseconds
     Mem::FillZ(&targetData, 12);  // Zero-fills 12-byte block starting from &targetData




         83                                  Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


              Summary – Classes

Prefix   Category      Examples                        Description
T        Type          TDesC, TPoint, TFileName        No destructor, “has-a” data owned internally

C        Class         CBase, CActive, CFbsBitmap      Any class has to be derived from CBase. Always
                                                       allocated on the heap. Member data automatically
                                                       initialized with zero. Important for cleanup stack.
R        Resource      RFile, RTimer,                  Owns resources other than on the default heap.
                       RWriteStream, RWindow           Usually allocated as members or automatic variables.
                                                       Usually require Close() to free resources.
M        Mixin,        MGraphicsDeviceMap,             Interface consisting of virtual functions.
         interface     MEikMenuObserver                Implementation derives from it. Only approved use of
                                                       multiple inheritance.
         Static        User, Math, Mem                 Consists purely of static functions, cannot be
         class                                         instantiated into an object.



         84                                    Andreas Jakl, 2009
When to use which class type?
                                                         Usually an interface  M class
Class contains no member data
                                                         Sometimes C class


Class contains only static functions
                                                         Static class  no prefix
(or factory classes)

Member data has no destructor /                          Only contains native types (T classes) or
does not need special cleanup                            “uses-a” data  T class


Size of the data contained by the class                  Stack is limited  avoid T class
will be large (> 512 bytes)                               typically a C class

                                                         Usually a C class. Also R-classes, which
Class owns data that needs cleanup
                                                         are seldom implemented yourself



    85                                    Andreas Jakl, 2009
Loading the .mif-File

●   Define the .mif-filename in
    CSpriteHandler::ConstructL()
      _LIT(KMifFile, "MopoidGraphics.mif");
●   Uncomment the line to dynamically add the folder
      NCommonFunctions::AddResourceDirL(KMifFile, fileName);
●   Images will be stored in iSprites-array
      TFixedArray<CFbsBitmap*, MopoidShared::ENumSprites> iSprites;

                                             Why the “i”?


     86                       Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


              Variable Naming Conventions

Prefix   Category       Examples                 Description
E        Enumerated     EMonday, ESolidBrush     Values in an enumeration – which itself should have T
         constant                                prefix: EMonday is a member of TDayOfWeek
K        Constant       KMaxFileName,            Constants from #define or const TInt.
                        KRgbWhite
i        Member         iDevice, iX              Any non-static member variable. i refers to ‘instance’
         variable
a        Argument       aDevice, aX              Function argument. Stands for ‘argument’  aOrigin, not
                                                 anOrigin!
         Automatic      device, x                Automatic: variable that is created automatically when
         variable                                required and destroyed when out of scope




         87                                 Andreas Jakl, 2009
Variables | T Classes | C Classes | R Classes | M Classes | Static Classes


     Example – Variables
enum TStuffState                     // Declares an enumeration, prefix T
  {
  EInitialized = 0,                  // Individual elements with prefix E
  EError
  };
const TInt KMaxLength = 50;          // Constant with prefix K

class TStuff                         // T type class
  {
public:
  void DoStuff(TInt aLength);        // Function argument with prefix a
private:
  TInt iLength;                      // Member (instance) variable with prefix i
  TStuffState iState;
  };

void TStuff::DoStuff(TInt aLength)
  {
  if (aLength > KMaxLength)
     iState = EError;
  else
     iLength = aLength;              // Note: no ambiguities!
  }
88                                   Andreas Jakl, 2009
Fixed Arrays

●   Standard C++ Array:
      TInt myArray[25];
●   The same using Symbian OS wrapper class:
      TFixedArray<TInt, 25> myArray;


                  <ptr>             [0]    [1]   …    [24]

                 myArray
                                           25x TInt



     89                    Andreas Jakl, 2009
TFixedArray - Advantages

●   Range checking (Panic if out of range)
      At(): Checks range in debug- and release-builds
      []: Checks range in debug-builds only
●   Comfort functions, e.g.:
      DeleteAll(): invokes delete on each element
      Reset(): fills each element with zeros
      Count(): number of elements in the array
      Begin(), End(): to navigate the array

     90                    Andreas Jakl, 2009
Loading Images

 ●   Create bitmap from specified ID in .mif-file
CSpriteHandler::ConstructL()
 iSprites[ESpritePanel] = AknIconUtils::CreateIconL(
                          fileName, EMbmMopoidgraphicsPanel);


 ●   Store it in the iSprites array
 ●   IDs?
         Right-click Icons_aif_scalable_dc.mk
          Edit MBM / MIF  MopoidGraphics.mif
         or: open <EPOCROOT>/include/MopoidGraphics.mbg

        91                     Andreas Jakl, 2009
Loading Image + Mask

 ●   Load image and mask at the same time
         Otherwise, alpha blending wouldn’t work as expected
         Panel and ball images need a transparency mask
         (rounded corners)
         Bricks are rectangular, no mask required ( use method
         from previous slide)
CSpriteHandler::ConstructL()
 AknIconUtils::CreateIconL(iSprites[ESpritePanel], iSprites[ESpritePanelM],
                           fileName, EMbmMopoidgraphicsPanel,
                           EMbmMopoidgraphicsPanel_mask);



        92                       Andreas Jakl, 2009
Load all Images

iSprites array-position                 .mif-ID
ESpritePanel                            EMbmMopoidgraphicsPanel
ESpritePanelM                           EMbmMopoidgraphicsPanel_mask
ESpriteBall                             EMbmMopoidgraphicsBall
ESpriteBallM                            EMbmMopoidgraphicsBall_mask
ESpriteBrickNormal                      EMbmMopoidgraphicsBrick_green
ESpriteBrickIndestructible              EMbmMopoidgraphicsBrick_brown
ESpriteBrickDouble                      EMbmMopoidgraphicsBrick_yellow
ESpriteBrickMoving                      EMbmMopoidgraphicsBrick_red
ESpriteBrickHarderBrick                 EMbmMopoidgraphicsBrick_violet
ESpriteBrickSofterBrick                 EMbmMopoidgraphicsBrick_blue

                 Defined in
                 MopoidSharedData.h

     93                           Andreas Jakl, 2009
Setting the Image Size

●   Dynamically set by the game engine – according to
    screen resolution
●   Handled in:
    void CSpriteHandler::DoSetSpriteSize(
              const MopoidShared::TSpriteIds aSpriteId,
              const TSize& aNewSize)


●   Set image size:
    CSpriteHandler::DoSetSpriteSize()
     AknIconUtils::SetSize(iSprites[aSpriteId], aNewSize);



       94                               Andreas Jakl, 2009
Memory Leaks

●   Test it:
       Launch Mopoid in the emulator
       Close the app in the emulator (not the emulator itself!)




      95                    Andreas Jakl, 2009
Deleting Images

●   Images owned by sprite handler
     Delete pointers in the destructor
    CSpriteHandler::~CSpriteHandler()
     iSprites.DeleteAll();


    (= same as for-loop with delete on every element)




       96                               Andreas Jakl, 2009
Panics

●   ... cannot be caught and handled!
●   Terminates thread (= usually the whole application)
●   Use them for checking code logic only
●   Can also be sent out by the system for critical errors
●   If a panic happens:
      Make sure you fix it, as you can’t handle it!
          // Stray signal detected!
          _LIT(KMsgStraySignal, "Stray signaln");
          User::Panic(KMsgStraySignal, 1);       // Panic with code 1

     97                              Andreas Jakl, 2009
Panics

●   Try it – add a serious error
CSpriteHandler::ConstructL()
iSprites[999] = AknIconUtils::CreateIconL(
                fileName, EMbmMopoidgraphicsPanel);


●   Range checked by TFixedArray (in debug builds)




      98                       Andreas Jakl, 2009
Information about Panics




●   SDK doc: Symbian OS v9.x  Symbian OS reference 
    System panic reference  USER



                  Tip: install the automated panic lookup plug-in for Carbide.c++:
     99                          Andreas Jakl, 2009
                  http://www.symbianresources.com/projects/paniclookup.php
Adapting to different screen layouts

Scalable UI


   100                            Andreas Jakl, 2009
Screen Layout Changes

●   Most current S60 phones:
       portrait & landscape QVGA (240 x 320)
       Changed by app or auto screen rotation (sensor)
●   Others:
       E90: outer screen 240 x 320, inner: 800 x 352
       5500 Sport: 208 x 208
       E70: 352 x 416
●   Future phones:
       VGA +
●    App should adapt to all resolutions and be notified about
    changes
     101                     Andreas Jakl, 2009
Scalable UI in Mopoid – Overview

Framework


Container Base Class (CCoeControl)
 HandleResourceChange()                                    SizeChanged()


Container (CMopoidContainer)

 HandleResourceChange()   SetExtentToWholeScreen()         SizeChanged()


Game Engine (CMopoidGameEngine)

                                                                           SetScreenSize()




     102                              Andreas Jakl, 2009
Scalable UI – Source Code

●   Upon start-up and subsequent orientation / resolution
    changes, the framework calls HandleResourceChange()
    of all visible container classes
    CMopoidContainer::HandleResourceChange(TInt aType)
     if(aType == KEikDynamicLayoutVariantSwitch)
         {
         // User switched the layout configuration
         // or the screen resolution
         // -> we have to recreate the layout
         SetExtentToWholeScreen();
         // Results in a call of SizeChanged()
         }

●    Applies the new size (whole screen) to the container

     103                               Andreas Jakl, 2009
Scalable UI – Source Code

●   In CMopoidContainer::SizeChanged()
       Query the current resolution
       Inform the game engine

    CMopoidContainer::SizeChanged()
    iGameEngine->SetScreenSize(this->Size());




     104                              Andreas Jakl, 2009
Finally get some content on the screen

Displaying Graphics


   105                            Andreas Jakl, 2009
Back Buffer


                     Transferred
                     as a whole
                    when drawing
                      is finished




                                          Back Buffer




           Screen
106                  Andreas Jakl, 2009
Game Loop
CMopoidGameEngine
                                              Calculate time
                                                difference
   CPeriodic           (static)
                    TimerCallBack()
                                               Animate the
                                                  panel
                      DoFrame()
                                             Draw the frame
                                               to the back
                                                  buffer

                                                 Request a         Asynch. call
                                               redraw event


                                                               CMopoidContainer
                                                                   Copy the back
                                                                    buffer to the
    107                               Andreas Jakl, 2009
                                                                       screen
DrawFrame()

●   First: clear the back buffer
CMopoidGameEngine::DrawFrame()
 // Clear back buffer
 iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ENullPen);
 iBackBufferBmpGc->SetBrushColor(KRgbBlack);
 iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush);

iBackBufferBmpGc->DrawRect( TRect(TPoint(0,0),iSettings->iScreenSize) );

iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ENullBrush);



                           Pen                         ENullPen

                        Brush                        ESolidBrush,
                                                     KRgbBlack

     108                        Andreas Jakl, 2009
Drawing Bricks (w/o transparency)

●   Bricks are drawn in the for-loop
    CMopoidGameEngine::DrawFrame()
     iBackBufferBmpGc->BitBlt(ConvToScreenCoord(
             iGrid->ConvertGridToXY(x, y)),
             iSpriteHandler->GetSprite(spriteId));

●   ConvToScreenCoord()
       Game internally calculates in VGA resolution
       Converts coordinates to current screen res
       Returns a TPoint (contains two TInt)
●   GetSprite()
       Returns the correct CFbsBitmap*
       spriteID: set in switch-statement just before = brick type
     109                             Andreas Jakl, 2009
Drawing Panel and Ball (with transp.)

●   Ball sprite
CMopoidGameEngine::DrawFrame()
iBackBufferBmpGc->BitBltMasked(ConvToScreenCoord(ballSpritePos),
         iSpriteHandler->GetSprite(MopoidShared::ESpriteBall),
         iSpriteHandler->GetSprite(MopoidShared::ESpriteBall)->SizeInPixels(),
         iSpriteHandler->GetSprite(MopoidShared::ESpriteBallM), EFalse);




●   Do the same for the panel near the end of the method
       Position: iPanel.iPos
       Bitmap IDs: ESpritePanel / ESpritePanelM


     110                         Andreas Jakl, 2009
Screen Flickering

●   Note: UI Designer clears the screen with white before
    the bitmap is copied  results in flickering on some
    devices
void CMopoidContainer::Draw(const TRect& aRect) const
  {
  // [[[ begin generated region: do not modify [Generated Contents]
  CWindowGc& gc = SystemGc();
  gc.Clear( aRect ); // Remove this line to prevent flickering
  // ]]] end generated region [Generated Contents]


●   Changes will get overwritten whenever you change the
    design

     111                   Andreas Jakl, 2009
White Border around Sprites

●   On S60 3rd Ed.-devices & the MR-emulator, there is a
    white border around the sprites (fixed in FP1+)




     112                  Andreas Jakl, 2009
Keeping the game loop alive

Periodic Events


   113                        Andreas Jakl, 2009
What is an Active Object?

●   Requests asynchronous service
       provided by Asynchronous Service Provider
●   Receives call-back when finished / error
       message handling by Active Scheduler


     Active Object ≈ Listener!




     114                   Andreas Jakl, 2009
Event Handling
             Asynchronous                                                  Asynchronous
            Service Providers                                             Service Providers

 Event 1         Event 2        Event 3                         Event 1        Event 2        Event 3




   Event          Event           Event                         Active Scheduler (in app. thread)
 Handler        Handler         Handler
 (Thread)       (Thread)        (Thread)                         Event          Event          Event
                                                                Handler        Handler        Handler
                                                                 (AO)           (AO)           (AO)


Application (Possibly an extra thread)                               Application (thread)


   Traditional Event-Handling                                             Active Objects
                                                                          (Symbian OS)
   115                                     Andreas Jakl, 2009
Active Objects

●   Asynchronous Service Provider (ASP)
       Executes asynchronous task
       e.g. timer, socket-related request, take a camera picture, load
       and prepare a sound file, ...
●   Application-side:
       AOs encapsulate ASP and event handling
       (after the request to the ASP has finished)
●   Modular separation:
       Active Scheduler (AS): event completion processing for all
       ASPs
       Active Object (AO): individual event handling

     116                      Andreas Jakl, 2009
Timers

●   A timer is an asynchronous service
       Pre-implemented: we don’t have to write the active
       object ourselves
       But be aware of the characteristics (non-pre-emptive
       multitasking between AOs in one thread)
       Don’t stick in call-back routine for too long  makes app
       unresponsive, blocks user event handling!
                    MopoidGameEngine.h
                    CPeriodic* iPeriodicTimer;


     117                        Andreas Jakl, 2009
Call-Back Interval

●    Starting is necessary several times
         First start
         New game
         Resume paused game
●     encapsulated in CMopoidGameEngine::StartTimerL()
●    Define call-back interval:
         5000 micro seconds = 0,005 seconds
    CMopoidGameEngine::StartTimerL()
    const TTimeIntervalMicroSeconds32 KTickInterval = 5000;

       118                             Andreas Jakl, 2009
Allocating the Timer Instance

 ●   Allocate timer object
        Standard priority is sufficient
        Remember: only affects other AOs of this app.
        It’s not the system-wide thread/process priority!
CMopoidGameEngine::StartTimerL()
 if (!iPeriodicTimer)
     {
     iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityStandard);
     }




      119                          Andreas Jakl, 2009
Starting the Timer
    CMopoidGameEngine::StartTimerL()
     iPeriodicTimer->Start(KTickInterval, KTickInterval,
             TCallBack(TimerCallBack, this));

●   TCallBack-object
        First parameter: TAny* (= void*) function pointer to call-
        back function.
        Implementing method has to take one parameter of type
        TAny* and return a TInt
        Second parameter: pointer that will passed to the static
        call-back function
        MopoidGameEngine.h (already declared, just for reference)
            static TInt TimerCallBack(TAny* aObject);

      120                                Andreas Jakl, 2009
Call-Back

●   Usual task of call-back function
       cast the parameter to the correct class
       call a non-static call-back method for complete access to the
       class
    TInt CMopoidGameEngine::TimerCallBack(TAny* aObject)
        {
        // Call non-static method
        return ((CMopoidGameEngine*)aObject)->DoFrame();
        }
●   Call-backs might not be regular
       Call-back of a different active object is running or
       higher priority call-backs waiting
        DoFrame() checks time difference from last frame
     121                      Andreas Jakl, 2009
Stopping the Timer

●    Cancel the timer
●    Delete the instance (recommended by the SDK doc)
    void CMopoidGameEngine::StopTimer()
           {
           // If the timer object exists: stop and delete it.
           if (iPeriodicTimer)
                  {
                  iPeriodicTimer->Cancel();
                  delete iPeriodicTimer;
                  iPeriodicTimer = NULL;
                  }
           }


      122                   Andreas Jakl, 2009
Back Light

●   Ball might stay in the upper part of the
    screen for some time, no key presses
    required
●   Make sure the back light doesn’t
    always turn off
●    Simulate user activity by resetting
    the inactivity timer of the framework:
    CMopoidGameEngine::DoFrame()
    User::ResetInactivityTime();



     123                           Andreas Jakl, 2009
Let’s start to play!

Handling Keys


   124                 Andreas Jakl, 2009
Control Stack
                                                   Controls put on the stack in the order: A, B, C, D

●   Symbian OS maintains                                                             Control X
    an internal control stack
                                                    ECoeStackPriorityDefault (=0)    Control Y
●   All controls that should                                                         Keyboard Focus
    receive key events are
    put on the stack                                ECoeStackPriorityMenu (=10)       Control Z

●   Starting at stack pos. 0,
    events are offered to                           ECoeStackPriorityDialog (=50)

    each control until they
                                          Events



                                                                                    Stack position 0
    are consumed by a                               ECoeStackPriorityDialog (=50)
    control
    CMopoidContainerView::DoActivateL()
    AppUi()->AddToStackL( *this, 2009
     125                  Andreas Jakl, iMopoidContainer );
Was the key event handled by us?

●   Controls are offered key events in:
    TKeyResponse CMopoidContainer::OfferKeyEventL(
        const TKeyEvent& aKeyEvent, TEventCode aType)


●   Return value depending on if the event was handled:

                  EKeyWasConsumed: We used the key event, do not send it to
    Return        other controls
(TKeyResponse)
                  EKeyWasNotConsumed: This key event was not interesting
                  for us, send it to other controls



     126                      Andreas Jakl, 2009
Keys

●   Type of event sent in aType parameter

      EEventKeyDown             EEventKey           EEventKeyUp


●   Handling keys for left & right
       Add cases to the switch statement:
       EStdKeyLeftArrow, EStdKeyRightArrow
       Send the event to the game engine:
       iGameEngine->iKeyHandler.LeftPressed()
       Set the prepared return variable “handled” to EKeyWasConsumed
       Don’t forget the break for the case-statement!

     127                      Andreas Jakl, 2009
Keep the user informed

Displaying Text


   128                   Andreas Jakl, 2009
Fonts

●   Games use low level methods to draw text
        Highly sophisticated games usually their own bitmap font
●   Retrieving a standard system font
    CMopoidSettings::ConstructL()
     iFontUsed = (CFont*) AknLayoutUtils::LayoutFontFromId(
                 EAknLogicalFontPrimarySmallFont);
     iFontHeight = iFontUsed->AscentInPixels();

●   Apply the font to the context
    CMopoidGameEngine::DrawTextL()
    iBackBufferBmpGc->UseFont(iSettings->iFontUsed);



     129                             Andreas Jakl, 2009
Font Colour

●   Setup for drawing text (in red colour)
       Brush was already set to a null brush before
CMopoidGameEngine::DrawTextL()
iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ESolidPen);
iBackBufferBmpGc->SetPenColor(KRgbRed);
TBuf<30> tempStr;


                                                                 ESolidPen,
                            Pen                                  KRgbRed
               text                                       text
                             Brush                                ENullBrush


     130                             Andreas Jakl, 2009
Buffer Descriptors

   ●   Comparable to (const) char[] of C
   ●   Directly contain the string
   ●   Use C++ templates to specify length (parameter)
 Constant: TBufC<5>

                  5       ‘H’ ‘e’ ‘l’ ‘l’ ‘o’
                iLength
                (TDesC)

Modifiable: TBuf<9>

                  5             9         ‘H’ ‘e’ ‘l’ ‘l’ ‘o’
                iLength     iMaxLength
                (TDesC)       (TDes)
        131                               Andreas Jakl, 2009
Size, Length, MaxLength

●   TBuf<9> with text “Hello”

                 5           9         ‘H’ ‘e’ ‘l’ ‘l’ ‘o’

               4 bytes     4 bytes      2 2 ...
                                                             Unicode characters!
                         Length() 5 (characters)
                         MaxLength() 9 (characters)
                         Size() 10 (bytes)
                         MaxSize() 18 (bytes)




     132                         Andreas Jakl, 2009
Initializing the TBuf

●   Assigning Strings
      // Define constant string literal
      _LIT(KString1, "Hello ");
      _LIT(KString2, "World");
      // Copy KString1 into new TBuf with max. length of 15
      TBuf<15> buf1(KString1);
      // Same as above, this time using Copy() and KString2
      TBuf<15> buf2;      // Initialize empty TBuf with max. length of 15
      buf2.Copy(KString2);
      // Append contents of buf2 to buf1
      buf1.Append(buf2);
      // Create constant descriptor based on KString1
      TBufC<15> cBuf1(KString1);
      // Replace contents of cBuf1 with contents of buf1
      cBuf1 = buf1;
     133                             Andreas Jakl, 2009
Using the TBuf

 _LIT(KHelloWorld, "Hello World");      // Defines constant string literal
 const TInt maxLength = 15;
 // Create a modifiable buffer
 TBuf<maxLength> buf;
 TInt curLength = buf.Length();         // ...... ?
 TInt maxLength2 = buf.MaxLength();     // ...... ?
 // Set the contents of the buffer
 buf = KHelloWorld;
 curLength = buf.Length();              // ...... ?
 TInt curSize = buf.Size();             // ...... ?
 TText ch = buf[1];                     // ...... ?




134                          Andreas Jakl, 2009
Using the TBuf

 _LIT(KHelloWorld, "Hello World");      // Defines constant string literal
 const TInt maxLength = 15;
 // Create a modifiable buffer
 TBuf<maxLength> buf;
 TInt curLength = buf.Length();         // == 0
 TInt maxLength2 = buf.MaxLength();     // == 20
 // Set the contents of the buffer
 buf = KHelloWorld;
 curLength = buf.Length();              // == 11
 TInt curSize = buf.Size();                                  // == 22
 TText ch = buf[1];                                          // == ‘e’




135                          Andreas Jakl, 2009
Maximum Length

 _LIT(KHello, "Hello ");   // Defines constant string literal
 TBuf<15> buf(KHello);     // buf == “Hello ”
 buf.Append(KHello);       // buf == “Hello Hello “
 buf.Append(KHello);       // Exceeds maximum length Panic!

                                  SDK-Doc for USER 11-panic:
                                  “This panic is raised when any
                                  operation that moves or copies
                                  data to a 16-bit variant descriptor,
                                  causes the length of that descriptor
                                  to exceed its maximum length. […]”




136                        Andreas Jakl, 2009
Inheritance Hierarchy

●   Abstract base class
    because of:
       Generalisation
       (use base type for
       parameters!)
       Provide basic
       functions shared by
       all types (e.g.
       Compare(),                         constant   modifiable
       Find(), Mid(), ...)

     137                     Andreas Jakl, 2009
Reading Text from Resource Files

●   Multiple options to read text from resource files
●   Here: through environment from Symbian OS
    framework
    CMopoidGameEngine::DrawTextL()
    CEikonEnv* env = CEikonEnv::Static();

●   Read text from resource files into the descriptor
    CMopoidGameEngine::DrawTextL()
    env->ReadResourceL(tempStr, R_HIGHSCORE);

●   (Remember: you declared the resource yourself!)
    MopoidContainer.rssi
    RESOURCE TBUF r_highscore { buf = STR_highscore; }

     138                             Andreas Jakl, 2009
Formatting and Displaying Text

●   tempStr now contains “High Score: ”
●   Append the current score:
    CMopoidGameEngine::DrawTextL()
    tempStr.AppendNum(iSettings->iHighScore);

●   Draw the text
        x-coord: 5
        y was calculated directly above
    CMopoidGameEngine::DrawTextL()
    iBackBufferBmpGc->DrawText(tempStr,
        TPoint(5, yTextStartBottom));


     139                             Andreas Jakl, 2009
Current Score

●   Like for the previous text:
       Resource: R_SCORE
       Number: iSettings->iScore
       x-coordinate: 5
       y-coordinate:
       one line above previous text
       yTextStartBottom - iSettings->iTextYOffset




     140                   Andreas Jakl, 2009
Aligning Text

●   Print text on the right side of the screen
CMopoidGameEngine::DrawTextL()
 iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,
                     yTextStartBottom,
                     CGraphicsContext::ERight, 3);

Level            Text: R_LEVEL
                 Value: iSettings->iLevel
                 Position:
                 y: yTextStartBottom
                 x-offset: 3 (from the right side of the screen)
Lives            Text: R_LIVES
                 Value: iSettings->iLives
                 Position:
                 y: yTextStartBottom - iSettings->iTextYOffset
                 x-offset: 3
        141                       Andreas Jakl, 2009
Final State

●   Remove the comment from the code block
    ( activate the rest of the DrawTextL()-method)
●   The final state:




     142                 Andreas Jakl, 2009
Be persistent

Reading / Writing Files


   143           Andreas Jakl, 2009
Preparations

●   Filename and version have already been declared
    MopoidGameEngine.h
    #define MOPOID_FILE_VERSION_NUMBER   1
    _LIT(KMopoidDataFile, "settings.dat");


●   We will use the CFileStore-class
     add the required include file (see SDK doc)
    MopoidGameEngine.h
    #include <s32file.h>




     144                   Andreas Jakl, 2009
Data Caging – Overview
                                         • All binaries of all apps in one
                                           dir
                                         • Can only be executed from
                   Executable              there
                                         • Usually: no read / write access
                                         • sysbin




                                                • Bitmaps, fonts, help files
                          Resources             • Usually: read-only
                                                • resource




                                         • Each application its own dir
                                         • Used for settings, ...
                     Private
                                         • Usually: read / write only for
                      Data                 own private dir
                                         • private<UID3>

145                 Andreas Jakl, 2009
Data Caging

●   App. only has access to:
                                                                          Separating code
       Own directories                                                       and data!
       “Open” directories
●   Access based on capabilities and identity

    SystemAppsJourneyJourney.app               SysBinJourney.exe

    SystemAppsJourneyJourney.mbm               ResourceAppsJourney.mbm

    SystemAppsJourneyJourney.rsc               Private10003a3fJourney.rsc

            Symbian OS, pre-V9                               Symbian OS 9.x

     146                               Andreas Jakl, 2009
Data Caging – Directories

Directory              Capability   Capability       Used for
                       (Read)       (Write)

sys                   AllFiles     TCB              Applications can only be executed from here.


resource              -            TCB              Fonts, bitmaps, help-files, … Only read-access
                                                     for apps, to prevent corruption.
private<own SID>     -            -                For application data (settings, …). DLLs do not
                                                     have own private dir, but instead use that of
                                                     their loading process.
private<other SID>   AllFiles     AllFiles         AllFiles-capability required to access private
                                                     data of other apps.
All others             -            -                Unrestricted data – images, …




       147                              Andreas Jakl, 2009
More about directories

●   Data caging provides secure area for application’s data
●   All executables installed to sysbin
       Risk of filename clashes – use your unique UID as part of
       the executable filename
       Removable drives:
       Hash stored to c:syshash
       Prevents execution of modified executables




     148                    Andreas Jakl, 2009
Data Files

●   Data file should be stored in our private directory:
    private<UID3>settings.dat
●   Dynamically add the path:
    CMopoidGameEngine::SaveGameProgessL()
    NCommonFunctions::AddPrivateDirL(iFs,
        KMopoidDataFile, fileName);


●   Central part of this custom utility function:
    NCommonFunctions::AddPrivateDirL()
    aFs.PrivatePath( aCompleteName );



     149                                 Andreas Jakl, 2009
File Store

●   Many ways to access files are possible (RFile, ...)
●   Here: CFileStore – one of the most flexible            Store (File)
       Encapsulates file-based, persistent stores          Stream (ID)

       Stores multiple streams, each identified by an ID   Stream (ID)




                                                                 ...
       Allows easy serialization of objects
       Direct file store: doesn’t allow modifying data – not important
       for us, we will always replace the stream
    CMopoidGameEngine::SaveGameProgessL()
    CFileStore* store = CDirectFileStore::ReplaceLC(
        iFs, fileName, EFileWrite);
    store->SetTypeL(KDirectFileStoreLayoutUid);

     150                            Andreas Jakl, 2009
Creating a Stream

●   One stream has to be the root stream
       We only use one stream – set it to the root stream (later)
       Multiple streams: e.g., for a database
    CMopoidGameEngine::SaveGameProgessL()
    RStoreWriteStream stream;
    TStreamId id = stream.CreateLC(*store);




     151                            Andreas Jakl, 2009
Writing Data

●   For now: file version and high score
    CMopoidGameEngine::SaveGameProgessL()
    // Write file version number
    stream.WriteInt32L(MOPOID_FILE_VERSION_NUMBER);
    // Write highscore
    stream.WriteInt32L(iSettings->iHighScore);

●   Saving the file version?
       Updating the game != uninstallation
       Keeps additional files
       New game version might add additional settings
       Should know file version, to import or discard old file!

     152                            Andreas Jakl, 2009
Closing the File

●   Make sure that all data is written and close everything
    CMopoidGameEngine::SaveGameProgessL()
    // Commit the changes to the stream
    stream.CommitL();
    CleanupStack::PopAndDestroy(&stream);

    // Set the stream in the store and commit the store
    store->SetRootL(id);
    store->CommitL();
    CleanupStack::PopAndDestroy(store);




     153                            Andreas Jakl, 2009
Cleanup Stack

●   Situation: function creates local heap-object
●   Before code gets to the delete-statement: error
          Function is left (Leave)
          Pointer-address on the stack is freed
          Object itself is orphaned               memory leak!
                                                           CImage
      void CMyObj::DoSomethingL()
      {                                                  void CImage::DoSomethingDangerousL()
           CImage* img = new (ELeave) CImage();            {
                                                           User::Leave(KErrNotFound);
            img->DoSomethingDangerousL();                  }
            delete img;
      }                           img = pointer on the stack
     154                          to an instance 2009 heap
                                      Andreas Jakl, on the
Cleanup Stack

●   Memory situation if a leave occurs:




                       img
                      Stack                    Heap

                                          Object stays on the heap;
                                          Pointer to delete the instance is lost
                                             memory leak

     155                      Andreas Jakl, 2009
Cleanup Stack

●   Solution: Cleanup Stack

void CMyObj::DoSomethingL()                                       img
{
       CImage* img = new (ELeave) CImage();                   CleanupStack
       CleanupStack::PushL(img);
       img->DoSomethingDangerousL();
       CleanupStack::PopAndDestroy();
}
                                                                 img
                                                                 Stack        Heap
    When no leave occurs: object still
    has to be deleted by you +                        Cleanup stack saves a second pointer
    removed from the cleanup stack!                   to the object on the heap.


      156                                Andreas Jakl, 2009
R-Classes Cleanup

●   R-classes usually have extra methods to free the resources
       Just calling the destructor wouldn’t be sufficient!
       In the case of the RBuf descriptor (heap based string): Close()
       Special method to put the instance on the cleanup stack – has
       to tell it how to destroy the object
    CMopoidGameEngine::SaveGameProgessL()
    RBuf fileName;

    // Push the variable onto the cleanup stack
    fileName.CleanupClosePushL();

    // ... any leave here would also destroy the obj.

    // Pop and destroy (calls Close() on the object)
    CleanupStack::PopAndDestroy(&fileName);
     157                            Andreas Jakl, 2009
Loading

●   Similar to saving files
     1.    Open the file store
            CMopoidGameEngine::LoadGameProgessL()
            CFileStore* store = CDirectFileStore::OpenLC(
                iFs, fileName, EFileRead);

     2.    Open the root stream (no ID is required for the root)
            CMopoidGameEngine::LoadGameProgessL()
            RStoreReadStream stream;
            stream.OpenLC(*store, store->Root());




     158                             Andreas Jakl, 2009
Reading Data

3.    Read the data
       CMopoidGameEngine::LoadGameProgessL()
       TInt versionNumber = stream.ReadInt32L();
       if (versionNumber != MOPOID_FILE_VERSION_NUMBER)
              User::Leave(KErrNotFound);

       iSettings->iHighScore = stream.ReadInt32L();

      If the file version doesn’t match – same behaviour as if
      the file wasn’t found. You could import an old version
      instead.



159                             Andreas Jakl, 2009
If the File Was Not Found

●   File not found-error (or wrong version)
       Ignored
       Settings-class initialized with default values
           CMopoidGameEngine::ConstructL()
           // Load high score and settings
           TRAPD(err, LoadGameProgressL());
           if (err != KErrNone && err != KErrNotFound)
                  User::Leave(err);


●   All other errors (e.g., not enough disc space left)
       TRAP’d leave is sent out again
     160                                Andreas Jakl, 2009
Cleanup

    4.     Close all handles
            CMopoidGameEngine::LoadGameProgessL()
            CleanupStack::PopAndDestroy(&stream);
            CleanupStack::PopAndDestroy(store);


●   What about cleanup upon deinstallation?
         Required by Symbian Signed criteria!
         The whole private directory would be deleted anyway,
         but it’s still better to explicitly specify it



     161                             Andreas Jakl, 2009
Cleanup – Uninstallation

●   Files that are to be removed during
    uninstallation: specified in the package file
    Mopoid.pkg
    ; --- Settings-file
    ""-"!:privateE2C4F75Bsettings.dat",FN


●   “FN” means “FileNull” – SDK help:
    A file which does not yet exist, so is not included in the sis file. It is created by
    the running application and will be deleted when the application is removed.
    The name assigned to the source file is unimportant and should be empty, i.e.
    “”. Note that such files will not be deleted when upgrading to a later version.
    This ensures that such files as .ini files, which store application preferences,
    are not lost in an upgrade.

     162                               Andreas Jakl, 2009
Make a good appearance in the phone menu:

Application Icon


  163                          Andreas Jakl, 2009
Application Icon

●   Icons have to be .svg-files as well, encapsulated in a .mif
●   Set for the whole application
       Open application.uidesign
       Switch to the “AppUi”-tab
       Right-click on the title pane
       Choose: “Override Context Icon”
       Select the “Mopoid_aif.mif”-file
       Image: qgn_menu_Mopoid.svg

     164                     Andreas Jakl, 2009
Is anyone out there?

Foreground / Background


   165                 Andreas Jakl, 2009
Background?

●   Symbian OS = multitasking system
●   Sent to the background due to:
       Incoming call
       Warnings (e.g., low battery)
       User sending you to the background
●   Applications should react to this
       Save current state
       Free shared common resources (e.g., camera)
       Pause games
       Enter low power state

     166                    Andreas Jakl, 2009
Foreground Notification

●   Abstact method of the View base class (CAknView)
●   Out task: override this method, called automatically!
       Declare it in a protected section of the view header
    MopoidContainerView.h
    void HandleForegroundEventL(TBool aForeground);




     167                    Andreas Jakl, 2009
Foreground Handling

●   Desired behaviour
       Pause the game when it looses the foreground
       Do not resume the game when it regains foreground status –
       player can’t continue playing 1 ms after the call!
    MopoidContainerView.cpp
    // Handle any change of focus
    void CMopoidContainerView::HandleForegroundEventL(TBool aForeground) {
         if (aForeground) { // gained focus
             // Don't resume the game - wait for user to resume it
             if (iMopoidContainer && iMopoidContainer->iGameEngine)
                 iMopoidContainer->iGameEngine->iHaveFocus = ETrue;
         } else { // lost focus – Pause game
             if (iMopoidContainer && iMopoidContainer->iGameEngine) {
                 iMopoidContainer->iGameEngine->PauseGame();
                 iMopoidContainer->iGameEngine->iHaveFocus = EFalse;
             }
         }
         // call base class event handler
         CAknView::HandleForegroundEventL(aForeground);
     168                         Andreas Jakl, 2009
         }
Adapting the Game to the Environment

Sound Volume / Dynamic Menus


  169                          Andreas Jakl, 2009
Sounds and Mobile Games

●   Mobile Phones are used everywhere
       train, toilet, bus stop, ...
●   Sound is not always appropriate!
●   Gameloft: games ask desired volume on every start-up!
●   Add two additional menu items to
    MopoidContainer.uidesign
       Sound On
       Sound Off
●   Create event handler methods
     170                       Andreas Jakl, 2009
(De) activating Sound

●   Send the command to the game engine
TBool CMopoidContainerView::HandleSound_OnMenuItemSelectedL( TInt aCommand )
    {
    if (iMopoidContainer && iMopoidContainer->iGameEngine)
        {
        iMopoidContainer->iGameEngine->SetSoundLevelL(ETrue);
        }
    return ETrue;
    }


●   ... do the inverse for the sound off-event!
●   Add the sound state to the settings file
       Accessible from the game engine via iSettings->iSoundLevel
       Write it using WriteInt32L()
     171                       Andreas Jakl, 2009
Dynamic Menus

●   The visibility state of a menu item is not directly
    defined (in S60, UIQ 3 is different)
●   Instead, framework calls a method each time right
    before the menu is displayed
●   App gets the chance to dim individual items there
●   Override the method from the CAknView base class:
    MopoidContainerView.h
    void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane);




     172                    Andreas Jakl, 2009
Dimming Menu Items

●   Check which resource is currently
    initialized – the menu pane is relevant
●   Menu IDs are defined by the UI designer
    in MopoidContainer.hrh
●   Dim “Sound Off / On” menu items
    according to sound state
MopoidContainerView::DynInitMenuPaneL()
if (R_MOPOID_CONTAINER_MENU_PANE1_MENU_PANE == aResourceId &&
    iMopoidContainer && iMopoidContainer->iGameEngine)
    {
    aMenuPane->SetItemDimmed(EMopoidContainerViewSound_OnMenuItemCommand,
                             iMopoidContainer->iGameEngine->IsSoundOn());
    aMenuPane->SetItemDimmed(EMopoidContainerViewSound_OffMenuItemCommand,
                             !iMopoidContainer->iGameEngine->IsSoundOn());
    }

     173                             Andreas Jakl, 2009
We’re finished!

Summary


   174            Andreas Jakl, 2009
Mopoid

●   Tasks                                            Defining and displaying text,
                                                     fonts, descriptors
       Create your own application
       using the UI designer                         Using vector graphics
       Define a menu and an about                    Scalable UI
       box                                           Asynchronous events,
       Leaves, Panics and Cleanup                    timers
       Stack                                         Key handling
       Project structure, libraries                  Files, data caging (platform
       Class types, naming                           security)
       conventions                                   Foreground / background
                                                     Dynamic menu
     175                        Andreas Jakl, 2009
That’s it

Thanks for your attention!


   176          Andreas Jakl, 2009

More Related Content

Viewers also liked

Alexander Oswald The Future of Maemo and Symbian
Alexander Oswald The Future of Maemo and SymbianAlexander Oswald The Future of Maemo and Symbian
Alexander Oswald The Future of Maemo and SymbianNokiaAppForum
 
Jak zaktualizować swój telefon poprzez Nokia Suite.
Jak zaktualizować swój telefon poprzez Nokia Suite.Jak zaktualizować swój telefon poprzez Nokia Suite.
Jak zaktualizować swój telefon poprzez Nokia Suite.Nokia Poland
 
D4 m symbian^3 ui & fresh theme
D4 m symbian^3 ui & fresh themeD4 m symbian^3 ui & fresh theme
D4 m symbian^3 ui & fresh themeScott Weiss
 
Symbian Foundation Press Kit
Symbian Foundation Press KitSymbian Foundation Press Kit
Symbian Foundation Press KitAngela Barison
 
Symbian OS - GUI Architectures
Symbian OS - GUI ArchitecturesSymbian OS - GUI Architectures
Symbian OS - GUI ArchitecturesAndreas Jakl
 
Symbian Os Introduction
Symbian Os IntroductionSymbian Os Introduction
Symbian Os IntroductionDeepak Rathi
 
Symbian Operating system
Symbian Operating systemSymbian Operating system
Symbian Operating systemPravin Shinde
 
Seminar report on Symbian OS
Seminar report on Symbian OSSeminar report on Symbian OS
Seminar report on Symbian OSDarsh Kotecha
 

Viewers also liked (11)

Alexander Oswald The Future of Maemo and Symbian
Alexander Oswald The Future of Maemo and SymbianAlexander Oswald The Future of Maemo and Symbian
Alexander Oswald The Future of Maemo and Symbian
 
Jak zaktualizować swój telefon poprzez Nokia Suite.
Jak zaktualizować swój telefon poprzez Nokia Suite.Jak zaktualizować swój telefon poprzez Nokia Suite.
Jak zaktualizować swój telefon poprzez Nokia Suite.
 
D4 m symbian^3 ui & fresh theme
D4 m symbian^3 ui & fresh themeD4 m symbian^3 ui & fresh theme
D4 m symbian^3 ui & fresh theme
 
Symbian Foundation Press Kit
Symbian Foundation Press KitSymbian Foundation Press Kit
Symbian Foundation Press Kit
 
Symbian OS - GUI Architectures
Symbian OS - GUI ArchitecturesSymbian OS - GUI Architectures
Symbian OS - GUI Architectures
 
Symbian os
Symbian osSymbian os
Symbian os
 
Symbian Os Introduction
Symbian Os IntroductionSymbian Os Introduction
Symbian Os Introduction
 
Symbian OS
Symbian OSSymbian OS
Symbian OS
 
Symbian Operating system
Symbian Operating systemSymbian Operating system
Symbian Operating system
 
Seminar report on Symbian OS
Seminar report on Symbian OSSeminar report on Symbian OS
Seminar report on Symbian OS
 
Symbian OS
Symbian OSSymbian OS
Symbian OS
 

Similar to Symbian OS - Mopoid Next Gen - Slides

Symbian OS - Quick Start
Symbian OS - Quick StartSymbian OS - Quick Start
Symbian OS - Quick StartAndreas Jakl
 
Targeting Android with Qt
Targeting Android with QtTargeting Android with Qt
Targeting Android with QtEspen Riskedal
 
Open Kode, Airplay And The New Reality Of Write Once Run Anywhere
Open Kode, Airplay And The New Reality Of Write Once Run AnywhereOpen Kode, Airplay And The New Reality Of Write Once Run Anywhere
Open Kode, Airplay And The New Reality Of Write Once Run Anywhereguest991eb3
 
Andreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo QuickstartAndreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo QuickstartNokiaAppForum
 
Report in Operations and Research (OPERSEA) — STI College Bacolod
Report in Operations and Research (OPERSEA) — STI College BacolodReport in Operations and Research (OPERSEA) — STI College Bacolod
Report in Operations and Research (OPERSEA) — STI College BacolodEphramar Telog
 
0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlabNational Cheng Kung University
 
Java ME - 01 - Overview
Java ME - 01 - OverviewJava ME - 01 - Overview
Java ME - 01 - OverviewAndreas Jakl
 
Dot Net Project Mini Game
Dot Net Project Mini GameDot Net Project Mini Game
Dot Net Project Mini Gamevarun arora
 
DCC Labs Company Presentation
DCC Labs Company PresentationDCC Labs Company Presentation
DCC Labs Company PresentationDCC Labs
 
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LIST
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LISTCOMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LIST
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LISTtarun kumar sharma
 
0xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp020xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp02chon2010
 
Andreas Jakl Software Development on Nokia Deviceswith Qt
Andreas Jakl Software Development on Nokia Deviceswith QtAndreas Jakl Software Development on Nokia Deviceswith Qt
Andreas Jakl Software Development on Nokia Deviceswith QtNokiaAppForum
 
2011 android
2011 android2011 android
2011 androidvpedapolu
 
Minko stage3d 20130222
Minko stage3d 20130222Minko stage3d 20130222
Minko stage3d 20130222Minko3D
 

Similar to Symbian OS - Mopoid Next Gen - Slides (20)

Symbian OS - Quick Start
Symbian OS - Quick StartSymbian OS - Quick Start
Symbian OS - Quick Start
 
Targeting Android with Qt
Targeting Android with QtTargeting Android with Qt
Targeting Android with Qt
 
Mono
MonoMono
Mono
 
Open Kode, Airplay And The New Reality Of Write Once Run Anywhere
Open Kode, Airplay And The New Reality Of Write Once Run AnywhereOpen Kode, Airplay And The New Reality Of Write Once Run Anywhere
Open Kode, Airplay And The New Reality Of Write Once Run Anywhere
 
Andreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo QuickstartAndreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo Quickstart
 
Report in Operations and Research (OPERSEA) — STI College Bacolod
Report in Operations and Research (OPERSEA) — STI College BacolodReport in Operations and Research (OPERSEA) — STI College Bacolod
Report in Operations and Research (OPERSEA) — STI College Bacolod
 
0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab0xdroid -- community-developed Android distribution by 0xlab
0xdroid -- community-developed Android distribution by 0xlab
 
Java ME - 01 - Overview
Java ME - 01 - OverviewJava ME - 01 - Overview
Java ME - 01 - Overview
 
Symbian
SymbianSymbian
Symbian
 
Symbian os
Symbian osSymbian os
Symbian os
 
Symbian
SymbianSymbian
Symbian
 
Dot Net Project Mini Game
Dot Net Project Mini GameDot Net Project Mini Game
Dot Net Project Mini Game
 
Using the NDK and Renderscript
Using the NDK and RenderscriptUsing the NDK and Renderscript
Using the NDK and Renderscript
 
DCC Labs Company Presentation
DCC Labs Company PresentationDCC Labs Company Presentation
DCC Labs Company Presentation
 
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LIST
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LISTCOMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LIST
COMPUTER GRAPHICS AND MULTI MEDIA SOFTWARE LIST
 
ARM
ARMARM
ARM
 
0xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp020xdroid osdc-2010-100426084937-phpapp02
0xdroid osdc-2010-100426084937-phpapp02
 
Andreas Jakl Software Development on Nokia Deviceswith Qt
Andreas Jakl Software Development on Nokia Deviceswith QtAndreas Jakl Software Development on Nokia Deviceswith Qt
Andreas Jakl Software Development on Nokia Deviceswith Qt
 
2011 android
2011 android2011 android
2011 android
 
Minko stage3d 20130222
Minko stage3d 20130222Minko stage3d 20130222
Minko stage3d 20130222
 

More from Andreas Jakl

Create Engaging Healthcare Experiences with Augmented Reality
Create Engaging Healthcare Experiences with Augmented RealityCreate Engaging Healthcare Experiences with Augmented Reality
Create Engaging Healthcare Experiences with Augmented RealityAndreas Jakl
 
AR / VR Interaction Development with Unity
AR / VR Interaction Development with UnityAR / VR Interaction Development with Unity
AR / VR Interaction Development with UnityAndreas Jakl
 
Android Development with Kotlin, Part 3 - Code and App Management
Android Development with Kotlin, Part 3 - Code and App ManagementAndroid Development with Kotlin, Part 3 - Code and App Management
Android Development with Kotlin, Part 3 - Code and App ManagementAndreas Jakl
 
Android Development with Kotlin, Part 2 - Internet Services and JSON
Android Development with Kotlin, Part 2 - Internet Services and JSONAndroid Development with Kotlin, Part 2 - Internet Services and JSON
Android Development with Kotlin, Part 2 - Internet Services and JSONAndreas Jakl
 
Android Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndroid Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndreas Jakl
 
Android and NFC / NDEF (with Kotlin)
Android and NFC / NDEF (with Kotlin)Android and NFC / NDEF (with Kotlin)
Android and NFC / NDEF (with Kotlin)Andreas Jakl
 
Basics of Web Technologies
Basics of Web TechnologiesBasics of Web Technologies
Basics of Web TechnologiesAndreas Jakl
 
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & More
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & MoreBluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & More
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & MoreAndreas Jakl
 
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?Andreas Jakl
 
Mobile Test Automation
Mobile Test AutomationMobile Test Automation
Mobile Test AutomationAndreas Jakl
 
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...Andreas Jakl
 
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows PhoneWinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows PhoneAndreas Jakl
 
Nokia New Asha Platform Developer Training
Nokia New Asha Platform Developer TrainingNokia New Asha Platform Developer Training
Nokia New Asha Platform Developer TrainingAndreas Jakl
 
Windows Phone 8 NFC Quickstart
Windows Phone 8 NFC QuickstartWindows Phone 8 NFC Quickstart
Windows Phone 8 NFC QuickstartAndreas Jakl
 
Windows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App ScenariosWindows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App ScenariosAndreas Jakl
 
Windows 8 Platform NFC Development
Windows 8 Platform NFC DevelopmentWindows 8 Platform NFC Development
Windows 8 Platform NFC DevelopmentAndreas Jakl
 
NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)Andreas Jakl
 
06 - Qt Communication
06 - Qt Communication06 - Qt Communication
06 - Qt CommunicationAndreas Jakl
 
05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics05 - Qt External Interaction and Graphics
05 - Qt External Interaction and GraphicsAndreas Jakl
 

More from Andreas Jakl (20)

Create Engaging Healthcare Experiences with Augmented Reality
Create Engaging Healthcare Experiences with Augmented RealityCreate Engaging Healthcare Experiences with Augmented Reality
Create Engaging Healthcare Experiences with Augmented Reality
 
AR / VR Interaction Development with Unity
AR / VR Interaction Development with UnityAR / VR Interaction Development with Unity
AR / VR Interaction Development with Unity
 
Android Development with Kotlin, Part 3 - Code and App Management
Android Development with Kotlin, Part 3 - Code and App ManagementAndroid Development with Kotlin, Part 3 - Code and App Management
Android Development with Kotlin, Part 3 - Code and App Management
 
Android Development with Kotlin, Part 2 - Internet Services and JSON
Android Development with Kotlin, Part 2 - Internet Services and JSONAndroid Development with Kotlin, Part 2 - Internet Services and JSON
Android Development with Kotlin, Part 2 - Internet Services and JSON
 
Android Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - IntroductionAndroid Development with Kotlin, Part 1 - Introduction
Android Development with Kotlin, Part 1 - Introduction
 
Android and NFC / NDEF (with Kotlin)
Android and NFC / NDEF (with Kotlin)Android and NFC / NDEF (with Kotlin)
Android and NFC / NDEF (with Kotlin)
 
Basics of Web Technologies
Basics of Web TechnologiesBasics of Web Technologies
Basics of Web Technologies
 
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & More
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & MoreBluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & More
Bluetooth Beacons - Bluetooth 5, iBeacon, Eddystone, Arduino, Windows 10 & More
 
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
Which new scenarios are enabled by Windows 10 for NFC, Bluetooth LE & Beacons?
 
Mobile Test Automation
Mobile Test AutomationMobile Test Automation
Mobile Test Automation
 
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
Qt App Development - Cross-Platform Development for Android, iOS, Windows Pho...
 
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows PhoneWinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
WinJS, Apache Cordova & NFC - HTML5 apps for Android and Windows Phone
 
Nokia New Asha Platform Developer Training
Nokia New Asha Platform Developer TrainingNokia New Asha Platform Developer Training
Nokia New Asha Platform Developer Training
 
Windows Phone 8 NFC Quickstart
Windows Phone 8 NFC QuickstartWindows Phone 8 NFC Quickstart
Windows Phone 8 NFC Quickstart
 
Windows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App ScenariosWindows (Phone) 8 NFC App Scenarios
Windows (Phone) 8 NFC App Scenarios
 
Windows 8 Platform NFC Development
Windows 8 Platform NFC DevelopmentWindows 8 Platform NFC Development
Windows 8 Platform NFC Development
 
NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)NFC Development with Qt - v2.2.0 (5. November 2012)
NFC Development with Qt - v2.2.0 (5. November 2012)
 
06 - Qt Communication
06 - Qt Communication06 - Qt Communication
06 - Qt Communication
 
05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics05 - Qt External Interaction and Graphics
05 - Qt External Interaction and Graphics
 
04 - Qt Data
04 - Qt Data04 - Qt Data
04 - Qt Data
 

Recently uploaded

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Recently uploaded (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

Symbian OS - Mopoid Next Gen - Slides

  • 1. mopoid Symbian OS Workshop 1 Andreas Jakl, 2009 v2.4.1 – 19 April 2009
  • 2. Disclaimer ● These slides are provided free of charge at http://www.symbianresources.com and are used during Symbian OS courses at the University of Applied Sciences in Hagenberg, Austria ( http://www.fh-hagenberg.at/ ) ● Respecting the copyright laws, you are allowed to use them: for your own, personal, non-commercial use in the academic environment ● In all other cases (e.g. for commercial training), please contact andreas.jakl@fh-hagenberg.at ● The correctness of the contents of these materials cannot be guaranteed. Andreas Jakl is not liable for incorrect information or damage that may arise from using the materials. ● Parts of these materials are based on information from Symbian Press-books published by John Wiley & Sons, Ltd. This document contains copyright materials which are proprietary to Symbian, UIQ, Nokia and SonyEricsson. “S60™” is a trademark of Nokia. “UIQ™” is a trademark of UIQ Technology. Pictures of mobile phones or applications are copyright their respective manufacturers / developers. “Symbian ™”, “Symbian OS ™” and all other Symbian-based marks and logos are trademarks of Symbian Software Limited and are used under license. © Symbian Software Limited 2006. 2 Andreas Jakl, 2009
  • 3. Motivation ● Why C++ for Symbian OS / S60? High performance (Nearly) unlimited possibilities  Ideal platform for innovative projects! ● Bonus: increase your value on the market with Symbian OS knowledge 3 Andreas Jakl, 2009
  • 4. Schedule ● Instead of theory, we’ll do a practical project 4 Andreas Jakl, 2009
  • 5. Mopoid ● Tasks Defining and displaying text, fonts, descriptors Create your own application using the UI designer Using vector graphics Define a menu and an about Scalable UI box Asynchronous events, Leaves, Panics and Cleanup timers Stack Key handling Project structure, libraries Files, data caging (platform Class types, naming security) conventions Foreground / background Dynamic menu 5 Andreas Jakl, 2009
  • 6. Conventions ● Slides are a mixture of explanations and tasks you have to do TODOs are marked on the left side of the slides After the game framework is imported, source code edits are also marked with a // TODO: comment // TODO: Refresh back light timer Slides with explanations of specific Symbian OS concepts are marked in the upper right corner 6 Andreas Jakl, 2009
  • 7. IDEs – Carbide.c++ ● Carbide.c++ (based on Eclipse) New main development platform Integrates Eclipse with required tools ● Editions: Express: basic Developer: UI-designer, on-device debugging Professional: Performance tools OEM: ROM and JTAG support (all free starting with Carbide.c++ 2.0) 7 Andreas Jakl, 2009
  • 8. Carbide.c++ 8 Andreas Jakl, 2009
  • 9. S60 SDKs SDK OS version Devices 1st Ed. v6.0 7650 ● Choose SDK depending on 1st Ed, FP 1 v6.1 N-Gage, SX1, 3650, Sendo- required compatibility and X, … features 2nd Ed v7.0s 6600, … 2nd Ed, FP 1 v7.0s 7610, 6670, ● Binary compatibility break 6260, … with Symbian OS 9 2nd Ed, FP 2 v8.0 6630, 6680, 6681, … ● www.forum.nokia.com 2nd Ed, FP 3 v8.1 N70, N90, … 3rd Ed v9.1 E61, N73, N75, … Commonly used for 3rd Ed, FP 1 v9.2 N95, E90, … maximum compatibility 3rd Ed, FP 2 v9.3 N96, N78, … 5th Ed v9.4 5800, N97, … Introduces touch 5th Ed, FP1 v9.5? ? screens to S60 9 Andreas Jakl, 2009
  • 10. Installation 1. Carbide.c++ 2.0 Developer Edition (or later) http://www.forum.nokia.com/main/resources/tools_and_sdks/car bide/index.html 2. Perl 5.6.x (Set the path variable!) – not 5.8 / 5.10! http://downloads.activestate.com/ActivePerl/Windows/5.6/Active Perl-5.6.1.638-MSWin32-x86.msi 3. SDK(s) (S60 3rd Ed. MR + newer) http://www.forum.nokia.com/Resources_and_Information/Tools/ Platforms/S60_Platform_SDKs/  Install all tools on the same drive (recommended: C:, no network drive!) 10 Andreas Jakl, 2009
  • 11. Updating Carbide.c++ ● Go to: Help  Software Updates  Find and Install ... Search for new features to install ● Only install updates from the Carbide.c++ update site! Updating other components might overwrite Carbide.c++ settings! 11 Andreas Jakl, 2009
  • 12. Workspace ● Workspace location: Has to be on the same drive as the SDK ( C:) Must not contain space characters Example: C:Symbiandev 12 Andreas Jakl, 2009
  • 13. Create new project ● File  New  C++ Application for S60 Project 13 Andreas Jakl, 2009
  • 14. Create new project ● Call it: Mopoid ● Check again if the path is really on the SDK drive (C:) and does not contain space characters! 14 Andreas Jakl, 2009
  • 15. Phone Build ● Build configurations: WINSCW: Build for the windows-based emulator ARMV5: Optimized builds for the device using the ARM RealView-compiler (commercial) GCCE: Standard builds for the device using the free GCC(E) compiler. Comes with the SDK 15 Andreas Jakl, 2009
  • 16. Choose UI-Design ● Select the empty design We’ll do low level graphics on an empty canvas 16 Andreas Jakl, 2009
  • 17. Application UID (UID3) ● Development for v9: 0xE0000000 - 0xEFFFFFFF Development UID automatically assigned by Carbide ● Get UIDs for public applications: Range Purpose Different range for signed / 0x00000000 – 0x0FFFFFFF Development use (< v9) unsigned 0x10000000 – 0x1FFFFFFF Legacy UID (pre-v9) 0x20000000 – 0x2FFFFFFF v9 protected UIDs Get one for free at: 0xA0000000 – 0xAFFFFFFF v9 unprotected UIDs http://www.symbiansigned.com/ 0xE0000000 – 0xEFFFFFFF Development use (v9) 0xF0000000 – 0xFFFFFFFF Legacy UID (pre-v9) 17 Andreas Jakl, 2009
  • 18. Our Project 18 Andreas Jakl, 2009
  • 19. UI-Components ● Window Sub-component of the device screen Principal window filling up entire screen Not used for display Can contain many panes ● Pane Sub-component of a window Can contain many sub-panes 19 Andreas Jakl, 2009
  • 20. S60 UI ● Status Pane Status Pane Information about running application & device (e.g. Main Pane battery strength) ● Main Pane Control Pane Application content ● Control Pane Softkey labels 20 Andreas Jakl, 2009
  • 21. First tests Compile 21 Andreas Jakl, 2009
  • 22. Choose Build Target ● Active Build Configuration  Emulator 22 Andreas Jakl, 2009
  • 23. You can only use the mouse to navigate on the Compile Project screen on touch-enabled emulators! Otherwise, use the buttons below. ● (optional) Project  Build Project ● Run  Run ● Or: 23 Andreas Jakl, 2009
  • 24. Launch Configuration ● Launch: Mopoid.exe Game is directly started in the emulator Emulator shuts down when app exits ● Launch: Emulator Start game manually from the menu Adv.: recompile without closing the emulator, error messages on app shutdown more visible ● Available from: Carbide.c++ 1.3.1+ with SDKs > S60 3rd MR 24 Andreas Jakl, 2009
  • 25. Possible Problems ***Generating makefiles. bldmake.bat bldfiles WINSCW UDEB WARNING: EPOCROOT does not specify an existing directory ● Compilation error: BLDMAKE ERROR: Directory "Symbian9.1S60_3rd_MREPOC32" does not exist Total Time: 0 sec ===Build Command = build WINSCW UDEB -v=== Exec error:Launching failed***build returned with exit value = -1 ***Stopping. Check the Problems view or Console output for errors. -1  your workspace / project is not on the same drive as the Symbian OS SDK (usually C:) (told you to put it there several times ) 25 Andreas Jakl, 2009
  • 26. Emulator ● Application added to the end of the list in the “Installat.” folder ● Can be moved with “Options  Move *to folder+” ● Useful when working on the same project for some time 26 Andreas Jakl, 2009
  • 27. Building for the Device ● Change build configuration to Phone Release (GCCE) ● .sisx-file created in /sis/-folder of your project ● Send to device using PC Suite or Bluetooth 27 Andreas Jakl, 2009
  • 28. .sis vs .sisx ● Both have been created, installing .sis: ● .sisx = signed version of the .sis ● Without a valid certificate: self-signed with automatically generated certificate ● Installation of self-signed applications not allowed by default on some devices Change: Application manager  Software installation  change from “Signed only” to “All” 28 Andreas Jakl, 2009
  • 29. Own Build Configurations for Devices ● When importing a project or adding a build configuration (= SDK) later on: Right-click the project  Properties  Carbide.c++  Carbide Build Configurations Check that the current configuration is “Phone Release (GCCE)” for the S60 3rd Ed. MR-SDK Go to the “SIS Builder”-tab Click on “Add” to bring up “SIS Properties” dialog Choose the .pkg file 29 Andreas Jakl, 2009
  • 30. Automatic Building ● You might be used to Eclipse displaying errors as you type... ● ... but this is for Java, not for C++! ● You can still enable automatic compilation on resource change – might be useful for smaller projects Window  Preferences...  General  Workspace  Build automatically or: Project  Build automatically 30 Andreas Jakl, 2009
  • 31. Application structure Application class ● Entry point for OS ● Defines application UID ● Creates Document class ● Normally no changes required here. 31 Andreas Jakl, 2009
  • 32. Application structure (2) Document class ● Takes care of data model ● Creates Application UI (AppUI-class) ● Usually no changes required in this class either. 32 Andreas Jakl, 2009
  • 33. Application structure (3) AppUI class ● “Controller” of the app. ● Not visible itself ● Manages views (container) ● General, application-wide event handling (exit, pause, ...) 33 Andreas Jakl, 2009
  • 34. Application structure (4) View class ● Manages title- and status pane ● Command handling (for this view) 34 Andreas Jakl, 2009
  • 35. Application structure (5) Container class ● Handling of UI components ● Manages “what is visible” in the main pane (= main part of the screen) 35 Andreas Jakl, 2009
  • 36. App Startup (S60 Views) RunApplication CreateDocumentL() CreateAppUiL() ConstructL() DoActivateL() Avkon View Switching Application CMyApplication CMyDocument CMyAppUi CMyView1 CMyContainer1 Avkon CAknViewAppUi CAknApplication CAknDocument CAknAppUi CAknView CAknAppUiBase Uikon CEikApplication CEikDocument CEikAppUi AppArc Cone CApaApplication CApaDocument CCoeAppUi CCoeControl 36 Andreas Jakl, 2009
  • 37. UI-Design Menu, About Boxes and Leaves 37 Andreas Jakl, 2009
  • 38. Hint: the UI designer creates source code when you save the design. This can be problematic when you Menu Definition change or rename something. Therefore, only save when you’re finished! ● Open the UI design (MopoidContainer.uidesign) ● Create 3 menu items: Start new game About Exit 38 Andreas Jakl, 2009
  • 39. Exit Command ● Change the command id of the “Exit” command to EAknCmdExit Optional: Change the title 39 Andreas Jakl, 2009
  • 40. About Box ● Add a “Standard Note” dialog ● Modify its properties: Type: “information” (actually not 100% correct, should give information about an unexpected situation according to UI guidelines. But it’s fine for this demo) Text: your about message... Name: “noteAbout” 40 Andreas Jakl, 2009
  • 41. Connection: Menu  Dialog ● Open the options menu ● Right click  “Handle ‘Selected’ Event” for the “About” menu item 41 Andreas Jakl, 2009
  • 42. Connection: Menu  Dialog ● UI-Designer created: RunNoteAboutL() – to display the note dialog HandleAboutMenuItemSelectedL() – called when the menu item is selected ● Our task: Run the note when the menu item is selected TBool CMopoidContainerView::HandleAboutMenuItemSelectedL( TInt aCommand ) { RunNoteAboutL(); return ETrue; } 42 Andreas Jakl, 2009
  • 43. Result 43 Andreas Jakl, 2009
  • 44. Exceptions – Java ● Try & Catch for handling exceptions ● Functions can throw “Exceptions” Calling function Integer Class Try { … int x = Integer.parseInt(“1234”); static int parseInt throws NumberFormatException { } catch (NumberFormatException e) { … System.out.println(“Unable to convert this String to a number.”); } } … 44 Andreas Jakl, 2009
  • 45. The TRAP(D) macros are Leave – Symbian defined in e32cmn.h ● TRAP(D) catches exceptions (“Leave”) ● Functions send out leave ● Function name marked by an L-suffix Main-Function DoExampleL()-Function TRAPD(err, DoExampleL()); void DoExampleL() if (err) { { RFs fsSession; // Connect to the file console->Printf(KTxtFailed, err); server } User::LeaveIfError(fsSession.Connect()); // … TRAPD-Makro declares fsSession.Close(); err as TInt and = Leaves if the Connect() } KErrNone function does not return KErrNone 45 Andreas Jakl, 2009
  • 46. Central Exception Handling New (ELeave) … … NewL() … … User::Leave() … … ConstructL() … F5L() … … F6L() …. … F8L() …. … F3L() … F4L() … TRAPD(err, F2L()); if (err) … 46 Andreas Jakl, 2009
  • 47. Handling Leaves ● Try to implement central leave-handling ● If leave not handled by your code error-message shown by the UI-framework! ● Therefore: Only handle leaves yourself if they influence your application 47 Andreas Jakl, 2009
  • 48. S60 Framework Leave is passed on until (traps the leave a TRAP statement is reached somewhere) void CMopoidContainerView::HandleCommandL( TInt aCommand ) { TBool commandHandled = EFalse; switch ( aCommand ) { case EMopoidContainerViewAboutMenuItemCommand: commandHandled = HandleAboutMenuItemSelectedL( aCommand ); break; // ... TBool CMopoidContainerView::HandleAboutMenuItemSelectedL( TInt aCommand ) { RunNoteAboutL(); return ETrue; } No memory left to void CMopoidContainerView::RunNoteAboutL( const TDesC* aOverrideText ) { allocate the object CAknInformationNote* note = new ( ELeave ) CAknInformationNote(); if ( aOverrideText == NULL ) { HBufC* noteText = StringLoader::LoadLC(R_MOPOID_CONTAINER_NOTE_ABOUT); note->ExecuteLD( *noteText ); CleanupStack::PopAndDestroy( noteText ); } else { note->ExecuteLD( *aOverrideText ); } 48 } Andreas Jakl, 2009
  • 49. Add the pre-implemented framework to your project Game Engine 49 Andreas Jakl, 2009
  • 50. Extraction and Sources 1. Close Carbide.c++ 2. Unzip Mopoid.Update.zip to c:Symbiandev Keep the directory structure Overwrite all files (if there is no warning, the directory is wrong) 3. Start Carbide.c++ 4. Click on the project, press F5 (Refresh) 5. Open mopoid.mmp (project definition file) Switch to the “Sources”-tab Make sure all files in the “src”-dir are ticked. The header files do not have to be included here 50 Andreas Jakl, 2009
  • 51. Libraries 5. Switch to the “Libraries”-tab and add: bitgdi.lib mediaclientaudio.lib mediaclientimage.lib ● How to find out which libraries you need?  SDK documentation for the APIs that you use. Otherwise, you’ll get C++ linker errors. 51 Andreas Jakl, 2009
  • 52. Text in Symbian OS ● Mobile phones are global  localization is vital! ● Text is defined in C++ resource files One resource file per language Separate UI elements from source code! Easier to maintain Only appropriate language is loaded 52 Andreas Jakl, 2009
  • 53. Localization – Overview If using .rls-files instead of .loc, use rls_string instead of #define <AppName>.l01 <AppName>.l02 <AppName>.l03 UK English French German #define STR_hi “Hello” #define STR_hi “Salut” #define STR_hi “Hallo” <AppName>.loc Include currently active <AppName>.r01 language UK English compiled #ifdef LANGUAGE_01... resource file <AppName>.rss <AppName>.r02 Strings replaced with Resource Compiler French compiled #defines from currently resource file active .lxx <AppName>.r03 German compiled resource file 53 Andreas Jakl, 2009
  • 54. String Resources ● Define text in one place – and not in the source code ● Easy to modify, easy to localize <AppName>.l01 / .rls ... (Text only!) <Program>.cpp (C++ Source Code) #define STR_Loading “Loading...” #include <stringloader.h> #define STR_Caption “Hello World” #include <<AppName>.rsg> <AppName>.rss (UI Definition) void C<AppName>AppUi::DisplayInfo() #include “<AppName>.l01” { RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info HBufC* buf = StringLoader::LoadLC ( R_LOADING ); { [...] short_caption = STR_Caption; } CleanupStack::PopAndDestroy(buf); RESOURCE TBUF r_loading { buf = STR_Loading; } } [...] <AppName>.rsg (Generated by resource compiler) #define R_LOCALISABLE_APP_INFO 0x66a61005 #define R_LOADING 0x66a61006 54 Andreas Jakl, 2009
  • 55. Additional Game Text ● Define strings like explained on the previous slide Add an additional space char after MopoidContainer.l01 / MopoidContainer.rssi the “:” Resource name String name Text r_score STR_score Score: r_level STR_level Level: r_pause STR_pause Game Paused r_gameover STR_gameover Game Over r_finished STR_finished You made it! r_enterlevel STR_enterlevel Entering Level: r_lifelost STR_lifelost Live Lost! r_lives STR_lives Lives: r_pressjoystick STR_pressjoystick Press Joystick r_highscore STR_highscore High Score: r_title STR_title mopoid 55 Andreas Jakl, 2009
  • 56. New Game ● In the UI designer, create a new event handler for the “Start new game” menu item CMopoidContainerView::HandleStart_new_gameMenuItemSelectedL() if (iMopoidContainer->iGameEngine) iMopoidContainer->iGameEngine->StartNewGameL(); 56 Andreas Jakl, 2009
  • 57. Graphics ● Today’s phones: screen orientation / size changes ● Mopoid uses vector graphics ● S60: support for SVG-T 57 Andreas Jakl, 2009
  • 58. Adding Game Graphics ● Add a multi image file (.mif) to the icons-makefile: groupIcons_aif_scalable_dc.mk ● Target directory: resourceappsMopoidGraphics.mif ● Header generation: Header ● Header file: epoc32includeMopoidGraphics.mbg 58 Andreas Jakl, 2009
  • 59. Adding Game Graphics ● Choose images: bricks, panel and ball ● Set the mask depth for the bricks to n/a 59 Andreas Jakl, 2009
  • 60. Copying Data to the Emulator ● C:-drive of the phone is emulated in <EPOCROOT>winscwc e.g.: C:Symbian9.1S60_3rd_MREpoc32winscwc ● Additional game resources required during runtime: sounds and level definition file 1. Open Mopoid.mmp and write down the UID3 60 Andreas Jakl, 2009
  • 61. Copying Data to the Emulator ● Open groupbld.inf Lists which project definition & make files belong to the project and which files to export ● Export the files to the private directory The makefile will automatically create the .mif-file in the 61 Andreas Jakl, 2009 right dir
  • 62. Copying Data – Carbide.c++ 1.2 ● Bug in Carbide.c++ 1.2: directories saved with wrong slashes, resulting in this error: ● Solution: Correct slashes in bld.inf-file (not needed for 1.3+) Find & replace: “/”  “” 62 Andreas Jakl, 2009
  • 63. Phone Release ● Copy additional data files to the phone ● Contents of the SIS-file defined in sisMopoid.pkg Mopoid.pkg ; The icon-file "$(EPOCROOT)epoc32datazresourceappsMopoidGraphics.mif" -"!:resourceappsMopoidGraphics.mif" ; Sound files "..gfxhit.wav" -"!:privateE2C4F75Bhit.wav" Adapt the UID to "..gfxbounce.wav" your own! -"!:privateE2C4F75Bbounce.wav“ ; Levels definition file "..gfxlevels.dat" -"!:privateE2C4F75Blevels.dat" ; Required for the application to be covered by backup/restore facility "..sisbackup_registration.xml" -"!:privateE2C4F75Bbackup_registration.xml" 63 Andreas Jakl, 2009
  • 64. Sound Bug-Fix ● Error in the S60 3rd Ed., MR-SDK – includes are not set correctly for the sound API, resulting in this error: ● Solution: add a system include to Mopoid.mmp: <EPOCROOT>/ include/mmf/plugin 64 Andreas Jakl, 2009
  • 65. Testing ● Before building, choose “Project”  “Clean” ● This is what Mopoid should look like now (white, empty): ● ... if there are serious problems, use Mopoid.Merged.zip 65 Andreas Jakl, 2009
  • 66. Troubleshooting ● When encountering problems, clean your project Toolchain might not detect some changes in files, resulting in compile errors Cleaning is always a good idea, with any language on any platform! ● Frequent problem in this step: MopoidGraphics.mbg is not found when compiling Next slides: how to make sure everything is cleaned to solve this issue 66 Andreas Jakl, 2009
  • 67. Background Info: Build Toolchain ● Involved files and commands in a command-line build: Input files in <projectdir> Command Outputs Intermediate build files in epoc32build<projectdir> bld.inf > bldmake bldfiles abld.bat in <projectdir> Intermediate files in epoc32build<projectdir> project.mmp > abld build wins udeb Binary files in eopc32releasewinscwudeb 67 Andreas Jakl, 2009
  • 68. Clean Everything ● Clean Levels Level 0 (abld clean): Removes everything built by abld <target>. This includes: all intermediate files created during compilation and all the executables and import libraries created by the linker. Level 1 (abld reallyclean): As clean, but additionally removes exported files and makefiles. Level 2 (abld reallyclean, bldmake clean): Removes all files created by bldmake. ● Change to Level 2: Window  Preferences  Carbide.c++  Build  SBSv1-tab 68 Andreas Jakl, 2009
  • 69. Manual Cleaning ● In case cleaning alone doesn’t help - manually delete all files created by your project: Make sure the emulator isn’t running Search for “mopoid” in <SDK-dir>epoc32 Delete all files (not folders, problematic with Windows) 69 Andreas Jakl, 2009
  • 70. Getting the images out of the .mif-file Loading Images 70 Andreas Jakl, 2009
  • 71. Class Types ● CSpriteHandler loads, scales and provides images Why the “C”? Draw the image Set vector image size in pixels Load image (CAknIconUtils) .mif-File SVG-Images 71 Andreas Jakl, 2009
  • 72. Fundamental Types ● Defined in <SDK-path>epoc32includee32def.h Standard ANSI Symbian OS Description int TInt Signed (32-bit) Integer unsigend int TUint Unsigned (32-bit) Integer float TReal32 Single-precision IEEE 754 floating-point double TReal, TReal64 Double-precision IEEE 754 floating-point long long TInt64 Uses native 64-bit support bool TBool (ETrue, False) Equates to int due to early compilers void* TAny* “Pointer to anything” also available: TText[8|16], TInt[8|16|32], TUint[8|16|32], TUint64 72 Andreas Jakl, 2009
  • 73. Examples Example: TInt, TReal TInt x = 5; TReal y = (TReal)x + 0.5; Example: TBool TBool b = ETrue; // Bad style: ETrue = 1, but any non-zero number should be interpreted as true! if (b == ETrue) { ... } // Good style: if (b) { ... } Example: void / TAny* // Symbian OS uses ‘void’ for ‘nothing’ and ‘TAny*’ for ‘pointer to anyting’ void Foo(); // Returns no result TAny* p; // Pointer to anything 73 Andreas Jakl, 2009
  • 74. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes T Classes ● Remember the fundamental types (TInt, ...)? ● T classes  similar behaviour Do not have a destructor – Therefore, no member data that has a destructor Contain all data internally – No pointers, references or handles (“has-a” relation) ● Can be created on the stack and the heap ● Also usually used instead of a traditional C struct 74 Andreas Jakl, 2009
  • 75. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes T Classes – Example TPoint definition from e32cmn.h class TPoint { public: enum TUninitialized { EUninitialized }; /** Constructs default point, initialising its iX and iY members to zero. */ TPoint(TUninitialized) {} inline TPoint(); inline TPoint(TInt aX, TInt aY); IMPORT_C TBool operator==(const TPoint& aPoint) const; // [...] IMPORT_C TPoint operator-() const; IMPORT_C void SetXY(TInt aX, TInt aY); IMPORT_C TSize AsSize() const; public: Usage example /** The x coordinate. */ void CMyControl::Draw(const TRect &aRect) TInt iX; const /** The y coordinate. */ { TInt iY; CWindowGc& gc = SystemGc (); }; gc.DrawLine (TPoint (0, 0), iLastPoint); } 75 Andreas Jakl, 2009
  • 76. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes C Classes ● Properties of C classes (‘C’ for ‘cleanup’) Usually created on the heap (they’re often too large for stack themselves) Usually own pointers to large objects, resources, ... ● Derive from CBase (directly or indirectly) Safe construction / Destruction Zero initialization 76 Andreas Jakl, 2009
  • 77. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes C Classes – Characteristics ● Safe construction / destruction CBase defines virtual destructor – C++ therefore calls destructor in correct order – Also required for the cleanup stack (later module) Declares a private copy constructor and assignment operator – Prevents errors – If required: derived class has to declare it ● Zero initialization CBase overloads new-operator Zero-initializes all member data 77 Andreas Jakl, 2009
  • 78. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes C Classes – Example class CSprite : public CBase { public: // Constructors and destructors static CSprite* NewL( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap* aMask); static CSprite* NewLC( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap* aMask); virtual ~CSprite(); public: // New methods (omitted for clarity) private: // Constructors CSprite( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap* aMask); void ConstructL(); private: // Data TPoint iPosition; const CFbsBitmap * const iImage; const CFbsBitmap * const iMask; }; 78 Andreas Jakl, 2009
  • 79. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes R Classes ● Own an external resource handle, e.g.: Server session (RFs – file server session) Memory (RArray, RBuf) ● Initialization: Open(), Create() or Initialize() Close() or Reset() instead of destructor No automated Close() through the destructor! 79 Andreas Jakl, 2009
  • 80. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes R Classes – Example void CMyClass::SendCachedDataL() { RSocketServ socketServer; // Connect to the SocketServer User::LeaveIfError( socketServer.Connect() ); // Make sure Close() is called at the end CleanupClosePushL( socketServer ); // … CleanupStack::PopAndDestroy(); // Calls Close() on the socket server object } 80 Andreas Jakl, 2009
  • 81. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes M Classes ● M class M is for “mixin” Used for defining interface classes Declares pure virtual functions Should not contain members or constructors ● Implementing class Usually derives from CBase and the interface Only form of multiple inheritance encouraged on Symbian OS 81 Andreas Jakl, 2009
  • 82. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes M Classes – Example // Interface definition class MMdaAudioPlayerCallback { public: virtual void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) = 0; virtual void MapcPlayComplete(TInt aError) = 0; }; The CBase-derivation always has to be first! // Implementing class class CSoundPlayer : public CBase, public MMdaAudioPlayerCallback { // [...] protected: // Functions from base classes void MapcInitComplete( TInt aError, const TTimeIntervalMicroSeconds& aDuration ); void MapcPlayComplete( TInt aError ); // [...] } 82 Andreas Jakl, 2009
  • 83. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes Static Classes ● Static classes provide utility code ● Can not be instantiated ● No prefix letter Examples TInt computerMoveX = Math::Rand(iSeed) % iGridSize.iWidth; User::After(1000); // Suspends the current thread for 1000 microseconds Mem::FillZ(&targetData, 12); // Zero-fills 12-byte block starting from &targetData 83 Andreas Jakl, 2009
  • 84. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes Summary – Classes Prefix Category Examples Description T Type TDesC, TPoint, TFileName No destructor, “has-a” data owned internally C Class CBase, CActive, CFbsBitmap Any class has to be derived from CBase. Always allocated on the heap. Member data automatically initialized with zero. Important for cleanup stack. R Resource RFile, RTimer, Owns resources other than on the default heap. RWriteStream, RWindow Usually allocated as members or automatic variables. Usually require Close() to free resources. M Mixin, MGraphicsDeviceMap, Interface consisting of virtual functions. interface MEikMenuObserver Implementation derives from it. Only approved use of multiple inheritance. Static User, Math, Mem Consists purely of static functions, cannot be class instantiated into an object. 84 Andreas Jakl, 2009
  • 85. When to use which class type? Usually an interface  M class Class contains no member data Sometimes C class Class contains only static functions Static class  no prefix (or factory classes) Member data has no destructor / Only contains native types (T classes) or does not need special cleanup “uses-a” data  T class Size of the data contained by the class Stack is limited  avoid T class will be large (> 512 bytes)  typically a C class Usually a C class. Also R-classes, which Class owns data that needs cleanup are seldom implemented yourself 85 Andreas Jakl, 2009
  • 86. Loading the .mif-File ● Define the .mif-filename in CSpriteHandler::ConstructL() _LIT(KMifFile, "MopoidGraphics.mif"); ● Uncomment the line to dynamically add the folder NCommonFunctions::AddResourceDirL(KMifFile, fileName); ● Images will be stored in iSprites-array TFixedArray<CFbsBitmap*, MopoidShared::ENumSprites> iSprites; Why the “i”? 86 Andreas Jakl, 2009
  • 87. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes Variable Naming Conventions Prefix Category Examples Description E Enumerated EMonday, ESolidBrush Values in an enumeration – which itself should have T constant prefix: EMonday is a member of TDayOfWeek K Constant KMaxFileName, Constants from #define or const TInt. KRgbWhite i Member iDevice, iX Any non-static member variable. i refers to ‘instance’ variable a Argument aDevice, aX Function argument. Stands for ‘argument’  aOrigin, not anOrigin! Automatic device, x Automatic: variable that is created automatically when variable required and destroyed when out of scope 87 Andreas Jakl, 2009
  • 88. Variables | T Classes | C Classes | R Classes | M Classes | Static Classes Example – Variables enum TStuffState // Declares an enumeration, prefix T { EInitialized = 0, // Individual elements with prefix E EError }; const TInt KMaxLength = 50; // Constant with prefix K class TStuff // T type class { public: void DoStuff(TInt aLength); // Function argument with prefix a private: TInt iLength; // Member (instance) variable with prefix i TStuffState iState; }; void TStuff::DoStuff(TInt aLength) { if (aLength > KMaxLength) iState = EError; else iLength = aLength; // Note: no ambiguities! } 88 Andreas Jakl, 2009
  • 89. Fixed Arrays ● Standard C++ Array: TInt myArray[25]; ● The same using Symbian OS wrapper class: TFixedArray<TInt, 25> myArray; <ptr> [0] [1] … [24] myArray 25x TInt 89 Andreas Jakl, 2009
  • 90. TFixedArray - Advantages ● Range checking (Panic if out of range) At(): Checks range in debug- and release-builds []: Checks range in debug-builds only ● Comfort functions, e.g.: DeleteAll(): invokes delete on each element Reset(): fills each element with zeros Count(): number of elements in the array Begin(), End(): to navigate the array 90 Andreas Jakl, 2009
  • 91. Loading Images ● Create bitmap from specified ID in .mif-file CSpriteHandler::ConstructL() iSprites[ESpritePanel] = AknIconUtils::CreateIconL( fileName, EMbmMopoidgraphicsPanel); ● Store it in the iSprites array ● IDs? Right-click Icons_aif_scalable_dc.mk  Edit MBM / MIF  MopoidGraphics.mif or: open <EPOCROOT>/include/MopoidGraphics.mbg 91 Andreas Jakl, 2009
  • 92. Loading Image + Mask ● Load image and mask at the same time Otherwise, alpha blending wouldn’t work as expected Panel and ball images need a transparency mask (rounded corners) Bricks are rectangular, no mask required ( use method from previous slide) CSpriteHandler::ConstructL() AknIconUtils::CreateIconL(iSprites[ESpritePanel], iSprites[ESpritePanelM], fileName, EMbmMopoidgraphicsPanel, EMbmMopoidgraphicsPanel_mask); 92 Andreas Jakl, 2009
  • 93. Load all Images iSprites array-position .mif-ID ESpritePanel EMbmMopoidgraphicsPanel ESpritePanelM EMbmMopoidgraphicsPanel_mask ESpriteBall EMbmMopoidgraphicsBall ESpriteBallM EMbmMopoidgraphicsBall_mask ESpriteBrickNormal EMbmMopoidgraphicsBrick_green ESpriteBrickIndestructible EMbmMopoidgraphicsBrick_brown ESpriteBrickDouble EMbmMopoidgraphicsBrick_yellow ESpriteBrickMoving EMbmMopoidgraphicsBrick_red ESpriteBrickHarderBrick EMbmMopoidgraphicsBrick_violet ESpriteBrickSofterBrick EMbmMopoidgraphicsBrick_blue Defined in MopoidSharedData.h 93 Andreas Jakl, 2009
  • 94. Setting the Image Size ● Dynamically set by the game engine – according to screen resolution ● Handled in: void CSpriteHandler::DoSetSpriteSize( const MopoidShared::TSpriteIds aSpriteId, const TSize& aNewSize) ● Set image size: CSpriteHandler::DoSetSpriteSize() AknIconUtils::SetSize(iSprites[aSpriteId], aNewSize); 94 Andreas Jakl, 2009
  • 95. Memory Leaks ● Test it: Launch Mopoid in the emulator Close the app in the emulator (not the emulator itself!) 95 Andreas Jakl, 2009
  • 96. Deleting Images ● Images owned by sprite handler  Delete pointers in the destructor CSpriteHandler::~CSpriteHandler() iSprites.DeleteAll(); (= same as for-loop with delete on every element) 96 Andreas Jakl, 2009
  • 97. Panics ● ... cannot be caught and handled! ● Terminates thread (= usually the whole application) ● Use them for checking code logic only ● Can also be sent out by the system for critical errors ● If a panic happens: Make sure you fix it, as you can’t handle it! // Stray signal detected! _LIT(KMsgStraySignal, "Stray signaln"); User::Panic(KMsgStraySignal, 1); // Panic with code 1 97 Andreas Jakl, 2009
  • 98. Panics ● Try it – add a serious error CSpriteHandler::ConstructL() iSprites[999] = AknIconUtils::CreateIconL( fileName, EMbmMopoidgraphicsPanel); ● Range checked by TFixedArray (in debug builds) 98 Andreas Jakl, 2009
  • 99. Information about Panics ● SDK doc: Symbian OS v9.x  Symbian OS reference  System panic reference  USER Tip: install the automated panic lookup plug-in for Carbide.c++: 99 Andreas Jakl, 2009 http://www.symbianresources.com/projects/paniclookup.php
  • 100. Adapting to different screen layouts Scalable UI 100 Andreas Jakl, 2009
  • 101. Screen Layout Changes ● Most current S60 phones: portrait & landscape QVGA (240 x 320) Changed by app or auto screen rotation (sensor) ● Others: E90: outer screen 240 x 320, inner: 800 x 352 5500 Sport: 208 x 208 E70: 352 x 416 ● Future phones: VGA + ●  App should adapt to all resolutions and be notified about changes 101 Andreas Jakl, 2009
  • 102. Scalable UI in Mopoid – Overview Framework Container Base Class (CCoeControl) HandleResourceChange() SizeChanged() Container (CMopoidContainer) HandleResourceChange() SetExtentToWholeScreen() SizeChanged() Game Engine (CMopoidGameEngine) SetScreenSize() 102 Andreas Jakl, 2009
  • 103. Scalable UI – Source Code ● Upon start-up and subsequent orientation / resolution changes, the framework calls HandleResourceChange() of all visible container classes CMopoidContainer::HandleResourceChange(TInt aType) if(aType == KEikDynamicLayoutVariantSwitch) { // User switched the layout configuration // or the screen resolution // -> we have to recreate the layout SetExtentToWholeScreen(); // Results in a call of SizeChanged() } ●  Applies the new size (whole screen) to the container 103 Andreas Jakl, 2009
  • 104. Scalable UI – Source Code ● In CMopoidContainer::SizeChanged() Query the current resolution Inform the game engine CMopoidContainer::SizeChanged() iGameEngine->SetScreenSize(this->Size()); 104 Andreas Jakl, 2009
  • 105. Finally get some content on the screen Displaying Graphics 105 Andreas Jakl, 2009
  • 106. Back Buffer Transferred as a whole when drawing is finished Back Buffer Screen 106 Andreas Jakl, 2009
  • 107. Game Loop CMopoidGameEngine Calculate time difference CPeriodic (static) TimerCallBack() Animate the panel DoFrame() Draw the frame to the back buffer Request a Asynch. call redraw event CMopoidContainer Copy the back buffer to the 107 Andreas Jakl, 2009 screen
  • 108. DrawFrame() ● First: clear the back buffer CMopoidGameEngine::DrawFrame() // Clear back buffer iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ENullPen); iBackBufferBmpGc->SetBrushColor(KRgbBlack); iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ESolidBrush); iBackBufferBmpGc->DrawRect( TRect(TPoint(0,0),iSettings->iScreenSize) ); iBackBufferBmpGc->SetBrushStyle(CGraphicsContext::ENullBrush); Pen ENullPen Brush ESolidBrush, KRgbBlack 108 Andreas Jakl, 2009
  • 109. Drawing Bricks (w/o transparency) ● Bricks are drawn in the for-loop CMopoidGameEngine::DrawFrame() iBackBufferBmpGc->BitBlt(ConvToScreenCoord( iGrid->ConvertGridToXY(x, y)), iSpriteHandler->GetSprite(spriteId)); ● ConvToScreenCoord() Game internally calculates in VGA resolution Converts coordinates to current screen res Returns a TPoint (contains two TInt) ● GetSprite() Returns the correct CFbsBitmap* spriteID: set in switch-statement just before = brick type 109 Andreas Jakl, 2009
  • 110. Drawing Panel and Ball (with transp.) ● Ball sprite CMopoidGameEngine::DrawFrame() iBackBufferBmpGc->BitBltMasked(ConvToScreenCoord(ballSpritePos), iSpriteHandler->GetSprite(MopoidShared::ESpriteBall), iSpriteHandler->GetSprite(MopoidShared::ESpriteBall)->SizeInPixels(), iSpriteHandler->GetSprite(MopoidShared::ESpriteBallM), EFalse); ● Do the same for the panel near the end of the method Position: iPanel.iPos Bitmap IDs: ESpritePanel / ESpritePanelM 110 Andreas Jakl, 2009
  • 111. Screen Flickering ● Note: UI Designer clears the screen with white before the bitmap is copied  results in flickering on some devices void CMopoidContainer::Draw(const TRect& aRect) const { // [[[ begin generated region: do not modify [Generated Contents] CWindowGc& gc = SystemGc(); gc.Clear( aRect ); // Remove this line to prevent flickering // ]]] end generated region [Generated Contents] ● Changes will get overwritten whenever you change the design 111 Andreas Jakl, 2009
  • 112. White Border around Sprites ● On S60 3rd Ed.-devices & the MR-emulator, there is a white border around the sprites (fixed in FP1+) 112 Andreas Jakl, 2009
  • 113. Keeping the game loop alive Periodic Events 113 Andreas Jakl, 2009
  • 114. What is an Active Object? ● Requests asynchronous service provided by Asynchronous Service Provider ● Receives call-back when finished / error message handling by Active Scheduler  Active Object ≈ Listener! 114 Andreas Jakl, 2009
  • 115. Event Handling Asynchronous Asynchronous Service Providers Service Providers Event 1 Event 2 Event 3 Event 1 Event 2 Event 3 Event Event Event Active Scheduler (in app. thread) Handler Handler Handler (Thread) (Thread) (Thread) Event Event Event Handler Handler Handler (AO) (AO) (AO) Application (Possibly an extra thread) Application (thread) Traditional Event-Handling Active Objects (Symbian OS) 115 Andreas Jakl, 2009
  • 116. Active Objects ● Asynchronous Service Provider (ASP) Executes asynchronous task e.g. timer, socket-related request, take a camera picture, load and prepare a sound file, ... ● Application-side: AOs encapsulate ASP and event handling (after the request to the ASP has finished) ● Modular separation: Active Scheduler (AS): event completion processing for all ASPs Active Object (AO): individual event handling 116 Andreas Jakl, 2009
  • 117. Timers ● A timer is an asynchronous service Pre-implemented: we don’t have to write the active object ourselves But be aware of the characteristics (non-pre-emptive multitasking between AOs in one thread) Don’t stick in call-back routine for too long  makes app unresponsive, blocks user event handling! MopoidGameEngine.h CPeriodic* iPeriodicTimer; 117 Andreas Jakl, 2009
  • 118. Call-Back Interval ● Starting is necessary several times First start New game Resume paused game ●  encapsulated in CMopoidGameEngine::StartTimerL() ● Define call-back interval: 5000 micro seconds = 0,005 seconds CMopoidGameEngine::StartTimerL() const TTimeIntervalMicroSeconds32 KTickInterval = 5000; 118 Andreas Jakl, 2009
  • 119. Allocating the Timer Instance ● Allocate timer object Standard priority is sufficient Remember: only affects other AOs of this app. It’s not the system-wide thread/process priority! CMopoidGameEngine::StartTimerL() if (!iPeriodicTimer) { iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityStandard); } 119 Andreas Jakl, 2009
  • 120. Starting the Timer CMopoidGameEngine::StartTimerL() iPeriodicTimer->Start(KTickInterval, KTickInterval, TCallBack(TimerCallBack, this)); ● TCallBack-object First parameter: TAny* (= void*) function pointer to call- back function. Implementing method has to take one parameter of type TAny* and return a TInt Second parameter: pointer that will passed to the static call-back function MopoidGameEngine.h (already declared, just for reference) static TInt TimerCallBack(TAny* aObject); 120 Andreas Jakl, 2009
  • 121. Call-Back ● Usual task of call-back function cast the parameter to the correct class call a non-static call-back method for complete access to the class TInt CMopoidGameEngine::TimerCallBack(TAny* aObject) { // Call non-static method return ((CMopoidGameEngine*)aObject)->DoFrame(); } ● Call-backs might not be regular Call-back of a different active object is running or higher priority call-backs waiting  DoFrame() checks time difference from last frame 121 Andreas Jakl, 2009
  • 122. Stopping the Timer ● Cancel the timer ● Delete the instance (recommended by the SDK doc) void CMopoidGameEngine::StopTimer() { // If the timer object exists: stop and delete it. if (iPeriodicTimer) { iPeriodicTimer->Cancel(); delete iPeriodicTimer; iPeriodicTimer = NULL; } } 122 Andreas Jakl, 2009
  • 123. Back Light ● Ball might stay in the upper part of the screen for some time, no key presses required ● Make sure the back light doesn’t always turn off ●  Simulate user activity by resetting the inactivity timer of the framework: CMopoidGameEngine::DoFrame() User::ResetInactivityTime(); 123 Andreas Jakl, 2009
  • 124. Let’s start to play! Handling Keys 124 Andreas Jakl, 2009
  • 125. Control Stack Controls put on the stack in the order: A, B, C, D ● Symbian OS maintains Control X an internal control stack ECoeStackPriorityDefault (=0) Control Y ● All controls that should Keyboard Focus receive key events are put on the stack ECoeStackPriorityMenu (=10) Control Z ● Starting at stack pos. 0, events are offered to ECoeStackPriorityDialog (=50) each control until they Events Stack position 0 are consumed by a ECoeStackPriorityDialog (=50) control CMopoidContainerView::DoActivateL() AppUi()->AddToStackL( *this, 2009 125 Andreas Jakl, iMopoidContainer );
  • 126. Was the key event handled by us? ● Controls are offered key events in: TKeyResponse CMopoidContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType) ● Return value depending on if the event was handled: EKeyWasConsumed: We used the key event, do not send it to Return other controls (TKeyResponse) EKeyWasNotConsumed: This key event was not interesting for us, send it to other controls 126 Andreas Jakl, 2009
  • 127. Keys ● Type of event sent in aType parameter EEventKeyDown EEventKey EEventKeyUp ● Handling keys for left & right Add cases to the switch statement: EStdKeyLeftArrow, EStdKeyRightArrow Send the event to the game engine: iGameEngine->iKeyHandler.LeftPressed() Set the prepared return variable “handled” to EKeyWasConsumed Don’t forget the break for the case-statement! 127 Andreas Jakl, 2009
  • 128. Keep the user informed Displaying Text 128 Andreas Jakl, 2009
  • 129. Fonts ● Games use low level methods to draw text Highly sophisticated games usually their own bitmap font ● Retrieving a standard system font CMopoidSettings::ConstructL() iFontUsed = (CFont*) AknLayoutUtils::LayoutFontFromId( EAknLogicalFontPrimarySmallFont); iFontHeight = iFontUsed->AscentInPixels(); ● Apply the font to the context CMopoidGameEngine::DrawTextL() iBackBufferBmpGc->UseFont(iSettings->iFontUsed); 129 Andreas Jakl, 2009
  • 130. Font Colour ● Setup for drawing text (in red colour) Brush was already set to a null brush before CMopoidGameEngine::DrawTextL() iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ESolidPen); iBackBufferBmpGc->SetPenColor(KRgbRed); TBuf<30> tempStr; ESolidPen, Pen KRgbRed text text Brush ENullBrush 130 Andreas Jakl, 2009
  • 131. Buffer Descriptors ● Comparable to (const) char[] of C ● Directly contain the string ● Use C++ templates to specify length (parameter) Constant: TBufC<5> 5 ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ iLength (TDesC) Modifiable: TBuf<9> 5 9 ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ iLength iMaxLength (TDesC) (TDes) 131 Andreas Jakl, 2009
  • 132. Size, Length, MaxLength ● TBuf<9> with text “Hello” 5 9 ‘H’ ‘e’ ‘l’ ‘l’ ‘o’ 4 bytes 4 bytes 2 2 ... Unicode characters! Length() 5 (characters) MaxLength() 9 (characters) Size() 10 (bytes) MaxSize() 18 (bytes) 132 Andreas Jakl, 2009
  • 133. Initializing the TBuf ● Assigning Strings // Define constant string literal _LIT(KString1, "Hello "); _LIT(KString2, "World"); // Copy KString1 into new TBuf with max. length of 15 TBuf<15> buf1(KString1); // Same as above, this time using Copy() and KString2 TBuf<15> buf2; // Initialize empty TBuf with max. length of 15 buf2.Copy(KString2); // Append contents of buf2 to buf1 buf1.Append(buf2); // Create constant descriptor based on KString1 TBufC<15> cBuf1(KString1); // Replace contents of cBuf1 with contents of buf1 cBuf1 = buf1; 133 Andreas Jakl, 2009
  • 134. Using the TBuf _LIT(KHelloWorld, "Hello World"); // Defines constant string literal const TInt maxLength = 15; // Create a modifiable buffer TBuf<maxLength> buf; TInt curLength = buf.Length(); // ...... ? TInt maxLength2 = buf.MaxLength(); // ...... ? // Set the contents of the buffer buf = KHelloWorld; curLength = buf.Length(); // ...... ? TInt curSize = buf.Size(); // ...... ? TText ch = buf[1]; // ...... ? 134 Andreas Jakl, 2009
  • 135. Using the TBuf _LIT(KHelloWorld, "Hello World"); // Defines constant string literal const TInt maxLength = 15; // Create a modifiable buffer TBuf<maxLength> buf; TInt curLength = buf.Length(); // == 0 TInt maxLength2 = buf.MaxLength(); // == 20 // Set the contents of the buffer buf = KHelloWorld; curLength = buf.Length(); // == 11 TInt curSize = buf.Size(); // == 22 TText ch = buf[1]; // == ‘e’ 135 Andreas Jakl, 2009
  • 136. Maximum Length _LIT(KHello, "Hello "); // Defines constant string literal TBuf<15> buf(KHello); // buf == “Hello ” buf.Append(KHello); // buf == “Hello Hello “ buf.Append(KHello); // Exceeds maximum length Panic! SDK-Doc for USER 11-panic: “This panic is raised when any operation that moves or copies data to a 16-bit variant descriptor, causes the length of that descriptor to exceed its maximum length. […]” 136 Andreas Jakl, 2009
  • 137. Inheritance Hierarchy ● Abstract base class because of: Generalisation (use base type for parameters!) Provide basic functions shared by all types (e.g. Compare(), constant modifiable Find(), Mid(), ...) 137 Andreas Jakl, 2009
  • 138. Reading Text from Resource Files ● Multiple options to read text from resource files ● Here: through environment from Symbian OS framework CMopoidGameEngine::DrawTextL() CEikonEnv* env = CEikonEnv::Static(); ● Read text from resource files into the descriptor CMopoidGameEngine::DrawTextL() env->ReadResourceL(tempStr, R_HIGHSCORE); ● (Remember: you declared the resource yourself!) MopoidContainer.rssi RESOURCE TBUF r_highscore { buf = STR_highscore; } 138 Andreas Jakl, 2009
  • 139. Formatting and Displaying Text ● tempStr now contains “High Score: ” ● Append the current score: CMopoidGameEngine::DrawTextL() tempStr.AppendNum(iSettings->iHighScore); ● Draw the text x-coord: 5 y was calculated directly above CMopoidGameEngine::DrawTextL() iBackBufferBmpGc->DrawText(tempStr, TPoint(5, yTextStartBottom)); 139 Andreas Jakl, 2009
  • 140. Current Score ● Like for the previous text: Resource: R_SCORE Number: iSettings->iScore x-coordinate: 5 y-coordinate: one line above previous text yTextStartBottom - iSettings->iTextYOffset 140 Andreas Jakl, 2009
  • 141. Aligning Text ● Print text on the right side of the screen CMopoidGameEngine::DrawTextL() iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect, yTextStartBottom, CGraphicsContext::ERight, 3); Level Text: R_LEVEL Value: iSettings->iLevel Position: y: yTextStartBottom x-offset: 3 (from the right side of the screen) Lives Text: R_LIVES Value: iSettings->iLives Position: y: yTextStartBottom - iSettings->iTextYOffset x-offset: 3 141 Andreas Jakl, 2009
  • 142. Final State ● Remove the comment from the code block ( activate the rest of the DrawTextL()-method) ● The final state: 142 Andreas Jakl, 2009
  • 143. Be persistent Reading / Writing Files 143 Andreas Jakl, 2009
  • 144. Preparations ● Filename and version have already been declared MopoidGameEngine.h #define MOPOID_FILE_VERSION_NUMBER 1 _LIT(KMopoidDataFile, "settings.dat"); ● We will use the CFileStore-class  add the required include file (see SDK doc) MopoidGameEngine.h #include <s32file.h> 144 Andreas Jakl, 2009
  • 145. Data Caging – Overview • All binaries of all apps in one dir • Can only be executed from Executable there • Usually: no read / write access • sysbin • Bitmaps, fonts, help files Resources • Usually: read-only • resource • Each application its own dir • Used for settings, ... Private • Usually: read / write only for Data own private dir • private<UID3> 145 Andreas Jakl, 2009
  • 146. Data Caging ● App. only has access to: Separating code Own directories and data! “Open” directories ● Access based on capabilities and identity SystemAppsJourneyJourney.app SysBinJourney.exe SystemAppsJourneyJourney.mbm ResourceAppsJourney.mbm SystemAppsJourneyJourney.rsc Private10003a3fJourney.rsc Symbian OS, pre-V9 Symbian OS 9.x 146 Andreas Jakl, 2009
  • 147. Data Caging – Directories Directory Capability Capability Used for (Read) (Write) sys AllFiles TCB Applications can only be executed from here. resource - TCB Fonts, bitmaps, help-files, … Only read-access for apps, to prevent corruption. private<own SID> - - For application data (settings, …). DLLs do not have own private dir, but instead use that of their loading process. private<other SID> AllFiles AllFiles AllFiles-capability required to access private data of other apps. All others - - Unrestricted data – images, … 147 Andreas Jakl, 2009
  • 148. More about directories ● Data caging provides secure area for application’s data ● All executables installed to sysbin Risk of filename clashes – use your unique UID as part of the executable filename Removable drives: Hash stored to c:syshash Prevents execution of modified executables 148 Andreas Jakl, 2009
  • 149. Data Files ● Data file should be stored in our private directory: private<UID3>settings.dat ● Dynamically add the path: CMopoidGameEngine::SaveGameProgessL() NCommonFunctions::AddPrivateDirL(iFs, KMopoidDataFile, fileName); ● Central part of this custom utility function: NCommonFunctions::AddPrivateDirL() aFs.PrivatePath( aCompleteName ); 149 Andreas Jakl, 2009
  • 150. File Store ● Many ways to access files are possible (RFile, ...) ● Here: CFileStore – one of the most flexible Store (File) Encapsulates file-based, persistent stores Stream (ID) Stores multiple streams, each identified by an ID Stream (ID) ... Allows easy serialization of objects Direct file store: doesn’t allow modifying data – not important for us, we will always replace the stream CMopoidGameEngine::SaveGameProgessL() CFileStore* store = CDirectFileStore::ReplaceLC( iFs, fileName, EFileWrite); store->SetTypeL(KDirectFileStoreLayoutUid); 150 Andreas Jakl, 2009
  • 151. Creating a Stream ● One stream has to be the root stream We only use one stream – set it to the root stream (later) Multiple streams: e.g., for a database CMopoidGameEngine::SaveGameProgessL() RStoreWriteStream stream; TStreamId id = stream.CreateLC(*store); 151 Andreas Jakl, 2009
  • 152. Writing Data ● For now: file version and high score CMopoidGameEngine::SaveGameProgessL() // Write file version number stream.WriteInt32L(MOPOID_FILE_VERSION_NUMBER); // Write highscore stream.WriteInt32L(iSettings->iHighScore); ● Saving the file version? Updating the game != uninstallation Keeps additional files New game version might add additional settings Should know file version, to import or discard old file! 152 Andreas Jakl, 2009
  • 153. Closing the File ● Make sure that all data is written and close everything CMopoidGameEngine::SaveGameProgessL() // Commit the changes to the stream stream.CommitL(); CleanupStack::PopAndDestroy(&stream); // Set the stream in the store and commit the store store->SetRootL(id); store->CommitL(); CleanupStack::PopAndDestroy(store); 153 Andreas Jakl, 2009
  • 154. Cleanup Stack ● Situation: function creates local heap-object ● Before code gets to the delete-statement: error Function is left (Leave) Pointer-address on the stack is freed Object itself is orphaned memory leak! CImage void CMyObj::DoSomethingL() { void CImage::DoSomethingDangerousL() CImage* img = new (ELeave) CImage(); { User::Leave(KErrNotFound); img->DoSomethingDangerousL(); } delete img; } img = pointer on the stack 154 to an instance 2009 heap Andreas Jakl, on the
  • 155. Cleanup Stack ● Memory situation if a leave occurs: img Stack Heap Object stays on the heap; Pointer to delete the instance is lost memory leak 155 Andreas Jakl, 2009
  • 156. Cleanup Stack ● Solution: Cleanup Stack void CMyObj::DoSomethingL() img { CImage* img = new (ELeave) CImage(); CleanupStack CleanupStack::PushL(img); img->DoSomethingDangerousL(); CleanupStack::PopAndDestroy(); } img Stack Heap When no leave occurs: object still has to be deleted by you + Cleanup stack saves a second pointer removed from the cleanup stack! to the object on the heap. 156 Andreas Jakl, 2009
  • 157. R-Classes Cleanup ● R-classes usually have extra methods to free the resources Just calling the destructor wouldn’t be sufficient! In the case of the RBuf descriptor (heap based string): Close() Special method to put the instance on the cleanup stack – has to tell it how to destroy the object CMopoidGameEngine::SaveGameProgessL() RBuf fileName; // Push the variable onto the cleanup stack fileName.CleanupClosePushL(); // ... any leave here would also destroy the obj. // Pop and destroy (calls Close() on the object) CleanupStack::PopAndDestroy(&fileName); 157 Andreas Jakl, 2009
  • 158. Loading ● Similar to saving files 1. Open the file store CMopoidGameEngine::LoadGameProgessL() CFileStore* store = CDirectFileStore::OpenLC( iFs, fileName, EFileRead); 2. Open the root stream (no ID is required for the root) CMopoidGameEngine::LoadGameProgessL() RStoreReadStream stream; stream.OpenLC(*store, store->Root()); 158 Andreas Jakl, 2009
  • 159. Reading Data 3. Read the data CMopoidGameEngine::LoadGameProgessL() TInt versionNumber = stream.ReadInt32L(); if (versionNumber != MOPOID_FILE_VERSION_NUMBER) User::Leave(KErrNotFound); iSettings->iHighScore = stream.ReadInt32L(); If the file version doesn’t match – same behaviour as if the file wasn’t found. You could import an old version instead. 159 Andreas Jakl, 2009
  • 160. If the File Was Not Found ● File not found-error (or wrong version) Ignored Settings-class initialized with default values CMopoidGameEngine::ConstructL() // Load high score and settings TRAPD(err, LoadGameProgressL()); if (err != KErrNone && err != KErrNotFound) User::Leave(err); ● All other errors (e.g., not enough disc space left) TRAP’d leave is sent out again 160 Andreas Jakl, 2009
  • 161. Cleanup 4. Close all handles CMopoidGameEngine::LoadGameProgessL() CleanupStack::PopAndDestroy(&stream); CleanupStack::PopAndDestroy(store); ● What about cleanup upon deinstallation? Required by Symbian Signed criteria! The whole private directory would be deleted anyway, but it’s still better to explicitly specify it 161 Andreas Jakl, 2009
  • 162. Cleanup – Uninstallation ● Files that are to be removed during uninstallation: specified in the package file Mopoid.pkg ; --- Settings-file ""-"!:privateE2C4F75Bsettings.dat",FN ● “FN” means “FileNull” – SDK help: A file which does not yet exist, so is not included in the sis file. It is created by the running application and will be deleted when the application is removed. The name assigned to the source file is unimportant and should be empty, i.e. “”. Note that such files will not be deleted when upgrading to a later version. This ensures that such files as .ini files, which store application preferences, are not lost in an upgrade. 162 Andreas Jakl, 2009
  • 163. Make a good appearance in the phone menu: Application Icon 163 Andreas Jakl, 2009
  • 164. Application Icon ● Icons have to be .svg-files as well, encapsulated in a .mif ● Set for the whole application Open application.uidesign Switch to the “AppUi”-tab Right-click on the title pane Choose: “Override Context Icon” Select the “Mopoid_aif.mif”-file Image: qgn_menu_Mopoid.svg 164 Andreas Jakl, 2009
  • 165. Is anyone out there? Foreground / Background 165 Andreas Jakl, 2009
  • 166. Background? ● Symbian OS = multitasking system ● Sent to the background due to: Incoming call Warnings (e.g., low battery) User sending you to the background ● Applications should react to this Save current state Free shared common resources (e.g., camera) Pause games Enter low power state 166 Andreas Jakl, 2009
  • 167. Foreground Notification ● Abstact method of the View base class (CAknView) ● Out task: override this method, called automatically! Declare it in a protected section of the view header MopoidContainerView.h void HandleForegroundEventL(TBool aForeground); 167 Andreas Jakl, 2009
  • 168. Foreground Handling ● Desired behaviour Pause the game when it looses the foreground Do not resume the game when it regains foreground status – player can’t continue playing 1 ms after the call! MopoidContainerView.cpp // Handle any change of focus void CMopoidContainerView::HandleForegroundEventL(TBool aForeground) { if (aForeground) { // gained focus // Don't resume the game - wait for user to resume it if (iMopoidContainer && iMopoidContainer->iGameEngine) iMopoidContainer->iGameEngine->iHaveFocus = ETrue; } else { // lost focus – Pause game if (iMopoidContainer && iMopoidContainer->iGameEngine) { iMopoidContainer->iGameEngine->PauseGame(); iMopoidContainer->iGameEngine->iHaveFocus = EFalse; } } // call base class event handler CAknView::HandleForegroundEventL(aForeground); 168 Andreas Jakl, 2009 }
  • 169. Adapting the Game to the Environment Sound Volume / Dynamic Menus 169 Andreas Jakl, 2009
  • 170. Sounds and Mobile Games ● Mobile Phones are used everywhere train, toilet, bus stop, ... ● Sound is not always appropriate! ● Gameloft: games ask desired volume on every start-up! ● Add two additional menu items to MopoidContainer.uidesign Sound On Sound Off ● Create event handler methods 170 Andreas Jakl, 2009
  • 171. (De) activating Sound ● Send the command to the game engine TBool CMopoidContainerView::HandleSound_OnMenuItemSelectedL( TInt aCommand ) { if (iMopoidContainer && iMopoidContainer->iGameEngine) { iMopoidContainer->iGameEngine->SetSoundLevelL(ETrue); } return ETrue; } ● ... do the inverse for the sound off-event! ● Add the sound state to the settings file Accessible from the game engine via iSettings->iSoundLevel Write it using WriteInt32L() 171 Andreas Jakl, 2009
  • 172. Dynamic Menus ● The visibility state of a menu item is not directly defined (in S60, UIQ 3 is different) ● Instead, framework calls a method each time right before the menu is displayed ● App gets the chance to dim individual items there ● Override the method from the CAknView base class: MopoidContainerView.h void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane); 172 Andreas Jakl, 2009
  • 173. Dimming Menu Items ● Check which resource is currently initialized – the menu pane is relevant ● Menu IDs are defined by the UI designer in MopoidContainer.hrh ● Dim “Sound Off / On” menu items according to sound state MopoidContainerView::DynInitMenuPaneL() if (R_MOPOID_CONTAINER_MENU_PANE1_MENU_PANE == aResourceId && iMopoidContainer && iMopoidContainer->iGameEngine) { aMenuPane->SetItemDimmed(EMopoidContainerViewSound_OnMenuItemCommand, iMopoidContainer->iGameEngine->IsSoundOn()); aMenuPane->SetItemDimmed(EMopoidContainerViewSound_OffMenuItemCommand, !iMopoidContainer->iGameEngine->IsSoundOn()); } 173 Andreas Jakl, 2009
  • 174. We’re finished! Summary 174 Andreas Jakl, 2009
  • 175. Mopoid ● Tasks Defining and displaying text, fonts, descriptors Create your own application using the UI designer Using vector graphics Define a menu and an about Scalable UI box Asynchronous events, Leaves, Panics and Cleanup timers Stack Key handling Project structure, libraries Files, data caging (platform Class types, naming security) conventions Foreground / background Dynamic menu 175 Andreas Jakl, 2009
  • 176. That’s it Thanks for your attention! 176 Andreas Jakl, 2009