1 //**************************************************************************
5 //**************************************************************************
14 #include <X11/keysym.h>
15 #include "x11window.h"
24 extern void OGL_InitData();
25 extern void OGL_InitRenderer();
26 extern void OGL_ResetData();
27 extern void OGL_ResetLumpTexData();
31 void OGL_GrabScreen();
34 class HexenWindow : public X11Window
42 void swap() { glXSwapBuffers( display(), window() ); }
44 GLXContext context() { return _ctx; }
48 XUngrabPointer( display(), CurrentTime );
55 XGrabPointer( display(), window(), True,
56 ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
57 GrabModeAsync, GrabModeAsync, window(), None, CurrentTime );
64 virtual void unknownEvent( XEvent* );
65 virtual void configureEvent( XConfigureEvent* );
66 virtual void deleteEvent( XEvent* );
67 virtual void buttonDown( XButtonEvent* );
68 virtual void buttonUp( XButtonEvent* );
69 virtual void motionEvent( XMotionEvent* );
70 virtual void keyDown( XKeyEvent* );
71 virtual void keyUp( XKeyEvent* );
72 virtual void exposeEvent( XExposeEvent* );
76 void postKey( evtype_t type, KeySym key );
77 void postMouseEvent( int dx, int dy );
96 int screenWidth = SCREENWIDTH*2;
97 int screenHeight = SCREENHEIGHT*2;
99 int ratioLimit = 0; // Zero if none.
102 int DisplayTicker = 0;
106 extern boolean novideo; // if true, stay in text mode for debugging
109 //==================================================
115 //==================================================
117 #define KEY_TAB 9 // From am_map.h
121 #define KEY_PGUP 0x49
122 #define KEY_PGDN 0x51
123 #define KEY_HOME 0x47
128 ============================================================================
132 ============================================================================
135 //--------------------------------------------------------------------------
139 //--------------------------------------------------------------------------
141 void I_WaitVBL(int vbls)
153 //--------------------------------------------------------------------------
157 // Palette source must use 8 bit RGB elements.
159 //--------------------------------------------------------------------------
161 void I_SetPalette( byte *palette )
166 ============================================================================
170 ============================================================================
182 extern int screenblocks;
186 if( UpdateState == I_NOUPDATE )
191 UpdateState = I_NOUPDATE; // clear out all draw types
195 //--------------------------------------------------------------------------
197 // PROC I_InitGraphics
199 //--------------------------------------------------------------------------
201 void I_InitGraphics(void)
209 p = M_CheckParm( "-height" );
210 if (p && p < myargc - 1)
212 screenHeight = atoi(myargv[p+1]);
214 p = M_CheckParm( "-width" );
215 if( p && p < myargc - 1 )
217 screenWidth = atoi(myargv[p+1]);
219 ST_Message("Screen Width %d, Screen Height %d\n",screenWidth, screenHeight);
220 _win = new HexenWindow();
226 //OGL_InitData(); // JHexen has this at the end of R_Init().
229 // Clear the buffers.
230 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
233 // Print some OpenGL information.
234 ST_Message( "I_InitGraphics: OpenGL information:\n" );
235 ST_Message( " Vendor: %s\n", glGetString(GL_VENDOR) );
236 ST_Message( " Renderer: %s\n", glGetString(GL_RENDERER) );
237 ST_Message( " Version: %s\n", glGetString(GL_VERSION) );
238 ST_Message( " GLU Version: %s\n", gluGetString((GLenum)GLU_VERSION) );
240 // Check the maximum texture size.
241 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTexSize );
242 ST_Message(" Maximum texture size: %d\n", maxTexSize);
243 if( maxTexSize == 256 )
245 //ST_Message(" Is this Voodoo? Using size ratio limit.\n");
249 if( M_CheckParm("-3dfxtest") )
252 ST_Message(" 3dfx test mode.\n");
257 //I_SetPalette( (byte*) W_CacheLumpName("PLAYPAL", PU_CACHE) );
258 _win->grabPointer ();
261 //--------------------------------------------------------------------------
263 // PROC I_ShutdownGraphics
265 //--------------------------------------------------------------------------
267 void I_ShutdownGraphics(void)
270 OGL_ResetLumpTexData();
273 //--------------------------------------------------------------------------
277 // Reads the screen currently displayed into a linear buffer.
279 //--------------------------------------------------------------------------
282 void I_ReadScreen(byte *scr)
284 memcpy(scr, screen, SCREENWIDTH*SCREENHEIGHT);
288 //===========================================================================
291 void I_StartTic (void)
293 // Handle keyboard & mouse events.
295 while( _win->eventsPending() )
296 _win->handleNextEvent();
303 ============================================================================
307 ============================================================================
319 int I_TimerISR (void)
327 ============================================================================
331 ============================================================================
343 void I_StartupCyberMan(void);
345 void I_StartupMouse (void)
359 void I_ReadMouse (void)
365 //==========================================================================
371 //==========================================================================
373 void I_StartupReadKeys(void)
375 //if( KEY_ESCAPE pressed )
380 void checkGLContext()
382 GLXContext c = glXGetCurrentContext();
383 if( ! c || (c != _win->context()) )
384 printf( "Bad context!\n" );
386 printf( "context ok\n" );
392 //---------------------------------------------------------------------------
395 HexenWindow::HexenWindow()
396 : X11Window( "HHEXEN", 0, 0, screenWidth, screenHeight )
398 int attrib[] = { GLX_RGBA,
399 GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1,
400 GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, None };
409 if( glXQueryExtension( display(), 0, 0 ) == 0 )
411 fprintf( stderr, "GLX Extension not available!\n" );
415 _vinfo = glXChooseVisual( display(), screen(), attrib );
418 fprintf( stderr, "Couldn't get an RGB, double-buffered visual!\n" );
422 _ctx = glXCreateContext( display(), _vinfo, NULL, True );
423 glXMakeCurrent( display(), window(), _ctx );
425 setTitle( "HHexen v1.3" );
426 setSizeHints( screenWidth,screenHeight,screenWidth,screenHeight );
427 setIconName( "HHEXEN" );
431 HexenWindow::~HexenWindow()
435 glXDestroyContext( display(), _ctx );
440 void HexenWindow::deleteEvent( XEvent* )
445 void HexenWindow::configureEvent( XConfigureEvent* e )
447 screenWidth = width();
448 screenHeight = height();
451 void HexenWindow::unknownEvent( XEvent* e )
456 void HexenWindow::buttonDown( XButtonEvent* e )
463 case Button1: _buttons |= MOUSEB1 ; break;
464 case Button2: _buttons |= MOUSEB2 ; break;
465 case Button3: _buttons |= MOUSEB3 ; break;
469 postMouseEvent( 0, 0 );
473 void HexenWindow::buttonUp( XButtonEvent* e )
477 case Button1: _buttons &= ~MOUSEB1 ; break;
478 case Button2: _buttons &= ~MOUSEB2 ; break;
479 case Button3: _buttons &= ~MOUSEB3 ; break;
483 postMouseEvent( 0, 0 );
487 void HexenWindow::motionEvent( XMotionEvent* e )
492 if (e->x == width()/2 && e->y == height()/2)
498 dx = (e->x - _prevX);
500 dy = (e->y - _prevY);
505 postMouseEvent( dx, dy );
509 if( (e->x < 30) || (e->x > (screenWidth-30)) ||
510 (e->y < 30) || (e->y > (screenHeight-30)) )
512 XWarpPointer( display(), None, window(), 0, 0, 0, 0,
513 screenWidth / 2, screenHeight / 2 );
514 _prevX = e->x; _prevY = e->y;
520 void HexenWindow::keyDown( XKeyEvent* e )
522 KeySym key = keysym( e );
524 //TODO: filter key repeat.
526 if( e->state & Mod1Mask ) // Control key defaults to attack.
532 else if( key == XK_g )
546 postKey( ev_keydown, key );
551 void HexenWindow::keyUp( XKeyEvent* e )
553 postKey( ev_keyup, keysym( e ) );
557 void HexenWindow::exposeEvent( XExposeEvent* )
559 UpdateState |= I_FULLSCRN;
563 void HexenWindow::postKey( evtype_t type, KeySym key )
571 case XK_Up: ev.data1 = KEY_UPARROW; break;
572 case XK_Down: ev.data1 = KEY_DOWNARROW; break;
573 case XK_Left: ev.data1 = KEY_LEFTARROW; break;
574 case XK_Right: ev.data1 = KEY_RIGHTARROW; break;
576 case XK_Escape: ev.data1 = KEY_ESCAPE; break;
577 case XK_Return: ev.data1 = KEY_ENTER; break;
578 case XK_F1: ev.data1 = KEY_F1; break;
579 case XK_F2: ev.data1 = KEY_F2; break;
580 case XK_F3: ev.data1 = KEY_F3; break;
581 case XK_F4: ev.data1 = KEY_F4; break;
582 case XK_F5: ev.data1 = KEY_F5; break;
583 case XK_F6: ev.data1 = KEY_F6; break;
584 case XK_F7: ev.data1 = KEY_F7; break;
585 case XK_F8: ev.data1 = KEY_F8; break;
586 case XK_F9: ev.data1 = KEY_F9; break;
587 case XK_F10: ev.data1 = KEY_F10; break;
588 case XK_F11: ev.data1 = KEY_F11; break;
589 case XK_F12: ev.data1 = KEY_F12; break;
591 case XK_Insert: ev.data1 = KEY_INS; break;
592 case XK_Delete: ev.data1 = KEY_DEL; break;
593 case XK_Page_Up: ev.data1 = KEY_PGUP; break;
594 case XK_Page_Down: ev.data1 = KEY_PGDN; break;
595 case XK_Home: ev.data1 = KEY_HOME; break;
596 case XK_End: ev.data1 = KEY_END; break;
598 case XK_Tab: ev.data1 = KEY_TAB; break;
600 case XK_BackSpace: ev.data1 = KEY_BACKSPACE; break;
602 case XK_Pause: ev.data1 = KEY_PAUSE; break;
604 case XK_equal: ev.data1 = KEY_EQUALS; break;
607 case XK_minus: ev.data1 = KEY_MINUS; break;
610 case XK_Shift_R: ev.data1 = KEY_RSHIFT; break;
613 case XK_Control_R: ev.data1 = KEY_RCTRL; break;
618 case XK_Meta_R: ev.data1 = KEY_RALT; break;
629 void HexenWindow::postMouseEvent( int dx, int dy )
635 ev.data2 = (short) dx << 2;
636 ev.data3 = -(short) dy << 2;
642 // Returns zero if a unique file name could not be found.
643 static int makeUniqueFilename( char* filename )
647 for( i = 0; i < 100; i++ )
649 sprintf( filename, "hexen%02d.ppm", i );
651 if( access( filename, F_OK ) == -1 )
653 // It does not exist.
662 //--------------------------------------------------------------------------
664 // Copies the current contents of the frame buffer and returns a pointer
665 // to data containing 24-bit RGB triplets.
667 //--------------------------------------------------------------------------
669 void OGL_GrabScreen()
673 unsigned char* buffer = new unsigned char[ screenWidth * screenHeight * 3 ];
675 if( buffer && makeUniqueFilename( filename ) )
677 glReadPixels( 0, 0, screenWidth, screenHeight, GL_RGB,
678 GL_UNSIGNED_BYTE, buffer );
680 fp = fopen( filename, "w" );
683 unsigned char* rgb = buffer + (screenWidth * screenHeight * 3);
685 fprintf( fp, "P6\n%d %d\n255\n", screenWidth, screenHeight );
687 while( rgb > buffer )
689 rgb -= 3 * screenWidth;
690 fwrite( rgb, 1, 3 * screenWidth, fp );