/* * ================= * PF_setmodel * * setmodel(entity, model) * ================= */ static void PF_setmodel() { edict_t e = GetEdict(OFS.OFS_PARM0); int m_idx = GetInt(OFS.OFS_PARM1); string m = Progs.GetString(m_idx); // check to see if model was properly precached for (int i = 0; i < Server.sv.model_precache.Length; i++) { string check = Server.sv.model_precache[i]; if (check == null) { break; } if (check == m) { e.v.model = m_idx; // m - pr_strings; e.v.modelindex = i; model_t mod = Server.sv.models[(int)e.v.modelindex]; if (mod != null) { SetMinMaxSize(e, ref mod.mins, ref mod.maxs, true); } else { SetMinMaxSize(e, ref Common.ZeroVector, ref Common.ZeroVector, true); } return; } } Progs.RunError("no precache: {0}\n", m); }
public void Clear() { this.active = false; this.paused = false; this.loadgame = false; this.time = 0; this.lastcheck = 0; this.lastchecktime = 0; this.name = null; this.modelname = null; this.worldmodel = null; Array.Clear(this.model_precache, 0, this.model_precache.Length); Array.Clear(this.models, 0, this.models.Length); Array.Clear(this.sound_precache, 0, this.sound_precache.Length); Array.Clear(this.lightstyles, 0, this.lightstyles.Length); this.num_edicts = 0; this.max_edicts = 0; this.edicts = null; this.state = 0; this.datagram.Clear(); this.reliable_datagram.Clear(); this.signon.Clear(); }
public void Clear() { this.forcelink = false; this.update_type = 0; this.baseline = entity_state_t.Empty; this.msgtime = 0; this.msg_origins[0] = Vector3.Zero; this.msg_origins[1] = Vector3.Zero; this.origin = Vector3.Zero; this.msg_angles[0] = Vector3.Zero; this.msg_angles[1] = Vector3.Zero; this.angles = Vector3.Zero; this.model = null; this.efrag = null; this.frame = 0; this.syncbase = 0; this.colormap = null; this.effects = 0; this.skinnum = 0; this.visframe = 0; this.dlightframe = 0; this.dlightbits = 0; this.trivial_accept = 0; this.topnode = null; }
public void CopyFrom(model_t src) { this.name = src.name; this.needload = src.needload; this.type = src.type; this.numframes = src.numframes; this.synctype = src.synctype; this.flags = src.flags; this.mins = src.mins; this.maxs = src.maxs; this.radius = src.radius; this.clipbox = src.clipbox; this.clipmins = src.clipmins; this.clipmaxs = src.clipmaxs; this.firstmodelsurface = src.firstmodelsurface; this.nummodelsurfaces = src.nummodelsurfaces; this.numsubmodels = src.numsubmodels; this.submodels = src.submodels; this.numplanes = src.numplanes; this.planes = src.planes; this.numleafs = src.numleafs; this.leafs = src.leafs; this.numvertexes = src.numvertexes; this.vertexes = src.vertexes; this.numedges = src.numedges; this.edges = src.edges; this.numnodes = src.numnodes; this.nodes = src.nodes; this.numtexinfo = src.numtexinfo; this.texinfo = src.texinfo; this.numsurfaces = src.numsurfaces; this.surfaces = src.surfaces; this.numsurfedges = src.numsurfedges; this.surfedges = src.surfedges; this.numclipnodes = src.numclipnodes; this.clipnodes = src.clipnodes; this.nummarksurfaces = src.nummarksurfaces; this.marksurfaces = src.marksurfaces; for (int i = 0; i < src.hulls.Length; i++) { this.hulls[i].CopyFrom(src.hulls[i]); } this.numtextures = src.numtextures; this.textures = src.textures; this.visdata = src.visdata; this.lightdata = src.lightdata; this.entities = src.entities; this.cache = src.cache; }
public void Clear() { this.movemessages = 0; this.cmd.Clear(); Array.Clear(this.stats, 0, this.stats.Length); this.items = 0; Array.Clear(this.item_gettime, 0, this.item_gettime.Length); this.faceanimtime = 0; foreach (cshift_t cs in this.cshifts) cs.Clear(); foreach (cshift_t cs in this.prev_cshifts) cs.Clear(); this.mviewangles[0] = Vector3.Zero; this.mviewangles[1] = Vector3.Zero; this.viewangles = Vector3.Zero; this.mvelocity[0] = Vector3.Zero; this.mvelocity[1] = Vector3.Zero; this.velocity = Vector3.Zero; this.punchangle = Vector3.Zero; this.idealpitch = 0; this.pitchvel = 0; this.nodrift = false; this.driftmove = 0; this.laststop = 0; this.viewheight = 0; this.crouch = 0; this.paused = false; this.onground = false; this.inwater = false; this.intermission = 0; this.completed_time = 0; this.mtime[0] = 0; this.mtime[1] = 0; this.time = 0; this.oldtime = 0; this.last_received_message = 0; Array.Clear(this.model_precache, 0, this.model_precache.Length); Array.Clear(this.sound_precache, 0, this.sound_precache.Length); this.levelname = null; this.viewentity = 0; this.maxclients = 0; this.gametype = 0; this.worldmodel = null; this.free_efrags = null; this.num_entities = 0; this.num_statics = 0; this.viewent.Clear(); this.cdtrack = 0; this.looptrack = 0; this.scores = null; }
public void Clear() { this.entity = 0; this.model = null; this.endtime = 0; this.start = Vector3.Zero; this.end = Vector3.Zero; }
static void SetupSubModel(model_t mod, ref dmodel_t submodel) { mod.hulls[0].firstclipnode = submodel.headnode[0]; for (int j = 1; j < BspFile.MAX_MAP_HULLS; j++) { mod.hulls[j].firstclipnode = submodel.headnode[j]; mod.hulls[j].lastclipnode = mod.numclipnodes - 1; } mod.firstmodelsurface = submodel.firstface; mod.nummodelsurfaces = submodel.numfaces; Common.Copy(submodel.maxs, out mod.maxs); // mod.maxs = submodel.maxs; Common.Copy(submodel.mins, out mod.mins); // mod.mins = submodel.mins; mod.radius = RadiusFromBounds(ref mod.mins, ref mod.maxs); mod.numleafs = submodel.visleafs; }
/// <summary> /// GL_BuildLightmaps /// Builds the lightmap texture with all the surfaces from all brush models /// </summary> static void BuildLightMaps() { Array.Clear(_Allocated, 0, _Allocated.Length); //memset (allocated, 0, sizeof(allocated)); _FrameCount = 1; // no dlightcache if (_LightMapTextures == 0) _LightMapTextures = Drawer.GenerateTextureNumberRange(MAX_LIGHTMAPS); Drawer.LightMapFormat = PixelFormat.Luminance;// GL_LUMINANCE; // default differently on the Permedia if (Scr.IsPermedia) Drawer.LightMapFormat = PixelFormat.Rgba; if (Common.HasParam("-lm_1")) Drawer.LightMapFormat = PixelFormat.Luminance; if (Common.HasParam("-lm_a")) Drawer.LightMapFormat = PixelFormat.Alpha; //if (Common.HasParam("-lm_i")) // Drawer.LightMapFormat = PixelFormat.Intensity; //if (Common.HasParam("-lm_2")) // Drawer.LightMapFormat = PixelFormat.Rgba4; if (Common.HasParam("-lm_4")) Drawer.LightMapFormat = PixelFormat.Rgba; switch (Drawer.LightMapFormat) { case PixelFormat.Rgba: _LightMapBytes = 4; break; //case PixelFormat.Rgba4: //_LightMapBytes = 2; //break; case PixelFormat.Luminance: //case PixelFormat.Intensity: case PixelFormat.Alpha: _LightMapBytes = 1; break; } for (int j = 1; j < QDef.MAX_MODELS; j++) { model_t m = Client.cl.model_precache[j]; if (m == null) break; if (m.name != null && m.name.StartsWith("*")) continue; _CurrentVertBase = m.vertexes; _CurrentModel = m; for (int i = 0; i < m.numsurfaces; i++) { CreateSurfaceLightmap(m.surfaces[i]); if ((m.surfaces[i].flags & Surf.SURF_DRAWTURB) != 0) continue; if ((m.surfaces[i].flags & Surf.SURF_DRAWSKY) != 0) continue; BuildSurfaceDisplayList(m.surfaces[i]); } } if (_glTexSort.Value == 0) Drawer.SelectTexture(MTexTarget.TEXTURE1_SGIS); // // upload all lightmaps that were filled // GCHandle handle = GCHandle.Alloc(_LightMaps, GCHandleType.Pinned); try { IntPtr ptr = handle.AddrOfPinnedObject(); long lmAddr = ptr.ToInt64(); for (int i = 0; i < MAX_LIGHTMAPS; i++) { if (_Allocated[i, 0] == 0) break; // no more used _LightMapModified[i] = false; _LightMapRectChange[i].l = BLOCK_WIDTH; _LightMapRectChange[i].t = BLOCK_HEIGHT; _LightMapRectChange[i].w = 0; _LightMapRectChange[i].h = 0; Drawer.Bind(_LightMapTextures + i); Drawer.SetTextureFilters(TextureMinFilter.Linear, TextureMagFilter.Linear); long addr = lmAddr + i * BLOCK_WIDTH * BLOCK_HEIGHT * _LightMapBytes; GL.TexImage2D(TextureTarget.Texture2D, 0, (PixelInternalFormat)_LightMapBytes, BLOCK_WIDTH, BLOCK_HEIGHT, 0, Drawer.LightMapFormat, PixelType.UnsignedByte, new IntPtr(addr)); } } finally { handle.Free(); } if (_glTexSort.Value == 0) Drawer.SelectTexture(MTexTarget.TEXTURE0_SGIS); }
/// <summary> /// Mod_LoadSpriteModel /// </summary> public static void LoadSpriteModel(model_t mod, byte[] buffer) { dsprite_t pin = Sys.BytesToStructure<dsprite_t>(buffer, 0); int version = Common.LittleLong(pin.version); if (version != SPRITE_VERSION) Sys.Error("{0} has wrong version number ({1} should be {2})", mod.name, version, SPRITE_VERSION); int numframes = Common.LittleLong(pin.numframes); msprite_t psprite = new msprite_t(); // Uze: sprite models are not cached so mod.cache = new cache_user_t(); mod.cache.data = psprite; psprite.type = Common.LittleLong(pin.type); psprite.maxwidth = Common.LittleLong(pin.width); psprite.maxheight = Common.LittleLong(pin.height); psprite.beamlength = Common.LittleFloat(pin.beamlength); mod.synctype = (synctype_t)Common.LittleLong((int)pin.synctype); psprite.numframes = numframes; mod.mins.X = mod.mins.Y = -psprite.maxwidth / 2; mod.maxs.X = mod.maxs.Y = psprite.maxwidth / 2; mod.mins.Z = -psprite.maxheight / 2; mod.maxs.Z = psprite.maxheight / 2; // // load the frames // if (numframes < 1) Sys.Error("Mod_LoadSpriteModel: Invalid # of frames: {0}\n", numframes); mod.numframes = numframes; int frameOffset = dsprite_t.SizeInBytes; psprite.frames = new mspriteframedesc_t[numframes]; for (int i = 0; i < numframes; i++) { spriteframetype_t frametype = (spriteframetype_t)BitConverter.ToInt32(buffer, frameOffset); frameOffset += 4; psprite.frames[i].type = frametype; if (frametype == spriteframetype_t.SPR_SINGLE) { frameOffset = LoadSpriteFrame(new ByteArraySegment(buffer, frameOffset), out psprite.frames[i].frameptr, i); } else { frameOffset = LoadSpriteGroup(new ByteArraySegment(buffer, frameOffset), out psprite.frames[i].frameptr, i); } } mod.type = modtype_t.mod_sprite; }
/// <summary> /// Mod_LoadModel /// Loads a model into the cache /// </summary> public static model_t LoadModel(model_t mod, bool crash) { if (!mod.needload) { if (mod.type == modtype_t.mod_alias) { if (Cache.Check(mod.cache) != null) return mod; } else return mod; // not cached at all } // // load the file // byte[] buf = Common.LoadFile(mod.name); if (buf == null) { if (crash) Sys.Error("Mod_NumForName: {0} not found", mod.name); return null; } // // allocate a new model // _LoadModel = mod; // // fill it in // // call the apropriate loader mod.needload = false; switch (BitConverter.ToUInt32(buf, 0))// LittleLong(*(unsigned *)buf)) { case IDPOLYHEADER: LoadAliasModel(mod, buf); break; case IDSPRITEHEADER: LoadSpriteModel(mod, buf); break; default: LoadBrushModel(mod, buf); break; } return mod; }
/// <summary> /// Mod_LoadBrushModel /// </summary> public static void LoadBrushModel(model_t mod, byte[] buffer) { mod.type = modtype_t.mod_brush; dheader_t header = Sys.BytesToStructure<dheader_t>(buffer, 0); int i = Common.LittleLong(header.version); if (i != BspFile.BSPVERSION) Sys.Error("Mod_LoadBrushModel: {0} has wrong version number ({1} should be {2})", mod.name, i, BspFile.BSPVERSION); header.version = i; // swap all the lumps _ModBase = buffer; for (i = 0; i < header.lumps.Length; i++) { header.lumps[i].filelen = Common.LittleLong(header.lumps[i].filelen); header.lumps[i].fileofs = Common.LittleLong(header.lumps[i].fileofs); } // load into heap LoadVertexes(ref header.lumps[Lumps.LUMP_VERTEXES]); LoadEdges(ref header.lumps[Lumps.LUMP_EDGES]); LoadSurfEdges(ref header.lumps[Lumps.LUMP_SURFEDGES]); LoadTextures(ref header.lumps[Lumps.LUMP_TEXTURES]); LoadLighting(ref header.lumps[Lumps.LUMP_LIGHTING]); LoadPlanes(ref header.lumps[Lumps.LUMP_PLANES]); LoadTexInfo(ref header.lumps[Lumps.LUMP_TEXINFO]); LoadFaces(ref header.lumps[Lumps.LUMP_FACES]); LoadMarkSurfaces(ref header.lumps[Lumps.LUMP_MARKSURFACES]); LoadVisibility(ref header.lumps[Lumps.LUMP_VISIBILITY]); LoadLeafs(ref header.lumps[Lumps.LUMP_LEAFS]); LoadNodes(ref header.lumps[Lumps.LUMP_NODES]); LoadClipNodes(ref header.lumps[Lumps.LUMP_CLIPNODES]); LoadEntities(ref header.lumps[Lumps.LUMP_ENTITIES]); LoadSubModels(ref header.lumps[Lumps.LUMP_MODELS]); MakeHull0(); mod.numframes = 2; // regular and alternate animation // // set up the submodels (FIXME: this is confusing) // for (i = 0; i < mod.numsubmodels; i++) { SetupSubModel(mod, ref mod.submodels[i]); if (i < mod.numsubmodels - 1) { // duplicate the basic information string name = "*" + (i + 1).ToString(); _LoadModel = FindName(name); _LoadModel.CopyFrom(mod); // *loadmodel = *mod; _LoadModel.name = name; //strcpy (loadmodel->name, name); mod = _LoadModel; //mod = loadmodel; } } }
/// <summary> /// Mod_LoadAliasModel /// </summary> public static void LoadAliasModel(model_t mod, byte[] buffer) { mdl_t pinmodel = Sys.BytesToStructure<mdl_t>(buffer, 0); int version = Common.LittleLong(pinmodel.version); if (version != ALIAS_VERSION) Sys.Error("{0} has wrong version number ({1} should be {2})", mod.name, version, ALIAS_VERSION); // // allocate space for a working header, plus all the data except the frames, // skin and group info // _Header = new aliashdr_t(); mod.flags = Common.LittleLong(pinmodel.flags); // // endian-adjust and copy the data, starting with the alias model header // _Header.boundingradius = Common.LittleFloat(pinmodel.boundingradius); _Header.numskins = Common.LittleLong(pinmodel.numskins); _Header.skinwidth = Common.LittleLong(pinmodel.skinwidth); _Header.skinheight = Common.LittleLong(pinmodel.skinheight); if (_Header.skinheight > MAX_LBM_HEIGHT) Sys.Error("model {0} has a skin taller than {1}", mod.name, MAX_LBM_HEIGHT); _Header.numverts = Common.LittleLong(pinmodel.numverts); if (_Header.numverts <= 0) Sys.Error("model {0} has no vertices", mod.name); if (_Header.numverts > MAXALIASVERTS) Sys.Error("model {0} has too many vertices", mod.name); _Header.numtris = Common.LittleLong(pinmodel.numtris); if (_Header.numtris <= 0) Sys.Error("model {0} has no triangles", mod.name); _Header.numframes = Common.LittleLong(pinmodel.numframes); int numframes = _Header.numframes; if (numframes < 1) Sys.Error("Mod_LoadAliasModel: Invalid # of frames: {0}\n", numframes); _Header.size = Common.LittleFloat(pinmodel.size) * ALIAS_BASE_SIZE_RATIO; mod.synctype = (synctype_t)Common.LittleLong((int)pinmodel.synctype); mod.numframes = _Header.numframes; _Header.scale = Common.LittleVector(Common.ToVector(ref pinmodel.scale)); _Header.scale_origin = Common.LittleVector(Common.ToVector(ref pinmodel.scale_origin)); _Header.eyeposition = Common.LittleVector(Common.ToVector(ref pinmodel.eyeposition)); // // load the skins // int offset = LoadAllSkins(_Header.numskins, new ByteArraySegment(buffer, mdl_t.SizeInBytes)); // // load base s and t vertices // int stvOffset = offset; // in bytes for (int i = 0; i < _Header.numverts; i++, offset += stvert_t.SizeInBytes) { _STVerts[i] = Sys.BytesToStructure<stvert_t>(buffer, offset); _STVerts[i].onseam = Common.LittleLong(_STVerts[i].onseam); _STVerts[i].s = Common.LittleLong(_STVerts[i].s); _STVerts[i].t = Common.LittleLong(_STVerts[i].t); } // // load triangle lists // int triOffset = stvOffset + _Header.numverts * stvert_t.SizeInBytes; offset = triOffset; for (int i = 0; i < _Header.numtris; i++, offset += dtriangle_t.SizeInBytes) { _Triangles[i] = Sys.BytesToStructure<dtriangle_t>(buffer, offset); _Triangles[i].facesfront = Common.LittleLong(_Triangles[i].facesfront); for (int j = 0; j < 3; j++) _Triangles[i].vertindex[j] = Common.LittleLong(_Triangles[i].vertindex[j]); } // // load the frames // _PoseNum = 0; int framesOffset = triOffset + _Header.numtris * dtriangle_t.SizeInBytes; _Header.frames = new maliasframedesc_t[_Header.numframes]; for (int i = 0; i < numframes; i++) { aliasframetype_t frametype = (aliasframetype_t)BitConverter.ToInt32(buffer, framesOffset); framesOffset += 4; if (frametype == aliasframetype_t.ALIAS_SINGLE) { framesOffset = LoadAliasFrame(new ByteArraySegment(buffer, framesOffset), ref _Header.frames[i]); } else { framesOffset = LoadAliasGroup(new ByteArraySegment(buffer, framesOffset), ref _Header.frames[i]); } } _Header.numposes = _PoseNum; mod.type = modtype_t.mod_alias; // FIXME: do this right mod.mins = -Vector3.One * 16.0f; mod.maxs = -mod.mins; // // build the draw lists // Mesh.MakeAliasModelDisplayLists(mod, _Header); // // move the complete, relocatable alias model to the cache // mod.cache = Cache.Alloc(aliashdr_t.SizeInBytes * _Header.frames.Length * maliasframedesc_t.SizeInBytes, null); if (mod.cache == null) return; mod.cache.data = _Header; }
/// <summary> /// Mod_LeafPVS /// </summary> public static byte[] LeafPVS(mleaf_t leaf, model_t model) { if (leaf == model.leafs[0]) return _Novis; return DecompressVis(leaf.compressed_vis, leaf.visofs, model); }
/// <summary> /// Mod_Init /// </summary> public static void Init() { if (_glSubDivideSize == null) { _glSubDivideSize = new Cvar("gl_subdivide_size", "128", true); } for (int i = 0; i < _Known.Length; i++) _Known[i] = new model_t(); Common.FillArray(_Novis, (byte)0xff); }
/// <summary> /// Mod_Extradata /// handles caching /// </summary> public static aliashdr_t GetExtraData(model_t mod) { object r = Cache.Check(mod.cache); if (r != null) return (aliashdr_t)r; LoadModel(mod, true); if (mod.cache.data == null) Sys.Error("Mod_Extradata: caching failed"); return (aliashdr_t)mod.cache.data; }
static int[] _VertexOrder = new int[MAX_COMMANDS]; // vertexorder #endregion Fields #region Methods /// <summary> /// GL_MakeAliasModelDisplayLists /// </summary> public static void MakeAliasModelDisplayLists(model_t m, aliashdr_t hdr) { _AliasModel = m; _AliasHdr = hdr; // // look for a cached version // string path = Path.ChangeExtension("glquake/" + Path.GetFileNameWithoutExtension(m.name), ".ms2"); DisposableWrapper<BinaryReader> file; Common.FOpenFile(path, out file); if (file != null) { using (file) { BinaryReader reader = file.Object; _NumCommands = reader.ReadInt32(); _NumOrder = reader.ReadInt32(); for (int i = 0; i < _NumCommands; i++) _Commands[i] = reader.ReadInt32(); for (int i = 0; i < _NumOrder; i++) _VertexOrder[i] = reader.ReadInt32(); } } else { // // build it from scratch // Con.Print("meshing {0}...\n", m.name); BuildTris(); // trifans or lists // // save out the cached version // string fullpath = Path.Combine(Common.GameDir, path); Stream fs = Sys.FileOpenWrite(fullpath, true); if (fs != null) using (BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII)) { writer.Write(_NumCommands); writer.Write(_NumOrder); for (int i = 0; i < _NumCommands; i++) writer.Write(_Commands[i]); for (int i = 0; i < _NumOrder; i++) writer.Write(_VertexOrder[i]); } } // // save the data out // _AliasHdr.poseverts = _NumOrder; int[] cmds = new int[_NumCommands]; //Hunk_Alloc (numcommands * 4); _AliasHdr.commands = cmds; // in bytes??? // (byte*)cmds - (byte*)paliashdr; Buffer.BlockCopy(_Commands, 0, cmds, 0, _NumCommands * 4); //memcpy (cmds, commands, numcommands * 4); trivertx_t[][] poseverts = Mod.PoseVerts; trivertx_t[] verts = new trivertx_t[_AliasHdr.numposes * _AliasHdr.poseverts]; // Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); _AliasHdr.posedata = verts; // (byte*)verts - (byte*)paliashdr; int offset = 0; for (int i = 0; i < _AliasHdr.numposes; i++) for (int j = 0; j < _NumOrder; j++) { verts[offset++] = poseverts[i][_VertexOrder[j]]; // *verts++ = poseverts[i][vertexorder[j]]; } }
/// <summary> /// CL_ParseBeam /// </summary> static void ParseBeam(model_t m) { int ent = Net.Reader.ReadShort(); Vector3 start = Net.Reader.ReadCoords(); Vector3 end = Net.Reader.ReadCoords(); // override any beam with the same entity for (int i = 0; i < MAX_BEAMS; i++) { beam_t b = _Beams[i]; if (b.entity == ent) { b.entity = ent; b.model = m; b.endtime = (float)(cl.time + 0.2); b.start = start; b.end = end; return; } } // find a free beam for (int i = 0; i < MAX_BEAMS; i++) { beam_t b = _Beams[i]; if (b.model == null || b.endtime < cl.time) { b.entity = ent; b.model = m; b.endtime = (float)(cl.time + 0.2); b.start = start; b.end = end; return; } } Con.Print("beam list overflow!\n"); }
/// <summary> /// Mod_PointInLeaf /// </summary> public static mleaf_t PointInLeaf(ref Vector3 p, model_t model) { if (model == null || model.nodes == null) Sys.Error("Mod_PointInLeaf: bad model"); mleaf_t result = null; mnodebase_t node = model.nodes[0]; while (true) { if (node.contents < 0) { result = (mleaf_t)node; break; } mnode_t n = (mnode_t)node; mplane_t plane = n.plane; float d = Vector3.Dot(p, plane.normal) - plane.dist; if (d > 0) node = n.children[0]; else node = n.children[1]; } return result; }
/// <summary> /// Mod_DecompressVis /// </summary> private static byte[] DecompressVis(byte[] p, int startIndex, model_t model) { int row = (model.numleafs + 7) >> 3; int offset = 0; if (p == null) { // no vis info, so make all visible while (row != 0) { _Decompressed[offset++] = 0xff; row--; } return _Decompressed; } int srcOffset = startIndex; do { if (p[srcOffset] != 0)// (*in) { _Decompressed[offset++] = p[srcOffset++]; // *out++ = *in++; continue; } int c = p[srcOffset + 1];// in[1]; srcOffset += 2; // in += 2; while (c != 0) { _Decompressed[offset++] = 0; // *out++ = 0; c--; } } while (offset < row); // out - decompressed < row return _Decompressed; }