Move to SDL for graphics.

Translate key scancodes to correct internal format when reading
settings from config file - backwards compatible with config files
for original exes

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 26
This commit is contained in:
Simon Howard 2005-07-24 02:14:04 +00:00
parent 7de2353daa
commit e74dfd3cb7
5 changed files with 306 additions and 644 deletions

View file

@ -3,18 +3,10 @@ AC_CONFIG_AUX_DIR(autotools)
AC_PROG_CC
AC_PATH_X
AM_PATH_SDL(1.1.3)
AM_INIT_AUTOMAKE(AC_PACKAGE_TARNAME,AC_PACKAGE_VERSION)
X_CFLAGS="-I$x_includes"
X_LDFLAGS="-L$x_libraries -lX11"
echo $X_CFLAGS
AC_SUBST(X_CFLAGS)
AC_SUBST(X_LDFLAGS)
AM_CONFIG_HEADER(config.h:config.hin)
AC_OUTPUT([

View file

@ -1,8 +1,8 @@
bindir = $(prefix)/bin
CFLAGS = @CFLAGS@ @X_CFLAGS@ -DNORMALUNIX
LDFLAGS = @LDFLAGS@ @X_LDFLAGS@ -lX11 -lXext
CFLAGS = @CFLAGS@ @SDL_CFLAGS@ -DNORMALUNIX
LDFLAGS = @LDFLAGS@ @SDL_LIBS@
chocolate_doom_SOURCES=\
am_map.c d_think.h i_video.c p_floor.c p_tick.c r_things.h \

View file

@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: doomdef.h 20 2005-07-23 19:29:45Z fraggle $
// $Id: doomdef.h 26 2005-07-24 02:14:04Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@ -286,6 +286,37 @@ typedef enum
#define KEY_LALT KEY_RALT
// new keys:
#define KEY_CAPSLOCK (0x80+0x3a)
#define KEY_SCRLCK (0x80+0x46)
#define KEYP_0 (0x80+0x52)
#define KEYP_1 (0x80+0x4F)
#define KEYP_2 (0x80+0x50)
#define KEYP_3 (0x80+0x41)
#define KEYP_4 (0x80+0x4B)
#define KEYP_5 (0x80+0x4C)
#define KEYP_6 (0x80+0x4D)
#define KEYP_7 (0x80+0x47)
#define KEYP_8 (0x80+0x48)
#define KEYP_9 (0x80+0x49)
#define KEY_HOME (0x80+0x47)
#define KEY_END (0x80+0x4f)
#define KEY_PGUP (0x80+0x49)
#define KEY_PGDN (0x80+0x51)
#define KEY_INS (0x80+0x52)
#define KEY_DEL (0x80+0x53)
#define KEYP_UPARROW KEY_UPARROW
#define KEYP_DOWNARROW KEY_DOWNARROW
#define KEYP_LEFTARROW KEY_LEFTARROW
#define KEYP_RIGHTARROW KEY_RIGHTARROW
#define KEYP_MULTIPLY '*'
#define KEYP_PLUS '+'
#define KEYP_MINUS '-'
#define KEYP_DIVIDE '/'
// DOOM basic types (boolean),
@ -341,6 +372,12 @@ typedef enum
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.4 2005/07/24 02:14:04 fraggle
// Move to SDL for graphics.
// Translate key scancodes to correct internal format when reading
// settings from config file - backwards compatible with config files
// for original exes
//
// Revision 1.3 2005/07/23 19:29:45 fraggle
// Put version number back to 1.9
//

View file

@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: i_video.c 23 2005-07-23 21:32:47Z fraggle $
// $Id: i_video.c 26 2005-07-24 02:14:04Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@ -22,6 +22,12 @@
// 02111-1307, USA.
//
// $Log$
// Revision 1.6 2005/07/24 02:14:04 fraggle
// Move to SDL for graphics.
// Translate key scancodes to correct internal format when reading
// settings from config file - backwards compatible with config files
// for original exes
//
// Revision 1.5 2005/07/23 21:32:47 fraggle
// Add missing errno.h, fix crash on startup when no IWAD present
//
@ -44,27 +50,10 @@
//-----------------------------------------------------------------------------
static const char
rcsid[] = "$Id: i_video.c 23 2005-07-23 21:32:47Z fraggle $";
rcsid[] = "$Id: i_video.c 26 2005-07-24 02:14:04Z fraggle $";
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/extensions/XShm.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <ctype.h>
#include <SDL.h>
#include "doomstat.h"
#include "i_system.h"
@ -74,26 +63,10 @@ rcsid[] = "$Id: i_video.c 23 2005-07-23 21:32:47Z fraggle $";
#include "doomdef.h"
SDL_Surface *screen;
#define POINTER_WARP_COUNTDOWN 1
Display* X_display=0;
Window X_mainWindow;
Colormap X_cmap;
Visual* X_visual;
GC X_gc;
XEvent X_event;
int X_screen;
XVisualInfo X_visualinfo;
XImage* image;
int X_width;
int X_height;
// MIT SHared Memory extension.
boolean doShm;
XShmSegmentInfo X_shminfo;
int X_shmeventtype;
// Fake mouse handling.
// This cannot work properly w/o DGA.
// Needs an invisible mouse cursor at least.
@ -106,92 +79,92 @@ int doPointerWarp = POINTER_WARP_COUNTDOWN;
// to use ....
static int multiply=1;
//
// Translates the key currently in X_event
// Translates the SDL key
//
int xlatekey(void)
int xlatekey(SDL_keysym *sym)
{
int rc;
switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0))
switch(sym->sym)
{
case XK_Left: rc = KEY_LEFTARROW; break;
case XK_Right: rc = KEY_RIGHTARROW; break;
case XK_Down: rc = KEY_DOWNARROW; break;
case XK_Up: rc = KEY_UPARROW; break;
case XK_Escape: rc = KEY_ESCAPE; break;
case XK_Return: rc = KEY_ENTER; break;
case XK_Tab: rc = KEY_TAB; break;
case XK_F1: rc = KEY_F1; break;
case XK_F2: rc = KEY_F2; break;
case XK_F3: rc = KEY_F3; break;
case XK_F4: rc = KEY_F4; break;
case XK_F5: rc = KEY_F5; break;
case XK_F6: rc = KEY_F6; break;
case XK_F7: rc = KEY_F7; break;
case XK_F8: rc = KEY_F8; break;
case XK_F9: rc = KEY_F9; break;
case XK_F10: rc = KEY_F10; break;
case XK_F11: rc = KEY_F11; break;
case XK_F12: rc = KEY_F12; break;
case SDLK_LEFT: return KEY_LEFTARROW;
case SDLK_RIGHT: return KEY_RIGHTARROW;
case SDLK_DOWN: return KEY_DOWNARROW;
case SDLK_UP: return KEY_UPARROW;
case SDLK_ESCAPE: return KEY_ESCAPE;
case SDLK_RETURN: return KEY_ENTER;
case SDLK_TAB: return KEY_TAB;
case SDLK_F1: return KEY_F1;
case SDLK_F2: return KEY_F2;
case SDLK_F3: return KEY_F3;
case SDLK_F4: return KEY_F4;
case SDLK_F5: return KEY_F5;
case SDLK_F6: return KEY_F6;
case SDLK_F7: return KEY_F7;
case SDLK_F8: return KEY_F8;
case SDLK_F9: return KEY_F9;
case SDLK_F10: return KEY_F10;
case SDLK_F11: return KEY_F11;
case SDLK_F12: return KEY_F12;
case XK_BackSpace:
case XK_Delete: rc = KEY_BACKSPACE; break;
case SDLK_BACKSPACE: return KEY_BACKSPACE;
case SDLK_DELETE: return KEY_DEL;
case XK_Pause: rc = KEY_PAUSE; break;
case SDLK_PAUSE: return KEY_PAUSE;
case XK_KP_Equal:
case XK_equal: rc = KEY_EQUALS; break;
case SDLK_EQUALS:
case SDLK_KP_EQUALS: return KEY_EQUALS;
case XK_KP_Subtract:
case XK_minus: rc = KEY_MINUS; break;
case SDLK_MINUS: return KEY_MINUS;
case XK_Shift_L:
case XK_Shift_R:
rc = KEY_RSHIFT;
break;
case SDLK_LSHIFT:
case SDLK_RSHIFT:
return KEY_RSHIFT;
case XK_Control_L:
case XK_Control_R:
rc = KEY_RCTRL;
break;
case SDLK_LCTRL:
case SDLK_RCTRL:
return KEY_RCTRL;
case XK_Alt_L:
case XK_Meta_L:
case XK_Alt_R:
case XK_Meta_R:
rc = KEY_RALT;
break;
case SDLK_LALT:
case SDLK_LMETA:
case SDLK_RALT:
case SDLK_RMETA:
return KEY_RALT;
case SDLK_CAPSLOCK: return KEY_CAPSLOCK;
case SDLK_SCROLLOCK: return KEY_SCRLCK;
case SDLK_KP0: return KEYP_0;
case SDLK_KP1: return KEYP_1;
case SDLK_KP2: return KEYP_2;
case SDLK_KP3: return KEYP_3;
case SDLK_KP4: return KEYP_4;
case SDLK_KP5: return KEYP_5;
case SDLK_KP6: return KEYP_6;
case SDLK_KP7: return KEYP_7;
case SDLK_KP8: return KEYP_8;
case SDLK_KP9: return KEYP_9;
case SDLK_HOME: return KEY_HOME;
case SDLK_INSERT: return KEY_INS;
case SDLK_END: return KEY_END;
case SDLK_PAGEUP: return KEY_PGUP;
case SDLK_PAGEDOWN: return KEY_PGDN;
case SDLK_KP_MULTIPLY: return KEYP_MULTIPLY;
case SDLK_KP_PLUS: return KEYP_PLUS;
case SDLK_KP_MINUS: return KEYP_MINUS;
case SDLK_KP_DIVIDE: return KEYP_DIVIDE;
default:
if (rc >= XK_space && rc <= XK_asciitilde)
rc = rc - XK_space + ' ';
if (rc >= 'A' && rc <= 'Z')
rc = rc - 'A' + 'a';
break;
return tolower(sym->unicode);
}
return rc;
}
void I_ShutdownGraphics(void)
{
// Detach from X server
if (X_display && !XShmDetach(X_display, &X_shminfo))
I_Error("XShmDetach() failed in I_ShutdownGraphics()");
// Release shared memory.
shmdt(X_shminfo.shmaddr);
shmctl(X_shminfo.shmid, IPC_RMID, 0);
// Paranoia.
if (image) {
image->data = NULL;
}
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
@ -208,125 +181,102 @@ void I_StartFrame (void)
static int lastmousex = 0;
static int lastmousey = 0;
boolean mousemoved = false;
boolean shmFinished;
void I_GetEvent(void)
{
SDL_Event sdlevent;
event_t event;
// put event-grabbing stuff in here
XNextEvent(X_display, &X_event);
switch (X_event.type)
while (SDL_PollEvent(&sdlevent))
{
case KeyPress:
event.type = ev_keydown;
event.data1 = xlatekey();
D_PostEvent(&event);
// fprintf(stderr, "k");
break;
case KeyRelease:
event.type = ev_keyup;
event.data1 = xlatekey();
D_PostEvent(&event);
// fprintf(stderr, "ku");
break;
case ButtonPress:
event.type = ev_mouse;
event.data1 =
(X_event.xbutton.state & Button1Mask)
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
| (X_event.xbutton.state & Button3Mask ? 4 : 0)
| (X_event.xbutton.button == Button1)
| (X_event.xbutton.button == Button2 ? 2 : 0)
| (X_event.xbutton.button == Button3 ? 4 : 0);
event.data2 = event.data3 = 0;
D_PostEvent(&event);
// fprintf(stderr, "b");
break;
case ButtonRelease:
event.type = ev_mouse;
event.data1 =
(X_event.xbutton.state & Button1Mask)
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
| (X_event.xbutton.state & Button3Mask ? 4 : 0);
// suggest parentheses around arithmetic in operand of |
event.data1 =
event.data1
^ (X_event.xbutton.button == Button1 ? 1 : 0)
^ (X_event.xbutton.button == Button2 ? 2 : 0)
^ (X_event.xbutton.button == Button3 ? 4 : 0);
event.data2 = event.data3 = 0;
D_PostEvent(&event);
// fprintf(stderr, "bu");
break;
case MotionNotify:
event.type = ev_mouse;
event.data1 =
(X_event.xmotion.state & Button1Mask)
| (X_event.xmotion.state & Button2Mask ? 2 : 0)
| (X_event.xmotion.state & Button3Mask ? 4 : 0);
event.data2 = (X_event.xmotion.x - lastmousex) << 2;
event.data3 = (lastmousey - X_event.xmotion.y) << 2;
switch (sdlevent.type)
{
case SDL_KEYDOWN:
event.type = ev_keydown;
event.data1 = xlatekey(&sdlevent.key.keysym);
D_PostEvent(&event);
break;
case SDL_KEYUP:
event.type = ev_keyup;
event.data1 = xlatekey(&sdlevent.key.keysym);
D_PostEvent(&event);
break;
#if 0
case ButtonPress:
event.type = ev_mouse;
event.data1 =
(X_event.xbutton.state & Button1Mask)
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
| (X_event.xbutton.state & Button3Mask ? 4 : 0)
| (X_event.xbutton.button == Button1)
| (X_event.xbutton.button == Button2 ? 2 : 0)
| (X_event.xbutton.button == Button3 ? 4 : 0);
event.data2 = event.data3 = 0;
D_PostEvent(&event);
// fprintf(stderr, "b");
break;
case ButtonRelease:
event.type = ev_mouse;
event.data1 =
(X_event.xbutton.state & Button1Mask)
| (X_event.xbutton.state & Button2Mask ? 2 : 0)
| (X_event.xbutton.state & Button3Mask ? 4 : 0);
// suggest parentheses around arithmetic in operand of |
event.data1 =
event.data1
^ (X_event.xbutton.button == Button1 ? 1 : 0)
^ (X_event.xbutton.button == Button2 ? 2 : 0)
^ (X_event.xbutton.button == Button3 ? 4 : 0);
event.data2 = event.data3 = 0;
D_PostEvent(&event);
// fprintf(stderr, "bu");
break;
case MotionNotify:
event.type = ev_mouse;
event.data1 =
(X_event.xmotion.state & Button1Mask)
| (X_event.xmotion.state & Button2Mask ? 2 : 0)
| (X_event.xmotion.state & Button3Mask ? 4 : 0);
event.data2 = (X_event.xmotion.x - lastmousex) << 2;
event.data3 = (lastmousey - X_event.xmotion.y) << 2;
if (event.data2 || event.data3)
{
lastmousex = X_event.xmotion.x;
lastmousey = X_event.xmotion.y;
if (X_event.xmotion.x != X_width/2 &&
X_event.xmotion.y != X_height/2)
{
D_PostEvent(&event);
// fprintf(stderr, "m");
mousemoved = false;
} else
{
mousemoved = true;
}
}
break;
if (event.data2 || event.data3)
{
lastmousex = X_event.xmotion.x;
lastmousey = X_event.xmotion.y;
if (X_event.xmotion.x != X_width/2 &&
X_event.xmotion.y != X_height/2)
{
D_PostEvent(&event);
// fprintf(stderr, "m");
mousemoved = false;
} else
{
mousemoved = true;
}
}
break;
case Expose:
case ConfigureNotify:
break;
case Expose:
case ConfigureNotify:
break;
default:
if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
break;
default:
if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
break;
#endif
}
}
}
Cursor
createnullcursor
( Display* display,
Window root )
{
Pixmap cursormask;
XGCValues xgc;
GC gc;
XColor dummycolour;
Cursor cursor;
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
xgc.function = GXclear;
gc = XCreateGC(display, cursormask, GCFunction, &xgc);
XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
dummycolour.pixel = 0;
dummycolour.red = 0;
dummycolour.flags = 04;
cursor = XCreatePixmapCursor(display, cursormask, cursormask,
&dummycolour,&dummycolour, 0,0);
XFreePixmap(display,cursormask);
XFreeGC(display,gc);
return cursor;
}
//
// I_StartTic
//
void I_StartTic (void)
{
I_GetEvent();
#if 0
if (!X_display)
return;
@ -353,7 +303,7 @@ void I_StartTic (void)
}
mousemoved = false;
#endif
}
@ -391,7 +341,7 @@ void I_FinishUpdate (void)
screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
}
#if 0
// scales the screen size before blitting it
if (multiply == 2)
{
@ -498,45 +448,11 @@ void I_FinishUpdate (void)
void Expand4(unsigned *, double *);
Expand4 ((unsigned *)(screens[0]), (double *) (image->data));
}
#endif
if (doShm)
{
if (!XShmPutImage( X_display,
X_mainWindow,
X_gc,
image,
0, 0,
0, 0,
X_width, X_height,
True ))
I_Error("XShmPutImage() failed\n");
// wait for it to finish and processes all input events
shmFinished = false;
do
{
I_GetEvent();
} while (!shmFinished);
}
else
{
// draw the image
XPutImage( X_display,
X_mainWindow,
X_gc,
image,
0, 0,
0, 0,
X_width, X_height );
// sync up with server
XSync(X_display, False);
}
// draw to screen
SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
}
@ -549,388 +465,38 @@ void I_ReadScreen (byte* scr)
}
//
// Palette stuff.
//
static XColor colors[256];
void UploadNewPalette(Colormap cmap, byte *palette)
{
register int i;
register int c;
static boolean firstcall = true;
#ifdef __cplusplus
if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)
#else
if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)
#endif
{
// initialize the colormap
if (firstcall)
{
firstcall = false;
for (i=0 ; i<256 ; i++)
{
colors[i].pixel = i;
colors[i].flags = DoRed|DoGreen|DoBlue;
}
}
// set the X colormap entries
for (i=0 ; i<256 ; i++)
{
c = gammatable[usegamma][*palette++];
colors[i].red = (c<<8) + c;
c = gammatable[usegamma][*palette++];
colors[i].green = (c<<8) + c;
c = gammatable[usegamma][*palette++];
colors[i].blue = (c<<8) + c;
}
// store the colors to the current colormap
XStoreColors(X_display, cmap, colors, 256);
}
}
//
// I_SetPalette
//
void I_SetPalette (byte* palette)
{
UploadNewPalette(X_cmap, palette);
SDL_Color sdl_palette[256];
int i;
for (i=0; i<256; ++i)
{
sdl_palette[i].r = *palette++;
sdl_palette[i].g = *palette++;
sdl_palette[i].b = *palette++;
}
SDL_SetColors(screen, sdl_palette, 0, 256);
}
//
// This function is probably redundant,
// if XShmDetach works properly.
// ddt never detached the XShm memory,
// thus there might have been stale
// handles accumulating.
//
void grabsharedmemory(int size)
{
int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm';
struct shmid_ds shminfo;
int minsize = 320*200;
int id;
int rc;
// UNUSED int done=0;
int pollution=5;
// try to use what was here before
do
{
id = shmget((key_t) key, minsize, 0777); // just get the id
if (id != -1)
{
rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it
if (!rc)
{
if (shminfo.shm_nattch)
{
fprintf(stderr, "User %d appears to be running "
"DOOM. Is that wise?\n", shminfo.shm_cpid);
key++;
}
else
{
if (getuid() == shminfo.shm_perm.cuid)
{
rc = shmctl(id, IPC_RMID, 0);
if (!rc)
fprintf(stderr,
"Was able to kill my old shared memory\n");
else
I_Error("Was NOT able to kill my old shared memory");
id = shmget((key_t)key, size, IPC_CREAT|0777);
if (id==-1)
I_Error("Could not get shared memory");
rc=shmctl(id, IPC_STAT, &shminfo);
break;
}
if (size >= shminfo.shm_segsz)
{
fprintf(stderr,
"will use %d's stale shared memory\n",
shminfo.shm_cpid);
break;
}
else
{
fprintf(stderr,
"warning: can't use stale "
"shared memory belonging to id %d, "
"key=0x%x\n",
shminfo.shm_cpid, key);
key++;
}
}
}
else
{
I_Error("could not get stats on key=%d", key);
}
}
else
{
id = shmget((key_t)key, size, IPC_CREAT|0777);
if (id==-1)
{
extern int errno;
fprintf(stderr, "errno=%d\n", errno);
I_Error("Could not get any shared memory");
}
break;
}
} while (--pollution);
if (!pollution)
{
I_Error("Sorry, system too polluted with stale "
"shared memory segments.\n");
}
X_shminfo.shmid = id;
// attach to the shared memory segment
image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id,
(int) (image->data));
}
void I_InitGraphics(void)
{
SDL_Init(SDL_INIT_VIDEO);
char* displayname;
char* d;
int n;
int pnum;
int x=0;
int y=0;
// warning: char format, different type arg
char xsign=' ';
char ysign=' ';
int oktodraw;
unsigned long attribmask;
XSetWindowAttributes attribs;
XGCValues xgcvalues;
int valuemask;
static int firsttime=1;
if (!firsttime)
return;
firsttime = 0;
signal(SIGINT, (void (*)(int)) I_Quit);
if (M_CheckParm("-2"))
multiply = 2;
if (M_CheckParm("-3"))
multiply = 3;
if (M_CheckParm("-4"))
multiply = 4;
X_width = SCREENWIDTH * multiply;
X_height = SCREENHEIGHT * multiply;
// check for command-line display name
if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
displayname = myargv[pnum+1];
else
displayname = 0;
// check if the user wants to grab the mouse (quite unnice)
grabMouse = !!M_CheckParm("-grabmouse");
// check for command-line geometry
if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment
{
// warning: char format, different type arg 3,5
n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y);
if (n==2)
x = y = 0;
else if (n==6)
{
if (xsign == '-')
x = -x;
if (ysign == '-')
y = -y;
}
else
I_Error("bad -geom parameter");
}
// open the display
X_display = XOpenDisplay(displayname);
if (!X_display)
{
if (displayname)
I_Error("Could not open display [%s]", displayname);
else
I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
}
// use the default visual
X_screen = DefaultScreen(X_display);
if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo))
I_Error("xdoom currently only supports 256-color PseudoColor screens");
X_visual = X_visualinfo.visual;
// check for the MITSHM extension
doShm = XShmQueryExtension(X_display);
// even if it's available, make sure it's a local connection
if (doShm)
{
if (!displayname) displayname = (char *) getenv("DISPLAY");
if (displayname)
{
d = displayname;
while (*d && (*d != ':')) d++;
if (*d) *d = 0;
if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false;
}
}
fprintf(stderr, "Using MITSHM extension\n");
// create the colormap
X_cmap = XCreateColormap(X_display, RootWindow(X_display,
X_screen), X_visual, AllocAll);
// setup attributes for main window
attribmask = CWEventMask | CWColormap | CWBorderPixel;
attribs.event_mask =
KeyPressMask
| KeyReleaseMask
// | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
| ExposureMask;
attribs.colormap = X_cmap;
attribs.border_pixel = 0;
// create the main window
X_mainWindow = XCreateWindow( X_display,
RootWindow(X_display, X_screen),
x, y,
X_width, X_height,
0, // borderwidth
8, // depth
InputOutput,
X_visual,
attribmask,
&attribs );
XDefineCursor(X_display, X_mainWindow,
createnullcursor( X_display, X_mainWindow ) );
// create the GC
valuemask = GCGraphicsExposures;
xgcvalues.graphics_exposures = False;
X_gc = XCreateGC( X_display,
X_mainWindow,
valuemask,
&xgcvalues );
// map the window
XMapWindow(X_display, X_mainWindow);
// wait until it is OK to draw
oktodraw = 0;
while (!oktodraw)
{
XNextEvent(X_display, &X_event);
if (X_event.type == Expose
&& !X_event.xexpose.count)
{
oktodraw = 1;
}
}
// grabs the pointer so it is restricted to this window
if (grabMouse)
XGrabPointer(X_display, X_mainWindow, True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
GrabModeAsync, GrabModeAsync,
X_mainWindow, None, CurrentTime);
if (doShm)
{
X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
// create the image
image = XShmCreateImage( X_display,
X_visual,
8,
ZPixmap,
0,
&X_shminfo,
X_width,
X_height );
grabsharedmemory(image->bytes_per_line * image->height);
// UNUSED
// create the shared memory segment
// X_shminfo.shmid = shmget (IPC_PRIVATE,
// image->bytes_per_line * image->height, IPC_CREAT | 0777);
// if (X_shminfo.shmid < 0)
// {
// perror("");
// I_Error("shmget() failed in InitGraphics()");
// }
// fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid);
// attach to the shared memory segment
// image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
if (!image->data)
{
perror("");
I_Error("shmat() failed in InitGraphics()");
}
// get the X server to attach to it
if (!XShmAttach(X_display, &X_shminfo))
I_Error("XShmAttach() failed in InitGraphics()");
}
else
{
image = XCreateImage( X_display,
X_visual,
8,
ZPixmap,
0,
(char*)malloc(X_width * X_height),
X_width, X_height,
8,
X_width );
}
screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, 8, 0);
if (multiply == 1)
screens[0] = (unsigned char *) (image->data);
screens[0] = (unsigned char *) (screen->pixels);
else
screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
SDL_EnableUNICODE(1);
}

View file

@ -1,7 +1,7 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: m_misc.c 19 2005-07-23 19:17:11Z fraggle $
// $Id: m_misc.c 26 2005-07-24 02:14:04Z fraggle $
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 2005 Simon Howard
@ -23,6 +23,12 @@
//
//
// $Log$
// Revision 1.4 2005/07/24 02:14:04 fraggle
// Move to SDL for graphics.
// Translate key scancodes to correct internal format when reading
// settings from config file - backwards compatible with config files
// for original exes
//
// Revision 1.3 2005/07/23 19:17:11 fraggle
// Use ANSI-standard limit constants. Remove LINUX define.
//
@ -41,7 +47,7 @@
//-----------------------------------------------------------------------------
static const char
rcsid[] = "$Id: m_misc.c 19 2005-07-23 19:17:11Z fraggle $";
rcsid[] = "$Id: m_misc.c 26 2005-07-24 02:14:04Z fraggle $";
#include <sys/stat.h>
#include <sys/types.h>
@ -232,14 +238,13 @@ extern int mb_used;
extern char* chat_macros[];
typedef struct
{
char* name;
int* location;
int defaultvalue;
int scantranslate; // PC scan code hack
int untranslated; // lousy hack
int scantranslate; // translate this value to a scancode
int untranslated;
} default_t;
default_t defaults[] =
@ -250,17 +255,17 @@ default_t defaults[] =
{"show_messages",&showMessages, 1},
{"key_right",&key_right, KEY_RIGHTARROW},
{"key_left",&key_left, KEY_LEFTARROW},
{"key_up",&key_up, KEY_UPARROW},
{"key_down",&key_down, KEY_DOWNARROW},
{"key_strafeleft",&key_strafeleft, ','},
{"key_straferight",&key_straferight, '.'},
{"key_right",&key_right, KEY_RIGHTARROW, 1},
{"key_left",&key_left, KEY_LEFTARROW, 1},
{"key_up",&key_up, KEY_UPARROW, 1},
{"key_down",&key_down, KEY_DOWNARROW, 1},
{"key_strafeleft",&key_strafeleft, ',', 1},
{"key_straferight",&key_straferight, '.', 1},
{"key_fire",&key_fire, KEY_RCTRL},
{"key_use",&key_use, ' '},
{"key_strafe",&key_strafe, KEY_RALT},
{"key_speed",&key_speed, KEY_RSHIFT},
{"key_fire",&key_fire, KEY_RCTRL, 1},
{"key_use",&key_use, ' ', 1},
{"key_strafe",&key_strafe, KEY_RALT, 1},
{"key_speed",&key_speed, KEY_RSHIFT, 1},
{"use_mouse",&usemouse, 1},
{"mouseb_fire",&mousebfire,0},
@ -298,10 +303,32 @@ default_t defaults[] =
int numdefaults;
char* defaultfile;
static int scantokey[128] =
{
0 , 27, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', 13, KEY_RCTRL, 'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
'\'', '`', KEY_RSHIFT,'\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT,KEYP_MULTIPLY,
KEY_RALT, ' ', KEY_CAPSLOCK,KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_PAUSE,KEY_SCRLCK,KEY_HOME,
KEYP_UPARROW,KEY_PGUP,KEYP_MINUS,KEYP_LEFTARROW,KEYP_5,KEYP_RIGHTARROW,KEYP_PLUS,KEY_END,
KEYP_DOWNARROW,KEY_PGDN,KEY_INS,KEY_DEL,0, 0, 0, KEY_F11,
KEY_F12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
//
// M_SaveDefaults
//
void M_SaveDefaults (void)
{
int i;
@ -318,6 +345,36 @@ void M_SaveDefaults (void)
&& defaults[i].defaultvalue < 0xfff)
{
v = *defaults[i].location;
// translate keys back to scancodes
if (defaults[i].scantranslate)
{
// use the untranslated version if we can, to reduce
// the possibility of screwing up the user's config
// file
if (defaults[i].untranslated)
{
v = defaults[i].untranslated;
}
else
{
// search for a reverse mapping back to a scancode
// in the scantokey table
int s;
for (s=0; s<128; ++s)
{
if (scantokey[s] == v)
{
v = s;
break;
}
}
}
}
fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
} else {
fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
@ -332,7 +389,6 @@ void M_SaveDefaults (void)
//
// M_LoadDefaults
//
extern byte scantokey[128];
void M_LoadDefaults (void)
{
@ -348,8 +404,10 @@ void M_LoadDefaults (void)
// set everything to base values
numdefaults = sizeof(defaults)/sizeof(defaults[0]);
for (i=0 ; i<numdefaults ; i++)
{
*defaults[i].location = defaults[i].defaultvalue;
defaults[i].untranslated = 0;
}
// check for a custom default file
i = M_CheckParm ("-config");
if (i && i<myargc-1)
@ -385,6 +443,15 @@ void M_LoadDefaults (void)
for (i=0 ; i<numdefaults ; i++)
if (!strcmp(def, defaults[i].name))
{
if (defaults[i].scantranslate)
{
// translate scancodes read from config
// file (save the old value in untranslated)
defaults[i].untranslated = parm;
parm = scantokey[parm];
}
if (!isstring)
*defaults[i].location = parm;
else