void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) { FString patchname; int Mirror = 0; sc.MustGetString(); init.TexName = sc.String; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginX = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); part.OriginY = sc.Number; if (sc.CheckString("{")) { while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("flipx")) { Mirror |= 1; } else if (sc.Compare("flipy")) { Mirror |= 2; } else if (sc.Compare("rotate")) { sc.MustGetNumber(); sc.Number = (((sc.Number + 90)%360)-90); if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) { sc.ScriptError("Rotation must be a multiple of 90 degrees."); } part.Rotate = (sc.Number / 90) & 3; } else if (sc.Compare("Translation")) { int match; bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; sc.MustGetString(); match = sc.MatchString(maps); if (match >= 0) { part.Blend = BLEND_SPECIALCOLORMAP1 + match; } else if (sc.Compare("ICE")) { part.Blend = BLEND_ICEMAP; } else if (sc.Compare("DESATURATE")) { sc.MustGetStringName(","); sc.MustGetNumber(); part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); } else { sc.UnGet(); part.Translation = new FRemapTable; part.Translation->MakeIdentity(); do { sc.MustGetString(); part.Translation->AddToTranslation(sc.String); } while (sc.CheckString(",")); } } else if (sc.Compare("Colormap")) { float r1,g1,b1; float r2,g2,b2; sc.MustGetFloat(); r1 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); g1 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); b1 = (float)sc.Float; if (!sc.CheckString(",")) { part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); } else { sc.MustGetFloat(); r2 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); g2 = (float)sc.Float; sc.MustGetStringName(","); sc.MustGetFloat(); b2 = (float)sc.Float; part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); } } else if (sc.Compare("Blend")) { bComplex = true; if (part.Translation != NULL) delete part.Translation; part.Translation = NULL; part.Blend = 0; if (!sc.CheckNumber()) { sc.MustGetString(); part.Blend = V_GetColor(NULL, sc); } else { int r,g,b; r = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); g = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); b = sc.Number; //sc.MustGetStringName(","); This was never supposed to be here. part.Blend = MAKERGB(r, g, b); } // Blend.a may never be 0 here. if (sc.CheckString(",")) { sc.MustGetFloat(); if (sc.Float > 0.f) part.Blend.a = clamp<int>(int(sc.Float*255), 1, 254); else part.Blend = 0; } else part.Blend.a = 255; } else if (sc.Compare("alpha")) { sc.MustGetFloat(); part.Alpha = clamp<blend_t>(int(sc.Float * BLENDUNIT), 0, BLENDUNIT); // bComplex is not set because it is only needed when the style is not OP_COPY. } else if (sc.Compare("style")) { static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; sc.MustGetString(); part.op = sc.MustMatchString(styles); bComplex |= (part.op != OP_COPY); bTranslucentPatches = bComplex; } else if (sc.Compare("useoffsets")) { init.UseOffsets = true; } } } if (Mirror & 2) { part.Rotate = (part.Rotate + 2) & 3; Mirror ^= 1; } if (Mirror & 1) { part.Rotate |= 4; } }
void R_InitColormaps () { // [RH] Try and convert BOOM colormaps into blending values. // This is a really rough hack, but it's better than // not doing anything with them at all (right?) FakeCmap cm; R_DeinitColormaps(); cm.name[0] = 0; cm.blend = 0; fakecmaps.Push(cm); uint32_t NumLumps = Wads.GetNumLumps(); for (uint32_t i = 0; i < NumLumps; i++) { if (Wads.GetLumpNamespace(i) == ns_colormaps) { char name[9]; name[8] = 0; Wads.GetLumpName (name, i); if (Wads.CheckNumForName (name, ns_colormaps) == (int)i) { strncpy(cm.name, name, 8); cm.blend = 0; cm.lump = i; fakecmaps.Push(cm); } } } int rr = 0, gg = 0, bb = 0; for(int x=0;x<256;x++) { rr += GPalette.BaseColors[x].r; gg += GPalette.BaseColors[x].g; bb += GPalette.BaseColors[x].b; } rr >>= 8; gg >>= 8; bb >>= 8; int palette_brightness = (rr*77 + gg*143 + bb*35) / 255; // To calculate the blend it will just average the colors of the first map if (fakecmaps.Size() > 1) { uint8_t map[256]; for (unsigned j = 1; j < fakecmaps.Size(); j++) { if (Wads.LumpLength (fakecmaps[j].lump) >= 256) { int k, r, g, b; FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump); lump.Read(map, 256); r = g = b = 0; for (k = 0; k < 256; k++) { r += GPalette.BaseColors[map[k]].r; g += GPalette.BaseColors[map[k]].g; b += GPalette.BaseColors[map[k]].b; } r /= 256; g /= 256; b /= 256; // The calculated average is too dark so brighten it according to the palettes's overall brightness int maxcol = MAX<int>(MAX<int>(palette_brightness, r), MAX<int>(g, b)); fakecmaps[j].blend = PalEntry (255, r * 255 / maxcol, g * 255 / maxcol, b * 255 / maxcol); } } } // build default special maps (e.g. invulnerability) for (unsigned i = 0; i < countof(SpecialColormapParms); ++i) { AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1], SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0], SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]); } // desaturated colormaps. These are used for texture composition for(int m = 0; m < 31; m++) { uint8_t *shade = DesaturateColormap[m]; for (int c = 0; c < 256; c++) { int intensity = (GPalette.BaseColors[c].r * 77 + GPalette.BaseColors[c].g * 143 + GPalette.BaseColors[c].b * 37) / 256; int r = (GPalette.BaseColors[c].r * (31-m) + intensity *m) / 31; int g = (GPalette.BaseColors[c].g * (31-m) + intensity *m) / 31; int b = (GPalette.BaseColors[c].b * (31-m) + intensity *m) / 31; shade[c] = ColorMatcher.Pick(r, g, b); } } }
void R_InitColormaps () { // [RH] Try and convert BOOM colormaps into blending values. // This is a really rough hack, but it's better than // not doing anything with them at all (right?) FakeCmap cm; R_DeinitColormaps(); cm.name[0] = 0; cm.blend = 0; fakecmaps.Push(cm); DWORD NumLumps = Wads.GetNumLumps(); for (DWORD i = 0; i < NumLumps; i++) { if (Wads.GetLumpNamespace(i) == ns_colormaps) { char name[9]; name[8] = 0; Wads.GetLumpName (name, i); if (Wads.CheckNumForName (name, ns_colormaps) == (int)i) { strncpy(cm.name, name, 8); cm.blend = 0; cm.lump = i; fakecmaps.Push(cm); } } } realcolormaps = new BYTE[256*NUMCOLORMAPS*fakecmaps.Size()]; R_SetDefaultColormap ("COLORMAP"); if (fakecmaps.Size() > 1) { BYTE unremap[256], remap[256], mapin[256]; int i; unsigned j; memcpy (remap, GPalette.Remap, 256); memset (unremap, 0, 256); for (i = 0; i < 256; ++i) { unremap[remap[i]] = i; } remap[0] = 0; for (j = 1; j < fakecmaps.Size(); j++) { if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256) { int k, r, g, b; FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump); BYTE *const map = realcolormaps + NUMCOLORMAPS*256*j; for (k = 0; k < NUMCOLORMAPS; ++k) { BYTE *map2 = &map[k*256]; lump.Read (mapin, 256); map2[0] = 0; for (r = 1; r < 256; ++r) { map2[r] = remap[mapin[unremap[r]]]; } } r = g = b = 0; for (k = 0; k < 256; k++) { r += GPalette.BaseColors[map[k]].r; g += GPalette.BaseColors[map[k]].g; b += GPalette.BaseColors[map[k]].b; } fakecmaps[j].blend = PalEntry (255, r/256, g/256, b/256); } } } NormalLight.Color = PalEntry (255, 255, 255); NormalLight.Fade = 0; NormalLight.Maps = realcolormaps; NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps); numfakecmaps = fakecmaps.Size(); // build default special maps (e.g. invulnerability) for (unsigned i = 0; i < countof(SpecialColormapParms); ++i) { AddSpecialColormap(SpecialColormapParms[i].Start[0], SpecialColormapParms[i].Start[1], SpecialColormapParms[i].Start[2], SpecialColormapParms[i].End[0], SpecialColormapParms[i].End[1], SpecialColormapParms[i].End[2]); } // desaturated colormaps. These are used for texture composition for(int m = 0; m < 31; m++) { BYTE *shade = DesaturateColormap[m]; for (int c = 0; c < 256; c++) { int intensity = (GPalette.BaseColors[c].r * 77 + GPalette.BaseColors[c].g * 143 + GPalette.BaseColors[c].b * 37) / 256; int r = (GPalette.BaseColors[c].r * (31-m) + intensity *m) / 31; int g = (GPalette.BaseColors[c].g * (31-m) + intensity *m) / 31; int b = (GPalette.BaseColors[c].b * (31-m) + intensity *m) / 31; shade[c] = ColorMatcher.Pick(r, g, b); } } }