Add support for the Nokia N-Gage (#5597)

* Add initial support for the Nokia N-Gage

* N-Gage: disable clipping for the time being, issue needs to be resolved later

* Move va_copy definition to SDL_internal.h

* Move stdlib.h include to SDL_config_ngage.h, much cleaner this way

* Remove redundant include, add HAVE_STDLIB_H

* Revert "N-Gage: disable clipping for the time being, issue needs to be resolved later"

This reverts commit 4f5f0fc36cc7f34fad05e45671dfa7b8dc32fd51.

* N-Gage: fix clipping issue by providing proper math functions
This commit is contained in:
Michael Fitzmayer 2022-05-03 17:51:49 +02:00 committed by GitHub
parent 3fcc2cb500
commit fbd230bb6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1941 additions and 1 deletions

44
docs/README-ngage.md Normal file
View File

@ -0,0 +1,44 @@
Nokia N-Gage
============
SDL2 port for Symbian S60v1/2 with a main focus on the Nokia N-Gage
(Classic and QD) by [Michael Fitzmayer](https://github.com/mupfdev).
Compiling
---------
SDL is part of the [N-Gage SDK.](https://github.com/ngagesdk) project.
The library is included in the
[toolchain](https://github.com/ngagesdk/ngage-toolchain) as a
sub-module.
A complete example project based on SDL2 can be found in the GitHub
account of the SDK: [Example
project](https://github.com/ngagesdk/wordle).
Current level of implementation
-------------------------------
The video driver currently provides full screen video support with
keyboard input.
At the moment only the software renderer works.
Audio is not yet implemented.
Acknowledgements
----------------
Thanks to Hannu Viitala, Kimmo Kinnunen and Markus Mertama for the
valuable insight into Symbian programming. Without the SDL 1.2 port for
CDoom, this adaptation would not have been possible.
I would like to thank my friends
[Razvan](https://twitter.com/bewarerazvan) and [Dan
Whelan](https://danwhelan.ie/), for their continuous support. Without
you and the [N-Gage community](https://discord.gg/dbUzqJ26vs), I would
have lost my patience long ago.
Last but not least, I would like to say a special thank you to the
[EKA2L1](https://12z1.com/) team. Thank you for all your patience and
support in troubleshooting.

View File

@ -51,6 +51,7 @@ More documentation and FAQs are available online at [the wiki](http://wiki.libsd
- [Windows](README-windows.md)
- [WinRT](README-winrt.md)
- [PSVita](README-vita.md)
- [Nokia N-Gage](README-ngage.md)
If you need help with the library, or just want to discuss SDL related
issues, you can join the [SDL Discourse](https://discourse.libsdl.org/),

View File

@ -43,6 +43,8 @@
#include "SDL_config_os2.h"
#elif defined(__EMSCRIPTEN__)
#include "SDL_config_emscripten.h"
#elif defined(__NGAGE__)
#include "SDL_config_ngage.h"
#else
/* This is a minimal configuration just to get SDL running on new platforms. */
#include "SDL_config_minimal.h"

View File

@ -0,0 +1,89 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_config_ngage_h_
#define SDL_config_ngage_h_
#define SDL_config_h_
#include "SDL_platform.h"
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
typedef unsigned long uintptr_t;
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#define HAVE_STDIO_H 1
#define HAVE_STDLIB_H 1
#define HAVE_MATH_H 1
#define HAVE_CEIL 1
#define HAVE_COPYSIGN 1
#define HAVE_COS 1
#define HAVE_EXP 1
#define HAVE_FABS 1
#define HAVE_FLOOR 1
#define HAVE_LOG 1
#define HAVE_LOG10 1
#define HAVE_SCALBN 1
#define HAVE_SIN 1
#define HAVE_SQRT 1
#define HAVE_TAN 1
#define HAVE_MALLOC 1
#define SDL_MAIN_NEEDED 1
#define LACKS_SYS_MMAN_H 1
/* Enable the N-Gage thread support (src/thread/ngage/\*.c) */
#define SDL_THREAD_NGAGE 1
/* Enable the N-Gage timer support (src/timer/ngage/\*.c) */
#define SDL_TIMER_NGAGE 1
/* Enable the N=Hahe video driver (src/video/ngage/\*.c) */
#define SDL_VIDEO_DRIVER_NGAGE 1
/* Enable the dummy audio driver (src/audio/dummy/\*.c) */
#define SDL_AUDIO_DRIVER_DUMMY 1
/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */
#define SDL_JOYSTICK_DISABLED 1
/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */
#define SDL_HAPTIC_DISABLED 1
/* Enable the stub HIDAPI */
#define SDL_HIDAPI_DISABLED 1
/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */
#define SDL_SENSOR_DISABLED 1
/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */
#define SDL_LOADSO_DISABLED 1
/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */
#define SDL_FILESYSTEM_DUMMY 1
#endif /* SDL_config_ngage_h_ */

View File

@ -65,6 +65,10 @@
#undef __LINUX__ /* do we need to do this? */
#define __ANDROID__ 1
#endif
#if defined(__NGAGE__)
#undef __NGAGE__
#define __NGAGE__ 1
#endif
#if defined(__APPLE__)
/* lets us know what version of Mac OS X we're compiling on */

View File

@ -567,6 +567,8 @@ SDL_GetPlatform(void)
return "PlayStation Portable";
#elif __VITA__
return "PlayStation Vita";
#elif __NGAGE__
return "Nokia N-Gage";
#else
return "Unknown (see SDL_platform.h)";
#endif

View File

@ -27,7 +27,10 @@
#endif
/* Do our best to make sure va_copy is working */
#if defined(_MSC_VER) && _MSC_VER <= 1800
#if defined(__NGAGE__)
#undef va_copy
#define va_copy(dst, src) dst = src
#elif defined(_MSC_VER) && _MSC_VER <= 1800
/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */
#undef va_copy
#define va_copy(dst, src) dst = src

View File

@ -59,6 +59,8 @@
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
#elif defined(__VITA__)
#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
#elif defined(__NGAGE__)
#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */
#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN)
#define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */
#endif

View File

@ -0,0 +1,82 @@
/*
EPOC version (originally for SDL 1.2) by Hannu Viitala
(hannu.j.viitala@mbnet.fi).
*/
#include "../../SDL_internal.h"
/* Include the SDL main definition header */
#include "SDL_main.h"
#include <e32std.h>
#include <e32def.h>
#include <e32svr.h>
#include <e32base.h>
#include <estlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <w32std.h>
#include <apgtask.h>
#include "SDL_error.h"
extern "C" int main(int argc, char *argv[]);
TInt E32Main()
{
/* Get the clean-up stack */
CTrapCleanup* cleanup = CTrapCleanup::New();
/* Arrange for multi-threaded operation */
SpawnPosixServerThread();
/* Get args and environment */
int argc = 0;
char** argv = 0;
char** envp = 0;
__crt0(argc,argv,envp);
/* Start the application! */
/* Create stdlib */
_REENT;
/* Set process and thread priority and name */
RThread currentThread;
RProcess thisProcess;
TParse exeName;
exeName.Set(thisProcess.FileName(), NULL, NULL);
currentThread.Rename(exeName.Name());
currentThread.SetProcessPriority(EPriorityLow);
currentThread.SetPriority(EPriorityMuchLess);
/* Increase heap size */
RHeap* newHeap = NULL;
RHeap* oldHeap = NULL;
TInt heapSize = 7500000;
int ret;
newHeap = User::ChunkHeap(NULL, heapSize, heapSize, KMinHeapGrowBy);
if (NULL == newHeap)
{
ret = 3;
goto cleanup;
}
else
{
oldHeap = User::SwitchHeap(newHeap);
/* Call stdlib main */
ret = main(argc, argv);
}
cleanup:
_cleanup();
CloseSTDLIB();
delete cleanup;
return ret;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -40,6 +40,8 @@
#include "stdcpp/SDL_systhread_c.h"
#elif SDL_THREAD_OS2
#include "os2/SDL_systhread_c.h"
#elif SDL_THREAD_NGAGE
#include "ngage/SDL_systhread_c.h"
#else
#error Need thread implementation for this platform
#include "generic/SDL_systhread_c.h"

View File

@ -0,0 +1,107 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
/* An implementation of mutexes using semaphores */
#include <e32std.h>
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
struct SDL_mutex
{
TInt handle;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
static 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_LockMutex(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);
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,195 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
/* An implementation of semaphores using mutexes and condition variables */
#include <e32std.h>
#include "SDL_error.h"
#include "SDL_thread.h"
#define SDL_MUTEX_TIMEOUT -2
struct SDL_semaphore
{
TInt handle;
TInt count;
};
struct TInfo
{
TInfo(TInt aTime, TInt aHandle) :
iTime(aTime), iHandle(aHandle), iVal(0) {}
TInt iTime;
TInt iHandle;
TInt iVal;
};
extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
static TBool RunThread(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;
}
static TInt
NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
return ((RThread*)(aPtr1))->Create
(aName,
RunThread,
KDefaultStackSize,
NULL,
aPtr2);
}
static TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2)
{
TInt value = *((TInt*) aPtr2);
return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
}
static void WaitAll(SDL_sem *sem)
{
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Wait();
while(sem->count < 0)
{
sema.Wait();
}
}
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);
}
void
SDL_DestroySemaphore(SDL_sem * sem)
{
if (sem)
{
RSemaphore sema;
sema.SetHandle(sem->handle);
sema.Signal(sema.Count());
sema.Close();
delete sem;
sem = NULL;
}
}
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);
}
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;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,147 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_THREAD_NGAGE
/* N-Gage thread management routines for SDL */
#include <e32std.h>
extern "C" {
#undef NULL
#include "SDL_error.h"
#include "SDL_thread.h"
#include "../SDL_systhread.h"
#include "../SDL_thread_c.h"
};
static int object_count;
static int
RunThread(TAny* data)
{
SDL_RunThread((SDL_Thread*)data);
return(0);
}
static 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)
{
RThread rthread;
TInt status = CreateUnique(NewThread, &rthread, thread);
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(const char *name)
{
return;
}
SDL_threadID
SDL_ThreadID(void)
{
RThread current;
TThreadId id = current.Id();
return id;
}
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
return (0);
}
void
SDL_SYS_WaitThread(SDL_Thread * thread)
{
RThread t;
t.Open(thread->threadid);
if(t.ExitReason() == EExitPending)
{
TRequestStatus status;
t.Logon(status);
User::WaitForRequest(status);
}
t.Close();
}
void
SDL_SYS_DetachThread(SDL_Thread * thread)
{
return;
}
/* 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();
}
#endif /* SDL_THREAD_NGAGE */
/* vim: ts=4 sw=4
*/

View File

@ -0,0 +1,25 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
typedef int SYS_ThreadHandle;
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,100 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if defined(SDL_TIMER_NGAGE)
#include <e32std.h>
#include <e32hal.h>
#include "SDL_timer.h"
static SDL_bool ticks_started = SDL_FALSE;
static TUint start = 0;
static TInt tickPeriodMilliSeconds;
#ifdef __cplusplus
extern "C" {
#endif
void
SDL_TicksInit(void)
{
if (ticks_started)
{
return;
}
ticks_started = SDL_TRUE;
start = User::TickCount();
TTimeIntervalMicroSeconds32 period;
TInt tmp = UserHal::TickPeriod(period);
(void)tmp; /* Suppress redundant warning. */
tickPeriodMilliSeconds = period.Int() / 1000;
}
void
SDL_TicksQuit(void)
{
ticks_started = SDL_FALSE;
}
Uint64
SDL_GetTicks64(void)
{
if (! ticks_started)
{
SDL_TicksInit();
}
TUint deltaTics = User::TickCount() - start;
// Overlaps early, but should do the trick for now.
return (Uint64)(deltaTics * tickPeriodMilliSeconds);
}
Uint64
SDL_GetPerformanceCounter(void)
{
return (Uint64)User::TickCount();
}
Uint64
SDL_GetPerformanceFrequency(void)
{
return 1000000;
}
void
SDL_Delay(Uint32 ms)
{
User::After(TTimeIntervalMicroSeconds32(ms * 1000));
}
#ifdef __cplusplus
}
#endif
#endif /* SDL_TIMER_NGAGE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -457,6 +457,7 @@ extern VideoBootStrap VIVANTE_bootstrap;
extern VideoBootStrap Emscripten_bootstrap;
extern VideoBootStrap QNX_bootstrap;
extern VideoBootStrap OFFSCREEN_bootstrap;
extern VideoBootStrap NGAGE_bootstrap;
extern VideoBootStrap OS2DIVE_bootstrap;
extern VideoBootStrap OS2VMAN_bootstrap;

View File

@ -118,6 +118,9 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_OFFSCREEN
&OFFSCREEN_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_NGAGE
&NGAGE_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_OS2
&OS2DIVE_bootstrap,
&OS2VMAN_bootstrap,

View File

@ -0,0 +1,200 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_NGAGE
/* Being a ngage driver, there's no event stream. We just define stubs for
most of the API. */
#ifdef __cplusplus
extern "C" {
#endif
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#ifdef __cplusplus
}
#endif
#include "SDL_ngagevideo.h"
#include "SDL_ngageevents_c.h"
int HandleWsEvent(_THIS, const TWsEvent& aWsEvent);
void
NGAGE_PumpEvents(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
while (phdata->NGAGE_WsEventStatus != KRequestPending)
{
phdata->NGAGE_WsSession.GetEvent(phdata->NGAGE_WsEvent);
HandleWsEvent(_this, phdata->NGAGE_WsEvent);
phdata->NGAGE_WsEventStatus = KRequestPending;
phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus);
}
}
/*****************************************************************************/
/* Internal */
/*****************************************************************************/
#include <bautils.h>
#include <hal.h>
extern void DisableKeyBlocking(_THIS);
extern void RedrawWindowL(_THIS);
TBool isCursorVisible = EFalse;
static SDL_Scancode ConvertScancode(_THIS, int key)
{
SDL_Keycode keycode;
switch(key)
{
case EStdKeyBackspace: // Clear key
keycode = SDLK_BACKSPACE;
break;
case 0x31: // 1
keycode = SDLK_1;
break;
case 0x32: // 2
keycode = SDLK_2;
break;
case 0x33: // 3
keycode = SDLK_3;
break;
case 0x34: // 4
keycode = SDLK_4;
break;
case 0x35: // 5
keycode = SDLK_5;
break;
case 0x36: // 6
keycode = SDLK_6;
break;
case 0x37: // 7
keycode = SDLK_7;
break;
case 0x38: // 8
keycode = SDLK_8;
break;
case 0x39: // 9
keycode = SDLK_9;
break;
case 0x30: // 0
keycode = SDLK_0;
break;
case 0x2a: // Asterisk
keycode = SDLK_ASTERISK;
break;
case EStdKeyHash: // Hash
keycode = SDLK_SLASH;
break;
case EStdKeyDevice0: // Left softkey
keycode = SDLK_F1;
break;
case EStdKeyDevice1: // Right softkey
keycode = SDLK_F2;
break;
case EStdKeyApplication0: // Green softkey
keycode = SDLK_F3;
break;
case EStdKeyApplication1: // Red softkey
keycode = SDLK_F4;
break;
case EStdKeyDevice3: // Middle softkey
keycode = SDLK_RETURN;
break;
case EStdKeyUpArrow: // Up arrow
keycode = SDLK_UP;
break;
case EStdKeyDownArrow: // Down arrow
keycode = SDLK_DOWN;
break;
case EStdKeyLeftArrow: // Left arrow
keycode = SDLK_LEFT;
break;
case EStdKeyRightArrow: // Right arrow
keycode = SDLK_RIGHT;
break;
default:
keycode = SDLK_UNKNOWN;
break;
}
return SDL_GetScancodeFromKey(keycode);
}
int HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
int posted = 0;
switch (aWsEvent.Type())
{
case EEventKeyDown: /* Key events */
SDL_SendKeyboardKey(SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
break;
case EEventKeyUp: /* Key events */
SDL_SendKeyboardKey(SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
break;
case EEventFocusGained: /* SDL window got focus */
phdata->NGAGE_IsWindowFocused = ETrue;
/* Draw window background and screen buffer */
DisableKeyBlocking(_this); //Markus: guess why :-)
RedrawWindowL(_this);
break;
case EEventFocusLost: /* SDL window lost focus */
{
phdata->NGAGE_IsWindowFocused = EFalse;
RWsSession s;
s.Connect();
RWindowGroup g(s);
g.Construct(TUint32(&g), EFalse);
g.EnableReceiptOfFocus(EFalse);
RWindow w(s);
w.Construct(g, TUint32(&w));
w.SetExtent(TPoint(0, 0), phdata->NGAGE_WsWindow.Size());
w.SetOrdinalPosition(0);
w.Activate();
w.Close();
g.Close();
s.Close();
break;
}
case EEventModifiersChanged:
break;
default:
break;
}
return posted;
}
#endif /* SDL_VIDEO_DRIVER_NGAGE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,28 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "SDL_ngagevideo.h"
extern void NGAGE_PumpEvents(_THIS);
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,424 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_NGAGE
#include <SDL.h>
#include "../SDL_sysvideo.h"
#include "SDL_ngagevideo.h"
#include "SDL_ngageframebuffer_c.h"
#define NGAGE_SURFACE "NGAGE_FrameBuffer"
/* For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit
*
* TUint16 is enough, but using TUint32 so we can use better instruction
* selection on ARMI.
*/
static TUint32 NGAGE_HWPalette_256_to_Screen[256];
int GetBpp(TDisplayMode displaymode);
void DirectUpdate(_THIS, int numrects, SDL_Rect *rects);
void DrawBackground(_THIS);
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer);
void RedrawWindowL(_THIS);
int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
SDL_Surface *surface;
const Uint32 surface_format = SDL_PIXELFORMAT_RGB444;
int w, h;
/* Free the old framebuffer surface */
SDL_NGAGE_DestroyWindowFramebuffer(_this, window);
/* Create a new one */
SDL_GetWindowSize(window, &w, &h);
surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format);
if (! surface) {
return -1;
}
/* Save the info and return! */
SDL_SetWindowData(window, NGAGE_SURFACE, surface);
*format = surface_format;
*pixels = surface->pixels;
*pitch = surface->pitch;
/* Initialise Epoc frame buffer */
TDisplayMode displayMode = phdata->NGAGE_WsScreen->DisplayMode();
TScreenInfoV01 screenInfo;
TPckg<TScreenInfoV01> sInfo(screenInfo);
UserSvr::ScreenInfo(sInfo);
phdata->NGAGE_ScreenSize = screenInfo.iScreenSize;
phdata->NGAGE_DisplayMode = displayMode;
phdata->NGAGE_HasFrameBuffer = screenInfo.iScreenAddressValid;
phdata->NGAGE_FrameBuffer = phdata->NGAGE_HasFrameBuffer ? (TUint8*) screenInfo.iScreenAddress : NULL;
phdata->NGAGE_BytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
phdata->NGAGE_BytesPerScanLine = screenInfo.iScreenSize.iWidth * phdata->NGAGE_BytesPerPixel;
phdata->NGAGE_BytesPerScreen = phdata->NGAGE_BytesPerScanLine * phdata->NGAGE_ScreenSize.iHeight;
SDL_Log("Screen width %d", screenInfo.iScreenSize.iWidth);
SDL_Log("Screen height %d", screenInfo.iScreenSize.iHeight);
SDL_Log("Screen dmode %d", displayMode);
SDL_Log("Screen valid %d", screenInfo.iScreenAddressValid);
SDL_Log("Bytes per pixel %d", phdata->NGAGE_BytesPerPixel);
SDL_Log("Bytes per scan line %d", phdata->NGAGE_BytesPerScanLine);
SDL_Log("Bytes per screen %d", phdata->NGAGE_BytesPerScreen);
/* It seems that in SA1100 machines for 8bpp displays there is a 512
* palette table at the beginning of the frame buffer.
*
* In 12 bpp machines the table has 16 entries.
*/
if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 8)
{
phdata->NGAGE_FrameBuffer += 512;
}
else
{
phdata->NGAGE_FrameBuffer += 32;
}
/*if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 12)
phdata->NGAGE_FrameBuffer += 16 * 2;
if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 16)
phdata->NGAGE_FrameBuffer += 16 * 2;
*/
// Get draw device for updating the screen
TScreenInfoV01 screenInfo2;
NGAGE_Runtime::GetScreenInfo(screenInfo2);
TRAPD(status, phdata->NGAGE_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode));
User::LeaveIfError(status);
/* Activate events for me */
phdata->NGAGE_WsEventStatus = KRequestPending;
phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus);
SDL_Log("SDL:WsEventStatus");
User::WaitForRequest(phdata->NGAGE_WsEventStatus);
phdata->NGAGE_RedrawEventStatus = KRequestPending;
phdata->NGAGE_WsSession.RedrawReady(&phdata->NGAGE_RedrawEventStatus);
SDL_Log("SDL:RedrawEventStatus");
User::WaitForRequest(phdata->NGAGE_RedrawEventStatus);
phdata->NGAGE_WsWindow.PointerFilter(EPointerFilterDrag, 0);
phdata->NGAGE_ScreenOffset = TPoint(0, 0);
SDL_Log("SDL:DrawBackground");
DrawBackground(_this); // Clear screen
return 0;
}
int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
{
static int frame_number;
SDL_Surface *surface;
surface = (SDL_Surface *) SDL_GetWindowData(window, NGAGE_SURFACE);
if (! surface)
{
return SDL_SetError("Couldn't find ngage surface for window");
}
/* Send the data to the display */
if (SDL_getenv("SDL_VIDEO_NGAGE_SAVE_FRAMES"))
{
char file[128];
SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
(int)SDL_GetWindowID(window), ++frame_number);
SDL_SaveBMP(surface, file);
}
DirectUpdate(_this, numrects, (SDL_Rect*)rects);
return 0;
}
void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
{
SDL_Surface *surface;
surface = (SDL_Surface *) SDL_SetWindowData(window, NGAGE_SURFACE, NULL);
SDL_FreeSurface(surface);
}
/*****************************************************************************/
/* Runtime */
/*****************************************************************************/
#include <e32svr.h>
#include <hal_data.h>
#include <hal.h>
EXPORT_C void NGAGE_Runtime::GetScreenInfo(TScreenInfoV01& screenInfo2)
{
TPckg<TScreenInfoV01> sInfo2(screenInfo2);
UserSvr::ScreenInfo(sInfo2);
}
/*****************************************************************************/
/* Internal */
/*****************************************************************************/
int GetBpp(TDisplayMode displaymode)
{
return TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode);
}
void DrawBackground(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
/* Draw background */
TUint16* screenBuffer = (TUint16*)phdata->NGAGE_FrameBuffer;
/* Draw black background */
Mem::FillZ(screenBuffer, phdata->NGAGE_BytesPerScreen);
}
void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
SDL_Surface *screen = (SDL_Surface*)SDL_GetWindowData(_this->windows, NGAGE_SURFACE);
TInt i;
//const TInt sourceNumBytesPerPixel = ((screen->format->BitsPerPixel-1) >> 3) + 1;
TDisplayMode displayMode = phdata->NGAGE_DisplayMode;
const TInt sourceNumBytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
//
const TPoint fixedOffset = phdata->NGAGE_ScreenOffset;
const TInt screenW = screen->w;
const TInt screenH = screen->h;
const TInt sourceScanlineLength = screenW;
const TInt targetScanlineLength = phdata->NGAGE_ScreenSize.iWidth;
/* Render the rectangles in the list */
for (i = 0; i < numrects; ++i)
{
const SDL_Rect& currentRect = rects[i];
SDL_Rect rect2;
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;
}
/* 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;
}
/* Clip from bottom */
maxY = Min(maxY, phdata->NGAGE_ScreenSize.iHeight-1);
/* TODO: Clip from the right side */
const TInt sourceRectWidth = maxX - rect2.x + 1;
const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel;
const TInt sourceRectHeight = maxY - rect2.y + 1;
const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength;
const TUint skipValue = 1; /* 1 = No skip */
TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY +rect2.y) * targetScanlineLength;
switch (screen->format->BitsPerPixel)
{
case 12:
{
TUint16* bitmapLine = (TUint16*)screen->pixels + sourceStartOffset;
TUint16* screenMemory = screenBuffer + targetStartOffset;
if (skipValue == 1)
{
for(TInt y = 0 ; y < sourceRectHeight ; y++)
{
Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes);
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
else
{
for(TInt y = 0 ; y < sourceRectHeight ; y++)
{
TUint16* bitmapPos = bitmapLine; /* 2 bytes per pixel */
TUint16* screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */
for(TInt x = 0 ; x < sourceRectWidth ; x++)
{
__ASSERT_DEBUG(screenMemory < (screenBuffer + phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapLine < ((TUint16*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapLine >= (TUint16*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
*screenMemoryLinePos++ = *bitmapPos;
bitmapPos += skipValue;
}
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
}
break;
// 256 color paletted mode: 8 bpp --> 12 bpp
default:
{
if(phdata->NGAGE_BytesPerPixel <= 2)
{
TUint8* bitmapLine = (TUint8*)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 + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos < ((TUint8*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos >= (TUint8*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
*screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++];
}
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
else
{
TUint8* bitmapLine = (TUint8*)screen->pixels + sourceStartOffset;
TUint32* screenMemory = reinterpret_cast<TUint32*>(screenBuffer + targetStartOffset);
for(TInt y = 0 ; y < sourceRectHeight ; y++)
{
TUint8* bitmapPos = bitmapLine; /* 1 byte per pixel */
TUint32* 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 < (reinterpret_cast<TUint32*>(screenBuffer) + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast<TUint32*>(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos < ((TUint8*)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt));
__ASSERT_DEBUG(bitmapPos >= (TUint8*)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt));
*screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++];
}
bitmapLine += sourceScanlineLength;
screenMemory += targetScanlineLength;
}
}
}
}
}
}
void DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
if (! phdata->NGAGE_IsWindowFocused)
{
SDL_PauseAudio(1);
SDL_Delay(1000);
return;
}
SDL_PauseAudio(0);
TUint16* screenBuffer = (TUint16*)phdata->NGAGE_FrameBuffer;
/*if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270)
{
// ...
}
else */
{
DirectDraw(_this, numrects, rects, screenBuffer);
}
//TRect rect2 = TRect(phdata->NGAGE_WsWindow.Size());
for (int i = 0; i < numrects; ++i)
{
TInt aAx = rects[i].x;
TInt aAy = rects[i].y;
TInt aBx = rects[i].w;
TInt aBy = rects[i].h;
TRect rect2 = TRect(aAx, aAy, aBx, aBy);
phdata->NGAGE_DrawDevice->UpdateRegion(rect2); /* Should we update rects parameter area only?? */
phdata->NGAGE_DrawDevice->Update();
}
}
void RedrawWindowL(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
SDL_Surface *screen = (SDL_Surface*)SDL_GetWindowData(_this->windows, NGAGE_SURFACE);
int w = screen->w;
int h = screen->h;
if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
w = screen->h;
h = screen->w;
}
if ((w < phdata->NGAGE_ScreenSize.iWidth)
|| (h < phdata->NGAGE_ScreenSize.iHeight)) {
DrawBackground(_this);
}
/* Tell the system that something has been drawn */
TRect rect = TRect(phdata->NGAGE_WsWindow.Size());
phdata->NGAGE_WsWindow.Invalidate(rect);
/* Draw current buffer */
SDL_Rect fullScreen;
fullScreen.x = 0;
fullScreen.y = 0;
fullScreen.w = screen->w;
fullScreen.h = screen->h;
DirectUpdate(_this, 1, &fullScreen);
}
#endif /* SDL_VIDEO_DRIVER_NGAGE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,38 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
extern int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
extern int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
extern void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
/****************************************************************************/
/* Runtime */
/****************************************************************************/
class NGAGE_Runtime
{
public:
IMPORT_C static void GetScreenInfo(TScreenInfoV01& screenInfo2);
};
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,192 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include <stdlib.h>
#ifdef NULL
#undef NULL
#endif
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_NGAGE
#ifdef __cplusplus
extern "C" {
#endif
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#ifdef __cplusplus
}
#endif
#include "SDL_ngagevideo.h"
#include "SDL_ngagewindow.h"
#include "SDL_ngageevents_c.h"
#include "SDL_ngageframebuffer_c.h"
#define NGAGEVID_DRIVER_NAME "ngage"
/* Initialization/Query functions */
static int NGAGE_VideoInit(_THIS);
static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
static void NGAGE_VideoQuit(_THIS);
/* NGAGE driver bootstrap functions */
static void
NGAGE_DeleteDevice(SDL_VideoDevice * device)
{
SDL_VideoData *phdata = (SDL_VideoData*)device->driverdata;
if (phdata)
{
/* Free Epoc resources */
/* Disable events for me */
if (phdata->NGAGE_WsEventStatus != KRequestPending)
{
phdata->NGAGE_WsSession.EventReadyCancel();
}
if (phdata->NGAGE_RedrawEventStatus != KRequestPending)
{
phdata->NGAGE_WsSession.RedrawReadyCancel();
}
free(phdata->NGAGE_DrawDevice);
if (phdata->NGAGE_WsWindow.WsHandle())
{
phdata->NGAGE_WsWindow.Close();
}
if (phdata->NGAGE_WsWindowGroup.WsHandle())
{
phdata->NGAGE_WsWindowGroup.Close();
}
delete phdata->NGAGE_WindowGc;
phdata->NGAGE_WindowGc = NULL;
delete phdata->NGAGE_WsScreen;
phdata->NGAGE_WsScreen = NULL;
if (phdata->NGAGE_WsSession.WsHandle())
{
phdata->NGAGE_WsSession.Close();
}
SDL_free(phdata);
phdata = NULL;
}
if (device)
{
SDL_free(device);
device = NULL;
}
}
static SDL_VideoDevice *
NGAGE_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
SDL_VideoData *phdata;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return (0);
}
/* Initialize internal N-Gage specific data */
phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (! phdata)
{
SDL_OutOfMemory();
SDL_free(device);
return (0);
}
/* General video */
device->VideoInit = NGAGE_VideoInit;
device->VideoQuit = NGAGE_VideoQuit;
device->SetDisplayMode = NGAGE_SetDisplayMode;
device->PumpEvents = NGAGE_PumpEvents;
device->CreateWindowFramebuffer = SDL_NGAGE_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = SDL_NGAGE_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = SDL_NGAGE_DestroyWindowFramebuffer;
device->free = NGAGE_DeleteDevice;
/* "Window" */
device->CreateSDLWindow = NGAGE_CreateWindow;
device->DestroyWindow = NGAGE_DestroyWindow;
/* N-Gage specific data */
device->driverdata = phdata;
return device;
}
VideoBootStrap NGAGE_bootstrap = {
NGAGEVID_DRIVER_NAME, "SDL ngage video driver",
NGAGE_CreateDevice
};
int
NGAGE_VideoInit(_THIS)
{
SDL_DisplayMode mode;
/* Use 12-bpp desktop mode */
mode.format = SDL_PIXELFORMAT_RGB444;
mode.w = 176;
mode.h = 208;
mode.refresh_rate = 0;
mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
}
SDL_zero(mode);
SDL_AddDisplayMode(&_this->displays[0], &mode);
/* We're done! */
return 0;
}
static int
NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
return 0;
}
void
NGAGE_VideoQuit(_THIS)
{
}
#endif /* SDL_VIDEO_DRIVER_NGAGE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,75 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef _SDL_ngagevideo_h
#define _SDL_ngagevideo_h
#include "../SDL_sysvideo.h"
#include <e32std.h>
#include <e32svr.h>
#include <bitdev.h>
#include <w32std.h>
#include <bitdraw.h> // CFbsDrawDevice
#define _THIS SDL_VideoDevice *_this
typedef struct SDL_VideoData
{
/* Epoc window server info */
RWsSession NGAGE_WsSession;
RWindowGroup NGAGE_WsWindowGroup;
TInt NGAGE_WsWindowGroupID;
RWindow NGAGE_WsWindow;
CWsScreenDevice* NGAGE_WsScreen;
CWindowGc* NGAGE_WindowGc;
TRequestStatus NGAGE_WsEventStatus;
TRequestStatus NGAGE_RedrawEventStatus;
TWsEvent NGAGE_WsEvent;
//TWsRedrawEvent NGAGE_RedrawEvent;
CFbsDrawDevice* NGAGE_DrawDevice;
TBool NGAGE_IsWindowFocused; /* Not used yet */
/* Screen hardware frame buffer info */
TBool NGAGE_HasFrameBuffer;
TInt NGAGE_BytesPerPixel;
TInt NGAGE_BytesPerScanLine;
TInt NGAGE_BytesPerScreen;
TDisplayMode NGAGE_DisplayMode;
TSize NGAGE_ScreenSize;
TUint8* NGAGE_FrameBuffer;
TPoint NGAGE_ScreenOffset;
CFbsBitGc::TGraphicsOrientation NGAGE_ScreenOrientation;
/* Simulate double screen height */
//TInt NGAGE_ScreenXScaleValue;
//TInt NGAGE_ScreenYScaleValue;
} SDL_VideoData;
#endif /* _SDL_ngagevideo_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,129 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_NGAGE
#include "../SDL_sysvideo.h"
#include "SDL_ngagewindow.h"
const TUint32 WindowClientHandle = 9210;
void DisableKeyBlocking(_THIS);
void ConstructWindowL(_THIS);
int
NGAGE_CreateWindow(_THIS, SDL_Window* window)
{
NGAGE_Window* ngage_window = (NGAGE_Window*)SDL_calloc(1, sizeof(NGAGE_Window));
if (!ngage_window) {
return SDL_OutOfMemory();
}
window->driverdata = ngage_window;
if (window->x == SDL_WINDOWPOS_UNDEFINED) {
window->x = 0;
}
if (window->y == SDL_WINDOWPOS_UNDEFINED) {
window->y = 0;
}
ngage_window->sdl_window = window;
ConstructWindowL(_this);
return 0;
}
void
NGAGE_DestroyWindow(_THIS, SDL_Window* window)
{
NGAGE_Window* ngage_window = (NGAGE_Window*)window->driverdata;
if (ngage_window) {
SDL_free(ngage_window);
}
window->driverdata = NULL;
}
/*****************************************************************************/
/* Internal */
/*****************************************************************************/
void DisableKeyBlocking(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
TRawEvent event;
event.Set((TRawEvent::TType) /*EDisableKeyBlock*/ 51);
phdata->NGAGE_WsSession.SimulateRawEvent(event);
}
void ConstructWindowL(_THIS)
{
SDL_VideoData *phdata = (SDL_VideoData*)_this->driverdata;
TInt error;
error = phdata->NGAGE_WsSession.Connect();
User::LeaveIfError(error);
phdata->NGAGE_WsScreen=new(ELeave) CWsScreenDevice(phdata->NGAGE_WsSession);
User::LeaveIfError(phdata->NGAGE_WsScreen->Construct());
User::LeaveIfError(phdata->NGAGE_WsScreen->CreateContext(phdata->NGAGE_WindowGc));
phdata->NGAGE_WsWindowGroup=RWindowGroup(phdata->NGAGE_WsSession);
User::LeaveIfError(phdata->NGAGE_WsWindowGroup.Construct(WindowClientHandle));
phdata->NGAGE_WsWindowGroup.SetOrdinalPosition(0);
RProcess thisProcess;
TParse exeName;
exeName.Set(thisProcess.FileName(), NULL, NULL);
TBuf<32> winGroupName;
winGroupName.Append(0);
winGroupName.Append(0);
winGroupName.Append(0); // UID
winGroupName.Append(0);
winGroupName.Append(exeName.Name()); // Caption
winGroupName.Append(0);
winGroupName.Append(0); // DOC name
phdata->NGAGE_WsWindowGroup.SetName(winGroupName);
phdata->NGAGE_WsWindow=RWindow(phdata->NGAGE_WsSession);
User::LeaveIfError(phdata->NGAGE_WsWindow.Construct(phdata->NGAGE_WsWindowGroup,WindowClientHandle - 1));
phdata->NGAGE_WsWindow.SetBackgroundColor(KRgbWhite);
phdata->NGAGE_WsWindow.Activate();
phdata->NGAGE_WsWindow.SetSize(phdata->NGAGE_WsScreen->SizeInPixels());
phdata->NGAGE_WsWindow.SetVisible(ETrue);
phdata->NGAGE_WsWindowGroupID = phdata->NGAGE_WsWindowGroup.Identifier();
phdata->NGAGE_IsWindowFocused = EFalse;
DisableKeyBlocking(_this);
}
#endif /* SDL_VIDEO_DRIVER_NGAGE */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SDL_ngagewindow_h
#define _SDL_ngagewindow_h
#include "../SDL_sysvideo.h"
#include "SDL_syswm.h"
#include "SDL_ngagevideo.h"
typedef struct {
SDL_Window* sdl_window;
} NGAGE_Window;
extern int
NGAGE_CreateWindow(_THIS, SDL_Window* window);
extern void
NGAGE_DestroyWindow(_THIS, SDL_Window* window);
#endif /* _SDL_ngagewindow */
/* vi: set ts=4 sw=4 expandtab: */