ManiaDrive/raydium/myglut-win32.c
2025-01-26 18:33:45 +01:00

452 lines
12 KiB
C

/*
Raydium - CQFD Corp.
http://raydium.org/
License: GPL - GNU General Public License, see "gpl.txt" file.
*/
#include "headers/myglut.h"
#include <windows.h>
#include <gl/glaux.h>
static HINSTANCE currInstance;
static HWND currWnd;
static HDC currDC;
static HGLRC currGLRC;
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
// ---------------------- public API
void glutInit(int *argc, char **argv)
{
currInstance = NULL ;
currWnd = NULL ;
currDC = NULL ;
currGLRC = NULL ;
glutReshapeFuncCB=NULL;
glutKeyboardFuncCB=NULL;
glutSpecialUpFuncCB=NULL;
glutSpecialFuncCB=NULL;
glutMotionFuncCB=NULL;
glutPassiveMotionFuncCB=NULL;
glutMouseFuncCB=NULL;
glutDisplayFuncCB=NULL;
glutIdleFuncCB=NULL;
_glutMouseVisible=1;
}
void mylgutCloseWindow(void)
{
wglMakeCurrent ( NULL, NULL ) ;
wglDeleteContext ( currGLRC ) ;
DestroyWindow ( currWnd ) ;
}
//glutSetCursor
void glutSetCursor(int cursor)
{
switch(cursor)
{
case GLUT_CURSOR_LEFT_ARROW:
if(_glutMouseVisible) break;
ShowCursor(1);
_glutMouseVisible=1;
break;
case GLUT_CURSOR_NONE:
default:
if(!_glutMouseVisible) break;
ShowCursor(0);
_glutMouseVisible=0;
break;
break;
}
//SetCursor( LoadCursor ( NULL, wcursor ) ) ;
}
//glutWarpPointer (move mouse)
void glutWarpPointer(int x, int y)
{
POINT point;
point.x = x;
point.y = y;
ClientToScreen(currWnd /* ? */, &point);
SetCursorPos(point.x, point.y);
}
//glutSwapBuffers
void glutSwapBuffers(void)
{
glFlush () ;
SwapBuffers ( currDC ) ;
}
//glutMainLoop is generic (myglut.c)
// ------------- private part
void myglutGetEvents (void)
{
MSG msg;
while ( PeekMessage( &msg, currWnd, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg ) ;
DispatchMessage ( &msg ) ;
}
}
void pwInit ( int x, int y, int w, int h, int multisample,
char *title, int border, int num_samples )
{
WNDCLASS wc;
signed char fullscn;
RECT rect;
DWORD style = 0;
int iPixelFormat;
int origin [2] = { 0, 0 };
int size [2] = { 640, 480 };
PIXELFORMATDESCRIPTOR pfd;
currInstance = GetModuleHandleA( NULL ) ;
/* Register the window class */
wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW ;
wc.lpfnWndProc = WndProc ;
wc.cbClsExtra = 0 ;
wc.cbWndExtra = 0 ;
wc.hInstance = currInstance ;
wc.hIcon = LoadIcon ( NULL, IDI_APPLICATION ) ;
wc.hCursor = LoadCursor ( NULL, IDC_ARROW ) ;
wc.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 ) ;
wc.lpszMenuName = NULL ;
wc.lpszClassName = "RaydiumAppClass" ;
if ( !RegisterClass( &wc ) )
{
raydium_log("(my)glut: ERROR: Can't register window class" ) ;
exit ( 1 ) ;
}
/* Setup window style */
fullscn = (w == -1 && h == -1 ) ? 1 : 0 ;
if ( w == -1 ) w = GetSystemMetrics( SM_CXSCREEN ) ;
if ( h == -1 ) h = GetSystemMetrics( SM_CYSCREEN ) ;
if ( x == -1 ) x = (GetSystemMetrics( SM_CXSCREEN ) / 2) - (w/2) ;
if ( y == -1 ) y = (GetSystemMetrics( SM_CYSCREEN ) / 2) - (h/2);
origin [ 0 ] = x ;
origin [ 1 ] = y ;
size [ 0 ] = w ;
size [ 1 ] = h ;
rect.left = x ;
rect.top = y ;
rect.right = rect.left + w ;
rect.bottom = rect.top + h ;
if ( !fullscn )
style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS ;
else
style = WS_POPUP ;
AdjustWindowRect( &rect, style, 0 ) ;
/* Create the window */
currWnd = CreateWindow(
"RaydiumAppClass", title, style,
rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
NULL, NULL, currInstance, NULL ) ;
if ( !currWnd )
{
raydium_log("(my)glut: ERROR: Can't create window" ) ;
exit ( 1 ) ;
}
/* Get DC for this window */
currDC = GetDC ( currWnd ) ;
if ( !currDC )
{
raydium_log("(my)glut: ERROR: Can't get window DC" ) ;
exit ( 1 ) ;
}
// wglGetExtensionsStringARBtype *wglGetExtensionsStringARB = (wglGetExtensionsStringARBtype *)wglGetProcAddress ( "wglGetExtensionsStringARB" ) ;
// const char *extensionsString = wglGetExtensionsStringARB ( currDC ) ;
// printf ( "%s %x %s\n", glGetString ( GL_EXTENSIONS ), wglGetExtensionsStringARB, extensionsString ) ;
// if (!GLExtensionExists("WGL_ARB_multisample "))
// return suggestedFormat;
pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=24;
pfd.cRedBits=0;
pfd.cRedShift=0;
pfd.cGreenBits=0;
pfd.cGreenShift=0;
pfd.cBlueBits=0;
pfd.cBlueShift=0;
pfd.cAlphaBits=0;
pfd.cAlphaShift=0;
pfd.cAccumBits=0;
pfd.cAccumRedBits=0;
pfd.cAccumGreenBits=0;
pfd.cAccumBlueBits=0;
pfd.cAccumAlphaBits=0;
pfd.cDepthBits=32;
pfd.cStencilBits=1;
pfd.cAuxBuffers=0;
pfd.iLayerType=PFD_MAIN_PLANE;
pfd.bReserved=0;
pfd.dwLayerMask=0;
pfd.dwVisibleMask=0;
pfd.dwDamageMask=0;
/* Get best available match of pixel format for DC */
iPixelFormat = ChoosePixelFormat ( currDC, &pfd ) ;
if ( iPixelFormat == 0 )
{
raydium_log("(my)glut: ERROR: Can't get OpenGL pixel format" ) ;
exit ( 1 ) ;
}
/* Set the pixel format of the DC */
if ( !SetPixelFormat( currDC, iPixelFormat, &pfd ) )
{
raydium_log("(my)glut: ERROR: Can't set OpenGL pixel format" ) ;
exit ( 1 ) ;
}
/* Show the window and paint its contents */
ShowWindow ( currWnd, SW_SHOW ) ;
UpdateWindow ( currWnd ) ;
/* Create openGL context and make it current */
currGLRC = wglCreateContext ( currDC ) ;
if ( !currGLRC )
{
raydium_log("(my)glut: ERROR: Unable to open a suitable window");
exit ( 1 ) ;
}
if ( !wglMakeCurrent ( currDC, currGLRC ) )
{
raydium_log("(my)glut: ERROR: Unable to open a suitable window");
exit ( 1 ) ;
}
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers () ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
glutSwapBuffers () ;
// if (glutReshapeFuncCB)
// glutReshapeFuncCB(w, h);
DescribePixelFormat(currDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
raydium_log("Found %ix%i with %i bpp color and %i bits zbuffer (stencil is %i)",w,h,pfd.cColorBits,pfd.cDepthBits,pfd.cStencilBits);
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static int key = -1 ;
static int updown = GLUT_UP ;
static int old_key = -1 ; // We need this because "key" changes case
int button = -1 ;
static int mb = 0 ;
static int lastx = 0 ;
static int lasty = 0 ;
BYTE state[256];
WORD code[2];
signed char b;
signed char special=0;
signed char repeating=0;
int size[2];
switch (uMsg)
{
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
updown = GLUT_DOWN ;
if ( uMsg == WM_LBUTTONDOWN ) { button = GLUT_LEFT_BUTTON ; mb |= 1 ; }
else if ( uMsg == WM_MBUTTONDOWN ) { button = GLUT_MIDDLE_BUTTON ; mb |= 2 ; }
else { button = GLUT_RIGHT_BUTTON ; mb |= 4 ; }
SetCapture ( hWnd ) ;
lastx = (LOWORD( lParam ) ) ;
lasty = (HIWORD( lParam ) ) ;
if ( button != -1 && glutMouseFuncCB )
(*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
break;
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
updown = GLUT_UP ;
if ( uMsg == WM_LBUTTONUP ) { button = GLUT_LEFT_BUTTON ; mb &= ~1 ; }
else if ( uMsg == WM_MBUTTONUP ) { button = GLUT_MIDDLE_BUTTON ; mb &= ~2 ; }
else { button = GLUT_RIGHT_BUTTON ; mb &= ~4 ; }
if ( mb == 0 ) ReleaseCapture () ;
lastx = (LOWORD( lParam ) ) ;
lasty = (HIWORD( lParam ) ) ;
if ( button != -1 && glutMouseFuncCB )
(*glutMouseFuncCB) ( button, updown, lastx, lasty ) ;
break;
case WM_MOUSEMOVE:
lastx = (LOWORD( lParam ) );
lasty = (HIWORD( lParam ) );
if ( glutPassiveMotionFuncCB )
(*glutPassiveMotionFuncCB) ( lastx, lasty ) ;
break;
case WM_MOUSEWHEEL:
if ( ( short ) HIWORD( wParam ) > 0 )
{
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 3, GLUT_DOWN, lastx, lasty ) ;
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 3, GLUT_UP, lastx, lasty ) ;
}
else
{
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 4, GLUT_DOWN, lastx, lasty ) ;
if ( glutPassiveMotionFuncCB )
(*glutMouseFuncCB) ( 4, GLUT_UP, lastx, lasty ) ;
}
case WM_KEYDOWN:
// If the key is already down, we are on auto-repeat. Break if the autorepeat is disabled.
if ( ( updown == GLUT_DOWN ) && ( (int)wParam == old_key ) )
{
/* if ( autoRepeat )
{*/
// Disable CTRL, SHIFT, CapsLock keys from making a callback
if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
break ;
/* if ( key != -1 && kbCB ) // Autorepeat enabled, call the callback with an "up" setting
(*kbCB) ( key, PW_UP, lastx, lasty ) ;
}
else*/
repeating=1;
}
updown = GLUT_DOWN ;
old_key = wParam ;
// FALLTHROUGH
case WM_KEYUP:
if ( uMsg == WM_KEYUP ) updown = GLUT_UP ;
key = wParam ;
// Disable CTRL, SHIFT, CapsLock keys from making a callback
if ( ( key == VK_CONTROL ) || ( key == VK_SHIFT ) || ( key == VK_CAPITAL ) )
break ;
switch ( key )
{
case VK_F1: key = GLUT_KEY_F1; special=1; break;
case VK_F2: key = GLUT_KEY_F2; special=1; break;
case VK_F3: key = GLUT_KEY_F3; special=1; break;
case VK_F4: key = GLUT_KEY_F4; special=1; break;
case VK_F5: key = GLUT_KEY_F5; special=1; break;
case VK_F6: key = GLUT_KEY_F6; special=1; break;
case VK_F7: key = GLUT_KEY_F7; special=1; break;
case VK_F8: key = GLUT_KEY_F8; special=1; break;
case VK_F9: key = GLUT_KEY_F9; special=1; break;
case VK_F10: key = GLUT_KEY_F10; special=1; break;
case VK_F11: key = GLUT_KEY_F11; special=1; break;
case VK_F12: key = GLUT_KEY_F12; special=1; break;
case VK_LEFT: key = GLUT_KEY_LEFT; special=1; break;
case VK_RIGHT: key = GLUT_KEY_RIGHT; special=1; break;
case VK_UP: key = GLUT_KEY_UP; special=1; break;
case VK_DOWN: key = GLUT_KEY_DOWN; special=1; break;
case VK_PRIOR: key = GLUT_KEY_PAGE_UP; special=1; break;
case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; special=1; break;
case VK_HOME: key = GLUT_KEY_HOME; special=1; break;
case VK_END: key = GLUT_KEY_END; special=1; break;
case VK_INSERT: key = GLUT_KEY_INSERT; special=1; break;
default:
// don't do this for WinCE
b = GetKeyboardState( state );
assert(b);
code [ 0 ] = 0; // WK: I need to do this, or on my Win2k box, the upper bits remain unchanged.
if( ToAscii( key, 0, state, code, 0 ) == 1 )
if((0xFF00 & code[0]) == 0) // setting a high bit in key causes crashes later on (out of range array access)
key=code[ 0 ];
}
if ( key != -1)
{
// special down
if(special && updown==GLUT_DOWN && glutSpecialFuncCB && !repeating)
glutSpecialFuncCB(key,lastx,lasty);
// special up
if(special && updown==GLUT_UP && glutSpecialUpFuncCB && !repeating)
glutSpecialUpFuncCB(key,lastx,lasty);
// normal
if(!special && updown==GLUT_DOWN && glutKeyboardFuncCB)
glutKeyboardFuncCB(key,lastx,lasty);
/*if(!special && repeating && glutKeyboardFuncCB)
glutKeyboardFuncCB(key,lastx,lasty);*/
//(*kbCB) ( key, updown, lastx, lasty ) ;
}
break;
case WM_SIZE:
size[0] = LOWORD(lParam) ;
size[1] = HIWORD(lParam) ;
_glutWindowSize[0]=size[0];
_glutWindowSize[1]=size[1];
if (glutReshapeFuncCB)
glutReshapeFuncCB(size[0], size[1]);
break;
case WM_CLOSE:
exit(0);
break;
default:
return ( DefWindowProc ( hWnd, uMsg, wParam, lParam ) ) ;
}
return 0;
}