Symbian^3 port

This commit is contained in:
Shinovon 2026-04-29 05:15:13 +05:00
parent 77cdaaf97e
commit 3eb71f2cc5
106 changed files with 2098 additions and 745 deletions

View file

@ -26,35 +26,19 @@ void GetLocalTime_CP(SYSTEMTIME *out) {
// Compatible with Linux/POSIX and MinGW on Windows
#ifndef _WIN32
HANDLE FindFirstFile(const char* pathname, WIN32_FIND_DATA* firstfile) {
char pathCopy[MAX_PATH];
strcpy(pathCopy, pathname);
char newpathname[64];
snprintf(newpathname, sizeof(newpathname), "E:/data/gta3/%s", pathname);
char* path = strtok(newpathname, "\\*");
strncpy(firstfile->folder, path, sizeof(firstfile->folder));
char *folder = strtok(pathCopy, "*");
char *extension = strtok(NULL, "*");
// because I remember like strtok might not return NULL for last delimiter
if (extension && extension - folder == strlen(pathname))
extension = nil;
// Case-sensitivity and backslashes...
// Will be freed at the bottom
char *realFolder = casepath(folder);
if (realFolder) {
folder = realFolder;
}
strncpy(firstfile->folder, folder, sizeof(firstfile->folder));
if (extension)
strncpy(firstfile->extension, extension, sizeof(firstfile->extension));
// Both w/ extension and w/o extension is ok
if (strlen(path) + 2 != strlen(pathname))
strncpy(firstfile->extension, strtok(NULL, "\\*"), sizeof(firstfile->extension));
else
firstfile->extension[0] = '\0';
if (realFolder)
free(realFolder);
strncpy(firstfile->extension, "", sizeof(firstfile->extension));
HANDLE d;
if ((d = (HANDLE)opendir(firstfile->folder)) == NULL || !FindNextFile(d, firstfile))
if ((d = (HANDLE)opendir(path)) == NULL || !FindNextFile(d, firstfile))
return NULL;
return d;
@ -67,12 +51,11 @@ bool FindNextFile(HANDLE d, WIN32_FIND_DATA* finddata) {
int extensionLen = strlen(finddata->extension);
while ((file = readdir((DIR*)d)) != NULL) {
// We only want "DT_REG"ular Files, but reportedly some FS and OSes gives DT_UNKNOWN as type.
if ((file->d_type == DT_UNKNOWN || file->d_type == DT_REG || file->d_type == DT_LNK) &&
(extensionLen == 0 || strncasecmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) {
if ((extensionLen == 0 || strncmp(&file->d_name[strlen(file->d_name) - extensionLen], finddata->extension, extensionLen) == 0)) {
sprintf(relativepath, "%s/%s", finddata->folder, file->d_name);
realpath(relativepath, path);
// realpath(relativepath, path);
strcpy(path, relativepath);
stat(path, &fileStats);
strncpy(finddata->cFileName, file->d_name, sizeof(finddata->cFileName));
finddata->ftLastWriteTime = fileStats.st_mtime;
@ -182,115 +165,26 @@ int _caserename(const char *old_filename, const char *new_filename)
// Returned string should freed manually (if exists)
char* casepath(char const* path, bool checkPathFirst)
{
if (checkPathFirst && access(path, F_OK) != -1) {
// File path is correct
return nil;
}
size_t l = strlen(path);
char data_path[512];
getcwd(data_path, sizeof(data_path));
char* out = (char*)malloc(l + strlen(data_path) + 2);
size_t l = strlen(path);
char* p = (char*)alloca(l + 1);
char* out = (char*)malloc(l + 3); // for extra ./
strcpy(p, path);
if (strncmp(path, "E:", 2) == 0 || strncmp(path, "F:", 2) == 0) {
strcpy(out, path);
} else {
sprintf(out, "%s/%s", data_path, path);
}
// my addon: linux doesn't handle filenames with spaces at the end nicely
p = trim(p);
l = strlen(out);
for (int i = l-1; i >= 0; i--) {
if (out[i] == '\\' || out[i] == '/' || out[i] == ' ')
out[i] = '\0';
else
break;
}
size_t rl = 0;
DIR* d;
char* c;
#if defined(__SWITCH__) || defined(PSP2)
if( (c = strstr(p, ":/")) != NULL) // scheme used by some environments, eg. switch, vita
{
size_t deviceNameOffset = c - p + 3;
char* deviceNamePath = (char*)alloca(deviceNameOffset + 1);
strlcpy(deviceNamePath, p, deviceNameOffset);
deviceNamePath[deviceNameOffset] = 0;
d = opendir(deviceNamePath);
p = c + 1;
}
else
#endif
if (p[0] == '/' || p[0] == '\\')
{
d = opendir("/");
}
else
{
d = opendir(".");
out[0] = '.';
out[1] = 0;
rl = 1;
}
bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't)
bool mayBeTrailingSlash = false;
while (c = strsep(&p, "/\\"))
{
// May be trailing slash(allow), slash at the start(avoid), or multiple slashes(avoid)
if (*c == '\0')
{
mayBeTrailingSlash = true;
continue;
} else {
mayBeTrailingSlash = false;
}
out[rl] = '/';
rl += 1;
out[rl] = 0;
if (cantProceed)
{
strcpy(out + rl, c);
rl += strlen(c);
continue;
}
struct dirent* e;
while (e = readdir(d))
{
if (strcasecmp(c, e->d_name) == 0)
{
strcpy(out + rl, e->d_name);
int reportedLen = (int)strlen(e->d_name);
rl += reportedLen;
assert(reportedLen == strlen(c) && "casepath: This is not good at all");
closedir(d);
d = opendir(out);
// Either it wasn't a folder, or permission error, I/O error etc.
if (!d) {
cantProceed = true;
}
break;
}
}
if (!e)
{
printf("casepath couldn't find dir/file \"%s\", full path was %s\n", c, path);
// No match, add original name and continue converting further slashes.
strcpy(out + rl, c);
rl += strlen(c);
cantProceed = true;
}
}
if (d) closedir(d);
if (mayBeTrailingSlash) {
out[rl] = '/'; rl += 1;
out[rl] = '\0';
}
if (rl > l + 2) {
printf("\n\ncasepath: Corrected path length is longer then original+2:\n\tOriginal: %s (%zu chars)\n\tCorrected: %s (%zu chars)\n\n", path, l, out, rl);
}
return out;
return out;
}
#endif

View file

@ -59,7 +59,9 @@ int _caserename(const char *old_filename, const char *new_filename);
#ifdef RW_GL3
typedef struct
{
#ifndef __SYMBIAN32__
GLFWwindow* window;
#endif
RwBool fullScreen;
RwV2d lastMousePos;
double mouseWheel; // glfw doesn't cache it
@ -96,6 +98,12 @@ extern RwUInt32 gGameState;
RwBool IsForegroundApp();
#if !defined PATH_MAX
#define PATH_MAX 260
#endif
#if !defined NAME_MAX
#define NAME_MAX 120
#endif
#ifndef MAX_PATH
#if !defined _WIN32 || defined __MINGW32__
#define MAX_PATH PATH_MAX

View file

@ -11,7 +11,7 @@ extern "C"
{
#endif /* __cplusplus */
#ifdef _WIN32
#if defined(_WIN32) || defined(__SYMBIAN32__)
extern RwUInt32 psTimer(void);
#else
extern double psTimer(void);

View file

@ -17,7 +17,7 @@ static RwBool DefaultVideoMode = TRUE;
RsGlobalType RsGlobal;
#ifdef _WIN32
#if defined _WIN32 || defined __SYMBIAN32__
RwUInt32
#else
double

View file

@ -254,7 +254,7 @@ extern RwBool
RsInputDeviceAttach(RsInputDeviceType inputDevice,
RsInputEventHandler inputEventHandler);
#ifdef _WIN32
#if defined _WIN32 || defined __SYMBIAN32__
extern RwUInt32
#else
extern double

View file

@ -0,0 +1,586 @@
#include <e32base.h>
#include <e32keys.h>
#include <coemain.h>
#include <w32std.h>
#include <aknapp.h>
#include <akndoc.h>
#include <aknappui.h>
#include <coecntrl.h>
#include <eikstart.h>
#include <hal.h>
#include <pthread.h>
#include <gles2/gl2.h>
#include <EGL/egl.h>
#include <locale.h>
#include "common.h"
#include "rwcore.h"
#include "skel/skeleton.h"
#include "platform.h"
#include "crossplatform.h"
#include "main.h"
#include "FileMgr.h"
#include "Pad.h"
#include "DMAudio.h"
#include "ControllerConfig.h"
#include "Frontend.h"
#include "Game.h"
#include "PCSave.h"
#include "MemoryCard.h"
#include "Sprite2d.h"
#include "AnimViewer.h"
#include "MemoryMgr.h"
#include "Text.h"
#include "Timer.h"
psGlobalType psGlobal;
uint32 gGameState = 0;
long _dwOperatingSystemVersion = 0;
uint32 _dwMemAvailPhys = 0;
static EGLDisplay eglDisplay;
static EGLContext eglContext;
static EGLSurface eglSurface;
static EGLConfig eglConfig;
rw::EngineOpenParams openParams;
const TUid KUidRE3 = {0xe0d67647};
#define JOY_A 0 // cross
#define JOY_B 1 // circle
#define JOY_X 2 // square
#define JOY_Y 3 // triangle
#define JOY_LB 6
#define JOY_RB 7
#define JOY_START 11
#define JOY_DPAD_UP 12
#define JOY_DPAD_RIGHT 13
#define JOY_DPAD_DOWN 14
#define JOY_DPAD_LEFT 15
static uint8 virtualButtons[17] = { 0 };
static float virtualLeftStickX = 0.0f;
static float virtualLeftStickY = 0.0f;
static float virtualRightStickX = 0.0f;
static float virtualRightStickY = 0.0f;
static TInt tickPeriod;
static uint32 cyclesPerMS;
static psGlobalType PsGlobal;
static TBool foreground;
void _InputTranslateShiftKeyUpDown(RsKeyCodes *rs) {
}
const char* _psGetUserFilesFolder() {
return "E:\\Data\\gta3\\";
}
void HandleExit() {
}
RwInt32 _psGetNumVideModes() {
return 1;
}
RwChar** _psGetVideoModeList() {
static RwChar* modes[] = { (RwChar*)"Native" };
return modes;
}
void _psSelectScreenVM(RwInt32 videoMode) {
RwTexDictionarySetCurrent( nil );
FrontEndMenuManager.UnloadTextures();
FrontEndMenuManager.LoadAllTextures();
}
void CapturePad(int padID) {
if (padID != 0) return;
if (!ControlsManager.m_bFirstCapture) {
memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
} else {
memset(&ControlsManager.m_OldState, 0, sizeof(ControlsManager.m_OldState));
}
ControlsManager.m_NewState.buttons = virtualButtons;
ControlsManager.m_NewState.numButtons = 17;
ControlsManager.m_NewState.id = 0;
ControlsManager.m_NewState.isGamepad = true;
memcpy(ControlsManager.m_NewState.mappedButtons, virtualButtons, 17);
if (ControlsManager.m_bFirstCapture) {
memcpy(&ControlsManager.m_OldState, &ControlsManager.m_NewState, sizeof(ControlsManager.m_NewState));
ControlsManager.m_bFirstCapture = false;
}
RsPadButtonStatus bs;
bs.padID = padID;
RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
{
if (CPad::m_bMapPadOneToPadTwo)
bs.padID = 1;
RsPadEventHandler(rsPADBUTTONUP, (void *)&bs);
RsPadEventHandler(rsPADBUTTONDOWN, (void *)&bs);
}
CPad *pad = CPad::GetPad(0);
pad->PCTempJoyState.LeftStickX = (int32)(virtualLeftStickX * 128.0f);
pad->PCTempJoyState.LeftStickY = (int32)(virtualLeftStickY * 128.0f);
pad->PCTempJoyState.RightStickX = (int32)(virtualRightStickX * 128.0f);
pad->PCTempJoyState.RightStickY = (int32)(virtualRightStickY * 128.0f);
}
RwBool psCameraBeginUpdate(RwCamera *camera) {
RwCameraBeginUpdate(camera);
return TRUE;
}
void psCameraShowRaster(RwCamera *camera) {
RwCameraShowRaster(camera, NULL, 0);
}
RwMemoryFunctions* psGetMemoryFunctions(void) {
return nil;
}
RwImage* psGrabScreen(RwCamera *camera) {
return NULL;
}
RwBool psInstallFileSystem(void) {
return TRUE;
}
void psMouseSetPos(RwV2d *pos) {
}
RwBool psNativeTextureSupport(void) {
return TRUE;
}
RwBool psSelectDevice(void) {
return TRUE;
}
void psTerminate(void) {
}
RwBool psInitialize(void) {
CFileMgr::Initialise();
TInt memFree = 0;
if (HAL::Get(HALData::EMemoryRAMFree, memFree) == KErrNone) {
if (memFree > 40 * 1024 * 1024) {
_dwMemAvailPhys = 40 * 1024 * 1024;
} else if (memFree <= 0) {
_dwMemAvailPhys = 10 * 1024 * 1024;
} else {
_dwMemAvailPhys = memFree;
}
} else {
_dwMemAvailPhys = 40 * 1024 * 1024;
}
C_PcSave::SetSaveDirectory(_psGetUserFilesFolder());
return TRUE;
}
RwUInt32 psTimer(void) {
// return (RwUInt32)User::NTickCount();
TTime time;
time.HomeTime();
return (RwUInt32)(time.Int64() / 1000);
}
namespace sk {
void SetMousePosition(int x, int y) {}
}
extern "C" void RDebug_Printf(const char*, ...);
void RDebug_Printf(const char* c, ...)
{
VA_LIST list;
VA_START(list, c);
TBuf8<0x100> buf;
TPtrC8 des((const TUint8 *)c);
buf.FormatList(des, list);
RDebug::RawPrint(buf);
}
uint32 CTimer::GetCyclesPerMillisecond(void) {
// return cyclesPerMS;
return 1;
}
RwBool IsForegroundApp() {
return foreground;
}
class CCContainer : public CCoeControl {
public:
CAknAppUi* iAppUi;
CPeriodic* iPeriodic;
RwUInt32 gGameState;
static TInt LoopCallBack(TAny* p) {
CCContainer* container = (CCContainer*) p;
if(RsGlobal.quit) {
RsEventHandler(rsRWTERMINATE, nil);
container->iAppUi->Exit();
return EFalse;
}
switch (container->gGameState) {
case GS_START_UP:
foreground = true;
if (HAL::Get(HAL::ENanoTickPeriod, tickPeriod) != KErrNone) {
User::Panic(_L("Could not init timer"), 0);
}
cyclesPerMS = 1000 / tickPeriod;
if (cyclesPerMS < 1) cyclesPerMS = 1;
container->gGameState = GS_INIT_ONCE;
break;
case GS_INIT_ONCE:
LoadingScreen(nil, nil, "loadsc0");
if ( !CGame::InitialiseOnceAfterRW() ) {
RsGlobal.quit = TRUE;
return ETrue;
}
// container->gGameState = GS_INIT_FRONTEND;
container->gGameState = GS_INIT_PLAYING_GAME;
break;
case GS_INIT_FRONTEND:
LoadingScreen(nil, nil, "loadsc0");
FrontEndMenuManager.m_bGameNotLoaded = true;
CMenuManager::m_bStartUpFrontEndRequested = true;
container->gGameState = GS_FRONTEND;
// container->gGameState = GS_INIT_PLAYING_GAME;
break;
case GS_FRONTEND:
RsEventHandler(rsFRONTENDIDLE, nil);
if ( !FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bWantToLoad )
{
container->gGameState = GS_INIT_PLAYING_GAME;
TRACE("gGameState = GS_INIT_PLAYING_GAME;");
}
if ( FrontEndMenuManager.m_bWantToLoad )
{
InitialiseGame();
FrontEndMenuManager.m_bGameNotLoaded = false;
container->gGameState = GS_PLAYING_GAME;
TRACE("gGameState = GS_PLAYING_GAME;");
}
break;
case GS_INIT_PLAYING_GAME:
InitialiseGame();
FrontEndMenuManager.m_bGameNotLoaded = false;
container->gGameState = GS_PLAYING_GAME;
TRACE("gGameState = GS_PLAYING_GAME;");
break;
case GS_PLAYING_GAME:
// float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)tickPeriod; //(float)CTimer::GetCyclesPerMillisecond();
// if ( RwInitialised )
// {
// if (!CMenuManager::m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms)
RsEventHandler(rsIDLE, (void *)TRUE);
// }
break;
}
if (IsForegroundApp()) {
User::ResetInactivityTime();
}
return ETrue;
}
void RestartTimerL(TInt aInterval) {
if (iPeriodic) iPeriodic->Cancel();
else iPeriodic = CPeriodic::NewL(CActive::EPriorityStandard);
iPeriodic->Start(aInterval, aInterval, TCallBack(CCContainer::LoopCallBack, this));
}
void ConstructL(const TRect& aRect, CAknAppUi* aAppUi) {
iAppUi = aAppUi;
CreateWindowL();
SetExtentToWholeScreen();
Window().EnableAdvancedPointers();
EnableDragEvents();
ActivateL();
TSize size = Size();
RsGlobal.width = size.iWidth;
RsGlobal.height = size.iHeight;
EGLint attribs[] = {
EGL_BUFFER_SIZE, 16,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLES, 0,
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(eglDisplay, NULL, NULL);
eglBindAPI(EGL_OPENGL_ES_API);
EGLint numConfigs;
eglChooseConfig(eglDisplay, attribs, &eglConfig, 1, &numConfigs);
EGLint contextAttribs[ 3 ] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
RWindow& window = Window();
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, &window, NULL);
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
setlocale(LC_ALL, "");
setlocale(LC_CTYPE, "C");
setlocale(LC_COLLATE, "C");
setlocale(LC_NUMERIC, "C");
chdir("E:\\Data\\gta3\\");
gGameState = GS_START_UP;
FrontEndMenuManager.LoadSettings();
CMenuManager::OS_Language = LANG_ENGLISH;
CMenuManager::m_PrefsLanguage = CMenuManager::LANGUAGE_AMERICAN;
TheText.Unload();
TheText.Load();
chdir("E:\\Data\\gta3\\");
if(RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR) return;
openParams.width = RsGlobal.width;
openParams.height = RsGlobal.height;
openParams.windowtitle = RsGlobal.appName;
ControlsManager.MakeControllerActionsBlank();
ControlsManager.InitDefaultControlConfiguration();
if(RsEventHandler(rsRWINITIALIZE, &openParams) == rsEVENTERROR) return;
CPad::GetPad(0)->Clear(true);
CPad::GetPad(1)->Clear(true);
PsGlobal.lastMousePos.x = PsGlobal.lastMousePos.y = 0.0f;
RsGlobal.ps = &PsGlobal;
ControlsManager.InitDefaultControlConfigJoyPad(15);
ControlsManager.InitDefaultControlConfigMouse(MousePointerStateHelper.GetMouseSetUp());
{
RwRect r;
r.x = 0;
r.y = 0;
r.w = RsGlobal.maximumWidth;
r.h = RsGlobal.maximumHeight;
RsEventHandler(rsCAMERASIZE, &r);
}
RestartTimerL(10000);
}
virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent) {
int x = aPointerEvent.iPosition.iX;
int y = aPointerEvent.iPosition.iY;
int w = RsGlobal.width;
int h = RsGlobal.height;
// if (FrontEndMenuManager.m_bMenuActive) {
// PSGLOBAL(lastMousePos).x = x;
// PSGLOBAL(lastMousePos).y = y;
// FrontEndMenuManager.m_nMouseTempPosX = x;
// FrontEndMenuManager.m_nMouseTempPosY = y;
//
// if (aPointerEvent.iType == TPointerEvent::EButton1Down) {
// CPad::GetPad(0)->PCTempMouseControllerState.LMB = true;
// } else if (aPointerEvent.iType == TPointerEvent::EButton1Up) {
// CPad::GetPad(0)->PCTempMouseControllerState.RMB = false;
// }
// CCoeControl::HandlePointerEventL(aPointerEvent);
// return;
// }
const TAdvancedPointerEvent* advpointer = aPointerEvent.AdvancedPointerEvent();
int i = advpointer != NULL ? advpointer->PointerNumber() : 0;
static int activeZone[10];
static int stickCenterX[10];
static int stickCenterY[10];
if (i > 9) {
CCoeControl::HandlePointerEventL(aPointerEvent);
return;
}
if (aPointerEvent.iType == TPointerEvent::EButton1Down) {
if (x < w / 3 && y > h / 4) {
// bottom left: left stick
activeZone[i] = 1;
stickCenterX[i] = x;
stickCenterY[i] = y;
} else if (x > w * 2 / 3 && y > h / 4) {
// bottom right: right stick
activeZone[i] = 2;
stickCenterX[i] = x;
stickCenterY[i] = y;
} else if (x > w - (w / 5) && y < h / 4) {
// top right: enter/exit
activeZone[i] = 3;
virtualButtons[JOY_Y] = 1;
} else if (x < w / 5 && y < h / 4) {
// top left: brake
activeZone[i] = 4;
virtualButtons[JOY_X] = 1;
} else {
// gas
activeZone[i] = 5;
virtualButtons[JOY_B] = 1;
}
}
if (aPointerEvent.iType == TPointerEvent::EDrag) {
if (activeZone[i] == 1 || activeZone[i] == 2) {
float dx = (float)(x - stickCenterX[i]) / (w / 8.0f);
float dy = (float)(y - stickCenterY[i]) / (h / 6.0f);
if (dx < -1.0f) dx = -1.0f;
if (dx > 1.0f) dx = 1.0f;
if (dy < -1.0f) dy = -1.0f;
if (dy > 1.0f) dy = 1.0f;
if (activeZone[i] == 1) {
virtualLeftStickX = dx;
virtualLeftStickY = dy;
} else {
virtualRightStickX = dx;
virtualRightStickY = dy;
}
}
}
if (aPointerEvent.iType == TPointerEvent::EButton1Up) {
if (activeZone[i] == 1) {
virtualLeftStickX = 0.0f;
virtualLeftStickY = 0.0f;
} else if (activeZone[i] == 2) {
virtualRightStickX = 0.0f;
virtualRightStickY = 0.0f;
} else if (activeZone[i] == 3) {
virtualButtons[JOY_Y] = 0;
} else if (activeZone[i] == 4) {
virtualButtons[JOY_X] = 0;
} else if (activeZone[i] == 5) {
virtualButtons[JOY_B] = 0;
}
activeZone[i] = 0;
}
CCoeControl::HandlePointerEventL(aPointerEvent);
}
};
class RE3AppUi : public CAknAppUi {
CCContainer* iContainer;
public:
void ConstructL() {
BaseConstructL(CAknAppUi::EAknEnableSkin);
iContainer = new (ELeave) CCContainer;
iContainer->SetMopParent(this);
iContainer->ConstructL(ClientRect(), this);
AddToStackL(iContainer);
}
void HandleForegroundEventL(TBool aForeground) {
foreground = aForeground;
}
~RE3AppUi() {
if (iContainer) {
RemoveFromStack(iContainer);
delete iContainer;
}
}
void HandleCommandL(TInt aCommand) {
if (aCommand == EAknSoftkeyBack || aCommand == EEikCmdExit) {
RsGlobal.quit = 1;
}
}
};
class RE3Document: public CAknDocument {
public:
static RE3Document* NewL(CEikApplication& aApp);
virtual ~RE3Document();
protected:
void ConstructL();
public:
RE3Document(CEikApplication& aApp);
private:
CEikAppUi* CreateAppUiL();
};
RE3Document::RE3Document(CEikApplication& aApp) : CAknDocument(aApp) {}
RE3Document::~RE3Document() {}
void RE3Document::ConstructL() {}
RE3Document* RE3Document::NewL(CEikApplication& aApp) {
RE3Document* self = new (ELeave) RE3Document(aApp);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CEikAppUi* RE3Document::CreateAppUiL() {
return new (ELeave) RE3AppUi;
}
class RE3App: public CAknApplication {
private:
CApaDocument* CreateDocumentL();
TUid AppDllUid() const;
};
LOCAL_C CApaApplication* NewApplication();
GLDEF_C TInt E32Main();
TUid RE3App::AppDllUid() const {
return KUidRE3;
}
CApaDocument* RE3App::CreateDocumentL() {
return RE3Document::NewL(*this);
}
CApaApplication* NewApplication() {
return new RE3App;
}
TInt E32Main() {
User::SetFloatingPointMode(EFpModeRunFast);
return EikStart::RunApplication(NewApplication);
}