/* ================= 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 ); } }
/* ============ 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 ); } }
/* ================ 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; }
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; }