vid_sunxil.c

来自「quake1 dos源代码最新版本」· C语言 代码 · 共 1,318 行 · 第 1/3 页

C
1,318
字号
/*
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_sunxil.c -- uses X to setup windows and XIL to copy images (scaled as needed)
// 		   to screen

#define _BSD
#define BYTE_DEFINED 1

#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <thread.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 <xil/xil.h>

#include "quakedef.h"
#include "d_local.h"

#define MIN_WIDTH 320
#define MIN_HEIGHT 200

cvar_t	*_windowed_mouse;
cvar_t	*m_filter;
float old_windowed_mouse;

// The following X property format is defined in Motif 1.1's
// Xm/MwmUtils.h, but QUAKE should not depend on that header
// file. Note: Motif 1.2 expanded this structure with
// uninteresting fields (to QUAKE) so just stick with the
// smaller Motif 1.1 structure.

#define MWM_HINTS_DECORATIONS   2
typedef struct
{
	long flags;
	long functions;
	long decorations;
	long input_mode;
} MotifWmHints;

#define MAX_COLUMN_SIZE	11

#define MAX_MODEDESCS	(MAX_COLUMN_SIZE*3)

typedef struct
{
	int		modenum;
	int		iscur;
	char	desc[256];
} modedesc_t;

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);

extern int sb_updates;

qboolean        mouse_avail;
int             mouse_buttons=3;
int             mouse_oldbuttonstate;
int             mouse_buttonstate;
float   mouse_x, mouse_y;
float   old_mouse_x, old_mouse_y;
int p_mouse_x;
int p_mouse_y;

typedef struct
{
	int input;
	int output;
} keymap_t;

viddef_t vid; // global video state
unsigned short       d_8to16table[256];

int		num_shades=32;

int	d_con_indirect = 0;

int		vid_buffersize;

#define STD_EVENT_MASK \
( \
	StructureNotifyMask | \
	KeyPressMask | \
	KeyReleaseMask | \
	ButtonPressMask | \
	ButtonReleaseMask | \
	ExposureMask | \
	PointerMotionMask | \
	FocusChangeMask \
)

int		VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar;
byte	*VGA_pagebase;

qboolean			x_fullscreen = true;
Display				*x_disp = NULL;
int				x_screen, x_screen_width, x_screen_height;
int				x_center_width, x_center_height;
int				x_std_event_mask = STD_EVENT_MASK;
Window				x_win, x_root_win;
qboolean			x_focus = true;
int				global_dx, global_dy;


static Colormap			x_cmap;
static GC			x_gc;
static Visual			*x_vis;
static XVisualInfo		*x_visinfo;
static Atom			aHints = NULL;
static Atom			aWMDelete = NULL;

static qboolean			oktodraw = false;
static qboolean			X11_active = false;


static int verbose=1;

static byte current_palette[768];

cvar_t	*pixel_multiply;
int current_pixel_multiply = 2;

#define PM(a) (int)((current_pixel_multiply)?((a)*current_pixel_multiply):(a))
#define MP(a) (int)((current_pixel_multiply)?((a)/current_pixel_multiply):(a))

static int 				render_pipeline[2];
static XilSystemState 			state;
static XilImage				display_image  = NULL;
static XilImage				quake_image  = NULL;
static int				use_mt = 0;
static int				count_frames = 0;

/*
================
D_BeginDirectRect
================
*/
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
{
// direct drawing of the "accessing disk" icon isn't supported under Nextstep
}


/*
================
D_EndDirectRect
================
*/
void D_EndDirectRect (int x, int y, int width, int height)
{
// direct drawing of the "accessing disk" icon isnt supported under Nextstep
}


/*
=================
VID_Gamma_f

Keybinding command
=================
*/

byte vid_gamma[256];

void VID_Gamma_f (void)
{

	float	g, f, inf;
	int		i;

	if (Cmd_Argc () == 2) {
		g = Q_atof (Cmd_Argv(1));

		for (i=0 ; i<255 ; i++)	{
			f = pow ((i+1)/256.0, g);
			inf = f*255 + 0.5;
			if (inf < 0)
				inf = 0;
			if (inf > 255)
				inf = 255;
			vid_gamma[i] = inf;
		}

		VID_SetPalette (current_palette);

		vid.recalc_refdef = 1;				// force a surface cache flush
	}

}

qboolean CheckPixelMultiply (void)
{
	int m;
	int w, h;
	XWindowAttributes wattr;
	XWindowChanges chg;
	unsigned int value_mask;
	int old_pixel;

	if ((m = (int)pixel_multiply->value) != current_pixel_multiply) {
		if (m < 1)
			m = 1;
		if (m > 4)
			m = 4;

		old_pixel = current_pixel_multiply;
		current_pixel_multiply = m;
		Cvar_SetValue(pixel_multiply, m);

		if(XGetWindowAttributes(x_disp, x_win, & wattr) == 0)
			return true; // ???

		memset(&chg, 0, sizeof(chg));
		chg.width = wattr.width/old_pixel * current_pixel_multiply;
		chg.height = wattr.height/old_pixel * current_pixel_multiply;

		if (chg.width < MIN_WIDTH*current_pixel_multiply)
			chg.width = MIN_WIDTH*current_pixel_multiply;
		if (chg.height < MIN_HEIGHT*current_pixel_multiply)
			chg.height = MIN_HEIGHT*current_pixel_multiply;

		XConfigureWindow(x_disp, x_win, CWWidth | CWHeight, &chg);

		vid.width = MP(wattr.width) & ~3;
		vid.height = MP(wattr.height);

		if (vid.width < 320)
			vid.width = 320;
		if (vid.height < 200)
			vid.height = 200;
		VID_ResetFramebuffer();

		return true;
	}
	return false;
}

// ========================================================================
// Tragic death handler
// ========================================================================

void TragicDeath(int signal_num)
{
	//XAutoRepeatOn(x_disp);
	XCloseDisplay(x_disp);
	Sys_Error("This death brought to you by the number %d\n", signal_num);
}

// ========================================================================
// makes a null cursor
// ========================================================================

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;
}


void VID_MenuDraw( void )
{
	qpic_t		*p;
	char		*ptr;
	int			i, j, column, row, dup;
	char		temp[100];

	p = Draw_CachePic ("gfx/vidmodes.lmp");
	M_DrawPic ( (320-p->width)/2, 4, p);
	M_Print (4*8, 36 + MAX_COLUMN_SIZE * 8 + 8, "Video mode switching unavailable");
	M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, "Press any key...");
}

void VID_MenuKey( int key ) { M_Menu_Options_f (); }

// Called at startup to set up translation tables, takes 256 8 bit RGB values
// the palette data will go away after the call, so it must be copied off if
// the video driver will need it again

byte	surfcache[1024*1024];

//
// VID_SetWindowTitle - set the window and icon titles
//

void VID_SetWindowTitle( Window win, char *pszName )
{
	XTextProperty	textprop;
	XWMHints		*wmHints;

	// Setup ICCCM properties
	textprop.value = (unsigned char *)pszName;
	textprop.encoding = XA_STRING;
	textprop.format = 8;
	textprop.nitems = strlen(pszName);
	wmHints = XAllocWMHints();
	wmHints->initial_state = NormalState;
	wmHints->flags = StateHint;
	XSetWMProperties( x_disp, win, &textprop, &textprop,
					  // Only put WM_COMMAND property on first window.
					  com_argv, com_argc, NULL, NULL, NULL );
	XFree( wmHints );

	aWMDelete = XInternAtom( x_disp, "WM_DELETE_WINDOW", False );
	XSetWMProtocols( x_disp, win, &aWMDelete, 1 );
}

//
// VID_FullScreen - open the window in full screen mode
//

qboolean VID_FullScreen( Window win )
{
	MotifWmHints    hints;
	XWindowChanges  changes;

	aHints = XInternAtom( x_disp, "_MOTIF_WM_HINTS", 0 );
	if (aHints == None) {
		Con_Printf( "Could not intern X atom for _MOTIF_WM_HINTS." );
		return( false );
	}

	hints.flags = MWM_HINTS_DECORATIONS;
	hints.decorations = 0; // Absolutely no decorations.
	XChangeProperty( x_disp, win, aHints, aHints, 32, PropModeReplace, (unsigned char *)&hints, 4 );

	changes.x = 0;
	changes.y = 0;
	changes.width = x_screen_width;
	changes.height = x_screen_height;
	changes.stack_mode = TopIf;
	XConfigureWindow( x_disp, win, CWX | CWY | CWWidth | CWHeight | CWStackMode, &changes);
	return( true );
}

// 2001-09-18 New cvar system by Maddes (Init)  start
/*
===================
VID_Init_Cvars
===================
*/
void VID_Init_Cvars (void)
{
	pixel_multiply = Cvar_Get ("pixel_multiply", "2", CVAR_ARCHIVE|CVAR_ORIGINAL);
}
// 2001-09-18 New cvar system by Maddes (Init)  end

void	VID_Init (unsigned char *palette)
{

	int pnum, i;
	XVisualInfo template;
	int num_visuals;
	int template_mask;
	int w, h;

	int desired_width=320, desired_height=200;

	Cmd_AddCommand ("gamma", VID_Gamma_f);

//	pixel_multiply = Cvar_Get ("pixel_multiply", "2", CVAR_ARCHIVE|CVAR_ORIGINAL);	// 2001-09-18 New cvar system by Maddes (Init)

	if (pipe(render_pipeline) < 0)
		Sys_Error("VID_Init: pipe");

	for (i=0 ; i<256 ; i++)
		vid_gamma[i] = i;

	vid.width = 320;
	vid.height = 200;
	vid.aspect = 1.0;
	vid.numpages = 2;
	vid.colormap = host_colormap;
	vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
	//vid.cbits = VID_CBITS;
	//vid.grades = VID_GRADES;

	srandom(getpid());

	verbose = COM_CheckParm("-verbose");
	count_frames = COM_CheckParm("-count_frames");

//
// open the display
//
	x_disp = XOpenDisplay(0);

	if (!x_disp) {
		if (getenv("DISPLAY"))
			Sys_Error("VID: Could not open display [%s]\n",
				getenv("DISPLAY"));
		else
			Sys_Error("VID: Could not open local display\n");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?