]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - wad.c
huge audit of dprints throughout engine, all notices of successfully
[xonotic/darkplaces.git] / wad.c
diff --git a/wad.c b/wad.c
index e5b53c353b39341b0e725f37316d016754b62052..23c0b6e6f13991133bc4014abdf3aeb2b98a009a 100644 (file)
--- a/wad.c
+++ b/wad.c
@@ -17,16 +17,29 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
-// wad.c
+
 
 #include "quakedef.h"
+#include "image.h"
+#include "wad.h"
 
-static int                     wad_numlumps;
-static lumpinfo_t      *wad_lumps;
-static qbyte                   *wad_base = NULL;
-static mempool_t       *wad_mempool = NULL;
+typedef struct mwad_s
+{
+       qfile_t *file;
+       int numlumps;
+       lumpinfo_t *lumps;
+}
+mwad_t;
 
-void SwapPic (qpic_t *pic);
+typedef struct wadstate_s
+{
+       unsigned char *gfx_base;
+       mwad_t gfx;
+       memexpandablearray_t hlwads;
+}
+wadstate_t;
+
+static wadstate_t wad;
 
 /*
 ==================
@@ -39,7 +52,7 @@ Space padding is so names can be printed nicely in tables.
 Can safely be performed in place.
 ==================
 */
-static void W_CleanupName (char *in, char *out)
+static void W_CleanupName (const char *in, char *out)
 {
        int             i;
        int             c;
@@ -59,93 +72,85 @@ static void W_CleanupName (char *in, char *out)
                out[i] = 0;
 }
 
-
-
-/*
-====================
-W_LoadWadFile
-====================
-*/
-void W_LoadWadFile (char *filename)
+static void W_SwapLumps(int numlumps, lumpinfo_t *lumps)
 {
-       lumpinfo_t              *lump_p;
-       wadinfo_t               *header;
-       int                             i;
-       int                             infotableofs;
-       void                    *temp;
-
-       temp = FS_LoadFile (filename, false);
-       if (!temp)
-               Sys_Error ("W_LoadWadFile: couldn't load %s", filename);
-
-       if (wad_mempool)
-               Mem_FreePool(&wad_mempool);
-       wad_mempool = Mem_AllocPool(filename);
-       wad_base = Mem_Alloc(wad_mempool, fs_filesize);
-
-       memcpy(wad_base, temp, fs_filesize);
-       Mem_Free(temp);
-
-       header = (wadinfo_t *)wad_base;
-
-       if (memcmp(header->identification, "WAD2", 4))
-               Sys_Error ("Wad file %s doesn't have WAD2 id\n",filename);
-
-       wad_numlumps = LittleLong(header->numlumps);
-       infotableofs = LittleLong(header->infotableofs);
-       wad_lumps = (lumpinfo_t *)(wad_base + infotableofs);
+       int i;
+       for (i = 0;i < numlumps;i++)
+       {
+               lumps[i].filepos = LittleLong(lumps[i].filepos);
+               lumps[i].disksize = LittleLong(lumps[i].disksize);
+               lumps[i].size = LittleLong(lumps[i].size);
+               W_CleanupName(lumps[i].name, lumps[i].name);
+       }
+}
 
-       for (i=0, lump_p = wad_lumps ; i<wad_numlumps ; i++,lump_p++)
+void W_UnloadAll(void)
+{
+       unsigned int i;
+       mwad_t *w;
+       // free gfx.wad if it is loaded
+       if (wad.gfx_base)
+               Mem_Free(wad.gfx_base);
+       wad.gfx_base = NULL;
+       // close all hlwad files and free their lumps data
+       for (i = 0;i < Mem_ExpandableArray_IndexRange(&wad.hlwads);i++)
        {
-               lump_p->filepos = LittleLong(lump_p->filepos);
-               lump_p->size = LittleLong(lump_p->size);
-               W_CleanupName (lump_p->name, lump_p->name);
-               if (lump_p->type == TYP_QPIC)
-                       SwapPic ( (qpic_t *)(wad_base + lump_p->filepos));
+               w = Mem_ExpandableArray_RecordAtIndex(&wad.hlwads, i);
+               if (!w)
+                       continue;
+               if (w->file)
+                       FS_Close(w->file);
+               w->file = NULL;
+               if (w->lumps)
+                       Mem_Free(w->lumps);
+               w->lumps = NULL;
        }
+       // free the hlwads array
+       Mem_ExpandableArray_FreeArray(&wad.hlwads);
+       // clear all state
+       memset(&wad, 0, sizeof(wad));
 }
 
-void *W_GetLumpName (char *name)
+unsigned char *W_GetLumpName(const char *name)
 {
-       int             i;
-       lumpinfo_t      *lump;
-       char    clean[16];
+       int i;
+       fs_offset_t filesize;
+       lumpinfo_t *lump;
+       char clean[16];
+       wadinfo_t *header;
+       int infotableofs;
 
        W_CleanupName (name, clean);
 
-       for (lump = wad_lumps, i = 0;i < wad_numlumps;i++, lump++)
-               if (!strcmp(clean, lump->name))
-                       return (void *)(wad_base + lump->filepos);
-
-       return NULL;
-}
-
-/*
-=============================================================================
-
-automatic byte swapping
+       if (!wad.gfx_base)
+       {
+               if ((wad.gfx_base = FS_LoadFile ("gfx.wad", cls.permanentmempool, false, &filesize)))
+               {
+                       if (memcmp(wad.gfx_base, "WAD2", 4))
+                       {
+                               Con_Print("gfx.wad doesn't have WAD2 id\n");
+                               Mem_Free(wad.gfx_base);
+                               wad.gfx_base = NULL;
+                       }
+                       else
+                       {
+                               header = (wadinfo_t *)wad.gfx_base;
+                               wad.gfx.numlumps = LittleLong(header->numlumps);
+                               infotableofs = LittleLong(header->infotableofs);
+                               wad.gfx.lumps = (lumpinfo_t *)(wad.gfx_base + infotableofs);
 
-=============================================================================
-*/
+                               // byteswap the gfx.wad lumps in place
+                               W_SwapLumps(wad.gfx.numlumps, wad.gfx.lumps);
+                       }
+               }
+       }
 
-void SwapPic (qpic_t *pic)
-{
-       pic->width = LittleLong(pic->width);
-       pic->height = LittleLong(pic->height);
+       for (lump = wad.gfx.lumps, i = 0;i < wad.gfx.numlumps;i++, lump++)
+               if (!strcmp(clean, lump->name))
+                       return (wad.gfx_base + lump->filepos);
+       return NULL;
 }
 
-// LordHavoc: added alternate WAD2/WAD3 system for HalfLife texture wads
-#define TEXWAD_MAXIMAGES 16384
-typedef struct
-{
-       char name[16];
-       qfile_t *file;
-       int position;
-       int size;
-} texwadlump_t;
-
-static texwadlump_t texwadlump[TEXWAD_MAXIMAGES];
-
 /*
 ====================
 W_LoadTextureWadFile
@@ -153,71 +158,72 @@ W_LoadTextureWadFile
 */
 void W_LoadTextureWadFile (char *filename, int complain)
 {
-       lumpinfo_t              *lumps, *lump_p;
        wadinfo_t               header;
-       int                             i, j;
        int                             infotableofs;
        qfile_t                 *file;
        int                             numlumps;
+       mwad_t                  *w;
 
-       file = FS_Open (filename, "rb", false);
+       file = FS_Open (filename, "rb", false, false);
        if (!file)
        {
                if (complain)
-                       Con_Printf ("W_LoadTextureWadFile: couldn't find %s", filename);
+                       Con_Printf("W_LoadTextureWadFile: couldn't find %s\n", filename);
                return;
        }
 
        if (FS_Read(file, &header, sizeof(wadinfo_t)) != sizeof(wadinfo_t))
-       {Con_Printf ("W_LoadTextureWadFile: unable to read wad header");return;}
+       {Con_Print("W_LoadTextureWadFile: unable to read wad header\n");FS_Close(file);file = NULL;return;}
 
        if(memcmp(header.identification, "WAD3", 4))
-       {Con_Printf ("W_LoadTextureWadFile: Wad file %s doesn't have WAD3 id\n",filename);return;}
+       {Con_Printf("W_LoadTextureWadFile: Wad file %s doesn't have WAD3 id\n",filename);FS_Close(file);file = NULL;return;}
 
        numlumps = LittleLong(header.numlumps);
-       if (numlumps < 1 || numlumps > TEXWAD_MAXIMAGES)
-       {Con_Printf ("W_LoadTextureWadFile: invalid number of lumps (%i)\n", numlumps);return;}
+       if (numlumps < 1 || numlumps > 65536)
+       {Con_Printf("W_LoadTextureWadFile: invalid number of lumps (%i)\n", numlumps);FS_Close(file);file = NULL;return;}
        infotableofs = LittleLong(header.infotableofs);
        if (FS_Seek (file, infotableofs, SEEK_SET))
-       {Con_Printf ("W_LoadTextureWadFile: unable to seek to lump table");return;}
-       if (!(lumps = Mem_Alloc(tempmempool, sizeof(lumpinfo_t)*numlumps)))
-       {Con_Printf ("W_LoadTextureWadFile: unable to allocate temporary memory for lump table");return;}
+       {Con_Print("W_LoadTextureWadFile: unable to seek to lump table\n");FS_Close(file);file = NULL;return;}
 
-       if (FS_Read(file, lumps, sizeof(lumpinfo_t) * numlumps) != (int)sizeof(lumpinfo_t) * numlumps)
-       {Con_Printf ("W_LoadTextureWadFile: unable to read lump table");return;}
+       if (!wad.hlwads.mempool)
+               Mem_ExpandableArray_NewArray(&wad.hlwads, cls.permanentmempool, sizeof(mwad_t), 16);
+       w = Mem_ExpandableArray_AllocRecord(&wad.hlwads);
+       w->file = file;
+       w->numlumps = numlumps;
+       w->lumps = Mem_Alloc(cls.permanentmempool, w->numlumps * sizeof(lumpinfo_t));
 
-       for (i=0, lump_p = lumps ; i<numlumps ; i++,lump_p++)
+       if (!w->lumps)
        {
-               W_CleanupName (lump_p->name, lump_p->name);
-               for (j = 0;j < TEXWAD_MAXIMAGES;j++)
-               {
-                       if (texwadlump[j].name[0]) // occupied slot, check the name
-                       {
-                               if (!strcmp(lump_p->name, texwadlump[j].name)) // name match, replace old one
-                                       break;
-                       }
-                       else // empty slot
-                               break;
-               }
-               if (j >= TEXWAD_MAXIMAGES)
-                       break; // abort loading
-               W_CleanupName (lump_p->name, texwadlump[j].name);
-               texwadlump[j].file = file;
-               texwadlump[j].position = LittleLong(lump_p->filepos);
-               texwadlump[j].size = LittleLong(lump_p->disksize);
+               Con_Print("W_LoadTextureWadFile: unable to allocate temporary memory for lump table\n");
+               FS_Close(w->file);
+               w->file = NULL;
+               w->numlumps = 0;
+               return;
+       }
+
+       if (FS_Read(file, w->lumps, sizeof(lumpinfo_t) * w->numlumps) != (fs_offset_t)sizeof(lumpinfo_t) * numlumps)
+       {
+               Con_Print("W_LoadTextureWadFile: unable to read lump table\n");
+               FS_Close(w->file);
+               w->file = NULL;
+               w->numlumps = 0;
+               Mem_Free(w->lumps);
+               w->lumps = NULL;
+               return;
        }
-       Mem_Free(lumps);
+
+       W_SwapLumps(w->numlumps, w->lumps);
+
        // leaves the file open
 }
 
-
-qbyte *W_ConvertWAD3Texture(miptex_t *tex)
+unsigned char *W_ConvertWAD3TextureBGRA(miptex_t *tex)
 {
-       qbyte *in, *data, *out, *pal;
+       unsigned char *in, *data, *out, *pal;
        int d, p;
 
-       in = (qbyte *)((int) tex + tex->offsets[0]);
-       data = out = Mem_Alloc(tempmempool, tex->width * tex->height * 4);
+       in = (unsigned char *)tex + tex->offsets[0];
+       data = out = (unsigned char *)Mem_Alloc(tempmempool, tex->width * tex->height * 4);
        if (!data)
                return NULL;
        image_width = tex->width;
@@ -232,9 +238,9 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex)
                else
                {
                        p *= 3;
-                       out[0] = pal[p];
+                       out[2] = pal[p];
                        out[1] = pal[p+1];
-                       out[2] = pal[p+2];
+                       out[0] = pal[p+2];
                        out[3] = 255;
                }
                out += 4;
@@ -242,43 +248,45 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex)
        return data;
 }
 
-qbyte *W_GetTexture(char *name)
+unsigned char *W_GetTextureBGRA(char *name)
 {
-       char texname[17];
-       int i, j;
-       qfile_t *file;
+       unsigned int i, j, k;
        miptex_t *tex;
-       qbyte *data;
+       unsigned char *data;
+       mwad_t *w;
+       char texname[17];
 
        texname[16] = 0;
-       W_CleanupName (name, texname);
-       for (i = 0;i < TEXWAD_MAXIMAGES;i++)
+       W_CleanupName(name, texname);
+       if (!wad.hlwads.mempool)
+               Mem_ExpandableArray_NewArray(&wad.hlwads, cls.permanentmempool, sizeof(mwad_t), 16);
+       for (k = 0;k < Mem_ExpandableArray_IndexRange(&wad.hlwads);k++)
        {
-               if (texwadlump[i].name[0])
+               w = (mwad_t *)Mem_ExpandableArray_RecordAtIndex(&wad.hlwads, k);
+               if (!w)
+                       continue;
+               for (i = 0;i < (unsigned int)w->numlumps;i++)
                {
-                       if (!strcmp(texname, texwadlump[i].name)) // found it
+                       if (!strcmp(texname, w->lumps[i].name)) // found it
                        {
-                               file = texwadlump[i].file;
-                               if (FS_Seek(file, texwadlump[i].position, SEEK_SET))
-                               {Con_Printf("W_GetTexture: corrupt WAD3 file");return NULL;}
+                               if (FS_Seek(w->file, w->lumps[i].filepos, SEEK_SET))
+                               {Con_Print("W_GetTexture: corrupt WAD3 file\n");return NULL;}
 
-                               tex = Mem_Alloc(tempmempool, texwadlump[i].size);
+                               tex = (miptex_t *)Mem_Alloc(tempmempool, w->lumps[i].disksize);
                                if (!tex)
                                        return NULL;
-                               if (FS_Read(file, tex, texwadlump[i].size) < texwadlump[i].size)
-                               {Con_Printf("W_GetTexture: corrupt WAD3 file");return NULL;}
+                               if (FS_Read(w->file, tex, w->lumps[i].size) < w->lumps[i].disksize)
+                               {Con_Print("W_GetTexture: corrupt WAD3 file\n");return NULL;}
 
                                tex->width = LittleLong(tex->width);
                                tex->height = LittleLong(tex->height);
                                for (j = 0;j < MIPLEVELS;j++)
                                        tex->offsets[j] = LittleLong(tex->offsets[j]);
-                               data = W_ConvertWAD3Texture(tex);
+                               data = W_ConvertWAD3TextureBGRA(tex);
                                Mem_Free(tex);
                                return data;
                        }
                }
-               else
-                       break;
        }
        image_width = image_height = 0;
        return NULL;