Commit 52001505 authored by Ryan C. Gordon's avatar Ryan C. Gordon

Removed EPOC port...it's being replaced by an updated Symbian port with the

 original author's blessing.

--HG--
branch : SDL-1.2
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/branches/SDL-1.2%402360
parent 92435d92
==============================================================================
Using the Simple DirectMedia Layer with EPOC/SymbianOS 6.0
==============================================================================
==============================================================================
I. Building the Simple DirectMedia Layer libraries:
You can get Symbian SDK from:
http://www.symbian.com.
First create "Epoc" directory under SDL main directory and unpack
EpocBuildFiles.zip in it.
To build the librarys goto "epoc" directory and type:
bldmake bldfiles
abld makefile vc6 (for creating Microsoft Visual C++ makefiles)
abld build wins udeb (building for wins emulator)
abld build armi urel (building for real device)
==============================================================================
II. Building the Simple DirectMedia Layer programs:
Building SDL test programs is easy once you have built the libraries:
abld test build wins udeb
abld test build armi urel
Supported real screen resolutions
320 x 200 x 8 bit
320 x 200 x 12 bit
640 x 200 x 8 bit
640 x 200 x 12 bit
Supported "emulated" screen resolutions
640 x 400 x 8 bit
640 x 400 x 12 bit
640 x 480 x 8 bit
640 x 480 x 12 bit
"Emulated" resolutions are implemented by by shrinking the screen vertically
i.e. only every second scanline is drawn. This is mainly ment to be used for
testing quick ports of programs. Using faked resolutions is a waste of memory
and cpu power!
==============================================================================
III. Running test programs
Copy executable to the device and run it from the File manager. The Esc
key quits demo programs. In Crystal, Exe programs do not appear in task list
nor in Extras :-(. Test programs are tested in Nokia 9210 Communicator.
Special keys used in SDL:
The Caps lock key enables or disables the virtual cursor.
Function keys are mapped as follows:
F1=chr+q, F2=chr+w,..., F8=chr+i,
F9=chr+a,..., F12=chr+d.
==============================================================================
IV. Enjoy! :)
If you have a project you'd like me to know about, or want to ask questions,
go ahead and join the SDL developer's mailing list by sending e-mail to:
sdl-request@libsdl.org
and put "subscribe" into the subject of the message. Or alternatively you
can use the web interface:
http://www.libsdl.org/mailman/listinfo/sdl
You can find more info about Epoc version of SDL from Hannu Viitala's
homepage
http://www.mbnet.fi/~haviital
==============================================================================
......@@ -43,6 +43,9 @@ SDL 1.2.12 is a minor bug fix release.
<P>
Support for AmigaOS has been removed from the main SDL code.
</P>
<P>
Support for Nokia 9210 "EPOC" driver has been removed from the main SDL code.
</P>
</BLOCKQUOTE>
<H3> Unix Notes </H3>
......
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_sysmutex.cpp
Epoc version by Markus Mertama (w@iki.fi)
*/
/* Mutex functions using the Win32 API */
#include<e32std.h>
#include "SDL_error.h"
#include "SDL_mutex.h"
struct SDL_mutex
{
TInt handle;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
TInt NewMutex(const TDesC& aName, TAny* aPtr1, TAny*)
{
return ((RMutex*)aPtr1)->CreateGlobal(aName);
}
/* Create a mutex */
SDL_mutex *SDL_CreateMutex(void)
{
RMutex rmutex;
TInt status = CreateUnique(NewMutex, &rmutex, NULL);
if(status != KErrNone)
{
SDL_SetError("Couldn't create mutex");
}
SDL_mutex* mutex = new /*(ELeave)*/ SDL_mutex;
mutex->handle = rmutex.Handle();
return(mutex);
}
/* Free the mutex */
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if ( mutex )
{
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
rmutex.Close();
delete(mutex);
mutex = NULL;
}
}
/* Lock the mutex */
int SDL_mutexP(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Wait();
return(0);
}
/* Unlock the mutex */
int SDL_mutexV(SDL_mutex *mutex)
{
if ( mutex == NULL ) {
SDL_SetError("Passed a NULL mutex");
return -1;
}
RMutex rmutex;
rmutex.SetHandle(mutex->handle);
rmutex.Signal();
return(0);
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_syssem.cpp
Epoc version by Markus Mertama (w@iki.fi)
*/
/* Semaphore functions using the Win32 API */
#include <e32std.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#define SDL_MUTEX_TIMEOUT -2
struct SDL_semaphore
{
TInt handle;
TInt count;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2);
TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
TInt value = *((TInt*) aPtr2);
return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
}
/* Create a semaphore */
SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
{
RSemaphore s;
TInt status = CreateUnique(NewSema, &s, &initial_value);
if(status != KErrNone)
{
SDL_SetError("Couldn't create semaphore");
}
SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;
sem->handle = s.Handle();
sem->count = initial_value;
return(sem);
}
/* Free the semaphore */
void SDL_DestroySemaphore(SDL_sem *sem)
{
if ( sem )
{
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal(sema.Count());
sema.Close();
delete sem;
sem = NULL;
}
}
struct TInfo
{
TInfo(TInt aTime, TInt aHandle) :
iTime(aTime), iHandle(aHandle), iVal(0) {}
TInt iTime;
TInt iHandle;
TInt iVal;
};
TBool ThreadRun(TAny* aInfo)
{
TInfo* info = STATIC_CAST(TInfo*, aInfo);
User::After(info->iTime);
RSemaphore sema;
sema.SetHandle(info->iHandle);
sema.Signal();
info->iVal = SDL_MUTEX_TIMEOUT;
return 0;
}
void _WaitAll(SDL_sem *sem)
{
//since SemTryWait may changed the counter.
//this may not be atomic, but hopes it works.
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Wait();
while(sem->count < 0)
{
sema.Wait();
}
}
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return -1;
}
if ( timeout == SDL_MUTEX_MAXWAIT )
{
_WaitAll(sem);
return SDL_MUTEX_MAXWAIT;
}
RThread thread;
TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
TInt status = CreateUnique(NewThread, &thread, info);
if(status != KErrNone)
return status;
thread.Resume();
_WaitAll(sem);
if(thread.ExitType() == EExitPending)
{
thread.Kill(SDL_MUTEX_TIMEOUT);
}
thread.Close();
return info->iVal;
}
int SDL_SemTryWait(SDL_sem *sem)
{
if(sem->count > 0)
{
sem->count--;
}
return SDL_MUTEX_TIMEOUT;
}
int SDL_SemWait(SDL_sem *sem)
{
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
}
/* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return 0;
}
return sem->count;
}
int SDL_SemPost(SDL_sem *sem)
{
if ( ! sem ) {
SDL_SetError("Passed a NULL sem");
return -1;
}
sem->count++;
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal();
return 0;
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_systhread.cpp
Epoc thread management routines for SDL
Epoc version by Markus Mertama (w@iki.fi)
*/
extern "C" {
#undef NULL
#include "SDL_error.h"
#include "SDL_thread.h"
#include "../SDL_systhread.h"
};
#include <e32std.h>
static int object_count;
int RunThread(TAny* data)
{
SDL_RunThread(data);
return(0);
}
TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
return ((RThread*)(aPtr1))->Create(aName,
RunThread,
KDefaultStackSize,
NULL,
aPtr2);
}
int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2)
{
TBuf<16> name;
TInt status = KErrNone;
do
{
object_count++;
name.Format(_L("SDL_%x"), object_count);
status = aFunc(name, aPtr1, aPtr2);
}
while(status == KErrAlreadyExists);
return status;
}
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
{
RThread rthread;
TInt status = CreateUnique(NewThread, &rthread, args);
if (status != KErrNone)
{
delete(((RThread*)(thread->handle)));
thread->handle = NULL;
SDL_SetError("Not enough resources to create thread");
return(-1);
}
rthread.Resume();
thread->handle = rthread.Handle();
return(0);
}
void SDL_SYS_SetupThread(void)
{
return;
}
Uint32 SDL_ThreadID(void)
{
RThread current;
TThreadId id = current.Id();
return id;
}
void SDL_SYS_WaitThread(SDL_Thread *thread)
{
RUndertaker taker;
taker.Create();
TRequestStatus status;
taker.Logon(status, thread->handle);
User::WaitForRequest(status);
taker.Close();
}
/* WARNING: This function is really a last resort.
* Threads should be signaled and then exit by themselves.
* TerminateThread() doesn't perform stack and DLL cleanup.
*/
void SDL_SYS_KillThread(SDL_Thread *thread)
{
RThread rthread;
rthread.SetHandle(thread->handle);
rthread.Kill(0);
rthread.Close();
}
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_systhread_c.h
Epoc version by Markus Mertama (w@iki.fi)
*/
typedef int SYS_ThreadHandle;
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
#ifdef SDL_TIMER_EPOC
/*
SDL_systimer.cpp
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
#include <e32std.h>
#include <e32hal.h>
extern "C" {
#include "SDL_error.h"
#include "SDL_thread.h"
#include "SDL_timer.h"
#include "../SDL_timer_c.h"
static TUint start = 0;
static TInt tickPeriodMilliSeconds;
void SDL_StartTicks(void)
{
/* Set first ticks value */
start = User::TickCount();
TTimeIntervalMicroSeconds32 period;
TInt tmp = UserHal::TickPeriod(period);
tickPeriodMilliSeconds = period.Int() / 1000;
}
Uint32 SDL_GetTicks(void)
{
TUint deltaTics = User::TickCount() - start;
return(deltaTics * tickPeriodMilliSeconds);
}
void SDL_Delay(Uint32 ms)
{
User::After(TTimeIntervalMicroSeconds32(ms*1000));
}
/* Data to handle a single periodic alarm */
static int timer_alive = 0;
static SDL_Thread *timer = NULL;
static int RunTimer(void *unused)
{
Uint32 ms;
while ( timer_alive ) {
if ( SDL_timer_running ) {
SDL_ThreadedTimerCheck();
}
SDL_Delay(10);
}
return(0);
}
/* This is only called if the event thread is not running */
int SDL_SYS_TimerInit(void)
{
timer_alive = 1;
timer = SDL_CreateThread(RunTimer, NULL);
if ( timer == NULL )
return(-1);
return(SDL_SetTimerThreaded(1));
}
void SDL_SYS_TimerQuit(void)
{
timer_alive = 0;
if ( timer ) {
SDL_WaitThread(timer, NULL);
timer = NULL;
}
}
int SDL_SYS_StartTimer(void)
{
SDL_SetError("Internal logic error: Epoc uses threaded timer");
return(-1);
}
void SDL_SYS_StopTimer(void)
{
return;
}
}; // extern "C"
#endif /* SDL_TIMER_EPOC */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_epocevents.cpp
Handle the event stream, converting Epoc events into SDL events
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
#include <stdio.h>
#undef NULL
extern "C" {
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_keysym.h"
#include "SDL_keyboard.h"
#include "SDL_timer.h"
#include "../../events/SDL_events_c.h"
}; /* extern "C" */
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include <hal.h>
extern "C" {
/* The translation tables from a console scancode to a SDL keysym */
static SDLKey keymap[MAX_SCANCODE];
static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
}; /* extern "C" */
TBool isCursorVisible = ETrue;
int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
{
int posted = 0;
SDL_keysym keysym;
switch (aWsEvent.Type()) {
case EEventPointer: /* Mouse pointer events */
{
const TPointerEvent* pointerEvent = aWsEvent.Pointer();
TPoint mousePos = pointerEvent->iPosition;
//SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
if (Private->EPOC_ShrinkedHeight) {
mousePos.iY <<= 1; /* Scale y coordinate to shrinked screen height */
}
posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
if (pointerEvent->iType==TPointerEvent::EButton1Down) {
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
}
else if (pointerEvent->iType==TPointerEvent::EButton1Up) {
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
}
else if (pointerEvent->iType==TPointerEvent::EButton2Down) {
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
}
else if (pointerEvent->iType==TPointerEvent::EButton2Up) {
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
}
//!!posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
break;
}
case EEventKeyDown: /* Key events */
{
(void*)TranslateKey(aWsEvent.Key()->iScanCode, &keysym);
/* Special handling */
switch((int)keysym.sym) {
case SDLK_CAPSLOCK:
if (!isCursorVisible) {
/* Enable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
}
else {
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
}
isCursorVisible = !isCursorVisible;
break;
}
posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
break;
}
case EEventKeyUp: /* Key events */
{
posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
break;
}
case EEventFocusGained: /* SDL window got focus */
{
//Private->EPOC_IsWindowFocused = ETrue;
/* Draw window background and screen buffer */
RedrawWindowL(_this);
break;
}
case EEventFocusLost: /* SDL window lost focus */
{
//Private->EPOC_IsWindowFocused = EFalse;
// Wait and eat events until focus is gained again
/*
while (ETrue) {
Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
User::WaitForRequest(Private->EPOC_WsEventStatus);
Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
TInt eventType = Private->EPOC_WsEvent.Type();
Private->EPOC_WsEventStatus = KRequestPending;
//Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
if (eventType == EEventFocusGained) {
RedrawWindowL(_this);
break;
}
}
*/
break;
}
case EEventModifiersChanged:
{
TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
TUint modstate = KMOD_NONE;
if (modEvent->iModifiers == EModifierLeftShift)
modstate |= KMOD_LSHIFT;
if (modEvent->iModifiers == EModifierRightShift)
modstate |= KMOD_RSHIFT;
if (modEvent->iModifiers == EModifierLeftCtrl)
modstate |= KMOD_LCTRL;
if (modEvent->iModifiers == EModifierRightCtrl)
modstate |= KMOD_RCTRL;
if (modEvent->iModifiers == EModifierLeftAlt)
modstate |= KMOD_LALT;
if (modEvent->iModifiers == EModifierRightAlt)
modstate |= KMOD_RALT;
if (modEvent->iModifiers == EModifierLeftFunc)
modstate |= KMOD_LMETA;
if (modEvent->iModifiers == EModifierRightFunc)
modstate |= KMOD_RMETA;
if (modEvent->iModifiers == EModifierCapsLock)
modstate |= KMOD_CAPS;
SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
break;
}
default:
break;
}
return posted;
}
extern "C" {
void EPOC_PumpEvents(_THIS)
{
int posted = 0; // !! Do we need this?
//Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
while (Private->EPOC_WsEventStatus != KRequestPending) {
Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
Private->EPOC_WsEventStatus = KRequestPending;
Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
}
}
void EPOC_InitOSKeymap(_THIS)
{
int i;
/* Initialize the key translation table */
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* Numbers */
for ( i = 0; i<32; ++i ){
keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
}
/* e.g. Alphabet keys */
for ( i = 0; i<32; ++i ){
keymap['A' + i] = (SDLKey)(SDLK_a+i);
}
keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
keymap[EStdKeyTab] = SDLK_TAB;
keymap[EStdKeyEnter] = SDLK_RETURN;
keymap[EStdKeyEscape] = SDLK_ESCAPE;
keymap[EStdKeySpace] = SDLK_SPACE;
keymap[EStdKeyPause] = SDLK_PAUSE;
keymap[EStdKeyHome] = SDLK_HOME;
keymap[EStdKeyEnd] = SDLK_END;
keymap[EStdKeyPageUp] = SDLK_PAGEUP;
keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
keymap[EStdKeyDelete] = SDLK_DELETE;
keymap[EStdKeyUpArrow] = SDLK_UP;
keymap[EStdKeyDownArrow] = SDLK_DOWN;
keymap[EStdKeyLeftArrow] = SDLK_LEFT;
keymap[EStdKeyRightArrow] = SDLK_RIGHT;
keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
keymap[EStdKeyRightShift] = SDLK_RSHIFT;
keymap[EStdKeyLeftAlt] = SDLK_LALT;
keymap[EStdKeyRightAlt] = SDLK_RALT;
keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
keymap[EStdKeyLeftFunc] = SDLK_LMETA;
keymap[EStdKeyRightFunc] = SDLK_RMETA;
keymap[EStdKeyInsert] = SDLK_INSERT;
keymap[EStdKeyComma] = SDLK_COMMA;
keymap[EStdKeyFullStop] = SDLK_PERIOD;
keymap[EStdKeyForwardSlash] = SDLK_SLASH;
keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
keymap[EStdKeySingleQuote] = SDLK_QUOTE;
keymap[EStdKeyHash] = SDLK_HASH;
keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
keymap[EStdKeyMinus] = SDLK_MINUS;
keymap[EStdKeyEquals] = SDLK_EQUALS;
keymap[EStdKeyF1] = SDLK_F1; /* chr + q */
keymap[EStdKeyF2] = SDLK_F2; /* chr + w */
keymap[EStdKeyF3] = SDLK_F3; /* chr + e */
keymap[EStdKeyF4] = SDLK_F4; /* chr + r */
keymap[EStdKeyF5] = SDLK_F5; /* chr + t */
keymap[EStdKeyF6] = SDLK_F6; /* chr + y */
keymap[EStdKeyF7] = SDLK_F7; /* chr + i */
keymap[EStdKeyF8] = SDLK_F8; /* chr + o */
keymap[EStdKeyF9] = SDLK_F9; /* chr + a */
keymap[EStdKeyF10] = SDLK_F10; /* chr + s */
keymap[EStdKeyF11] = SDLK_F11; /* chr + d */
keymap[EStdKeyF12] = SDLK_F12; /* chr + f */
/* !!TODO
EStdKeyNumLock=0x1b,
EStdKeyScrollLock=0x1c,
EStdKeyNkpForwardSlash=0x84,
EStdKeyNkpAsterisk=0x85,
EStdKeyNkpMinus=0x86,
EStdKeyNkpPlus=0x87,
EStdKeyNkpEnter=0x88,
EStdKeyNkp1=0x89,
EStdKeyNkp2=0x8a,
EStdKeyNkp3=0x8b,
EStdKeyNkp4=0x8c,
EStdKeyNkp5=0x8d,
EStdKeyNkp6=0x8e,
EStdKeyNkp7=0x8f,
EStdKeyNkp8=0x90,
EStdKeyNkp9=0x91,
EStdKeyNkp0=0x92,
EStdKeyNkpFullStop=0x93,
EStdKeyMenu=0x94,
EStdKeyBacklightOn=0x95,
EStdKeyBacklightOff=0x96,
EStdKeyBacklightToggle=0x97,
EStdKeyIncContrast=0x98,
EStdKeyDecContrast=0x99,
EStdKeySliderDown=0x9a,
EStdKeySliderUp=0x9b,
EStdKeyDictaphonePlay=0x9c,
EStdKeyDictaphoneStop=0x9d,
EStdKeyDictaphoneRecord=0x9e,
EStdKeyHelp=0x9f,
EStdKeyOff=0xa0,
EStdKeyDial=0xa1,
EStdKeyIncVolume=0xa2,
EStdKeyDecVolume=0xa3,
EStdKeyDevice0=0xa4,
EStdKeyDevice1=0xa5,
EStdKeyDevice2=0xa6,
EStdKeyDevice3=0xa7,
EStdKeyDevice4=0xa8,
EStdKeyDevice5=0xa9,
EStdKeyDevice6=0xaa,
EStdKeyDevice7=0xab,
EStdKeyDevice8=0xac,
EStdKeyDevice9=0xad,
EStdKeyDeviceA=0xae,
EStdKeyDeviceB=0xaf,
EStdKeyDeviceC=0xb0,
EStdKeyDeviceD=0xb1,
EStdKeyDeviceE=0xb2,
EStdKeyDeviceF=0xb3,
EStdKeyApplication0=0xb4,
EStdKeyApplication1=0xb5,
EStdKeyApplication2=0xb6,
EStdKeyApplication3=0xb7,
EStdKeyApplication4=0xb8,
EStdKeyApplication5=0xb9,
EStdKeyApplication6=0xba,
EStdKeyApplication7=0xbb,
EStdKeyApplication8=0xbc,
EStdKeyApplication9=0xbd,
EStdKeyApplicationA=0xbe,
EStdKeyApplicationB=0xbf,
EStdKeyApplicationC=0xc0,
EStdKeyApplicationD=0xc1,
EStdKeyApplicationE=0xc2,
EStdKeyApplicationF=0xc3,
EStdKeyYes=0xc4,
EStdKeyNo=0xc5,
EStdKeyIncBrightness=0xc6,
EStdKeyDecBrightness=0xc7,
EStdKeyCaseOpen=0xc8,
EStdKeyCaseClose=0xc9
*/
}
static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
{
char debug[256];
//SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
/* Set the keysym information */
keysym->scancode = scancode;
if ((scancode >= MAX_SCANCODE) &&
((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
SDL_SetError("Too big scancode");
keysym->scancode = SDLK_UNKNOWN;
keysym->mod = KMOD_NONE;
return keysym;
}
keysym->mod = SDL_GetModState(); //!!Is this right??
/* Handle function keys: F1, F2, F3 ... */
if (keysym->mod & KMOD_META) {
if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphapet keys */
switch(scancode) {
case 'Q': scancode = EStdKeyF1; break;
case 'W': scancode = EStdKeyF2; break;
case 'E': scancode = EStdKeyF3; break;
case 'R': scancode = EStdKeyF4; break;
case 'T': scancode = EStdKeyF5; break;
case 'Y': scancode = EStdKeyF6; break;
case 'U': scancode = EStdKeyF7; break;
case 'I': scancode = EStdKeyF8; break;
case 'A': scancode = EStdKeyF9; break;
case 'S': scancode = EStdKeyF10; break;
case 'D': scancode = EStdKeyF11; break;
case 'F': scancode = EStdKeyF12; break;
}
keysym->sym = keymap[scancode];
}
}
if (scancode >= ENonCharacterKeyBase) {
// Non character keys
keysym->sym = keymap[scancode -
ENonCharacterKeyBase + 0x0081]; // !!hard coded
} else {
keysym->sym = keymap[scancode];
}
/* If UNICODE is on, get the UNICODE value for the key */
keysym->unicode = 0;
#if 0 // !!TODO:unicode
if ( SDL_TranslateUNICODE )
{
/* Populate the unicode field with the ASCII value */
keysym->unicode = scancode;
}
#endif
//!!
//sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
// keysym->scancode, keysym->sym, keysym->mod);
//SDL_TRACE(debug); //!!
return(keysym);
}
}; /* extern "C" */
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2006 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_epocevents_c.h
Handle the event stream, converting Epoc events into SDL events
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
extern "C" {
#include "../SDL_sysvideo.h"
};
#define MAX_SCANCODE 255
/* Variables and functions exported by SDL_sysevents.c to other parts
of the native video subsystem (SDL_sysvideo.c)
*/
extern "C" {
extern void EPOC_InitOSKeymap(_THIS);
extern void EPOC_PumpEvents(_THIS);
};
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_epocvideo.cpp
Epoc based SDL video driver implementation
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
extern "C" {
#include "SDL_timer.h"
#include "SDL_video.h"
#undef NULL
#include "../SDL_pixels_c.h"
};
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include <hal.h>
#include <coedef.h>
/* For debugging */
void RDebug_Print_b(char* error_str, void* param)
{
TBuf8<128> error8((TUint8*)error_str);
TBuf<128> error;
error.Copy(error8);
if (param) //!! Do not work if the parameter is really 0!!
RDebug::Print(error, param);
else
RDebug::Print(error);
}
extern "C" void RDebug_Print(char* error_str, void* param)
{
RDebug_Print_b(error_str, param);
}
int Debug_AvailMem2()
{
//User::CompressAllHeaps();
TMemoryInfoV1Buf membuf;
User::LeaveIfError(UserHal::MemoryInfo(membuf));
TMemoryInfoV1 minfo = membuf();
return(minfo.iFreeRamInBytes);
}
extern "C" int Debug_AvailMem()
{
return(Debug_AvailMem2());
}
extern "C" {
/* Initialization/Query functions */
static int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int EPOC_SetColors(_THIS, int firstcolor, int ncolors,
SDL_Color *colors);
static void EPOC_VideoQuit(_THIS);
/* Hardware surface functions */
static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface);
static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface);
static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface);
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
static int EPOC_Available(void);
static SDL_VideoDevice *EPOC_CreateDevice(int devindex);
/* Mouse functions */
static WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
static void EPOC_FreeWMCursor(_THIS, WMcursor *cursor);
static int EPOC_ShowWMCursor(_THIS, WMcursor *cursor);
/* !! Table for fast conversion from 8 bit to 12 bit */
static TUint16 EPOC_HWPalette_256_to_4k[256];
VideoBootStrap EPOC_bootstrap = {
"epoc", "EPOC system",
EPOC_Available, EPOC_CreateDevice
};
const TUint32 WindowClientHandle = 9210; //!!
/* Epoc video driver bootstrap functions */
static int EPOC_Available(void)
{
return 1; /* Always available */
}
static void EPOC_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device->hidden);
SDL_free(device);
}
static SDL_VideoDevice *EPOC_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
/* Allocate all variables that we free on delete */
device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
if ( device ) {
SDL_memset(device, 0, (sizeof *device));
device->hidden = (struct SDL_PrivateVideoData *)
SDL_malloc((sizeof *device->hidden));
}
if ( (device == NULL) || (device->hidden == NULL) ) {
SDL_OutOfMemory();
if ( device ) {
SDL_free(device);
}
return(0);
}
SDL_memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = EPOC_VideoInit;
device->ListModes = EPOC_ListModes;
device->SetVideoMode = EPOC_SetVideoMode;
device->SetColors = EPOC_SetColors;
device->UpdateRects = NULL;
device->VideoQuit = EPOC_VideoQuit;
device->AllocHWSurface = EPOC_AllocHWSurface;
device->CheckHWBlit = NULL;
device->FillHWRect = NULL;
device->SetHWColorKey = NULL;
device->SetHWAlpha = NULL;
device->LockHWSurface = EPOC_LockHWSurface;
device->UnlockHWSurface = EPOC_UnlockHWSurface;
device->FlipHWSurface = EPOC_FlipHWSurface;
device->FreeHWSurface = EPOC_FreeHWSurface;
device->SetIcon = NULL;
device->SetCaption = NULL;
device->GetWMInfo = NULL;
device->FreeWMCursor = EPOC_FreeWMCursor;
device->CreateWMCursor = EPOC_CreateWMCursor;
device->ShowWMCursor = EPOC_ShowWMCursor;
device->WarpWMCursor = NULL;
device->InitOSKeymap = EPOC_InitOSKeymap;
device->PumpEvents = EPOC_PumpEvents;
device->free = EPOC_DeleteDevice;
return device;
}
int GetBpp(TDisplayMode displaymode)
{
TInt numColors = TDisplayModeUtils::NumDisplayModeColors(displaymode);
TInt bitsPerPixel = 1;
for (TInt32 i = 2; i < numColors; i <<= 1, bitsPerPixel++);
return bitsPerPixel;
}
void ConstructWindowL(_THIS)
{
TInt error;
error = Private->EPOC_WsSession.Connect();
User::LeaveIfError(error);
Private->EPOC_WsScreen=new(ELeave) CWsScreenDevice(Private->EPOC_WsSession);
User::LeaveIfError(Private->EPOC_WsScreen->Construct());
User::LeaveIfError(Private->EPOC_WsScreen->CreateContext(Private->EPOC_WindowGc));
Private->EPOC_WsWindowGroup=RWindowGroup(Private->EPOC_WsSession);
User::LeaveIfError(Private->EPOC_WsWindowGroup.Construct(WindowClientHandle));
Private->EPOC_WsWindowGroup.SetOrdinalPosition(0);
//!!
TBuf<32> winGroupName;
winGroupName.Append(0);
winGroupName.Append(0);
winGroupName.Append(0);// uid
winGroupName.Append(0);
winGroupName.Append(_L("SDL")); // caption
winGroupName.Append(0);
winGroupName.Append(0); //doc name
Private->EPOC_WsWindowGroup.SetName(winGroupName); //!!
Private->EPOC_WsWindow=RWindow(Private->EPOC_WsSession);
User::LeaveIfError(Private->EPOC_WsWindow.Construct(Private->EPOC_WsWindowGroup,WindowClientHandle));
Private->EPOC_WsWindow.SetBackgroundColor(KRgbWhite);
Private->EPOC_WsWindow.Activate();
Private->EPOC_WsWindow.SetSize(Private->EPOC_WsScreen->SizeInPixels());
Private->EPOC_WsWindow.SetVisible(ETrue);
Private->EPOC_WsWindowGroupID = Private->EPOC_WsWindowGroup.Identifier();
Private->EPOC_IsWindowFocused = EFalse;
}
int EPOC_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
// !!TODO:handle leave functions!
int i;
/* Initialize all variables that we clean on shutdown */
for ( i=0; i<SDL_NUMMODES; ++i ) {
Private->SDL_modelist[i] = (SDL_Rect *)SDL_malloc(sizeof(SDL_Rect));
Private->SDL_modelist[i]->x = Private->SDL_modelist[i]->y = 0;
}
/* Modes sorted largest to smallest !!TODO:sorting order??*/
Private->SDL_modelist[0]->w = 640; Private->SDL_modelist[0]->h = 200;
Private->SDL_modelist[1]->w = 320; Private->SDL_modelist[1]->h = 200;
Private->SDL_modelist[2]->w = 640; Private->SDL_modelist[2]->h = 400;
Private->SDL_modelist[3]->w = 640; Private->SDL_modelist[3]->h = 480;
Private->SDL_modelist[4] = NULL;
/* Construct Epoc window */
ConstructWindowL(_this);
/* Initialise Epoc frame buffer */
TDisplayMode displayMode = Private->EPOC_WsScreen->DisplayMode();
#ifndef __WINS__
TScreenInfoV01 screenInfo;
TPckg<TScreenInfoV01> sInfo(screenInfo);
UserSvr::ScreenInfo(sInfo);
Private->EPOC_ScreenSize = screenInfo.iScreenSize;
Private->EPOC_DisplayMode = displayMode;
Private->EPOC_HasFrameBuffer = screenInfo.iScreenAddressValid;
Private->EPOC_FrameBuffer = Private->EPOC_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL;
Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
Private->EPOC_BytesPerScanLine = screenInfo.iScreenSize.iWidth * Private->EPOC_BytesPerPixel;
/* It seems that in SA1100 machines for 8bpp displays there is a 512 palette table at the
* beginning of the frame buffer. E.g. Series 7 and Netbook.
* In 12 bpp machines the table has 16 entries.
*/
if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 8)
Private->EPOC_FrameBuffer += 512;
if (Private->EPOC_HasFrameBuffer && GetBpp(displayMode) == 12)
Private->EPOC_FrameBuffer += 16 * 2;
#else /* defined __WINS__ */
/* Create bitmap, device and context for screen drawing */
Private->EPOC_ScreenSize = Private->EPOC_WsScreen->SizeInPixels();
Private->EPOC_Bitmap = new (ELeave) CWsBitmap(Private->EPOC_WsSession);
Private->EPOC_Bitmap->Create(Private->EPOC_ScreenSize, displayMode);
Private->EPOC_DisplayMode = displayMode;
Private->EPOC_HasFrameBuffer = ETrue;
Private->EPOC_FrameBuffer = NULL; /* Private->EPOC_Bitmap->DataAddress() can change any time */
Private->EPOC_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
Private->EPOC_BytesPerScanLine = Private->EPOC_WsScreen->SizeInPixels().iWidth * Private->EPOC_BytesPerPixel;
#endif /* __WINS__ */
_this->info.current_w = Private->EPOC_ScreenSize.iWidth;
_this->info.current_h = Private->EPOC_ScreenSize.iHeight;
/* The "best" video format should be returned to caller. */
vformat->BitsPerPixel = /*!!GetBpp(displayMode) */ 8;
vformat->BytesPerPixel = /*!!Private->EPOC_BytesPerPixel*/ 1;
/* Activate events for me */
Private->EPOC_WsEventStatus = KRequestPending;
Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
Private->EPOC_RedrawEventStatus = KRequestPending;
Private->EPOC_WsSession.RedrawReady(&Private->EPOC_RedrawEventStatus);
Private->EPOC_WsWindow.PointerFilter(EPointerFilterDrag, 0);
Private->EPOC_ScreenOffset = 0;
//!! TODO: error handling
//if (ret != KErrNone)
// return(-1);
//else
return(0);
}
SDL_Rect **EPOC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
if (format->BitsPerPixel == 12 || format->BitsPerPixel == 8)
return Private->SDL_modelist;
return NULL;
}
int EPOC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
for(int i = firstcolor; i < ncolors; i++) {
// 4k value: 000rgb
TUint16 color4K = 0;
color4K |= (colors[i].r & 0x0000f0) << 4;
color4K |= (colors[i].g & 0x0000f0);
color4K |= (colors[i].b & 0x0000f0) >> 4;
EPOC_HWPalette_256_to_4k[i] = color4K;
}
return(0);
}
SDL_Surface *EPOC_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
/* Check parameters */
if (!((width == 640 && height == 200 && bpp == 12) ||
(width == 640 && height == 400 && bpp == 12) ||
(width == 640 && height == 480 && bpp == 12) ||
(width == 320 && height == 200 && bpp == 12) ||
(width == 640 && height == 200 && bpp == 8) ||
(width == 640 && height == 400 && bpp == 8) ||
(width == 640 && height == 480 && bpp == 8) ||
(width == 320 && height == 200 && bpp == 8))) {
SDL_SetError("Requested video mode is not supported");
return NULL;
}
if (current && current->pixels) {
SDL_free(current->pixels);
current->pixels = NULL;
}
if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
return(NULL);
}
/* Set up the new mode framebuffer */
if (bpp == 8)
current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC|SDL_HWPALETTE);
else // 12 bpp
current->flags = (SDL_FULLSCREEN|SDL_SWSURFACE|SDL_PREALLOC);
current->w = width;
current->h = height;
int numBytesPerPixel = ((bpp-1)>>3) + 1;
current->pitch = numBytesPerPixel * width; // Number of bytes in scanline
current->pixels = SDL_malloc(width * height * numBytesPerPixel);
SDL_memset(current->pixels, 0, width * height * numBytesPerPixel);
/* Set the blit function */
_this->UpdateRects = EPOC_DirectUpdate;
/* Must buffer height be shrinked to screen by 2 ? */
if (current->h >= 400)
Private->EPOC_ShrinkedHeight = ETrue;
/* Centralize game window on device screen */
Private->EPOC_ScreenOffset = (Private->EPOC_ScreenSize.iWidth - current->w) / 2;
/* We're done */
return(current);
}
void RedrawWindowL(_THIS)
{
SDL_Rect fullScreen;
fullScreen.x = 0;
fullScreen.y = 0;
fullScreen.w = _this->screen->w;
fullScreen.h = _this->screen->h;
#ifdef __WINS__
TBitmapUtil lock(Private->EPOC_Bitmap);
lock.Begin(TPoint(0,0)); // Lock bitmap heap
Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
#endif
if (fullScreen.w < Private->EPOC_ScreenSize.iWidth
&& fullScreen.w < Private->EPOC_ScreenSize.iWidth) {
/* Draw blue stripes background */
#ifdef __WINS__
TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
#else
TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
#endif
for (int y=0; y < Private->EPOC_ScreenSize.iHeight; y++) {
for (int x=0; x < Private->EPOC_ScreenSize.iWidth; x++) {
TUint16 color = ((x+y)>>1) & 0xf; /* Draw pattern */
*screenBuffer++ = color;
}
}
}
/* Tell the system that something has been drawn */
TRect rect = TRect(Private->EPOC_WsWindow.Size());
Private->EPOC_WsWindow.Invalidate(rect);
#ifdef __WINS__
Private->EPOC_WsWindow.BeginRedraw(rect);
Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
Private->EPOC_WsWindow.EndRedraw();
Private->EPOC_WindowGc->Deactivate();
lock.End(); // Unlock bitmap heap
Private->EPOC_WsSession.Flush();
#endif
/* Draw current buffer */
EPOC_DirectUpdate(_this, 1, &fullScreen);
}
/* We don't actually allow hardware surfaces other than the main one */
static int EPOC_AllocHWSurface(_THIS, SDL_Surface *surface)
{
return(-1);
}
static void EPOC_FreeHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
static int EPOC_LockHWSurface(_THIS, SDL_Surface *surface)
{
return(0);
}
static void EPOC_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
static int EPOC_FlipHWSurface(_THIS, SDL_Surface *surface)
{
return(0);
}
static void EPOC_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
{
TInt focusWindowGroupId = Private->EPOC_WsSession.GetFocusWindowGroup();
if (focusWindowGroupId != Private->EPOC_WsWindowGroupID) {
/* Force focus window to redraw again for cleaning away SDL screen graphics */
TInt pos = Private->EPOC_WsWindowGroup.OrdinalPosition();
Private->EPOC_WsWindowGroup.SetOrdinalPosition(0, KMaxTInt);
TRect rect = TRect(Private->EPOC_WsWindow.Size());
Private->EPOC_WsWindow.Invalidate(rect);
Private->EPOC_WsWindowGroup.SetOrdinalPosition(pos, ECoeWinPriorityNormal);
/* If this is not the topmost window, wait here! Sleep for 1 second to give cpu to
multitasking and poll for being the topmost window.
*/
while (Private->EPOC_WsSession.GetFocusWindowGroup() != Private->EPOC_WsWindowGroupID)
SDL_Delay(1000);
RedrawWindowL(_this);
}
TInt i;
TInt sourceNumBytesPerPixel = ((_this->screen->format->BitsPerPixel-1)>>3) + 1;
TInt targetNumBytesPerPixel = Private->EPOC_BytesPerPixel;
TInt fixedOffset = Private->EPOC_ScreenOffset;
TInt screenW = _this->screen->w;
TInt screenH = _this->screen->h;
TInt sourceScanlineLength = screenW;
if (Private->EPOC_ShrinkedHeight) { /* simulate 400 pixel height in 200 pixel screen */
sourceScanlineLength <<= 1;
screenH >>= 1;
}
TInt targetScanlineLength = Private->EPOC_ScreenSize.iWidth;
#ifdef __WINS__
TBitmapUtil lock(Private->EPOC_Bitmap);
lock.Begin(TPoint(0,0)); // Lock bitmap heap
Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
TUint16* screenBuffer = (TUint16*)Private->EPOC_Bitmap->DataAddress();
#else
TUint16* screenBuffer = (TUint16*)Private->EPOC_FrameBuffer;
#endif
/* Render the rectangles in the list */
for ( i=0; i < numrects; ++i ) {
SDL_Rect rect2;
const SDL_Rect& currentRect = rects[i];
rect2.x = currentRect.x;
rect2.y = currentRect.y;
rect2.w = currentRect.w;
rect2.h = currentRect.h;
if (rect2.w <= 0 || rect2.h <= 0) /* sanity check */
continue;
if (Private->EPOC_ShrinkedHeight) { /* simulate 400 pixel height in 200 pixel screen */
rect2.y >>= 1;
if (!(rect2.h >>= 1))
rect2.h = 1; // always at least 1 pixel height!
}
/* All variables are measured in pixels */
/* Check rects validity, i.e. upper and lower bounds */
TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1);
TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1);
if (maxX < 0 || maxY < 0) /* sanity check */
continue;
maxY = Min(maxY, 199);
TInt sourceRectWidth = maxX - rect2.x + 1;
TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
TInt sourceRectHeight = maxY - rect2.y + 1;
TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
TInt targetStartOffset = fixedOffset + rect2.x + rect2.y * targetScanlineLength;
// !! Nokia9210 native mode: 12 bpp --> 12 bpp
if (_this->screen->format->BitsPerPixel == 12) {
TUint16* bitmapLine = (TUint16*)_this->screen->pixels + sourceStartOffset;
TUint16* screenMemory = screenBuffer + targetStartOffset;
for(TInt y = 0 ; y < sourceRectHeight ; y++) {
__ASSERT_DEBUG(screenMemory < (screenBuffer
+ Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight),
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(screenMemory >= screenBuffer,
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapLine < ((TUint16*)_this->screen->pixels +
+ (_this->screen->w * _this->screen->h)),
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapLine >= (TUint16*)_this->screen->pixels,
User::Panic(_L("SDL"), KErrCorrupt));
Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
// !! 256 color paletted mode: 8 bpp --> 12 bpp
else {
TUint8* bitmapLine = (TUint8*)_this->screen->pixels + sourceStartOffset;
TUint16* screenMemory = screenBuffer + targetStartOffset;
for(TInt y = 0 ; y < sourceRectHeight ; y++) {
TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
/* Convert each pixel from 256 palette to 4k color values */
for(TInt x = 0 ; x < sourceRectWidth ; x++) {
__ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer
+ (Private->EPOC_ScreenSize.iWidth * Private->EPOC_ScreenSize.iHeight)),
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer,
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos < ((TUint8*)_this->screen->pixels +
+ (_this->screen->w * _this->screen->h)),
User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos >= (TUint8*)_this->screen->pixels,
User::Panic(_L("SDL"), KErrCorrupt));
*screenMemoryLinePos = EPOC_HWPalette_256_to_4k[*bitmapPos];
bitmapPos++;
screenMemoryLinePos++;
}
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
}
#ifdef __WINS__
TRect rect = TRect(Private->EPOC_WsWindow.Size());
Private->EPOC_WsWindow.Invalidate(rect);
Private->EPOC_WsWindow.BeginRedraw(rect);
Private->EPOC_WindowGc->BitBlt(TPoint(), Private->EPOC_Bitmap);
Private->EPOC_WsWindow.EndRedraw();
Private->EPOC_WindowGc->Deactivate();
lock.End(); // Unlock bitmap heap
Private->EPOC_WsSession.Flush();
#endif
/* Update virtual cursor */
//!!Private->EPOC_WsSession.SetPointerCursorPosition(Private->EPOC_WsSession.PointerCursorPosition());
return;
}
/* Note: If we are terminated, this could be called in the middle of
another SDL video routine -- notably UpdateRects.
*/
void EPOC_VideoQuit(_THIS)
{
int i;
/* Free video mode lists */
for ( i=0; i<SDL_NUMMODES; ++i ) {
if ( Private->SDL_modelist[i] != NULL ) {
SDL_free(Private->SDL_modelist[i]);
Private->SDL_modelist[i] = NULL;
}
}
if ( _this->screen && (_this->screen->flags & SDL_HWSURFACE) ) {
/* Direct screen access, no memory buffer */
_this->screen->pixels = NULL;
}
if (_this->screen && _this->screen->pixels) {
SDL_free(_this->screen->pixels);
_this->screen->pixels = NULL;
}
/* Free Epoc resources */
/* Disable events for me */
if (Private->EPOC_WsEventStatus != KRequestPending)
Private->EPOC_WsSession.EventReadyCancel();
if (Private->EPOC_RedrawEventStatus != KRequestPending)
Private->EPOC_WsSession.RedrawReadyCancel();
#ifdef __WINS__
delete Private->EPOC_Bitmap;
Private->EPOC_Bitmap = NULL;
#endif
if (Private->EPOC_WsWindow.WsHandle())
Private->EPOC_WsWindow.Close();
if (Private->EPOC_WsWindowGroup.WsHandle())
Private->EPOC_WsWindowGroup.Close();
delete Private->EPOC_WindowGc;
Private->EPOC_WindowGc = NULL;
delete Private->EPOC_WsScreen;
Private->EPOC_WsScreen = NULL;
if (Private->EPOC_WsSession.WsHandle())
Private->EPOC_WsSession.Close();
}
WMcursor *EPOC_CreateWMCursor(_THIS, Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y)
{
return (WMcursor *) 9210; // it's ok to return something unuseful but true
}
void EPOC_FreeWMCursor(_THIS, WMcursor *cursor)
{
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
}
int EPOC_ShowWMCursor(_THIS, WMcursor *cursor)
{
if (cursor == (WMcursor *)9210) {
/* Enable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNormal);
}
else {
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
Private->EPOC_WsSession.SetPointerCursorMode(EPointerCursorNone);
}
return(1);
}
}; // extern "C"
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"
/*
SDL_epocvideo.h
Epoc based SDL video driver implementation
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
*/
#ifndef _SDL_epocvideo_h
#define _SDL_epocvideo_h
extern "C" {
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
};
#include <e32std.h>
#include <bitdev.h>
#include <w32std.h>
/* Hidden "this" pointer for the video functions */
#define _THIS SDL_VideoDevice *_this
#define Private _this->hidden
#define SDL_NUMMODES 4
/* Private display data */
struct SDL_PrivateVideoData {
SDL_Rect *SDL_modelist[SDL_NUMMODES+1];
/* Epoc window server info */
RWsSession EPOC_WsSession;
RWindowGroup EPOC_WsWindowGroup;
TInt EPOC_WsWindowGroupID;
RWindow EPOC_WsWindow;
CWsScreenDevice* EPOC_WsScreen;
CWindowGc* EPOC_WindowGc;
TRequestStatus EPOC_WsEventStatus;
TRequestStatus EPOC_RedrawEventStatus;
TWsEvent EPOC_WsEvent;
TWsRedrawEvent EPOC_RedrawEvent;
#ifdef __WINS__
CWsBitmap* EPOC_Bitmap;
#endif
TBool EPOC_IsWindowFocused; //!!Not used for anything yet!
/* Screen hardware frame buffer info */
TBool EPOC_HasFrameBuffer;
TInt EPOC_BytesPerPixel;
TInt EPOC_BytesPerScanLine;
TDisplayMode EPOC_DisplayMode;
TSize EPOC_ScreenSize;
TUint8* EPOC_FrameBuffer; /* if NULL in HW we can't do direct screen access */
TInt EPOC_ScreenOffset;
/* Simulate double screen height */
TBool EPOC_ShrinkedHeight;
};
extern "C" {
extern void RedrawWindowL(_THIS);
};
#endif /* _SDL_epocvideo_h */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment