diff --git a/src/client/refresh/files/maps.c b/src/client/refresh/files/maps.c index 78eb7bc2..a9e665ec 100644 --- a/src/client/refresh/files/maps.c +++ b/src/client/refresh/files/maps.c @@ -417,19 +417,12 @@ Mod_CalcSurfaceExtents(const int *surfedges, mvertex_t *vertexes, medge_t *edges } } -/* -================= -Mod_LoadTexinfo - -extra for skybox in soft render -================= -*/ void -Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo, +Mod_LoadTexinfoRBSP(const char *name, mtexinfo_t **texinfo, int *numtexinfo, const byte *mod_base, const lump_t *l, findimage_t find_image, struct image_s *notexture, maptype_t maptype) { - texinfo_t *in; + texrinfo_t *in; mtexinfo_t *out, *step; int i, count; @@ -442,6 +435,7 @@ Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo, } count = l->filelen / sizeof(*in); + /* extra for skybox in soft render */ out = Hunk_Alloc((count + EXTRA_LUMP_TEXINFO) * sizeof(*out)); *texinfo = out; @@ -498,6 +492,105 @@ Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo, } } +void +Mod_LoadTexinfoQ2(const char *name, mtexinfo_t **texinfo, int *numtexinfo, + const byte *mod_base, const lump_t *l, findimage_t find_image, + struct image_s *notexture, maptype_t maptype) +{ + texinfo_t *in; + mtexinfo_t *out, *step; + int i, count; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, name); + } + + count = l->filelen / sizeof(*in); + /* extra for skybox in soft render */ + out = Hunk_Alloc((count + EXTRA_LUMP_TEXINFO) * sizeof(*out)); + + *texinfo = out; + *numtexinfo = count; + + for ( i=0 ; ivecs[0][j] = LittleFloat(in->vecs[0][j]); + out->vecs[1][j] = LittleFloat(in->vecs[1][j]); + } + + /* Convert flags for game type */ + out->flags = Mod_LoadSurfConvertFlags(LittleLong(in->flags), maptype); + + next = LittleLong(in->nexttexinfo); + if (next > 0) + { + out->next = *texinfo + next; + } + else + { + /* + * Fix for the problem where the game + * domed core when loading a new level. + */ + out->next = NULL; + } + + image = GetTexImage(in->texture, find_image); + if (!image) + { + R_Printf(PRINT_ALL, "%s: Couldn't load %s\n", + __func__, in->texture); + image = notexture; + } + + out->image = image; + } + + // count animation frames + for (i=0 ; inumframes = 1; + for (step = out->next ; step && step != out ; step=step->next) + { + out->numframes++; + } + } +} + +/* +================= +Mod_LoadTexinfo + +extra for skybox in soft render +================= +*/ +void +Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexinfo, + const byte *mod_base, const lump_t *l, findimage_t find_image, + struct image_s *notexture, maptype_t maptype) +{ + if (maptype == map_sin) + { + Mod_LoadTexinfoRBSP(name, texinfo, numtexinfo, mod_base, l, find_image, + notexture, maptype); + } + else + { + Mod_LoadTexinfoQ2(name, texinfo, numtexinfo, mod_base, l, find_image, + notexture, maptype); + } +} + /* ================= Mod_LoadEdges @@ -1283,6 +1376,80 @@ calcTexinfoAndFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl return ret; } +static int +calcRBSPTexinfoAndFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl) +{ + drface_t* face_in = (void *)(mod_base + fl->fileofs); + const texrinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs); + + if (fl->filelen % sizeof(*face_in) || tl->filelen % sizeof(*texinfo_in)) + { + // will error out when actually loading it + return 0; + } + + int ret = 0; + + int face_count = fl->filelen / sizeof(*face_in); + int texinfo_count = tl->filelen / sizeof(*texinfo_in); + + { + int baseSize = (face_count + EXTRA_LUMP_FACES) * sizeof(msurface_t); + baseSize = (baseSize + 31) & ~31; + ret += baseSize; + + int ti_size = texinfo_count * sizeof(mtexinfo_t); + ti_size = (ti_size + 31) & ~31; + ret += ti_size; + } + + int numWarpFaces = 0; + + for (int surfnum = 0; surfnum < face_count; surfnum++, face_in++) + { + int numverts = LittleShort(face_in->numedges); + int ti = LittleShort(face_in->texinfo); + if ((ti < 0) || (ti >= texinfo_count)) + { + return 0; // will error out + } + int texFlags = LittleLong(texinfo_in[ti].flags); + + /* set the drawing flags */ + if (texFlags & SURF_WARP) + { + if (numverts > 60) + return 0; // will error out in R_SubdividePolygon() + + // R_SubdivideSurface(out, loadmodel); /* cut up polygon for warps */ + // for each (pot. recursive) call to R_SubdividePolygon(): + // sizeof(mpoly_t) + ((numverts - 4) + 2) * sizeof(mvtx_t) + + // this is tricky, how much is allocated depends on the size of the surface + // which we don't know (we'd need the vertices etc to know, but we can't load + // those without allocating...) + // so we just count warped faces and use a generous estimate below + + ++numWarpFaces; + } + else + { + // LM_BuildPolygonFromSurface(out); + // => poly = Hunk_Alloc(sizeof(mpoly_t) + (numverts - 4) * sizeof(mvtx_t)); + int polySize = sizeof(mpoly_t) + (numverts - 4) * sizeof(mvtx_t); + polySize = (polySize + 31) & ~31; + ret += polySize; + } + } + + // yeah, this is a bit hacky, but it looks like for each warped face + // 256-55000 bytes are allocated (usually on the lower end), + // so just assume 48k per face to be safe + ret += numWarpFaces * 49152; + + return ret; +} + static int calcTexinfoAndQFacesSize(const byte *mod_base, const lump_t *fl, const lump_t *tl) { @@ -1371,8 +1538,18 @@ Mod_CalcNonModelLumpHunkSize(const byte *mod_base, const dheader_t *header, { hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_EDGES], sizeof(dedge_t), sizeof(medge_t), EXTRA_LUMP_EDGES); - hunkSize += calcTexinfoAndFacesSize(mod_base, - &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]); + + if (maptype == map_sin) + { + hunkSize += calcRBSPTexinfoAndFacesSize(mod_base, + &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]); + } + else + { + hunkSize += calcTexinfoAndFacesSize(mod_base, + &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]); + } + hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFFACES], sizeof(short), sizeof(msurface_t *), 0); // yes, out is indeed a pointer! diff --git a/src/client/refresh/gl1/gl1_model.c b/src/client/refresh/gl1/gl1_model.c index 81296502..c910fd55 100644 --- a/src/client/refresh/gl1/gl1_model.c +++ b/src/client/refresh/gl1/gl1_model.c @@ -307,6 +307,134 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, LM_EndBuildingLightmaps(); } +static void +Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, + const bspx_header_t *bspx_header) +{ + int i, count, surfnum, lminfosize; + const dlminfo_t *lminfos; + msurface_t *out; + drface_t *in; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, loadmodel->name); + } + + count = l->filelen / sizeof(*in); + out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base); + if ((lminfos != NULL) && + (lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces)) + { + R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n", + __func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces); + lminfos = NULL; + } + + LM_BeginBuildingLightmaps(loadmodel); + + for (surfnum = 0; surfnum < count; surfnum++, in++, out++) + { + int side, ti, planenum, lightofs; + + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + + if (out->numedges < 3) + { + Com_Error(ERR_DROP, "%s: Surface with %d edges", + __func__, out->numedges); + } + out->flags = 0; + out->polys = NULL; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + + if (side) + { + out->flags |= SURF_PLANEBACK; + } + + if (planenum < 0 || planenum >= loadmodel->numplanes) + { + Com_Error(ERR_DROP, "%s: Incorrect %d planenum.", + __func__, planenum); + } + out->plane = loadmodel->planes + planenum; + + ti = LittleShort(in->texinfo); + + if ((ti < 0) || (ti >= loadmodel->numtexinfo)) + { + Com_Error(ERR_DROP, "%s: bad texinfo number", + __func__); + } + + out->texinfo = loadmodel->texinfo + ti; + + lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out); + if (lightofs < 0) { + memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs)); + out->lmshift = DEFAULT_LMSHIFT; + out->lmvlen[0] = 1.0f; + out->lmvlen[1] = 1.0f; + + Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); + + lightofs = in->lightofs; + } + + Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata, + out, in->styles, lightofs); + + /* set the drawing flags */ + if (out->texinfo->flags & SURF_WARP) + { + out->flags |= SURF_DRAWTURB; + + for (i = 0; i < 2; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + + R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); /* cut up polygon for warps */ + } + + if (r_fixsurfsky->value) + { + if (out->texinfo->flags & SURF_SKY) + { + out->flags |= SURF_DRAWSKY; + } + } + + /* create lightmaps and polygons */ + if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP))) + { + LM_CreateSurfaceLightmap(out); + } + + if (!(out->texinfo->flags & SURF_WARP)) + { + LM_BuildPolygonFromSurface(loadmodel, out); + } + } + + LM_EndBuildingLightmaps(); +} + static void Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, const bspx_header_t *bspx_header) @@ -530,7 +658,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) if ((header->ident == IDBSPHEADER) || (header->ident == RBSPHEADER)) { - Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + if (maptype == map_sin) + { + Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } + else + { + Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } } else { diff --git a/src/client/refresh/gl3/gl3_model.c b/src/client/refresh/gl3/gl3_model.c index c9f22a62..be6361ed 100644 --- a/src/client/refresh/gl3/gl3_model.c +++ b/src/client/refresh/gl3/gl3_model.c @@ -308,6 +308,134 @@ Mod_LoadFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l, LM_EndBuildingLightmaps(); } +static void +Mod_LoadRFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l, + const bspx_header_t *bspx_header) +{ + int i, count, surfnum, lminfosize; + const dlminfo_t *lminfos; + msurface_t *out; + drface_t *in; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, loadmodel->name); + } + + count = l->filelen / sizeof(*in); + out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base); + if ((lminfos != NULL) && + (lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces)) + { + R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n", + __func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces); + lminfos = NULL; + } + + LM_BeginBuildingLightmaps(loadmodel); + + for (surfnum = 0; surfnum < count; surfnum++, in++, out++) + { + int side, ti, planenum, lightofs; + + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + + if (out->numedges < 3) + { + Com_Error(ERR_DROP, "%s: Surface with %d edges", + __func__, out->numedges); + } + out->flags = 0; + out->polys = NULL; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + + if (side) + { + out->flags |= SURF_PLANEBACK; + } + + if (planenum < 0 || planenum >= loadmodel->numplanes) + { + Com_Error(ERR_DROP, "%s: Incorrect %d planenum.", + __func__, planenum); + } + out->plane = loadmodel->planes + planenum; + + ti = LittleShort(in->texinfo); + + if ((ti < 0) || (ti >= loadmodel->numtexinfo)) + { + Com_Error(ERR_DROP, "%s: bad texinfo number", + __func__); + } + + out->texinfo = loadmodel->texinfo + ti; + + lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out); + if (lightofs < 0) { + memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs)); + out->lmshift = DEFAULT_LMSHIFT; + out->lmvlen[0] = 1.0f; + out->lmvlen[1] = 1.0f; + + Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); + + lightofs = in->lightofs; + } + + Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata, + out, in->styles, lightofs); + + /* set the drawing flags */ + if (out->texinfo->flags & SURF_WARP) + { + out->flags |= SURF_DRAWTURB; + + for (i = 0; i < 2; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + + R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); /* cut up polygon for warps */ + } + + if (r_fixsurfsky->value) + { + if (out->texinfo->flags & SURF_SKY) + { + out->flags |= SURF_DRAWSKY; + } + } + + /* create lightmaps and polygons */ + if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP))) + { + LM_CreateSurfaceLightmap(out); + } + + if (!(out->texinfo->flags & SURF_WARP)) + { + LM_BuildPolygonFromSurface(loadmodel, out); + } + } + + LM_EndBuildingLightmaps(); +} + static void Mod_LoadQFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l, const bspx_header_t *bspx_header) @@ -531,7 +659,14 @@ Mod_LoadBrushModel(gl3model_t *mod, const void *buffer, int modfilelen) if ((header->ident == IDBSPHEADER) || (header->ident == RBSPHEADER)) { - Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + if (maptype == map_sin) + { + Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } + else + { + Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } } else { diff --git a/src/client/refresh/gl4/gl4_model.c b/src/client/refresh/gl4/gl4_model.c index 045e998c..8905ba95 100644 --- a/src/client/refresh/gl4/gl4_model.c +++ b/src/client/refresh/gl4/gl4_model.c @@ -308,6 +308,134 @@ Mod_LoadFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l, LM_EndBuildingLightmaps(); } +static void +Mod_LoadRFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l, + const bspx_header_t *bspx_header) +{ + int i, count, surfnum, lminfosize; + const dlminfo_t *lminfos; + msurface_t *out; + drface_t *in; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, loadmodel->name); + } + + count = l->filelen / sizeof(*in); + out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base); + if ((lminfos != NULL) && + (lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces)) + { + R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n", + __func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces); + lminfos = NULL; + } + + LM_BeginBuildingLightmaps(loadmodel); + + for (surfnum = 0; surfnum < count; surfnum++, in++, out++) + { + int side, ti, planenum, lightofs; + + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + + if (out->numedges < 3) + { + Com_Error(ERR_DROP, "%s: Surface with %d edges", + __func__, out->numedges); + } + out->flags = 0; + out->polys = NULL; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + + if (side) + { + out->flags |= SURF_PLANEBACK; + } + + if (planenum < 0 || planenum >= loadmodel->numplanes) + { + Com_Error(ERR_DROP, "%s: Incorrect %d planenum.", + __func__, planenum); + } + out->plane = loadmodel->planes + planenum; + + ti = LittleShort(in->texinfo); + + if ((ti < 0) || (ti >= loadmodel->numtexinfo)) + { + Com_Error(ERR_DROP, "%s: bad texinfo number", + __func__); + } + + out->texinfo = loadmodel->texinfo + ti; + + lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out); + if (lightofs < 0) { + memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs)); + out->lmshift = DEFAULT_LMSHIFT; + out->lmvlen[0] = 1.0f; + out->lmvlen[1] = 1.0f; + + Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); + + lightofs = in->lightofs; + } + + Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata, + out, in->styles, lightofs); + + /* set the drawing flags */ + if (out->texinfo->flags & SURF_WARP) + { + out->flags |= SURF_DRAWTURB; + + for (i = 0; i < 2; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + + R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); /* cut up polygon for warps */ + } + + if (r_fixsurfsky->value) + { + if (out->texinfo->flags & SURF_SKY) + { + out->flags |= SURF_DRAWSKY; + } + } + + /* create lightmaps and polygons */ + if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP))) + { + LM_CreateSurfaceLightmap(out); + } + + if (!(out->texinfo->flags & SURF_WARP)) + { + LM_BuildPolygonFromSurface(loadmodel, out); + } + } + + LM_EndBuildingLightmaps(); +} + static void Mod_LoadQFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l, const bspx_header_t *bspx_header) @@ -531,7 +659,14 @@ Mod_LoadBrushModel(gl4model_t *mod, const void *buffer, int modfilelen) if ((header->ident == IDBSPHEADER) || (header->ident == RBSPHEADER)) { - Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + if (maptype == map_sin) + { + Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } + else + { + Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } } else { diff --git a/src/client/refresh/soft/sw_model.c b/src/client/refresh/soft/sw_model.c index 58dc8cb8..2ead2ed8 100644 --- a/src/client/refresh/soft/sw_model.c +++ b/src/client/refresh/soft/sw_model.c @@ -303,6 +303,125 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, } } +static void +Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, + const bspx_header_t *bspx_header) +{ + int i, count, surfnum; + msurface_t *out; + drface_t *in; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, loadmodel->name); + } + + count = l->filelen / sizeof(*in); + out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + for (surfnum = 0; surfnum < count; surfnum++, in++, out++) + { + int side, ti, planenum, lightofs; + + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleLong(in->numedges); + + if (out->numedges < 3) + { + Com_Error(ERR_DROP, "%s: Surface with %d edges", + __func__, out->numedges); + } + out->flags = 0; + out->polys = NULL; + + planenum = LittleLong(in->planenum); + side = LittleLong(in->side); + + if (side) + { + out->flags |= SURF_PLANEBACK; + } + + if (planenum < 0 || planenum >= loadmodel->numplanes) + { + Com_Error(ERR_DROP, "%s: Incorrect %d planenum.", + __func__, planenum); + } + out->plane = loadmodel->planes + planenum; + + ti = LittleLong(in->texinfo); + + if ((ti < 0) || (ti >= loadmodel->numtexinfo)) + { + Com_Error(ERR_DROP, "%s: bad texinfo number", + __func__); + } + + out->texinfo = loadmodel->texinfo + ti; + + lightofs = -1; + if (lightofs < 0) { + memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs)); + out->lmshift = DEFAULT_LMSHIFT; + out->lmvlen[0] = 1.0f; + out->lmvlen[1] = 1.0f; + + Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); + + lightofs = in->lightofs; + } + + Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata, + out, in->styles, in->lightofs); + + if (!out->texinfo->image) + continue; + + if (r_fixsurfsky->value) + { + if (out->texinfo->flags & SURF_SKY) + { + out->flags |= SURF_DRAWSKY; + continue; + } + } + + /* set the drawing flags */ + if (out->texinfo->flags & SURF_WARP) + { + out->flags |= SURF_DRAWTURB; + + for (i = 0; i < 2; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + continue; + } + + //============== + // this marks flowing surfaces as turbulent. + if (out->texinfo->flags & SURF_FLOWING) + { + out->flags |= SURF_DRAWTURB; + for (i=0 ; i<2 ; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + continue; + } + //============== + } +} + static void Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, const bspx_header_t *bspx_header) @@ -517,7 +636,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) if ((header->ident == IDBSPHEADER) || (header->ident == RBSPHEADER)) { - Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + if (maptype == map_sin) + { + Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } + else + { + Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } } else { diff --git a/src/client/refresh/vk/vk_model.c b/src/client/refresh/vk/vk_model.c index 44f084c3..190f196c 100644 --- a/src/client/refresh/vk/vk_model.c +++ b/src/client/refresh/vk/vk_model.c @@ -282,6 +282,134 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, LM_EndBuildingLightmaps(); } +static void +Mod_LoadRFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, + const bspx_header_t *bspx_header) +{ + int i, count, surfnum, lminfosize; + const dlminfo_t *lminfos; + msurface_t *out; + drface_t *in; + + in = (void *)(mod_base + l->fileofs); + + if (l->filelen % sizeof(*in)) + { + Com_Error(ERR_DROP, "%s: funny lump size in %s", + __func__, loadmodel->name); + } + + count = l->filelen / sizeof(*in); + out = Hunk_Alloc((count + EXTRA_LUMP_FACES) * sizeof(*out)); + + loadmodel->surfaces = out; + loadmodel->numsurfaces = count; + + lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base); + if ((lminfos != NULL) && + (lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces)) + { + R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size " YQ2_COM_PRIdS " does not match surface count %d\n", + __func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces); + lminfos = NULL; + } + + LM_BeginBuildingLightmaps(loadmodel); + + for (surfnum = 0; surfnum < count; surfnum++, in++, out++) + { + int side, ti, planenum, lightofs; + + out->firstedge = LittleLong(in->firstedge); + out->numedges = LittleShort(in->numedges); + + if (out->numedges < 3) + { + Com_Error(ERR_DROP, "%s: Surface with %d edges", + __func__, out->numedges); + } + out->flags = 0; + out->polys = NULL; + + planenum = LittleShort(in->planenum); + side = LittleShort(in->side); + + if (side) + { + out->flags |= SURF_PLANEBACK; + } + + if (planenum < 0 || planenum >= loadmodel->numplanes) + { + Com_Error(ERR_DROP, "%s: Incorrect %d planenum.", + __func__, planenum); + } + out->plane = loadmodel->planes + planenum; + + ti = LittleShort(in->texinfo); + + if ((ti < 0) || (ti >= loadmodel->numtexinfo)) + { + Com_Error(ERR_DROP, "%s: bad texinfo number", + __func__); + } + + out->texinfo = loadmodel->texinfo + ti; + + lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out); + if (lightofs < 0) { + memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs)); + out->lmshift = DEFAULT_LMSHIFT; + out->lmvlen[0] = 1.0f; + out->lmvlen[1] = 1.0f; + + Mod_CalcSurfaceExtents(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); + + lightofs = in->lightofs; + } + + Mod_LoadSetSurfaceLighting(loadmodel->lightdata, loadmodel->numlightdata, + out, in->styles, lightofs); + + /* set the drawing flags */ + if (out->texinfo->flags & SURF_WARP) + { + out->flags |= SURF_DRAWTURB; + + for (i = 0; i < 2; i++) + { + out->extents[i] = 16384; + out->texturemins[i] = -8192; + } + + R_SubdivideSurface(loadmodel->surfedges, loadmodel->vertexes, + loadmodel->edges, out); /* cut up polygon for warps */ + } + + if (r_fixsurfsky->value) + { + if (out->texinfo->flags & SURF_SKY) + { + out->flags |= SURF_DRAWSKY; + } + } + + /* create lightmaps and polygons */ + if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP))) + { + LM_CreateSurfaceLightmap(out); + } + + if (!(out->texinfo->flags & SURF_WARP)) + { + LM_BuildPolygonFromSurface(loadmodel, out); + } + } + + LM_EndBuildingLightmaps(); +} + static void Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l, const bspx_header_t *bspx_header) @@ -505,7 +633,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen) if ((header->ident == IDBSPHEADER) || (header->ident == RBSPHEADER)) { - Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + if (maptype == map_sin) + { + Mod_LoadRFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } + else + { + Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header); + } } else {