mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-26 04:05:53 +01:00
Fix up some mismerges and get the OpenGL code to compile again.
This commit is contained in:
parent
c2be372822
commit
2668cdc44f
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <Engine/Base/ListIterator.inl>
|
#include <Engine/Base/ListIterator.inl>
|
||||||
|
|
||||||
|
BOOL _TBCapability = FALSE;
|
||||||
|
|
||||||
extern INDEX ogl_iTBufferEffect;
|
extern INDEX ogl_iTBufferEffect;
|
||||||
extern INDEX ogl_iTBufferSamples;
|
extern INDEX ogl_iTBufferSamples;
|
||||||
|
@ -329,7 +330,6 @@ void CGfxLibrary::InitContext_OGL(void)
|
||||||
OGL_CHECKERROR;
|
OGL_CHECKERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PLATFORM_WIN32
|
|
||||||
// if T-buffer is supported
|
// if T-buffer is supported
|
||||||
if( _TBCapability) {
|
if( _TBCapability) {
|
||||||
// add extension and disable t-buffer usage by default
|
// add extension and disable t-buffer usage by default
|
||||||
|
@ -337,7 +337,6 @@ void CGfxLibrary::InitContext_OGL(void)
|
||||||
pglDisable( GL_MULTISAMPLE_3DFX);
|
pglDisable( GL_MULTISAMPLE_3DFX);
|
||||||
OGL_CHECKERROR;
|
OGL_CHECKERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// test for clamp to edge
|
// test for clamp to edge
|
||||||
TestExtension_OGL( GLF_EXT_EDGECLAMP, "GL_EXT_texture_edge_clamp");
|
TestExtension_OGL( GLF_EXT_EDGECLAMP, "GL_EXT_texture_edge_clamp");
|
||||||
|
@ -440,69 +439,6 @@ void CGfxLibrary::InitContext_OGL(void)
|
||||||
if( shd_bCacheAll) CacheShadows();
|
if( shd_bCacheAll) CacheShadows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// initialize OpenGL driver
|
|
||||||
BOOL CGfxLibrary::InitDriver_OGL( BOOL b3Dfx/*=FALSE*/)
|
|
||||||
{
|
|
||||||
ASSERT( gl_hiDriver==NONE);
|
|
||||||
UINT iOldErrorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
|
|
||||||
CTString strDriverFileName = b3Dfx ? "3DFXVGL.DLL" : "OPENGL32.DLL";
|
|
||||||
|
|
||||||
try
|
|
||||||
{ // if driver doesn't exists on disk
|
|
||||||
char strBuffer[_MAX_PATH+1];
|
|
||||||
char *strDummy;
|
|
||||||
int iRes = SearchPathA( NULL, strDriverFileName, NULL, _MAX_PATH, strBuffer, &strDummy);
|
|
||||||
if( iRes==0) ThrowF_t(TRANS("OpenGL driver '%s' not present"), strDriverFileName);
|
|
||||||
|
|
||||||
// load opengl library
|
|
||||||
gl_hiDriver = ::LoadLibraryA( strDriverFileName);
|
|
||||||
// if it cannot be loaded (although it is present on disk)
|
|
||||||
if( gl_hiDriver==NONE) {
|
|
||||||
// if it is 3dfx stand-alone driver
|
|
||||||
if( b3Dfx) {
|
|
||||||
// do a fatal error and inform user to deinstall it,
|
|
||||||
// since this loading attempt probably messed up the entire system
|
|
||||||
FatalError(TRANS( "3Dfx OpenGL driver '%s' is installed, but cannot be loaded!\n"
|
|
||||||
"If you previously had a 3Dfx card and it was removed,\n"
|
|
||||||
"please deinstall the driver and restart windows before\n"
|
|
||||||
"continuing.\n"), strDriverFileName);
|
|
||||||
} // fail!
|
|
||||||
ThrowF_t(TRANS("Cannot load OpenGL driver '%s'"), strDriverFileName);
|
|
||||||
}
|
|
||||||
// prepare functions
|
|
||||||
OGL_SetFunctionPointers_t(gl_hiDriver);
|
|
||||||
}
|
|
||||||
catch( char *strError)
|
|
||||||
{ // didn't make it :(
|
|
||||||
if( gl_hiDriver!=NONE) FreeLibrary(gl_hiDriver);
|
|
||||||
gl_hiDriver = NONE;
|
|
||||||
CPrintF( TRANS("Error starting OpenGL: %s\n"), strError);
|
|
||||||
SetErrorMode(iOldErrorMode);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// revert to old error mode
|
|
||||||
SetErrorMode(iOldErrorMode);
|
|
||||||
|
|
||||||
// if default driver
|
|
||||||
if( !b3Dfx) {
|
|
||||||
// use GDI functions
|
|
||||||
pwglSwapBuffers = ::SwapBuffers;
|
|
||||||
pwglSetPixelFormat = ::SetPixelFormat;
|
|
||||||
pwglChoosePixelFormat = ::ChoosePixelFormat;
|
|
||||||
// NOTE:
|
|
||||||
// some ICD implementations are not infact in OPENGL32.DLL, but in some
|
|
||||||
// other installed DLL, which is loaded when original OPENGL32.DLL from MS is
|
|
||||||
// loaded. For those, we in fact load OPENGL32.DLL from MS, so we must _not_
|
|
||||||
// call these functions directly, because they are in MS dll. We must call
|
|
||||||
// functions from GDI, which in turn call either OPENGL32.DLL, _or_ the client driver,
|
|
||||||
// as appropriate.
|
|
||||||
}
|
|
||||||
// done
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ClearFunctionPointers(void)
|
static void ClearFunctionPointers(void)
|
||||||
{
|
{
|
||||||
// clear gl function pointers
|
// clear gl function pointers
|
||||||
|
@ -526,6 +462,10 @@ void CGfxLibrary::EndDriver_OGL(void)
|
||||||
gfxDeleteTexture( _fog_ulTexture);
|
gfxDeleteTexture( _fog_ulTexture);
|
||||||
gfxDeleteTexture( _haze_ulTexture);
|
gfxDeleteTexture( _haze_ulTexture);
|
||||||
|
|
||||||
|
ASSERT( _ptdFlat!=NULL);
|
||||||
|
_ptdFlat->td_tpLocal.Clear();
|
||||||
|
_ptdFlat->Unbind();
|
||||||
|
|
||||||
PlatformEndDriver_OGL();
|
PlatformEndDriver_OGL();
|
||||||
ClearFunctionPointers();
|
ClearFunctionPointers();
|
||||||
}
|
}
|
||||||
|
@ -535,8 +475,6 @@ void CGfxLibrary::EndDriver_OGL(void)
|
||||||
/*
|
/*
|
||||||
* 3dfx t-buffer control
|
* 3dfx t-buffer control
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
extern void SetTBufferEffect( BOOL bEnable)
|
extern void SetTBufferEffect( BOOL bEnable)
|
||||||
{
|
{
|
||||||
// adjust console vars
|
// adjust console vars
|
||||||
|
|
|
@ -7,7 +7,7 @@ static void FailFunction_t(const char *strName) {
|
||||||
ThrowF_t(TRANS("Required function %s not found."), strName);
|
ThrowF_t(TRANS("Required function %s not found."), strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetFunctionPointers_t(HINSTANCE hiOGL)
|
static void OGL_SetFunctionPointers_t(HINSTANCE hiOGL)
|
||||||
{
|
{
|
||||||
const char *strName;
|
const char *strName;
|
||||||
// get gl function pointers
|
// get gl function pointers
|
||||||
|
@ -26,24 +26,20 @@ BOOL CGfxLibrary::InitDriver_OGL(BOOL init3dfx)
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
|
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
|
||||||
CPrintF( TRANS("Error starting OpenGL: %s\n"), SDL_GetError());
|
CPrintF( TRANS("Error starting OpenGL: %s\n"), SDL_GetError());
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_EnableUNICODE(1);
|
SDL_EnableUNICODE(1);
|
||||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||||
|
|
||||||
// !!! FIXME: Is it safe to add new cvars for a specific platform?
|
if (SDL_GL_LoadLibrary(NULL) == -1) {
|
||||||
const char *envlib = getenv("SERIOUS_GLLIBRARY");
|
CPrintF(TRANSV("Cannot load OpenGL driver"));
|
||||||
CTString strDriverFileName = ((envlib) ? envlib : "libGL.so.1");
|
|
||||||
|
|
||||||
if (SDL_GL_LoadLibrary(strDriverFileName) == -1) {
|
|
||||||
CPrintF(TRANSV("Cannot load OpenGL driver '%s'"), (const char *) strDriverFileName);
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare functions
|
// prepare functions
|
||||||
SetFunctionPointers_t(gl_hiDriver);
|
OGL_SetFunctionPointers_t(gl_hiDriver);
|
||||||
|
|
||||||
// done
|
// done
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -15,7 +15,7 @@ void WIN_CheckError(BOOL bRes, const char *strDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void SetFunctionPointers_t(HINSTANCE hiOGL)
|
static void OGL_SetFunctionPointers_t(HINSTANCE hiOGL)
|
||||||
{
|
{
|
||||||
const char *strName;
|
const char *strName;
|
||||||
// get gl function pointers
|
// get gl function pointers
|
||||||
|
@ -40,11 +40,11 @@ BOOL CGfxLibrary::InitDriver_OGL( BOOL b3Dfx/*=FALSE*/)
|
||||||
{ // if driver doesn't exists on disk
|
{ // if driver doesn't exists on disk
|
||||||
char strBuffer[_MAX_PATH+1];
|
char strBuffer[_MAX_PATH+1];
|
||||||
char *strDummy;
|
char *strDummy;
|
||||||
int iRes = SearchPath( NULL, strDriverFileName, NULL, _MAX_PATH, strBuffer, &strDummy);
|
int iRes = SearchPathA( NULL, strDriverFileName, NULL, _MAX_PATH, strBuffer, &strDummy);
|
||||||
if( iRes==0) ThrowF_t(TRANS("OpenGL driver '%s' not present"), strDriverFileName);
|
if( iRes==0) ThrowF_t(TRANS("OpenGL driver '%s' not present"), strDriverFileName);
|
||||||
|
|
||||||
// load opengl library
|
// load opengl library
|
||||||
gl_hiDriver = ::LoadLibrary( strDriverFileName);
|
gl_hiDriver = ::LoadLibraryA( strDriverFileName);
|
||||||
|
|
||||||
// if it cannot be loaded (although it is present on disk)
|
// if it cannot be loaded (although it is present on disk)
|
||||||
if( gl_hiDriver==NONE) {
|
if( gl_hiDriver==NONE) {
|
||||||
|
@ -60,7 +60,7 @@ BOOL CGfxLibrary::InitDriver_OGL( BOOL b3Dfx/*=FALSE*/)
|
||||||
ThrowF_t(TRANS("Cannot load OpenGL driver '%s'"), (const char *) strDriverFileName);
|
ThrowF_t(TRANS("Cannot load OpenGL driver '%s'"), (const char *) strDriverFileName);
|
||||||
}
|
}
|
||||||
// prepare functions
|
// prepare functions
|
||||||
SetFunctionPointers_t(gl_hiDriver);
|
OGL_SetFunctionPointers_t(gl_hiDriver);
|
||||||
}
|
}
|
||||||
catch( char *strError)
|
catch( char *strError)
|
||||||
{ // didn't make it :(
|
{ // didn't make it :(
|
||||||
|
@ -131,11 +131,12 @@ BOOL CGfxLibrary::CreateContext_OGL(HDC hdc)
|
||||||
pwglDeleteContext( hglrc); \
|
pwglDeleteContext( hglrc); \
|
||||||
ReleaseDC( dummyhwnd, hdc); \
|
ReleaseDC( dummyhwnd, hdc); \
|
||||||
DestroyWindow( dummyhwnd); \
|
DestroyWindow( dummyhwnd); \
|
||||||
UnregisterClass( classname, hInstance)
|
UnregisterClassA( classname, hInstance);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// helper for choosing t-buffer's pixel format
|
// helper for choosing t-buffer's pixel format
|
||||||
static _TBCapability = FALSE;
|
extern BOOL _TBCapability;
|
||||||
static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
PIX pixResWidth, PIX pixResHeight)
|
PIX pixResWidth, PIX pixResHeight)
|
||||||
{
|
{
|
||||||
|
@ -144,9 +145,9 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
char *wglextensions = NULL;
|
char *wglextensions = NULL;
|
||||||
HGLRC hglrc;
|
HGLRC hglrc;
|
||||||
HWND dummyhwnd;
|
HWND dummyhwnd;
|
||||||
WNDCLASS cls;
|
WNDCLASSA cls;
|
||||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||||
char *classname = "dummyOGLwin";
|
LPCSTR classname = "dummyOGLwin";
|
||||||
cls.style = CS_OWNDC;
|
cls.style = CS_OWNDC;
|
||||||
cls.lpfnWndProc = DefWindowProc;
|
cls.lpfnWndProc = DefWindowProc;
|
||||||
cls.cbClsExtra = 0;
|
cls.cbClsExtra = 0;
|
||||||
|
@ -158,16 +159,16 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
cls.lpszMenuName = NULL;
|
cls.lpszMenuName = NULL;
|
||||||
cls.lpszClassName = classname;
|
cls.lpszClassName = classname;
|
||||||
// didn't manage to register class?
|
// didn't manage to register class?
|
||||||
if( !RegisterClass(&cls)) return 0;
|
if( !RegisterClassA(&cls)) return 0;
|
||||||
|
|
||||||
// create window fullscreen
|
// create window fullscreen
|
||||||
//CPrintF( " Dummy window: %d x %d\n", pixResWidth, pixResHeight);
|
//CPrintF( " Dummy window: %d x %d\n", pixResWidth, pixResHeight);
|
||||||
dummyhwnd = CreateWindowEx( WS_EX_TOPMOST, classname, "Dummy OGL window",
|
dummyhwnd = CreateWindowExA( WS_EX_TOPMOST, classname, "Dummy OGL window",
|
||||||
WS_POPUP|WS_VISIBLE, 0, 0, pixResWidth, pixResHeight,
|
WS_POPUP|WS_VISIBLE, 0, 0, pixResWidth, pixResHeight,
|
||||||
NULL, NULL, hInstance, NULL);
|
NULL, NULL, hInstance, NULL);
|
||||||
// didn't make it?
|
// didn't make it?
|
||||||
if( dummyhwnd == NULL) {
|
if( dummyhwnd == NULL) {
|
||||||
UnregisterClass( classname, hInstance);
|
UnregisterClassA( classname, hInstance);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " Dummy passed...\n");
|
//CPrintF( " Dummy passed...\n");
|
||||||
|
@ -177,7 +178,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
if( !iPixelFormat) {
|
if( !iPixelFormat) {
|
||||||
ReleaseDC( dummyhwnd, hdc);
|
ReleaseDC( dummyhwnd, hdc);
|
||||||
DestroyWindow(dummyhwnd);
|
DestroyWindow(dummyhwnd);
|
||||||
UnregisterClass( classname, hInstance);
|
UnregisterClassA( classname, hInstance);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " Choose pixel format passed...\n");
|
//CPrintF( " Choose pixel format passed...\n");
|
||||||
|
@ -185,7 +186,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
if( !pwglSetPixelFormat( hdc, iPixelFormat, ppfd)) {
|
if( !pwglSetPixelFormat( hdc, iPixelFormat, ppfd)) {
|
||||||
ReleaseDC( dummyhwnd, hdc);
|
ReleaseDC( dummyhwnd, hdc);
|
||||||
DestroyWindow(dummyhwnd);
|
DestroyWindow(dummyhwnd);
|
||||||
UnregisterClass( classname, hInstance);
|
UnregisterClassA( classname, hInstance);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " Set pixel format passed...\n");
|
//CPrintF( " Set pixel format passed...\n");
|
||||||
|
@ -193,7 +194,6 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
// create context using the default accelerated pixelformat that was passed
|
// create context using the default accelerated pixelformat that was passed
|
||||||
hglrc = pwglCreateContext(hdc);
|
hglrc = pwglCreateContext(hdc);
|
||||||
pwglMakeCurrent( hdc, hglrc);
|
pwglMakeCurrent( hdc, hglrc);
|
||||||
|
|
||||||
// update the value list with information passed from the ppfd.
|
// update the value list with information passed from the ppfd.
|
||||||
aiAttribList[ 9] = ppfd->cColorBits;
|
aiAttribList[ 9] = ppfd->cColorBits;
|
||||||
aiAttribList[11] = ppfd->cDepthBits;
|
aiAttribList[11] = ppfd->cDepthBits;
|
||||||
|
@ -206,7 +206,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
{ // windows extension string supported
|
{ // windows extension string supported
|
||||||
pwglGetExtensionsStringARB = (char* (__stdcall*)(HDC))pwglGetProcAddress( "wglGetExtensionsStringARB");
|
pwglGetExtensionsStringARB = (char* (__stdcall*)(HDC))pwglGetProcAddress( "wglGetExtensionsStringARB");
|
||||||
if( pwglGetExtensionsStringARB == NULL) {
|
if( pwglGetExtensionsStringARB == NULL) {
|
||||||
BACKOFF;
|
BACKOFF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " WGL extension string passed...\n");
|
//CPrintF( " WGL extension string passed...\n");
|
||||||
|
@ -214,7 +214,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
wglextensions = (char*)pwglGetExtensionsStringARB(hdc);
|
wglextensions = (char*)pwglGetExtensionsStringARB(hdc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BACKOFF;
|
BACKOFF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
pwglGetPixelFormatAttribivARB = (BOOL (__stdcall*)(HDC,int,int,UINT,int*,int*) )pwglGetProcAddress( "wglGetPixelFormatAttribivARB");
|
pwglGetPixelFormatAttribivARB = (BOOL (__stdcall*)(HDC,int,int,UINT,int*,int*) )pwglGetProcAddress( "wglGetPixelFormatAttribivARB");
|
||||||
pglTBufferMask3DFX = (void (__stdcall*)(GLuint))pwglGetProcAddress("glTBufferMask3DFX");
|
pglTBufferMask3DFX = (void (__stdcall*)(GLuint))pwglGetProcAddress("glTBufferMask3DFX");
|
||||||
if( pwglChoosePixelFormatARB==NULL && pglTBufferMask3DFX==NULL) {
|
if( pwglChoosePixelFormatARB==NULL && pglTBufferMask3DFX==NULL) {
|
||||||
BACKOFF;
|
BACKOFF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " WGL choose pixel format present...\n");
|
//CPrintF( " WGL choose pixel format present...\n");
|
||||||
|
@ -243,7 +243,7 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
// try to get all formats that fit the pixel format criteria
|
// try to get all formats that fit the pixel format criteria
|
||||||
if( !pwglChoosePixelFormatARB( hdc, piAttribList, NULL, iMaxFormats, piFormats, &uiNumFormats)) {
|
if( !pwglChoosePixelFormatARB( hdc, piAttribList, NULL, iMaxFormats, piFormats, &uiNumFormats)) {
|
||||||
FreeMemory(piFormats);
|
FreeMemory(piFormats);
|
||||||
BACKOFF;
|
BACKOFF
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//CPrintF( " WGL choose pixel format passed...\n");
|
//CPrintF( " WGL choose pixel format passed...\n");
|
||||||
|
@ -260,11 +260,10 @@ static INDEX ChoosePixelFormatTB( HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd,
|
||||||
{ // wglChoosePixelFormatARB extension does not exist :(
|
{ // wglChoosePixelFormatARB extension does not exist :(
|
||||||
iPixelFormat = 0;
|
iPixelFormat = 0;
|
||||||
}
|
}
|
||||||
BACKOFF;
|
BACKOFF
|
||||||
return iPixelFormat;
|
return iPixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *CGfxLibrary::OGL_GetProcAddress(const char *procname)
|
void *CGfxLibrary::OGL_GetProcAddress(const char *procname)
|
||||||
{
|
{
|
||||||
return(pwglGetProcAddress(procname));
|
return(pwglGetProcAddress(procname));
|
||||||
|
@ -439,4 +438,3 @@ BOOL CGfxLibrary::SetCurrentViewport_OGL(CViewPort *pvp)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user