/*
=================
idRenderModelManagerLocal::RemoveModel
=================
*/
void idRenderModelManagerLocal::RemoveModel( idRenderModel* model )
{
	int index = models.FindIndex( model );
	if( index != -1 )
	{
		hash.RemoveIndex( hash.GenerateKey( model->Name(), false ), index );
		models.RemoveIndex( index );
	}
}
Exemple #2
0
/*
============
idCmdSystemLocal::ExecuteCommandBuffer
============
*/
void idCmdSystemLocal::ExecuteCommandBuffer( void ) {
	int			i;
	char *		text;
	int			quotes;
	idCmdArgs	args;

	while( textLength ) {

		if ( wait )	{
			// skip out while text still remains in buffer, leaving it for next frame
			wait--;
			break;
		}

		// find a \n or ; line break
		text = (char *)textBuf;

		quotes = 0;
		for ( i = 0; i < textLength; i++ ) {
			if ( text[i] == '"' ) {
				quotes++;
			}
			if ( !( quotes & 1 ) &&  text[i] == ';' ) {
				break;	// don't break if inside a quoted string
			}
			if ( text[i] == '\n' || text[i] == '\r' || text[i] == 0 ) {
				break;
			}
		}
			
		text[i] = 0;

		if ( !idStr::Cmp( text, "_execTokenized" ) ) {
			args = tokenizedCmds[ 0 ];
			tokenizedCmds.RemoveIndex( 0 );
		} else {
			args.TokenizeString( text, false );
		}

		// delete the text from the command buffer and move remaining commands down
		// this is necessary because commands (exec) can insert data at the
		// beginning of the text buffer
        
		if ( i == textLength ) {
			textLength = 0;
            memset (textBuf, 0, MAX_CMD_BUFFER);
		} else {
            i++;
			textLength -= i;
			memmove( text, text+i, textLength );
		}

		// execute the command line that we have already tokenized
		ExecuteTokenizedString( args );
	}
}
Exemple #3
0
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

	// process any overflow.
	if (event_overflow.Num() > 0)
	{
		res = event_overflow[0];
		event_overflow.RemoveIndex(0);
		return res;
	}

	// overflow text input.
	static char *s = NULL;
	static size_t s_pos = 0;

	if (s) {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		s_pos++;
		if (!s[s_pos]) {
			free(s);
			s = NULL;
			s_pos = 0;
		}

		return res;
	}

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

    bool getNext = true;
	while (SDL_PollEvent(&ev) && getNext) {
        getNext = false;
		switch (ev.type) {
#ifdef __WINDOWS__ // on windows we need to grab the hwnd.
		case SDL_SYSWMEVENT:
			if (win32.hWnd == NULL)
			{
				win32.hWnd = ev.syswm.msg->msg.win.hwnd;
			}
			getNext = true; // try to get a decent event.
			break;
#endif
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
				case SDL_WINDOWEVENT_FOCUS_GAINED: {
						// unset modifier, in case alt-tab was used to leave window and ALT is still set
						// as that can cause fullscreen-toggling when pressing enter...
						SDL_Keymod currentmod = SDL_GetModState();
					
						int newmod = KMOD_NONE;
						if (currentmod & KMOD_CAPS) // preserve capslock
							newmod |= KMOD_CAPS;

						SDL_SetModState((SDL_Keymod)newmod);
					} // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST

					GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
					break;
				case SDL_WINDOWEVENT_FOCUS_LOST:
					GLimp_GrabInput(0);
					break;
			}

			return res_none;

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);
			if(!key) {
				if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) {
					key = Sys_GetConsoleKey(true);
				} else {
					if (ev.type == SDL_KEYDOWN) {
						common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
            			getNext = true; // try to get a decent event.
						break;
					}

				}
			}

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

			if ( (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				|| SDL_GetEventState(SDL_TEXTINPUT) == SDL_DISABLE)
				c = key;

			return res;

		case SDL_TEXTINPUT:
			if (ev.text.text && *ev.text.text) {

				res.evType = SE_CHAR;
				res.evValue = *ev.text.text;
				
				// if there are more characters hold onto them for later events.
				if (ev.text.text[1] != 0)
					s = strdup(ev.text.text+1);

				return res;
			}

			getNext = true; // try to get a decent event.
			break;

		case SDL_MOUSEMOTION:
			if (g_inputGrabbed)
			{
				res.evType = SE_MOUSE;

				res.evValue = ev.motion.xrel;
				res.evValue2 = ev.motion.yrel;

				mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
				mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));
			
				return res;
			}

			getNext = true;
			break;

		case SDL_MOUSEWHEEL:
			if (g_inputGrabbed)
			{
				res.evType = SE_KEY;

				if (ev.wheel.y > 0) {
					res.evValue = K_MWHEELUP;
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
				} else {
					res.evValue = K_MWHEELDOWN;
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
				}

				res.evValue2 = 1;

				return res;
			}

			getNext = true;
			break;

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			if (g_inputGrabbed)
			{
				res.evType = SE_KEY;

				switch (ev.button.button) {
				case SDL_BUTTON_LEFT:
					res.evValue = K_MOUSE1;
					mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				case SDL_BUTTON_MIDDLE:
					res.evValue = K_MOUSE3;
					mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				case SDL_BUTTON_RIGHT:
					res.evValue = K_MOUSE2;
					mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
					break;
				}

				res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

				return res;
			}

			getNext = true;
			break;

		case SDL_CONTROLLERBUTTONDOWN:
		case SDL_CONTROLLERBUTTONUP:
			{
				sys_jEvents jEvent =  mapjoybutton( (SDL_GameControllerButton)ev.cbutton.button);
				joystick_polls.Append(joystick_poll_t(	jEvent,
														ev.cbutton.state == SDL_PRESSED ? 1 : 0) );

				res.evType = SE_KEY;
				res.evValue2 = ev.cbutton.state == SDL_PRESSED ? 1 : 0;
				if ( ( jEvent >= J_ACTION1 ) && ( jEvent <= J_ACTION_MAX ) ) {
					res.evValue = K_JOY1 + ( jEvent - J_ACTION1 );
					return res;
				} else if ( ( jEvent >= J_DPAD_UP ) && ( jEvent <= J_DPAD_RIGHT ) ) {
					res.evValue = K_JOY_DPAD_UP + ( jEvent - J_DPAD_UP );
					return res;
				}

				getNext = true; // try to get a decent event.
			}
			break;

		case SDL_CONTROLLERAXISMOTION:
			{
				const int range = 16384;

				sys_jEvents jEvent = mapjoyaxis( (SDL_GameControllerAxis)ev.caxis.axis);
				joystick_polls.Append(joystick_poll_t(	jEvent, ev.caxis.value) );

				if ( jEvent == J_AXIS_LEFT_X ) {
					PushButton( K_JOY_STICK1_LEFT, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK1_RIGHT, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_LEFT_Y ) {
					PushButton( K_JOY_STICK1_UP, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK1_DOWN, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_X ) {
					PushButton( K_JOY_STICK2_LEFT, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK2_RIGHT, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_Y ) {
					PushButton( K_JOY_STICK2_UP, ( ev.caxis.value < -range ) );
					PushButton( K_JOY_STICK2_DOWN, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_LEFT_TRIG ) {
					PushButton( K_JOY_TRIGGER1, ( ev.caxis.value > range ) );
				} else if ( jEvent == J_AXIS_RIGHT_TRIG ) {
					PushButton( K_JOY_TRIGGER2, ( ev.caxis.value > range ) );
				}
				if ( jEvent >= J_AXIS_MIN && jEvent <= J_AXIS_MAX ) {
					int axis = jEvent - J_AXIS_MIN;
					int percent = ( ev.caxis.value * 16 ) / range;
					if ( joyAxis[axis] != percent ) {
						joyAxis[axis] = percent;
						res.evType = SE_JOYSTICK;
						res.evValue = axis;
						res.evValue2 = percent;
						return res;
					}
				}

				getNext = true; // try to get a decent event.
			}
			break;

		case SDL_JOYDEVICEADDED:
			SDL_GameControllerOpen( ev.jdevice.which );
			// TODO: hot swapping maybe.
			//lbOnControllerPlugIn(event.jdevice.which);
			break;

		case SDL_JOYDEVICEREMOVED:
			// TODO: hot swapping maybe.
			//lbOnControllerUnPlug(event.jdevice.which);
			break;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
            	getNext = true; // try to get a decent event.
            	break;
			}
		default:
            getNext = true; // try to get a decent event.
            break;
		}
	}

	return res_none;
}
Exemple #4
0
static idStr R_LoadPreprocessed( const idStr& filename, idList<idStr>& previoulsyLoadedFiles, idList<idStr>& includeStack ) {
	includeStack.Append( filename );
	previoulsyLoadedFiles.Append( filename );

	const int fileIndex = previoulsyLoadedFiles.Num() - 1;
	
	idStr content = R_ReadFile(filename.c_str());
	idStr ret;

	fhStrRef ptr = fhStrRef( content.c_str(), content.Length() );
	fhStrRef remaining = ptr;

	int currentLine = 1;
	int currentColumn = 1;
	bool isLineComment = false;

	for (; !ptr.IsEmpty(); ++ptr) {

		if (ptr[0] == '\n')	{
			++currentLine;
			currentColumn = 1;
			isLineComment = false;
			continue;
		}

		if (isLineComment) {
			continue;
		}

		if (ptr.StartsWith( "//" )) {
			isLineComment = true;
			continue;
		}

		static const fhStrRef includeDirective = "#include \"";
		if (currentColumn == 1 && ptr.StartsWith( includeDirective )) {
			fhStrRef includeFilename = ptr.Substr( includeDirective.Length() );
			for (int i = 0; i < includeFilename.Length() + 1; ++i) {
				if (i == includeFilename.Length())
					throw fhParseException( filename, currentLine, currentColumn, "unexpected end-of-file in preprocessor include" );

				if (includeFilename[i] == '\n')
					throw fhParseException( filename, currentLine, currentColumn, "unexpected end-of-line in preprocessor include" );

				if (includeFilename[i] == '"') {
					includeFilename = includeFilename.Substr( 0, i );
					break;
				}
			}

			if (includeFilename.IsEmpty())
				throw fhParseException( filename, currentLine, currentColumn, "empty filename in preprocessor include" );

			if (includeStack.FindIndex( includeFilename.ToString() ) >= 0)
				throw fhParseException( filename, currentLine, currentColumn, "circular preprocessor include" );

			idStr includeContent;
			//try to load included shader relative to current file. If that fails try to load included shader from root directory.
			try	{
				idStr includeFilePath;
				filename.ExtractFilePath(includeFilePath);				
				includeFilePath.AppendPath( includeFilename.c_str(), includeFilename.Length() );

				includeContent = R_LoadPreprocessed( includeFilePath, previoulsyLoadedFiles, includeStack );
				ret.Append( remaining.c_str(), ptr.c_str() - remaining.c_str() );
				ret.Append( includeContent );
				//ret.Append( "\n#line " + toString( currentLine + 1 ) + " \"" + filename + "\"" );
			} catch (const fhFileNotFoundException& e) {				
				try	{
					includeContent = R_LoadPreprocessed( includeFilename.ToString(), previoulsyLoadedFiles, includeStack );
					ret.Append( remaining.c_str(), ptr.c_str() - remaining.c_str() );
					ret.Append( includeContent );
					//ret.append( "\n#line " + ToString( currentLine + 1 ) + " \"" + filename + "\"" );
				} catch (const fhFileNotFoundException& e) {
					throw fhParseException( filename, currentLine, currentColumn, idStr( "include file not found: " ) + includeFilename.ToString() );
				}
			}

			//skip rest of the line
			while (!ptr.IsEmpty() && ptr[0] != '\n') {
				++ptr;
			}

			++currentLine;
			currentColumn = 1;
			remaining = ptr;

			continue;
		}

		currentColumn++;
	}

	ret.Append( remaining.ToString() );
	includeStack.RemoveIndex(includeStack.Num() - 1);
	return ret;
}