⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vid_next.m

📁 Quake 2 Source code for students by Theerthan You can also download from idsoftwares.com
💻 M
📖 第 1 页 / 共 3 页
字号:
// vid_next.m -- NEXTSTEP video driver

#define	INTERCEPTOR

#import <appkit/appkit.h>
#import <string.h>
#import "intercep.h"
#include "quakedef.h"
#include "d_local.h"

int	BASEWIDTH = 320;
int BASEHEIGHT = 200;

void SetupBitmap (void);
void SetupFramebuffer (void);
void UpdateBitmap (void);
void UpdateFramebuffer (vrect_t *vrect);
void SetVideoEncoding (char *encoding);
void Update8_1 (pixel_t *src, byte *dest, int width,
		int height, int destrowbytes);
void Update16_1 (pixel_t *src, unsigned short *dest, int width,
		int height, int destrowbytes);
void Update32_1 (pixel_t *src, unsigned *dest, int width,
		int height, int destrowbytes);


@interface QuakeView : View
@end

@interface FrameWindow:Window
@end

unsigned short	d_8to16table[256];	// not used in 8 bpp mode
unsigned	d_8to24table[256];	// not used in 8 bpp mode


/*
==========================================================================

						API FUNCTIONS

==========================================================================
*/

typedef enum {disp_bitmap, disp_framebuffer}	display_t;

pixel_t		*vid_buffer;
pixel_t		*buffernative;
unsigned	pcolormap[4][256];	// map from quake pixels to native pixels
unsigned	pixbytesnative;
unsigned	rowbytesnative;
int			dither;

int			drawdirect = 0;

int			d_con_indirect = 0;

display_t		vid_display;

byte			vid_palette[768];	// saved for restarting vid system

id				vid_window_i;
id				vid_view_i;
#ifdef INTERCEPTOR
NXDirectBitmap	*vid_dbitmap_i;
NXFramebuffer	*vid_framebuffer_i;
#endif

NXRect   		screenBounds;		// only valid in framebuffer mode

int				vid_scale;

char			*vid_encodingstring;

int				vid_fullscreen;
int				vid_screen;

int				vid_high_hunk_mark;

typedef enum
{
	enc_24_rgba,
	enc_24_0rgb,
	enc_24_rgb0,
	enc_12_rgba,
	enc_12_rgb0,
	enc_15_0rgb,
	enc_564,
	enc_8_gray,
	enc_8_rgb
} vid_encoding_t;

typedef struct
{
	char			*string;
	int				pixelbytes;
	void			(*colormap) (void);
	vid_encoding_t	name;
} vidtype_t;

vid_encoding_t	vid_encoding;
 
void	Table8 (void);
void	Table15 (void);
void	Table12 (void);
void	Table12Swap (void);
void	Table24 (void);
void	Table24Swap (void);

vidtype_t vid_encodingtable[]=
{
{"RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA",4, Table24Swap, enc_24_rgba},
{"--------RRRRRRRRGGGGGGGGBBBBBBBB",4, Table24, enc_24_0rgb},
{"RRRRRRRRGGGGGGGGBBBBBBBB--------",4, Table24Swap, enc_24_rgb0},
{"RRRRGGGGBBBBAAAA",2, Table12Swap, enc_12_rgba},
{"RRRRGGGGBBBB----",2, Table12, enc_12_rgb0},
{"-RRRRRGGGGGBBBBB",2, Table15, enc_15_0rgb},
{"WWWWWWWW",1, Table8, enc_8_gray},
{"PPPPPPPP",1, Table8, enc_8_rgb},
{NULL,0, 0, 0}
};

vidtype_t	*vid_type;
void	InitNS8Bit (void);

/*
================
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 isn't supported under Nextstep
}


/*
==============
VID_Restart

internal call only
===============
*/
void VID_Restart (display_t mode, int scale)
{
	vid_display = mode;
	vid_scale = scale;

	[NXApp activateSelf:YES];

	if (vid_display == disp_framebuffer)
		SetupFramebuffer ();
	else
		SetupBitmap ();

	vid.recalc_refdef = 1;
}


/*
=================
VID_Scale_f

Keybinding command
=================
*/
void VID_Scale_f (void)
{
	int		scale;
	
	if (Cmd_Argc () != 2)
		return;
		
	scale = atoi (Cmd_Argv(1));
	if (scale != 1 && scale != 2)
	{
		Con_Printf ("scale must be 1 or 2\n");
		return;
	}
	VID_Shutdown ();
	VID_Restart (vid_display, scale);
}

/*
=================
VID_Mode_f

Keybinding command
=================
*/
void VID_Mode_f (void)
{
	int		mode;

	if (Cmd_Argc () != 2)
		return;

	mode = atoi (Cmd_Argv(1));

	VID_Shutdown ();
	if (mode == 0)
	{
		drawdirect = 0;
		VID_Restart (disp_bitmap, vid_scale);
	}
	else if (mode == 1)
	{
		drawdirect = 0;
		VID_Restart (disp_framebuffer, vid_scale);
	}
	else
	{
		drawdirect = 1;
		VID_Restart (disp_framebuffer, vid_scale);
	}
}

/*
=================
VID_Size_f

Keybinding command
=================
*/
void VID_Size_f (void)
{	
	if (Cmd_Argc () != 3)
		return;

	VID_Shutdown ();

	BASEWIDTH = atoi (Cmd_Argv(1));
	BASEHEIGHT = atoi (Cmd_Argv(2));

	VID_Restart (vid_display, vid_scale);
}

/*
================
VID_Init
================
*/
void	VID_Init (unsigned char *palette)
{
	InitNS8Bit ();			// fixed palette lookups
	
	Q_memcpy (vid_palette, palette, sizeof(vid_palette));

	if (COM_CheckParm ("-bitmap"))
		vid_display = disp_bitmap;
	else
		vid_display = disp_framebuffer;

	if (COM_CheckParm ("-screen2"))
		vid_screen = 1;
	else
		vid_screen = 0;

	if (COM_CheckParm ("-direct"))
		drawdirect = 1;
	
	Cmd_AddCommand ("vid_scale", VID_Scale_f);
	Cmd_AddCommand ("vid_mode", VID_Mode_f);
	Cmd_AddCommand ("vid_size", VID_Size_f);

	vid.width = BASEWIDTH;
	vid.height = BASEHEIGHT;
	vid.aspect = 1.0;
	vid.numpages = 1;
	vid.colormap = host_colormap;
	vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
	vid.maxwarpwidth = WARP_WIDTH;
	vid.maxwarpheight = WARP_HEIGHT;

	if (COM_CheckParm ("-scale2"))
		vid_scale = 2;
	else
		vid_scale = 1;
		
    [Application new];

	VID_Restart (vid_display, vid_scale);
}


/*
================
VID_Shutdown
================
*/
void VID_Shutdown (void)
{
#ifdef INTERCEPTOR
	if (vid_dbitmap_i)
	{
		[vid_dbitmap_i free];
		vid_dbitmap_i = 0;
	}
	if (vid_framebuffer_i)
	{
		[vid_framebuffer_i free];
		vid_framebuffer_i = 0;
	}
#endif
	[vid_window_i close];
	[vid_window_i free];
}


/*
================
VID_Update
================
*/
void	VID_Update (vrect_t *rects)
{
	if (drawdirect)
		return;

	while (rects)
	{
		UpdateFramebuffer (rects);
		rects = rects->pnext;
	}

	if (vid_display == disp_bitmap)
		UpdateBitmap ();
}


/*
================
VID_SetPalette
================
*/
void	VID_SetPalette (unsigned char *palette)
{
	Q_memcpy (vid_palette, palette, sizeof(vid_palette));
	vid_type->colormap ();
}


/*
================
VID_ShiftPalette
================
*/
void    VID_ShiftPalette (unsigned char *palette)
{

	VID_SetPalette (palette);
}


/*
==========================================================================

						NS STUFF

==========================================================================
*/


/*
=================
SetVideoEncoding
=================
*/
void SetVideoEncoding (char *encoding)
{
	vidtype_t			*type;

	Sys_Printf ("SetVideoEncoding: %s\n",encoding);
	vid_encodingstring = encoding;
	
	for (type = vid_encodingtable ; type->string ; type++)
	{
		if (strcmp(type->string, encoding) == 0)
		{
			pixbytesnative = type->pixelbytes;
			vid_encoding = type->name;
			type->colormap ();
			vid_type = type;
			return;
		}
	}
	
	Sys_Error ("Unsupported video encoding: %s\n",encoding);
}

/*
=================
AllocBuffers
=================
*/
void AllocBuffers (qboolean withnative)
{
	int		surfcachesize;
	void	*surfcache;
	int		pixels;
	int		pixbytes;
	int		vid_buffersize;

	if (vid_buffer)
	{
		D_FlushCaches ();
		Hunk_FreeToHighMark (vid_high_hunk_mark);
		vid_high_hunk_mark = 0;
		vid_buffer = NULL;
	}

	pixels = vid.width * vid.height;

	pixbytes = 1 +sizeof (*d_pzbuffer);
	if (withnative)
		pixbytes += pixbytesnative;
		
	surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
	vid_buffersize = pixels * pixbytes + surfcachesize;

	vid_high_hunk_mark = Hunk_HighMark ();
	vid_buffer = Hunk_HighAllocName (vid_buffersize, "video");
	if (!vid_buffer)
		Sys_Error ("Couldn't alloc video buffers");

	vid.buffer = vid_buffer;

	d_pzbuffer = (unsigned short *)((byte *)vid_buffer + pixels);
	surfcache = (byte *)d_pzbuffer + pixels * sizeof (*d_pzbuffer);
	if (withnative)
		buffernative = (byte *)surfcache + surfcachesize;

	D_InitCaches (surfcache, surfcachesize);
}

/*
=================
SetupFramebuffer
=================
*/
void SetupFramebuffer (void)
{
#ifdef INTERCEPTOR
    int			windowNum;
	NXRect		cont;
	NXScreen	const *screens;
	int			screencount;

//
// get the screen list
//
	[NXApp getScreens:&screens count:&screencount];

//
// create vid_framebuffer_i
//
    vid_framebuffer_i = [[NXFramebuffer alloc]
		   initFromScreen:screens[vid_screen].screenNumber andMapIfPossible:YES];
    [vid_framebuffer_i screenBounds:&screenBounds];

	SetVideoEncoding ([vid_framebuffer_i pixelEncoding]);

	buffernative = [vid_framebuffer_i data];
	rowbytesnative = [vid_framebuffer_i bytesPerRow];

//
// create window
//
	if (vid_fullscreen)
	{
		vid.height = screenBounds.size.height / vid_scale;
		vid.width = screenBounds.size.width / vid_scale;
		cont.origin.x = 0;
		cont.origin.y = 0;
		cont.size.width = screenBounds.size.width;
		cont.size.height = screenBounds.size.height;
	}
	else
	{
		buffernative = (unsigned char *)buffernative + 8 * rowbytesnative +
				8 * pixbytesnative;
		vid.width = BASEWIDTH;
		vid.height = BASEHEIGHT;
		cont.origin.x = 8;
		cont.origin.y = screenBounds.size.height - (vid.height*vid_scale) - 8;
		cont.size.width = vid.width * vid_scale;
		cont.size.height = vid.height * vid_scale;
	}

    vid_window_i = [[FrameWindow alloc]
		 initContent:		&cont
		 style:				NX_PLAINSTYLE
		 backing:			NX_NONRETAINED
		 buttonMask:		0
		 defer:				NO
		 screen:			screens+vid_screen];
    windowNum = [vid_window_i windowNum];
    PSsetwindowlevel(40, windowNum);
    PSsetautofill(YES, windowNum);
    PSgsave();
    PSwindowdeviceround(windowNum);
    PSsetgray(NX_BLACK);
    PSsetexposurecolor();
    PSgrestore();

//
// create view
//
	vid_view_i = [[QuakeView alloc] initFrame: &screenBounds];
	[[vid_window_i setContentView: vid_view_i] free];
	[vid_window_i makeFirstResponder: vid_view_i];
	[vid_window_i setDelegate: vid_view_i];	
	[vid_window_i display];
	[vid_window_i makeKeyAndOrderFront: nil];
	NXPing ();

	AllocBuffers (false);	// no native buffer

	if (drawdirect)
	{	// the direct drawing mode to NeXT colorspace
		vid.buffer = buffernative;
		vid.rowbytes = rowbytesnative;
	}
	else
		vid.rowbytes = vid.width;

	vid.conbuffer = vid.buffer;
	vid.conrowbytes = vid.rowbytes;
	vid.conwidth = vid.width;
	vid.conheight = vid.height;
#endif
}

/*
=================
SetupBitmap
=================
*/
void SetupBitmap (void)
{
	int		depth;
	NXRect	content;

//
// open a window
//
	NXSetRect (&content, 8,136, vid.width*vid_scale, vid.height*vid_scale);
	vid_window_i = [[Window alloc]
			initContent:	&content
			style:			NX_RESIZEBARSTYLE
			backing:		NX_RETAINED
			buttonMask:		0
			defer:			NO
		];
	[vid_window_i display];
	[vid_window_i makeKeyAndOrderFront: nil];

	NXPing ();

	content.origin.x = content.origin.y = 0;
	vid_view_i = [[QuakeView alloc] initFrame: &content];
	[[vid_window_i setContentView: vid_view_i] free];
	[vid_window_i makeFirstResponder: vid_view_i];
	[vid_window_i setDelegate: vid_view_i];

	[vid_window_i addToEventMask: NX_FLAGSCHANGEDMASK];

//
// find video info
//
    depth = [Window defaultDepthLimit];
    switch (depth) {
	case NX_EightBitGrayDepth:
		SetVideoEncoding ("WWWWWWWW");
	    break;
	case NX_TwelveBitRGBDepth:
		SetVideoEncoding ("RRRRGGGGBBBBAAAA");
	    break;
	default:
	case NX_TwentyFourBitRGBDepth:
		SetVideoEncoding ("RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA");
	    break;
//	default:	// 8 bit color shows up as an unknown...
		Sys_Error ("Unsupported window depth");
    }

⌨️ 快捷键说明

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