void FFont::LoadTranslations() { unsigned int count = LastChar - FirstChar + 1; uint32_t usedcolors[256] = {}; uint8_t identity[256]; TArray<double> Luminosity; for (unsigned int i = 0; i < count; i++) { if (Chars[i].TranslatedPic) { FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage()); if (pic) { pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture RecordTextureColors(pic, usedcolors); } } } ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity); for (unsigned int i = 0; i < count; i++) { if(Chars[i].TranslatedPic) static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr); }
FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual) { Width = w; Height = h; bComplex = complex; bTextual = textual; Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size()); NumParts = parts.Size(); memcpy(Parts, parts.Data(), sizeof(TexPart) * parts.Size()); bUseGamePalette = false; if (!bComplex) { for (int i = 0; i < NumParts; i++) { if (!Parts[i].Image->UseGamePalette()) return; } bUseGamePalette = true; // only if all patches use the game palette. } }
void D3DObjectImage::EndCache(D3DDevice *d3d) { if (!_cache_enabled || _cache.Length() == 0) return; D3DShaderPack::Current()->SetVDecl(d3d, D3DShaderPack::VDECL_XYUVC); D3DShaderPack::Current()->SetVS(d3d, D3DShaderPack::VS_COPY_UV_COLOR); D3DShaderPack::Current()->SetPS(d3d, D3DShaderPack::PS_TEX_COLOR_FILTER); static TArray<Vertex> sorted; static TArray<GroupDesc> groups; sorted.Allocate(0); groups.Allocate(0); bool found = true; while (found) { found = false; int cur_id = -1; int num = 0; for (int i = 0; i < _cache.Length(); i++) { // We have processed this if (_cache[i]->_image_id < 0) continue; found = true; if (cur_id < 0) cur_id = _cache[i]->_image_id; if (_cache[i]->_image_id == cur_id) { if (!_cache[i]->_with_border) { Vertex *data = _cache[i]->MakeData(); sorted.Add(data[0]); sorted.Add(data[1]); sorted.Add(data[2]); sorted.Add(data[3]); sorted.Add(data[4]); sorted.Add(data[5]); _cache[i]->_image_id = -_cache[i]->_image_id - 1; num++; } else { Vertex *data = _cache[i]->MakeDataBorder(); int last_len = sorted.Length(); sorted.Allocate(last_len + 6 * 9); CopyMemory(&sorted[last_len], data, sizeof(Vertex) * 6 * 9); _cache[i]->_image_id = -_cache[i]->_image_id - 1; num += 9; } } } if (num > 0) { GroupDesc gd = {num, cur_id}; groups.Add(gd); } } // Restore ids for (int i = 0; i < _cache.Length(); i++) _cache[i]->_image_id = -_cache[i]->_image_id - 1; D3DVertexBufferCache::CacheEntryInfo ce_info; if (!D3DVertexBufferCache::Current()->InitBuffer(d3d, (BYTE *)sorted.Data(), sorted.Length() * sizeof(Vertex), ce_info)) { return; } D3DVertexBufferCache::Current()->SelectBufferToDevice(d3d, ce_info.id, sizeof(Vertex)); HRESULT hr; for (int i = 0, cur = 0; i < groups.Length(); i++) { if (FAILED(hr = D3DImageCache::Current()->SelectImageToDevice(d3d, groups[i].id))) { Log("Failed to select texture: %X", (DWORD)hr); } // d3d->GetDevice()->DrawPrimitiveUP(D3DPT_TRIANGLELIST, groups[i].num * 2, // &sorted[cur], sizeof(Vertex)); d3d->GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST, cur, groups[i].num * 2); cur += groups[i].num * 6; } DBG("Image cache drawn: %d items, %d groups", _cache.Length(), groups.Length()); _cache_enabled = false; }