mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-30 08:00:51 +00:00
938 lines
17 KiB
Objective-C
938 lines
17 KiB
Objective-C
#import "qedefs.h"
|
|
|
|
id cameraview_i;
|
|
BOOL timedrawing = 0;
|
|
|
|
@implementation CameraView
|
|
|
|
/*
|
|
==================
|
|
initFrame:
|
|
==================
|
|
*/
|
|
- initWithFrame: (NSRect) frameRect
|
|
{
|
|
int size;
|
|
|
|
[super initWithFrame: frameRect];
|
|
|
|
cameraview_i = self;
|
|
|
|
angles[0] = angles[1] = angles[2] = 0.0;
|
|
|
|
[self matrixFromAngles];
|
|
|
|
origin[0] = 64;
|
|
origin[1] = 64;
|
|
origin[2] = 48;
|
|
|
|
move = 16;
|
|
|
|
bounds = [self bounds];
|
|
size = bounds.size.width * bounds.size.height;
|
|
zbuffer = malloc (size*4);
|
|
imagebuffer = malloc (size*4);
|
|
|
|
return self;
|
|
}
|
|
|
|
- setXYOrigin: (NSPoint) point
|
|
{
|
|
origin[0] = point.x;
|
|
origin[1] = point.y;
|
|
return self;
|
|
}
|
|
|
|
- setZOrigin: (float) point
|
|
{
|
|
origin[2] = point;
|
|
return self;
|
|
}
|
|
|
|
- setOrigin: (vec3_t) org angle: (float) angle
|
|
{
|
|
VectorCopy (org, origin);
|
|
angles[1] = angle;
|
|
[self matrixFromAngles];
|
|
return self;
|
|
}
|
|
|
|
- getOrigin: (vec3_t) org
|
|
{
|
|
VectorCopy (origin, org);
|
|
return self;
|
|
}
|
|
|
|
- (float)yawAngle
|
|
{
|
|
return angles[1];
|
|
}
|
|
|
|
- upFloor: sender
|
|
{
|
|
sb_floor_dir = 1;
|
|
sb_floor_dist = 99999;
|
|
[map_i makeObjectsPerformSelector: @selector(feetToFloor)];
|
|
if (sb_floor_dist == 99999)
|
|
{
|
|
qprintf ("already on top floor");
|
|
return self;
|
|
}
|
|
qprintf ("up floor");
|
|
origin[2] += sb_floor_dist;
|
|
[quakeed_i updateCamera];
|
|
return self;
|
|
}
|
|
|
|
- downFloor: sender
|
|
{
|
|
sb_floor_dir = -1;
|
|
sb_floor_dist = -99999;
|
|
[map_i makeAllPerform: @selector(feetToFloor)];
|
|
if (sb_floor_dist == -99999)
|
|
{
|
|
qprintf ("already on bottom floor");
|
|
return self;
|
|
}
|
|
qprintf ("down floor");
|
|
origin[2] += sb_floor_dist;
|
|
[quakeed_i updateCamera];
|
|
return self;
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
UI TARGETS
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
============
|
|
homeView
|
|
============
|
|
*/
|
|
- homeView: sender
|
|
{
|
|
angles[0] = angles[2] = 0;
|
|
|
|
[self matrixFromAngles];
|
|
|
|
[quakeed_i updateAll];
|
|
|
|
qprintf ("homed view angle");
|
|
|
|
return self;
|
|
}
|
|
|
|
- drawMode: (NSMatrix) sender
|
|
{
|
|
drawmode = [sender selectedColumn];
|
|
[quakeed_i updateCamera];
|
|
return self;
|
|
}
|
|
|
|
- setDrawMode: (drawmode_t)mode
|
|
{
|
|
drawmode = mode;
|
|
[mode_radio_i selectCellAtRow: 0 column: mode];
|
|
[quakeed_i updateCamera];
|
|
return self;
|
|
}
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
TRANSFORMATION METHODS
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
- matrixFromAngles
|
|
{
|
|
if (angles[0] > M_PI*0.4)
|
|
angles[0] = M_PI*0.4;
|
|
if (angles[0] < -M_PI*0.4)
|
|
angles[0] = -M_PI*0.4;
|
|
|
|
// vpn
|
|
matrix[2][0] = cos(angles[0])*cos(angles[1]);
|
|
matrix[2][1] = cos(angles[0])*sin(angles[1]);
|
|
matrix[2][2] = sin(angles[0]);
|
|
|
|
// vup
|
|
matrix[1][0] = cos(angles[0]+M_PI/2)*cos(angles[1]);
|
|
matrix[1][1] = cos(angles[0]+M_PI/2)*sin(angles[1]);
|
|
matrix[1][2] = sin(angles[0]+M_PI/2);
|
|
|
|
// vright
|
|
CrossProduct (matrix[2], matrix[1], matrix[0]);
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
- inverseTransform: (vec_t *)invec to:(vec_t *)outvec
|
|
{
|
|
vec3_t inverse[3];
|
|
vec3_t temp;
|
|
int i,j;
|
|
|
|
for (i=0 ; i<3 ; i++)
|
|
for (j=0 ; j<3 ; j++)
|
|
inverse[i][j] = matrix[j][i];
|
|
|
|
temp[0] = DotProduct(invec, inverse[0]);
|
|
temp[1] = DotProduct(invec, inverse[1]);
|
|
temp[2] = DotProduct(invec, inverse[2]);
|
|
|
|
VectorAdd (temp, origin, outvec);
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
DRAWING METHODS
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
vec3_t trans;
|
|
int clipflags;
|
|
vec3_t screen; // only valid if clipflags == 0
|
|
} campt_t;
|
|
#define CLIP_RIGHT 1
|
|
#define CLIP_LEFT 2
|
|
#define CLIP_TOP 4
|
|
#define CLIP_BOTTOM 8
|
|
#define CLIP_FRONT 16
|
|
|
|
int cam_cur;
|
|
campt_t campts[2];
|
|
|
|
vec3_t r_matrix[3];
|
|
vec3_t r_origin;
|
|
float mid_x, mid_y;
|
|
float topscale = (240.0/3)/160;
|
|
float bottomscale = (240.0*2/3)/160;
|
|
|
|
extern plane_t frustum[5];
|
|
|
|
void MakeCampt (vec3_t in, campt_t *pt)
|
|
{
|
|
vec3_t temp;
|
|
float scale;
|
|
|
|
// transform the points
|
|
VectorSubtract (in, r_origin, temp);
|
|
|
|
pt->trans[0] = DotProduct(temp, r_matrix[0]);
|
|
pt->trans[1] = DotProduct(temp, r_matrix[1]);
|
|
pt->trans[2] = DotProduct(temp, r_matrix[2]);
|
|
|
|
// check clip flags
|
|
if (pt->trans[2] < 1)
|
|
pt->clipflags = CLIP_FRONT;
|
|
else
|
|
pt->clipflags = 0;
|
|
|
|
if (pt->trans[0] > pt->trans[2])
|
|
pt->clipflags |= CLIP_RIGHT;
|
|
else if (-pt->trans[0] > pt->trans[2])
|
|
pt->clipflags |= CLIP_LEFT;
|
|
|
|
if (pt->trans[1] > pt->trans[2]*topscale )
|
|
pt->clipflags |= CLIP_TOP;
|
|
else if (-pt->trans[1] > pt->trans[2]*bottomscale )
|
|
pt->clipflags |= CLIP_BOTTOM;
|
|
|
|
if (pt->clipflags)
|
|
return;
|
|
|
|
// project
|
|
scale = mid_x/pt->trans[2];
|
|
pt->screen[0] = mid_x + pt->trans[0]*scale;
|
|
pt->screen[1] = mid_y + pt->trans[1]*scale;
|
|
}
|
|
|
|
|
|
void CameraMoveto(vec3_t p)
|
|
{
|
|
campt_t *pt;
|
|
|
|
if (upath->numberOfPoints > 2048)
|
|
lineflush ();
|
|
|
|
pt = &campts[cam_cur];
|
|
cam_cur ^= 1;
|
|
MakeCampt (p,pt);
|
|
if (!pt->clipflags)
|
|
{ // onscreen, so move there immediately
|
|
UPmoveto (upath, pt->screen[0], pt->screen[1]);
|
|
}
|
|
}
|
|
|
|
void ClipLine (vec3_t p1, vec3_t p2, int planenum)
|
|
{
|
|
float d, d2, frac;
|
|
vec3_t new;
|
|
plane_t *pl;
|
|
float scale;
|
|
|
|
if (planenum == 5)
|
|
{ // draw it!
|
|
scale = mid_x/p1[2];
|
|
new[0] = mid_x + p1[0]*scale;
|
|
new[1] = mid_y + p1[1]*scale;
|
|
UPmoveto (upath, new[0], new[1]);
|
|
|
|
scale = mid_x/p2[2];
|
|
new[0] = mid_x + p2[0]*scale;
|
|
new[1] = mid_y + p2[1]*scale;
|
|
UPlineto (upath, new[0], new[1]);
|
|
return;
|
|
}
|
|
|
|
pl = &frustum[planenum];
|
|
|
|
d = DotProduct (p1, pl->normal) - pl->dist;
|
|
d2 = DotProduct (p2, pl->normal) - pl->dist;
|
|
if (d <= ON_EPSILON && d2 <= ON_EPSILON)
|
|
{ // off screen
|
|
return;
|
|
}
|
|
|
|
if (d >= 0 && d2 >= 0)
|
|
{ // on front
|
|
ClipLine (p1, p2, planenum+1);
|
|
return;
|
|
}
|
|
|
|
frac = d/(d-d2);
|
|
new[0] = p1[0] + frac*(p2[0]-p1[0]);
|
|
new[1] = p1[1] + frac*(p2[1]-p1[1]);
|
|
new[2] = p1[2] + frac*(p2[2]-p1[2]);
|
|
|
|
if (d > 0)
|
|
ClipLine (p1, new, planenum+1);
|
|
else
|
|
ClipLine (new, p2, planenum+1);
|
|
}
|
|
|
|
int c_off, c_on, c_clip;
|
|
|
|
void CameraLineto(vec3_t p)
|
|
{
|
|
campt_t *p1, *p2;
|
|
int bits;
|
|
|
|
p2 = &campts[cam_cur];
|
|
cam_cur ^= 1;
|
|
p1 = &campts[cam_cur];
|
|
MakeCampt (p, p2);
|
|
|
|
if (p1->clipflags & p2->clipflags)
|
|
{
|
|
c_off++;
|
|
return; // entirely off screen
|
|
}
|
|
|
|
bits = p1->clipflags | p2->clipflags;
|
|
|
|
if (! bits )
|
|
{
|
|
c_on++;
|
|
UPmoveto (upath, p1->screen[0], p1->screen[1]);
|
|
UPlineto (upath, p2->screen[0], p2->screen[1]);
|
|
return; // entirely on screen
|
|
}
|
|
|
|
// needs to be clipped
|
|
c_clip++;
|
|
|
|
ClipLine (p1->trans, p2->trans, 0);
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
drawSolid
|
|
=============
|
|
*/
|
|
- drawSolid
|
|
{
|
|
const unsigned char *planes[5];
|
|
|
|
//
|
|
// draw it
|
|
//
|
|
VectorCopy (origin, r_origin);
|
|
VectorCopy (matrix[0], r_matrix[0]);
|
|
VectorCopy (matrix[1], r_matrix[1]);
|
|
VectorCopy (matrix[2], r_matrix[2]);
|
|
|
|
r_width = [self bounds].size.width;
|
|
r_height = [self bounds].size.height;
|
|
r_picbuffer = imagebuffer;
|
|
r_zbuffer = zbuffer;
|
|
|
|
r_drawflat = (drawmode == dr_flat);
|
|
|
|
REN_BeginCamera ();
|
|
REN_ClearBuffers ();
|
|
|
|
//
|
|
// render the setbrushes
|
|
//
|
|
[map_i makeAllPerform: @selector(CameraRenderSelf)];
|
|
|
|
//
|
|
// display the output
|
|
//
|
|
[[self window] setBackingType:NSBackingStoreRetained];
|
|
|
|
planes[0] = (unsigned char *)imagebuffer;
|
|
NSDrawBitmap(
|
|
bounds, r_width, r_height,
|
|
8, 3, 32, r_width*4,
|
|
NO, // not planar
|
|
NO, // no alpha
|
|
NSCalibratedRGBColorSpace,
|
|
planes
|
|
);
|
|
|
|
// NSPing ();
|
|
[[self window] setBackingType:NSBackingStoreBuffered];
|
|
|
|
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
/*
|
|
===================
|
|
drawWire
|
|
===================
|
|
*/
|
|
- drawWire: (NSRect) rect
|
|
{
|
|
// copy current info to globals for the C callbacks
|
|
mid_x = bounds.size.width / 2;
|
|
mid_y = 2 * bounds.size.height / 3;
|
|
|
|
VectorCopy (origin, r_origin);
|
|
VectorCopy (matrix[0], r_matrix[0]);
|
|
VectorCopy (matrix[1], r_matrix[1]);
|
|
VectorCopy (matrix[2], r_matrix[2]);
|
|
|
|
r_width = bounds.size.width;
|
|
r_height = bounds.size.height;
|
|
r_picbuffer = imagebuffer;
|
|
r_zbuffer = zbuffer;
|
|
|
|
REN_BeginCamera ();
|
|
|
|
// erase window
|
|
NSEraseRect (rect);
|
|
|
|
// draw all entities
|
|
linestart (0,0,0);
|
|
[map_i makeUnselectedPerform: @selector(CameraDrawSelf)];
|
|
lineflush ();
|
|
|
|
return self;
|
|
}
|
|
|
|
/*
|
|
===================
|
|
drawSelf
|
|
===================
|
|
*/
|
|
- drawSelf: (NSRect) rects :(int)rectCount
|
|
{
|
|
static float drawtime; // static to shut up compiler warning
|
|
|
|
if (timedrawing)
|
|
drawtime = I_FloatTime ();
|
|
|
|
if (drawmode == dr_texture || drawmode == dr_flat)
|
|
[self drawSolid];
|
|
else
|
|
[self drawWire: rects];
|
|
|
|
if (timedrawing) {
|
|
// NSPing ();
|
|
drawtime = I_FloatTime() - drawtime;
|
|
printf ("CameraView drawtime: %5.3f\n", drawtime);
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
XYDrawSelf
|
|
=============
|
|
*/
|
|
- XYDrawSelf
|
|
{
|
|
|
|
PSsetrgbcolor (0,0,1.0);
|
|
PSsetlinewidth (0.15);
|
|
PSmoveto (origin[0]-16,origin[1]);
|
|
PSrlineto (16,8);
|
|
PSrlineto (16,-8);
|
|
PSrlineto (-16,-8);
|
|
PSrlineto (-16,8);
|
|
PSrlineto (32,0);
|
|
|
|
PSmoveto (origin[0],origin[1]);
|
|
PSrlineto (64*cos(angles[1]+M_PI/4), 64*sin(angles[1]+M_PI/4));
|
|
PSmoveto (origin[0],origin[1]);
|
|
PSrlineto (64*cos(angles[1]-M_PI/4), 64*sin(angles[1]-M_PI/4));
|
|
|
|
PSstroke ();
|
|
|
|
return self;
|
|
}
|
|
|
|
/*
|
|
=============
|
|
ZDrawSelf
|
|
=============
|
|
*/
|
|
- ZDrawSelf
|
|
{
|
|
PSsetrgbcolor (0,0,1.0);
|
|
PSsetlinewidth (0.15);
|
|
|
|
PSmoveto (-16,origin[2]);
|
|
PSrlineto (16,8);
|
|
PSrlineto (16,-8);
|
|
PSrlineto (-16,-8);
|
|
PSrlineto (-16,8);
|
|
PSrlineto (32,0);
|
|
|
|
PSmoveto (-15,origin[2]-47);
|
|
PSrlineto (29,0);
|
|
PSrlineto (0,54);
|
|
PSrlineto (-29,0);
|
|
PSrlineto (0,-54);
|
|
|
|
PSstroke ();
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
/*
|
|
===============================================================================
|
|
|
|
XYZ mouse view methods
|
|
|
|
===============================================================================
|
|
*/
|
|
|
|
/*
|
|
================
|
|
modalMoveLoop
|
|
================
|
|
*/
|
|
- modalMoveLoop: (NSPoint) basept : (vec3_t) movemod : converter
|
|
{
|
|
vec3_t originbase;
|
|
NSEvent *event;
|
|
NSPoint newpt;
|
|
// NSPoint brushpt;
|
|
vec3_t delta;
|
|
// id ent;
|
|
int i;
|
|
// vec3_t temp;
|
|
unsigned int eventMask = NSLeftMouseUpMask | NSRightMouseUpMask |
|
|
NSLeftMouseDraggedMask | NSRightMouseDraggedMask |
|
|
NSApplicationDefinedMask | NSKeyDownMask;
|
|
|
|
qprintf ("moving camera position");
|
|
|
|
VectorCopy (origin, originbase);
|
|
|
|
//
|
|
// modal event loop using instance drawing
|
|
//
|
|
goto drawentry;
|
|
|
|
while ([event type] != NSLeftMouseUp && [event type] != NSRightMouseUp)
|
|
{
|
|
//
|
|
// calculate new point
|
|
//
|
|
newpt = [event locationInWindow];
|
|
[converter convertPoint: newpt fromView: nil];
|
|
|
|
delta[0] = newpt.x - basept.x;
|
|
delta[1] = newpt.y - basept.y;
|
|
delta[2] = delta[1]; // height change
|
|
|
|
for (i=0 ; i<3 ; i++)
|
|
origin[i] = originbase[i]+movemod[i]*delta[i];
|
|
|
|
#if 0 // FIXME
|
|
//
|
|
// if command is down, look towards brush or entity
|
|
//
|
|
if ([event modifierFlags] & NSShiftKeyMask)
|
|
{
|
|
ent = [quakemap_i selectedEntity];
|
|
if (ent)
|
|
{
|
|
[ent origin: temp];
|
|
brushpt.x = temp[0];
|
|
brushpt.y = temp[1];
|
|
}
|
|
else
|
|
brushpt = [brush_i centerPoint];
|
|
angles[1] = atan2 (brushpt.y - newpt.y, brushpt.x - newpt.x);
|
|
[self matrixFromAngles];
|
|
}
|
|
#endif
|
|
|
|
drawentry:
|
|
// instance draw new frame
|
|
[quakeed_i newinstance];
|
|
[self display];
|
|
|
|
event = [NSApp nextEventMatchingMask: eventMask
|
|
untilDate: [NSDate distantFuture]
|
|
inMode: NSEventTrackingRunLoopMode
|
|
dequeue: YES];
|
|
|
|
if ([event type] == NSKeyDown) {
|
|
[self _keyDown: event];
|
|
[self display];
|
|
goto drawentry;
|
|
}
|
|
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
/*
|
|
===============
|
|
XYmouseDown
|
|
===============
|
|
*/
|
|
- (BOOL) XYmouseDown: (NSPoint) pt flags: (unsigned int) flags // return YES if brush handled
|
|
{
|
|
vec3_t movemod;
|
|
|
|
if (fabs(pt.x - origin[0]) > 16
|
|
|| fabs(pt.y - origin[1]) > 16 )
|
|
return NO;
|
|
|
|
#if 0
|
|
if (flags & NS_ALTERNATEMASK)
|
|
{ // up / down drag
|
|
movemod[0] = 0;
|
|
movemod[1] = 0;
|
|
movemod[2] = 1;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
movemod[0] = 1;
|
|
movemod[1] = 1;
|
|
movemod[2] = 0;
|
|
}
|
|
|
|
[self modalMoveLoop: pt : movemod : xyview_i];
|
|
|
|
return YES;
|
|
}
|
|
|
|
|
|
/*
|
|
===============
|
|
ZmouseDown
|
|
===============
|
|
*/
|
|
- (BOOL) ZmouseDown: (NSPoint) pt flags: (unsigned int) flags // return YES if brush handled
|
|
{
|
|
vec3_t movemod;
|
|
|
|
if (fabs(pt.y - origin[2]) > 16
|
|
|| pt.x < -8 || pt.x > 8 )
|
|
return NO;
|
|
|
|
movemod[0] = 0;
|
|
movemod[1] = 0;
|
|
movemod[2] = 1;
|
|
|
|
[self modalMoveLoop: pt : movemod : zview_i];
|
|
|
|
return YES;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/*
|
|
===================
|
|
viewDrag:
|
|
===================
|
|
*/
|
|
- viewDrag: (NSPoint) pt
|
|
{
|
|
float dx,dy;
|
|
NSEvent *event;
|
|
NSPoint newpt;
|
|
unsigned int eventMask = NSKeyDownMask | NSRightMouseUpMask |
|
|
NSRightMouseDraggedMask;
|
|
|
|
// modal event loop using instance drawing
|
|
goto drawentry;
|
|
|
|
while ([event type] != NSRightMouseUp) {
|
|
|
|
// calculate new point
|
|
newpt = [event locationInWindow];
|
|
[self convertPoint: newpt fromView: nil];
|
|
|
|
dx = newpt.x - pt.x;
|
|
dy = newpt.y - pt.y;
|
|
pt = newpt;
|
|
|
|
angles[1] -= dx/bounds.size.width*M_PI/2 * 4;
|
|
angles[0] += dy/bounds.size.width*M_PI/2 * 4;
|
|
|
|
[self matrixFromAngles];
|
|
|
|
drawentry:
|
|
[quakeed_i newinstance];
|
|
[self display];
|
|
|
|
event = [NSApp nextEventMatchingMask: eventMask
|
|
untilDate: [NSDate distantFuture]
|
|
inMode: NSEventTrackingRunLoopMode
|
|
dequeue: YES];
|
|
|
|
if ([event type] == NSKeyDown) {
|
|
[self _keyDown: event];
|
|
[self display];
|
|
goto drawentry;
|
|
}
|
|
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
|
|
/*
|
|
===================
|
|
mouseDown
|
|
===================
|
|
*/
|
|
- (void) mouseDown: (NSEvent *) theEvent
|
|
{
|
|
NSPoint pt;
|
|
int i;
|
|
vec3_t p1, p2;
|
|
float forward, right, up;
|
|
int flags;
|
|
|
|
pt = [theEvent locationInWindow];
|
|
|
|
[self convertPoint: pt fromView: nil];
|
|
|
|
VectorCopy (origin, p1);
|
|
forward = 160;
|
|
right = pt.x - 160;
|
|
up = pt.y - 240*2/3;
|
|
for (i=0 ; i<3 ; i++)
|
|
p2[i] = forward*matrix[2][i] + up*matrix[1][i] + right*matrix[0][i];
|
|
for (i=0 ; i<3 ; i++)
|
|
p2[i] = p1[i] + 100*p2[i];
|
|
|
|
flags = [theEvent modifierFlags] & (NSShiftKeyMask | NSControlKeyMask |
|
|
NSAlternateKeyMask | NSCommandKeyMask);
|
|
|
|
// bare click to select a texture
|
|
if (!flags) {
|
|
[map_i getTextureRay: p1 : p2];
|
|
return;
|
|
}
|
|
|
|
// shift click to select / deselect a brush from the world
|
|
if (flags == NSShiftKeyMask) {
|
|
[map_i selectRay: p1 : p2 : NO];
|
|
return;
|
|
}
|
|
|
|
|
|
// cmd-shift click to set a target/targetname entity connection
|
|
if (flags == (NSShiftKeyMask | NSCommandKeyMask)) {
|
|
[map_i entityConnect: p1 : p2];
|
|
return;
|
|
}
|
|
|
|
// alt click = set entire brush texture
|
|
if (flags == NSAlternateKeyMask) {
|
|
if (drawmode != dr_texture) {
|
|
qprintf ("No texture setting except in texture mode!\n");
|
|
NopSound ();
|
|
return;
|
|
}
|
|
[map_i setTextureRay: p1 : p2 : YES];
|
|
[quakeed_i updateAll];
|
|
return;
|
|
}
|
|
|
|
// ctrl-alt click = set single face texture
|
|
if (flags == (NSControlKeyMask | NSAlternateKeyMask) ) {
|
|
if (drawmode != dr_texture) {
|
|
qprintf ("No texture setting except in texture mode!\n");
|
|
NopSound ();
|
|
return;
|
|
}
|
|
[map_i setTextureRay: p1 : p2 : NO];
|
|
[quakeed_i updateAll];
|
|
return;
|
|
}
|
|
|
|
qprintf ("bad modifier flags for click");
|
|
NopSound ();
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
===================
|
|
rightMouseDown
|
|
===================
|
|
*/
|
|
- (void) rightMouseDown: (NSEvent *) theEvent
|
|
{
|
|
NSPoint pt;
|
|
int flags;
|
|
|
|
pt = [theEvent locationInWindow];
|
|
|
|
[self convertPoint: pt fromView: nil];
|
|
|
|
flags = [theEvent modifierFlags] & (NSShiftKeyMask | NSControlKeyMask |
|
|
NSAlternateKeyMask | NSCommandKeyMask);
|
|
|
|
// click = drag camera
|
|
if (!flags) {
|
|
qprintf ("looking");
|
|
[self viewDrag: pt];
|
|
return;
|
|
}
|
|
|
|
qprintf ("bad modifier flags for click");
|
|
NopSound ();
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
===============
|
|
keyDown
|
|
===============
|
|
*/
|
|
- (void) _keyDown: (NSEvent *) theEvent
|
|
{
|
|
NSString *chars = [theEvent characters];
|
|
unichar ch;
|
|
|
|
if ([chars length] != 1) {
|
|
qprintf ("Incorrect number of characters in keyDown event.");
|
|
return;
|
|
}
|
|
|
|
ch = [chars characterAtIndex: 1];
|
|
|
|
switch (ch) {
|
|
case 13:
|
|
return;
|
|
|
|
case 'a':
|
|
case 'A':
|
|
angles[0] += M_PI/8;
|
|
[self matrixFromAngles];
|
|
[quakeed_i updateCamera];
|
|
return;
|
|
|
|
case 'z':
|
|
case 'Z':
|
|
angles[0] -= M_PI/8;
|
|
[self matrixFromAngles];
|
|
[quakeed_i updateCamera];
|
|
return;
|
|
|
|
case NSRightArrowFunctionKey:
|
|
angles[1] -= M_PI*move/(64*2);
|
|
[self matrixFromAngles];
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case NSLeftArrowFunctionKey:
|
|
angles[1] += M_PI*move/(64*2);
|
|
[self matrixFromAngles];
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case NSUpArrowFunctionKey:
|
|
origin[0] += move*cos(angles[1]);
|
|
origin[1] += move*sin(angles[1]);
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case NSDownArrowFunctionKey:
|
|
origin[0] -= move*cos(angles[1]);
|
|
origin[1] -= move*sin(angles[1]);
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case '.':
|
|
origin[0] += move*cos(angles[1]-M_PI_2);
|
|
origin[1] += move*sin(angles[1]-M_PI_2);
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case ',':
|
|
origin[0] -= move*cos(angles[1]-M_PI_2);
|
|
origin[1] -= move*sin(angles[1]-M_PI_2);
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case 'd':
|
|
case 'D':
|
|
origin[2] += move;
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
|
|
case 'c':
|
|
case 'C':
|
|
origin[2] -= move;
|
|
[quakeed_i updateCamera];
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
@end
|