mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +00:00 
			
		
		
		
	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 4f5f0fc36c.
* N-Gage: fix clipping issue by providing proper math functions
			
			
This commit is contained in:
		 Michael Fitzmayer
					Michael Fitzmayer
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							3fcc2cb500
						
					
				
				
					commit
					fbd230bb6c
				
			
							
								
								
									
										44
									
								
								docs/README-ngage.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								docs/README-ngage.md
									
									
									
									
									
										Normal 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. | ||||
| @@ -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/), | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
							
								
								
									
										89
									
								
								include/SDL_config_ngage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								include/SDL_config_ngage.h
									
									
									
									
									
										Normal 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_ */ | ||||
| @@ -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 */ | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										82
									
								
								src/main/ngage/SDL_ngage_main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/main/ngage/SDL_ngage_main.cpp
									
									
									
									
									
										Normal 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: */ | ||||
| @@ -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" | ||||
|   | ||||
							
								
								
									
										107
									
								
								src/thread/ngage/SDL_sysmutex.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/thread/ngage/SDL_sysmutex.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										195
									
								
								src/thread/ngage/SDL_syssem.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								src/thread/ngage/SDL_syssem.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										147
									
								
								src/thread/ngage/SDL_systhread.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/thread/ngage/SDL_systhread.cpp
									
									
									
									
									
										Normal 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 | ||||
|  */ | ||||
							
								
								
									
										25
									
								
								src/thread/ngage/SDL_systhread_c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/thread/ngage/SDL_systhread_c.h
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										100
									
								
								src/timer/ngage/SDL_systimer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/timer/ngage/SDL_systimer.cpp
									
									
									
									
									
										Normal 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: */ | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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, | ||||
|   | ||||
							
								
								
									
										200
									
								
								src/video/ngage/SDL_ngageevents.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								src/video/ngage/SDL_ngageevents.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										28
									
								
								src/video/ngage/SDL_ngageevents_c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/video/ngage/SDL_ngageevents_c.h
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										424
									
								
								src/video/ngage/SDL_ngageframebuffer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										424
									
								
								src/video/ngage/SDL_ngageframebuffer.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										38
									
								
								src/video/ngage/SDL_ngageframebuffer_c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/video/ngage/SDL_ngageframebuffer_c.h
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										192
									
								
								src/video/ngage/SDL_ngagevideo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								src/video/ngage/SDL_ngagevideo.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										75
									
								
								src/video/ngage/SDL_ngagevideo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/video/ngage/SDL_ngagevideo.h
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										129
									
								
								src/video/ngage/SDL_ngagewindow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/video/ngage/SDL_ngagewindow.cpp
									
									
									
									
									
										Normal 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: */ | ||||
							
								
								
									
										45
									
								
								src/video/ngage/SDL_ngagewindow.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/video/ngage/SDL_ngagewindow.h
									
									
									
									
									
										Normal 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: */ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user