You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
9.0 KiB
355 lines
9.0 KiB
/* |
|
platform.h - common platform-dependent function defines |
|
Copyright (C) 2018 a1batross |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
*/ |
|
|
|
#pragma once |
|
#ifndef PLATFORM_H |
|
#define PLATFORM_H |
|
|
|
#include "common.h" |
|
#include "system.h" |
|
#include "defaults.h" |
|
#include "cursor_type.h" |
|
#include "key_modifiers.h" |
|
|
|
/* |
|
============================================================================== |
|
|
|
SYSTEM UTILS |
|
|
|
============================================================================== |
|
*/ |
|
double Platform_DoubleTime( void ); |
|
void Platform_Sleep( int msec ); |
|
void Platform_ShellExecute( const char *path, const char *parms ); |
|
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow ); |
|
void Platform_SetStatus( const char *status ); |
|
qboolean Platform_DebuggerPresent( void ); |
|
|
|
// legacy iOS port functions |
|
#if TARGET_OS_IOS |
|
const char *IOS_GetDocsDir( void ); |
|
void IOS_LaunchDialog( void ); |
|
#endif // TARGET_OS_IOS |
|
|
|
#if XASH_WIN32 || XASH_LINUX |
|
#define XASH_PLATFORM_HAVE_STATUS 1 |
|
#else |
|
#undef XASH_PLATFORM_HAVE_STATUS |
|
#endif |
|
|
|
#if XASH_POSIX |
|
void Posix_Daemonize( void ); |
|
#endif |
|
|
|
#if XASH_SDL |
|
void SDLash_Init( void ); |
|
void SDLash_Shutdown( void ); |
|
#endif |
|
|
|
#if XASH_ANDROID |
|
const char *Android_GetAndroidID( void ); |
|
const char *Android_LoadID( void ); |
|
void Android_SaveID( const char *id ); |
|
void Android_Init( void ); |
|
void *Android_GetNativeObject( const char *name ); |
|
int Android_GetKeyboardHeight( void ); |
|
void Android_Shutdown( void ); |
|
#endif |
|
|
|
#if XASH_WIN32 |
|
void Wcon_CreateConsole( void ); |
|
void Wcon_DestroyConsole( void ); |
|
#endif |
|
|
|
#if XASH_NSWITCH |
|
void NSwitch_Init( void ); |
|
void NSwitch_Shutdown( void ); |
|
#endif |
|
|
|
#if XASH_PSVITA |
|
void PSVita_Init( void ); |
|
void PSVita_Shutdown( void ); |
|
qboolean PSVita_GetBasePath( char *buf, const size_t buflen ); |
|
int PSVita_GetArgv( int in_argc, char **in_argv, char ***out_argv ); |
|
void PSVita_InputUpdate( void ); |
|
#endif |
|
|
|
#if XASH_DOS |
|
void DOS_Init( void ); |
|
void DOS_Shutdown( void ); |
|
#endif |
|
|
|
#if XASH_LINUX |
|
void Linux_Init( void ); |
|
void Linux_Shutdown( void ); |
|
void Linux_SetTimer( float time ); |
|
#endif |
|
|
|
static inline void Platform_Init( void ) |
|
{ |
|
#if XASH_POSIX |
|
// daemonize as early as possible, because we need to close our file descriptors |
|
Posix_Daemonize( ); |
|
#endif |
|
|
|
#if XASH_SDL |
|
SDLash_Init( ); |
|
#endif |
|
|
|
#if XASH_ANDROID |
|
Android_Init( ); |
|
#elif XASH_NSWITCH |
|
NSwitch_Init( ); |
|
#elif XASH_PSVITA |
|
PSVita_Init( ); |
|
#elif XASH_DOS |
|
DOS_Init( ); |
|
#elif XASH_WIN32 |
|
Wcon_CreateConsole( ); |
|
#elif XASH_LINUX |
|
Linux_Init( ); |
|
#endif |
|
} |
|
|
|
static inline void Platform_Shutdown( void ) |
|
{ |
|
#if XASH_NSWITCH |
|
NSwitch_Shutdown( ); |
|
#elif XASH_PSVITA |
|
PSVita_Shutdown( ); |
|
#elif XASH_DOS |
|
DOS_Shutdown( ); |
|
#elif XASH_WIN32 |
|
Wcon_DestroyConsole( ); |
|
#elif XASH_LINUX |
|
Linux_Shutdown( ); |
|
#endif |
|
|
|
#if XASH_SDL |
|
SDLash_Shutdown( ); |
|
#endif |
|
} |
|
|
|
static inline qboolean Sys_DebuggerPresent( void ) |
|
{ |
|
#if XASH_LINUX || XASH_WIN32 |
|
return Platform_DebuggerPresent(); |
|
#else |
|
return false; |
|
#endif |
|
} |
|
|
|
/* |
|
============================================================================== |
|
|
|
MOBILE API |
|
|
|
============================================================================== |
|
*/ |
|
void Platform_Vibrate( float life, char flags ); |
|
|
|
/* |
|
============================================================================== |
|
|
|
INPUT |
|
|
|
============================================================================== |
|
*/ |
|
// Gamepad support |
|
int Platform_JoyInit( int numjoy ); // returns number of connected gamepads, negative if error |
|
// Text input |
|
void Platform_EnableTextInput( qboolean enable ); |
|
key_modifier_t Platform_GetKeyModifiers( void ); |
|
// System events |
|
void Platform_RunEvents( void ); |
|
// Mouse |
|
void Platform_GetMousePos( int *x, int *y ); |
|
void Platform_SetMousePos( int x, int y ); |
|
void Platform_PreCreateMove( void ); |
|
void Platform_MouseMove( float *x, float *y ); |
|
void Platform_SetCursorType( VGUI_DefaultCursor type ); |
|
// Clipboard |
|
int Platform_GetClipboardText( char *buffer, size_t size ); |
|
void Platform_SetClipboardText( const char *buffer ); |
|
|
|
#if XASH_SDL == 12 |
|
#define SDL_SetWindowGrab( wnd, state ) SDL_WM_GrabInput( (state) ) |
|
#define SDL_MinimizeWindow( wnd ) SDL_WM_IconifyWindow() |
|
#define SDL_IsTextInputActive() host.textmode |
|
#endif |
|
|
|
#if !XASH_SDL |
|
#define SDL_VERSION_ATLEAST( x, y, z ) 0 |
|
#endif |
|
|
|
static inline void Platform_SetTimer( float time ) |
|
{ |
|
#if XASH_LINUX |
|
Linux_SetTimer( time ); |
|
#endif |
|
} |
|
|
|
/* |
|
============================================================================== |
|
|
|
WINDOW MANAGEMENT |
|
|
|
============================================================================== |
|
*/ |
|
typedef enum |
|
{ |
|
rserr_ok, |
|
rserr_invalid_fullscreen, |
|
rserr_invalid_mode, |
|
rserr_unknown |
|
} rserr_t; |
|
|
|
struct vidmode_s; |
|
typedef enum window_mode_e window_mode_t; |
|
// Window |
|
qboolean R_Init_Video( const int type ); |
|
void R_Free_Video( void ); |
|
qboolean VID_SetMode( void ); |
|
rserr_t R_ChangeDisplaySettings( int width, int height, window_mode_t window_mode ); |
|
int R_MaxVideoModes( void ); |
|
struct vidmode_s *R_GetVideoMode( int num ); |
|
void* GL_GetProcAddress( const char *name ); // RenderAPI requirement |
|
void GL_UpdateSwapInterval( void ); |
|
int GL_SetAttribute( int attr, int val ); |
|
int GL_GetAttribute( int attr, int *val ); |
|
void GL_SwapBuffers( void ); |
|
void *SW_LockBuffer( void ); |
|
void SW_UnlockBuffer( void ); |
|
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b ); |
|
|
|
|
|
// |
|
// in_evdev.c |
|
// |
|
#if XASH_USE_EVDEV |
|
void Evdev_SetGrab( qboolean grab ); |
|
void Evdev_Shutdown( void ); |
|
void Evdev_Init( void ); |
|
void IN_EvdevMove( float *yaw, float *pitch ); |
|
void IN_EvdevFrame ( void ); |
|
#endif // XASH_USE_EVDEV |
|
/* |
|
============================================================================== |
|
|
|
AUDIO INPUT/OUTPUT |
|
|
|
============================================================================== |
|
*/ |
|
// initializes cycling through a DMA buffer and returns information on it |
|
qboolean SNDDMA_Init( void ); |
|
void SNDDMA_Shutdown( void ); |
|
void SNDDMA_BeginPainting( void ); |
|
void SNDDMA_Submit( void ); |
|
void SNDDMA_Activate( qboolean active ); // pause audio |
|
// void SNDDMA_PrintDeviceName( void ); // unused |
|
// void SNDDMA_LockSound( void ); // unused |
|
// void SNDDMA_UnlockSound( void ); // unused |
|
|
|
qboolean VoiceCapture_Init( void ); |
|
void VoiceCapture_Shutdown( void ); |
|
qboolean VoiceCapture_Activate( qboolean activate ); |
|
qboolean VoiceCapture_Lock( qboolean lock ); |
|
|
|
// this allows to make break in current line, without entering libc code |
|
// libc built with -fomit-frame-pointer may just eat stack frame (hello, glibc), making entering libc even more useless |
|
// calling syscalls directly allows to make break like if it was asm("int $3") on x86 |
|
#if XASH_LINUX && XASH_X86 |
|
#define INLINE_RAISE(x) asm volatile( "int $3;" ); |
|
#define INLINE_NANOSLEEP1() // nothing! |
|
#elif XASH_LINUX && XASH_ARM && !XASH_64BIT |
|
#define INLINE_RAISE(x) do \ |
|
{ \ |
|
int raise_pid = getpid(); \ |
|
int raise_tid = gettid(); \ |
|
int raise_sig = (x); \ |
|
__asm__ volatile ( \ |
|
"mov r7,#268\n\t" \ |
|
"mov r0,%0\n\t" \ |
|
"mov r1,%1\n\t" \ |
|
"mov r2,%2\n\t" \ |
|
"svc 0\n\t" \ |
|
: \ |
|
: "r"(raise_pid), "r"(raise_tid), "r"(raise_sig) \ |
|
: "r0", "r1", "r2", "r7", "memory" \ |
|
); \ |
|
} while( 0 ) |
|
#define INLINE_NANOSLEEP1() do \ |
|
{ \ |
|
struct timespec ns_t1 = {1, 0}; \ |
|
struct timespec ns_t2 = {0, 0}; \ |
|
__asm__ volatile ( \ |
|
"mov r7,#162\n\t" \ |
|
"mov r0,%0\n\t" \ |
|
"mov r1,%1\n\t" \ |
|
"svc 0\n\t" \ |
|
: \ |
|
: "r"(&ns_t1), "r"(&ns_t2) \ |
|
: "r0", "r1", "r7", "memory" \ |
|
); \ |
|
} while( 0 ) |
|
#elif XASH_LINUX && XASH_ARM && XASH_64BIT |
|
#define INLINE_RAISE(x) do \ |
|
{ \ |
|
int raise_pid = getpid(); \ |
|
int raise_tid = gettid(); \ |
|
int raise_sig = (x); \ |
|
__asm__ volatile ( \ |
|
"mov x8,#131\n\t" \ |
|
"mov x0,%0\n\t" \ |
|
"mov x1,%1\n\t" \ |
|
"mov x2,%2\n\t" \ |
|
"svc 0\n\t" \ |
|
: \ |
|
: "r"(raise_pid), "r"(raise_tid), "r"(raise_sig) \ |
|
: "x0", "x1", "x2", "x8", "memory", "cc" \ |
|
); \ |
|
} while( 0 ) |
|
#define INLINE_NANOSLEEP1() do \ |
|
{ \ |
|
struct timespec ns_t1 = {1, 0}; \ |
|
struct timespec ns_t2 = {0, 0}; \ |
|
__asm__ volatile ( \ |
|
"mov x8,#101\n\t" \ |
|
"mov x0,%0\n\t" \ |
|
"mov x1,%1\n\t" \ |
|
"svc 0\n\t" \ |
|
: \ |
|
: "r"(&ns_t1), "r"(&ns_t2) \ |
|
: "x0", "x1", "x8", "memory", "cc" \ |
|
); \ |
|
} while( 0 ) |
|
#elif XASH_LINUX |
|
#ifdef __NR_tgkill |
|
#define INLINE_RAISE(x) syscall( __NR_tgkill, getpid(), gettid(), x ) |
|
#else // __NR_tgkill |
|
#define INLINE_RAISE(x) raise(x) |
|
#endif // __NR_tgkill |
|
#define INLINE_NANOSLEEP1() do \ |
|
{ \ |
|
struct timespec ns_t1 = {1, 0}; \ |
|
struct timespec ns_t2 = {0, 0}; \ |
|
nanosleep( &ns_t1, &ns_t2 ); \ |
|
} while( 0 ) |
|
#else // generic |
|
#define INLINE_RAISE(x) raise(x) |
|
#define INLINE_NANOSLEEP1() sleep(1) |
|
#endif // generic |
|
|
|
#endif // PLATFORM_H
|
|
|