/** * Advance time counters. */ static void advanceTime(timespan_t delta) { int oldGameTic = 0; sysTime += delta; oldGameTic = SECONDS_TO_TICKS(gameTime); // The difference between gametic and demotic is that demotic // is not altered at any point. Gametic changes at handshakes. gameTime += delta; demoTime += delta; if(DD_IsSharpTick()) { // When a new sharp tick begins, we want that the 35 Hz tick // calculated from gameTime also changes. If this is not the // case, we will adjust gameTime slightly so that it syncs again. if(oldGameTic == SECONDS_TO_TICKS(gameTime)) { LOGDEV_XVERBOSE("Syncing gameTime with sharp ticks (tic=%i pos=%f)") << oldGameTic << frameTimePos; // Realign. gameTime = (SECONDS_TO_TICKS(gameTime) + 1) / 35.f; } } // World time always advances unless a local game is paused on client-side. App_WorldSystem().advanceTime(delta); }
void Demo_PauseRecording(int playerNum) { client_t *cl = clients + playerNum; // A demo is not being recorded? if(!cl->recording || cl->recordPaused) return; // All packets will be written for the same tic. writeInfo[playerNum].pausetime = SECONDS_TO_TICKS(demoTime); cl->recordPaused = true; }
/** * Advance time counters. */ static void advanceTime(timespan_t time) { int oldGameTic = 0; sysTime += time; if(!stopTime || netGame) { oldGameTic = SECONDS_TO_TICKS(gameTime); // The difference between gametic and demotic is that demotic // is not altered at any point. Gametic changes at handshakes. gameTime += time; demoTime += time; if(DD_IsSharpTick()) { // When a new sharp tick begins, we want that the 35 Hz tick // calculated from gameTime also changes. If this is not the // case, we will adjust gameTime slightly so that it syncs again. if(oldGameTic == SECONDS_TO_TICKS(gameTime)) { DEBUG_VERBOSE2_Message(("DD_AdvanceTime: Syncing gameTime with sharp ticks (tic=%i pos=%f)\n", oldGameTic, frameTimePos)); // Realign. gameTime = (SECONDS_TO_TICKS(gameTime) + 1) / 35.f; } } // Leveltic is reset to zero at every map change. // The map time only advances when the game is not paused. #ifdef __CLIENT__ if(!clientPaused) #endif { ddMapTime += time; } } }
/** * This is the main ticker of the engine. We'll call all the other tickers * from here. * * @param time Duration of the tick. This will never be longer than 1.0/TICSPERSEC. */ static void baseTicker(timespan_t time) { if(DD_IsFrameTimeAdvancing()) { #ifdef __CLIENT__ // Demo ticker. Does stuff like smoothing of view angles. Demo_Ticker(time); #endif P_Ticker(time); UI2_Ticker(time); // InFine ticks whenever it's active. FI_Ticker(); // Game logic. if(App_GameLoaded() && gx.Ticker) { gx.Ticker(time); } #ifdef __CLIENT__ // Windowing system ticks. R_Ticker(time); if(isClient) { Cl_Ticker(time); } #elif __SERVER__ Sv_Ticker(time); #endif if(DD_IsSharpTick()) { // Set frametime back by one tick (to stay in the 0..1 range). realFrameTimePos -= 1; // Camera smoothing: now that the world tic has occurred, the next sharp // position can be processed. R_NewSharpWorld(); #ifdef LIBDENG_PLAYER0_MOVEMENT_ANALYSIS if(ddPlayers[0].shared.inGame && ddPlayers[0].shared.mo) { mobj_t* mo = ddPlayers[0].shared.mo; static coord_t prevPos[3] = { 0, 0, 0 }; static coord_t prevSpeed = 0; coord_t speed = V2d_Length(mo->mom); coord_t actualMom[2] = { mo->origin[0] - prevPos[0], mo->origin[1] - prevPos[1] }; coord_t actualSpeed = V2d_Length(actualMom); Con_Message("%i,%f,%f,%f,%f", SECONDS_TO_TICKS(sysTime + time), ddPlayers[0].shared.forwardMove, speed, actualSpeed, speed - prevSpeed); V3d_Copy(prevPos, mo->origin); prevSpeed = speed; } #endif } #ifdef __CLIENT__ // While paused, don't modify frametime so things keep still. if(!clientPaused) #endif { frameTimePos = realFrameTimePos; } } // Console is always ticking. Con_Ticker(time); // User interface ticks. if(tickUI) { UI_Ticker(time); } // Plugins tick always. DD_CallHooks(HOOK_TICKER, 0, &time); // The netcode gets to tick, too. Net_Ticker(time); }
// --[ Method ]--------------------------------------------------------------- // // - Class : CStravaganzaMaxTools // // - prototype : bool BuildShaders() // // - Purpose : Builds the shader list from MAX's materials. // Preview mode requires texture files to be stored with full // path in order to load them. When we export, we only store the // filename. Another thing is that in the export mode, we copy // all textures into the path specified by the user if that // option is checked. // // ----------------------------------------------------------------------------- bool CStravaganzaMaxTools::BuildShaders() { std::vector<Mtl*>::iterator it; assert(m_vecShaders.empty()); if(!m_bPreview && m_bCopyTextures && m_strTexturePath == "") { CLogger::NotifyWindow("Textures won't be copied\nSpecify a valid output texture path first"); } LOG.Write("\n\n-Building shaders: "); for(it = m_vecMaterials.begin(); it != m_vecMaterials.end(); ++it) { Mtl* pMaxMaterial = *it; assert(pMaxMaterial); LOG.Write("\n %s", pMaxMaterial->GetName().data()); CShaderStandard* pShaderStd = new CShaderStandard; pShaderStd->SetName(pMaxMaterial->GetName().data()); // Properties StdMat2 *pMaxStandardMtl = NULL; StdMat2 *pMaxBakedMtl = NULL; float fAlpha; if(pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial; } else if(pMaxMaterial->ClassID() == Class_ID(BAKE_SHELL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(0); pMaxBakedMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(1); } if(pMaxStandardMtl) { // Standard material fAlpha = pMaxStandardMtl->GetOpacity(0); Shader* pMaxShader = pMaxStandardMtl->GetShader(); CVector4 v4Specular = ColorToVector4(pMaxStandardMtl->GetSpecular(0), 0.0f) * pMaxShader->GetSpecularLevel(0, 0); pShaderStd->SetAmbient (ColorToVector4(pMaxStandardMtl->GetAmbient(0), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxStandardMtl->GetDiffuse(0), fAlpha)); pShaderStd->SetSpecular (v4Specular); pShaderStd->SetShininess(pMaxShader->GetGlossiness(0, 0) * 128.0f); if(pMaxStandardMtl->GetTwoSided() == TRUE) { pShaderStd->SetTwoSided(true); } // Need to cast to StdMat2 in order to get access to IsFaceted(). // ¿Is StdMat2 always the interface for standard materials? if(((StdMat2*)pMaxStandardMtl)->IsFaceted()) { pShaderStd->SetFaceted(true); } if(pMaxStandardMtl->GetWire() == TRUE) { pShaderStd->SetPostWire(true); pShaderStd->SetWireLineThickness(pMaxStandardMtl->GetWireSize(0)); } } else { // Material != Standard fAlpha = 1.0f; // pMaxMaterial->GetXParency(); pShaderStd->SetAmbient (ColorToVector4(pMaxMaterial->GetAmbient(), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxMaterial->GetDiffuse(), fAlpha)); pShaderStd->SetSpecular (CVector4(0.0f, 0.0f, 0.0f, 0.0f)); pShaderStd->SetShininess(0.0f); } // Layers if(!pMaxStandardMtl) { m_vecShaders.push_back(pShaderStd); continue; } bool bDiffuseMap32Bits = false; StdMat2 *pStandardMtl; for(int i = 0; i < 3; i++) { int nMap; pStandardMtl = pMaxStandardMtl; // 0 = diffuse, 1 == bump, 2 = lightmap (self illumination slot) or envmap (reflection slot) if(i == 0) { nMap = ID_DI; } else if(i == 1) { nMap = ID_BU; // If its a baked material, get the bump map from there if(pMaxBakedMtl) { pStandardMtl = pMaxBakedMtl; } } else if(i == 2) { bool bBaked = false; // If its a baked material, get the map2 (lightmap) from there if(pMaxBakedMtl) { if(pMaxBakedMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { bBaked = true; nMap = ID_SI; pStandardMtl = pMaxBakedMtl; } } if(!bBaked) { if(pStandardMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { nMap = ID_SI; } else { nMap = ID_RL; } } } // Check validity if(pStandardMtl->GetMapState(nMap) != MAXMAPSTATE_ENABLED) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } Texmap* pMaxTexmap = pStandardMtl->GetSubTexmap(nMap); if(!pMaxTexmap) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } // Get texmaps std::vector<std::string> vecTextures, vecPaths; CShaderStandard::SLayerInfo layerInfo; CShaderStandard::SBitmapInfo bitmapInfo; if(pMaxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) { BitmapTex* pMaxBitmapTex = (BitmapTex*)pMaxTexmap; Bitmap* pMaxBitmap = pMaxBitmapTex->GetBitmap(SECONDS_TO_TICKS(m_fStartTime)); StdUVGen* pMaxUVGen = pMaxBitmapTex->GetUVGen(); if(!pMaxBitmap) { if(i == 0) { LOG.Write("\n Invalid diffuse. Skipping."); break; } continue; } assert(pMaxUVGen); BitmapInfo bi = pMaxBitmap->Storage()->bi; // bi.Name() returns the full path // bi.Filename() returns just the filename vecTextures.push_back(bi.Filename()); vecPaths. push_back(bi.Name()); LOG.Write("\n Bitmap %s", vecTextures[0].data()); // Check if diffuse texture has alpha channel if(i == 0) { CBitmap bitmap; CInputFile bitmapFile; if(!bitmapFile.Open(bi.Name(), false)) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load file %s", bi.Name()); } else { if(!bitmap.Load(&bitmapFile, GetFileExt(bi.Name()))) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load bitmap %s", bi.Name()); } else { if(bitmap.GetBpp() == 32) { bDiffuseMap32Bits = true; LOG.Write(" (with alpha channel)"); } bitmap.Free(); } bitmapFile.Close(); } } // Ok, copy properties layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURE2D; bitmapInfo.strFile = m_bPreview ? bi.Name() : bi.Filename(); bitmapInfo.bTile = ((pMaxUVGen->GetTextureTiling() & (U_WRAP | V_WRAP)) == (U_WRAP | V_WRAP)) ? true : false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; // won't be used (forcefiltering = false) layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = pMaxUVGen->GetCoordMapping(0) == UVMAP_SPHERE_ENV ? CShaderStandard::UVGEN_ENVMAPPING : CShaderStandard::UVGEN_EXPLICITMAPPING; layerInfo.uMapChannel = pMaxUVGen->GetMapChannel(); layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(pMaxUVGen->GetUOffs(0), pMaxUVGen->GetVOffs(0), 0.0f); layerInfo.v3RotationOffset = CVector3(pMaxUVGen->GetUAng(0), pMaxUVGen->GetVAng(0), pMaxUVGen->GetWAng(0)); } else if(pMaxTexmap->ClassID() == Class_ID(ACUBIC_CLASS_ID, 0)) { ACubic* pMaxCubic = (ACubic*)pMaxTexmap; IParamBlock2* pBlock = pMaxCubic->pblock; Interval validRange = m_pMaxInterface->GetAnimRange(); for(int nFace = 0; nFace < 6; nFace++) { int nMaxFace; switch(nFace) { case 0: nMaxFace = 3; break; case 1: nMaxFace = 2; break; case 2: nMaxFace = 1; break; case 3: nMaxFace = 0; break; case 4: nMaxFace = 5; break; case 5: nMaxFace = 4; break; } TCHAR *name; pBlock->GetValue(acubic_bitmap_names, TICKS_TO_SECONDS(m_fStartTime), name, validRange, nMaxFace); vecPaths.push_back(name); CStr path, file, ext; SplitFilename(CStr(name), &path, &file, &ext); std::string strFile = std::string(file.data()) + ext.data(); vecTextures.push_back(strFile); bitmapInfo.strFile = m_bPreview ? name : strFile; bitmapInfo.bTile = false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); } layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURECUBEMAP; layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = CShaderStandard::UVGEN_ENVMAPPING; layerInfo.uMapChannel = 0; layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationOffset = CVector3(0.0f, 0.0f, 0.0f); } else { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } if(!m_bPreview && m_bCopyTextures && m_strTexturePath != "") { for(int nTex = 0; nTex != vecTextures.size(); nTex++) { // Copy textures into the specified folder std::string strDestPath = m_strTexturePath; if(strDestPath[strDestPath.length() - 1] != '\\') { strDestPath.append("\\", 1); } strDestPath.append(vecTextures[nTex]); if(!CopyFile(vecPaths[nTex].data(), strDestPath.data(), FALSE)) { CLogger::NotifyWindow("Unable to copy %s to\n%s", vecPaths[i], strDestPath.data()); } } } if(layerInfo.eUVGen == CShaderStandard::UVGEN_ENVMAPPING && i == 1) { CLogger::NotifyWindow("%s : Bump with spheremapping not supported", pShaderStd->GetName().data()); } else { // Add layer switch(i) { case 0: pShaderStd->SetLayer(CShaderStandard::LAYER_DIFF, layerInfo); break; case 1: pShaderStd->SetLayer(CShaderStandard::LAYER_BUMP, layerInfo); break; case 2: pShaderStd->SetLayer(CShaderStandard::LAYER_MAP2, layerInfo); break; } } } // ¿Do we need blending? if(ARE_EQUAL(fAlpha, 1.0f) && !bDiffuseMap32Bits) { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_ONE); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_ZERO); } else { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_SRCALPHA); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_INVSRCALPHA); } // Add shader m_vecShaders.push_back(pShaderStd); } return true; }
static void _clock_isr( int vector, int code ) { (void)(vector); (void)(code); pcb_t *pcb; // spin the pinwheel ++_pinwheel; if( _pinwheel == (CLOCK_FREQUENCY / 10) ) { _pinwheel = 0; ++_pindex; c_putchar_at( 79, 0, "|/-\\"[ _pindex & 3 ] ); } // increment the system time ++_system_time; /* ** wake up any sleeper whose time has come ** ** we give awakened processes preference over the ** current process (when it is scheduled again) */ while( !_queue_empty(_sleeping) && (uint32_t) _queue_kpeek(_sleeping) <= _system_time ) { // time to wake up! remove it from the queue pcb = (pcb_t *) _queue_remove( _sleeping ); if( pcb == NULL ) { #ifdef DEBUG _kpanic( "_clock_isr", "NULL from sleep queue remove" ); #else c_puts( "*** _clock_isr: NULL from sleep queue\n" ); break; #endif } // and schedule it for dispatch _schedule( pcb ); } // check the current process to see if it needs to be scheduled // sanity check! _current->quantum -= 1; if( _current->quantum < 1 ) { _schedule( _current ); _dispatch(); } #ifdef DUMP_QUEUES // Approximately every 10 seconds, dump the queues, and // print the contents of the SIO buffers. if( (_system_time % SECONDS_TO_TICKS(10)) == 0 ) { c_printf( "Queue contents @%08x\n", _system_time ); _queue_dump( "ready[0]", _ready[0] ); _queue_dump( "ready[1]", _ready[1] ); _queue_dump( "ready[2]", _ready[2] ); _queue_dump( "ready[3]", _ready[3] ); _queue_dump( "sleep", _sleeping ); _sio_dump(); } #endif // tell the PIC we're done __outb( PIC_MASTER_CMD_PORT, PIC_EOI ); }
/** * Send all the relevant information to each client. */ void Sv_TransmitFrame(void) { int i, cTime, numInGame, pCount; // Obviously clients don't transmit anything. if(!allowFrames || isClient || Sys_IsShuttingDown()) { return; } if(!netGame) { // When not running a netGame, only generate deltas when somebody // is recording a demo. for(i = 0; i < DDMAXPLAYERS; ++i) if(Sv_IsFrameTarget(i)) break; if(i == DDMAXPLAYERS) { // Nobody is a frame target. return; } } if(SECONDS_TO_TICKS(gameTime) == lastTransmitTic) { // We were just here! return; } lastTransmitTic = SECONDS_TO_TICKS(gameTime); LOG_AS("Sv_TransmitFrame"); // Generate new deltas for the frame. Sv_GenerateFrameDeltas(); // How many players currently in the game? numInGame = Sv_GetNumPlayers(); for(i = 0, pCount = 0; i < DDMAXPLAYERS; ++i) { if(!Sv_IsFrameTarget(i)) { // This player is not a valid target for frames. continue; } // When the interval is greater than zero, this causes the frames // to be sent at different times for each player. pCount++; cTime = SECONDS_TO_TICKS(gameTime); if(frameInterval > 0 && numInGame > 1) { cTime += (pCount * frameInterval) / numInGame; } if(cTime <= clients[i].lastTransmit + frameInterval) { // Still too early to send. continue; } clients[i].lastTransmit = cTime; if(clients[i].ready) // && clients[i].updateCount > 0) { // A frame will be sent to this client. If the client // doesn't send ticcmds, the updatecount will eventually // decrease back to zero. //clients[i].updateCount--; Sv_SendFrame(i); } else { LOG_NET_XVERBOSE("NOT sending at tic %i to plr %i (ready:%b)") << lastTransmitTic << i << clients[i].ready; } } }