mirror of
https://github.com/nzp-team/glquake.git
synced 2024-11-29 15:22:18 +00:00
Fix circlepad look controls
This commit is contained in:
parent
0ac6573d65
commit
b989a18aca
22 changed files with 35 additions and 16328 deletions
BIN
nzportable.3dsx
BIN
nzportable.3dsx
Binary file not shown.
BIN
nzportable.elf
BIN
nzportable.elf
Binary file not shown.
|
@ -36,11 +36,14 @@ cvar_t cl_nolerp = {"cl_nolerp","0"};
|
|||
cvar_t lookspring = {"lookspring","0", true};
|
||||
cvar_t lookstrafe = {"lookstrafe","0", true};
|
||||
cvar_t sensitivity = {"sensitivity","3", true};
|
||||
cvar_t in_tolerance = {"tolerance","0.25", true};
|
||||
cvar_t in_acceleration = {"acceleration","1.0", true};
|
||||
cvar_t in_analog_strafe = {"in_analog_strafe", "0", true};
|
||||
|
||||
cvar_t m_pitch = {"m_pitch","0.022", true};
|
||||
cvar_t m_yaw = {"m_yaw","0.022", true};
|
||||
cvar_t m_forward = {"m_forward","1", true};
|
||||
cvar_t m_side = {"m_side","0.8", true};
|
||||
cvar_t m_pitch = {"m_pitch","-0.22", true};
|
||||
cvar_t m_yaw = {"m_yaw","0", true};
|
||||
cvar_t m_forward = {"m_forward","0", true};
|
||||
cvar_t m_side = {"m_side","0", true};
|
||||
|
||||
|
||||
client_static_t cls;
|
||||
|
@ -741,11 +744,14 @@ void CL_Init (void)
|
|||
Cvar_RegisterVariable (&lookspring);
|
||||
Cvar_RegisterVariable (&lookstrafe);
|
||||
Cvar_RegisterVariable (&sensitivity);
|
||||
Cvar_RegisterVariable (&in_tolerance);
|
||||
Cvar_RegisterVariable (&in_acceleration);
|
||||
|
||||
Cvar_RegisterVariable (&m_pitch);
|
||||
Cvar_RegisterVariable (&m_yaw);
|
||||
Cvar_RegisterVariable (&m_forward);
|
||||
Cvar_RegisterVariable (&m_side);
|
||||
Cvar_RegisterVariable (&in_mlook);
|
||||
|
||||
// Cvar_RegisterVariable (&cl_autofire);
|
||||
|
||||
|
|
|
@ -268,11 +268,16 @@ extern cvar_t cl_pitchdriftspeed;
|
|||
extern cvar_t lookspring;
|
||||
extern cvar_t lookstrafe;
|
||||
extern cvar_t sensitivity;
|
||||
extern cvar_t in_tolerance;
|
||||
extern cvar_t in_acceleration;
|
||||
extern cvar_t in_aimassist;
|
||||
extern cvar_t in_analog_strafe;
|
||||
|
||||
extern cvar_t m_pitch;
|
||||
extern cvar_t m_yaw;
|
||||
extern cvar_t m_forward;
|
||||
extern cvar_t m_side;
|
||||
extern cvar_t in_mlook;
|
||||
|
||||
|
||||
#define MAX_TEMP_ENTITIES 64 // lightning bolts, etc
|
||||
|
|
|
@ -1,866 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vt.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*#include "vga.h" */
|
||||
#include "vgakeyboard.h"
|
||||
#include "vgamouse.h"
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "GL/fxmesa.h"
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
static fxMesaContext fc = NULL;
|
||||
#define stringify(m) { #m, m }
|
||||
|
||||
unsigned short d_8to16table[256];
|
||||
unsigned d_8to24table[256];
|
||||
unsigned char d_15to8table[65536];
|
||||
|
||||
int num_shades=32;
|
||||
|
||||
struct
|
||||
{
|
||||
char *name;
|
||||
int num;
|
||||
} mice[] =
|
||||
{
|
||||
stringify(MOUSE_MICROSOFT),
|
||||
stringify(MOUSE_MOUSESYSTEMS),
|
||||
stringify(MOUSE_MMSERIES),
|
||||
stringify(MOUSE_LOGITECH),
|
||||
stringify(MOUSE_BUSMOUSE),
|
||||
stringify(MOUSE_PS2),
|
||||
};
|
||||
|
||||
static unsigned char scantokey[128];
|
||||
|
||||
int num_mice = sizeof (mice) / sizeof(mice[0]);
|
||||
|
||||
int d_con_indirect = 0;
|
||||
|
||||
int svgalib_inited=0;
|
||||
int UseMouse = 1;
|
||||
int UseKeyboard = 1;
|
||||
|
||||
int mouserate = MOUSE_DEFAULTSAMPLERATE;
|
||||
|
||||
cvar_t vid_mode = {"vid_mode","5",false};
|
||||
cvar_t vid_redrawfull = {"vid_redrawfull","0",false};
|
||||
cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true};
|
||||
|
||||
char *framebuffer_ptr;
|
||||
|
||||
cvar_t mouse_button_commands[3] =
|
||||
{
|
||||
{"mouse1","+attack"},
|
||||
{"mouse2","+strafe"},
|
||||
{"mouse3","+forward"},
|
||||
};
|
||||
|
||||
int mouse_buttons;
|
||||
int mouse_buttonstate;
|
||||
int mouse_oldbuttonstate;
|
||||
float mouse_x, mouse_y;
|
||||
float old_mouse_x, old_mouse_y;
|
||||
int mx, my;
|
||||
|
||||
cvar_t m_filter = {"m_filter","1"};
|
||||
|
||||
int scr_width, scr_height;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
//int texture_mode = GL_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
|
||||
int texture_mode = GL_LINEAR;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
|
||||
|
||||
int texture_extension_number = 1;
|
||||
|
||||
float gldepthmin, gldepthmax;
|
||||
|
||||
cvar_t gl_ztrick = {"gl_ztrick","1"};
|
||||
|
||||
const char *gl_vendor;
|
||||
const char *gl_renderer;
|
||||
const char *gl_version;
|
||||
const char *gl_extensions;
|
||||
|
||||
void (*qgl3DfxSetPaletteEXT) (GLuint *);
|
||||
void (*qglColorTableEXT) (int, int, int, int, int, const void *);
|
||||
|
||||
static float vid_gamma = 1.0;
|
||||
|
||||
qboolean is8bit = false;
|
||||
qboolean isPermedia = false;
|
||||
qboolean gl_mtexable = false;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void D_EndDirectRect (int x, int y, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
int matchmouse(int mouse, char *name)
|
||||
{
|
||||
int i;
|
||||
for (i=0 ; i<num_mice ; i++)
|
||||
if (!strcmp(mice[i].name, name))
|
||||
return i;
|
||||
return mouse;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void vtswitch(int newconsole)
|
||||
{
|
||||
|
||||
int fd;
|
||||
struct vt_stat x;
|
||||
|
||||
// switch consoles and wait until reactivated
|
||||
fd = open("/dev/console", O_RDONLY);
|
||||
ioctl(fd, VT_GETSTATE, &x);
|
||||
ioctl(fd, VT_ACTIVATE, newconsole);
|
||||
ioctl(fd, VT_WAITACTIVE, x.v_active);
|
||||
close(fd);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void keyhandler(int scancode, int state)
|
||||
{
|
||||
|
||||
int sc;
|
||||
|
||||
sc = scancode & 0x7f;
|
||||
|
||||
Key_Event(scantokey[sc], state == KEY_EVENTPRESS);
|
||||
|
||||
}
|
||||
|
||||
void VID_Shutdown(void)
|
||||
{
|
||||
if (!fc)
|
||||
return;
|
||||
|
||||
fxMesaDestroyContext(fc);
|
||||
|
||||
if (UseKeyboard)
|
||||
keyboard_close();
|
||||
}
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
printf("Received signal %d, exiting...\n", sig);
|
||||
Sys_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void InitSig(void)
|
||||
{
|
||||
signal(SIGHUP, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGQUIT, signal_handler);
|
||||
signal(SIGILL, signal_handler);
|
||||
signal(SIGTRAP, signal_handler);
|
||||
signal(SIGIOT, signal_handler);
|
||||
signal(SIGBUS, signal_handler);
|
||||
signal(SIGFPE, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
}
|
||||
|
||||
void VID_ShiftPalette(unsigned char *p)
|
||||
{
|
||||
// VID_SetPalette(p);
|
||||
}
|
||||
|
||||
void VID_SetPalette (unsigned char *palette)
|
||||
{
|
||||
byte *pal;
|
||||
unsigned r,g,b;
|
||||
unsigned v;
|
||||
int r1,g1,b1;
|
||||
int j,k,l,m;
|
||||
unsigned short i;
|
||||
unsigned *table;
|
||||
FILE *f;
|
||||
char s[255];
|
||||
int dist, bestdist;
|
||||
static qboolean palflag = false;
|
||||
|
||||
//
|
||||
// 8 8 8 encoding
|
||||
//
|
||||
pal = palette;
|
||||
table = d_8to24table;
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
r = pal[0];
|
||||
g = pal[1];
|
||||
b = pal[2];
|
||||
pal += 3;
|
||||
|
||||
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
|
||||
*table++ = v;
|
||||
}
|
||||
d_8to24table[255] &= 0xffffff; // 255 is transparent
|
||||
|
||||
// JACK: 3D distance calcs - k is last closest, l is the distance.
|
||||
for (i=0; i < (1<<15); i++) {
|
||||
/* Maps
|
||||
000000000000000
|
||||
000000000011111 = Red = 0x1F
|
||||
000001111100000 = Blue = 0x03E0
|
||||
111110000000000 = Grn = 0x7C00
|
||||
*/
|
||||
r = ((i & 0x1F) << 3)+4;
|
||||
g = ((i & 0x03E0) >> 2)+4;
|
||||
b = ((i & 0x7C00) >> 7)+4;
|
||||
pal = (unsigned char *)d_8to24table;
|
||||
for (v=0,k=0,bestdist=10000*10000; v<256; v++,pal+=4) {
|
||||
r1 = (int)r - (int)pal[0];
|
||||
g1 = (int)g - (int)pal[1];
|
||||
b1 = (int)b - (int)pal[2];
|
||||
dist = (r1*r1)+(g1*g1)+(b1*b1);
|
||||
if (dist < bestdist) {
|
||||
k=v;
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
d_15to8table[i]=k;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMultiTextureExtensions(void)
|
||||
{
|
||||
void *prjobj;
|
||||
|
||||
if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) {
|
||||
Con_Printf("Found GL_SGIS_multitexture...\n");
|
||||
|
||||
if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
|
||||
Con_Printf("Unable to open symbol list for main program.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS");
|
||||
qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS");
|
||||
|
||||
if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) {
|
||||
Con_Printf("Multitexture extensions found.\n");
|
||||
gl_mtexable = true;
|
||||
} else
|
||||
Con_Printf("Symbol not found, disabled.\n");
|
||||
|
||||
dlclose(prjobj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
GL_Init
|
||||
===============
|
||||
*/
|
||||
void GL_Init (void)
|
||||
{
|
||||
gl_vendor = glGetString (GL_VENDOR);
|
||||
Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
|
||||
gl_renderer = glGetString (GL_RENDERER);
|
||||
Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
|
||||
|
||||
gl_version = glGetString (GL_VERSION);
|
||||
Con_Printf ("GL_VERSION: %s\n", gl_version);
|
||||
gl_extensions = glGetString (GL_EXTENSIONS);
|
||||
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
|
||||
|
||||
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
|
||||
|
||||
CheckMultiTextureExtensions ();
|
||||
|
||||
glClearColor (1,0,0,0);
|
||||
glCullFace(GL_FRONT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.666);
|
||||
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel (GL_FLAT);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GL_BeginRendering
|
||||
|
||||
=================
|
||||
*/
|
||||
void GL_BeginRendering (int *x, int *y, int *width, int *height)
|
||||
{
|
||||
extern cvar_t gl_clear;
|
||||
|
||||
*x = *y = 0;
|
||||
*width = scr_width;
|
||||
*height = scr_height;
|
||||
|
||||
// if (!wglMakeCurrent( maindc, baseRC ))
|
||||
// Sys_Error ("wglMakeCurrent failed");
|
||||
|
||||
// glViewport (*x, *y, *width, *height);
|
||||
}
|
||||
|
||||
|
||||
void GL_EndRendering (void)
|
||||
{
|
||||
glFlush();
|
||||
fxMesaSwapBuffers();
|
||||
}
|
||||
|
||||
void Init_KBD(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (COM_CheckParm("-nokbd")) UseKeyboard = 0;
|
||||
|
||||
if (UseKeyboard)
|
||||
{
|
||||
for (i=0 ; i<128 ; i++)
|
||||
scantokey[i] = ' ';
|
||||
|
||||
scantokey[42] = K_SHIFT;
|
||||
scantokey[54] = K_SHIFT;
|
||||
scantokey[72] = K_UPARROW;
|
||||
scantokey[103] = K_UPARROW;
|
||||
scantokey[80] = K_DOWNARROW;
|
||||
scantokey[108] = K_DOWNARROW;
|
||||
scantokey[75] = K_LEFTARROW;
|
||||
scantokey[105] = K_LEFTARROW;
|
||||
scantokey[77] = K_RIGHTARROW;
|
||||
scantokey[106] = K_RIGHTARROW;
|
||||
scantokey[29] = K_CTRL;
|
||||
scantokey[97] = K_CTRL;
|
||||
scantokey[56] = K_ALT;
|
||||
scantokey[100] = K_ALT;
|
||||
// scantokey[58] = JK_CAPS;
|
||||
// scantokey[69] = JK_NUM_LOCK;
|
||||
scantokey[71] = K_HOME;
|
||||
scantokey[73] = K_PGUP;
|
||||
scantokey[79] = K_END;
|
||||
scantokey[81] = K_PGDN;
|
||||
scantokey[82] = K_INS;
|
||||
scantokey[83] = K_DEL;
|
||||
scantokey[1 ] = K_ESCAPE;
|
||||
scantokey[28] = K_ENTER;
|
||||
scantokey[15] = K_TAB;
|
||||
scantokey[14] = K_BACKSPACE;
|
||||
scantokey[119] = K_PAUSE;
|
||||
scantokey[57] = ' ';
|
||||
|
||||
scantokey[102] = K_HOME;
|
||||
scantokey[104] = K_PGUP;
|
||||
scantokey[107] = K_END;
|
||||
scantokey[109] = K_PGDN;
|
||||
scantokey[110] = K_INS;
|
||||
scantokey[111] = K_DEL;
|
||||
|
||||
scantokey[2] = '1';
|
||||
scantokey[3] = '2';
|
||||
scantokey[4] = '3';
|
||||
scantokey[5] = '4';
|
||||
scantokey[6] = '5';
|
||||
scantokey[7] = '6';
|
||||
scantokey[8] = '7';
|
||||
scantokey[9] = '8';
|
||||
scantokey[10] = '9';
|
||||
scantokey[11] = '0';
|
||||
scantokey[12] = '-';
|
||||
scantokey[13] = '=';
|
||||
scantokey[41] = '`';
|
||||
scantokey[26] = '[';
|
||||
scantokey[27] = ']';
|
||||
scantokey[39] = ';';
|
||||
scantokey[40] = '\'';
|
||||
scantokey[51] = ',';
|
||||
scantokey[52] = '.';
|
||||
scantokey[53] = '/';
|
||||
scantokey[43] = '\\';
|
||||
|
||||
scantokey[59] = K_F1;
|
||||
scantokey[60] = K_F2;
|
||||
scantokey[61] = K_F3;
|
||||
scantokey[62] = K_F4;
|
||||
scantokey[63] = K_F5;
|
||||
scantokey[64] = K_F6;
|
||||
scantokey[65] = K_F7;
|
||||
scantokey[66] = K_F8;
|
||||
scantokey[67] = K_F9;
|
||||
scantokey[68] = K_F10;
|
||||
scantokey[87] = K_F11;
|
||||
scantokey[88] = K_F12;
|
||||
scantokey[30] = 'a';
|
||||
scantokey[48] = 'b';
|
||||
scantokey[46] = 'c';
|
||||
scantokey[32] = 'd';
|
||||
scantokey[18] = 'e';
|
||||
scantokey[33] = 'f';
|
||||
scantokey[34] = 'g';
|
||||
scantokey[35] = 'h';
|
||||
scantokey[23] = 'i';
|
||||
scantokey[36] = 'j';
|
||||
scantokey[37] = 'k';
|
||||
scantokey[38] = 'l';
|
||||
scantokey[50] = 'm';
|
||||
scantokey[49] = 'n';
|
||||
scantokey[24] = 'o';
|
||||
scantokey[25] = 'p';
|
||||
scantokey[16] = 'q';
|
||||
scantokey[19] = 'r';
|
||||
scantokey[31] = 's';
|
||||
scantokey[20] = 't';
|
||||
scantokey[22] = 'u';
|
||||
scantokey[47] = 'v';
|
||||
scantokey[17] = 'w';
|
||||
scantokey[45] = 'x';
|
||||
scantokey[21] = 'y';
|
||||
scantokey[44] = 'z';
|
||||
|
||||
scantokey[78] = '+';
|
||||
scantokey[74] = '-';
|
||||
|
||||
if (keyboard_init())
|
||||
Sys_Error("keyboard_init() failed");
|
||||
keyboard_seteventhandler(keyhandler);
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_RESOLUTIONS 16
|
||||
|
||||
static int resolutions[NUM_RESOLUTIONS][3]={
|
||||
320,200, GR_RESOLUTION_320x200,
|
||||
320,240, GR_RESOLUTION_320x240,
|
||||
400,256, GR_RESOLUTION_400x256,
|
||||
400,300, GR_RESOLUTION_400x300,
|
||||
512,384, GR_RESOLUTION_512x384,
|
||||
640,200, GR_RESOLUTION_640x200,
|
||||
640,350, GR_RESOLUTION_640x350,
|
||||
640,400, GR_RESOLUTION_640x400,
|
||||
640,480, GR_RESOLUTION_640x480,
|
||||
800,600, GR_RESOLUTION_800x600,
|
||||
960,720, GR_RESOLUTION_960x720,
|
||||
856,480, GR_RESOLUTION_856x480,
|
||||
512,256, GR_RESOLUTION_512x256,
|
||||
1024,768, GR_RESOLUTION_1024x768,
|
||||
1280,1024,GR_RESOLUTION_1280x1024,
|
||||
1600,1200,GR_RESOLUTION_1600x1200
|
||||
};
|
||||
|
||||
int findres(int *width, int *height)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<NUM_RESOLUTIONS;i++)
|
||||
if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) {
|
||||
*width = resolutions[i][0];
|
||||
*height = resolutions[i][1];
|
||||
return resolutions[i][2];
|
||||
}
|
||||
|
||||
*width = 640;
|
||||
*height = 480;
|
||||
return GR_RESOLUTION_640x480;
|
||||
}
|
||||
|
||||
qboolean VID_Is8bit(void)
|
||||
{
|
||||
return is8bit;
|
||||
}
|
||||
|
||||
void VID_Init8bitPalette(void)
|
||||
{
|
||||
// Check for 8bit Extensions and initialize them.
|
||||
int i;
|
||||
void *prjobj;
|
||||
|
||||
if (COM_CheckParm("-no8bit"))
|
||||
return;
|
||||
|
||||
if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
|
||||
Con_Printf("Unable to open symbol list for main program.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strstr(gl_extensions, "3DFX_set_global_palette") &&
|
||||
(qgl3DfxSetPaletteEXT = dlsym(prjobj, "gl3DfxSetPaletteEXT")) != NULL) {
|
||||
GLubyte table[256][4];
|
||||
char *oldpal;
|
||||
|
||||
Con_SafePrintf("... Using 3DFX_set_global_palette\n");
|
||||
glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
|
||||
oldpal = (char *) d_8to24table; //d_8to24table3dfx;
|
||||
for (i=0;i<256;i++) {
|
||||
table[i][2] = *oldpal++;
|
||||
table[i][1] = *oldpal++;
|
||||
table[i][0] = *oldpal++;
|
||||
table[i][3] = 255;
|
||||
oldpal++;
|
||||
}
|
||||
qgl3DfxSetPaletteEXT((GLuint *)table);
|
||||
is8bit = true;
|
||||
|
||||
} else if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") &&
|
||||
(qglColorTableEXT = dlsym(prjobj, "glColorTableEXT")) != NULL) {
|
||||
char thePalette[256*3];
|
||||
char *oldPalette, *newPalette;
|
||||
|
||||
Con_SafePrintf("... Using GL_EXT_shared_texture_palette\n");
|
||||
glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
|
||||
oldPalette = (char *) d_8to24table; //d_8to24table3dfx;
|
||||
newPalette = thePalette;
|
||||
for (i=0;i<256;i++) {
|
||||
*newPalette++ = *oldPalette++;
|
||||
*newPalette++ = *oldPalette++;
|
||||
*newPalette++ = *oldPalette++;
|
||||
oldPalette++;
|
||||
}
|
||||
qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
|
||||
is8bit = true;
|
||||
|
||||
}
|
||||
|
||||
dlclose(prjobj);
|
||||
}
|
||||
|
||||
static void Check_Gamma (unsigned char *pal)
|
||||
{
|
||||
float f, inf;
|
||||
unsigned char palette[768];
|
||||
int i;
|
||||
|
||||
if ((i = COM_CheckParm("-gamma")) == 0) {
|
||||
if ((gl_renderer && strstr(gl_renderer, "Voodoo")) ||
|
||||
(gl_vendor && strstr(gl_vendor, "3Dfx")))
|
||||
vid_gamma = 1;
|
||||
else
|
||||
vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware
|
||||
} else
|
||||
vid_gamma = Q_atof(com_argv[i+1]);
|
||||
|
||||
for (i=0 ; i<768 ; i++)
|
||||
{
|
||||
f = pow ( (pal[i]+1)/256.0 , vid_gamma );
|
||||
inf = f*255 + 0.5;
|
||||
if (inf < 0)
|
||||
inf = 0;
|
||||
if (inf > 255)
|
||||
inf = 255;
|
||||
palette[i] = inf;
|
||||
}
|
||||
|
||||
memcpy (pal, palette, sizeof(palette));
|
||||
}
|
||||
|
||||
void VID_Init(unsigned char *palette)
|
||||
{
|
||||
int i;
|
||||
GLint attribs[32];
|
||||
char gldir[MAX_OSPATH];
|
||||
int width = 640, height = 480;
|
||||
|
||||
Init_KBD();
|
||||
|
||||
Cvar_RegisterVariable (&vid_mode);
|
||||
Cvar_RegisterVariable (&vid_redrawfull);
|
||||
Cvar_RegisterVariable (&vid_waitforrefresh);
|
||||
Cvar_RegisterVariable (&gl_ztrick);
|
||||
|
||||
vid.maxwarpwidth = WARP_WIDTH;
|
||||
vid.maxwarpheight = WARP_HEIGHT;
|
||||
vid.colormap = host_colormap;
|
||||
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
|
||||
|
||||
// interpret command-line params
|
||||
|
||||
// set vid parameters
|
||||
attribs[0] = FXMESA_DOUBLEBUFFER;
|
||||
attribs[1] = FXMESA_ALPHA_SIZE;
|
||||
attribs[2] = 1;
|
||||
attribs[3] = FXMESA_DEPTH_SIZE;
|
||||
attribs[4] = 1;
|
||||
attribs[5] = FXMESA_NONE;
|
||||
|
||||
if ((i = COM_CheckParm("-width")) != 0)
|
||||
width = atoi(com_argv[i+1]);
|
||||
if ((i = COM_CheckParm("-height")) != 0)
|
||||
height = atoi(com_argv[i+1]);
|
||||
|
||||
if ((i = COM_CheckParm("-conwidth")) != 0)
|
||||
vid.conwidth = Q_atoi(com_argv[i+1]);
|
||||
else
|
||||
vid.conwidth = 640;
|
||||
|
||||
vid.conwidth &= 0xfff8; // make it a multiple of eight
|
||||
|
||||
if (vid.conwidth < 320)
|
||||
vid.conwidth = 320;
|
||||
|
||||
// pick a conheight that matches with correct aspect
|
||||
vid.conheight = vid.conwidth*3 / 4;
|
||||
|
||||
if ((i = COM_CheckParm("-conheight")) != 0)
|
||||
vid.conheight = Q_atoi(com_argv[i+1]);
|
||||
if (vid.conheight < 200)
|
||||
vid.conheight = 200;
|
||||
|
||||
fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz,
|
||||
attribs);
|
||||
if (!fc)
|
||||
Sys_Error("Unable to create 3DFX context.\n");
|
||||
|
||||
InitSig(); // trap evil signals
|
||||
|
||||
scr_width = width;
|
||||
scr_height = height;
|
||||
|
||||
fxMesaMakeCurrent(fc);
|
||||
|
||||
if (vid.conheight > height)
|
||||
vid.conheight = height;
|
||||
if (vid.conwidth > width)
|
||||
vid.conwidth = width;
|
||||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
|
||||
vid.aspect = ((float)vid.height / (float)vid.width) *
|
||||
(320.0 / 240.0);
|
||||
vid.numpages = 2;
|
||||
|
||||
GL_Init();
|
||||
|
||||
sprintf (gldir, "%s/glquake", com_gamedir);
|
||||
Sys_mkdir (gldir);
|
||||
|
||||
Check_Gamma(palette);
|
||||
VID_SetPalette(palette);
|
||||
|
||||
// Check for 3DFX Extensions and initialize them.
|
||||
VID_Init8bitPalette();
|
||||
|
||||
Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
|
||||
|
||||
vid.recalc_refdef = 1; // force a surface cache flush
|
||||
}
|
||||
|
||||
void Sys_SendKeyEvents(void)
|
||||
{
|
||||
if (UseKeyboard)
|
||||
while (keyboard_update());
|
||||
}
|
||||
|
||||
void Force_CenterView_f (void)
|
||||
{
|
||||
cl.viewangles[PITCH] = 0;
|
||||
}
|
||||
|
||||
|
||||
void mousehandler(int buttonstate, int dx, int dy)
|
||||
{
|
||||
mouse_buttonstate = buttonstate;
|
||||
mx += dx;
|
||||
my += dy;
|
||||
}
|
||||
|
||||
void IN_Init(void)
|
||||
{
|
||||
|
||||
int mtype;
|
||||
char *mousedev;
|
||||
int mouserate;
|
||||
|
||||
if (UseMouse)
|
||||
{
|
||||
|
||||
Cvar_RegisterVariable (&mouse_button_commands[0]);
|
||||
Cvar_RegisterVariable (&mouse_button_commands[1]);
|
||||
Cvar_RegisterVariable (&mouse_button_commands[2]);
|
||||
Cmd_AddCommand ("force_centerview", Force_CenterView_f);
|
||||
|
||||
mouse_buttons = 3;
|
||||
|
||||
mtype = vga_getmousetype();
|
||||
|
||||
mousedev = "/dev/mouse";
|
||||
if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV");
|
||||
if (COM_CheckParm("-mdev"))
|
||||
mousedev = com_argv[COM_CheckParm("-mdev")+1];
|
||||
|
||||
mouserate = 1200;
|
||||
if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE"));
|
||||
if (COM_CheckParm("-mrate"))
|
||||
mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]);
|
||||
|
||||
if (mouse_init(mousedev, mtype, mouserate))
|
||||
{
|
||||
Con_Printf("No mouse found\n");
|
||||
UseMouse = 0;
|
||||
}
|
||||
else
|
||||
mouse_seteventhandler(mousehandler);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void IN_Shutdown(void)
|
||||
{
|
||||
if (UseMouse)
|
||||
mouse_close();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
if (UseMouse && cls.state != ca_dedicated)
|
||||
{
|
||||
// poll mouse values
|
||||
while (mouse_update())
|
||||
;
|
||||
|
||||
// perform button actions
|
||||
if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
|
||||
Key_Event (K_MOUSE1, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
|
||||
Key_Event (K_MOUSE1, false);
|
||||
|
||||
if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
|
||||
Key_Event (K_MOUSE2, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
|
||||
Key_Event (K_MOUSE2, false);
|
||||
|
||||
if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
|
||||
!(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
|
||||
Key_Event (K_MOUSE3, true);
|
||||
else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
|
||||
(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
|
||||
Key_Event (K_MOUSE3, false);
|
||||
|
||||
mouse_oldbuttonstate = mouse_buttonstate;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_MouseMove (usercmd_t *cmd)
|
||||
{
|
||||
if (!UseMouse)
|
||||
return;
|
||||
|
||||
// poll mouse values
|
||||
while (mouse_update())
|
||||
;
|
||||
|
||||
if (m_filter.value)
|
||||
{
|
||||
mouse_x = (mx + old_mouse_x) * 0.5;
|
||||
mouse_y = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x = mx;
|
||||
mouse_y = my;
|
||||
}
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
mx = my = 0; // clear for next update
|
||||
|
||||
mouse_x *= sensitivity.value;
|
||||
mouse_y *= sensitivity.value;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
|
||||
cmd->sidemove += m_side.value * mouse_x;
|
||||
else
|
||||
cl.viewangles[YAW] -= m_yaw.value * mouse_x;
|
||||
|
||||
if (in_mlook.state & 1)
|
||||
V_StopPitchDrift ();
|
||||
|
||||
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
|
||||
{
|
||||
cl.viewangles[PITCH] += m_pitch.value * mouse_y;
|
||||
if (cl.viewangles[PITCH] > 80)
|
||||
cl.viewangles[PITCH] = 80;
|
||||
if (cl.viewangles[PITCH] < -70)
|
||||
cl.viewangles[PITCH] = -70;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in_strafe.state & 1) && noclip_anglehack)
|
||||
cmd->upmove -= m_forward.value * mouse_y;
|
||||
else
|
||||
cmd->forwardmove -= m_forward.value * mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
IN_MouseMove(cmd);
|
||||
}
|
||||
|
||||
|
|
@ -1,997 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/vt.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#include <GL/glx.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include <X11/extensions/xf86dga.h>
|
||||
#include <X11/extensions/xf86vmode.h>
|
||||
|
||||
#define WARP_WIDTH 320
|
||||
#define WARP_HEIGHT 200
|
||||
|
||||
static Display *dpy = NULL;
|
||||
static int scrnum;
|
||||
static Window win;
|
||||
static GLXContext ctx = NULL;
|
||||
|
||||
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
|
||||
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
|
||||
PointerMotionMask | ButtonMotionMask )
|
||||
#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask )
|
||||
|
||||
|
||||
unsigned short d_8to16table[256];
|
||||
unsigned d_8to24table[256];
|
||||
unsigned char d_15to8table[65536];
|
||||
|
||||
cvar_t vid_mode = {"vid_mode","0",false};
|
||||
|
||||
static qboolean mouse_avail;
|
||||
static qboolean mouse_active;
|
||||
static int mx, my;
|
||||
static int old_mouse_x, old_mouse_y;
|
||||
|
||||
static cvar_t in_mouse = {"in_mouse", "1", false};
|
||||
static cvar_t in_dgamouse = {"in_dgamouse", "1", false};
|
||||
static cvar_t m_filter = {"m_filter", "0"};
|
||||
|
||||
qboolean dgamouse = false;
|
||||
qboolean vidmode_ext = false;
|
||||
|
||||
static int win_x, win_y;
|
||||
|
||||
static int scr_width, scr_height;
|
||||
|
||||
static XF86VidModeModeInfo **vidmodes;
|
||||
static int default_dotclock_vidmode;
|
||||
static int num_vidmodes;
|
||||
static qboolean vidmode_active = false;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
//int texture_mode = GL_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
|
||||
int texture_mode = GL_LINEAR;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
|
||||
//int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
|
||||
|
||||
int texture_extension_number = 1;
|
||||
|
||||
float gldepthmin, gldepthmax;
|
||||
|
||||
cvar_t gl_ztrick = {"gl_ztrick","1"};
|
||||
|
||||
const char *gl_vendor;
|
||||
const char *gl_renderer;
|
||||
const char *gl_version;
|
||||
const char *gl_extensions;
|
||||
|
||||
void (*qglColorTableEXT) (int, int, int, int, int, const void*);
|
||||
void (*qgl3DfxSetPaletteEXT) (GLuint *);
|
||||
|
||||
static float vid_gamma = 1.0;
|
||||
|
||||
qboolean is8bit = false;
|
||||
qboolean isPermedia = false;
|
||||
qboolean gl_mtexable = false;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
void D_EndDirectRect (int x, int y, int width, int height)
|
||||
{
|
||||
}
|
||||
|
||||
static int XLateKey(XKeyEvent *ev)
|
||||
{
|
||||
|
||||
int key;
|
||||
char buf[64];
|
||||
KeySym keysym;
|
||||
|
||||
key = 0;
|
||||
|
||||
XLookupString(ev, buf, sizeof buf, &keysym, 0);
|
||||
|
||||
switch(keysym)
|
||||
{
|
||||
case XK_KP_Page_Up:
|
||||
case XK_Page_Up: key = K_PGUP; break;
|
||||
|
||||
case XK_KP_Page_Down:
|
||||
case XK_Page_Down: key = K_PGDN; break;
|
||||
|
||||
case XK_KP_Home:
|
||||
case XK_Home: key = K_HOME; break;
|
||||
|
||||
case XK_KP_End:
|
||||
case XK_End: key = K_END; break;
|
||||
|
||||
case XK_KP_Left:
|
||||
case XK_Left: key = K_LEFTARROW; break;
|
||||
|
||||
case XK_KP_Right:
|
||||
case XK_Right: key = K_RIGHTARROW; break;
|
||||
|
||||
case XK_KP_Down:
|
||||
case XK_Down: key = K_DOWNARROW; break;
|
||||
|
||||
case XK_KP_Up:
|
||||
case XK_Up: key = K_UPARROW; break;
|
||||
|
||||
case XK_Escape: key = K_ESCAPE; break;
|
||||
|
||||
case XK_KP_Enter:
|
||||
case XK_Return: key = K_ENTER; break;
|
||||
|
||||
case XK_Tab: key = K_TAB; break;
|
||||
|
||||
case XK_F1: key = K_F1; break;
|
||||
|
||||
case XK_F2: key = K_F2; break;
|
||||
|
||||
case XK_F3: key = K_F3; break;
|
||||
|
||||
case XK_F4: key = K_F4; break;
|
||||
|
||||
case XK_F5: key = K_F5; break;
|
||||
|
||||
case XK_F6: key = K_F6; break;
|
||||
|
||||
case XK_F7: key = K_F7; break;
|
||||
|
||||
case XK_F8: key = K_F8; break;
|
||||
|
||||
case XK_F9: key = K_F9; break;
|
||||
|
||||
case XK_F10: key = K_F10; break;
|
||||
|
||||
case XK_F11: key = K_F11; break;
|
||||
|
||||
case XK_F12: key = K_F12; break;
|
||||
|
||||
case XK_BackSpace: key = K_BACKSPACE; break;
|
||||
|
||||
case XK_KP_Delete:
|
||||
case XK_Delete: key = K_DEL; break;
|
||||
|
||||
case XK_Pause: key = K_PAUSE; break;
|
||||
|
||||
case XK_Shift_L:
|
||||
case XK_Shift_R: key = K_SHIFT; break;
|
||||
|
||||
case XK_Execute:
|
||||
case XK_Control_L:
|
||||
case XK_Control_R: key = K_CTRL; break;
|
||||
|
||||
case XK_Alt_L:
|
||||
case XK_Meta_L:
|
||||
case XK_Alt_R:
|
||||
case XK_Meta_R: key = K_ALT; break;
|
||||
|
||||
case XK_KP_Begin: key = '5'; break;
|
||||
|
||||
case XK_KP_Insert:
|
||||
case XK_Insert:key = K_INS; break;
|
||||
|
||||
case XK_KP_Multiply: key = '*'; break;
|
||||
case XK_KP_Add: key = '+'; break;
|
||||
case XK_KP_Subtract: key = '-'; break;
|
||||
case XK_KP_Divide: key = '/'; break;
|
||||
|
||||
#if 0
|
||||
case 0x021: key = '1';break;/* [!] */
|
||||
case 0x040: key = '2';break;/* [@] */
|
||||
case 0x023: key = '3';break;/* [#] */
|
||||
case 0x024: key = '4';break;/* [$] */
|
||||
case 0x025: key = '5';break;/* [%] */
|
||||
case 0x05e: key = '6';break;/* [^] */
|
||||
case 0x026: key = '7';break;/* [&] */
|
||||
case 0x02a: key = '8';break;/* [*] */
|
||||
case 0x028: key = '9';;break;/* [(] */
|
||||
case 0x029: key = '0';break;/* [)] */
|
||||
case 0x05f: key = '-';break;/* [_] */
|
||||
case 0x02b: key = '=';break;/* [+] */
|
||||
case 0x07c: key = '\'';break;/* [|] */
|
||||
case 0x07d: key = '[';break;/* [}] */
|
||||
case 0x07b: key = ']';break;/* [{] */
|
||||
case 0x022: key = '\'';break;/* ["] */
|
||||
case 0x03a: key = ';';break;/* [:] */
|
||||
case 0x03f: key = '/';break;/* [?] */
|
||||
case 0x03e: key = '.';break;/* [>] */
|
||||
case 0x03c: key = ',';break;/* [<] */
|
||||
#endif
|
||||
|
||||
default:
|
||||
key = *(unsigned char*)buf;
|
||||
if (key >= 'A' && key <= 'Z')
|
||||
key = key - 'A' + 'a';
|
||||
break;
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static void install_grabs(void)
|
||||
{
|
||||
|
||||
// inviso cursor
|
||||
XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
|
||||
|
||||
XGrabPointer(dpy, win,
|
||||
True,
|
||||
0,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
win,
|
||||
None,
|
||||
CurrentTime);
|
||||
|
||||
if (in_dgamouse.value) {
|
||||
int MajorVersion, MinorVersion;
|
||||
|
||||
if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
|
||||
// unable to query, probalby not supported
|
||||
Con_Printf( "Failed to detect XF86DGA Mouse\n" );
|
||||
in_dgamouse.value = 0;
|
||||
} else {
|
||||
dgamouse = true;
|
||||
XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
|
||||
XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
XWarpPointer(dpy, None, win,
|
||||
0, 0, 0, 0,
|
||||
vid.width / 2, vid.height / 2);
|
||||
}
|
||||
|
||||
XGrabKeyboard(dpy, win,
|
||||
False,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime);
|
||||
|
||||
mouse_active = true;
|
||||
|
||||
// XSync(dpy, True);
|
||||
}
|
||||
|
||||
static void uninstall_grabs(void)
|
||||
{
|
||||
if (!dpy || !win)
|
||||
return;
|
||||
|
||||
if (dgamouse) {
|
||||
dgamouse = false;
|
||||
XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
|
||||
}
|
||||
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
XUngrabKeyboard(dpy, CurrentTime);
|
||||
|
||||
// inviso cursor
|
||||
XUndefineCursor(dpy, win);
|
||||
|
||||
mouse_active = false;
|
||||
}
|
||||
|
||||
static void HandleEvents(void)
|
||||
{
|
||||
XEvent event;
|
||||
KeySym ks;
|
||||
int b;
|
||||
qboolean dowarp = false;
|
||||
int mwx = vid.width/2;
|
||||
int mwy = vid.height/2;
|
||||
|
||||
if (!dpy)
|
||||
return;
|
||||
|
||||
while (XPending(dpy)) {
|
||||
XNextEvent(dpy, &event);
|
||||
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
if (mouse_active) {
|
||||
if (dgamouse) {
|
||||
mx += (event.xmotion.x + win_x) * 2;
|
||||
my += (event.xmotion.y + win_y) * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mx += ((int)event.xmotion.x - mwx) * 2;
|
||||
my += ((int)event.xmotion.y - mwy) * 2;
|
||||
mwx = event.xmotion.x;
|
||||
mwy = event.xmotion.y;
|
||||
|
||||
if (mx || my)
|
||||
dowarp = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0)
|
||||
Key_Event(K_MOUSE1 + b, true);
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
b=-1;
|
||||
if (event.xbutton.button == 1)
|
||||
b = 0;
|
||||
else if (event.xbutton.button == 2)
|
||||
b = 2;
|
||||
else if (event.xbutton.button == 3)
|
||||
b = 1;
|
||||
if (b>=0)
|
||||
Key_Event(K_MOUSE1 + b, false);
|
||||
break;
|
||||
|
||||
case CreateNotify :
|
||||
win_x = event.xcreatewindow.x;
|
||||
win_y = event.xcreatewindow.y;
|
||||
break;
|
||||
|
||||
case ConfigureNotify :
|
||||
win_x = event.xconfigure.x;
|
||||
win_y = event.xconfigure.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dowarp) {
|
||||
/* move the mouse to the window center again */
|
||||
XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void IN_DeactivateMouse( void )
|
||||
{
|
||||
if (!mouse_avail || !dpy || !win)
|
||||
return;
|
||||
|
||||
if (mouse_active) {
|
||||
uninstall_grabs();
|
||||
mouse_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void IN_ActivateMouse( void )
|
||||
{
|
||||
if (!mouse_avail || !dpy || !win)
|
||||
return;
|
||||
|
||||
if (!mouse_active) {
|
||||
mx = my = 0; // don't spazz
|
||||
install_grabs();
|
||||
mouse_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VID_Shutdown(void)
|
||||
{
|
||||
if (!ctx || !dpy)
|
||||
return;
|
||||
IN_DeactivateMouse();
|
||||
if (dpy) {
|
||||
if (ctx)
|
||||
glXDestroyContext(dpy, ctx);
|
||||
if (win)
|
||||
XDestroyWindow(dpy, win);
|
||||
if (vidmode_active)
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
vidmode_active = false;
|
||||
dpy = NULL;
|
||||
win = 0;
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
void signal_handler(int sig)
|
||||
{
|
||||
printf("Received signal %d, exiting...\n", sig);
|
||||
Sys_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void InitSig(void)
|
||||
{
|
||||
signal(SIGHUP, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGQUIT, signal_handler);
|
||||
signal(SIGILL, signal_handler);
|
||||
signal(SIGTRAP, signal_handler);
|
||||
signal(SIGIOT, signal_handler);
|
||||
signal(SIGBUS, signal_handler);
|
||||
signal(SIGFPE, signal_handler);
|
||||
signal(SIGSEGV, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
}
|
||||
|
||||
void VID_ShiftPalette(unsigned char *p)
|
||||
{
|
||||
// VID_SetPalette(p);
|
||||
}
|
||||
|
||||
void VID_SetPalette (unsigned char *palette)
|
||||
{
|
||||
byte *pal;
|
||||
unsigned r,g,b;
|
||||
unsigned v;
|
||||
int r1,g1,b1;
|
||||
int j,k,l,m;
|
||||
unsigned short i;
|
||||
unsigned *table;
|
||||
FILE *f;
|
||||
char s[255];
|
||||
int dist, bestdist;
|
||||
|
||||
//
|
||||
// 8 8 8 encoding
|
||||
//
|
||||
pal = palette;
|
||||
table = d_8to24table;
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
r = pal[0];
|
||||
g = pal[1];
|
||||
b = pal[2];
|
||||
pal += 3;
|
||||
|
||||
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
|
||||
*table++ = v;
|
||||
}
|
||||
d_8to24table[255] &= 0xffffff; // 255 is transparent
|
||||
|
||||
for (i=0; i < (1<<15); i++) {
|
||||
/* Maps
|
||||
000000000000000
|
||||
000000000011111 = Red = 0x1F
|
||||
000001111100000 = Blue = 0x03E0
|
||||
111110000000000 = Grn = 0x7C00
|
||||
*/
|
||||
r = ((i & 0x1F) << 3)+4;
|
||||
g = ((i & 0x03E0) >> 2)+4;
|
||||
b = ((i & 0x7C00) >> 7)+4;
|
||||
pal = (unsigned char *)d_8to24table;
|
||||
for (v=0,k=0,bestdist=10000*10000; v<256; v++,pal+=4) {
|
||||
r1 = (int)r - (int)pal[0];
|
||||
g1 = (int)g - (int)pal[1];
|
||||
b1 = (int)b - (int)pal[2];
|
||||
dist = (r1*r1)+(g1*g1)+(b1*b1);
|
||||
if (dist < bestdist) {
|
||||
k=v;
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
d_15to8table[i]=k;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckMultiTextureExtensions(void)
|
||||
{
|
||||
void *prjobj;
|
||||
|
||||
if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) {
|
||||
Con_Printf("Found GL_SGIS_multitexture...\n");
|
||||
|
||||
if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
|
||||
Con_Printf("Unable to open symbol list for main program.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS");
|
||||
qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS");
|
||||
|
||||
if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) {
|
||||
Con_Printf("Multitexture extensions found.\n");
|
||||
gl_mtexable = true;
|
||||
} else
|
||||
Con_Printf("Symbol not found, disabled.\n");
|
||||
|
||||
dlclose(prjobj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
GL_Init
|
||||
===============
|
||||
*/
|
||||
void GL_Init (void)
|
||||
{
|
||||
gl_vendor = glGetString (GL_VENDOR);
|
||||
Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
|
||||
gl_renderer = glGetString (GL_RENDERER);
|
||||
Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
|
||||
|
||||
gl_version = glGetString (GL_VERSION);
|
||||
Con_Printf ("GL_VERSION: %s\n", gl_version);
|
||||
gl_extensions = glGetString (GL_EXTENSIONS);
|
||||
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
|
||||
|
||||
// Con_Printf ("%s %s\n", gl_renderer, gl_version);
|
||||
|
||||
CheckMultiTextureExtensions ();
|
||||
|
||||
glClearColor (1,0,0,0);
|
||||
glCullFace(GL_FRONT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.666);
|
||||
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel (GL_FLAT);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
GL_BeginRendering
|
||||
|
||||
=================
|
||||
*/
|
||||
void GL_BeginRendering (int *x, int *y, int *width, int *height)
|
||||
{
|
||||
extern cvar_t gl_clear;
|
||||
|
||||
*x = *y = 0;
|
||||
*width = scr_width;
|
||||
*height = scr_height;
|
||||
|
||||
// if (!wglMakeCurrent( maindc, baseRC ))
|
||||
// Sys_Error ("wglMakeCurrent failed");
|
||||
|
||||
// glViewport (*x, *y, *width, *height);
|
||||
}
|
||||
|
||||
|
||||
void GL_EndRendering (void)
|
||||
{
|
||||
glFlush();
|
||||
glXSwapBuffers(dpy, win);
|
||||
}
|
||||
|
||||
qboolean VID_Is8bit(void)
|
||||
{
|
||||
return is8bit;
|
||||
}
|
||||
|
||||
void VID_Init8bitPalette(void)
|
||||
{
|
||||
// Check for 8bit Extensions and initialize them.
|
||||
int i;
|
||||
void *prjobj;
|
||||
|
||||
if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
|
||||
Con_Printf("Unable to open symbol list for main program.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strstr(gl_extensions, "3DFX_set_global_palette") &&
|
||||
(qgl3DfxSetPaletteEXT = dlsym(prjobj, "gl3DfxSetPaletteEXT")) != NULL) {
|
||||
GLubyte table[256][4];
|
||||
char *oldpal;
|
||||
|
||||
Con_SafePrintf("8-bit GL extensions enabled.\n");
|
||||
glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
|
||||
oldpal = (char *) d_8to24table; //d_8to24table3dfx;
|
||||
for (i=0;i<256;i++) {
|
||||
table[i][2] = *oldpal++;
|
||||
table[i][1] = *oldpal++;
|
||||
table[i][0] = *oldpal++;
|
||||
table[i][3] = 255;
|
||||
oldpal++;
|
||||
}
|
||||
qgl3DfxSetPaletteEXT((GLuint *)table);
|
||||
is8bit = true;
|
||||
|
||||
} else if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") &&
|
||||
(qglColorTableEXT = dlsym(prjobj, "glColorTableEXT")) != NULL) {
|
||||
char thePalette[256*3];
|
||||
char *oldPalette, *newPalette;
|
||||
|
||||
Con_SafePrintf("8-bit GL extensions enabled.\n");
|
||||
glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
|
||||
oldPalette = (char *) d_8to24table; //d_8to24table3dfx;
|
||||
newPalette = thePalette;
|
||||
for (i=0;i<256;i++) {
|
||||
*newPalette++ = *oldPalette++;
|
||||
*newPalette++ = *oldPalette++;
|
||||
*newPalette++ = *oldPalette++;
|
||||
oldPalette++;
|
||||
}
|
||||
qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
|
||||
is8bit = true;
|
||||
}
|
||||
|
||||
dlclose(prjobj);
|
||||
}
|
||||
|
||||
static void Check_Gamma (unsigned char *pal)
|
||||
{
|
||||
float f, inf;
|
||||
unsigned char palette[768];
|
||||
int i;
|
||||
|
||||
if ((i = COM_CheckParm("-gamma")) == 0) {
|
||||
if ((gl_renderer && strstr(gl_renderer, "Voodoo")) ||
|
||||
(gl_vendor && strstr(gl_vendor, "3Dfx")))
|
||||
vid_gamma = 1;
|
||||
else
|
||||
vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware
|
||||
} else
|
||||
vid_gamma = Q_atof(com_argv[i+1]);
|
||||
|
||||
for (i=0 ; i<768 ; i++)
|
||||
{
|
||||
f = pow ( (pal[i]+1)/256.0 , vid_gamma );
|
||||
inf = f*255 + 0.5;
|
||||
if (inf < 0)
|
||||
inf = 0;
|
||||
if (inf > 255)
|
||||
inf = 255;
|
||||
palette[i] = inf;
|
||||
}
|
||||
|
||||
memcpy (pal, palette, sizeof(palette));
|
||||
}
|
||||
|
||||
void VID_Init(unsigned char *palette)
|
||||
{
|
||||
int i;
|
||||
int attrib[] = {
|
||||
GLX_RGBA,
|
||||
GLX_RED_SIZE, 1,
|
||||
GLX_GREEN_SIZE, 1,
|
||||
GLX_BLUE_SIZE, 1,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 1,
|
||||
None
|
||||
};
|
||||
char gldir[MAX_OSPATH];
|
||||
int width = 640, height = 480;
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
Window root;
|
||||
XVisualInfo *visinfo;
|
||||
qboolean fullscreen = true;
|
||||
int MajorVersion, MinorVersion;
|
||||
int actualWidth, actualHeight;
|
||||
|
||||
Cvar_RegisterVariable (&vid_mode);
|
||||
Cvar_RegisterVariable (&in_mouse);
|
||||
Cvar_RegisterVariable (&in_dgamouse);
|
||||
Cvar_RegisterVariable (&m_filter);
|
||||
Cvar_RegisterVariable (&gl_ztrick);
|
||||
|
||||
vid.maxwarpwidth = WARP_WIDTH;
|
||||
vid.maxwarpheight = WARP_HEIGHT;
|
||||
vid.colormap = host_colormap;
|
||||
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
|
||||
|
||||
// interpret command-line params
|
||||
|
||||
// set vid parameters
|
||||
if ((i = COM_CheckParm("-window")) != 0)
|
||||
fullscreen = false;
|
||||
|
||||
if ((i = COM_CheckParm("-width")) != 0)
|
||||
width = atoi(com_argv[i+1]);
|
||||
|
||||
if ((i = COM_CheckParm("-height")) != 0)
|
||||
height = atoi(com_argv[i+1]);
|
||||
|
||||
if ((i = COM_CheckParm("-conwidth")) != 0)
|
||||
vid.conwidth = Q_atoi(com_argv[i+1]);
|
||||
else
|
||||
vid.conwidth = 640;
|
||||
|
||||
vid.conwidth &= 0xfff8; // make it a multiple of eight
|
||||
|
||||
if (vid.conwidth < 320)
|
||||
vid.conwidth = 320;
|
||||
|
||||
// pick a conheight that matches with correct aspect
|
||||
vid.conheight = vid.conwidth*3 / 4;
|
||||
|
||||
if ((i = COM_CheckParm("-conheight")) != 0)
|
||||
vid.conheight = Q_atoi(com_argv[i+1]);
|
||||
if (vid.conheight < 200)
|
||||
vid.conheight = 200;
|
||||
|
||||
if (!(dpy = XOpenDisplay(NULL))) {
|
||||
fprintf(stderr, "Error couldn't open the X display\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
scrnum = DefaultScreen(dpy);
|
||||
root = RootWindow(dpy, scrnum);
|
||||
|
||||
// Get video mode list
|
||||
MajorVersion = MinorVersion = 0;
|
||||
if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
|
||||
vidmode_ext = false;
|
||||
} else {
|
||||
Con_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion);
|
||||
vidmode_ext = true;
|
||||
}
|
||||
|
||||
visinfo = glXChooseVisual(dpy, scrnum, attrib);
|
||||
if (!visinfo) {
|
||||
fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (vidmode_ext) {
|
||||
int best_fit, best_dist, dist, x, y;
|
||||
|
||||
XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
|
||||
|
||||
// Are we going fullscreen? If so, let's change video mode
|
||||
if (fullscreen) {
|
||||
best_dist = 9999999;
|
||||
best_fit = -1;
|
||||
|
||||
for (i = 0; i < num_vidmodes; i++) {
|
||||
if (width > vidmodes[i]->hdisplay ||
|
||||
height > vidmodes[i]->vdisplay)
|
||||
continue;
|
||||
|
||||
x = width - vidmodes[i]->hdisplay;
|
||||
y = height - vidmodes[i]->vdisplay;
|
||||
dist = (x * x) + (y * y);
|
||||
if (dist < best_dist) {
|
||||
best_dist = dist;
|
||||
best_fit = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit != -1) {
|
||||
actualWidth = vidmodes[best_fit]->hdisplay;
|
||||
actualHeight = vidmodes[best_fit]->vdisplay;
|
||||
|
||||
// change to the mode
|
||||
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
|
||||
vidmode_active = true;
|
||||
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
} else
|
||||
fullscreen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* window attributes */
|
||||
attr.background_pixel = 0;
|
||||
attr.border_pixel = 0;
|
||||
attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
|
||||
attr.event_mask = X_MASK;
|
||||
if (vidmode_active) {
|
||||
mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
|
||||
CWEventMask | CWOverrideRedirect;
|
||||
attr.override_redirect = True;
|
||||
attr.backing_store = NotUseful;
|
||||
attr.save_under = False;
|
||||
} else
|
||||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
|
||||
|
||||
win = XCreateWindow(dpy, root, 0, 0, width, height,
|
||||
0, visinfo->depth, InputOutput,
|
||||
visinfo->visual, mask, &attr);
|
||||
XMapWindow(dpy, win);
|
||||
|
||||
if (vidmode_active) {
|
||||
XMoveWindow(dpy, win, 0, 0);
|
||||
XRaiseWindow(dpy, win);
|
||||
XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
|
||||
XFlush(dpy);
|
||||
// Move the viewport to top left
|
||||
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
|
||||
}
|
||||
|
||||
XFlush(dpy);
|
||||
|
||||
ctx = glXCreateContext(dpy, visinfo, NULL, True);
|
||||
|
||||
glXMakeCurrent(dpy, win, ctx);
|
||||
|
||||
scr_width = width;
|
||||
scr_height = height;
|
||||
|
||||
if (vid.conheight > height)
|
||||
vid.conheight = height;
|
||||
if (vid.conwidth > width)
|
||||
vid.conwidth = width;
|
||||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
|
||||
vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
|
||||
vid.numpages = 2;
|
||||
|
||||
InitSig(); // trap evil signals
|
||||
|
||||
GL_Init();
|
||||
|
||||
sprintf (gldir, "%s/glquake", com_gamedir);
|
||||
Sys_mkdir (gldir);
|
||||
|
||||
VID_SetPalette(palette);
|
||||
|
||||
// Check for 3DFX Extensions and initialize them.
|
||||
VID_Init8bitPalette();
|
||||
|
||||
Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
|
||||
|
||||
vid.recalc_refdef = 1; // force a surface cache flush
|
||||
}
|
||||
|
||||
void Sys_SendKeyEvents(void)
|
||||
{
|
||||
HandleEvents();
|
||||
}
|
||||
|
||||
void Force_CenterView_f (void)
|
||||
{
|
||||
cl.viewangles[PITCH] = 0;
|
||||
}
|
||||
|
||||
void IN_Init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void IN_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
if (!dpy || !win)
|
||||
return;
|
||||
|
||||
if (vidmode_active || key_dest == key_game)
|
||||
IN_ActivateMouse();
|
||||
else
|
||||
IN_DeactivateMouse ();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_MouseMove (usercmd_t *cmd)
|
||||
{
|
||||
if (!mouse_avail)
|
||||
return;
|
||||
|
||||
if (m_filter.value)
|
||||
{
|
||||
mx = (mx + old_mouse_x) * 0.5;
|
||||
my = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
|
||||
mx *= sensitivity.value;
|
||||
my *= sensitivity.value;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
|
||||
cmd->sidemove += m_side.value * mx;
|
||||
else
|
||||
cl.viewangles[YAW] -= m_yaw.value * mx;
|
||||
|
||||
if (in_mlook.state & 1)
|
||||
V_StopPitchDrift ();
|
||||
|
||||
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
|
||||
{
|
||||
cl.viewangles[PITCH] += m_pitch.value * my;
|
||||
if (cl.viewangles[PITCH] > 80)
|
||||
cl.viewangles[PITCH] = 80;
|
||||
if (cl.viewangles[PITCH] < -70)
|
||||
cl.viewangles[PITCH] = -70;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in_strafe.state & 1) && noclip_anglehack)
|
||||
cmd->upmove -= m_forward.value * my;
|
||||
else
|
||||
cmd->forwardmove -= m_forward.value * my;
|
||||
}
|
||||
mx = my = 0;
|
||||
}
|
||||
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
IN_MouseMove(cmd);
|
||||
}
|
||||
|
||||
|
1949
source/gl_vidnt.c
1949
source/gl_vidnt.c
File diff suppressed because it is too large
Load diff
615
source/in_dos.c
615
source/in_dos.c
|
@ -1,615 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// in_mouse.c -- dos mouse code
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "dosisms.h"
|
||||
|
||||
#define AUX_FLAG_FREELOOK 0x00000001
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long interruptVector;
|
||||
char deviceName[16];
|
||||
long numAxes;
|
||||
long numButtons;
|
||||
long flags;
|
||||
|
||||
vec3_t viewangles;
|
||||
|
||||
// intended velocities
|
||||
float forwardmove;
|
||||
float sidemove;
|
||||
float upmove;
|
||||
|
||||
long buttons;
|
||||
} externControl_t;
|
||||
|
||||
/*
|
||||
#define AUX_FLAG_FORCEFREELOOK 0x00000001 // r/o
|
||||
#define AUX_FLAG_EXTENDED 0x00000002 // r/o
|
||||
#define AUX_FLAG_RUN 0x00000004 // w/o
|
||||
#define AUX_FLAG_STRAFE 0x00000008 // w/o
|
||||
#define AUX_FLAG_FREELOOK 0x00000010 // w/o
|
||||
|
||||
#define AUX_MAP_UNDEFINED 0
|
||||
#define AUX_MAP_PITCH 1
|
||||
#define AUX_MAP_YAW 2
|
||||
#define AUX_MAP_ROLL 3
|
||||
#define AUX_MAP_FORWARD 4
|
||||
#define AUX_MAP_SIDE 5
|
||||
#define AUX_MAP_UP 6
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long interruptVector;
|
||||
// r/o
|
||||
char deviceName[16];
|
||||
// r/o
|
||||
long numAxes;
|
||||
// r/o 1-6
|
||||
long numButtons; // r/o 0-32
|
||||
long flags; // see above
|
||||
byte axisMapping[6]; // w/o default = p,y,r,f,s,u
|
||||
float axisValue[6]; // r/w
|
||||
float sensitivity[6]; // w/o default = 1.0
|
||||
long buttons; // r/o
|
||||
float last_frame_time; // w/o
|
||||
} externControl_t;
|
||||
*/
|
||||
|
||||
cvar_t m_filter = {"m_filter","1"};
|
||||
|
||||
qboolean mouse_avail;
|
||||
int mouse_buttons;
|
||||
int mouse_oldbuttonstate;
|
||||
int mouse_buttonstate;
|
||||
float mouse_x, mouse_y;
|
||||
float old_mouse_x, old_mouse_y;
|
||||
|
||||
|
||||
cvar_t in_joystick = {"joystick","1"};
|
||||
cvar_t joy_numbuttons = {"joybuttons","4", true};
|
||||
|
||||
qboolean joy_avail;
|
||||
int joy_oldbuttonstate;
|
||||
int joy_buttonstate;
|
||||
|
||||
int joyxl, joyxh, joyyl, joyyh;
|
||||
int joystickx, joysticky;
|
||||
|
||||
qboolean need_center;
|
||||
|
||||
qboolean extern_avail;
|
||||
int extern_buttons;
|
||||
int extern_oldbuttonstate;
|
||||
int extern_buttonstate;
|
||||
cvar_t aux_look = {"auxlook","1", true};
|
||||
externControl_t *extern_control;
|
||||
void IN_StartupExternal (void);
|
||||
void IN_ExternalMove (usercmd_t *cmd);
|
||||
|
||||
void IN_StartupJoystick (void);
|
||||
qboolean IN_ReadJoystick (void);
|
||||
|
||||
|
||||
void Toggle_AuxLook_f (void)
|
||||
{
|
||||
if (aux_look.value)
|
||||
Cvar_Set ("auxlook","0");
|
||||
else
|
||||
Cvar_Set ("auxlook","1");
|
||||
}
|
||||
|
||||
|
||||
void Force_CenterView_f (void)
|
||||
{
|
||||
cl.viewangles[PITCH] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_StartupMouse
|
||||
===========
|
||||
*/
|
||||
void IN_StartupMouse (void)
|
||||
{
|
||||
if ( COM_CheckParm ("-nomouse") )
|
||||
return;
|
||||
|
||||
// check for mouse
|
||||
regs.x.ax = 0;
|
||||
dos_int86(0x33);
|
||||
mouse_avail = regs.x.ax;
|
||||
if (!mouse_avail)
|
||||
{
|
||||
Con_Printf ("No mouse found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mouse_buttons = regs.x.bx;
|
||||
if (mouse_buttons > 3)
|
||||
mouse_buttons = 3;
|
||||
Con_Printf("%d-button mouse available\n", mouse_buttons);
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Init
|
||||
===========
|
||||
*/
|
||||
void IN_Init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
Cvar_RegisterVariable (&m_filter);
|
||||
Cvar_RegisterVariable (&in_joystick);
|
||||
Cvar_RegisterVariable (&joy_numbuttons);
|
||||
Cvar_RegisterVariable (&aux_look);
|
||||
Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f);
|
||||
Cmd_AddCommand ("force_centerview", Force_CenterView_f);
|
||||
|
||||
IN_StartupMouse ();
|
||||
IN_StartupJoystick ();
|
||||
|
||||
i = COM_CheckParm ("-control");
|
||||
if (i)
|
||||
{
|
||||
extern_control = real2ptr(Q_atoi (com_argv[i+1]));
|
||||
IN_StartupExternal ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Shutdown
|
||||
===========
|
||||
*/
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Commands
|
||||
===========
|
||||
*/
|
||||
void IN_Commands (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (mouse_avail)
|
||||
{
|
||||
regs.x.ax = 3; // read buttons
|
||||
dos_int86(0x33);
|
||||
mouse_buttonstate = regs.x.bx;
|
||||
|
||||
// perform button actions
|
||||
for (i=0 ; i<mouse_buttons ; i++)
|
||||
{
|
||||
if ( (mouse_buttonstate & (1<<i)) &&
|
||||
!(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_MOUSE1 + i, true);
|
||||
}
|
||||
if ( !(mouse_buttonstate & (1<<i)) &&
|
||||
(mouse_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_MOUSE1 + i, false);
|
||||
}
|
||||
}
|
||||
|
||||
mouse_oldbuttonstate = mouse_buttonstate;
|
||||
}
|
||||
|
||||
if (joy_avail)
|
||||
{
|
||||
joy_buttonstate = ((dos_inportb(0x201) >> 4)&15)^15;
|
||||
// perform button actions
|
||||
for (i=0 ; i<joy_numbuttons.value ; i++)
|
||||
{
|
||||
if ( (joy_buttonstate & (1<<i)) &&
|
||||
!(joy_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_JOY1 + i, true);
|
||||
}
|
||||
if ( !(joy_buttonstate & (1<<i)) &&
|
||||
(joy_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_JOY1 + i, false);
|
||||
}
|
||||
}
|
||||
|
||||
joy_oldbuttonstate = joy_buttonstate;
|
||||
}
|
||||
|
||||
if (extern_avail)
|
||||
{
|
||||
extern_buttonstate = extern_control->buttons;
|
||||
|
||||
// perform button actions
|
||||
for (i=0 ; i<extern_buttons ; i++)
|
||||
{
|
||||
if ( (extern_buttonstate & (1<<i)) &&
|
||||
!(extern_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_AUX1 + i, true);
|
||||
}
|
||||
if ( !(extern_buttonstate & (1<<i)) &&
|
||||
(extern_oldbuttonstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (K_AUX1 + i, false);
|
||||
}
|
||||
}
|
||||
|
||||
extern_oldbuttonstate = extern_buttonstate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_MouseMove (usercmd_t *cmd)
|
||||
{
|
||||
int mx, my;
|
||||
|
||||
if (!mouse_avail)
|
||||
return;
|
||||
|
||||
regs.x.ax = 11; // read move
|
||||
dos_int86(0x33);
|
||||
mx = (short)regs.x.cx;
|
||||
my = (short)regs.x.dx;
|
||||
|
||||
if (m_filter.value)
|
||||
{
|
||||
mouse_x = (mx + old_mouse_x) * 0.5;
|
||||
mouse_y = (my + old_mouse_y) * 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_x = mx;
|
||||
mouse_y = my;
|
||||
}
|
||||
old_mouse_x = mx;
|
||||
old_mouse_y = my;
|
||||
|
||||
mouse_x *= sensitivity.value;
|
||||
mouse_y *= sensitivity.value;
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
|
||||
cmd->sidemove += m_side.value * mouse_x;
|
||||
else
|
||||
cl.viewangles[YAW] -= m_yaw.value * mouse_x;
|
||||
|
||||
if (in_mlook.state & 1)
|
||||
V_StopPitchDrift ();
|
||||
|
||||
if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
|
||||
{
|
||||
cl.viewangles[PITCH] += m_pitch.value * mouse_y;
|
||||
if (cl.viewangles[PITCH] > 80)
|
||||
cl.viewangles[PITCH] = 80;
|
||||
if (cl.viewangles[PITCH] < -70)
|
||||
cl.viewangles[PITCH] = -70;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((in_strafe.state & 1) && noclip_anglehack)
|
||||
cmd->upmove -= m_forward.value * mouse_y;
|
||||
else
|
||||
cmd->forwardmove -= m_forward.value * mouse_y;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_JoyMove
|
||||
===========
|
||||
*/
|
||||
void IN_JoyMove (usercmd_t *cmd)
|
||||
{
|
||||
float speed, aspeed;
|
||||
|
||||
if (!joy_avail || !in_joystick.value)
|
||||
return;
|
||||
|
||||
IN_ReadJoystick ();
|
||||
if (joysticky > joyyh*2 || joystickx > joyxh*2)
|
||||
return; // assume something jumped in and messed up the joystick
|
||||
// reading time (win 95)
|
||||
|
||||
if (in_speed.state & 1)
|
||||
speed = cl_movespeedkey.value;
|
||||
else
|
||||
speed = 1;
|
||||
aspeed = speed*host_frametime;
|
||||
|
||||
if (in_strafe.state & 1)
|
||||
{
|
||||
if (joystickx < joyxl)
|
||||
cmd->sidemove -= speed*cl_sidespeed.value;
|
||||
else if (joystickx > joyxh)
|
||||
cmd->sidemove += speed*cl_sidespeed.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (joystickx < joyxl)
|
||||
cl.viewangles[YAW] += aspeed*cl_yawspeed.value;
|
||||
else if (joystickx > joyxh)
|
||||
cl.viewangles[YAW] -= aspeed*cl_yawspeed.value;
|
||||
cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
|
||||
}
|
||||
|
||||
if (in_mlook.state & 1)
|
||||
{
|
||||
if (m_pitch.value < 0)
|
||||
speed *= -1;
|
||||
|
||||
if (joysticky < joyyl)
|
||||
cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value;
|
||||
else if (joysticky > joyyh)
|
||||
cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (joysticky < joyyl)
|
||||
cmd->forwardmove += speed*cl_forwardspeed.value;
|
||||
else if (joysticky > joyyh)
|
||||
cmd->forwardmove -= speed*cl_backspeed.value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_Move
|
||||
===========
|
||||
*/
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
IN_MouseMove (cmd);
|
||||
IN_JoyMove (cmd);
|
||||
IN_ExternalMove (cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
JOYSTICK
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
qboolean IN_ReadJoystick (void)
|
||||
{
|
||||
int b;
|
||||
int count;
|
||||
|
||||
joystickx = 0;
|
||||
joysticky = 0;
|
||||
|
||||
count = 0;
|
||||
|
||||
b = dos_inportb(0x201);
|
||||
dos_outportb(0x201, b);
|
||||
|
||||
// clear counters
|
||||
while (++count < 10000)
|
||||
{
|
||||
b = dos_inportb(0x201);
|
||||
|
||||
joystickx += b&1;
|
||||
joysticky += (b&2)>>1;
|
||||
if ( !(b&3) )
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_Printf ("IN_ReadJoystick: no response\n");
|
||||
joy_avail = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WaitJoyButton
|
||||
=============
|
||||
*/
|
||||
qboolean WaitJoyButton (void)
|
||||
{
|
||||
int oldbuttons, buttons;
|
||||
|
||||
oldbuttons = 0;
|
||||
do
|
||||
{
|
||||
key_count = -1;
|
||||
Sys_SendKeyEvents ();
|
||||
key_count = 0;
|
||||
if (key_lastpress == K_ESCAPE)
|
||||
{
|
||||
Con_Printf ("aborted.\n");
|
||||
return false;
|
||||
}
|
||||
key_lastpress = 0;
|
||||
SCR_UpdateScreen ();
|
||||
buttons = ((dos_inportb(0x201) >> 4)&1)^1;
|
||||
if (buttons != oldbuttons)
|
||||
{
|
||||
oldbuttons = buttons;
|
||||
continue;
|
||||
}
|
||||
} while ( !buttons);
|
||||
|
||||
do
|
||||
{
|
||||
key_count = -1;
|
||||
Sys_SendKeyEvents ();
|
||||
key_count = 0;
|
||||
if (key_lastpress == K_ESCAPE)
|
||||
{
|
||||
Con_Printf ("aborted.\n");
|
||||
return false;
|
||||
}
|
||||
key_lastpress = 0;
|
||||
SCR_UpdateScreen ();
|
||||
buttons = ((dos_inportb(0x201) >> 4)&1)^1;
|
||||
if (buttons != oldbuttons)
|
||||
{
|
||||
oldbuttons = buttons;
|
||||
continue;
|
||||
}
|
||||
} while ( buttons);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
IN_StartupJoystick
|
||||
===============
|
||||
*/
|
||||
void IN_StartupJoystick (void)
|
||||
{
|
||||
int centerx, centery;
|
||||
|
||||
Con_Printf ("\n");
|
||||
|
||||
joy_avail = false;
|
||||
if ( COM_CheckParm ("-nojoy") )
|
||||
return;
|
||||
|
||||
if (!IN_ReadJoystick ())
|
||||
{
|
||||
joy_avail = false;
|
||||
Con_Printf ("joystick not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf ("joystick found\n");
|
||||
|
||||
Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n");
|
||||
if (!WaitJoyButton ())
|
||||
return;
|
||||
IN_ReadJoystick ();
|
||||
centerx = joystickx;
|
||||
centery = joysticky;
|
||||
|
||||
Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n");
|
||||
if (!WaitJoyButton ())
|
||||
return;
|
||||
IN_ReadJoystick ();
|
||||
joyxl = (centerx + joystickx)/2;
|
||||
joyyl = (centerx + joysticky)/2;
|
||||
|
||||
Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n");
|
||||
if (!WaitJoyButton ())
|
||||
return;
|
||||
IN_ReadJoystick ();
|
||||
joyxh = (centerx + joystickx)/2;
|
||||
joyyh = (centery + joysticky)/2;
|
||||
|
||||
joy_avail = true;
|
||||
Con_Printf ("joystick configured.\n");
|
||||
|
||||
Con_Printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
EXTERNAL
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
IN_StartupExternal
|
||||
===============
|
||||
*/
|
||||
void IN_StartupExternal (void)
|
||||
{
|
||||
if (extern_control->numButtons > 32)
|
||||
extern_control->numButtons = 32;
|
||||
|
||||
Con_Printf("%s Initialized\n", extern_control->deviceName);
|
||||
Con_Printf(" %u axes %u buttons\n", extern_control->numAxes, extern_control->numButtons);
|
||||
|
||||
extern_avail = true;
|
||||
extern_buttons = extern_control->numButtons;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_ExternalMove
|
||||
===========
|
||||
*/
|
||||
void IN_ExternalMove (usercmd_t *cmd)
|
||||
{
|
||||
qboolean freelook;
|
||||
|
||||
if (! extern_avail)
|
||||
return;
|
||||
|
||||
extern_control->viewangles[YAW] = cl.viewangles[YAW];
|
||||
extern_control->viewangles[PITCH] = cl.viewangles[PITCH];
|
||||
extern_control->viewangles[ROLL] = cl.viewangles[ROLL];
|
||||
extern_control->forwardmove = cmd->forwardmove;
|
||||
extern_control->sidemove = cmd->sidemove;
|
||||
extern_control->upmove = cmd->upmove;
|
||||
|
||||
Con_DPrintf("IN: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
|
||||
|
||||
dos_int86(extern_control->interruptVector);
|
||||
|
||||
Con_DPrintf("OUT: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
|
||||
|
||||
cl.viewangles[YAW] = extern_control->viewangles[YAW];
|
||||
cl.viewangles[PITCH] = extern_control->viewangles[PITCH];
|
||||
cl.viewangles[ROLL] = extern_control->viewangles[ROLL];
|
||||
cmd->forwardmove = extern_control->forwardmove;
|
||||
cmd->sidemove = extern_control->sidemove;
|
||||
cmd->upmove = extern_control->upmove;
|
||||
|
||||
if (cl.viewangles[PITCH] > 80)
|
||||
cl.viewangles[PITCH] = 80;
|
||||
if (cl.viewangles[PITCH] < -70)
|
||||
cl.viewangles[PITCH] = -70;
|
||||
|
||||
freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1);
|
||||
|
||||
if (freelook)
|
||||
V_StopPitchDrift ();
|
||||
}
|
||||
|
203
source/in_null.c
203
source/in_null.c
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// in_null.c -- for systems without a mouse
|
||||
|
||||
#include "quakedef.h"
|
||||
#include <3ds.h>
|
||||
|
||||
extern int bind_grab;
|
||||
|
||||
|
@ -30,61 +31,7 @@ extern cvar_t in_mlook; //Heffo - mlook cvar
|
|||
|
||||
void IN_Init (void)
|
||||
{
|
||||
// naievil -- fixme
|
||||
#if 0
|
||||
// Set up the controller.
|
||||
sceCtrlSetSamplingCycle(0);
|
||||
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
|
||||
|
||||
// Japanese users would prefer to have X as cancel and O as OK.
|
||||
//unsigned int okButton = PSP_CTRL_CIRCLE;
|
||||
//unsigned int cancelButton = PSP_CTRL_CROSS;
|
||||
unsigned int okButton = PSP_CTRL_CROSS;
|
||||
unsigned int cancelButton = PSP_CTRL_CIRCLE;
|
||||
|
||||
|
||||
// Build the button to Quake key maps.
|
||||
// Common keys:
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_SELECT)] = K_SELECT;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_START)] = K_ESCAPE;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_HOME)] = K_HOME;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_NOTE)] = K_NOTE;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_SCREEN)] = K_SCREEN;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_UP)] = K_UPARROW;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_RIGHT)] = K_RIGHTARROW;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_DOWN)] = K_DOWNARROW;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_LEFT)] = K_LEFTARROW;
|
||||
memcpy_vfpu(buttonToConsoleKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap));
|
||||
memcpy_vfpu(buttonToMessageKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap));
|
||||
memcpy_vfpu(buttonToMenuKeyMap, buttonToGameKeyMap, sizeof(ButtonToKeyMap));
|
||||
|
||||
// Game keys:
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_AUX1;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_AUX2;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_JOY1;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_CIRCLE)] = K_JOY2;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_CROSS)] = K_JOY3;
|
||||
buttonToGameKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_JOY4;
|
||||
|
||||
// Console keys:
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_PGUP;
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_PGDN;
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(okButton)] = K_ENTER;
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(cancelButton)] = K_ESCAPE;
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_DEL;
|
||||
buttonToConsoleKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_INS;
|
||||
|
||||
// Message keys:
|
||||
memcpy_vfpu(buttonToMessageKeyMap, buttonToConsoleKeyMap, sizeof(ButtonToKeyMap));
|
||||
|
||||
// Menu keys:
|
||||
buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_SQUARE)] = K_INS;
|
||||
buttonToMenuKeyMap[buttonMaskToShift(cancelButton)] = K_ESCAPE;
|
||||
buttonToMenuKeyMap[buttonMaskToShift(okButton)] = K_ENTER;
|
||||
buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_TRIANGLE)] = K_DEL;
|
||||
buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_LTRIGGER)] = K_AUX1;
|
||||
buttonToMenuKeyMap[buttonMaskToShift(PSP_CTRL_RTRIGGER)] = K_AUX2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IN_Shutdown (void)
|
||||
|
@ -94,132 +41,12 @@ void IN_Shutdown (void)
|
|||
|
||||
void IN_Commands (void)
|
||||
{
|
||||
// naievil -- fixme
|
||||
#if 0
|
||||
// Changed in or out of key binding mode?
|
||||
if ((bind_grab != 0) != readyToBindKeys)
|
||||
{
|
||||
// Was in key binding mode?
|
||||
if (readyToBindKeys)
|
||||
{
|
||||
// Just left key binding mode.
|
||||
// Release all keys which are pressed.
|
||||
for (unsigned int button = 0; button < buttonCount; ++button)
|
||||
{
|
||||
// Was the button pressed?
|
||||
if (lastPad.Buttons & (1 << button))
|
||||
{
|
||||
// Is the button in the map?
|
||||
const int key = buttonToGameKeyMap[button];
|
||||
if (key)
|
||||
{
|
||||
// Send a release event.
|
||||
Key_Event(key, qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're not ready to bind keys any more.
|
||||
readyToBindKeys = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entering key binding mode.
|
||||
// Release all keys which are pressed.
|
||||
for (unsigned int button = 0; button < buttonCount; ++button)
|
||||
{
|
||||
// Was the button pressed?
|
||||
if (lastPad.Buttons & (1 << button))
|
||||
{
|
||||
// Is the button in the map?
|
||||
const int key = buttonToMenuKeyMap[button];
|
||||
if (key)
|
||||
{
|
||||
// Send a release event.
|
||||
Key_Event(key, qfalse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're now ready to bind keys.
|
||||
readyToBindKeys = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Use a different key mapping depending on where inputs are going to go.
|
||||
const ButtonToKeyMap* buttonToKeyMap = 0;
|
||||
switch (key_dest)
|
||||
{
|
||||
case key_game:
|
||||
buttonToKeyMap = &buttonToGameKeyMap;
|
||||
break;
|
||||
|
||||
case key_console:
|
||||
buttonToKeyMap = &buttonToConsoleKeyMap;
|
||||
break;
|
||||
|
||||
case key_message:
|
||||
buttonToKeyMap = &buttonToMessageKeyMap;
|
||||
break;
|
||||
|
||||
case key_menu:
|
||||
case key_menu_pause:
|
||||
// Binding keys?
|
||||
if (readyToBindKeys)
|
||||
{
|
||||
buttonToKeyMap = &buttonToGameKeyMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonToKeyMap = &buttonToMenuKeyMap;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Sys_Error("Unhandled key destination %d", key_dest);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the pad state.
|
||||
SceCtrlData pad;
|
||||
sceCtrlPeekBufferPositive(&pad, 1);
|
||||
|
||||
// Find out which buttons have changed.
|
||||
SceCtrlData deltaPad;
|
||||
deltaPad.Buttons = pad.Buttons ^ lastPad.Buttons;
|
||||
deltaPad.Lx = pad.Lx - lastPad.Lx;
|
||||
deltaPad.Ly = pad.Ly - lastPad.Ly;
|
||||
deltaPad.TimeStamp = pad.TimeStamp - lastPad.TimeStamp;
|
||||
|
||||
// Handle buttons which have changed.
|
||||
for (unsigned int button = 0; button < buttonCount; ++button)
|
||||
{
|
||||
// Has the button changed?
|
||||
const unsigned int buttonMask = 1 << button;
|
||||
|
||||
if (deltaPad.Buttons & buttonMask)
|
||||
{
|
||||
// Is the button in the map?
|
||||
const int key = (*buttonToKeyMap)[button];
|
||||
if (key)
|
||||
{
|
||||
// Send an event.
|
||||
const qboolean state = (pad.Buttons & buttonMask) ? qtrue : qfalse;
|
||||
Key_Event(key, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the pad state for next time.
|
||||
lastPad = pad;
|
||||
#endif
|
||||
}
|
||||
|
||||
float IN_CalcInput(int axis, float speed, float tolerance, float acceleration) {
|
||||
|
||||
// naievil -- fixme
|
||||
#if 0
|
||||
float value = ((float) axis / 128.0f) - 1.0f;
|
||||
float value = ((float) axis / 154.0f);
|
||||
|
||||
if (value == 0.0f) {
|
||||
return 0.0f;
|
||||
|
@ -242,15 +69,13 @@ float IN_CalcInput(int axis, float speed, float tolerance, float acceleration) {
|
|||
value = abs_value;
|
||||
}
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern cvar_t scr_fov;
|
||||
extern int original_fov, final_fov;
|
||||
void IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
// naievil -- fixme
|
||||
#if 0
|
||||
// naievil -- fixme this operates incorrectly
|
||||
unsigned char analog_strafe = 0;
|
||||
// Don't let the pitch drift back to centre if analog nub look is on.
|
||||
if (in_mlook.value)
|
||||
|
@ -260,21 +85,25 @@ void IN_Move (usercmd_t *cmd)
|
|||
analog_strafe = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Read the pad state.
|
||||
SceCtrlData pad;
|
||||
sceCtrlPeekBufferPositive(&pad, 1);
|
||||
circlePosition pos;
|
||||
//Read the CirclePad position
|
||||
hidCircleRead(&pos);
|
||||
|
||||
//Print the CirclePad position
|
||||
|
||||
// Convert the inputs to floats in the range [-1, 1].
|
||||
// Implement the dead zone.
|
||||
float speed;
|
||||
float deadZone = in_tolerance.value;
|
||||
float acceleration = in_acceleration.value;
|
||||
int x_adjust = in_x_axis_adjust.value;
|
||||
int y_adjust = in_y_axis_adjust.value;
|
||||
int x_adjust = 0;
|
||||
int y_adjust = 0;
|
||||
|
||||
//shpuld begin
|
||||
if (!analog_strafe) {
|
||||
speed = in_sensitivity.value;
|
||||
speed = sensitivity.value;
|
||||
|
||||
// ==== Aim Assist + ====
|
||||
// cut look speed in half when facing enemy, unless
|
||||
|
@ -296,8 +125,8 @@ void IN_Move (usercmd_t *cmd)
|
|||
}
|
||||
//shpuld end
|
||||
|
||||
float x = IN_CalcInput(pad.Lx+x_adjust, speed, deadZone, acceleration);
|
||||
float y = IN_CalcInput(pad.Ly+y_adjust, speed, deadZone, acceleration);
|
||||
float x = IN_CalcInput(pos.dx+x_adjust, speed, deadZone, acceleration);
|
||||
float y = IN_CalcInput(pos.dy+y_adjust, speed, deadZone, acceleration);
|
||||
|
||||
// Set the yaw.
|
||||
|
||||
|
@ -311,6 +140,7 @@ void IN_Move (usercmd_t *cmd)
|
|||
// Set the pitch.
|
||||
const bool invertPitch = m_pitch.value < 0;
|
||||
const float pitchScale = yawScale * (invertPitch ? -1 : 1);
|
||||
|
||||
cl.viewangles[PITCH] += pitchScale * y * host_frametime;
|
||||
|
||||
// Don't look too far up or down.
|
||||
|
@ -318,6 +148,8 @@ void IN_Move (usercmd_t *cmd)
|
|||
cl.viewangles[PITCH] = 80.0f;
|
||||
if (cl.viewangles[PITCH] < -70.0f)
|
||||
cl.viewangles[PITCH] = -70.0f;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,6 +160,5 @@ void IN_Move (usercmd_t *cmd)
|
|||
cmd->sidemove += cl_sidespeed * x;
|
||||
cmd->forwardmove -= cl_forwardspeed * y;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
245
source/in_sun.c
245
source/in_sun.c
|
@ -1,245 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// in_sun.c -- SUN/X mouse input handler
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
|
||||
//
|
||||
// typedefs and defines
|
||||
//
|
||||
|
||||
#define MOUSE_SCALE 4
|
||||
|
||||
//
|
||||
// externs
|
||||
//
|
||||
|
||||
extern Display *x_disp;
|
||||
extern int x_screen, x_screen_width, x_screen_height;
|
||||
extern int x_center_height, x_center_width;
|
||||
extern int x_std_event_mask;
|
||||
extern Window x_win, x_root_win;
|
||||
extern qboolean x_fullscreen;
|
||||
extern qboolean x_focus;
|
||||
extern int global_dx, global_dy;
|
||||
//
|
||||
// globals
|
||||
//
|
||||
|
||||
cvar_t _windowed_mouse = {"_windowed_mouse","1", true};
|
||||
int x_root, y_root;
|
||||
int x_root_old, y_root_old;
|
||||
//
|
||||
// locals
|
||||
//
|
||||
|
||||
static int x_mouse_num, x_mouse_denom, x_mouse_thresh;
|
||||
|
||||
|
||||
static qboolean x_grabbed = false;
|
||||
|
||||
//
|
||||
// IN_CenterMouse - center the mouse in the screen
|
||||
//
|
||||
|
||||
void IN_CenterMouse( void )
|
||||
{
|
||||
CheckMouseState();
|
||||
|
||||
if (!x_grabbed)
|
||||
return;
|
||||
|
||||
XSelectInput( x_disp, x_win, x_std_event_mask & ~PointerMotionMask );
|
||||
XWarpPointer( x_disp, None, x_root_win, 0, 0, 0, 0, x_center_width,
|
||||
x_center_height );
|
||||
XSelectInput( x_disp, x_win, x_std_event_mask );
|
||||
}
|
||||
|
||||
//
|
||||
// Check to see if we have grabbed the mouse or not and deal with it
|
||||
// appropriately
|
||||
//
|
||||
static void CheckMouseState(void)
|
||||
{
|
||||
if (x_focus && _windowed_mouse.value && !x_grabbed) {
|
||||
x_grabbed = true;
|
||||
printf("fooling with mouse!\n");
|
||||
if (XGetPointerControl( x_disp, &x_mouse_num, &x_mouse_denom, &x_mouse_thresh ))
|
||||
printf( "XGetPointerControl failed!\n" );
|
||||
//printf( "mouse %d/%d thresh %d\n", x_mouse_num, x_mouse_denom, x_mouse_thresh );
|
||||
|
||||
// make input rawer
|
||||
XAutoRepeatOff(x_disp);
|
||||
XGrabKeyboard(x_disp, x_win, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
XGrabPointer(x_disp, x_win, True,
|
||||
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
|
||||
GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
|
||||
|
||||
// if (XChangePointerControl( x_disp, True, True, 1, MOUSE_SCALE, x_mouse_thresh ))
|
||||
// printf( "XChangePointerControl failed!\n" );
|
||||
|
||||
IN_CenterMouse();
|
||||
|
||||
// safe initial values
|
||||
x_root = x_root_old = vid.width >> 1;
|
||||
y_root = y_root_old = vid.height >> 1;
|
||||
} else if (x_grabbed && (!_windowed_mouse.value || !x_focus)) {
|
||||
printf("fooling with mouse!\n");
|
||||
x_grabbed = false;
|
||||
// undo mouse warp
|
||||
if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh ))
|
||||
printf( "XChangePointerControl failed!\n" );
|
||||
|
||||
XUngrabPointer( x_disp, CurrentTime );
|
||||
XUngrabKeyboard( x_disp, CurrentTime );
|
||||
XAutoRepeatOn( x_disp );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// IN_Init - setup mouse input
|
||||
//
|
||||
|
||||
void IN_Init (void)
|
||||
{
|
||||
if (!x_disp) Sys_Error( "X display not open!\n" );
|
||||
|
||||
Cvar_RegisterVariable (&_windowed_mouse);
|
||||
|
||||
// we really really want to clean these up...
|
||||
atexit( IN_Shutdown );
|
||||
}
|
||||
|
||||
//
|
||||
// IN_Shutdown - clean up mouse settings (must be done from signal handler too!)
|
||||
//
|
||||
|
||||
void IN_Shutdown (void)
|
||||
{
|
||||
if (!x_disp) return;
|
||||
|
||||
// undo mouse warp
|
||||
if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh ))
|
||||
printf( "XChangePointerControl failed!\n" );
|
||||
|
||||
XUngrabPointer( x_disp, CurrentTime );
|
||||
XUngrabKeyboard( x_disp, CurrentTime );
|
||||
XAutoRepeatOn( x_disp );
|
||||
}
|
||||
|
||||
//
|
||||
// IN_Commands - process buttons
|
||||
//
|
||||
|
||||
void IN_Commands (void)
|
||||
{
|
||||
// done in X event handler
|
||||
}
|
||||
|
||||
//
|
||||
// IN_Move - process mouse moves
|
||||
//
|
||||
|
||||
void
|
||||
IN_Move (usercmd_t *cmd)
|
||||
{
|
||||
static int last_dx, last_dy;
|
||||
static long long last_movement;
|
||||
long long now, gethrtime();
|
||||
|
||||
int dx, dy;
|
||||
|
||||
CheckMouseState();
|
||||
|
||||
|
||||
if (!x_grabbed)
|
||||
return; // no mouse movement
|
||||
|
||||
|
||||
now = gethrtime();
|
||||
|
||||
dx = global_dx;
|
||||
global_dx = 0;
|
||||
|
||||
dy = global_dy;
|
||||
global_dy = 0;
|
||||
|
||||
// printf("GOT: dx %d dy %d\n", dx, dy);
|
||||
|
||||
dx *= sensitivity.value;
|
||||
dy *= sensitivity.value;
|
||||
|
||||
//
|
||||
// implement low pass filter to smooth motion a bit
|
||||
//
|
||||
if (now - last_movement > 100000000) {
|
||||
dx = .6 * dx;
|
||||
dy = .6 * dy;
|
||||
}
|
||||
last_movement = now;
|
||||
|
||||
dx = .6 * dx + .4 * last_dx;
|
||||
dy = .6 * dy + .4 * last_dy;
|
||||
|
||||
|
||||
last_dx = dx;
|
||||
last_dy = dy;
|
||||
|
||||
if (!dx && !dy) {
|
||||
if (in_mlook.state & 1)
|
||||
V_StopPitchDrift ();
|
||||
return;
|
||||
}
|
||||
|
||||
// add mouse X/Y movement to cmd
|
||||
if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1)))
|
||||
cmd->sidemove += m_side.value * dx;
|
||||
else
|
||||
cl.viewangles[YAW] -= m_yaw.value * dx;
|
||||
|
||||
if (in_mlook.state & 1)
|
||||
V_StopPitchDrift ();
|
||||
|
||||
if ((in_mlook.state & 1) && !(in_strafe.state & 1)) {
|
||||
cl.viewangles[PITCH] += m_pitch.value * dy;
|
||||
if (cl.viewangles[PITCH] > 80) cl.viewangles[PITCH] = 80;
|
||||
if (cl.viewangles[PITCH] < -70) cl.viewangles[PITCH] = -70;
|
||||
}
|
||||
else {
|
||||
if ((in_strafe.state & 1) && noclip_anglehack) cmd->upmove -= m_forward.value * dy;
|
||||
else cmd->forwardmove -= m_forward.value * dy;
|
||||
}
|
||||
}
|
1239
source/in_win.c
1239
source/in_win.c
File diff suppressed because it is too large
Load diff
|
@ -221,8 +221,8 @@ void Sys_DefaultConfig(void)
|
|||
Cbuf_AddText ("bind RTRIGGER +attack\n");
|
||||
Cbuf_AddText ("bind PADUP \"impulse 10\"\n");
|
||||
Cbuf_AddText ("bind PADDOWN \"impulse 12\"\n");
|
||||
Cbuf_AddText ("lookstrafe \"1.000000\"\n");
|
||||
Cbuf_AddText ("lookspring \"0.000000\"\n");
|
||||
//Cbuf_AddText ("lookstrafe \"1.000000\"\n");
|
||||
//Cbuf_AddText ("lookspring \"0.000000\"\n");
|
||||
}
|
||||
|
||||
void Sys_SetKeys(u32 keys, u32 state){
|
||||
|
|
778
source/vid_dos.c
778
source/vid_dos.c
|
@ -1,778 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// vid_dos.c: DOS-specific video routines
|
||||
//
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dos.h>
|
||||
#include <dpmi.h>
|
||||
#include <go32.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "dosisms.h"
|
||||
#include "vid_dos.h"
|
||||
|
||||
int vid_modenum;
|
||||
vmode_t *pcurrentmode = NULL;
|
||||
int vid_testingmode, vid_realmode;
|
||||
double vid_testendtime;
|
||||
|
||||
cvar_t vid_mode = {"vid_mode","0", false};
|
||||
cvar_t vid_wait = {"vid_wait","0"};
|
||||
cvar_t vid_nopageflip = {"vid_nopageflip","0", true};
|
||||
cvar_t _vid_wait_override = {"_vid_wait_override", "0", true};
|
||||
cvar_t _vid_default_mode = {"_vid_default_mode","0", true};
|
||||
cvar_t _vid_default_mode_win = {"_vid_default_mode_win","1", true};
|
||||
cvar_t vid_config_x = {"vid_config_x","800", true};
|
||||
cvar_t vid_config_y = {"vid_config_y","600", true};
|
||||
cvar_t vid_stretch_by_2 = {"vid_stretch_by_2","1", true};
|
||||
cvar_t _windowed_mouse = {"_windowed_mouse","0", true};
|
||||
cvar_t vid_fullscreen_mode = {"vid_fullscreen_mode","3", true};
|
||||
cvar_t vid_windowed_mode = {"vid_windowed_mode","0", true};
|
||||
cvar_t block_switch = {"block_switch","0", true};
|
||||
cvar_t vid_window_x = {"vid_window_x", "0", true};
|
||||
cvar_t vid_window_y = {"vid_window_y", "0", true};
|
||||
|
||||
int d_con_indirect = 0;
|
||||
|
||||
int numvidmodes;
|
||||
vmode_t *pvidmodes;
|
||||
|
||||
static int firstupdate = 1;
|
||||
|
||||
extern regs_t regs;
|
||||
|
||||
void VID_TestMode_f (void);
|
||||
void VID_NumModes_f (void);
|
||||
void VID_DescribeCurrentMode_f (void);
|
||||
void VID_DescribeMode_f (void);
|
||||
void VID_DescribeModes_f (void);
|
||||
|
||||
byte vid_current_palette[768]; // save for mode changes
|
||||
|
||||
|
||||
static qboolean nomodecheck = false;
|
||||
|
||||
unsigned short d_8to16table[256]; // not used in 8 bpp mode
|
||||
unsigned d_8to24table[256]; // not used in 8 bpp mode
|
||||
|
||||
void VID_MenuDraw (void);
|
||||
void VID_MenuKey (int key);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_Init
|
||||
================
|
||||
*/
|
||||
void VID_Init (unsigned char *palette)
|
||||
{
|
||||
Cvar_RegisterVariable (&vid_mode);
|
||||
Cvar_RegisterVariable (&vid_wait);
|
||||
Cvar_RegisterVariable (&vid_nopageflip);
|
||||
Cvar_RegisterVariable (&_vid_wait_override);
|
||||
Cvar_RegisterVariable (&_vid_default_mode);
|
||||
Cvar_RegisterVariable (&_vid_default_mode_win);
|
||||
Cvar_RegisterVariable (&vid_config_x);
|
||||
Cvar_RegisterVariable (&vid_config_y);
|
||||
Cvar_RegisterVariable (&vid_stretch_by_2);
|
||||
Cvar_RegisterVariable (&_windowed_mouse);
|
||||
Cvar_RegisterVariable (&vid_fullscreen_mode);
|
||||
Cvar_RegisterVariable (&vid_windowed_mode);
|
||||
Cvar_RegisterVariable (&block_switch);
|
||||
|
||||
Cmd_AddCommand ("vid_testmode", VID_TestMode_f);
|
||||
Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
|
||||
Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
|
||||
Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
|
||||
Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
|
||||
|
||||
// set up the mode list; note that later inits link in their modes ahead of
|
||||
// earlier ones, so the standard VGA modes are always first in the list. This
|
||||
// is important because mode 0 must always be VGA mode 0x13
|
||||
if (!COM_CheckParm ("-stdvid"))
|
||||
VID_InitExtra ();
|
||||
VGA_Init ();
|
||||
|
||||
vid_testingmode = 0;
|
||||
|
||||
vid_modenum = vid_mode.value;
|
||||
|
||||
VID_SetMode (vid_modenum, palette);
|
||||
|
||||
vid_realmode = vid_modenum;
|
||||
|
||||
vid_menudrawfn = VID_MenuDraw;
|
||||
vid_menukeyfn = VID_MenuKey;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_GetModePtr
|
||||
=================
|
||||
*/
|
||||
vmode_t *VID_GetModePtr (int modenum)
|
||||
{
|
||||
vmode_t *pv;
|
||||
|
||||
pv = pvidmodes;
|
||||
if (!pv)
|
||||
Sys_Error ("VID_GetModePtr: empty vid mode list");
|
||||
|
||||
while (modenum--)
|
||||
{
|
||||
pv = pv->pnext;
|
||||
if (!pv)
|
||||
Sys_Error ("VID_GetModePtr: corrupt vid mode list");
|
||||
}
|
||||
|
||||
return pv;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
VID_NumModes
|
||||
================
|
||||
*/
|
||||
int VID_NumModes ()
|
||||
{
|
||||
return (numvidmodes);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ModeInfo
|
||||
================
|
||||
*/
|
||||
char *VID_ModeInfo (int modenum, char **ppheader)
|
||||
{
|
||||
static char *badmodestr = "Bad mode number";
|
||||
vmode_t *pv;
|
||||
|
||||
pv = VID_GetModePtr (modenum);
|
||||
|
||||
if (!pv)
|
||||
{
|
||||
if (ppheader)
|
||||
*ppheader = NULL;
|
||||
return badmodestr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ppheader)
|
||||
*ppheader = pv->header;
|
||||
return pv->name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_SetMode
|
||||
================
|
||||
*/
|
||||
int VID_SetMode (int modenum, unsigned char *palette)
|
||||
{
|
||||
int stat;
|
||||
vmode_t *pnewmode, *poldmode;
|
||||
|
||||
if ((modenum >= numvidmodes) || (modenum < 0))
|
||||
{
|
||||
Cvar_SetValue ("vid_mode", (float)vid_modenum);
|
||||
|
||||
nomodecheck = true;
|
||||
Con_Printf ("No such video mode: %d\n", modenum);
|
||||
nomodecheck = false;
|
||||
|
||||
if (pcurrentmode == NULL)
|
||||
{
|
||||
modenum = 0; // mode hasn't been set yet, so initialize to base
|
||||
// mode since they gave us an invalid initial mode
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pnewmode = VID_GetModePtr (modenum);
|
||||
|
||||
if (pnewmode == pcurrentmode)
|
||||
return 1; // already in the desired mode
|
||||
|
||||
// initialize the new mode
|
||||
poldmode = pcurrentmode;
|
||||
pcurrentmode = pnewmode;
|
||||
|
||||
vid.width = pcurrentmode->width;
|
||||
vid.height = pcurrentmode->height;
|
||||
vid.aspect = pcurrentmode->aspect;
|
||||
vid.rowbytes = pcurrentmode->rowbytes;
|
||||
|
||||
stat = (*pcurrentmode->setmode) (&vid, pcurrentmode);
|
||||
|
||||
if (stat < 1)
|
||||
{
|
||||
if (stat == 0)
|
||||
{
|
||||
// real, hard failure that requires resetting the mode
|
||||
if (!VID_SetMode (vid_modenum, palette)) // restore prior mode
|
||||
Sys_Error ("VID_SetMode: Unable to set any mode, probably "
|
||||
"because there's not enough memory available");
|
||||
Con_Printf ("Failed to set mode %d\n", modenum);
|
||||
return 0;
|
||||
}
|
||||
else if (stat == -1)
|
||||
{
|
||||
// not enough memory; just put things back the way they were
|
||||
pcurrentmode = poldmode;
|
||||
vid.width = pcurrentmode->width;
|
||||
vid.height = pcurrentmode->height;
|
||||
vid.aspect = pcurrentmode->aspect;
|
||||
vid.rowbytes = pcurrentmode->rowbytes;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Error ("VID_SetMode: invalid setmode return code %d");
|
||||
}
|
||||
}
|
||||
|
||||
(*pcurrentmode->setpalette) (&vid, pcurrentmode, palette);
|
||||
|
||||
vid_modenum = modenum;
|
||||
Cvar_SetValue ("vid_mode", (float)vid_modenum);
|
||||
|
||||
nomodecheck = true;
|
||||
Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL));
|
||||
nomodecheck = false;
|
||||
|
||||
vid.recalc_refdef = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_SetPalette
|
||||
================
|
||||
*/
|
||||
void VID_SetPalette (unsigned char *palette)
|
||||
{
|
||||
if (palette != vid_current_palette)
|
||||
Q_memcpy(vid_current_palette, palette, 768);
|
||||
(*pcurrentmode->setpalette)(&vid, pcurrentmode, vid_current_palette);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ShiftPalette
|
||||
================
|
||||
*/
|
||||
void VID_ShiftPalette (unsigned char *palette)
|
||||
{
|
||||
|
||||
VID_SetPalette (palette);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_Shutdown
|
||||
================
|
||||
*/
|
||||
void VID_Shutdown (void)
|
||||
{
|
||||
|
||||
regs.h.ah = 0;
|
||||
regs.h.al = 0x3;
|
||||
dos_int86(0x10);
|
||||
|
||||
vid_testingmode = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_Update
|
||||
================
|
||||
*/
|
||||
void VID_Update (vrect_t *rects)
|
||||
{
|
||||
if (firstupdate && _vid_default_mode.value)
|
||||
{
|
||||
if(_vid_default_mode.value >= numvidmodes)
|
||||
Cvar_SetValue ("_vid_default_mode", 0);
|
||||
|
||||
firstupdate = 0;
|
||||
Cvar_SetValue ("vid_mode", _vid_default_mode.value);
|
||||
}
|
||||
|
||||
(*pcurrentmode->swapbuffers)(&vid, pcurrentmode, rects);
|
||||
|
||||
if (!nomodecheck)
|
||||
{
|
||||
if (vid_testingmode)
|
||||
{
|
||||
if (realtime >= vid_testendtime)
|
||||
{
|
||||
VID_SetMode (vid_realmode, vid_current_palette);
|
||||
vid_testingmode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vid_mode.value != vid_realmode)
|
||||
{
|
||||
VID_SetMode ((int)vid_mode.value, vid_current_palette);
|
||||
Cvar_SetValue ("vid_mode", (float)vid_modenum);
|
||||
// so if mode set fails, we don't keep on
|
||||
// trying to set that mode
|
||||
vid_realmode = vid_modenum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_NumModes_f
|
||||
=================
|
||||
*/
|
||||
void VID_NumModes_f (void)
|
||||
{
|
||||
int nummodes;
|
||||
|
||||
nummodes = VID_NumModes ();
|
||||
if (nummodes == 1)
|
||||
Con_Printf ("%d video mode is available\n", VID_NumModes ());
|
||||
else
|
||||
Con_Printf ("%d video modes are available\n", VID_NumModes ());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_DescribeCurrentMode_f
|
||||
=================
|
||||
*/
|
||||
void VID_DescribeCurrentMode_f (void)
|
||||
{
|
||||
Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_DescribeMode_f
|
||||
=================
|
||||
*/
|
||||
void VID_DescribeMode_f (void)
|
||||
{
|
||||
int modenum;
|
||||
|
||||
modenum = Q_atoi (Cmd_Argv(1));
|
||||
|
||||
Con_Printf ("%s\n", VID_ModeInfo (modenum, NULL));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_DescribeModes_f
|
||||
=================
|
||||
*/
|
||||
void VID_DescribeModes_f (void)
|
||||
{
|
||||
int i, nummodes;
|
||||
char *pinfo, *pheader;
|
||||
vmode_t *pv;
|
||||
qboolean na;
|
||||
|
||||
na = false;
|
||||
|
||||
nummodes = VID_NumModes ();
|
||||
for (i=0 ; i<nummodes ; i++)
|
||||
{
|
||||
pv = VID_GetModePtr (i);
|
||||
pinfo = VID_ModeInfo (i, &pheader);
|
||||
if (pheader)
|
||||
Con_Printf ("\n%s\n", pheader);
|
||||
|
||||
if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes,
|
||||
(pv->numpages == 1) || vid_nopageflip.value))
|
||||
{
|
||||
Con_Printf ("%2d: %s\n", i, pinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf ("**: %s\n", pinfo);
|
||||
na = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (na)
|
||||
{
|
||||
Con_Printf ("\n[**: not enough system RAM for mode]\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_GetModeDescription
|
||||
=================
|
||||
*/
|
||||
char *VID_GetModeDescription (int mode)
|
||||
{
|
||||
char *pinfo, *pheader;
|
||||
vmode_t *pv;
|
||||
|
||||
pv = VID_GetModePtr (mode);
|
||||
pinfo = VID_ModeInfo (mode, &pheader);
|
||||
|
||||
if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes,
|
||||
(pv->numpages == 1) || vid_nopageflip.value))
|
||||
{
|
||||
return pinfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
VID_TestMode_f
|
||||
=================
|
||||
*/
|
||||
void VID_TestMode_f (void)
|
||||
{
|
||||
int modenum;
|
||||
double testduration;
|
||||
|
||||
if (!vid_testingmode)
|
||||
{
|
||||
modenum = Q_atoi (Cmd_Argv(1));
|
||||
|
||||
if (VID_SetMode (modenum, vid_current_palette))
|
||||
{
|
||||
vid_testingmode = 1;
|
||||
testduration = Q_atof (Cmd_Argv(2));
|
||||
if (testduration == 0)
|
||||
testduration = 5.0;
|
||||
vid_testendtime = realtime + testduration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_BeginDirectRect
|
||||
================
|
||||
*/
|
||||
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
|
||||
{
|
||||
|
||||
if (!vid.direct || !pcurrentmode)
|
||||
return;
|
||||
|
||||
if ((width > 24) || (height > 24) || (width < 1) || (height < 1))
|
||||
return;
|
||||
|
||||
if (width & 0x03)
|
||||
return;
|
||||
|
||||
(*pcurrentmode->begindirectrect) (&vid, pcurrentmode, x, y, pbitmap, width,
|
||||
height);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
D_EndDirectRect
|
||||
================
|
||||
*/
|
||||
void D_EndDirectRect (int x, int y, int width, int height)
|
||||
{
|
||||
|
||||
if (!vid.direct || !pcurrentmode)
|
||||
return;
|
||||
|
||||
if ((width > 24) || (height > 24) || (width < 1) || (height < 1))
|
||||
return;
|
||||
|
||||
if ((width & 0x03) || (height & 0x03))
|
||||
return;
|
||||
|
||||
(*pcurrentmode->enddirectrect) (&vid, pcurrentmode, x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
||||
extern void M_Menu_Options_f (void);
|
||||
extern void M_Print (int cx, int cy, char *str);
|
||||
extern void M_PrintWhite (int cx, int cy, char *str);
|
||||
extern void M_DrawCharacter (int cx, int line, int num);
|
||||
extern void M_DrawTransPic (int x, int y, qpic_t *pic);
|
||||
extern void M_DrawPic (int x, int y, qpic_t *pic);
|
||||
|
||||
static int vid_line, vid_wmodes, vid_column_size;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int modenum;
|
||||
char *desc;
|
||||
int iscur;
|
||||
} modedesc_t;
|
||||
|
||||
#define MAX_COLUMN_SIZE 11
|
||||
|
||||
#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3)
|
||||
|
||||
static modedesc_t modedescs[MAX_MODEDESCS];
|
||||
|
||||
/*
|
||||
================
|
||||
VID_MenuDraw
|
||||
================
|
||||
*/
|
||||
void VID_MenuDraw (void)
|
||||
{
|
||||
qpic_t *p;
|
||||
char *ptr;
|
||||
int nummodes, i, j, column, row, dup;
|
||||
char temp[100];
|
||||
|
||||
vid_wmodes = 0;
|
||||
nummodes = VID_NumModes ();
|
||||
|
||||
p = Draw_CachePic ("gfx/vidmodes.lmp");
|
||||
M_DrawPic ( (320-p->width)/2, 4, p);
|
||||
|
||||
for (i=0 ; i<nummodes ; i++)
|
||||
{
|
||||
if (vid_wmodes < MAX_MODEDESCS)
|
||||
{
|
||||
if (i != 1)
|
||||
{
|
||||
ptr = VID_GetModeDescription (i);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
dup = 0;
|
||||
|
||||
for (j=0 ; j<vid_wmodes ; j++)
|
||||
{
|
||||
if (!strcmp (modedescs[j].desc, ptr))
|
||||
{
|
||||
if (modedescs[j].modenum != 0)
|
||||
{
|
||||
modedescs[j].modenum = i;
|
||||
dup = 1;
|
||||
|
||||
if (i == vid_modenum)
|
||||
modedescs[j].iscur = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dup = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dup)
|
||||
{
|
||||
modedescs[vid_wmodes].modenum = i;
|
||||
modedescs[vid_wmodes].desc = ptr;
|
||||
modedescs[vid_wmodes].iscur = 0;
|
||||
|
||||
if (i == vid_modenum)
|
||||
modedescs[vid_wmodes].iscur = 1;
|
||||
|
||||
vid_wmodes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vid_column_size = (vid_wmodes + 2) / 3;
|
||||
|
||||
column = 16;
|
||||
row = 36;
|
||||
|
||||
for (i=0 ; i<vid_wmodes ; i++)
|
||||
{
|
||||
if (modedescs[i].iscur)
|
||||
M_PrintWhite (column, row, modedescs[i].desc);
|
||||
else
|
||||
M_Print (column, row, modedescs[i].desc);
|
||||
|
||||
row += 8;
|
||||
|
||||
if ((i % vid_column_size) == (vid_column_size - 1))
|
||||
{
|
||||
column += 13*8;
|
||||
row = 36;
|
||||
}
|
||||
}
|
||||
|
||||
// line cursor
|
||||
if (vid_testingmode)
|
||||
{
|
||||
sprintf (temp, "TESTING %s",
|
||||
modedescs[vid_line].desc);
|
||||
M_Print (13*8, 36 + MAX_COLUMN_SIZE * 8 + 8*4, temp);
|
||||
M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6,
|
||||
"Please wait 5 seconds...");
|
||||
}
|
||||
else
|
||||
{
|
||||
M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8,
|
||||
"Press Enter to set mode");
|
||||
M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*3,
|
||||
"T to test mode for 5 seconds");
|
||||
ptr = VID_GetModeDescription (vid_modenum);
|
||||
sprintf (temp, "D to make %s the default", ptr);
|
||||
M_Print (6*8, 36 + MAX_COLUMN_SIZE * 8 + 8*5, temp);
|
||||
ptr = VID_GetModeDescription ((int)_vid_default_mode.value);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
sprintf (temp, "Current default is %s", ptr);
|
||||
M_Print (7*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, temp);
|
||||
}
|
||||
|
||||
M_Print (15*8, 36 + MAX_COLUMN_SIZE * 8 + 8*8,
|
||||
"Esc to exit");
|
||||
|
||||
row = 36 + (vid_line % vid_column_size) * 8;
|
||||
column = 8 + (vid_line / vid_column_size) * 13*8;
|
||||
|
||||
M_DrawCharacter (column, row, 12+((int)(realtime*4)&1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_MenuKey
|
||||
================
|
||||
*/
|
||||
void VID_MenuKey (int key)
|
||||
{
|
||||
if (vid_testingmode)
|
||||
return;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
case K_ESCAPE:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
M_Menu_Options_f ();
|
||||
break;
|
||||
|
||||
case K_UPARROW:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
vid_line--;
|
||||
|
||||
if (vid_line < 0)
|
||||
vid_line = vid_wmodes - 1;
|
||||
break;
|
||||
|
||||
case K_DOWNARROW:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
vid_line++;
|
||||
|
||||
if (vid_line >= vid_wmodes)
|
||||
vid_line = 0;
|
||||
break;
|
||||
|
||||
case K_LEFTARROW:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
vid_line -= vid_column_size;
|
||||
|
||||
if (vid_line < 0)
|
||||
{
|
||||
vid_line += ((vid_wmodes + (vid_column_size - 1)) /
|
||||
vid_column_size) * vid_column_size;
|
||||
|
||||
while (vid_line >= vid_wmodes)
|
||||
vid_line -= vid_column_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case K_RIGHTARROW:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
vid_line += vid_column_size;
|
||||
|
||||
if (vid_line >= vid_wmodes)
|
||||
{
|
||||
vid_line -= ((vid_wmodes + (vid_column_size - 1)) /
|
||||
vid_column_size) * vid_column_size;
|
||||
|
||||
while (vid_line < 0)
|
||||
vid_line += vid_column_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case K_ENTER:
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
VID_SetMode (modedescs[vid_line].modenum, vid_current_palette);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
case 't':
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
if (VID_SetMode (modedescs[vid_line].modenum, vid_current_palette))
|
||||
{
|
||||
vid_testingmode = 1;
|
||||
vid_testendtime = realtime + 5.0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
S_LocalSound ("misc/menu1.wav");
|
||||
firstupdate = 0;
|
||||
Cvar_SetValue ("_vid_default_mode", vid_modenum);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// vid_dos.h: header file for DOS-specific video stuff
|
||||
|
||||
typedef struct vmode_s {
|
||||
struct vmode_s *pnext;
|
||||
char *name;
|
||||
char *header;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
float aspect;
|
||||
unsigned rowbytes;
|
||||
int planar;
|
||||
int numpages;
|
||||
void *pextradata;
|
||||
int (*setmode)(viddef_t *vid, struct vmode_s *pcurrentmode);
|
||||
void (*swapbuffers)(viddef_t *vid, struct vmode_s *pcurrentmode,
|
||||
vrect_t *rects);
|
||||
void (*setpalette)(viddef_t *vid, struct vmode_s *pcurrentmode,
|
||||
unsigned char *palette);
|
||||
void (*begindirectrect)(viddef_t *vid, struct vmode_s *pcurrentmode,
|
||||
int x, int y, byte *pbitmap, int width,
|
||||
int height);
|
||||
void (*enddirectrect)(viddef_t *vid, struct vmode_s *pcurrentmode,
|
||||
int x, int y, int width, int height);
|
||||
} vmode_t;
|
||||
|
||||
// vid_wait settings
|
||||
#define VID_WAIT_NONE 0
|
||||
#define VID_WAIT_VSYNC 1
|
||||
#define VID_WAIT_DISPLAY_ENABLE 2
|
||||
|
||||
extern int numvidmodes;
|
||||
extern vmode_t *pvidmodes;
|
||||
|
||||
extern int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes;
|
||||
extern byte *VGA_pagebase;
|
||||
extern vmode_t *VGA_pcurmode;
|
||||
|
||||
extern cvar_t vid_wait;
|
||||
extern cvar_t vid_nopageflip;
|
||||
extern cvar_t _vid_wait_override;
|
||||
|
||||
extern unsigned char colormap256[32][256];
|
||||
|
||||
extern void *vid_surfcache;
|
||||
extern int vid_surfcachesize;
|
||||
|
||||
void VGA_Init (void);
|
||||
void VID_InitVESA (void);
|
||||
void VID_InitExtra (void);
|
||||
void VGA_WaitVsync (void);
|
||||
void VGA_ClearVideoMem (int planar);
|
||||
void VGA_SetPalette(viddef_t *vid, vmode_t *pcurrentmode, unsigned char *pal);
|
||||
void VGA_SwapBuffersCopy (viddef_t *vid, vmode_t *pcurrentmode,
|
||||
vrect_t *rects);
|
||||
qboolean VGA_FreeAndAllocVidbuffer (viddef_t *vid, int allocnewbuffer);
|
||||
qboolean VGA_CheckAdequateMem (int width, int height, int rowbytes,
|
||||
int allocnewbuffer);
|
||||
void VGA_BeginDirectRect (viddef_t *vid, struct vmode_s *pcurrentmode, int x,
|
||||
int y, byte *pbitmap, int width, int height);
|
||||
void VGA_EndDirectRect (viddef_t *vid, struct vmode_s *pcurrentmode, int x,
|
||||
int y, int width, int height);
|
||||
void VGA_UpdateLinearScreen (void *srcptr, void *destptr, int width,
|
||||
int height, int srcrowbytes, int destrowbytes);
|
||||
|
795
source/vid_ext.c
795
source/vid_ext.c
|
@ -1,795 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// vid_ext.c: extended video modes
|
||||
// in this implementation, VESA-specific DOS video stuff
|
||||
//
|
||||
|
||||
// TODO: make dependencies on vid_vga.c explicit or eliminate them
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "dosisms.h"
|
||||
#include "vid_dos.h"
|
||||
#include <dpmi.h>
|
||||
|
||||
#define MODE_SUPPORTED_IN_HW 0x0001
|
||||
#define COLOR_MODE 0x0008
|
||||
#define GRAPHICS_MODE 0x0010
|
||||
#define VGA_INCOMPATIBLE 0x0020
|
||||
#define LINEAR_FRAME_BUFFER 0x0080
|
||||
|
||||
#define LINEAR_MODE 0x4000
|
||||
|
||||
#define VESA_DONT_WAIT_VSYNC 0 // when page flipping
|
||||
#define VESA_WAIT_VSYNC 0x80
|
||||
|
||||
#define MAX_VESA_MODES 30 // we'll just take the first 30 if there
|
||||
// are more
|
||||
typedef struct {
|
||||
int pages[3]; // either 2 or 3 is valid
|
||||
int vesamode; // LINEAR_MODE set if linear mode
|
||||
void *plinearmem; // linear address of start of frame buffer
|
||||
qboolean vga_incompatible;
|
||||
} vesa_extra_t;
|
||||
|
||||
static vmode_t vesa_modes[MAX_VESA_MODES] =
|
||||
{{NULL, NULL, " ********* VESA modes ********* "}};
|
||||
static vesa_extra_t vesa_extra[MAX_VESA_MODES];
|
||||
static char names[MAX_VESA_MODES][10];
|
||||
|
||||
extern regs_t regs;
|
||||
|
||||
static int VID_currentpage;
|
||||
static int VID_displayedpage;
|
||||
static int *VID_pagelist;
|
||||
static byte *VID_membase;
|
||||
static int VID_banked;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int modenum;
|
||||
int mode_attributes;
|
||||
int winasegment;
|
||||
int winbsegment;
|
||||
int bytes_per_scanline; // bytes per logical scanline (+16)
|
||||
int win; // window number (A=0, B=1)
|
||||
int win_size; // window size (+6)
|
||||
int granularity; // how finely i can set the window in vid mem (+4)
|
||||
int width, height; // displayed width and height (+18, +20)
|
||||
int bits_per_pixel; // er, better be 8, 15, 16, 24, or 32 (+25)
|
||||
int bytes_per_pixel; // er, better be 1, 2, or 4
|
||||
int memory_model; // and better be 4 or 6, packed or direct color (+27)
|
||||
int num_pages; // number of complete frame buffer pages (+29)
|
||||
int red_width; // the # of bits in the red component (+31)
|
||||
int red_pos; // the bit position of the red component (+32)
|
||||
int green_width; // etc.. (+33)
|
||||
int green_pos; // (+34)
|
||||
int blue_width; // (+35)
|
||||
int blue_pos; // (+36)
|
||||
int pptr;
|
||||
int pagesize;
|
||||
int numpages;
|
||||
} modeinfo_t;
|
||||
|
||||
static modeinfo_t modeinfo;
|
||||
|
||||
// all bytes to avoid problems with compiler field packing
|
||||
typedef struct vbeinfoblock_s {
|
||||
byte VbeSignature[4];
|
||||
byte VbeVersion[2];
|
||||
byte OemStringPtr[4];
|
||||
byte Capabilities[4];
|
||||
byte VideoModePtr[4];
|
||||
byte TotalMemory[2];
|
||||
byte OemSoftwareRev[2];
|
||||
byte OemVendorNamePtr[4];
|
||||
byte OemProductNamePtr[4];
|
||||
byte OemProductRevPtr[4];
|
||||
byte Reserved[222];
|
||||
byte OemData[256];
|
||||
} vbeinfoblock_t;
|
||||
|
||||
static int totalvidmem;
|
||||
static byte *ppal;
|
||||
qboolean vsync_exists, de_exists;
|
||||
|
||||
qboolean VID_ExtraGetModeInfo(int modenum);
|
||||
int VID_ExtraInitMode (viddef_t *vid, vmode_t *pcurrentmode);
|
||||
void VID_ExtraSwapBuffers (viddef_t *vid, vmode_t *pcurrentmode,
|
||||
vrect_t *rects);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_BankedBeginDirectRect
|
||||
================
|
||||
*/
|
||||
void VGA_BankedBeginDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode,
|
||||
int x, int y, byte *pbitmap, int width, int height)
|
||||
{
|
||||
|
||||
if (!lvid->direct)
|
||||
return;
|
||||
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_displayedpage;
|
||||
dos_int86(0x10);
|
||||
|
||||
VGA_BeginDirectRect (lvid, pcurrentmode, x, y, pbitmap, width, height);
|
||||
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_currentpage;
|
||||
dos_int86(0x10);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_BankedEndDirectRect
|
||||
================
|
||||
*/
|
||||
void VGA_BankedEndDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
|
||||
if (!lvid->direct)
|
||||
return;
|
||||
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_displayedpage;
|
||||
dos_int86(0x10);
|
||||
|
||||
VGA_EndDirectRect (lvid, pcurrentmode, x, y, width, height);
|
||||
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_currentpage;
|
||||
dos_int86(0x10);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_SetVESAPalette
|
||||
================
|
||||
*/
|
||||
void VID_SetVESAPalette (viddef_t *lvid, vmode_t *pcurrentmode,
|
||||
unsigned char *pal)
|
||||
{
|
||||
int i;
|
||||
byte *pp;
|
||||
|
||||
UNUSED(lvid);
|
||||
UNUSED(pcurrentmode);
|
||||
|
||||
pp = ppal;
|
||||
|
||||
for (i=0 ; i<256 ; i++)
|
||||
{
|
||||
pp[2] = pal[0] >> 2;
|
||||
pp[1] = pal[1] >> 2;
|
||||
pp[0] = pal[2] >> 2;
|
||||
pp += 4;
|
||||
pal += 3;
|
||||
}
|
||||
|
||||
regs.x.ax = 0x4F09;
|
||||
regs.x.bx = 0;
|
||||
regs.x.cx = 256;
|
||||
regs.x.dx = 0;
|
||||
regs.x.es = ptr2real(ppal) >> 4;
|
||||
regs.x.di = ptr2real(ppal) & 0xf;
|
||||
dos_int86(0x10);
|
||||
|
||||
if (regs.x.ax != 0x4f)
|
||||
Sys_Error ("Unable to load VESA palette\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraFarToLinear
|
||||
================
|
||||
*/
|
||||
void *VID_ExtraFarToLinear (void *ptr)
|
||||
{
|
||||
int temp;
|
||||
|
||||
temp = (int)ptr;
|
||||
return real2ptr(((temp & 0xFFFF0000) >> 12) + (temp & 0xFFFF));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraWaitDisplayEnable
|
||||
================
|
||||
*/
|
||||
void VID_ExtraWaitDisplayEnable ()
|
||||
{
|
||||
while ((inportb (0x3DA) & 0x01) == 1)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraVidLookForState
|
||||
================
|
||||
*/
|
||||
qboolean VID_ExtraVidLookForState (unsigned state, unsigned mask)
|
||||
{
|
||||
int i;
|
||||
double starttime, time;
|
||||
|
||||
starttime = Sys_FloatTime ();
|
||||
|
||||
do
|
||||
{
|
||||
for (i=0 ; i<100000 ; i++)
|
||||
{
|
||||
if ((inportb (0x3DA) & mask) == state)
|
||||
return true;
|
||||
}
|
||||
|
||||
time = Sys_FloatTime ();
|
||||
} while ((time - starttime) < 0.1);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraStateFound
|
||||
================
|
||||
*/
|
||||
qboolean VID_ExtraStateFound (unsigned state)
|
||||
{
|
||||
int i, workingstate;
|
||||
|
||||
workingstate = 0;
|
||||
|
||||
for (i=0 ; i<10 ; i++)
|
||||
{
|
||||
if (!VID_ExtraVidLookForState(workingstate, state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
workingstate ^= state;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_InitExtra
|
||||
================
|
||||
*/
|
||||
void VID_InitExtra (void)
|
||||
{
|
||||
int nummodes;
|
||||
short *pmodenums;
|
||||
vbeinfoblock_t *pinfoblock;
|
||||
__dpmi_meminfo phys_mem_info;
|
||||
|
||||
pinfoblock = dos_getmemory(sizeof(vbeinfoblock_t));
|
||||
|
||||
*(long *)pinfoblock->VbeSignature = 'V' + ('B'<<8) + ('E'<<16) + ('2'<<24);
|
||||
|
||||
// see if VESA support is available
|
||||
regs.x.ax = 0x4f00;
|
||||
regs.x.es = ptr2real(pinfoblock) >> 4;
|
||||
regs.x.di = ptr2real(pinfoblock) & 0xf;
|
||||
dos_int86(0x10);
|
||||
|
||||
if (regs.x.ax != 0x4f)
|
||||
return; // no VESA support
|
||||
|
||||
if (pinfoblock->VbeVersion[1] < 0x02)
|
||||
return; // not VESA 2.0 or greater
|
||||
|
||||
Con_Printf ("VESA 2.0 compliant adapter:\n%s\n",
|
||||
VID_ExtraFarToLinear (*(byte **)&pinfoblock->OemStringPtr[0]));
|
||||
|
||||
totalvidmem = *(unsigned short *)&pinfoblock->TotalMemory[0] << 16;
|
||||
|
||||
pmodenums = (short *)
|
||||
VID_ExtraFarToLinear (*(byte **)&pinfoblock->VideoModePtr[0]);
|
||||
|
||||
// find 8 bit modes until we either run out of space or run out of modes
|
||||
nummodes = 0;
|
||||
|
||||
while ((*pmodenums != -1) && (nummodes < MAX_VESA_MODES))
|
||||
{
|
||||
if (VID_ExtraGetModeInfo (*pmodenums))
|
||||
{
|
||||
vesa_modes[nummodes].pnext = &vesa_modes[nummodes+1];
|
||||
if (modeinfo.width > 999)
|
||||
{
|
||||
if (modeinfo.height > 999)
|
||||
{
|
||||
sprintf (&names[nummodes][0], "%4dx%4d", modeinfo.width,
|
||||
modeinfo.height);
|
||||
names[nummodes][9] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (&names[nummodes][0], "%4dx%3d", modeinfo.width,
|
||||
modeinfo.height);
|
||||
names[nummodes][8] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modeinfo.height > 999)
|
||||
{
|
||||
sprintf (&names[nummodes][0], "%3dx%4d", modeinfo.width,
|
||||
modeinfo.height);
|
||||
names[nummodes][8] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (&names[nummodes][0], "%3dx%3d", modeinfo.width,
|
||||
modeinfo.height);
|
||||
names[nummodes][7] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
vesa_modes[nummodes].name = &names[nummodes][0];
|
||||
vesa_modes[nummodes].width = modeinfo.width;
|
||||
vesa_modes[nummodes].height = modeinfo.height;
|
||||
vesa_modes[nummodes].aspect =
|
||||
((float)modeinfo.height / (float)modeinfo.width) *
|
||||
(320.0 / 240.0);
|
||||
vesa_modes[nummodes].rowbytes = modeinfo.bytes_per_scanline;
|
||||
vesa_modes[nummodes].planar = 0;
|
||||
vesa_modes[nummodes].pextradata = &vesa_extra[nummodes];
|
||||
vesa_modes[nummodes].setmode = VID_ExtraInitMode;
|
||||
vesa_modes[nummodes].swapbuffers = VID_ExtraSwapBuffers;
|
||||
vesa_modes[nummodes].setpalette = VID_SetVESAPalette;
|
||||
|
||||
if (modeinfo.mode_attributes & LINEAR_FRAME_BUFFER)
|
||||
{
|
||||
// add linear bit to mode for linear modes
|
||||
vesa_extra[nummodes].vesamode = modeinfo.modenum | LINEAR_MODE;
|
||||
vesa_extra[nummodes].pages[0] = 0;
|
||||
vesa_extra[nummodes].pages[1] = modeinfo.pagesize;
|
||||
vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2;
|
||||
vesa_modes[nummodes].numpages = modeinfo.numpages;
|
||||
|
||||
vesa_modes[nummodes].begindirectrect = VGA_BeginDirectRect;
|
||||
vesa_modes[nummodes].enddirectrect = VGA_EndDirectRect;
|
||||
|
||||
phys_mem_info.address = (int)modeinfo.pptr;
|
||||
phys_mem_info.size = 0x400000;
|
||||
|
||||
if (__dpmi_physical_address_mapping(&phys_mem_info))
|
||||
goto NextMode;
|
||||
|
||||
vesa_extra[nummodes].plinearmem =
|
||||
real2ptr (phys_mem_info.address);
|
||||
}
|
||||
else
|
||||
{
|
||||
// banked at 0xA0000
|
||||
vesa_extra[nummodes].vesamode = modeinfo.modenum;
|
||||
vesa_extra[nummodes].pages[0] = 0;
|
||||
vesa_extra[nummodes].plinearmem =
|
||||
real2ptr(modeinfo.winasegment<<4);
|
||||
|
||||
vesa_modes[nummodes].begindirectrect =
|
||||
VGA_BankedBeginDirectRect;
|
||||
vesa_modes[nummodes].enddirectrect = VGA_BankedEndDirectRect;
|
||||
vesa_extra[nummodes].pages[1] = modeinfo.pagesize;
|
||||
vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2;
|
||||
vesa_modes[nummodes].numpages = modeinfo.numpages;
|
||||
}
|
||||
|
||||
vesa_extra[nummodes].vga_incompatible =
|
||||
modeinfo.mode_attributes & VGA_INCOMPATIBLE;
|
||||
|
||||
nummodes++;
|
||||
}
|
||||
NextMode:
|
||||
pmodenums++;
|
||||
}
|
||||
|
||||
// add the VESA modes at the start of the mode list (if there are any)
|
||||
if (nummodes)
|
||||
{
|
||||
vesa_modes[nummodes-1].pnext = pvidmodes;
|
||||
pvidmodes = &vesa_modes[0];
|
||||
numvidmodes += nummodes;
|
||||
ppal = dos_getmemory(256*4);
|
||||
}
|
||||
|
||||
dos_freememory(pinfoblock);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraGetModeInfo
|
||||
================
|
||||
*/
|
||||
qboolean VID_ExtraGetModeInfo(int modenum)
|
||||
{
|
||||
char *infobuf;
|
||||
int numimagepages;
|
||||
|
||||
infobuf = dos_getmemory(256);
|
||||
|
||||
regs.x.ax = 0x4f01;
|
||||
regs.x.cx = modenum;
|
||||
regs.x.es = ptr2real(infobuf) >> 4;
|
||||
regs.x.di = ptr2real(infobuf) & 0xf;
|
||||
dos_int86(0x10);
|
||||
if (regs.x.ax != 0x4f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
modeinfo.modenum = modenum;
|
||||
modeinfo.bits_per_pixel = *(char*)(infobuf+25);
|
||||
modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8;
|
||||
modeinfo.width = *(short*)(infobuf+18);
|
||||
modeinfo.height = *(short*)(infobuf+20);
|
||||
|
||||
// we do only 8-bpp in software
|
||||
if ((modeinfo.bits_per_pixel != 8) ||
|
||||
(modeinfo.bytes_per_pixel != 1) ||
|
||||
(modeinfo.width > MAXWIDTH) ||
|
||||
(modeinfo.height > MAXHEIGHT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
modeinfo.mode_attributes = *(short*)infobuf;
|
||||
|
||||
// we only want color graphics modes that are supported by the hardware
|
||||
if ((modeinfo.mode_attributes &
|
||||
(MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE)) !=
|
||||
(MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// we only work with linear frame buffers, except for 320x200, which can
|
||||
// effectively be linear when banked at 0xA000
|
||||
if (!(modeinfo.mode_attributes & LINEAR_FRAME_BUFFER))
|
||||
{
|
||||
if ((modeinfo.width != 320) || (modeinfo.height != 200))
|
||||
return false;
|
||||
}
|
||||
|
||||
modeinfo.bytes_per_scanline = *(short*)(infobuf+16);
|
||||
|
||||
modeinfo.pagesize = modeinfo.bytes_per_scanline * modeinfo.height;
|
||||
|
||||
if (modeinfo.pagesize > totalvidmem)
|
||||
return false;
|
||||
|
||||
// force to one page if the adapter reports it doesn't support more pages
|
||||
// than that, no matter how much memory it has--it may not have hardware
|
||||
// support for page flipping
|
||||
numimagepages = *(unsigned char *)(infobuf+29);
|
||||
|
||||
if (numimagepages <= 0)
|
||||
{
|
||||
// wrong, but there seems to be an ATI VESA driver that reports 0
|
||||
modeinfo.numpages = 1;
|
||||
}
|
||||
else if (numimagepages < 3)
|
||||
{
|
||||
modeinfo.numpages = numimagepages;
|
||||
}
|
||||
else
|
||||
{
|
||||
modeinfo.numpages = 3;
|
||||
}
|
||||
|
||||
if (*(char*)(infobuf+2) & 5)
|
||||
{
|
||||
modeinfo.winasegment = *(unsigned short*)(infobuf+8);
|
||||
modeinfo.win = 0;
|
||||
}
|
||||
else if (*(char*)(infobuf+3) & 5)
|
||||
{
|
||||
modeinfo.winbsegment = *(unsigned short*)(infobuf+8);
|
||||
modeinfo.win = 1;
|
||||
}
|
||||
modeinfo.granularity = *(short*)(infobuf+4) * 1024;
|
||||
modeinfo.win_size = *(short*)(infobuf+6) * 1024;
|
||||
modeinfo.bits_per_pixel = *(char*)(infobuf+25);
|
||||
modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8;
|
||||
modeinfo.memory_model = *(unsigned char*)(infobuf+27);
|
||||
modeinfo.num_pages = *(char*)(infobuf+29) + 1;
|
||||
|
||||
modeinfo.red_width = *(char*)(infobuf+31);
|
||||
modeinfo.red_pos = *(char*)(infobuf+32);
|
||||
modeinfo.green_width = *(char*)(infobuf+33);
|
||||
modeinfo.green_pos = *(char*)(infobuf+34);
|
||||
modeinfo.blue_width = *(char*)(infobuf+35);
|
||||
modeinfo.blue_pos = *(char*)(infobuf+36);
|
||||
|
||||
modeinfo.pptr = *(long *)(infobuf+40);
|
||||
|
||||
#if 0
|
||||
printf("VID: (VESA) info for mode 0x%x\n", modeinfo.modenum);
|
||||
printf(" mode attrib = 0x%0x\n", modeinfo.mode_attributes);
|
||||
printf(" win a attrib = 0x%0x\n", *(unsigned char*)(infobuf+2));
|
||||
printf(" win b attrib = 0x%0x\n", *(unsigned char*)(infobuf+3));
|
||||
printf(" win a seg 0x%0x\n", (int) modeinfo.winasegment);
|
||||
printf(" win b seg 0x%0x\n", (int) modeinfo.winbsegment);
|
||||
printf(" bytes per scanline = %d\n",
|
||||
modeinfo.bytes_per_scanline);
|
||||
printf(" width = %d, height = %d\n", modeinfo.width,
|
||||
modeinfo.height);
|
||||
printf(" win = %c\n", 'A' + modeinfo.win);
|
||||
printf(" win granularity = %d\n", modeinfo.granularity);
|
||||
printf(" win size = %d\n", modeinfo.win_size);
|
||||
printf(" bits per pixel = %d\n", modeinfo.bits_per_pixel);
|
||||
printf(" bytes per pixel = %d\n", modeinfo.bytes_per_pixel);
|
||||
printf(" memory model = 0x%x\n", modeinfo.memory_model);
|
||||
printf(" num pages = %d\n", modeinfo.num_pages);
|
||||
printf(" red width = %d\n", modeinfo.red_width);
|
||||
printf(" red pos = %d\n", modeinfo.red_pos);
|
||||
printf(" green width = %d\n", modeinfo.green_width);
|
||||
printf(" green pos = %d\n", modeinfo.green_pos);
|
||||
printf(" blue width = %d\n", modeinfo.blue_width);
|
||||
printf(" blue pos = %d\n", modeinfo.blue_pos);
|
||||
printf(" phys mem = %x\n", modeinfo.pptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
dos_freememory(infobuf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraInitMode
|
||||
================
|
||||
*/
|
||||
int VID_ExtraInitMode (viddef_t *lvid, vmode_t *pcurrentmode)
|
||||
{
|
||||
vesa_extra_t *pextra;
|
||||
int pageoffset;
|
||||
|
||||
pextra = pcurrentmode->pextradata;
|
||||
|
||||
if (vid_nopageflip.value)
|
||||
lvid->numpages = 1;
|
||||
else
|
||||
lvid->numpages = pcurrentmode->numpages;
|
||||
|
||||
// clean up any old vid buffer lying around, alloc new if needed
|
||||
if (!VGA_FreeAndAllocVidbuffer (lvid, lvid->numpages == 1))
|
||||
return -1; // memory alloc failed
|
||||
|
||||
// clear the screen and wait for the next frame. VGA_pcurmode, which
|
||||
// VGA_ClearVideoMem relies on, is guaranteed to be set because mode 0 is
|
||||
// always the first mode set in a session
|
||||
if (VGA_pcurmode)
|
||||
VGA_ClearVideoMem (VGA_pcurmode->planar);
|
||||
|
||||
// set the mode
|
||||
regs.x.ax = 0x4f02;
|
||||
regs.x.bx = pextra->vesamode;
|
||||
dos_int86(0x10);
|
||||
|
||||
if (regs.x.ax != 0x4f)
|
||||
return 0;
|
||||
|
||||
VID_banked = !(pextra->vesamode & LINEAR_MODE);
|
||||
VID_membase = pextra->plinearmem;
|
||||
VGA_width = lvid->width;
|
||||
VGA_height = lvid->height;
|
||||
VGA_rowbytes = lvid->rowbytes;
|
||||
|
||||
lvid->colormap = host_colormap;
|
||||
|
||||
VID_pagelist = &pextra->pages[0];
|
||||
|
||||
// wait for display enable by default only when triple-buffering on a VGA-
|
||||
// compatible machine that actually has a functioning display enable status
|
||||
vsync_exists = VID_ExtraStateFound (0x08);
|
||||
de_exists = VID_ExtraStateFound (0x01);
|
||||
|
||||
if (!pextra->vga_incompatible &&
|
||||
(lvid->numpages == 3) &&
|
||||
de_exists &&
|
||||
(_vid_wait_override.value == 0.0))
|
||||
{
|
||||
Cvar_SetValue ("vid_wait", (float)VID_WAIT_DISPLAY_ENABLE);
|
||||
|
||||
VID_displayedpage = 0;
|
||||
VID_currentpage = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((lvid->numpages == 1) && (_vid_wait_override.value == 0.0))
|
||||
{
|
||||
Cvar_SetValue ("vid_wait", (float)VID_WAIT_NONE);
|
||||
VID_displayedpage = VID_currentpage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetValue ("vid_wait", (float)VID_WAIT_VSYNC);
|
||||
|
||||
VID_displayedpage = 0;
|
||||
|
||||
if (lvid->numpages > 1)
|
||||
VID_currentpage = 1;
|
||||
else
|
||||
VID_currentpage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: really should be a call to a function
|
||||
pageoffset = VID_pagelist[VID_displayedpage];
|
||||
|
||||
regs.x.ax = 0x4f07;
|
||||
regs.x.bx = 0x80; // wait for vsync so we know page 0 is visible
|
||||
regs.x.cx = pageoffset % VGA_rowbytes;
|
||||
regs.x.dx = pageoffset / VGA_rowbytes;
|
||||
dos_int86(0x10);
|
||||
|
||||
if (VID_banked)
|
||||
{
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_currentpage;
|
||||
dos_int86(0x10);
|
||||
|
||||
VGA_pagebase = VID_membase;
|
||||
}
|
||||
else
|
||||
{
|
||||
VGA_pagebase = VID_membase + VID_pagelist[VID_currentpage];
|
||||
}
|
||||
|
||||
if (lvid->numpages > 1)
|
||||
{
|
||||
lvid->buffer = VGA_pagebase;
|
||||
lvid->conbuffer = lvid->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
lvid->rowbytes = lvid->width;
|
||||
}
|
||||
|
||||
lvid->direct = VGA_pagebase;
|
||||
lvid->conrowbytes = lvid->rowbytes;
|
||||
lvid->conwidth = lvid->width;
|
||||
lvid->conheight = lvid->height;
|
||||
|
||||
lvid->maxwarpwidth = WARP_WIDTH;
|
||||
lvid->maxwarpheight = WARP_HEIGHT;
|
||||
|
||||
VGA_pcurmode = pcurrentmode;
|
||||
|
||||
D_InitCaches (vid_surfcache, vid_surfcachesize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VID_ExtraSwapBuffers
|
||||
================
|
||||
*/
|
||||
void VID_ExtraSwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode,
|
||||
vrect_t *rects)
|
||||
{
|
||||
int pageoffset;
|
||||
|
||||
UNUSED(rects);
|
||||
UNUSED(pcurrentmode);
|
||||
|
||||
pageoffset = VID_pagelist[VID_currentpage];
|
||||
|
||||
// display the newly finished page
|
||||
if (lvid->numpages > 1)
|
||||
{
|
||||
// page flipped
|
||||
regs.x.ax = 0x4f07;
|
||||
|
||||
if (vid_wait.value != VID_WAIT_VSYNC)
|
||||
{
|
||||
if ((vid_wait.value == VID_WAIT_DISPLAY_ENABLE) && de_exists)
|
||||
VID_ExtraWaitDisplayEnable ();
|
||||
|
||||
regs.x.bx = VESA_DONT_WAIT_VSYNC;
|
||||
}
|
||||
else
|
||||
{
|
||||
regs.x.bx = VESA_WAIT_VSYNC; // double buffered has to wait
|
||||
}
|
||||
|
||||
regs.x.cx = pageoffset % VGA_rowbytes;
|
||||
regs.x.dx = pageoffset / VGA_rowbytes;
|
||||
dos_int86(0x10);
|
||||
|
||||
VID_displayedpage = VID_currentpage;
|
||||
if (++VID_currentpage >= lvid->numpages)
|
||||
VID_currentpage = 0;
|
||||
|
||||
//
|
||||
// set the new write window if this is a banked mode; otherwise, set the
|
||||
// new address to which to write
|
||||
//
|
||||
if (VID_banked)
|
||||
{
|
||||
regs.x.ax = 0x4f05;
|
||||
regs.x.bx = 0;
|
||||
regs.x.dx = VID_currentpage;
|
||||
dos_int86(0x10);
|
||||
}
|
||||
else
|
||||
{
|
||||
lvid->direct = lvid->buffer; // direct drawing goes to the
|
||||
// currently displayed page
|
||||
lvid->buffer = VID_membase + VID_pagelist[VID_currentpage];
|
||||
lvid->conbuffer = lvid->buffer;
|
||||
}
|
||||
|
||||
VGA_pagebase = lvid->buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// non-page-flipped
|
||||
if (vsync_exists && (vid_wait.value == VID_WAIT_VSYNC))
|
||||
{
|
||||
VGA_WaitVsync ();
|
||||
}
|
||||
|
||||
while (rects)
|
||||
{
|
||||
VGA_UpdateLinearScreen (
|
||||
lvid->buffer + rects->x + (rects->y * lvid->rowbytes),
|
||||
VGA_pagebase + rects->x + (rects->y * VGA_rowbytes),
|
||||
rects->width,
|
||||
rects->height,
|
||||
lvid->rowbytes,
|
||||
VGA_rowbytes);
|
||||
|
||||
rects = rects->pnext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1257
source/vid_sunx.c
1257
source/vid_sunx.c
File diff suppressed because it is too large
Load diff
1288
source/vid_sunxil.c
1288
source/vid_sunxil.c
File diff suppressed because it is too large
Load diff
1003
source/vid_svgalib.c
1003
source/vid_svgalib.c
File diff suppressed because it is too large
Load diff
478
source/vid_vga.c
478
source/vid_vga.c
|
@ -1,478 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
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 2
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
//
|
||||
// vid_vga.c: VGA-specific DOS video stuff
|
||||
//
|
||||
|
||||
// TODO: proper handling of page-swap failure
|
||||
|
||||
#include <dos.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "d_local.h"
|
||||
#include "dosisms.h"
|
||||
#include "vid_dos.h"
|
||||
#include <dpmi.h>
|
||||
|
||||
extern regs_t regs;
|
||||
|
||||
int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes;
|
||||
byte *VGA_pagebase;
|
||||
vmode_t *VGA_pcurmode;
|
||||
|
||||
static int VGA_planar;
|
||||
static int VGA_numpages;
|
||||
static int VGA_buffersize;
|
||||
|
||||
void *vid_surfcache;
|
||||
int vid_surfcachesize;
|
||||
|
||||
int VGA_highhunkmark;
|
||||
|
||||
#include "vgamodes.h"
|
||||
|
||||
#define NUMVIDMODES (sizeof(vgavidmodes) / sizeof(vgavidmodes[0]))
|
||||
|
||||
void VGA_UpdatePlanarScreen (void *srcbuffer);
|
||||
|
||||
static byte backingbuf[48*24];
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_BeginDirectRect
|
||||
================
|
||||
*/
|
||||
void VGA_BeginDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, int x,
|
||||
int y, byte *pbitmap, int width, int height)
|
||||
{
|
||||
int i, j, k, plane, reps, repshift;
|
||||
|
||||
if (!lvid->direct)
|
||||
return;
|
||||
|
||||
if (lvid->aspect > 1.5)
|
||||
{
|
||||
reps = 2;
|
||||
repshift = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
reps = 1;
|
||||
repshift = 0;
|
||||
}
|
||||
|
||||
if (pcurrentmode->planar)
|
||||
{
|
||||
for (plane=0 ; plane<4 ; plane++)
|
||||
{
|
||||
// select the correct plane for reading and writing
|
||||
outportb (SC_INDEX, MAP_MASK);
|
||||
outportb (SC_DATA, 1 << plane);
|
||||
outportb (GC_INDEX, READ_MAP);
|
||||
outportb (GC_DATA, plane);
|
||||
|
||||
for (i=0 ; i<(height << repshift) ; i += reps)
|
||||
{
|
||||
for (k=0 ; k<reps ; k++)
|
||||
{
|
||||
for (j=0 ; j<(width >> 2) ; j++)
|
||||
{
|
||||
backingbuf[(i + k) * 24 + (j << 2) + plane] =
|
||||
lvid->direct[(y + i + k) * VGA_rowbytes +
|
||||
(x >> 2) + j];
|
||||
lvid->direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
|
||||
pbitmap[(i >> repshift) * 24 +
|
||||
(j << 2) + plane];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i<(height << repshift) ; i += reps)
|
||||
{
|
||||
for (j=0 ; j<reps ; j++)
|
||||
{
|
||||
memcpy (&backingbuf[(i + j) * 24],
|
||||
lvid->direct + x + ((y << repshift) + i + j) *
|
||||
VGA_rowbytes,
|
||||
width);
|
||||
memcpy (lvid->direct + x + ((y << repshift) + i + j) *
|
||||
VGA_rowbytes,
|
||||
&pbitmap[(i >> repshift) * width],
|
||||
width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_EndDirectRect
|
||||
================
|
||||
*/
|
||||
void VGA_EndDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, int x,
|
||||
int y, int width, int height)
|
||||
{
|
||||
int i, j, k, plane, reps, repshift;
|
||||
|
||||
if (!lvid->direct)
|
||||
return;
|
||||
|
||||
if (lvid->aspect > 1.5)
|
||||
{
|
||||
reps = 2;
|
||||
repshift = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
reps = 1;
|
||||
repshift = 0;
|
||||
}
|
||||
|
||||
if (pcurrentmode->planar)
|
||||
{
|
||||
for (plane=0 ; plane<4 ; plane++)
|
||||
{
|
||||
// select the correct plane for writing
|
||||
outportb (SC_INDEX, MAP_MASK);
|
||||
outportb (SC_DATA, 1 << plane);
|
||||
|
||||
for (i=0 ; i<(height << repshift) ; i += reps)
|
||||
{
|
||||
for (k=0 ; k<reps ; k++)
|
||||
{
|
||||
for (j=0 ; j<(width >> 2) ; j++)
|
||||
{
|
||||
lvid->direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
|
||||
backingbuf[(i + k) * 24 + (j << 2) + plane];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i<(height << repshift) ; i += reps)
|
||||
{
|
||||
for (j=0 ; j<reps ; j++)
|
||||
{
|
||||
memcpy (lvid->direct + x + ((y << repshift) + i + j) *
|
||||
VGA_rowbytes,
|
||||
&backingbuf[(i + j) * 24],
|
||||
width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_Init
|
||||
================
|
||||
*/
|
||||
void VGA_Init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// link together all the VGA modes
|
||||
for (i=0 ; i<(NUMVIDMODES - 1) ; i++)
|
||||
{
|
||||
vgavidmodes[i].pnext = &vgavidmodes[i+1];
|
||||
}
|
||||
|
||||
// add the VGA modes at the start of the mode list
|
||||
vgavidmodes[NUMVIDMODES-1].pnext = pvidmodes;
|
||||
pvidmodes = &vgavidmodes[0];
|
||||
|
||||
numvidmodes += NUMVIDMODES;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_WaitVsync
|
||||
================
|
||||
*/
|
||||
void VGA_WaitVsync (void)
|
||||
{
|
||||
while ((inportb (0x3DA) & 0x08) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_ClearVideoMem
|
||||
================
|
||||
*/
|
||||
void VGA_ClearVideoMem (int planar)
|
||||
{
|
||||
|
||||
if (planar)
|
||||
{
|
||||
// enable all planes for writing
|
||||
outportb (SC_INDEX, MAP_MASK);
|
||||
outportb (SC_DATA, 0x0F);
|
||||
}
|
||||
|
||||
Q_memset (VGA_pagebase, 0, VGA_rowbytes * VGA_height);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_FreeAndAllocVidbuffer
|
||||
================
|
||||
*/
|
||||
qboolean VGA_FreeAndAllocVidbuffer (viddef_t *lvid, int allocnewbuffer)
|
||||
{
|
||||
int tsize, tbuffersize;
|
||||
|
||||
if (allocnewbuffer)
|
||||
{
|
||||
// alloc an extra line in case we want to wrap, and allocate the z-buffer
|
||||
tbuffersize = (lvid->rowbytes * (lvid->height + 1)) +
|
||||
(lvid->width * lvid->height * sizeof (*d_pzbuffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
// just allocate the z-buffer
|
||||
tbuffersize = lvid->width * lvid->height * sizeof (*d_pzbuffer);
|
||||
}
|
||||
|
||||
tsize = D_SurfaceCacheForRes (lvid->width, lvid->height);
|
||||
|
||||
tbuffersize += tsize;
|
||||
|
||||
// see if there's enough memory, allowing for the normal mode 0x13 pixel,
|
||||
// z, and surface buffers
|
||||
if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
|
||||
0x10000 * 3) < minimum_memory)
|
||||
{
|
||||
Con_Printf ("Not enough memory for video mode\n");
|
||||
VGA_pcurmode = NULL; // so no further accesses to the buffer are
|
||||
// attempted, particularly when clearing
|
||||
return false; // not enough memory for mode
|
||||
}
|
||||
|
||||
VGA_buffersize = tbuffersize;
|
||||
vid_surfcachesize = tsize;
|
||||
|
||||
if (d_pzbuffer)
|
||||
{
|
||||
D_FlushCaches ();
|
||||
Hunk_FreeToHighMark (VGA_highhunkmark);
|
||||
d_pzbuffer = NULL;
|
||||
}
|
||||
|
||||
VGA_highhunkmark = Hunk_HighMark ();
|
||||
|
||||
d_pzbuffer = Hunk_HighAllocName (VGA_buffersize, "video");
|
||||
|
||||
vid_surfcache = (byte *)d_pzbuffer
|
||||
+ lvid->width * lvid->height * sizeof (*d_pzbuffer);
|
||||
|
||||
if (allocnewbuffer)
|
||||
{
|
||||
lvid->buffer = (void *)( (byte *)vid_surfcache + vid_surfcachesize);
|
||||
lvid->conbuffer = lvid->buffer;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_CheckAdequateMem
|
||||
================
|
||||
*/
|
||||
qboolean VGA_CheckAdequateMem (int width, int height, int rowbytes,
|
||||
int allocnewbuffer)
|
||||
{
|
||||
int tbuffersize;
|
||||
|
||||
tbuffersize = width * height * sizeof (*d_pzbuffer);
|
||||
|
||||
if (allocnewbuffer)
|
||||
{
|
||||
// alloc an extra line in case we want to wrap, and allocate the z-buffer
|
||||
tbuffersize += (rowbytes * (height + 1));
|
||||
}
|
||||
|
||||
tbuffersize += D_SurfaceCacheForRes (width, height);
|
||||
|
||||
// see if there's enough memory, allowing for the normal mode 0x13 pixel,
|
||||
// z, and surface buffers
|
||||
if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
|
||||
0x10000 * 3) < minimum_memory)
|
||||
{
|
||||
return false; // not enough memory for mode
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_InitMode
|
||||
================
|
||||
*/
|
||||
int VGA_InitMode (viddef_t *lvid, vmode_t *pcurrentmode)
|
||||
{
|
||||
vextra_t *pextra;
|
||||
|
||||
pextra = pcurrentmode->pextradata;
|
||||
|
||||
if (!VGA_FreeAndAllocVidbuffer (lvid, pextra->vidbuffer))
|
||||
return -1; // memory alloc failed
|
||||
|
||||
if (VGA_pcurmode)
|
||||
VGA_ClearVideoMem (VGA_pcurmode->planar);
|
||||
|
||||
// mode 0x13 is the base for all the Mode X-class mode sets
|
||||
regs.h.ah = 0;
|
||||
regs.h.al = 0x13;
|
||||
dos_int86(0x10);
|
||||
|
||||
VGA_pagebase = (void *)real2ptr(0xa0000);
|
||||
lvid->direct = (pixel_t *)VGA_pagebase;
|
||||
|
||||
// set additional registers as needed
|
||||
VideoRegisterSet (pextra->pregset);
|
||||
|
||||
VGA_numpages = 1;
|
||||
lvid->numpages = VGA_numpages;
|
||||
|
||||
VGA_width = (lvid->width + 0x1F) & ~0x1F;
|
||||
VGA_height = lvid->height;
|
||||
VGA_planar = pcurrentmode->planar;
|
||||
if (VGA_planar)
|
||||
VGA_rowbytes = lvid->rowbytes / 4;
|
||||
else
|
||||
VGA_rowbytes = lvid->rowbytes;
|
||||
VGA_bufferrowbytes = lvid->rowbytes;
|
||||
lvid->colormap = host_colormap;
|
||||
lvid->fullbright = 256 - LittleLong (*((int *)lvid->colormap + 2048));
|
||||
|
||||
lvid->maxwarpwidth = WARP_WIDTH;
|
||||
lvid->maxwarpheight = WARP_HEIGHT;
|
||||
|
||||
lvid->conbuffer = lvid->buffer;
|
||||
lvid->conrowbytes = lvid->rowbytes;
|
||||
lvid->conwidth = lvid->width;
|
||||
lvid->conheight = lvid->height;
|
||||
|
||||
VGA_pcurmode = pcurrentmode;
|
||||
|
||||
VGA_ClearVideoMem (pcurrentmode->planar);
|
||||
|
||||
if (_vid_wait_override.value)
|
||||
{
|
||||
Cvar_SetValue ("vid_wait", (float)VID_WAIT_VSYNC);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetValue ("vid_wait", (float)VID_WAIT_NONE);
|
||||
}
|
||||
|
||||
D_InitCaches (vid_surfcache, vid_surfcachesize);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_SetPalette
|
||||
================
|
||||
*/
|
||||
void VGA_SetPalette(viddef_t *lvid, vmode_t *pcurrentmode, unsigned char *pal)
|
||||
{
|
||||
int shiftcomponents=2;
|
||||
int i;
|
||||
|
||||
UNUSED(lvid);
|
||||
UNUSED(pcurrentmode);
|
||||
|
||||
dos_outportb(0x3c8, 0);
|
||||
for (i=0 ; i<768 ; i++)
|
||||
outportb(0x3c9, pal[i]>>shiftcomponents);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_SwapBuffersCopy
|
||||
================
|
||||
*/
|
||||
void VGA_SwapBuffersCopy (viddef_t *lvid, vmode_t *pcurrentmode,
|
||||
vrect_t *rects)
|
||||
{
|
||||
|
||||
UNUSED(pcurrentmode);
|
||||
|
||||
// TODO: can write a dword at a time
|
||||
// TODO: put in ASM
|
||||
// TODO: copy only specified rectangles
|
||||
if (VGA_planar)
|
||||
{
|
||||
|
||||
// TODO: copy only specified rectangles
|
||||
|
||||
VGA_UpdatePlanarScreen (lvid->buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (rects)
|
||||
{
|
||||
VGA_UpdateLinearScreen (
|
||||
lvid->buffer + rects->x + (rects->y * lvid->rowbytes),
|
||||
VGA_pagebase + rects->x + (rects->y * VGA_rowbytes),
|
||||
rects->width,
|
||||
rects->height,
|
||||
lvid->rowbytes,
|
||||
VGA_rowbytes);
|
||||
|
||||
rects = rects->pnext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGA_SwapBuffers
|
||||
================
|
||||
*/
|
||||
void VGA_SwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode, vrect_t *rects)
|
||||
{
|
||||
UNUSED(lvid);
|
||||
|
||||
if (vid_wait.value == VID_WAIT_VSYNC)
|
||||
VGA_WaitVsync ();
|
||||
|
||||
VGA_SwapBuffersCopy (lvid, pcurrentmode, rects);
|
||||
}
|
||||
|
3343
source/vid_win.c
3343
source/vid_win.c
File diff suppressed because it is too large
Load diff
1199
source/vid_x.c
1199
source/vid_x.c
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue