📄 cm.java
字号:
/* * Copyright (C) 1997-2001 Id Software, Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. * */// Created on 02.01.2004 by RST.// $Id: CM.java,v 1.12 2005/12/04 21:00:17 cawe Exp $package jake2.qcommon;import jake2.Defines;import jake2.Globals;import jake2.game.*;import jake2.util.*;import java.io.RandomAccessFile;import java.nio.*;import java.util.Arrays;public class CM { public static class cnode_t { cplane_t plane; // ptr int children[] = { 0, 0 }; // negative numbers are leafs } public static class cbrushside_t { cplane_t plane; // ptr mapsurface_t surface; // ptr } public static class cleaf_t { int contents; int cluster; int area; // was unsigned short, but is ok (rst) short firstleafbrush; // was unsigned short, but is ok (rst) short numleafbrushes; } public static class cbrush_t { int contents; int numsides; int firstbrushside; int checkcount; // to avoid repeated testings } public static class carea_t { int numareaportals; int firstareaportal; int floodnum; // if two areas have equal floodnums, they are connected int floodvalid; } static int checkcount; static String map_name = ""; static int numbrushsides; static cbrushside_t map_brushsides[] = new cbrushside_t[Defines.MAX_MAP_BRUSHSIDES]; static { for (int n = 0; n < Defines.MAX_MAP_BRUSHSIDES; n++) map_brushsides[n] = new cbrushside_t(); } public static int numtexinfo; public static mapsurface_t map_surfaces[] = new mapsurface_t[Defines.MAX_MAP_TEXINFO]; static { for (int n = 0; n < Defines.MAX_MAP_TEXINFO; n++) map_surfaces[n] = new mapsurface_t(); } static int numplanes; /** Extra for box hull ( +6) */ static cplane_t map_planes[] = new cplane_t[Defines.MAX_MAP_PLANES + 6]; static { for (int n = 0; n < Defines.MAX_MAP_PLANES + 6; n++) map_planes[n] = new cplane_t(); } static int numnodes; /** Extra for box hull ( +6) */ static cnode_t map_nodes[] = new cnode_t[Defines.MAX_MAP_NODES + 6]; static { for (int n = 0; n < Defines.MAX_MAP_NODES + 6; n++) map_nodes[n] = new cnode_t(); } static int numleafs = 1; // allow leaf funcs to be called without a map static cleaf_t map_leafs[] = new cleaf_t[Defines.MAX_MAP_LEAFS]; static { for (int n = 0; n < Defines.MAX_MAP_LEAFS; n++) map_leafs[n] = new cleaf_t(); } static int emptyleaf, solidleaf; static int numleafbrushes; public static int map_leafbrushes[] = new int[Defines.MAX_MAP_LEAFBRUSHES]; public static int numcmodels; public static cmodel_t map_cmodels[] = new cmodel_t[Defines.MAX_MAP_MODELS]; static { for (int n = 0; n < Defines.MAX_MAP_MODELS; n++) map_cmodels[n] = new cmodel_t(); } public static int numbrushes; public static cbrush_t map_brushes[] = new cbrush_t[Defines.MAX_MAP_BRUSHES]; static { for (int n = 0; n < Defines.MAX_MAP_BRUSHES; n++) map_brushes[n] = new cbrush_t(); } public static int numvisibility; public static byte map_visibility[] = new byte[Defines.MAX_MAP_VISIBILITY]; /** Main visibility data. */ public static qfiles.dvis_t map_vis = new qfiles.dvis_t(ByteBuffer .wrap(map_visibility)); public static int numentitychars; public static String map_entitystring; public static int numareas = 1; public static carea_t map_areas[] = new carea_t[Defines.MAX_MAP_AREAS]; static { for (int n = 0; n < Defines.MAX_MAP_AREAS; n++) map_areas[n] = new carea_t(); } public static int numareaportals; public static qfiles.dareaportal_t map_areaportals[] = new qfiles.dareaportal_t[Defines.MAX_MAP_AREAPORTALS]; static { for (int n = 0; n < Defines.MAX_MAP_AREAPORTALS; n++) map_areaportals[n] = new qfiles.dareaportal_t(); } public static int numclusters = 1; public static mapsurface_t nullsurface = new mapsurface_t(); public static int floodvalid; public static boolean portalopen[] = new boolean[Defines.MAX_MAP_AREAPORTALS]; public static cvar_t map_noareas; public static byte cmod_base[]; public static int checksum; public static int last_checksum; /** * Loads in the map and all submodels. */ public static cmodel_t CM_LoadMap(String name, boolean clientload, int checksum[]) { Com.DPrintf("CM_LoadMap(" + name + ")...\n"); byte buf[]; int i; qfiles.dheader_t header; int length; map_noareas = Cvar.Get("map_noareas", "0", 0); if (map_name.equals(name) && (clientload || 0 == Cvar.VariableValue("flushmap"))) { checksum[0] = last_checksum; if (!clientload) { Arrays.fill(portalopen, false); FloodAreaConnections(); } return map_cmodels[0]; // still have the right version } // free old stuff numnodes = 0; numleafs = 0; numcmodels = 0; numvisibility = 0; numentitychars = 0; map_entitystring = ""; map_name = ""; if (name == null || name.length() == 0) { numleafs = 1; numclusters = 1; numareas = 1; checksum[0] = 0; return map_cmodels[0]; // cinematic servers won't have anything at all } // // load the file // buf = FS.LoadFile(name); if (buf == null) Com.Error(Defines.ERR_DROP, "Couldn't load " + name); length = buf.length; ByteBuffer bbuf = ByteBuffer.wrap(buf); last_checksum = MD4.Com_BlockChecksum(buf, length); checksum[0] = last_checksum; header = new qfiles.dheader_t(bbuf.slice()); if (header.version != Defines.BSPVERSION) Com.Error(Defines.ERR_DROP, "CMod_LoadBrushModel: " + name + " has wrong version number (" + header.version + " should be " + Defines.BSPVERSION + ")"); cmod_base = buf; // load into heap CMod_LoadSurfaces(header.lumps[Defines.LUMP_TEXINFO]); // ok CMod_LoadLeafs(header.lumps[Defines.LUMP_LEAFS]); CMod_LoadLeafBrushes(header.lumps[Defines.LUMP_LEAFBRUSHES]); CMod_LoadPlanes(header.lumps[Defines.LUMP_PLANES]); CMod_LoadBrushes(header.lumps[Defines.LUMP_BRUSHES]); CMod_LoadBrushSides(header.lumps[Defines.LUMP_BRUSHSIDES]); CMod_LoadSubmodels(header.lumps[Defines.LUMP_MODELS]); CMod_LoadNodes(header.lumps[Defines.LUMP_NODES]); CMod_LoadAreas(header.lumps[Defines.LUMP_AREAS]); CMod_LoadAreaPortals(header.lumps[Defines.LUMP_AREAPORTALS]); CMod_LoadVisibility(header.lumps[Defines.LUMP_VISIBILITY]); CMod_LoadEntityString(header.lumps[Defines.LUMP_ENTITIES]); FS.FreeFile(buf); CM_InitBoxHull(); Arrays.fill(portalopen, false); FloodAreaConnections(); map_name = name; return map_cmodels[0]; } /** Loads Submodels. */ public static void CMod_LoadSubmodels(lump_t l) { Com.DPrintf("CMod_LoadSubmodels()\n"); qfiles.dmodel_t in; cmodel_t out; int i, j, count; if ((l.filelen % qfiles.dmodel_t.SIZE) != 0) Com.Error(Defines.ERR_DROP, "CMod_LoadBmodel: funny lump size"); count = l.filelen / qfiles.dmodel_t.SIZE; if (count < 1) Com.Error(Defines.ERR_DROP, "Map with no models"); if (count > Defines.MAX_MAP_MODELS) Com.Error(Defines.ERR_DROP, "Map has too many models"); Com.DPrintf(" numcmodels=" + count + "\n"); numcmodels = count; if (debugloadmap) { Com.DPrintf("submodles(headnode, <origin>, <mins>, <maxs>)\n"); } for (i = 0; i < count; i++) { in = new qfiles.dmodel_t(ByteBuffer.wrap(cmod_base, i * qfiles.dmodel_t.SIZE + l.fileofs, qfiles.dmodel_t.SIZE)); out = map_cmodels[i]; for (j = 0; j < 3; j++) { // spread the mins / maxs by a pixel out.mins[j] = in.mins[j] - 1; out.maxs[j] = in.maxs[j] + 1; out.origin[j] = in.origin[j]; } out.headnode = in.headnode; if (debugloadmap) { Com .DPrintf( "|%6i|%8.2f|%8.2f|%8.2f| %8.2f|%8.2f|%8.2f| %8.2f|%8.2f|%8.2f|\n", new Vargs().add(out.headnode) .add(out.origin[0]).add(out.origin[1]) .add(out.origin[2]).add(out.mins[0]) .add(out.mins[1]).add(out.mins[2]).add( out.maxs[0]).add(out.maxs[1]) .add(out.maxs[2])); } } } static boolean debugloadmap = false; /** Loads surfaces. */ public static void CMod_LoadSurfaces(lump_t l) { Com.DPrintf("CMod_LoadSurfaces()\n"); texinfo_t in; mapsurface_t out; int i, count; if ((l.filelen % texinfo_t.SIZE) != 0) Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l.filelen / texinfo_t.SIZE; if (count < 1) Com.Error(Defines.ERR_DROP, "Map with no surfaces"); if (count > Defines.MAX_MAP_TEXINFO) Com.Error(Defines.ERR_DROP, "Map has too many surfaces"); numtexinfo = count; Com.DPrintf(" numtexinfo=" + count + "\n"); if (debugloadmap) Com.DPrintf("surfaces:\n"); for (i = 0; i < count; i++) { out = map_surfaces[i] = new mapsurface_t(); in = new texinfo_t(cmod_base, l.fileofs + i * texinfo_t.SIZE, texinfo_t.SIZE); out.c.name = in.texture; out.rname = in.texture; out.c.flags = in.flags; out.c.value = in.value; if (debugloadmap) { Com.DPrintf("|%20s|%20s|%6i|%6i|\n", new Vargs() .add(out.c.name).add(out.rname).add(out.c.value).add( out.c.flags)); } } } /** Loads nodes. */ public static void CMod_LoadNodes(lump_t l) { Com.DPrintf("CMod_LoadNodes()\n"); qfiles.dnode_t in; int child; cnode_t out; int i, j, count; if ((l.filelen % qfiles.dnode_t.SIZE) != 0) Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size:" + l.fileofs + "," + qfiles.dnode_t.SIZE); count = l.filelen / qfiles.dnode_t.SIZE; if (count < 1) Com.Error(Defines.ERR_DROP, "Map has no nodes"); if (count > Defines.MAX_MAP_NODES) Com.Error(Defines.ERR_DROP, "Map has too many nodes"); numnodes = count; Com.DPrintf(" numnodes=" + count + "\n"); if (debugloadmap) { Com.DPrintf("nodes(planenum, child[0], child[1])\n"); } for (i = 0; i < count; i++) { in = new qfiles.dnode_t(ByteBuffer.wrap(cmod_base, qfiles.dnode_t.SIZE * i + l.fileofs, qfiles.dnode_t.SIZE)); out = map_nodes[i]; out.plane = map_planes[in.planenum]; for (j = 0; j < 2; j++) { child = in.children[j]; out.children[j] = child; } if (debugloadmap) { Com.DPrintf("|%6i| %6i| %6i|\n", new Vargs().add(in.planenum) .add(out.children[0]).add(out.children[1])); } } } /** Loads brushes.*/ public static void CMod_LoadBrushes(lump_t l) { Com.DPrintf("CMod_LoadBrushes()\n"); qfiles.dbrush_t in; cbrush_t out; int i, count; if ((l.filelen % qfiles.dbrush_t.SIZE) != 0) Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l.filelen / qfiles.dbrush_t.SIZE; if (count > Defines.MAX_MAP_BRUSHES) Com.Error(Defines.ERR_DROP, "Map has too many brushes"); numbrushes = count; Com.DPrintf(" numbrushes=" + count + "\n"); if (debugloadmap) { Com.DPrintf("brushes:(firstbrushside, numsides, contents)\n"); } for (i = 0; i < count; i++) { in = new qfiles.dbrush_t(ByteBuffer.wrap(cmod_base, i * qfiles.dbrush_t.SIZE + l.fileofs, qfiles.dbrush_t.SIZE)); out = map_brushes[i]; out.firstbrushside = in.firstside; out.numsides = in.numsides; out.contents = in.contents;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -