⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hw_md2.c

📁 The source code of Doom legacy for windows
💻 C
字号:
// Emacs style mode select   -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: hw_md2.c,v 1.4 2000/10/04 16:21:57 hurdler Exp $//// Copyright (C) 1998-2000 by DooM Legacy Team.//// 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.////// $Log: hw_md2.c,v $// Revision 1.4  2000/10/04 16:21:57  hurdler// small clean-up//// Revision 1.3  2000/03/29 20:17:31  hurdler// no message//// Revision 1.2  2000/02/27 00:42:11  hurdler// fix CR+LF problem//// Revision 1.1.1.1  2000/02/22 20:32:33  hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION://      MD2 Handling//      Inspired from md2.c by Mete Ciragan (mete@swissquake.ch)////-----------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "hw_drv.h"#include "../doomdef.h"#include "../z_zone.h"//// load model//// Hurdler: the current path is the Legacy.exe pathmd2_model_t* md2_readModel (const char *filename){    FILE        *file;    md2_model_t *model;    byte        buffer[MD2_MAX_FRAMESIZE];    int         i;    model = (md2_model_t *) malloc (sizeof (md2_model_t));    if (!model)        return 0;    file = fopen (filename, "rb");    if (!file)    {        free (model);        return 0;    }    // initialize model and read header     memset (model, 0, sizeof (md2_model_t));    fread (&model->header, sizeof (md2_header_t), 1, file);    if (model->header.magic != (int) (('2' << 24) + ('P' << 16) + ('D' << 8) + 'I'))    {        fclose (file);        free (model);        return 0;    }    // read skins    fseek (file, model->header.offsetSkins, SEEK_SET);    if (model->header.numSkins > 0)    {        model->skins = (md2_skin_t *) malloc (sizeof (md2_skin_t) * model->header.numSkins);        if (!model->skins)        {            md2_freeModel (model);            return 0;        }        for (i = 0; i < model->header.numSkins; i++)            fread (&model->skins[i], sizeof (md2_skin_t), 1, file);    }    // read texture coordinates     fseek (file, model->header.offsetTexCoords, SEEK_SET);    if (model->header.numTexCoords > 0)    {        model->texCoords = (md2_textureCoordinate_t *) malloc (sizeof (md2_textureCoordinate_t) * model->header.numTexCoords);        if (!model->texCoords)        {            md2_freeModel (model);            return 0;        }        for (i = 0; i < model->header.numTexCoords; i++)            fread (&model->texCoords[i], sizeof (md2_textureCoordinate_t), 1, file);    }    // read triangles     fseek (file, model->header.offsetTriangles, SEEK_SET);    if (model->header.numTriangles > 0)    {        model->triangles = (md2_triangle_t *) malloc (sizeof (md2_triangle_t) * model->header.numTriangles);        if (!model->triangles)        {            md2_freeModel (model);            return 0;        }        for (i = 0; i < model->header.numTriangles; i++)            fread (&model->triangles[i], sizeof (md2_triangle_t), 1, file);    }    // read alias frames     fseek (file, model->header.offsetFrames, SEEK_SET);    if (model->header.numFrames > 0)    {        model->frames = (md2_frame_t *) malloc (sizeof (md2_frame_t) * model->header.numFrames);        if (!model->frames)        {            md2_freeModel (model);            return 0;        }        for (i = 0; i < model->header.numFrames; i++)        {            md2_alias_frame_t *frame = (md2_alias_frame_t *) buffer;            int j;            model->frames[i].vertices = (md2_triangleVertex_t *) malloc (sizeof (md2_triangleVertex_t) * model->header.numVertices);            if (!model->frames[i].vertices)            {                md2_freeModel (model);                return 0;            }            fread (frame, 1, model->header.frameSize, file);            strcpy (model->frames[i].name, frame->name);            for (j = 0; j < model->header.numVertices; j++)            {                model->frames[i].vertices[j].vertex[0] = (float) ((int) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];                model->frames[i].vertices[j].vertex[2] = -1* ((float) ((int) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]);                model->frames[i].vertices[j].vertex[1] = (float) ((int) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2];            }        }    }    // read gl commands     fseek (file, model->header.offsetGlCommands, SEEK_SET);    if (model->header.numGlCommands)    {        model->glCommandBuffer = (int *) malloc (sizeof (int) * model->header.numGlCommands);        if (!model->glCommandBuffer)        {            md2_freeModel (model);            return 0;        }        fread (model->glCommandBuffer, sizeof (int), model->header.numGlCommands, file);    }    fclose (file);    return model;}/* * free model */void md2_freeModel (md2_model_t *model){    if (model)    {        if (model->skins)            free (model->skins);        if (model->texCoords)            free (model->texCoords);        if (model->triangles)            free (model->triangles);        if (model->frames)        {            int i;            for (i = 0; i < model->header.numFrames; i++)            {                if (model->frames[i].vertices)                    free (model->frames[i].vertices);            }            free (model->frames);        }        if (model->glCommandBuffer)            free (model->glCommandBuffer);        free (model);    }}/* * center model */void md2_getBoundingBox (md2_model_t *model, float *minmax){    int i;    float minx, maxx;    float miny, maxy;    float minz, maxz;    minx = miny = minz = 999999.0f;    maxx = maxy = maxz = -999999.0f;    /* get bounding box */    for (i = 0; i < model->header.numVertices; i++)    {        md2_triangleVertex_t *v = &model->frames[0].vertices[i];        if (v->vertex[0] < minx)            minx = v->vertex[0];        else if (v->vertex[0] > maxx)            maxx = v->vertex[0];        if (v->vertex[1] < miny)            miny = v->vertex[1];        else if (v->vertex[1] > maxy)            maxy = v->vertex[1];        if (v->vertex[2] < minz)            minz = v->vertex[2];        else if (v->vertex[2] > maxz)            maxz = v->vertex[2];    }    minmax[0] = minx;    minmax[1] = maxx;    minmax[2] = miny;    minmax[3] = maxy;    minmax[4] = minz;    minmax[5] = maxz;}int md2_getAnimationCount (md2_model_t *model){    int i, j, pos;    int count;    int lastId;    char name[16], last[16];    strcpy (last, model->frames[0].name);    pos = strlen (last) - 1;    j = 0;    while (last[pos] >= '0' && last[pos] <= '9' && j < 2)    {        pos--;        j++;    }    last[pos + 1] = '\0';    lastId = 0;    count = 0;    for (i = 0; i <= model->header.numFrames; i++)    {        if (i == model->header.numFrames)            strcpy (name, ""); // some kind of a sentinel        else            strcpy (name, model->frames[i].name);        pos = strlen (name) - 1;        j = 0;        while (name[pos] >= '0' && name[pos] <= '9' && j < 2)        {            pos--;            j++;        }        name[pos + 1] = '\0';        if (strcmp (last, name))        {            strcpy (last, name);            count++;        }    }    return count;}const char * md2_getAnimationName (md2_model_t *model, int animation){    int i, j, pos;    int count;    int lastId;    static char last[32];    char name[32];    strcpy (last, model->frames[0].name);    pos = strlen (last) - 1;    j = 0;    while (last[pos] >= '0' && last[pos] <= '9' && j < 2)    {        pos--;        j++;    }    last[pos + 1] = '\0';    lastId = 0;    count = 0;    for (i = 0; i <= model->header.numFrames; i++)    {        if (i == model->header.numFrames)            strcpy (name, ""); // some kind of a sentinel        else            strcpy (name, model->frames[i].name);        pos = strlen (name) - 1;        j = 0;        while (name[pos] >= '0' && name[pos] <= '9' && j < 2)        {            pos--;            j++;        }        name[pos + 1] = '\0';        if (strcmp (last, name))        {            if (count == animation)                return last;            strcpy (last, name);            count++;        }    }    return 0;}void md2_getAnimationFrames (md2_model_t *model, int animation, int *startFrame, int *endFrame){    int i, j, pos;    int count, numFrames, frameCount;    int lastId;    char name[16], last[16];    strcpy (last, model->frames[0].name);    pos = strlen (last) - 1;    j = 0;    while (last[pos] >= '0' && last[pos] <= '9' && j < 2)    {        pos--;        j++;    }    last[pos + 1] = '\0';    lastId = 0;    count = 0;    numFrames = 0;    frameCount = 0;    for (i = 0; i <= model->header.numFrames; i++)    {        if (i == model->header.numFrames)            strcpy (name, ""); // some kind of a sentinel        else            strcpy (name, model->frames[i].name);        pos = strlen (name) - 1;        j = 0;        while (name[pos] >= '0' && name[pos] <= '9' && j < 2)        {            pos--;            j++;        }        name[pos + 1] = '\0';        if (strcmp (last, name))        {            strcpy (last, name);            if (count == animation)            {                *startFrame = frameCount - numFrames;                *endFrame = frameCount - 1;                return;            }            count++;            numFrames = 0;        }        frameCount++;        numFrames++;    }    *startFrame = *endFrame = 0;}void md2_printModelInfo (md2_model_t *model){    int i;    CONS_Printf ("magic:\t\t\t%c%c%c%c\n", model->header.magic>>24,                                           (model->header.magic>>16)&0xff,                                           (model->header.magic>>8)&0xff,                                            model->header.magic&0xff);    CONS_Printf ("version:\t\t%d\n", model->header.version);    CONS_Printf ("skinWidth:\t\t%d\n", model->header.skinWidth);    CONS_Printf ("skinHeight:\t\t%d\n", model->header.skinHeight);    CONS_Printf ("frameSize:\t\t%d\n", model->header.frameSize);    CONS_Printf ("numSkins:\t\t%d\n", model->header.numSkins);    CONS_Printf ("numVertices:\t\t%d\n", model->header.numVertices);    CONS_Printf ("numTexCoords:\t\t%d\n", model->header.numTexCoords);    CONS_Printf ("numTriangles:\t\t%d\n", model->header.numTriangles);    CONS_Printf ("numGlCommands:\t\t%d\n", model->header.numGlCommands);    CONS_Printf ("numFrames:\t\t%d\n", model->header.numFrames);    CONS_Printf ("offsetSkins:\t\t%d\n", model->header.offsetSkins);    CONS_Printf ("offsetTexCoords:\t%d\n", model->header.offsetTexCoords);    CONS_Printf ("offsetTriangles:\t%d\n", model->header.offsetTriangles);    CONS_Printf ("offsetFrames:\t\t%d\n", model->header.offsetFrames);    CONS_Printf ("offsetGlCommands:\t%d\n", model->header.offsetGlCommands);    CONS_Printf ("offsetEnd:\t\t%d\n", model->header.offsetEnd);    for (i = 0; i < model->header.numFrames; i++)        CONS_Printf ("%s ", model->frames[i].name);    CONS_Printf ("\n");}#define word shorttypedef struct{    byte manufacturer;       byte version;            byte encoding;        byte bitsPerPixel;    word xmin;    word ymin;    word xmax;    word ymax;    word hDpi;    word vDpi;    byte colorMap[48];    byte reserved;        byte numPlanes;       word bytesPerLine;    word paletteInfo;     word hScreenSize;      word vScreenSize;    byte filler[54];  } PcxHeader;GlidePatch_t md2_tex_patch;// -----------------+// md2_loadTexture  : Download a pcx texture for MD2 models// -----------------+int md2_loadTexture (const char *filename){        GlidePatch_t    *grpatch;    grpatch = &md2_tex_patch;    if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data)    {        PcxHeader       header;        unsigned char   palette[768];        unsigned char   *image;        int             w, h;        int             ptr = 0;        int             ch, rep;        int             size;        FILE            *file;         if (!(file = fopen (filename, "rb")))            return 0;        if (fread (&header, sizeof (PcxHeader), 1, file) == -1)        {            fclose (file);            return 0;        }        fseek (file, -768, SEEK_END);        w = header.xmax - header.xmin + 1;        h = header.ymax - header.ymin + 1;        image= Z_Malloc( w*h, PU_HWRCACHE, &grpatch->mipmap.grInfo.data );        if (fread ((byte *) palette, sizeof (byte), 768, file) == -1)        {            fclose (file);            return 0;        }        fseek(file, sizeof (PcxHeader), SEEK_SET);        size = w * h;        while (ptr < size)        {            ch = fgetc(file);  //Hurdler: beurk            if (ch >= 192)            {                rep = ch - 192;                ch = fgetc(file);            }            else {                rep = 1;            }            while (rep--)                image[ptr++] = ch;        }        fclose(file);        grpatch->mipmap.downloaded = 0;        grpatch->mipmap.grInfo.format = GR_TEXFMT_P_8;         grpatch->mipmap.flags = 0;        grpatch->width = w;        grpatch->height = h;        grpatch->mipmap.width = w;        grpatch->mipmap.height = h;        // not correct!        grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256;        grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256;        grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;    }    HWD.pfnSetTexture( &grpatch->mipmap );    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -