void CSoundGroup::UploadPropertiesAndPlay(size_t theIndex, const CVector3D& position, entity_id_t source) { #if CONFIG2_AUDIO if ( !g_SoundManager ) return; bool isOnscreen = false; ALfloat initialRolllOff = 0.1f; ALfloat itemRollOff = initialRolllOff; float offSet = RadiansOffCenter(position, isOnscreen, itemRollOff); bool shouldBePlayed = isOnscreen || TestFlag(eDistanceless) || TestFlag(eOmnipresent); if ( !shouldBePlayed ) return; if (snd_group.size() == 0) Reload(); if ( snd_group.size() <= theIndex ) return; CSoundData* sndData = snd_group[theIndex]; if ( sndData == NULL ) return; ISoundItem* hSound = ((CSoundManager*)g_SoundManager)->ItemForEntity( source, sndData); if ( hSound == NULL ) return; if (!TestFlag(eOmnipresent)) { CVector3D origin = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation(); float sndDist = origin.Y; float itemDist = ( position - origin ).Length(); if ( (sndDist * 2) < itemDist ) sndDist = itemDist; if (TestFlag(eDistanceless)) itemRollOff = 0; if ( sndData->IsStereo() ) LOGWARNING("OpenAL: stereo sounds can't be positioned: %s", sndData->GetFileName().string8()); hSound->SetLocation(CVector3D((sndDist * sin(offSet)), 0, - sndDist * cos(offSet))); hSound->SetRollOff(itemRollOff); } if (TestFlag(eRandPitch)) hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper)); else hSound->SetPitch(m_Pitch); ALfloat theGain = m_Gain; if (TestFlag(eRandGain)) theGain = RandFloat(m_GainLower, m_GainUpper); hSound->SetCone(m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain); ((CSoundManager*)g_SoundManager)->PlayGroupItem(hSound, theGain); #else // !CONFIG2_AUDIO UNUSED2(theIndex); UNUSED2(position); UNUSED2(source); #endif // !CONFIG2_AUDIO }
bool cPlayer::LoadFromDisk() { LoadPermissionsFromDisk(); // Log player permissions, cause it's what the cool kids do LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) { if( itr->second ) LOGINFO("%s", itr->first.c_str() ); } AString SourceFile; Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); cFile f; if (!f.Open(SourceFile, cFile::fmRead)) { // This is a new player whom we haven't seen yet, bail out, let them have the defaults return false; } AString buffer; if (f.ReadRestOfFile(buffer) != f.GetSize()) { LOGWARNING("Cannot read player data from file \"%s\"", SourceFile.c_str()); return false; } f.Close(); Json::Value root; Json::Reader reader; if (!reader.parse(buffer, root, false)) { LOGWARNING("Cannot parse player data in file \"%s\", player will be reset", SourceFile.c_str()); } Json::Value & JSON_PlayerPosition = root["position"]; if (JSON_PlayerPosition.size() == 3) { SetPosX(JSON_PlayerPosition[(unsigned int)0].asDouble()); SetPosY(JSON_PlayerPosition[(unsigned int)1].asDouble()); SetPosZ(JSON_PlayerPosition[(unsigned int)2].asDouble()); m_LastPosX = GetPosX(); m_LastPosY = GetPosY(); m_LastPosZ = GetPosZ(); m_LastFoodPos = GetPosition(); } Json::Value & JSON_PlayerRotation = root["rotation"]; if (JSON_PlayerRotation.size() == 3) { SetRotation ((float)JSON_PlayerRotation[(unsigned int)0].asDouble()); SetPitch ((float)JSON_PlayerRotation[(unsigned int)1].asDouble()); SetRoll ((float)JSON_PlayerRotation[(unsigned int)2].asDouble()); } m_Health = root.get("health", 0).asInt(); m_AirLevel = root.get("air", MAX_AIR_LEVEL).asInt(); m_FoodLevel = root.get("food", MAX_FOOD_LEVEL).asInt(); m_FoodSaturationLevel = root.get("foodSaturation", MAX_FOOD_LEVEL).asDouble(); m_FoodTickTimer = root.get("foodTickTimer", 0).asInt(); m_FoodExhaustionLevel = root.get("foodExhaustion", 0).asDouble(); m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); m_Inventory.LoadFromJson(root["inventory"]); m_LoadedWorldName = root.get("world", "world").asString(); LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", m_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str() ); return true; }
bool Texture2D::SetData(unsigned level, int x, int y, int width, int height, const void* data) { if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } D3DLOCKED_RECT d3dLockedRect; RECT d3dRect; d3dRect.left = x; d3dRect.top = y; d3dRect.right = x + width; d3dRect.bottom = y + height; DWORD flags = 0; if (level == 0 && x == 0 && y == 0 && width == levelWidth && height == levelHeight && pool_ == D3DPOOL_DEFAULT) flags |= D3DLOCK_DISCARD; if (FAILED(((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, (flags & D3DLOCK_DISCARD) ? 0 : &d3dRect, flags))) { LOGERROR("Could not lock texture"); return false; } if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); unsigned rowOffset = GetRowDataSize(x); // GetRowDataSize() returns CPU-side (source) data size, so need to convert for X8R8G8B8 if (format_ == D3DFMT_X8R8G8B8) { rowSize = rowSize / 3 * 4; rowOffset = rowOffset / 3 * 4; } // Perform conversion from RGB / RGBA as necessary switch (format_) { default: for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedRect.pBits + (y + i) * d3dLockedRect.Pitch + rowOffset; memcpy(dest, src, rowSize); src += rowSize; } break; case D3DFMT_X8R8G8B8: for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedRect.pBits + (y + i) * d3dLockedRect.Pitch + rowOffset; for (int j = 0; j < levelWidth; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = 255; src += 3; } } break; case D3DFMT_A8R8G8B8: for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedRect.pBits + (y + i) * d3dLockedRect.Pitch + rowOffset; for (int j = 0; j < levelWidth; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = src[3]; src += 4; } } break; } ((IDirect3DTexture9*)object_)->UnlockRect(level); return true; }
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data) { PROFILE(SetTextureData); if (!object_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); int levelDepth = GetLevelDepth(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } D3DLOCKED_BOX d3dLockedBox; D3DBOX d3dBox; d3dBox.Left = x; d3dBox.Top = y; d3dBox.Front = z; d3dBox.Right = x + width; d3dBox.Bottom = y + height; d3dBox.Back = z + depth; DWORD flags = 0; if (level == 0 && x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth && pool_ == D3DPOOL_DEFAULT) flags |= D3DLOCK_DISCARD; if (FAILED(((IDirect3DVolumeTexture9*)object_)->LockBox(level, &d3dLockedBox, (flags & D3DLOCK_DISCARD) ? 0 : &d3dBox, flags))) { LOGERROR("Could not lock texture"); return false; } if (IsCompressed()) { height = (height + 3) >> 2; y >>= 2; } unsigned char* src = (unsigned char*)data; unsigned rowSize = GetRowDataSize(width); // GetRowDataSize() returns CPU-side (source) data size, so need to convert for X8R8G8B8 if (format_ == D3DFMT_X8R8G8B8) rowSize = rowSize / 3 * 4; // Perform conversion from RGB / RGBA as necessary switch (format_) { default: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; memcpy(dest, src, rowSize); src += rowSize; } } break; case D3DFMT_X8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < width; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = 255; src += 3; } } } break; case D3DFMT_A8R8G8B8: for (int k = 0; k < levelDepth; ++k) { for (int i = 0; i < height; ++i) { unsigned char* dest = (unsigned char*)d3dLockedBox.pBits + (k * d3dLockedBox.SlicePitch) + i * d3dLockedBox.RowPitch; for (int j = 0; j < width; ++j) { *dest++ = src[2]; *dest++ = src[1]; *dest++ = src[0]; *dest++ = src[3]; src += 4; } } } break; } ((IDirect3DVolumeTexture9*)object_)->UnlockBox(level); return true; }
////////////////////////////////////////////////////////////////////////// // Create the shadow map void ShadowMapInternals::CreateTexture() { // Cleanup if (Texture) { glDeleteTextures(1, &Texture); Texture = 0; } if (DummyTexture) { glDeleteTextures(1, &DummyTexture); DummyTexture = 0; } if (Framebuffer) { pglDeleteFramebuffersEXT(1, &Framebuffer); Framebuffer = 0; } // save the caller's FBO glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &SavedViewFBO); pglGenFramebuffersEXT(1, &Framebuffer); if (g_Renderer.m_ShadowMapSize != 0) { // non-default option to override the size Width = Height = g_Renderer.m_ShadowMapSize; } else { // get shadow map size as next power of two up from view width/height Width = Height = (int)round_up_to_pow2((unsigned)std::max(g_Renderer.GetWidth(), g_Renderer.GetHeight())); } // Clamp to the maximum texture size Width = std::min(Width, (int)ogl_max_tex_size); Height = std::min(Height, (int)ogl_max_tex_size); // Since we're using a framebuffer object, the whole texture is available EffectiveWidth = Width; EffectiveHeight = Height; const char* formatname; switch(DepthTextureBits) { case 16: formatname = "DEPTH_COMPONENT16"; break; case 24: formatname = "DEPTH_COMPONENT24"; break; case 32: formatname = "DEPTH_COMPONENT32"; break; default: formatname = "DEPTH_COMPONENT"; break; } LOGMESSAGE(L"Creating shadow texture (size %dx%d) (format = %hs)", Width, Height, formatname); if (g_Renderer.m_Options.m_ShadowAlphaFix) { glGenTextures(1, &DummyTexture); g_Renderer.BindTexture(0, DummyTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } glGenTextures(1, &Texture); g_Renderer.BindTexture(0, Texture); GLenum format; #if CONFIG2_GLES format = GL_DEPTH_COMPONENT; #else switch (DepthTextureBits) { case 16: format = GL_DEPTH_COMPONENT16; break; case 24: format = GL_DEPTH_COMPONENT24; break; case 32: format = GL_DEPTH_COMPONENT32; break; default: format = GL_DEPTH_COMPONENT; break; } #endif glTexImage2D(GL_TEXTURE_2D, 0, format, Width, Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL); // GLES requires type == UNSIGNED_SHORT or UNSIGNED_INT // set texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #if CONFIG2_GLES // GLES doesn't do depth comparisons, so treat it as a // basic unfiltered depth texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); #else // Enable automatic depth comparisons glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); // Use GL_LINEAR to trigger automatic PCF on some devices glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #endif ogl_WarnIfError(); // bind to framebuffer object glBindTexture(GL_TEXTURE_2D, 0); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Framebuffer); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, Texture, 0); if (g_Renderer.m_Options.m_ShadowAlphaFix) { pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, DummyTexture, 0); } else { #if CONFIG2_GLES #warning TODO: figure out whether the glDrawBuffer/glReadBuffer stuff is needed, since it is not supported by GLES #else glDrawBuffer(GL_NONE); #endif } #if !CONFIG2_GLES glReadBuffer(GL_NONE); #endif ogl_WarnIfError(); GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, SavedViewFBO); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING(L"Framebuffer object incomplete: 0x%04X", status); // Disable shadow rendering (but let the user try again if they want) g_Renderer.m_Options.m_Shadows = false; } }
/// Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed. bool cHopperEntity::MoveItemsFromChest(cChunk & a_Chunk) { cChestEntity * MainChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(m_PosX, m_PosY + 1, m_PosZ)); if (MainChest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX, m_PosY + 1, m_PosZ); return false; } if (MoveItemsFromGrid(*MainChest)) { // Moved the item from the chest directly above the hopper return true; } // Check if the chest is a double-chest (chest directly above was empty), if so, try to move from there: static const struct { int x, z; } Coords [] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, } ; for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) { int x = m_RelX + Coords[i].x; int z = m_RelZ + Coords[i].z; cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); if (Neighbor == NULL) { continue; } BLOCKTYPE Block = Neighbor->GetBlock(x, m_PosY + 1, z); if (Block != MainChest->GetBlockType()) { // Not the same kind of chest continue; } cChestEntity * SideChest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z)); if (SideChest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, m_PosX + Coords[i].x, m_PosY + 1, m_PosZ + Coords[i].z); } else { if (MoveItemsFromGrid(*SideChest)) { return true; } } return false; } // The chest was single and nothing could be moved return false; }
void cMojangAPI::CacheNamesToUUIDs(const AStringVector & a_PlayerNames) { // Create a list of names to query, by removing those that are already cached: AStringVector NamesToQuery; NamesToQuery.reserve(a_PlayerNames.size()); { cCSLock Lock(m_CSNameToUUID); for (AStringVector::const_iterator itr = a_PlayerNames.begin(), end = a_PlayerNames.end(); itr != end; ++itr) { if (m_NameToUUID.find(*itr) == m_NameToUUID.end()) { NamesToQuery.push_back(*itr); } } // for itr - a_PlayerNames[] } // Lock(m_CSNameToUUID) while (!NamesToQuery.empty()) { // Create the request body - a JSON containing up to MAX_PER_QUERY playernames: Json::Value root; int Count = 0; AStringVector::iterator itr = NamesToQuery.begin(), end = NamesToQuery.end(); for (; (itr != end) && (Count < MAX_PER_QUERY); ++itr, ++Count) { Json::Value req(*itr); root.append(req); } // for itr - a_PlayerNames[] NamesToQuery.erase(NamesToQuery.begin(), itr); Json::FastWriter Writer; AString RequestBody = Writer.write(root); // Create the HTTP request: AString Request; Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_NameToUUIDServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Type: application/json\r\n"; Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length()); Request += "\r\n"; Request += RequestBody; // Get the response from the server: AString Response; if (!SecureRequest(m_NameToUUIDServer, Request, Response)) { continue; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } Response.erase(0, idxHeadersEnd + 4); // Parse the returned string into Json: Json::Reader reader; if (!reader.parse(Response, root, false) || !root.isArray()) { LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); continue; } // Store the returned results into cache: Json::Value::UInt JsonCount = root.size(); Int64 Now = time(NULL); { cCSLock Lock(m_CSNameToUUID); for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_NameToUUID[StrToLower(JsonName)] = sProfile(JsonName, JsonUUID, "", "", Now); NotifyNameUUID(JsonName, JsonUUID); } // for idx - root[] } // cCSLock (m_CSNameToUUID) // Also cache the UUIDToName: { cCSLock Lock(m_CSUUIDToName); for (Json::Value::UInt idx = 0; idx < JsonCount; ++idx) { Json::Value & Val = root[idx]; AString JsonName = Val.get("name", "").asString(); AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString()); if (JsonUUID.empty()) { continue; } m_UUIDToName[JsonUUID] = sProfile(JsonName, JsonUUID, "", "", Now); } // for idx - root[] } } // while (!NamesToQuery.empty()) }
CMessage* CMessagePathResult::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val)) { LOGWARNING(L"CMessagePathResult::FromJSVal not implemented"); return NULL; }
void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { int Seed = m_ChunkGenerator.GetSeed(); eDimension Dimension = StringToDimension(a_IniFile.GetValue("General", "Dimension", "Overworld")); // Older configuration used "Structures" in addition to "Finishers"; we don't distinguish between the two anymore (#398) // Therefore, we load Structures from the ini file for compatibility, but move its contents over to Finishers: AString Structures = a_IniFile.GetValue("Generator", "Structures", ""); AString Finishers = a_IniFile.GetValueSet("Generator", "Finishers", "Ravines, WormNestCaves, WaterLakes, LavaLakes, OreNests, Trees, SprinkleFoliage, Ice, Snow, Lilypads, BottomLava, DeadBushes, PreSimulator"); if (!Structures.empty()) { LOGINFO("[Generator].Structures is deprecated, moving the contents to [Generator].Finishers."); // Structures used to generate before Finishers, so place them first: Structures.append(", "); Finishers = Structures + Finishers; a_IniFile.SetValue("Generator", "Finishers", Finishers); } a_IniFile.DeleteValue("Generator", "Structures"); // Create all requested finishers: AStringVector Str = StringSplitAndTrim(Finishers, ","); for (AStringVector::const_iterator itr = Str.begin(); itr != Str.end(); ++itr) { // Finishers, alpha-sorted: if (NoCaseCompare(*itr, "BottomLava") == 0) { int DefaultBottomLavaLevel = (Dimension == dimNether) ? 30 : 10; int BottomLavaLevel = a_IniFile.GetValueSetI("Generator", "BottomLavaLevel", DefaultBottomLavaLevel); m_FinishGens.push_back(new cFinishGenBottomLava(BottomLavaLevel)); } else if (NoCaseCompare(*itr, "DeadBushes") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_DEAD_BUSH, biDesert, 2, E_BLOCK_SAND, E_BLOCK_SAND)); } else if (NoCaseCompare(*itr, "DirectOverhangs") == 0) { m_FinishGens.push_back(new cStructGenDirectOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DistortedMembraneOverhangs") == 0) { m_FinishGens.push_back(new cStructGenDistortedMembraneOverhangs(Seed)); } else if (NoCaseCompare(*itr, "DualRidgeCaves") == 0) { float Threshold = (float)a_IniFile.GetValueSetF("Generator", "DualRidgeCavesThreshold", 0.3); m_FinishGens.push_back(new cStructGenDualRidgeCaves(Seed, Threshold)); } else if (NoCaseCompare(*itr, "Ice") == 0) { m_FinishGens.push_back(new cFinishGenIce); } else if (NoCaseCompare(*itr, "LavaLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "LavaLakesProbability", 10); m_FinishGens.push_back(new cStructGenLakes(Seed * 5 + 16873, E_BLOCK_STATIONARY_LAVA, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "LavaSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_LAVA, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "MarbleCaves") == 0) { m_FinishGens.push_back(new cStructGenMarbleCaves(Seed)); } else if (NoCaseCompare(*itr, "MineShafts") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "MineShaftsGridSize", 512); int MaxSystemSize = a_IniFile.GetValueSetI("Generator", "MineShaftsMaxSystemSize", 160); int ChanceCorridor = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCorridor", 600); int ChanceCrossing = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceCrossing", 200); int ChanceStaircase = a_IniFile.GetValueSetI("Generator", "MineShaftsChanceStaircase", 200); m_FinishGens.push_back(new cStructGenMineShafts( Seed, GridSize, MaxSystemSize, ChanceCorridor, ChanceCrossing, ChanceStaircase )); } else if (NoCaseCompare(*itr, "Lilypads") == 0) { m_FinishGens.push_back(new cFinishGenSingleBiomeSingleTopBlock(Seed, E_BLOCK_LILY_PAD, biSwampland, 4, E_BLOCK_WATER, E_BLOCK_STATIONARY_WATER)); } else if (NoCaseCompare(*itr, "NetherClumpFoliage") == 0) { m_FinishGens.push_back(new cFinishGenNetherClumpFoliage(Seed)); } else if (NoCaseCompare(*itr, "OreNests") == 0) { m_FinishGens.push_back(new cStructGenOreNests(Seed)); } else if (NoCaseCompare(*itr, "PreSimulator") == 0) { m_FinishGens.push_back(new cFinishGenPreSimulator); } else if (NoCaseCompare(*itr, "Ravines") == 0) { m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); } else if (NoCaseCompare(*itr, "Snow") == 0) { m_FinishGens.push_back(new cFinishGenSnow); } else if (NoCaseCompare(*itr, "SprinkleFoliage") == 0) { m_FinishGens.push_back(new cFinishGenSprinkleFoliage(Seed)); } else if (NoCaseCompare(*itr, "Trees") == 0) { m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); m_FinishGens.push_back(new cStructGenLakes(Seed * 3 + 652, E_BLOCK_STATIONARY_WATER, *m_HeightGen, Probability)); } else if (NoCaseCompare(*itr, "WaterSprings") == 0) { m_FinishGens.push_back(new cFinishGenFluidSprings(Seed, E_BLOCK_WATER, a_IniFile, Dimension)); } else if (NoCaseCompare(*itr, "WormNestCaves") == 0) { m_FinishGens.push_back(new cStructGenWormNestCaves(Seed)); } else { LOGWARNING("Unknown Finisher in the [Generator] section: \"%s\". Ignoring.", itr->c_str()); } } // for itr - Str[] }
CMessage* CMessageProgressiveLoad::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val)) { LOGWARNING(L"CMessageProgressiveLoad::FromJSVal not implemented"); return NULL; }
jsval CMessagePathResult::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const { LOGWARNING(L"CMessagePathResult::ToJSVal not implemented"); return JSVAL_VOID; }
jsval CMessageProgressiveLoad::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const { LOGWARNING(L"CMessageProgressiveLoad::ToJSVal not implemented"); return JSVAL_VOID; }
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { LOGWARNING("An error occured while listening for connections: %d (%s).", a_ErrorCode, a_ErrorMsg.c_str()); }
void Render() { PROFILE3("render"); #if CONFIG2_AUDIO if (g_SoundManager) g_SoundManager->IdleTask(); #endif ogl_WarnIfError(); g_Profiler2.RecordGPUFrameStart(); ogl_WarnIfError(); // prepare before starting the renderer frame if (g_Game && g_Game->IsGameStarted()) g_Game->GetView()->BeginFrame(); if (g_Game) g_Renderer.SetSimulation(g_Game->GetSimulation2()); // start new frame g_Renderer.BeginFrame(); ogl_WarnIfError(); if (g_Game && g_Game->IsGameStarted()) g_Game->GetView()->Render(); ogl_WarnIfError(); g_Renderer.RenderTextOverlays(); if (g_DoRenderGui) g_GUI->Draw(); ogl_WarnIfError(); // If we're in Atlas game view, render special overlays (e.g. editor bandbox) if (g_AtlasGameLoop && g_AtlasGameLoop->view) { g_AtlasGameLoop->view->DrawOverlays(); ogl_WarnIfError(); } // Text: glDisable(GL_DEPTH_TEST); g_Console->Render(); ogl_WarnIfError(); if (g_DoRenderLogger) g_Logger->Render(); ogl_WarnIfError(); // Profile information g_ProfileViewer.RenderProfile(); ogl_WarnIfError(); // Draw the cursor (or set the Windows cursor, on Windows) if (g_DoRenderCursor) { PROFILE3_GPU("cursor"); CStrW cursorName = g_CursorName; if (cursorName.empty()) { cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, false); } else { bool forceGL = false; CFG_GET_VAL("nohwcursor", Bool, forceGL); #if CONFIG2_GLES #warning TODO: implement cursors for GLES #else // set up transform for GL cursor glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); CMatrix3D transform; transform.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f); glLoadMatrixf(&transform._11); #endif if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0) LOGWARNING(L"Failed to draw cursor '%ls'", cursorName.c_str()); #if CONFIG2_GLES #warning TODO: implement cursors for GLES #else // restore transform glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); #endif } } glEnable(GL_DEPTH_TEST); g_Renderer.EndFrame(); PROFILE2_ATTR("draw calls: %d", (int)g_Renderer.GetStats().m_DrawCalls); PROFILE2_ATTR("terrain tris: %d", (int)g_Renderer.GetStats().m_TerrainTris); PROFILE2_ATTR("water tris: %d", (int)g_Renderer.GetStats().m_WaterTris); PROFILE2_ATTR("model tris: %d", (int)g_Renderer.GetStats().m_ModelTris); PROFILE2_ATTR("overlay tris: %d", (int)g_Renderer.GetStats().m_OverlayTris); PROFILE2_ATTR("blend splats: %d", (int)g_Renderer.GetStats().m_BlendSplats); PROFILE2_ATTR("particles: %d", (int)g_Renderer.GetStats().m_Particles); ogl_WarnIfError(); g_Profiler2.RecordGPUFrameEnd(); ogl_WarnIfError(); }
bool cGroupManager::LoadGroups() { cIniFile IniFile; if (!IniFile.ReadFile("groups.ini")) { LOGWARNING("Regenerating groups.ini, all groups will be reset"); IniFile.AddHeaderComment(" This is the MCServer permissions manager groups file"); IniFile.AddHeaderComment(" It stores all defined groups such as Administrators, Players, or Moderators"); IniFile.SetValue("Owner", "Permissions", "*", true); IniFile.SetValue("Owner", "Color", "2", true); IniFile.SetValue("Moderator", "Permissions", "core.time,core.item,core.teleport,core.ban,core.unban,core.save-all,core.toggledownfall"); IniFile.SetValue("Moderator", "Color", "2", true); IniFile.SetValue("Moderator", "Inherits", "Player", true); IniFile.SetValue("Player", "Permissions", "core.portal", true); IniFile.SetValue("Player", "Color", "f", true); IniFile.SetValue("Player", "Inherits", "Default", true); IniFile.SetValue("Default", "Permissions", "core.help,core.plugins,core.spawn,core.worlds,core.back,core.motd,core.build,core.locate,core.viewdistance", true); IniFile.SetValue("Default", "Color", "f", true); IniFile.WriteFile("groups.ini"); } int NumKeys = IniFile.GetNumKeys(); for (int i = 0; i < NumKeys; i++) { AString KeyName = IniFile.GetKeyName(i); cGroup * Group = GetGroup(KeyName.c_str()); Group->ClearPermission(); // Needed in case the groups are reloaded. LOGD("Loading group %s", KeyName.c_str()); Group->SetName(KeyName); AString Color = IniFile.GetValue(KeyName, "Color", "-"); if ((Color != "-") && (Color.length() >= 1)) { Group->SetColor(cChatColor::Color + Color[0]); } else { Group->SetColor(cChatColor::White); } AString Commands = IniFile.GetValue(KeyName, "Commands", ""); if (!Commands.empty()) { AStringVector Split = StringSplitAndTrim(Commands, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddCommand(Split[i]); } } AString Permissions = IniFile.GetValue(KeyName, "Permissions", ""); if (!Permissions.empty()) { AStringVector Split = StringSplitAndTrim(Permissions, ","); for (size_t i = 0; i < Split.size(); i++) { Group->AddPermission(Split[i]); } } AString Groups = IniFile.GetValue(KeyName, "Inherits", ""); if (!Groups.empty()) { AStringVector Split = StringSplitAndTrim(Groups, ","); for (size_t i = 0; i < Split.size(); i++) { Group->InheritFrom(GetGroup(Split[i].c_str())); } } } // Always return true, we can handle writefile fails later. return true; }
void cChunkDesc::ReadBlockArea(cBlockArea & a_Dest, int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ) { // Normalize the coords: if (a_MinRelX > a_MaxRelX) { std::swap(a_MinRelX, a_MaxRelX); } if (a_MinRelY > a_MaxRelY) { std::swap(a_MinRelY, a_MaxRelY); } if (a_MinRelZ > a_MaxRelZ) { std::swap(a_MinRelZ, a_MaxRelZ); } // Include the Max coords: a_MaxRelX += 1; a_MaxRelY += 1; a_MaxRelZ += 1; // Check coords validity: if (a_MinRelX < 0) { LOGWARNING("%s: MinRelX less than zero, adjusting to zero", __FUNCTION__); a_MinRelX = 0; } else if (a_MinRelX >= cChunkDef::Width) { LOGWARNING("%s: MinRelX more than chunk width, adjusting to chunk width", __FUNCTION__); a_MinRelX = cChunkDef::Width - 1; } if (a_MaxRelX < 0) { LOGWARNING("%s: MaxRelX less than zero, adjusting to zero", __FUNCTION__); a_MaxRelX = 0; } else if (a_MaxRelX > cChunkDef::Width) { LOGWARNING("%s: MaxRelX more than chunk width, adjusting to chunk width", __FUNCTION__); a_MaxRelX = cChunkDef::Width; } if (a_MinRelY < 0) { LOGWARNING("%s: MinRelY less than zero, adjusting to zero", __FUNCTION__); a_MinRelY = 0; } else if (a_MinRelY >= cChunkDef::Height) { LOGWARNING("%s: MinRelY more than chunk height, adjusting to chunk height", __FUNCTION__); a_MinRelY = cChunkDef::Height - 1; } if (a_MaxRelY < 0) { LOGWARNING("%s: MaxRelY less than zero, adjusting to zero", __FUNCTION__); a_MaxRelY = 0; } else if (a_MaxRelY > cChunkDef::Height) { LOGWARNING("%s: MaxRelY more than chunk height, adjusting to chunk height", __FUNCTION__); a_MaxRelY = cChunkDef::Height; } if (a_MinRelZ < 0) { LOGWARNING("%s: MinRelZ less than zero, adjusting to zero", __FUNCTION__); a_MinRelZ = 0; } else if (a_MinRelZ >= cChunkDef::Width) { LOGWARNING("%s: MinRelZ more than chunk width, adjusting to chunk width", __FUNCTION__); a_MinRelZ = cChunkDef::Width - 1; } if (a_MaxRelZ < 0) { LOGWARNING("%s: MaxRelZ less than zero, adjusting to zero", __FUNCTION__); a_MaxRelZ = 0; } else if (a_MaxRelZ > cChunkDef::Width) { LOGWARNING("%s: MaxRelZ more than chunk width, adjusting to chunk width", __FUNCTION__); a_MaxRelZ = cChunkDef::Width; } // Prepare the block area: int SizeX = a_MaxRelX - a_MinRelX; int SizeY = a_MaxRelY - a_MinRelY; int SizeZ = a_MaxRelZ - a_MinRelZ; a_Dest.Clear(); a_Dest.m_Origin.x = m_ChunkX * cChunkDef::Width + a_MinRelX; a_Dest.m_Origin.y = a_MinRelY; a_Dest.m_Origin.z = m_ChunkZ * cChunkDef::Width + a_MinRelZ; a_Dest.SetSize(SizeX, SizeY, SizeZ, cBlockArea::baTypes | cBlockArea::baMetas); for (int y = 0; y < SizeY; y++) { int CDY = a_MinRelY + y; for (int z = 0; z < SizeZ; z++) { int CDZ = a_MinRelZ + z; for (int x = 0; x < SizeX; x++) { int CDX = a_MinRelX + x; BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; GetBlockTypeMeta(CDX, CDY, CDZ, BlockType, BlockMeta); a_Dest.SetRelBlockTypeMeta(x, y, z, BlockType, BlockMeta); } // for x } // for z } // for y }
/// Moves items out from this hopper into the destination. Returns true if the contents have changed. bool cHopperEntity::MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick) { if (a_CurrentTick - m_LastMoveItemsOutTick < TICKS_PER_TRANSFER) { // Too early after the previous transfer return false; } // Get the coords of the block where to output items: int OutX, OutY, OutZ; NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); if (!GetOutputBlockPos(Meta, OutX, OutY, OutZ)) { // Not attached to another container return false; } if (OutY < 0) { // Cannot output below the zero-th block level return false; } // Convert coords to relative: int OutRelX = OutX - a_Chunk.GetPosX() * cChunkDef::Width; int OutRelZ = OutZ - a_Chunk.GetPosZ() * cChunkDef::Width; cChunk * DestChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(OutRelX, OutRelZ); if (DestChunk == NULL) { // The destination chunk has been unloaded, don't tick return false; } // Call proper moving function, based on the blocktype present at the coords: bool res = false; switch (DestChunk->GetBlock(OutRelX, OutY, OutRelZ)) { case E_BLOCK_TRAPPED_CHEST: case E_BLOCK_CHEST: { // Chests have special handling because of double-chests res = MoveItemsToChest(*DestChunk, OutX, OutY, OutZ); break; } case E_BLOCK_LIT_FURNACE: case E_BLOCK_FURNACE: { // Furnaces have special handling because of the direction-to-slot relation res = MoveItemsToFurnace(*DestChunk, OutX, OutY, OutZ, Meta); break; } case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: case E_BLOCK_HOPPER: { cBlockEntityWithItems * BlockEntity = static_cast<cBlockEntityWithItems *>(DestChunk->GetBlockEntity(OutX, OutY, OutZ)); if (BlockEntity == NULL) { LOGWARNING("%s: A block entity was not found where expected at {%d, %d, %d}", __FUNCTION__, OutX, OutY, OutZ); return false; } res = MoveItemsToGrid(*BlockEntity); break; } } // If the item has been moved, reset the last tick: if (res) { m_LastMoveItemsOutTick = a_CurrentTick; } return res; }
bool CMapGeneratorWorker::Run() { m_ScriptInterface->SetCallbackData(static_cast<void*> (this)); // Replace RNG with a seeded deterministic function m_ScriptInterface->ReplaceNondeterministicRNG(m_MapGenRNG); m_ScriptInterface->LoadGlobalScripts(); // Functions for RMS m_ScriptInterface->RegisterFunction<bool, std::wstring, CMapGeneratorWorker::LoadLibrary>("LoadLibrary"); m_ScriptInterface->RegisterFunction<void, CScriptValRooted, CMapGeneratorWorker::ExportMap>("ExportMap"); m_ScriptInterface->RegisterFunction<void, int, CMapGeneratorWorker::SetProgress>("SetProgress"); m_ScriptInterface->RegisterFunction<void, CMapGeneratorWorker::MaybeGC>("MaybeGC"); m_ScriptInterface->RegisterFunction<std::vector<std::string>, CMapGeneratorWorker::GetCivData>("GetCivData"); // TODO: This code is a bit ugly because we have to ensure that CScriptValRooted gets destroyed before the ScriptInterface. // In the future we should work more with the standard JSAPI types for rooting on the stack, which should avoid such problems. bool ret = true; { // Parse settings CScriptValRooted settingsVal = m_ScriptInterface->ParseJSON(m_Settings); if (settingsVal.undefined()) { LOGERROR(L"CMapGeneratorWorker::Run: Failed to parse settings"); ret = false; } else { // Init RNG seed u32 seed; if (!m_ScriptInterface->GetProperty(settingsVal.get(), "Seed", seed)) { // No seed specified LOGWARNING(L"CMapGeneratorWorker::Run: No seed value specified - using 0"); seed = 0; } m_MapGenRNG.seed(seed); // Copy settings to global variable if (!m_ScriptInterface->SetProperty(m_ScriptInterface->GetGlobalObject(), "g_MapSettings", settingsVal)) { LOGERROR(L"CMapGeneratorWorker::Run: Failed to define g_MapSettings"); ret = false; } else { // Load RMS LOGMESSAGE(L"Loading RMS '%ls'", m_ScriptPath.string().c_str()); if (!m_ScriptInterface->LoadGlobalScriptFile(m_ScriptPath)) { LOGERROR(L"CMapGeneratorWorker::Run: Failed to load RMS '%ls'", m_ScriptPath.string().c_str()); ret = false; } } } } // We must destroy the ScriptInterface in the same thread because the JSAPI requires that! SAFE_DELETE(m_ScriptInterface); return ret; }
/// Moves items to the chest at the specified coords. Returns true if contents have changed bool cHopperEntity::MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ) { // Try the chest directly connected to the hopper: cChestEntity * ConnectedChest = static_cast<cChestEntity *>(a_Chunk.GetBlockEntity(a_BlockX, a_BlockY, a_BlockZ)); if (ConnectedChest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d}", __FUNCTION__, a_BlockX, a_BlockY, a_BlockZ); return false; } if (MoveItemsToGrid(*ConnectedChest)) { // Chest block directly connected was not full return true; } // Check if the chest is a double-chest (chest block directly connected was full), if so, try to move into the other half: static const struct { int x, z; } Coords [] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, } ; int RelX = a_BlockX - a_Chunk.GetPosX() * cChunkDef::Width; int RelZ = a_BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width; for (size_t i = 0; i < ARRAYCOUNT(Coords); i++) { int x = RelX + Coords[i].x; int z = RelZ + Coords[i].z; cChunk * Neighbor = a_Chunk.GetRelNeighborChunkAdjustCoords(x, z); if (Neighbor == NULL) { continue; } BLOCKTYPE Block = Neighbor->GetBlock(x, a_BlockY, z); if (Block != ConnectedChest->GetBlockType()) { // Not the same kind of chest continue; } cChestEntity * Chest = static_cast<cChestEntity *>(Neighbor->GetBlockEntity(a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z)); if (Chest == NULL) { LOGWARNING("%s: A chest entity was not found where expected, at {%d, %d, %d} (%d, %d)", __FUNCTION__, a_BlockX + Coords[i].x, a_BlockY, a_BlockZ + Coords[i].z, x, z); continue; } if (MoveItemsToGrid(*Chest)) { return true; } return false; } // The chest was single and nothing could be moved return false; }
bool NavigationMesh::Build() { PROFILE(BuildNavigationMesh); // Release existing navigation data and zero the bounding box ReleaseNavigationMesh(); if (!node_) return false; if (!node_->GetWorldScale().Equals(Vector3::ONE)) LOGWARNING("Navigation mesh root node has scaling. Agent parameters may not work as intended"); Vector<NavigationGeometryInfo> geometryList; CollectGeometries(geometryList); if (geometryList.Empty()) return true; // Nothing to do // Build the combined bounding box for (unsigned i = 0; i < geometryList.Size(); ++i) boundingBox_.Merge(geometryList[i].boundingBox_); // Expand bounding box by padding boundingBox_.min_ -= padding_; boundingBox_.max_ += padding_; { PROFILE(BuildNavigationMesh); // Calculate number of tiles int gridW = 0, gridH = 0; float tileEdgeLength = (float)tileSize_ * cellSize_; rcCalcGridSize(&boundingBox_.min_.x_, &boundingBox_.max_.x_, cellSize_, &gridW, &gridH); numTilesX_ = (gridW + tileSize_ - 1) / tileSize_; numTilesZ_ = (gridH + tileSize_ - 1) / tileSize_; // Calculate max. number of tiles and polygons, 22 bits available to identify both tile & polygon within tile unsigned maxTiles = NextPowerOfTwo(numTilesX_ * numTilesZ_); unsigned tileBits = 0; unsigned temp = maxTiles; while (temp > 1) { temp >>= 1; ++tileBits; } unsigned maxPolys = 1 << (22 - tileBits); dtNavMeshParams params; rcVcopy(params.orig, &boundingBox_.min_.x_); params.tileWidth = tileEdgeLength; params.tileHeight = tileEdgeLength; params.maxTiles = maxTiles; params.maxPolys = maxPolys; navMesh_ = dtAllocNavMesh(); if (!navMesh_) { LOGERROR("Could not allocate navigation mesh"); return false; } if (dtStatusFailed(navMesh_->init(¶ms))) { LOGERROR("Could not initialize navigation mesh"); ReleaseNavigationMesh(); return false; } // Build each tile unsigned numTiles = 0; for (int z = 0; z < numTilesZ_; ++z) { for (int x = 0; x < numTilesX_; ++x) { if (BuildTile(geometryList, x, z)) ++numTiles; } } LOGDEBUG("Built navigation mesh with " + String(numTiles) + " tiles"); return true; } }
void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID) { ASSERT(a_UUID.size() == 32); // Check if already present: { if (m_UUIDToProfile.find(a_UUID) != m_UUIDToProfile.end()) { return; } } // Create the request address: AString Address = m_UUIDToProfileAddress; ReplaceString(Address, "%UUID%", a_UUID); // Create the HTTP request: AString Request; Request += "GET " + Address + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_UUIDToProfileServer + "\r\n"; Request += "User-Agent: MCServer\r\n"; Request += "Connection: close\r\n"; Request += "Content-Length: 0\r\n"; Request += "\r\n"; // Get the response from the server: AString Response; if (!SecureRequest(m_UUIDToProfileServer, Request, Response)) { return; } // Check the HTTP status line: const AString Prefix("HTTP/1.1 200 OK"); AString HexDump; if (Response.compare(0, Prefix.size(), Prefix)) { LOGINFO("%s failed: bad HTTP status line received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } // Erase the HTTP headers from the response: size_t idxHeadersEnd = Response.find("\r\n\r\n"); if (idxHeadersEnd == AString::npos) { LOGINFO("%s failed: bad HTTP response header received", __FUNCTION__); LOGD("Response: \n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } Response.erase(0, idxHeadersEnd + 4); // Parse the returned string into Json: Json::Reader reader; Json::Value root; if (!reader.parse(Response, root, false) || !root.isObject()) { LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); return; } /* Example response: { "id": "b1caf24202a841a78055a079c460eee7", "name": "xoft", "properties": [ { "name": "textures", "value": "eyJ0aW1lc3RhbXAiOjE0MDcwNzAzMjEyNzEsInByb2ZpbGVJZCI6ImIxY2FmMjQyMDJhODQxYTc4MDU1YTA3OWM0NjBlZWU3IiwicHJvZmlsZU5hbWUiOiJ4b2Z0IiwiaXNQdWJsaWMiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9iNzc5YmFiZjVhNTg3Zjk0OGFkNjc0N2VhOTEyNzU0MjliNjg4Mjk1YWUzYzA3YmQwZTJmNWJmNGQwNTIifX19", "signature": "XCty+jGEF39hEPrPhYNnCX087kPaoCjYruzYI/DS4nkL5hbjnkSM5Rh15hnUyv/FHhC8OF5rif3D1tQjtMI19KSVaXoUFXpbJM8/+PB8GDgEbX8Fc3u9nYkzOcM/xfxdYsFAdFhLQMkvase/BZLSuPhdy9DdI+TCrO7xuSTZfYmmwVuWo3w5gCY+mSIAnqltnOzaOOTcly75xvO0WYpVk7nJdnR2tvSi0wfrQPDrIg/uzhX7p0SnDqijmBU4QaNez/TNKiFxy69dAzt0RSotlQzqkDbyVKhhv9a4eY8h3pXi4UMftKEj4FAKczxLImkukJXuOn5NN15/Q+le0rJVBC60/xjKIVzltEsMN6qjWD0lQjey7WEL+4pGhCVuWY5KzuZjFvgqszuJTFz7lo+bcHiceldJtea8/fa02eTRObZvdLxbWC9ZfFY0IhpOVKfcLdno/ddDMNMQMi5kMrJ8MZZ/PcW1w5n7MMGWPGCla1kOaC55AL0QYSMGRVEZqgU9wXI5M7sHGZKGM4mWxkbEJYBkpI/p3GyxWgV6v33ZWlsz65TqlNrR1gCLaoFCm7Sif8NqPBZUAONHYon0roXhin/DyEanS93WV6i6FC1Wisscjq2AcvnOlgTo/5nN/1QsMbjNumuMGo37sqjRqlXoPb8zEUbAhhztYuJjEfQ2Rd8=" } ] } */ // Store the returned result into caches: AString PlayerName = root.get("name", "").asString(); if (PlayerName.empty()) { // No valid playername, bail out return; } Json::Value Properties = root.get("properties", ""); Int64 Now = time(NULL); { cCSLock Lock(m_CSUUIDToProfile); m_UUIDToProfile[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); } { cCSLock Lock(m_CSUUIDToName); m_UUIDToName[a_UUID] = sProfile(PlayerName, a_UUID, Properties, Now); } { cCSLock Lock(m_CSNameToUUID); m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, a_UUID, Properties, Now); } NotifyNameUUID(PlayerName, a_UUID); }
void cRoot::Start(void) { delete m_Log; m_Log = new cMCLogger(); m_bStop = false; while (!m_bStop) { m_bRestart = false; LoadGlobalSettings(); LOG("Creating new server instance..."); m_Server = new cServer(); LOG("Reading server config..."); cIniFile IniFile("settings.ini"); if (!IniFile.ReadFile()) { LOGWARNING("settings.ini inaccessible, all settings are reset to default values"); } m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0); if (m_PrimaryServerVersion == 0) { m_PrimaryServerVersion = cProtocolRecognizer::PROTO_VERSION_LATEST; } else { // Make a note in the log that the primary server version is explicitly set in the ini file LOGINFO("settings.ini: [Server].PrimaryServerVersion set to %d.", m_PrimaryServerVersion); } LOG("Starting server..."); if (!m_Server->InitServer(IniFile)) { LOGERROR("Failed to start server, shutting down."); return; } IniFile.WriteFile(); cIniFile WebIniFile("webadmin.ini"); if (!WebIniFile.ReadFile()) { LOGWARNING("webadmin.ini inaccessible, wabadmin is disabled"); } if (WebIniFile.GetValueB("WebAdmin", "Enabled", false)) { LOG("Creating WebAdmin..."); m_WebAdmin = new cWebAdmin(8080); } LOG("Loading settings..."); m_GroupManager = new cGroupManager(); m_CraftingRecipes = new cCraftingRecipes; m_FurnaceRecipe = new cFurnaceRecipe(); LOG("Loading worlds..."); LoadWorlds(); LOG("Loading plugin manager..."); m_PluginManager = new cPluginManager(); m_PluginManager->ReloadPluginsNow(); LOG("Loading MonsterConfig..."); m_MonsterConfig = new cMonsterConfig; // This sets stuff in motion LOG("Starting Authenticator..."); m_Authenticator.Start(); LOG("Starting worlds..."); StartWorlds(); LOG("Starting server..."); m_Server->Start(); #if !defined(ANDROID_NDK) LOG("Starting InputThread..."); m_InputThread = new cThread( InputThread, this, "cRoot::InputThread" ); m_InputThread->Start( false ); // We should NOT wait? Otherwise we can´t stop the server from other threads than the input thread #endif LOG("Initialization done, server running now."); while (!m_bStop && !m_bRestart) // These are modified by external threads { cSleep::MilliSleep(1000); } #if !defined(ANDROID_NDK) delete m_InputThread; m_InputThread = NULL; #endif // Deallocate stuffs LOG("Shutting down server..."); m_Server->Shutdown(); // This waits for threads to stop and d/c clients LOG("Stopping world threads..."); StopWorlds(); LOG("Stopping authenticator..."); m_Authenticator.Stop(); LOG("Freeing MonsterConfig..."); delete m_MonsterConfig; m_MonsterConfig = 0; LOG("Stopping WebAdmin..."); delete m_WebAdmin; m_WebAdmin = 0; LOG("Unloading recipes..."); delete m_FurnaceRecipe; m_FurnaceRecipe = NULL; delete m_CraftingRecipes; m_CraftingRecipes = NULL; LOG("Forgetting groups..."); delete m_GroupManager; m_GroupManager = 0; LOG("Unloading worlds..."); UnloadWorlds(); LOG("Stopping plugin manager..."); delete m_PluginManager; m_PluginManager = NULL; cItemHandler::Deinit(); cBlockHandler::Deinit(); LOG("Destroying server..."); //delete HeartBeat; HeartBeat = 0; delete m_Server; m_Server = 0; LOG("Shutdown done."); } delete m_Log; m_Log = 0; }
bool Texture3D::BeginLoad(Deserializer& source) { ResourceCache* cache = GetSubsystem<ResourceCache>(); // In headless mode, do not actually load the texture, just return success if (!graphics_) return true; // If device is lost, retry later if (graphics_->IsDeviceLost()) { LOGWARNING("Texture load while device is lost"); dataPending_ = true; return true; } String texPath, texName, texExt; SplitPath(GetName(), texPath, texName, texExt); cache->ResetDependencies(this); loadParameters_ = new XMLFile(context_); if (!loadParameters_->Load(source)) { loadParameters_.Reset(); return false; } XMLElement textureElem = loadParameters_->GetRoot(); XMLElement volumeElem = textureElem.GetChild("volume"); XMLElement colorlutElem = textureElem.GetChild("colorlut"); if (volumeElem) { String name = volumeElem.GetAttribute("name"); String volumeTexPath, volumeTexName, volumeTexExt; SplitPath(name, volumeTexPath, volumeTexName, volumeTexExt); // If path is empty, add the XML file path if (volumeTexPath.Empty()) name = texPath + name; loadImage_ = cache->GetTempResource<Image>(name); // Precalculate mip levels if async loading if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING) loadImage_->PrecalculateLevels(); cache->StoreResourceDependency(this, name); return true; } else if (colorlutElem) { String name = colorlutElem.GetAttribute("name"); String colorlutTexPath, colorlutTexName, colorlutTexExt; SplitPath(name, colorlutTexPath, colorlutTexName, colorlutTexExt); // If path is empty, add the XML file path if (colorlutTexPath.Empty()) name = texPath + name; SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(name); loadImage_ = new Image(context_); if (!loadImage_->LoadColorLUT(*(file.Get()))) { loadParameters_.Reset(); loadImage_.Reset(); return false; } // Precalculate mip levels if async loading if (loadImage_ && GetAsyncLoadState() == ASYNC_LOADING) loadImage_->PrecalculateLevels(); cache->StoreResourceDependency(this, name); return true; } LOGERROR("Texture3D XML data for " + GetName() + " did not contain either volume or colorlut element"); return false; }
void cBrewingRecipes::AddRecipeFromLine(const AString & a_Line, unsigned int a_LineNum) { AString Line(a_Line); Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end()); short InputDamage; short OutputDamage; std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>(); std::unique_ptr<cItem> IngredientItem = cpp14::make_unique<cItem>(); std::unique_ptr<cItem> OutputItem = cpp14::make_unique<cItem>(); const AStringVector & InputAndIngredient = StringSplit(Line, "+"); if (InputAndIngredient.size() != 2) { LOGWARNING("brewing.txt: line %d: A line with '+' was expected", a_LineNum); LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } const AStringVector & IngredientAndOutput = StringSplit(InputAndIngredient[1].c_str(), "="); if (IngredientAndOutput.size() != 2) { LOGWARNING("brewing.txt: line %d: A line with '=' was expected", a_LineNum); LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } if (!ParseItem(IngredientAndOutput[0], *IngredientItem)) { LOGWARNING("brewing.txt: Parsing of the item didn't worked."); LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } if (!StringToInteger<short>(InputAndIngredient[0], InputDamage)) { LOGWARNING("brewing.txt: line %d: Cannot parse the damage value for the input item\"%s\".", a_LineNum, InputAndIngredient[0].c_str()); LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } if (!StringToInteger<short>(IngredientAndOutput[1], OutputDamage)) { LOGWARNING("brewing.txt: line %d: Cannot parse the damage value for the output item\"%s\".", a_LineNum, IngredientAndOutput[1].c_str()); LOGINFO("Offending line: \"%s\"", a_Line.c_str()); return; } // The items has always the same type InputItem->m_ItemType = E_ITEM_POTION; InputItem->m_ItemDamage = InputDamage; OutputItem->m_ItemType = E_ITEM_POTION; OutputItem->m_ItemDamage = OutputDamage; std::unique_ptr<cRecipe> Recipe = cpp14::make_unique<cRecipe>(); Recipe->Input = std::move(InputItem); Recipe->Output = std::move(OutputItem); Recipe->Ingredient = std::move(IngredientItem); m_pState->Recipes.push_back(std::move(Recipe)); }
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override { LOGWARNING("HTTP server error on port %d: %d (%s)", m_Port, a_ErrorCode, a_ErrorMsg.c_str()); }
bool TextureCube::SetData(CubeMapFace face, unsigned level, int x, int y, int width, int height, const void* data) { if (!object_ || !graphics_) { LOGERROR("No texture created, can not set data"); return false; } if (!data) { LOGERROR("Null source for setting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for setting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Texture data assignment while device is lost"); dataPending_ = true; return true; } if (IsCompressed()) { x &= ~3; y &= ~3; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0) { LOGERROR("Illegal dimensions for setting data"); return false; } bool wholeLevel = x == 0 && y == 0 && width == levelWidth && height == levelHeight; // Use Direct3D convention with the vertical coordinates ie. 0 is top y = levelHeight - (y + height); graphics_->SetTextureForUpdate(this); unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_; if (!IsCompressed()) { if (wholeLevel) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format, width, height, 0, GetExternalFormat(format_), GetDataType(format_), data); else glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, x, y, width, height, GetExternalFormat(format_), GetDataType(format_), data); } else { if (wholeLevel) glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, format, width, height, 0, GetDataSize(width, height), data); else glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, x, y, width, height, format, GetDataSize(width, height), data); } graphics_->SetTexture(0, 0); return true; }
void JSONValue::SetVariantValue(const Variant& variant, Context* context) { if (!IsNull()) { LOGWARNING("JsonValue is not null"); } switch (variant.GetType()) { case VAR_BOOL: *this = variant.GetBool(); return; case VAR_INT: *this = variant.GetInt(); return; case VAR_FLOAT: *this = variant.GetFloat(); return; case VAR_DOUBLE: *this = variant.GetDouble(); return; case VAR_STRING: *this = variant.GetString(); return; case VAR_VARIANTVECTOR: SetVariantVector(variant.GetVariantVector(), context); return; case VAR_VARIANTMAP: SetVariantMap(variant.GetVariantMap(), context); return; case VAR_RESOURCEREF: { if (!context) { LOGERROR("Context must not null for ResourceRef"); return; } const ResourceRef& ref = variant.GetResourceRef(); *this = String(context->GetTypeName(ref.type_)) + ";" + ref.name_; } return; case VAR_RESOURCEREFLIST: { if (!context) { LOGERROR("Context must not null for ResourceRefList"); return; } const ResourceRefList& refList = variant.GetResourceRefList(); String str(context->GetTypeName(refList.type_)); for (unsigned i = 0; i < refList.names_.Size(); ++i) { str += ";"; str += refList.names_[i]; } *this = str; } return; case VAR_STRINGVECTOR: { const StringVector& vector = variant.GetStringVector(); Resize(vector.Size()); for (unsigned i = 0; i < vector.Size(); ++i) (*this)[i] = vector[i]; } return; default: *this = variant.ToString(); } }
void CPostprocManager::RecreateBuffers() { Cleanup(); m_Width = g_Renderer.GetWidth(); m_Height = g_Renderer.GetHeight(); #define GEN_BUFFER_RGBA(name, w, h) \ glGenTextures(1, (GLuint*)&name); \ glBindTexture(GL_TEXTURE_2D, name); \ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, \ GL_UNSIGNED_BYTE, 0); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Two fullscreen ping-pong textures. GEN_BUFFER_RGBA(m_ColourTex1, m_Width, m_Height); GEN_BUFFER_RGBA(m_ColourTex2, m_Width, m_Height); // Textures for several blur sizes. It would be possible to reuse // m_BlurTex2b, thus avoiding the need for m_BlurTex4b and m_BlurTex8b, though given // that these are fairly small it's probably not worth complicating the coordinates passed // to the blur helper functions. GEN_BUFFER_RGBA(m_BlurTex2a, m_Width / 2, m_Height / 2); GEN_BUFFER_RGBA(m_BlurTex2b, m_Width / 2, m_Height / 2); GEN_BUFFER_RGBA(m_BlurTex4a, m_Width / 4, m_Height / 4); GEN_BUFFER_RGBA(m_BlurTex4b, m_Width / 4, m_Height / 4); GEN_BUFFER_RGBA(m_BlurTex8a, m_Width / 8, m_Height / 8); GEN_BUFFER_RGBA(m_BlurTex8b, m_Width / 8, m_Height / 8); #undef GEN_BUFFER_RGBA // Allocate the Depth/Stencil texture. glGenTextures(1, (GLuint*)&m_DepthTex); glBindTexture(GL_TEXTURE_2D, m_DepthTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, m_Width, m_Height, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); // Set up the framebuffers with some initial textures. pglGenFramebuffersEXT(1, &m_PingFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_ColourTex1, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0); GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING(L"Framebuffer object incomplete (A): 0x%04X", status); } pglGenFramebuffersEXT(1, &m_PongFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_ColourTex2, 0); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING(L"Framebuffer object incomplete (B): 0x%04X", status); } pglGenFramebuffersEXT(1, &m_BloomFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); /*pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_BloomTex1, 0); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING(L"Framebuffer object incomplete (B): 0x%04X", status); }*/ pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
bool Texture2D::GetData(unsigned level, void* dest) const { if (!object_) { LOGERROR("No texture created, can not get data"); return false; } if (!dest) { LOGERROR("Null destination for getting data"); return false; } if (level >= levels_) { LOGERROR("Illegal mip level for getting data"); return false; } if (graphics_->IsDeviceLost()) { LOGWARNING("Getting texture data while device is lost"); return false; } int levelWidth = GetLevelWidth(level); int levelHeight = GetLevelHeight(level); D3DLOCKED_RECT d3dLockedRect; RECT d3dRect; d3dRect.left = 0; d3dRect.top = 0; d3dRect.right = levelWidth; d3dRect.bottom = levelHeight; if (FAILED(((IDirect3DTexture9*)object_)->LockRect(level, &d3dLockedRect, &d3dRect, D3DLOCK_READONLY))) { LOGERROR("Could not lock texture"); return false; } int height = levelHeight; if (IsCompressed()) height = (height + 3) >> 2; unsigned char* destPtr = (unsigned char*)dest; unsigned rowSize = GetRowDataSize(levelWidth); // GetRowDataSize() returns CPU-side (destination) data size, so need to convert for X8R8G8B8 if (format_ == D3DFMT_X8R8G8B8) rowSize = rowSize / 3 * 4; // Perform conversion to RGB / RGBA as necessary switch (format_) { default: for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedRect.pBits + i * d3dLockedRect.Pitch; memcpy(destPtr, src, rowSize); destPtr += rowSize; } break; case D3DFMT_X8R8G8B8: for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedRect.pBits + i * d3dLockedRect.Pitch; for (int j = 0; j < levelWidth; ++j) { destPtr[2] = *src++; destPtr[1] = *src++; destPtr[0] = *src++; ++src; destPtr += 3; } } break; case D3DFMT_A8R8G8B8: for (int i = 0; i < height; ++i) { unsigned char* src = (unsigned char*)d3dLockedRect.pBits + i * d3dLockedRect.Pitch; for (int j = 0; j < levelWidth; ++j) { destPtr[2] = *src++; destPtr[1] = *src++; destPtr[0] = *src++; destPtr[3] = *src++; destPtr += 4; } } break; } ((IDirect3DTexture9*)object_)->UnlockRect(level); return true; }
int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) { LOGWARNING("LUA: %s", lua_tostring(a_LuaState, -1)); LogStackTrace(a_LuaState, 1); return 1; // We left the error message on the stack as the return value }