+ All Categories
Home > Technology > Symbian OS - Mopoid Next Gen - Slides

Symbian OS - Mopoid Next Gen - Slides

Date post: 11-May-2015
Category:
Upload: andreas-jakl
View: 2,634 times
Download: 2 times
Share this document with a friend
Description:
First, you will learn how to create your own mobile project. Then, you will add the prewritten game logic of a small Arkanoid-like game called "Mopoid". This provides an interesting place to get to know important parts of development for Symbian OS, including the following: * Preparation: Setup of the tools and SDK * Creating a new project * Testing the project * Defining the menu * Displaying the about box * Getting the application to the mobile phone! * Adding the game engine to your project * Loading images (.svg vector graphics) * Scaling and displaying the graphics * Handling keys * Displaying text * Reading and writing files * Setting the application icon * Handling being in the background * Periodic events * ExercisesYou will see the results of your actions right away. Whenever a speciality of Symbian OS comes into sight (like memory handling), a short explanation will give you a brief overview of why it is this way and how to work with it.Of course, during this tutorial, we will only scratch the surface of all those topics, as each of them would easily fill an own tutorial of this size. But this tutorial will give you a basic understanding of how development for mobile phones using C++ works, and is a good starting point for your own projects.The original version of this tutorial has been released in December 2004 and was based on S60 1.x. In January 2009, the updated version for Symbian OS 9 / S60 3.x+ was released. The tutorial has been rewritten, the slides created from scratch, the game updated and greatly extended. Choose the version that fits to your target platform - most likely, this is going to be the new version. It's recommended to use both the tutorial document and the slides when working through the tutorial on your own.
Popular Tags:
176
mopoid Symbian OS Workshop 1 Andreas Jakl, 2009 v2.4.1 19 April 2009
Transcript
Page 1: Symbian OS - Mopoid Next Gen - Slides

mopoid

Symbian OS Workshop

1 Andreas Jakl, 2009 v2.4.1 – 19 April 2009

Page 2: Symbian OS - Mopoid Next Gen - Slides

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 [email protected]

● 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.

Andreas Jakl, 20092

Page 3: Symbian OS - Mopoid Next Gen - Slides

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

Page 4: Symbian OS - Mopoid Next Gen - Slides

Schedule

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

Andreas Jakl, 20094

Page 5: Symbian OS - Mopoid Next Gen - Slides

Mopoid

● Tasks

Create your own application using the UI designer

Define a menu and an about box

Leaves, Panics and Cleanup Stack

Project structure, libraries

Class types, naming conventions

Defining and displaying text, fonts, descriptors

Using vector graphics

Scalable UI

Asynchronous events, timers

Key handling

Files, data caging (platform security)

Foreground / background

Dynamic menuAndreas Jakl, 20095

Page 6: Symbian OS - Mopoid Next Gen - Slides

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

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

Andreas Jakl, 20096

// TODO: Refresh back light timer

Page 7: Symbian OS - Mopoid Next Gen - Slides

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)

Andreas Jakl, 20097

Page 8: Symbian OS - Mopoid Next Gen - Slides

Carbide.c++

Andreas Jakl, 20098

Page 9: Symbian OS - Mopoid Next Gen - Slides

S60 SDKs

● Choose SDK depending on required compatibility and features

● Binary compatibility break with Symbian OS 9

● www.forum.nokia.com

Andreas Jakl, 2009

SDK OS version Devices

1st Ed. v6.0 7650

1st Ed, FP 1 v6.1 N-Gage, SX1, 3650, Sendo-X, …

2nd Ed v7.0s 6600, …

2nd Ed, FP 1 v7.0s 7610, 6670, 6260, …

2nd Ed, FP 2 v8.0 6630, 6680, 6681, …

2nd Ed, FP 3 v8.1 N70, N90, …

3rd Ed v9.1 E61, N73, N75, …

3rd Ed, FP 1 v9.2 N95, E90, …

3rd Ed, FP 2 v9.3 N96, N78, …

5th Ed v9.4 5800, N97, …

5th Ed, FP1 v9.5? ?

Commonly used for maximum compatibility

9

Introduces touch screens to S60

Page 10: Symbian OS - Mopoid Next Gen - Slides

Installation

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

2. Perl 5.6.x (Set the path variable!) – not 5.8 / 5.10!http://downloads.activestate.com/ActivePerl/Windows/5.6/ActivePerl-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/

Andreas Jakl, 200910

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

Page 11: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 200911

Page 12: Symbian OS - Mopoid Next Gen - Slides

Workspace

● Workspace location:

Has to be on the same drive as the SDK ( C:\)

Must not contain space characters

Example: C:\Symbian\dev

Andreas Jakl, 200912

Page 13: Symbian OS - Mopoid Next Gen - Slides

Create new project

● File New C++ Application for S60 Project

Andreas Jakl, 200913

Page 14: Symbian OS - Mopoid Next Gen - Slides

Create new project

● Call it: Mopoid

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

Andreas Jakl, 200914

Page 15: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200915

Page 16: Symbian OS - Mopoid Next Gen - Slides

Choose UI-Design

● Select the empty design

We’ll do low level graphics on an empty canvas

Andreas Jakl, 200916

Page 17: Symbian OS - Mopoid Next Gen - Slides

Application UID (UID3)

● Development for v9: 0xE0000000 - 0xEFFFFFFF

Development UID automatically assigned by Carbide

● Get UIDs for public applications:

Different range for signed / unsigned

Get one for free at: http://www.symbiansigned.com/

Andreas Jakl, 200917

Range Purpose

0x00000000 – 0x0FFFFFFF Development use (< v9)

0x10000000 – 0x1FFFFFFF Legacy UID (pre-v9)

0x20000000 – 0x2FFFFFFF v9 protected UIDs

0xA0000000 – 0xAFFFFFFF v9 unprotected UIDs

0xE0000000 – 0xEFFFFFFF Development use (v9)

0xF0000000 – 0xFFFFFFFF Legacy UID (pre-v9)

Page 18: Symbian OS - Mopoid Next Gen - Slides

Our Project

Andreas Jakl, 200918

Page 19: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200919

Page 20: Symbian OS - Mopoid Next Gen - Slides

S60 UI

● Status Pane

Information about running application & device (e.g. battery strength)

● Main Pane

Application content

● Control Pane

Softkey labels

Andreas Jakl, 200920

Status Pane

Main Pane

Control Pane

Page 21: Symbian OS - Mopoid Next Gen - Slides

CompileFirst tests

Andreas Jakl, 200921

Page 22: Symbian OS - Mopoid Next Gen - Slides

Choose Build Target

● Active Build Configuration Emulator

Andreas Jakl, 200922

Page 23: Symbian OS - Mopoid Next Gen - Slides

Compile Project

● (optional) Project Build Project

● Run Run

● Or:

Andreas Jakl, 200923

You can only use the mouse to navigate on the screen on touch-enabled

emulators! Otherwise, use the buttons below.

Page 24: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200924

Page 25: Symbian OS - Mopoid Next Gen - Slides

Possible Problems

● Compilation error:

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

Andreas Jakl, 200925

***Generating makefiles.bldmake.bat bldfiles WINSCW UDEB WARNING: EPOCROOT does not specify an existing directoryBLDMAKE ERROR: Directory "\Symbian\9.1\S60_3rd_MR\EPOC32\" 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

Page 26: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200926

Page 27: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200927

Page 28: Symbian OS - Mopoid Next Gen - Slides

.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”

Andreas Jakl, 200928

Page 29: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200929

Page 30: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200930

Window Preferences... General Workspace Build automaticallyor: Project Build automatically

Page 31: Symbian OS - Mopoid Next Gen - Slides

Application structure

Application class

● Entry point for OS

● Defines application UID

● Creates Document class

● Normally no changesrequired here.

Andreas Jakl, 200931

Page 32: Symbian OS - Mopoid Next Gen - Slides

Application structure (2)

Document class

● Takes care of data model

● Creates Application UI (AppUI-class)

● Usually no changes requiredin this class either.

Andreas Jakl, 200932

Page 33: Symbian OS - Mopoid Next Gen - Slides

Application structure (3)

AppUI class

● “Controller” of the app.

● Not visible itself

● Manages views (container)

● General, application-wide event handling (exit, pause, ...)

Andreas Jakl, 200933

Page 34: Symbian OS - Mopoid Next Gen - Slides

Application structure (4)

View class

● Manages title- and statuspane

● Command handling(for this view)

Andreas Jakl, 200934

Page 35: Symbian OS - Mopoid Next Gen - Slides

Application structure (5)

Container class

● Handling of UI components

● Manages “what is visible” in the main pane (= main part of the screen)

Andreas Jakl, 200935

Page 36: Symbian OS - Mopoid Next Gen - Slides

Cone

Uikon

Avkon

AppArc

App Startup (S60 Views)

Andreas Jakl, 200936

CMyApplication CMyDocument CMyAppUi CMyView1 CMyContainer1

CAknApplication CAknDocument

CAknViewAppUi

CAknViewCAknAppUi

CAknAppUiBase

CEikAppUiCEikDocumentCEikApplication

CCoeAppUiCApaDocumentCApaApplication CCoeControl

CreateDocumentL() CreateAppUiL() ConstructL() DoActivateL()RunApplication

Avkon View Switching Application

Page 37: Symbian OS - Mopoid Next Gen - Slides

Menu, About Boxes and LeavesUI-Design

Andreas Jakl, 200937

Page 38: Symbian OS - Mopoid Next Gen - Slides

Menu Definition

● Open the UI design (MopoidContainer.uidesign)

● Create 3 menu items:

Start new game

About

Exit

Andreas Jakl, 200938

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

Page 39: Symbian OS - Mopoid Next Gen - Slides

Exit Command

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

Andreas Jakl, 200939

Optional: Change the title

Page 40: Symbian OS - Mopoid Next Gen - Slides

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”

Andreas Jakl, 200940

Page 41: Symbian OS - Mopoid Next Gen - Slides

Connection: Menu Dialog

● Open the options menu

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

Andreas Jakl, 200941

Page 42: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200942

TBool CMopoidContainerView::HandleAboutMenuItemSelectedL( TInt aCommand )

{

RunNoteAboutL();

return ETrue;

}

Page 43: Symbian OS - Mopoid Next Gen - Slides

Result

Andreas Jakl, 200943

Page 44: Symbian OS - Mopoid Next Gen - Slides

Exceptions – Java

● Try & Catch for handling exceptions

● Functions can throw “Exceptions”

Andreas Jakl, 200944

Calling function

Try {

int x = Integer.parseInt(“1234”);

} catch (NumberFormatException e) {

System.out.println(“Unable to convert this String to a number.”);

}

Integer Class

static int parseInt throwsNumberFormatException {

}

Page 45: Symbian OS - Mopoid Next Gen - Slides

Leave – Symbian

● TRAP(D) catches exceptions (“Leave”)

● Functions send out leave

● Function name marked by an L-suffix

Andreas Jakl, 200945

Main-Function

TRAPD(err, DoExampleL());if (err)

{console->Printf(KTxtFailed, err);}

DoExampleL()-Function

void DoExampleL(){

RFs fsSession; // Connect to the file server

User::LeaveIfError(fsSession.Connect()); // …fsSession.Close();}

TRAPD-Makro declares err as TInt and =

KErrNoneLeaves if the Connect()

function does not return KErrNone

The TRAP(D) macros are defined in e32cmn.h

Page 46: Symbian OS - Mopoid Next Gen - Slides

Central Exception Handling

Andreas Jakl, 200946

TRAPD(err, F2L());if (err) …

New (ELeave) …… NewL() …

… User::Leave() …… ConstructL() …

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

… F3L() …F4L() …

Page 47: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200947

Page 48: Symbian OS - Mopoid Next Gen - Slides

Andreas Jakl, 200948

S60 Framework(traps the leave

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;

}

void CMopoidContainerView::RunNoteAboutL( const TDesC* aOverrideText )

{

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 );

}

}

No memory left toallocate the object

Leave is passed on until a TRAP statement is reached

Page 49: Symbian OS - Mopoid Next Gen - Slides

Game EngineAdd the pre-implemented framework to your project

Andreas Jakl, 200949

Page 50: Symbian OS - Mopoid Next Gen - Slides

Extraction and Sources

1. Close Carbide.c++

2. Unzip Mopoid.Update.zip to c:\Symbian\dev\

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

Andreas Jakl, 200950

Page 51: Symbian OS - Mopoid Next Gen - Slides

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.

Andreas Jakl, 200951

Page 52: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200952

Page 53: Symbian OS - Mopoid Next Gen - Slides

Localization – Overview

Andreas Jakl, 200953

<AppName>.r03German compiled

resource file

<AppName>.r02French compiled

resource file

<AppName>.r01UK English compiled

resource file

Resource Compiler

<AppName>.rssStrings replaced with

#defines from currently active .lxx

<AppName>.locInclude currently active

language#ifdef LANGUAGE_01...

<AppName>.l01UK English

#define STR_hi “Hello”

<AppName>.l02French

#define STR_hi “Salut”

<AppName>.l03German

#define STR_hi “Hallo”

If using .rls-files instead of .loc, use rls_string instead of #define

Page 54: Symbian OS - Mopoid Next Gen - Slides

String Resources

● Define text in one place – and not in the source code

● Easy to modify, easy to localize

Andreas Jakl, 200954

<AppName>.l01 / .rls ... (Text only!)#define STR_Loading “Loading...”#define STR_Caption “Hello World”

<AppName>.rss (UI Definition)#include “<AppName>.l01”RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info{

short_caption = STR_Caption; }RESOURCE TBUF r_loading { buf = STR_Loading; }[...]

<Program>.cpp (C++ Source Code)#include <stringloader.h>#include <<AppName>.rsg>

void C<AppName>AppUi::DisplayInfo(){

HBufC* buf = StringLoader::LoadLC ( R_LOADING );[...]CleanupStack::PopAndDestroy(buf);

}

<AppName>.rsg (Generated by resource compiler)#define R_LOCALISABLE_APP_INFO 0x66a61005#define R_LOADING 0x66a61006

Page 55: Symbian OS - Mopoid Next Gen - Slides

Additional Game Text

● Define strings like explained on the previous slide

MopoidContainer.l01 / MopoidContainer.rssi

Andreas Jakl, 200955

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

Add an additional space char after

the “:”

Page 56: Symbian OS - Mopoid Next Gen - Slides

New Game

● In the UI designer, create a new event handler for the “Start new game” menu item

Andreas Jakl, 200956

if (iMopoidContainer->iGameEngine)

iMopoidContainer->iGameEngine->StartNewGameL();

CMopoidContainerView::HandleStart_new_gameMenuItemSelectedL()

Page 57: Symbian OS - Mopoid Next Gen - Slides

Graphics

● Today’s phones: screen orientation / size changes

● Mopoid uses vector graphics

● S60: support for SVG-T

Andreas Jakl, 200957

Page 58: Symbian OS - Mopoid Next Gen - Slides

Adding Game Graphics

● Add a multi image file (.mif) to the icons-makefile: \group\Icons_aif_scalable_dc.mk

● Target directory: resource\apps\MopoidGraphics.mif

● Header generation: Header

● Header file:epoc32\include\MopoidGraphics.mbg

Andreas Jakl, 200958

Page 59: Symbian OS - Mopoid Next Gen - Slides

Adding Game Graphics

● Choose images: bricks, panel and ball

● Set the mask depth for the bricks to n/a

Andreas Jakl, 200959

Page 60: Symbian OS - Mopoid Next Gen - Slides

Copying Data to the Emulator

● C:\-drive of the phone is emulated in

<EPOCROOT>\winscw\c

e.g.: C:\Symbian\9.1\S60_3rd_MR\Epoc32\winscw\c

● Additional game resources required during runtime: sounds and level definition file

1. Open Mopoid.mmp and write down the UID3

Andreas Jakl, 200960

Page 61: Symbian OS - Mopoid Next Gen - Slides

Copying Data to the Emulator

● Open \group\bld.inf

Lists which project definition & make files belong to the project and which files to export

● Export the files to the private directory

Andreas Jakl, 200961

The makefile will automatically create

the .mif-file in the right dir

Page 62: Symbian OS - Mopoid Next Gen - Slides

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: “/” “\”

Andreas Jakl, 200962

Page 63: Symbian OS - Mopoid Next Gen - Slides

Phone Release

● Copy additional data files to the phone

● Contents of the SIS-file defined in \sis\Mopoid.pkg

Andreas Jakl, 200963

; The icon-file

"$(EPOCROOT)epoc32\data\z\resource\apps\MopoidGraphics.mif"

-"!:\resource\apps\MopoidGraphics.mif"

; Sound files

"..\gfx\hit.wav"

-"!:\private\E2C4F75B\hit.wav"

"..\gfx\bounce.wav"

-"!:\private\E2C4F75B\bounce.wav“

; Levels definition file

"..\gfx\levels.dat"

-"!:\private\E2C4F75B\levels.dat"

; Required for the application to be covered by backup/restore facility

"..\sis\backup_registration.xml" -"!:\private\E2C4F75B\backup_registration.xml"

Adapt the UID to your own!

Mopoid.pkg

Page 64: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200964

Page 65: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200965

Page 66: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200966

Page 67: Symbian OS - Mopoid Next Gen - Slides

Background Info: Build Toolchain

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

Andreas Jakl, 200967

bld.inf

project.mmp

> bldmake bldfiles

> abld build wins udeb

Intermediate build files in\epoc32\build\<projectdir>

abld.bat in <projectdir>

Intermediate files in \epoc32\build\<projectdir>

Binary files in\eopc32\release\winscw\udeb\

Input files in <projectdir> Command Outputs

Page 68: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200968

Page 69: Symbian OS - Mopoid Next Gen - Slides

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)

Andreas Jakl, 200969

Page 70: Symbian OS - Mopoid Next Gen - Slides

Loading ImagesGetting the images out of the .mif-file

Andreas Jakl, 200970

Page 71: Symbian OS - Mopoid Next Gen - Slides

Class Types

● CSpriteHandler loads, scales and provides images

Andreas Jakl, 200971

SVG-Images

.mif-File

Load image (CAknIconUtils)

Set vector image size in

pixels

Draw the image

Why the “C”?

Page 72: Symbian OS - Mopoid Next Gen - Slides

Fundamental Types

● Defined in <SDK-path>\epoc32\include\e32def.h

Andreas Jakl, 200972

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

Page 73: Symbian OS - Mopoid Next Gen - Slides

Examples

Andreas Jakl, 200973

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: TBool

// Symbian OS uses ‘void’ for ‘nothing’ and ‘TAny*’ for ‘pointer to anyting’void Foo(); // Returns no resultTAny* p; // Pointer to anything

Example: void / TAny*

TInt x = 5;TReal y = (TReal)x + 0.5;

Example: TInt, TReal

Page 74: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200974

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 75: Symbian OS - Mopoid Next Gen - Slides

T Classes – Example

Andreas Jakl, 200975

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:/** The x coordinate. */TInt iX;/** The y coordinate. */TInt iY;};

TPoint definition from e32cmn.h

void CMyControl::Draw(const TRect &aRect) const

{CWindowGc& gc = SystemGc ();gc.DrawLine (TPoint (0, 0), iLastPoint);}

Usage example

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 76: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200976

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 77: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200977

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 78: Symbian OS - Mopoid Next Gen - Slides

C Classes – Example

Andreas Jakl, 200978

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: // ConstructorsCSprite( TInt aXVelocity, /* ... */, CFbsBitmap* aImage, CFbsBitmap* aMask);void ConstructL();

private: // DataTPoint iPosition;const CFbsBitmap * const iImage;const CFbsBitmap * const iMask;

};

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 79: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 200979

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 80: Symbian OS - Mopoid Next Gen - Slides

R Classes – Example

Andreas Jakl, 200980

void CMyClass::SendCachedDataL(){RSocketServ socketServer;

// Connect to the SocketServerUser::LeaveIfError( socketServer.Connect() );// Make sure Close() is called at the endCleanupClosePushL( socketServer );

// …

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

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 81: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200981

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 82: Symbian OS - Mopoid Next Gen - Slides

M Classes – Example

Andreas Jakl, 200982

// Interface definitionclass MMdaAudioPlayerCallback

{public:

virtual void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration) = 0;

virtual void MapcPlayComplete(TInt aError) = 0;};

// Implementing classclass CSoundPlayer : public CBase, public MMdaAudioPlayerCallback

{// [...]

protected: // Functions from base classesvoid MapcInitComplete( TInt aError, const TTimeIntervalMicroSeconds& aDuration );void MapcPlayComplete( TInt aError );// [...]}

The CBase-derivation always has to be first!

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 83: Symbian OS - Mopoid Next Gen - Slides

Static Classes

● Static classes provide utility code

● Can not be instantiated

● No prefix letter

Andreas Jakl, 200983

TInt computerMoveX = Math::Rand(iSeed) % iGridSize.iWidth;User::After(1000); // Suspends the current thread for 1000 microsecondsMem::FillZ(&targetData, 12); // Zero-fills 12-byte block starting from &targetData

Examples

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 84: Symbian OS - Mopoid Next Gen - Slides

Summary – Classes

Andreas Jakl, 200984

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, RWriteStream, RWindow

Owns resources other than on the default heap. Usually allocated as members or automatic variables. Usually require Close() to free resources.

M Mixin, interface

MGraphicsDeviceMap, MEikMenuObserver

Interface consisting of virtual functions. Implementation derives from it. Only approved use of multiple inheritance.

Static class

User, Math, Mem Consists purely of static functions, cannot be instantiated into an object.

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 85: Symbian OS - Mopoid Next Gen - Slides

When to use which class type?

Andreas Jakl, 200985

Class contains no member data

Class contains only static functions (or factory classes)

Member data has no destructor / does not need special cleanup

Size of the data contained by the class will be large (> 512 bytes)

Class owns data that needs cleanup

Usually an interface M classSometimes C class

Static class no prefix

Only contains native types (T classes) or

“uses-a” data T class

Stack is limited avoid T class typically a C class

Usually a C class. Also R-classes, which are seldom implemented yourself

Page 86: Symbian OS - Mopoid Next Gen - Slides

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;

Andreas Jakl, 200986

Why the “i”?

Page 87: Symbian OS - Mopoid Next Gen - Slides

Variable Naming Conventions

Andreas Jakl, 200987

Prefix Category Examples Description

E Enumerated constant

EMonday, ESolidBrush Values in an enumeration – which itself should have T prefix: EMonday is a member of TDayOfWeek

K Constant KMaxFileName, KRgbWhite

Constants from #define or const TInt.

i Member variable

iDevice, iX Any non-static member variable. i refers to ‘instance’

a Argument aDevice, aX Function argument. Stands for ‘argument’ aOrigin, not anOrigin!

Automaticvariable

device, x Automatic: variable that is created automatically when required and destroyed when out of scope

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 88: Symbian OS - Mopoid Next Gen - Slides

Example – Variables

Andreas Jakl, 200988

enum TStuffState // Declares an enumeration, prefix T{EInitialized = 0, // Individual elements with prefix EEError};

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 iTStuffState iState;};

void TStuff::DoStuff(TInt aLength){if (aLength > KMaxLength)

iState = EError;else

iLength = aLength; // Note: no ambiguities!}

Variables | T Classes | C Classes | R Classes | M Classes | Static Classes

Page 89: Symbian OS - Mopoid Next Gen - Slides

Fixed Arrays

● Standard C++ Array:

TInt myArray[25];

● The same using Symbian OS wrapper class:

TFixedArray<TInt, 25> myArray;

Andreas Jakl, 200989

[0]

myArray

[1] … [24]

25x TInt

<ptr>

Page 90: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200990

Page 91: Symbian OS - Mopoid Next Gen - Slides

Loading Images

● Create bitmap from specified ID in .mif-file

● 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

Andreas Jakl, 200991

iSprites[ESpritePanel] = AknIconUtils::CreateIconL(

fileName, EMbmMopoidgraphicsPanel);

CSpriteHandler::ConstructL()

Page 92: Symbian OS - Mopoid Next Gen - Slides

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)

Andreas Jakl, 200992

AknIconUtils::CreateIconL(iSprites[ESpritePanel], iSprites[ESpritePanelM],

fileName, EMbmMopoidgraphicsPanel,

EMbmMopoidgraphicsPanel_mask);

CSpriteHandler::ConstructL()

Page 93: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 200993

Defined in MopoidSharedData.h

Page 94: Symbian OS - Mopoid Next Gen - Slides

Setting the Image Size

● Dynamically set by the game engine – according to screen resolution

● Handled in:

● Set image size:

Andreas Jakl, 200994

void CSpriteHandler::DoSetSpriteSize(

const MopoidShared::TSpriteIds aSpriteId,

const TSize& aNewSize)

AknIconUtils::SetSize(iSprites[aSpriteId], aNewSize);

CSpriteHandler::DoSetSpriteSize()

Page 95: Symbian OS - Mopoid Next Gen - Slides

Memory Leaks

● Test it:

Launch Mopoid in the emulator

Close the app in the emulator (not the emulator itself!)

Andreas Jakl, 200995

Page 96: Symbian OS - Mopoid Next Gen - Slides

Deleting Images

● Images owned by sprite handler Delete pointers in the destructor

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

Andreas Jakl, 200996

iSprites.DeleteAll();

CSpriteHandler::~CSpriteHandler()

Page 97: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 200997

// Stray signal detected!_LIT(KMsgStraySignal, "Stray signal\n");User::Panic(KMsgStraySignal, 1); // Panic with code 1

Page 98: Symbian OS - Mopoid Next Gen - Slides

Panics

● Try it – add a serious error

● Range checked by TFixedArray (in debug builds)

Andreas Jakl, 200998

iSprites[999] = AknIconUtils::CreateIconL(

fileName, EMbmMopoidgraphicsPanel);

CSpriteHandler::ConstructL()

Page 99: Symbian OS - Mopoid Next Gen - Slides

Information about Panics

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

Andreas Jakl, 200999Tip: install the automated panic lookup plug-in for Carbide.c++:http://www.symbianresources.com/projects/paniclookup.php

Page 100: Symbian OS - Mopoid Next Gen - Slides

Scalable UIAdapting to different screen layouts

Andreas Jakl, 2009100

Page 101: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009101

Page 102: Symbian OS - Mopoid Next Gen - Slides

Scalable UI in Mopoid – Overview

Andreas Jakl, 2009102

Container (CMopoidContainer)

Container Base Class (CCoeControl)

Game Engine (CMopoidGameEngine)

HandleResourceChange()

HandleResourceChange() SetExtentToWholeScreen()

SizeChanged()

SizeChanged()

SetScreenSize()

Framework

Page 103: Symbian OS - Mopoid Next Gen - Slides

Scalable UI – Source Code

● Upon start-up and subsequent orientation / resolution changes, the framework calls HandleResourceChange() of all visible container classes

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

Andreas Jakl, 2009103

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()

}

CMopoidContainer::HandleResourceChange(TInt aType)

Page 104: Symbian OS - Mopoid Next Gen - Slides

Scalable UI – Source Code

● In CMopoidContainer::SizeChanged()

Query the current resolution

Inform the game engine

Andreas Jakl, 2009104

iGameEngine->SetScreenSize(this->Size());

CMopoidContainer::SizeChanged()

Page 105: Symbian OS - Mopoid Next Gen - Slides

Displaying GraphicsFinally get some content on the screen

Andreas Jakl, 2009105

Page 106: Symbian OS - Mopoid Next Gen - Slides

Back Buffer

Back Buffer

Screen

Transferredas a whole

when drawingis finished

106 Andreas Jakl, 2009

Page 107: Symbian OS - Mopoid Next Gen - Slides

CMopoidGameEngine

CMopoidContainer

Game Loop

(static) TimerCallBack()

CPeriodic

DoFrame()

Calculate time difference

Animate thepanel

Draw the frameto the back

buffer

Request a redraw event

Copy the back buffer to the

screen

Asynch. call

107 Andreas Jakl, 2009

Page 108: Symbian OS - Mopoid Next Gen - Slides

DrawFrame()

● First: clear the back buffer

Andreas Jakl, 2009108

// 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

Brush

ENullPen

ESolidBrush, KRgbBlack

CMopoidGameEngine::DrawFrame()

Page 109: Symbian OS - Mopoid Next Gen - Slides

Drawing Bricks (w/o transparency)

● Bricks are drawn in the for-loop

● 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

Andreas Jakl, 2009109

iBackBufferBmpGc->BitBlt(ConvToScreenCoord(

iGrid->ConvertGridToXY(x, y)),

iSpriteHandler->GetSprite(spriteId));

CMopoidGameEngine::DrawFrame()

Page 110: Symbian OS - Mopoid Next Gen - Slides

Drawing Panel and Ball (with transp.)

● Ball sprite

● Do the same for the panel near the end of the method

Position: iPanel.iPos

Bitmap IDs: ESpritePanel / ESpritePanelM

Andreas Jakl, 2009110

iBackBufferBmpGc->BitBltMasked(ConvToScreenCoord(ballSpritePos),

iSpriteHandler->GetSprite(MopoidShared::ESpriteBall),

iSpriteHandler->GetSprite(MopoidShared::ESpriteBall)->SizeInPixels(),

iSpriteHandler->GetSprite(MopoidShared::ESpriteBallM), EFalse);

CMopoidGameEngine::DrawFrame()

Page 111: Symbian OS - Mopoid Next Gen - Slides

Screen Flickering

● Note: UI Designer clears the screen with white before the bitmap is copied results in flickering on some devices

● Changes will get overwritten whenever you change the design

Andreas Jakl, 2009111

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]

Page 112: Symbian OS - Mopoid Next Gen - Slides

White Border around Sprites

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

Andreas Jakl, 2009112

Page 113: Symbian OS - Mopoid Next Gen - Slides

Periodic EventsKeeping the game loop alive

Andreas Jakl, 2009113

Page 114: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 2009114

Page 115: Symbian OS - Mopoid Next Gen - Slides

Event Handling

Andreas Jakl, 2009115

Event 1 Event 2 Event 3

Application (Possibly an extra thread)

Event 1 Event 2 Event 3

Application (thread)

Active Scheduler (in app. thread)

Traditional Event-Handling Active Objects(Symbian OS)

Event Handler(Thread)

Event Handler(Thread)

Event Handler(Thread) Event

Handler(AO)

Event Handler

(AO)

Event Handler

(AO)

Asynchronous Service Providers

Asynchronous Service Providers

Page 116: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009116

Page 117: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 2009117

CPeriodic* iPeriodicTimer;

MopoidGameEngine.h

Page 118: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009118

const TTimeIntervalMicroSeconds32 KTickInterval = 5000;

CMopoidGameEngine::StartTimerL()

Page 119: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 2009119

if (!iPeriodicTimer)

{

iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityStandard);

}

CMopoidGameEngine::StartTimerL()

Page 120: Symbian OS - Mopoid Next Gen - Slides

Starting the Timer

● 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

Andreas Jakl, 2009120

iPeriodicTimer->Start(KTickInterval, KTickInterval,

TCallBack(TimerCallBack, this));

CMopoidGameEngine::StartTimerL()

static TInt TimerCallBack(TAny* aObject);

MopoidGameEngine.h (already declared, just for reference)

Page 121: Symbian OS - Mopoid Next Gen - Slides

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

● Call-backs might not be regular

Call-back of a different active object is running orhigher priority call-backs waiting

DoFrame() checks time difference from last frame

Andreas Jakl, 2009121

TInt CMopoidGameEngine::TimerCallBack(TAny* aObject)

{

// Call non-static method

return ((CMopoidGameEngine*)aObject)->DoFrame();

}

Page 122: Symbian OS - Mopoid Next Gen - Slides

Stopping the Timer

● Cancel the timer

● Delete the instance (recommended by the SDK doc)

Andreas Jakl, 2009122

void CMopoidGameEngine::StopTimer()

{

// If the timer object exists: stop and delete it.

if (iPeriodicTimer)

{

iPeriodicTimer->Cancel();

delete iPeriodicTimer;

iPeriodicTimer = NULL;

}

}

Page 123: Symbian OS - Mopoid Next Gen - Slides

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:

Andreas Jakl, 2009123

User::ResetInactivityTime();

CMopoidGameEngine::DoFrame()

Page 124: Symbian OS - Mopoid Next Gen - Slides

Handling KeysLet’s start to play!

Andreas Jakl, 2009124

Page 125: Symbian OS - Mopoid Next Gen - Slides

Control Stack

● Symbian OS maintains an internal control stack

● All controls that should receive key events are put on the stack

● Starting at stack pos. 0, events are offered to each control until they are consumed by a control

Andreas Jakl, 2009125

ECoeStackPriorityDefault (=0)

ECoeStackPriorityMenu (=10)

ECoeStackPriorityDialog (=50)

ECoeStackPriorityDialog (=50)

Even

ts

Control X

Control YKeyboard Focus

Control Z

Controls put on the stack in the order: A, B, C, D

Stack position 0

AppUi()->AddToStackL( *this, iMopoidContainer );

CMopoidContainerView::DoActivateL()

Page 126: Symbian OS - Mopoid Next Gen - Slides

Was the key event handled by us?

● Controls are offered key events in:

● Return value depending on if the event was handled:

Andreas Jakl, 2009126

TKeyResponse CMopoidContainer::OfferKeyEventL(

const TKeyEvent& aKeyEvent, TEventCode aType)

Return(TKeyResponse)

EKeyWasConsumed: We used the key event, do not send it toother controls

EKeyWasNotConsumed: This key event was not interestingfor us, send it to other controls

Page 127: Symbian OS - Mopoid Next Gen - Slides

Keys

Andreas Jakl, 2009127

● Type of event sent in aType parameter

● 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!

EEventKeyDown EEventKey EEventKeyUp

Page 128: Symbian OS - Mopoid Next Gen - Slides

Displaying TextKeep the user informed

Andreas Jakl, 2009128

Page 129: Symbian OS - Mopoid Next Gen - Slides

Fonts

● Games use low level methods to draw text

Highly sophisticated games usually their own bitmap font

● Retrieving a standard system font

● Apply the font to the context

Andreas Jakl, 2009129

iFontUsed = (CFont*) AknLayoutUtils::LayoutFontFromId(

EAknLogicalFontPrimarySmallFont);

iFontHeight = iFontUsed->AscentInPixels();

CMopoidSettings::ConstructL()

iBackBufferBmpGc->UseFont(iSettings->iFontUsed);

CMopoidGameEngine::DrawTextL()

Page 130: Symbian OS - Mopoid Next Gen - Slides

Font Colour

● Setup for drawing text (in red colour)

Brush was already set to a null brush before

Andreas Jakl, 2009130

ENullBrush

ESolidPen, KRgbRed

text

iBackBufferBmpGc->SetPenStyle(CGraphicsContext::ESolidPen);

iBackBufferBmpGc->SetPenColor(KRgbRed);

TBuf<30> tempStr;

CMopoidGameEngine::DrawTextL()

Pen

Brushtext

Page 131: Symbian OS - Mopoid Next Gen - Slides

Buffer Descriptors

● Comparable to (const) char[] of C

● Directly contain the string

● Use C++ templates to specify length (parameter)

Andreas Jakl, 2009131

TBufC<5>

TBuf<9>

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

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

iLength(TDesC)

iMaxLength(TDes)

iLength(TDesC)

Constant:

Modifiable:

Page 132: Symbian OS - Mopoid Next Gen - Slides

Size, Length, MaxLength

● TBuf<9> with text “Hello”

Andreas Jakl, 2009132

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

Length() 5 (characters)MaxLength() 9 (characters)Size() 10 (bytes)MaxSize() 18 (bytes)

4 bytes 4 bytes 2 2 ...

Unicode characters!

Page 133: Symbian OS - Mopoid Next Gen - Slides

Initializing the TBuf

● Assigning Strings

Andreas Jakl, 2009133

// Define constant string literal_LIT(KString1, "Hello ");_LIT(KString2, "World");// Copy KString1 into new TBuf with max. length of 15TBuf<15> buf1(KString1);// Same as above, this time using Copy() and KString2TBuf<15> buf2; // Initialize empty TBuf with max. length of 15buf2.Copy(KString2);// Append contents of buf2 to buf1buf1.Append(buf2);// Create constant descriptor based on KString1TBufC<15> cBuf1(KString1);// Replace contents of cBuf1 with contents of buf1cBuf1 = buf1;

Page 134: Symbian OS - Mopoid Next Gen - Slides

Using the TBuf

Andreas Jakl, 2009134

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

Page 135: Symbian OS - Mopoid Next Gen - Slides

Using the TBuf

Andreas Jakl, 2009135

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

Page 136: Symbian OS - Mopoid Next Gen - Slides

Maximum Length

Andreas Jakl, 2009136

_LIT(KHello, "Hello "); // Defines constant string literalTBuf<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. […]”

Page 137: Symbian OS - Mopoid Next Gen - Slides

Inheritance Hierarchy

● Abstract base class because of:

Generalisation(use base type for parameters!)

Provide basic functions shared by all types (e.g. Compare(), Find(), Mid(), ...)

Andreas Jakl, 2009137

constant modifiable

Page 138: Symbian OS - Mopoid Next Gen - Slides

Reading Text from Resource Files

● Multiple options to read text from resource files

● Here: through environment from Symbian OS framework

● Read text from resource files into the descriptor

● (Remember: you declared the resource yourself!)

Andreas Jakl, 2009138

CEikonEnv* env = CEikonEnv::Static();

CMopoidGameEngine::DrawTextL()

env->ReadResourceL(tempStr, R_HIGHSCORE);

CMopoidGameEngine::DrawTextL()

RESOURCE TBUF r_highscore { buf = STR_highscore; }

MopoidContainer.rssi

Page 139: Symbian OS - Mopoid Next Gen - Slides

Formatting and Displaying Text

● tempStr now contains “High Score: ”

● Append the current score:

● Draw the text

x-coord: 5

y was calculated directly above

Andreas Jakl, 2009139

tempStr.AppendNum(iSettings->iHighScore);

CMopoidGameEngine::DrawTextL()

iBackBufferBmpGc->DrawText(tempStr,

TPoint(5, yTextStartBottom));

CMopoidGameEngine::DrawTextL()

Page 140: Symbian OS - Mopoid Next Gen - Slides

Current Score

● Like for the previous text:

Resource: R_SCORE

Number: iSettings->iScore

x-coordinate: 5

y-coordinate: one line above previous textyTextStartBottom - iSettings->iTextYOffset

Andreas Jakl, 2009140

Page 141: Symbian OS - Mopoid Next Gen - Slides

Aligning Text

● Print text on the right side of the screen

Andreas Jakl, 2009141

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

iBackBufferBmpGc->DrawText(tempStr, iSettings->iScreenRect,

yTextStartBottom,

CGraphicsContext::ERight, 3);

CMopoidGameEngine::DrawTextL()

Page 142: Symbian OS - Mopoid Next Gen - Slides

Final State

● Remove the comment from the code block ( activate the rest of the DrawTextL()-method)

● The final state:

Andreas Jakl, 2009142

Page 143: Symbian OS - Mopoid Next Gen - Slides

Reading / Writing FilesBe persistent

Andreas Jakl, 2009143

Page 144: Symbian OS - Mopoid Next Gen - Slides

Preparations

● Filename and version have already been declared

● We will use the CFileStore-class add the required include file (see SDK doc)

Andreas Jakl, 2009144

#define MOPOID_FILE_VERSION_NUMBER 1

_LIT(KMopoidDataFile, "settings.dat");

MopoidGameEngine.h

#include <s32file.h>

MopoidGameEngine.h

Page 145: Symbian OS - Mopoid Next Gen - Slides

Data Caging – Overview

Andreas Jakl, 2009145

Executable

• All binaries of all apps in onedir

• Can only be executed fromthere

• Usually: no read / write access

• \sys\bin\

Resources• Bitmaps, fonts, help files

• Usually: read-only

• \resource\

Private Data

• Each application its own dir

• Used for settings, ...

• Usually: read / write only forown private dir

• \private\<UID3>\

Page 146: Symbian OS - Mopoid Next Gen - Slides

Symbian OS 9.xSymbian OS, pre-V9

Data Caging

● App. only has access to:

Own directories

“Open” directories

● Access based on capabilities and identity

Andreas Jakl, 2009146

\System\Apps\Journey\Journey.app

\System\Apps\Journey\Journey.mbm

\System\Apps\Journey\Journey.rsc

\Sys\Bin\Journey.exe

\Resource\Apps\Journey.mbm

\Private\10003a3f\Journey.rsc

Separating code and data!

Page 147: Symbian OS - Mopoid Next Gen - Slides

Data Caging – Directories

Andreas Jakl, 2009147

Directory Capability(Read)

Capability(Write)

Used for

\sys AllFiles TCB Applications can only be executed from here.

\resource - TCB Fonts, bitmaps, help-files, … Only read-accessfor 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, …

Page 148: Symbian OS - Mopoid Next Gen - Slides

More about directories

● Data caging provides secure area for application’s data

● All executables installed to \sys\bin

Risk of filename clashes – use your unique UID as part of the executable filename

Removable drives:Hash stored to c:\sys\hashPrevents execution of modified executables

Andreas Jakl, 2009148

Page 149: Symbian OS - Mopoid Next Gen - Slides

Data Files

● Data file should be stored in our private directory:\private\<UID3>\settings.dat

● Dynamically add the path:

● Central part of this custom utility function:

Andreas Jakl, 2009149

NCommonFunctions::AddPrivateDirL(iFs,

KMopoidDataFile, fileName);

CMopoidGameEngine::SaveGameProgessL()

aFs.PrivatePath( aCompleteName );

NCommonFunctions::AddPrivateDirL()

Page 150: Symbian OS - Mopoid Next Gen - Slides

File Store

● Many ways to access files are possible (RFile, ...)

● Here: CFileStore – one of the most flexible

Encapsulates file-based, persistent stores

Stores multiple streams, each identified by an ID

Allows easy serialization of objects

Direct file store: doesn’t allow modifying data – not important for us, we will always replace the stream

Andreas Jakl, 2009150

CFileStore* store = CDirectFileStore::ReplaceLC(

iFs, fileName, EFileWrite);

store->SetTypeL(KDirectFileStoreLayoutUid);

CMopoidGameEngine::SaveGameProgessL()

Store (File)

Stream (ID)

Stream (ID)...

Page 151: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009151

RStoreWriteStream stream;

TStreamId id = stream.CreateLC(*store);

CMopoidGameEngine::SaveGameProgessL()

Page 152: Symbian OS - Mopoid Next Gen - Slides

Writing Data

● For now: file version and high score

● 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!

Andreas Jakl, 2009152

// Write file version number

stream.WriteInt32L(MOPOID_FILE_VERSION_NUMBER);

// Write highscore

stream.WriteInt32L(iSettings->iHighScore);

CMopoidGameEngine::SaveGameProgessL()

Page 153: Symbian OS - Mopoid Next Gen - Slides

Closing the File

● Make sure that all data is written and close everything

Andreas Jakl, 2009153

// 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);

CMopoidGameEngine::SaveGameProgessL()

Page 154: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 2009154

void CMyObj::DoSomethingL(){

}

CImage* img = new (ELeave) CImage();

img->DoSomethingDangerousL();

delete img;

void CImage::DoSomethingDangerousL(){User::Leave(KErrNotFound);}

CImage

img = pointer on the stack to an instance on the heap

Page 155: Symbian OS - Mopoid Next Gen - Slides

Cleanup Stack

● Memory situation if a leave occurs:

Andreas Jakl, 2009155

img

Stack Heap

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

memory leak

Page 156: Symbian OS - Mopoid Next Gen - Slides

Cleanup Stack

● Solution: Cleanup Stack

Andreas Jakl, 2009156

img

Stack Heap

img

CleanupStack

Cleanup stack saves a second pointerto the object on the heap.

void CMyObj::DoSomethingL(){

CImage* img = new (ELeave) CImage();CleanupStack::PushL(img);img->DoSomethingDangerousL();CleanupStack::PopAndDestroy();

}

When no leave occurs: object still has to be deleted by you + removed from the cleanup stack!

Page 157: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009157

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);

CMopoidGameEngine::SaveGameProgessL()

Page 158: Symbian OS - Mopoid Next Gen - Slides

Loading

● Similar to saving files

1. Open the file store

2. Open the root stream (no ID is required for the root)

Andreas Jakl, 2009158

CFileStore* store = CDirectFileStore::OpenLC(

iFs, fileName, EFileRead);

CMopoidGameEngine::LoadGameProgessL()

RStoreReadStream stream;

stream.OpenLC(*store, store->Root());

CMopoidGameEngine::LoadGameProgessL()

Page 159: Symbian OS - Mopoid Next Gen - Slides

Reading Data

3. Read the data

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

Andreas Jakl, 2009159

TInt versionNumber = stream.ReadInt32L();

if (versionNumber != MOPOID_FILE_VERSION_NUMBER)

User::Leave(KErrNotFound);

iSettings->iHighScore = stream.ReadInt32L();

CMopoidGameEngine::LoadGameProgessL()

Page 160: Symbian OS - Mopoid Next Gen - Slides

If the File Was Not Found

● File not found-error (or wrong version)

Ignored

Settings-class initialized with default values

● All other errors (e.g., not enough disc space left)

TRAP’d leave is sent out again

Andreas Jakl, 2009160

// Load high score and settings

TRAPD(err, LoadGameProgressL());

if (err != KErrNone && err != KErrNotFound)

User::Leave(err);

CMopoidGameEngine::ConstructL()

Page 161: Symbian OS - Mopoid Next Gen - Slides

Cleanup

4. Close all handles

● 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

Andreas Jakl, 2009161

CleanupStack::PopAndDestroy(&stream);

CleanupStack::PopAndDestroy(store);

CMopoidGameEngine::LoadGameProgessL()

Page 162: Symbian OS - Mopoid Next Gen - Slides

Cleanup – Uninstallation

● Files that are to be removed during uninstallation: specified in the package file

● “FN” means “FileNull” – SDK help:

Andreas Jakl, 2009162

; --- Settings-file

""-"!:\private\E2C4F75B\settings.dat",FN

Mopoid.pkg

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.

Page 163: Symbian OS - Mopoid Next Gen - Slides

Application IconMake a good appearance in the phone menu:

Andreas Jakl, 2009163

Page 164: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009164

Page 165: Symbian OS - Mopoid Next Gen - Slides

Foreground / BackgroundIs anyone out there?

Andreas Jakl, 2009165

Page 166: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009166

Page 167: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009167

void HandleForegroundEventL(TBool aForeground);

MopoidContainerView.h

Page 168: Symbian OS - Mopoid Next Gen - Slides

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!

Andreas Jakl, 2009168

// 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);

}

MopoidContainerView.cpp

Page 169: Symbian OS - Mopoid Next Gen - Slides

Sound Volume / Dynamic MenusAdapting the Game to the Environment

Andreas Jakl, 2009169

Page 170: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009170

Page 171: Symbian OS - Mopoid Next Gen - Slides

(De) activating Sound

● Send the command to the game engine

● ... 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()

Andreas Jakl, 2009171

TBool CMopoidContainerView::HandleSound_OnMenuItemSelectedL( TInt aCommand )

{

if (iMopoidContainer && iMopoidContainer->iGameEngine)

{

iMopoidContainer->iGameEngine->SetSoundLevelL(ETrue);

}

return ETrue;

}

Page 172: Symbian OS - Mopoid Next Gen - Slides

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:

Andreas Jakl, 2009172

void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane);

MopoidContainerView.h

Page 173: Symbian OS - Mopoid Next Gen - Slides

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

Andreas Jakl, 2009173

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());

}

MopoidContainerView::DynInitMenuPaneL()

Page 174: Symbian OS - Mopoid Next Gen - Slides

SummaryWe’re finished!

Andreas Jakl, 2009174

Page 175: Symbian OS - Mopoid Next Gen - Slides

Mopoid

● Tasks

Create your own application using the UI designer

Define a menu and an about box

Leaves, Panics and Cleanup Stack

Project structure, libraries

Class types, naming conventions

Defining and displaying text, fonts, descriptors

Using vector graphics

Scalable UI

Asynchronous events, timers

Key handling

Files, data caging (platform security)

Foreground / background

Dynamic menuAndreas Jakl, 2009175

Page 176: Symbian OS - Mopoid Next Gen - Slides

Thanks for your attention!That’s it

Andreas Jakl, 2009176


Recommended