2018-11-16 16:32:16 +03:00
|
|
|
/*
|
|
|
|
sys_win.c - win32 system utils
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "platform/platform.h"
|
2019-05-02 18:07:03 +03:00
|
|
|
#include "menu_int.h"
|
2022-04-06 16:06:16 +04:00
|
|
|
#include "server.h"
|
2019-08-09 03:07:56 +03:00
|
|
|
#include <shellapi.h>
|
2019-05-02 18:07:03 +03:00
|
|
|
|
2025-02-11 22:57:37 +03:00
|
|
|
HANDLE g_waitable_timer;
|
|
|
|
|
2018-11-16 16:32:16 +03:00
|
|
|
#if XASH_TIMER == TIMER_WIN32
|
|
|
|
double Platform_DoubleTime( void )
|
|
|
|
{
|
|
|
|
static LARGE_INTEGER g_PerformanceFrequency;
|
|
|
|
static LARGE_INTEGER g_ClockStart;
|
|
|
|
LARGE_INTEGER CurrentTime;
|
|
|
|
|
|
|
|
if( !g_PerformanceFrequency.QuadPart )
|
|
|
|
{
|
|
|
|
QueryPerformanceFrequency( &g_PerformanceFrequency );
|
|
|
|
QueryPerformanceCounter( &g_ClockStart );
|
|
|
|
}
|
|
|
|
QueryPerformanceCounter( &CurrentTime );
|
|
|
|
|
|
|
|
return (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)( g_PerformanceFrequency.QuadPart );
|
|
|
|
}
|
2024-12-04 18:32:03 +03:00
|
|
|
#endif // XASH_TIMER == TIMER_WIN32
|
2018-11-16 16:32:16 +03:00
|
|
|
|
2025-02-15 11:57:37 +03:00
|
|
|
void Win32_Init( qboolean con_showalways )
|
2025-02-11 22:57:37 +03:00
|
|
|
{
|
|
|
|
HMODULE hModule = LoadLibrary( "kernel32.dll" );
|
|
|
|
if( hModule )
|
|
|
|
{
|
|
|
|
HANDLE ( __stdcall *pfnCreateWaitableTimerExW)( LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess );
|
|
|
|
|
2025-02-15 11:57:37 +03:00
|
|
|
if(( pfnCreateWaitableTimerExW = (void *)GetProcAddress( hModule, "CreateWaitableTimerExW" )))
|
2025-02-11 22:57:37 +03:00
|
|
|
{
|
2025-02-15 11:57:37 +03:00
|
|
|
g_waitable_timer = pfnCreateWaitableTimerExW(
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0x1 /* CREATE_WAITABLE_TIMER_MANUAL_RESET */ | 0x2 /* CREATE_WAITABLE_TIMER_HIGH_RESOLUTION */,
|
|
|
|
0x0002 /* TIMER_MODIFY_STATE */ | SYNCHRONIZE | DELETE
|
|
|
|
);
|
2025-02-11 22:57:37 +03:00
|
|
|
}
|
|
|
|
|
2025-02-15 11:57:37 +03:00
|
|
|
FreeLibrary( hModule );
|
2025-02-11 22:57:37 +03:00
|
|
|
}
|
|
|
|
|
2025-02-15 11:57:37 +03:00
|
|
|
#if 0 // FIXME: creates object but doesn't wait for specific time for me on Windows 10, with the code above commented
|
2025-02-11 22:57:37 +03:00
|
|
|
if( !g_waitable_timer )
|
|
|
|
g_waitable_timer = CreateWaitableTimer( NULL, TRUE, NULL );
|
2025-02-15 11:57:37 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
Wcon_CreateConsole( con_showalways );
|
2025-02-11 22:57:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void Win32_Shutdown( void )
|
|
|
|
{
|
2025-02-15 11:57:37 +03:00
|
|
|
Wcon_DestroyConsole( );
|
|
|
|
|
2025-02-11 22:57:37 +03:00
|
|
|
if( g_waitable_timer )
|
2025-02-15 11:57:37 +03:00
|
|
|
{
|
|
|
|
CloseHandle( g_waitable_timer );
|
|
|
|
g_waitable_timer = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Win32_NanoSleep( int nsec )
|
|
|
|
{
|
2025-02-15 13:08:02 +03:00
|
|
|
LARGE_INTEGER ts;
|
2025-02-15 11:57:37 +03:00
|
|
|
|
|
|
|
if( !g_waitable_timer )
|
|
|
|
return false;
|
|
|
|
|
2025-02-15 13:08:02 +03:00
|
|
|
ts.QuadPart = { -nsec / 100 };
|
|
|
|
|
2025-02-15 11:57:37 +03:00
|
|
|
if( !SetWaitableTimer( g_waitable_timer, &ts, 0, NULL, NULL, FALSE ))
|
|
|
|
{
|
2025-02-11 22:57:37 +03:00
|
|
|
CloseHandle( g_waitable_timer );
|
2025-02-15 11:57:37 +03:00
|
|
|
g_waitable_timer = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( WaitForSingleObject( g_waitable_timer, Q_max( 1, nsec / 1000000 )) != WAIT_OBJECT_0 )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2025-02-11 22:57:37 +03:00
|
|
|
}
|
|
|
|
|
2024-02-27 05:17:01 +03:00
|
|
|
qboolean Platform_DebuggerPresent( void )
|
2018-11-16 16:32:16 +03:00
|
|
|
{
|
|
|
|
return IsDebuggerPresent();
|
|
|
|
}
|
|
|
|
|
2019-05-01 19:21:47 +03:00
|
|
|
void Platform_ShellExecute( const char *path, const char *parms )
|
|
|
|
{
|
|
|
|
if( !Q_strcmp( path, GENERIC_UPDATE_PAGE ) || !Q_strcmp( path, PLATFORM_UPDATE_PAGE ))
|
|
|
|
path = DEFAULT_UPDATE_PAGE;
|
2018-11-16 16:32:16 +03:00
|
|
|
|
2019-05-01 19:21:47 +03:00
|
|
|
ShellExecute( NULL, "open", path, parms, NULL, SW_SHOW );
|
|
|
|
}
|
2019-05-01 19:44:48 +03:00
|
|
|
|
2019-10-26 04:36:43 +03:00
|
|
|
#if XASH_MESSAGEBOX == MSGBOX_WIN32
|
2019-05-01 19:44:48 +03:00
|
|
|
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow )
|
|
|
|
{
|
|
|
|
MessageBox( parentMainWindow ? host.hWnd : NULL, message, title, MB_OK|MB_SETFOREGROUND|MB_ICONSTOP );
|
|
|
|
}
|
2019-10-26 04:36:43 +03:00
|
|
|
#endif // XASH_MESSAGEBOX == MSGBOX_WIN32
|
2024-12-24 09:59:47 +03:00
|
|
|
|