📄 macosx_input.m
字号:
if ([systemDefinedEvent subtype] == 7) {
if (!mouseactive)
return;
buttons = [systemDefinedEvent data2];
buttonsDelta = oldButtons ^ buttons;
//Com_Printf("uberbuttons: %08lx %08lx\n",buttonsDelta,buttons);
if (buttonsDelta & 1) {
isDown = buttons & 1;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE2: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 2) {
isDown = buttons & 2;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE3: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 4) {
isDown = buttons & 4;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE3, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE1: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 8) {
isDown = buttons & 8;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE4, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE4: %s\n", isDown ? "down" : "up");
}
}
if (buttonsDelta & 16) {
isDown = buttons & 16;
Sys_QueEvent(currentTime, SE_KEY, K_MOUSE5, isDown, 0, NULL);
if (in_showevents->integer) {
Com_Printf("MOUSE5: %s\n", isDown ? "down" : "up");
}
}
oldButtons = buttons;
}
}
static inline void processEvent(NSEvent *event, int currentTime)
{
NSEventType eventType;
if (!inputActive)
return;
eventType = [event type];
if (in_showevents->integer)
NSLog(@"event = %@", event);
switch (eventType) {
// These six event types are ignored since we do all of our mouse down/up process via the uber-mouse system defined event. We have to accept these events however since they get enqueued and the queue will fill up if we don't.
case NSLeftMouseDown:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, qtrue, 0, NULL);
return;
case NSLeftMouseUp:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE1, qfalse, 0, NULL);
return;
case NSRightMouseDown:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, qtrue, 0, NULL);
return;
case NSRightMouseUp:
//Sys_QueEvent(currentTime, SE_KEY, K_MOUSE2, qfalse, 0, NULL);
return;
case 25: // other mouse down
return;
case 26: // other mouse up
return;
case NSMouseMoved:
case NSLeftMouseDragged:
case NSRightMouseDragged:
case 27: // other mouse dragged
Sys_ProcessMouseMovedEvent(event, currentTime);
return;
case NSKeyDown:
case NSKeyUp:
processKeyEvent(event, eventType == NSKeyDown, currentTime);
return;
case NSFlagsChanged:
processFlagsChangedEvent(event, currentTime);
return;
case NSSystemDefined:
processSystemDefinedEvent(event, currentTime);
return;
case NSScrollWheel:
if ([event deltaY] < 0.0) {
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
} else {
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
Sys_QueEvent(currentTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
}
return;
default:
break;
}
[NSApp sendEvent:event];
}
static void Sys_SendKeyEvents(int currentTime)
{
#ifndef DEDICATED
NSEvent *event;
NSDate *timeout;
extern float SNDDMA_GetBufferDuration();
timeout = distantPast;
if (Sys_IsHidden)
timeout = [NSDate dateWithTimeIntervalSinceNow: 0.25 * SNDDMA_GetBufferDuration()];
// This gets call regardless of whether inputActive is true or not. This is important since we need to be poking the event queue in order for the unhide event to make its way through the system. This means that when we hide, we can just shut down the input system and reeanbled it when we unhide.
while ((event = [NSApp nextEventMatchingMask: NSAnyEventMask
untilDate: timeout
inMode: NSDefaultRunLoopMode
dequeue:YES])) {
if (Sys_IsHidden) {
// Just let NSApp handle events so that we'll get the app activation event
[NSApp sendEvent: event];
timeout = [NSDate dateWithTimeIntervalSinceNow: 0.1];
} else {
static int lastEventTime = 0;
static BOOL lastEventTimeValid = NO;
// Mac OS X 10.0.3 has a bug where the if the monitor goes to sleep in fullscreen GL mode, the gamma won't be restored. We'll restore the gamma if there is a pause while in the game of more than 10 seconds. We don't do this on the 'Sys_IsHidden' branch since unhiding will restore the monitor gamma.
if ((currentTime - lastEventTime > 1 * 1000) && lastEventTimeValid) {
//Com_Printf("Restoring monitor gamma after being idle for %f seconds.\n", (currentTime - lastEventTime) / 1000.0);
[NSCursor hide];
Sys_SetScreenFade(&glw_state.inGameTable, 1.0);
}
lastEventTime = [event timestamp] * 1000.0; //currentTime;
lastEventTimeValid = YES;
processEvent(event, lastEventTime);
}
}
#endif
}
/*
========================================================================
EVENT LOOP
========================================================================
*/
extern qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
#define MAX_QUED_EVENTS 256
#define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
static sysEvent_t eventQue[MAX_QUED_EVENTS];
static int eventHead, eventTail;
static byte sys_packetReceived[MAX_MSGLEN];
/*
================
Sys_QueEvent
A time of 0 will get the current time
Ptr should either be null, or point to a block of data that can
be freed by the game later.
================
*/
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
sysEvent_t *ev;
int i,j;
#ifndef DEDICATED
if (in_showevents->integer)
NSLog(@"EVENT ENQUEUE: time=%d type=%d value=0x%08x value2=0x%08x\n", time, type, value, value2);
#endif
if ( eventHead - eventTail >= MAX_QUED_EVENTS ) {
Com_Printf("Sys_QueEvent: overflow\n");
}
if ( !time ) {
time = Sys_Milliseconds();
}
// insert it by time
for ( i = eventTail ; i < eventHead ; i++ ) {
ev = &eventQue[ i & MASK_QUED_EVENTS ];
if ( ev->evTime > time ) {
break;
}
}
// insert before i
for ( j = eventHead ; j > i ; j-- ) {
eventQue[ j & MASK_QUED_EVENTS ] = eventQue[ (j-1) & MASK_QUED_EVENTS ];
}
ev = &eventQue[ i & MASK_QUED_EVENTS ];
eventHead++;
ev->evTime = time;
ev->evType = type;
ev->evValue = value;
ev->evValue2 = value2;
ev->evPtrLength = ptrLength;
ev->evPtr = ptr;
}
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent( void )
{
sysEvent_t ev;
char *s;
msg_t netmsg;
netadr_t adr;
int currentTime;
// return if we have data
if (eventHead > eventTail) {
eventTail++;
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
}
// The queue must be empty. Check all of the event sources. If the events are
// already in the queue, we can't imply any real ordering, so we'll avoid extra
// system calls and give them all the same time.
currentTime = Sys_Milliseconds();
// Check for mouse and keyboard events
Sys_SendKeyEvents(currentTime);
// check for console commands
s = Sys_ConsoleInput();
if ( s ) {
char *b;
int len;
len = strlen( s ) + 1;
b = Z_Malloc( len );
strcpy( b, s );
Sys_QueEvent( currentTime, SE_CONSOLE, 0, 0, len, b );
}
// During debugging it is sometimes usefull to be able to start/stop mouse input.
// Don't turn on the input when we've disabled it because we're hidden, however.
if (!com_dedicated->integer) {
if (in_nomouse->integer == mouseactive && !Sys_IsHidden) {
if (in_nomouse->integer)
Sys_StopMouseInput();
else
Sys_StartMouseInput();
}
}
// check for network packets
MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
if ( Sys_GetPacket ( &adr, &netmsg ) ) {
netadr_t *buf;
int len;
// copy out to a seperate buffer for qeueing
len = sizeof( netadr_t ) + netmsg.cursize;
buf = Z_Malloc( len );
*buf = adr;
memcpy( buf+1, netmsg.data, netmsg.cursize );
Sys_QueEvent( currentTime, SE_PACKET, 0, 0, len, buf );
}
// If we got an event, return it
if (eventHead > eventTail) {
eventTail++;
return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
}
// Otherwise, return an empty event to indicate that there are no events pending.
memset( &ev, 0, sizeof( ev ) );
ev.evTime = currentTime;
return ev;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -