/* This is a small part of the implementation of C4Landscape for what is * required by mape. We cannot link the full implementation since it would * introduce a dependency on C4Game, and therefore the rest of the engine. */ int32_t PixCol2Mat(BYTE pixc) { // Get texture int32_t iTex = PixCol2Tex(pixc); if (!iTex) return MNone; // Get material-texture mapping const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex); // Return material return pTex ? pTex->GetMaterialIndex() : MNone; }
void C4LandscapeRenderClassic::Update(C4Rect To, C4Landscape *pSource) { // clip to landscape size To.Intersect(C4Rect(0,0,iWidth,iHeight)); // everything clipped? if (To.Wdt<=0 || To.Hgt<=0) return; if (!Surface32->Lock()) return; // We clear the affected region here because ClearBoxDw allocates the // main memory buffer for the box, so that only that box needs to be // sent to the gpu, and not the whole texture, or every pixel // separately. It's an important optimization. Surface32->ClearBoxDw(To.x, To.y, To.Wdt, To.Hgt); // do lightning for (int32_t iX=To.x; iX<To.x+To.Wdt; ++iX) { int AboveDensity = 0, BelowDensity = 0; for (int i = 1; i <= 8; ++i) { AboveDensity += pSource->GetPlacement(iX, To.y - i - 1); BelowDensity += pSource->GetPlacement(iX, To.y + i - 1); } for (int32_t iY=To.y; iY<To.y+To.Hgt; ++iY) { AboveDensity -= pSource->GetPlacement(iX, iY - 9); AboveDensity += pSource->GetPlacement(iX, iY - 1); BelowDensity -= pSource->GetPlacement(iX, iY); BelowDensity += pSource->GetPlacement(iX, iY + 8); BYTE pix = pSource->_GetPix(iX, iY); // Sky if (!pix) { Surface32->SetPixDw(iX, iY, 0x00ffffff); continue; } // get density int iOwnDens = pSource->_GetPlacement(iX, iY); if (!iOwnDens) continue; iOwnDens *= 2; iOwnDens += pSource->GetPlacement(iX + 1, iY) + pSource->GetPlacement(iX - 1, iY); iOwnDens /= 4; // get texture map entry for pixel const C4TexMapEntry *pTex = pTexs->GetEntry(PixCol2Tex(pix)); assert(pTex); // get texture contents DWORD dwBackClr = 0u; if (pTex) dwBackClr = pTex->GetPattern().PatternClr(iX, iY); // get density of surrounding materials int iCompareDens = AboveDensity / 8; if (iOwnDens > iCompareDens) { // apply light LightenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens))); } else if (iOwnDens < iCompareDens && iOwnDens < 30) { DarkenClrBy(dwBackClr, std::min(30, 2 * (iCompareDens - iOwnDens))); } iCompareDens = BelowDensity / 8; if (iOwnDens > iCompareDens) { DarkenClrBy(dwBackClr, std::min(30, 2 * (iOwnDens - iCompareDens))); } Surface32->SetPixDw(iX, iY, dwBackClr); } } Surface32->Unlock(); }
void C4LandscapeRenderGL::BuildMatMap(uint32_t *pTex) { // TODO: Still merely an inefficient placeholder for things to come... // Build material-texture map (depth parameter where to find appropriate texture) for(int pix = 0; pix < 256; pix++) { // Look up indexed entry const C4TexMapEntry *pEntry = pTexs->GetEntry(PixCol2Tex(BYTE(pix))); if(!pEntry->GetTextureName()) { // Undefined textures transparent pTex[2*pix] = 0; pTex[2*pix+1] = RGBA(0,0,0,255); continue; } // Got animation? int iPhases = 1; const char *p = pEntry->GetTextureName(); while((p = strchr(p, '-'))) { p++; iPhases++; } // Hard-coded hack. Fix me! C4Material *pMaterial = pEntry->GetMaterial(); const int iPhaseLength = pMaterial->AnimationSpeed; float phase = 0; if (iPhases > 1) { phase = C4TimeMilliseconds::Now().AsInt() % (iPhases * iPhaseLength); phase /= iPhaseLength; } // Find our transition const char *pFrom = pEntry->GetTextureName(); float gTexCoo = 0; for(int iP = 0;; iP++) { // Get next phase const char *pTo = strchr(pFrom, '-'); if(!pTo) pTo = pEntry->GetTextureName(); else pTo++; // Add transition if(iP == int(phase)) { StdStrBuf From, To; From.CopyUntil(pFrom, '-'); To.CopyUntil(pTo, '-'); // Find transition int iTrans; if ((iTrans = LookupTextureTransition(From.getData(), To.getData())) >= 0) gTexCoo = float(iTrans) + fmod(phase, 1.0f); else if ((iTrans = LookupTextureTransition(To.getData(), From.getData())) >= 0) gTexCoo = float(iTrans) + 1.0 - fmod(phase, 1.0f); break; } // Advance pFrom = pTo; } // Assign texture int iTexCoo = int((gTexCoo * 256.0 / iMaterialTextureDepth) + 0.5); pTex[2*pix] = RGBA( Clamp(pMaterial->LightEmit[0], 0, 255), Clamp(pMaterial->LightEmit[1], 0, 255), Clamp(pMaterial->LightEmit[2], 0, 255), iTexCoo); pTex[2*pix+1] = RGBA( Clamp(pMaterial->LightSpot[0], 0, 255), Clamp(pMaterial->LightSpot[1], 0, 255), Clamp(pMaterial->LightSpot[2], 0, 255), Clamp(pMaterial->LightAngle, 0, 255)); } }