Example #1
0
///////////////////////////////
// Create a new view window
//
void CG_mvCreate(int pID)
{
    cg_window_t *w;

    if(CG_mvClientLocate(pID) != NULL) return;

    w = CG_windowAlloc(WFX_MULTIVIEW, 100);
    if(w == NULL) return;

    // Window specific
    w->id = WID_NONE;
    w->x = (cg.mv_cnt == 0) ? 0 : 30 + (12 * pID);
    w->y = (cg.mv_cnt == 0) ? 0 : 300 + (5 * pID);
    w->w = (cg.mv_cnt == 0) ? 640 : 128;
    w->h = (cg.mv_cnt == 0) ? 480 : 96;
    w->mvInfo = (pID & MV_PID) | MV_SELECTED;
    w->state = (cg.mv_cnt == 0) ? WSTATE_COMPLETE : WSTATE_START;

    if(cg.mv_cnt == 0) {
        cg.mvCurrentMainview = w;
        cg.mvCurrentActive = cg.mvCurrentMainview;

        if(cg_specHelp.integer > 0 && !cg.demoPlayback) {
            CG_ShowHelp_On(&cg.spechelpWindow);
        }
    }

    cg.mv_cnt++;
}
Example #2
0
///////////////////////////
// Delete a view window
//
void CG_mvFree( int pID ) {
	cg_window_t *w = CG_mvClientLocate( pID );

	if ( w != NULL ) {
		// Free it in mvDraw()
		w->targetTime = 100;
		w->time = trap_Milliseconds();
		w->state = WSTATE_SHUTDOWN;
	}
}
Example #3
0
// Mouse overlay for controlling multiview windows
void CG_cursorUpdate(void)
{
	int i, j, x;
	float nx, ny;
	int nSelectedWindow = -1;
	cg_window_t *w;
	cg_windowHandler_t *wh = &cg.winHandler;
	qboolean fFound = qfalse, fUpdateOverlay = qfalse;
	qboolean fSelect, fResize;


	// Get cursor current position (when connected to a server)
	if(!cg.demoPlayback) {

		// Allow for limbo'd updates as well
		trap_GetUserCmd(trap_GetCurrentCmdNumber(), &cg_pmove.cmd);

		nx = 640.0 * (65536.0 - cg_pmove.cmd.angles[1]) / 65536.0;
		ny = 480.0 / 65536.0 * ((int_m_pitch.value < 0.0) ? (65536.0 - cg_pmove.cmd.angles[0]) : cg_pmove.cmd.angles[0]);

		fSelect = ((cg_pmove.cmd.buttons & BUTTON_ATTACK) != 0);

		if(cgs.cursorX == (int)nx  && cgs.cursorY == (int)ny && !fSelect) {
			return;
		}

		fResize = ((cg_pmove.cmd.buttons & BUTTON_SPRINT) != 0);

		cgs.cursorUpdate = cg.time + 5000;
		cgs.cursorX = nx;
		cgs.cursorY = ny;
	} else {
		// Already updated in the keycatcher
		nx = cgs.cursorX;
		ny = cgs.cursorY;
		fSelect = cgs.fSelect;
		fResize = cgs.fResize;
	}

	// For mm4
	cg.mvCurrentActive = cg.mvCurrentMainview;

	// For overlay highlights
	for(i=0; i<cg.mvTotalClients; i++) {
		cg.mvOverlay[i].fActive = qfalse;
	}

	for(i=wh->numActiveWindows-1; i>=0; i--) {
		w = &wh->window[wh->activeWindows[i]];
		if((w->effects & WFX_MULTIVIEW) && w != cg.mvCurrentMainview) {
			// Mouse/window detection
			// If the current window is selected, and the button is down, then allow the update
			// to occur, as quick mouse movements can move it past the window borders
			if(!fFound &&
			  (
				((w->mvInfo & MV_SELECTED) && fSelect) ||
				(!fSelect && nx >= w->x && nx < w->x + w->w && ny >= w->y && ny < w->y + w->h)
			  )) {
				if(!(w->mvInfo & MV_SELECTED)) {
					w->mvInfo |= MV_SELECTED;
					nSelectedWindow = i;
				}

				// If not dragging/resizing, prime for later update
				if(!fSelect) {
					w->m_x = -1.0f;
					w->m_y = -1.0f;
				} else {
					if(w->m_x > 0 && w->m_y > 0) {
						if(fResize) {
							w->w += nx - w->m_x;
							if(w->x + w->w > 640-2) w->w = 640 - 2 - w->x;
							if(w->w < 64) w->w = 64;

							w->h += ny - w->m_y;
							if(w->y + w->h > 480-2) w->h = 480 - 2 - w->y;
							if(w->h < 48) w->h = 48;
						} else {
							w->x += nx - w->m_x;
							if(w->x + w->w > 640-2) w->x = 640 - 2 - w->w;
							if(w->x < 2) w->x = 2;

							w->y += ny - w->m_y;
							if(w->y + w->h > 480-2) w->y = 480 - 2 - w->h;
							if(w->y < 2) w->y = 2;
						}
					}

					w->m_x = nx;
					w->m_y = ny;
				}

				fFound = qtrue;
				cg.mvCurrentActive = w;

			// Reset mouse info for window if it loses focuse
			} else if(w->mvInfo & MV_SELECTED) {
				fUpdateOverlay = qtrue;
				w->m_x = -1.0f;
				w->m_y = -1.0f;
				w->mvInfo &= ~MV_SELECTED;

				if(fFound) break;		// Small optimization: we've found a new window, and cleared the old focus
			}
		}
	}

	nx = (float)(MVINFO_RIGHT - (MVINFO_TEXTSIZE * 3));
	ny = (float)(MVINFO_TOP + (MVINFO_TEXTSIZE + 1));

	// Highlight corresponding active window's overlay element
	if(fFound) {
		for(i=0; i<cg.mvTotalClients; i++) {
			if(cg.mvOverlay[i].pID == (cg.mvCurrentActive->mvInfo & MV_PID)) {
				cg.mvOverlay[i].fActive = qtrue;
				break;
			}
		}
	}

	// Check MV overlay detection here for better perf with more text elements
	// General boundary check
	else {
		// Ugh, have to loop through BOTH team lists
		int vOffset = 0;

		for(i=TEAM_AXIS; i<=TEAM_ALLIES; i++) {
			if(cg.mvTotalTeam[i] == 0) continue;
			if(cgs.cursorX >= nx && cgs.cursorY >= ny && cgs.cursorX < MVINFO_RIGHT &&
			  cgs.cursorY < ny + (cg.mvTotalTeam[i] * (MVINFO_TEXTSIZE + 1))) {
				int pos = (int)(cgs.cursorY - ny) / (MVINFO_TEXTSIZE + 1);

				if(pos < cg.mvTotalTeam[i]) {
					int x = MVINFO_RIGHT - cg.mvOverlay[(cg.mvTeamList[i][pos])].width;
					int y = MVINFO_TOP + vOffset + ((pos + 1) * (MVINFO_TEXTSIZE + 1));

					// See if we're really over something
					if(cgs.cursorX >= x && cgs.cursorY >= y &&
					   cgs.cursorX <= MVINFO_RIGHT &&
					   cgs.cursorY <= y + MVINFO_TEXTSIZE) {
						// Perform any other window handling here for MV
						// views based on element selection
						cg.mvOverlay[(cg.mvTeamList[i][pos])].fActive =	qtrue;
						
						w = CG_mvClientLocate(cg.mvOverlay[(cg.mvTeamList[i][pos])].pID);
						if(w != NULL) {
							cg.mvCurrentActive = w;
						}

						if(fSelect) {
							if(w != NULL) {
								// Swap window-view with mainview
								if(w != cg.mvCurrentMainview) {
									CG_mvMainviewSwap(w);
								}
							} else {
								// Swap non-view with mainview
								cg.mvCurrentMainview->mvInfo = (cg.mvCurrentMainview->mvInfo & ~MV_PID) |
															   (cg.mvOverlay[cg.mvTeamList[i][pos]].pID & MV_PID);
								fUpdateOverlay = qtrue;
							}
						}
					}
				}
			}
			vOffset += (cg.mvTotalTeam[i] + 2) * (MVINFO_TEXTSIZE + 1);
			ny += vOffset;
		}
	}

	// If we have a new highlight, reorder so our highlight is always
	// drawn last (on top of all other windows)
	if(nSelectedWindow >= 0) {
		fUpdateOverlay = qtrue;
		x = wh->activeWindows[nSelectedWindow];
		
		for(j=nSelectedWindow; j<wh->numActiveWindows-1; j++) {
			wh->activeWindows[j] = wh->activeWindows[j+1];
		}
		
		wh->activeWindows[wh->numActiveWindows-1] = x;
	}

	// Finally, sync the overlay, if needed
	if(fUpdateOverlay) {
		CG_mvOverlayUpdate();
	}
}