models: partial support mda file parse

This commit is contained in:
Denis Pauk 2024-09-15 17:46:21 +03:00
parent f64ab5bfb7
commit 6ba618fc42
9 changed files with 102 additions and 1 deletions

View file

@ -36,6 +36,7 @@ Models support:
| ------ | --------------- | ------------ | -------- | --------------------------------------- | | ------ | --------------- | ------------ | -------- | --------------------------------------- |
| mdl | Quake 1 | 8 bit | Single | Unsupported grouped textures | | mdl | Quake 1 | 8 bit | Single | Unsupported grouped textures |
| md2 | Quake 2 | 8 bit | Single | | | md2 | Quake 2 | 8 bit | Single | |
| mda | Anachronox | Part of md2 | Single | No tagged surfaces |
| md2 | Anachronox | 8/10/16 bit | Single | No tagged surfaces, unchecked with game | | md2 | Anachronox | 8/10/16 bit | Single | No tagged surfaces, unchecked with game |
| mdx | Kingpin | 8 bit | Multiple | No sfx support, unchecked with game | | mdx | Kingpin | 8 bit | Multiple | No sfx support, unchecked with game |
| fm | Heretic 2 | 8 bit | Multiple | | | fm | Heretic 2 | 8 bit | Multiple | |

View file

@ -29,6 +29,10 @@
#include "models.h" #include "models.h"
static void *
Mod_LoadModelFile(const char *mod_name, const void *buffer, int modfilelen,
struct image_s ***skins, int *numskins, readfile_t read_file, modtype_t *type);
/* /*
================= =================
Mod_LoadSTvertList Mod_LoadSTvertList
@ -2856,6 +2860,80 @@ Mod_LoadModel_SDEF(const char *mod_name, const void *buffer, int modfilelen,
return extradata; return extradata;
} }
static void *
Mod_LoadModel_MDA_Text(const char *mod_name, char *curr_buff,
readfile_t read_file, struct image_s ***skins, int *numskins, modtype_t *type)
{
char base_model[MAX_QPATH * 2] = {0};
while (curr_buff)
{
const char *token;
token = COM_Parse(&curr_buff);
if (!*token)
{
continue;
}
/* found basemodel */
else if (!strncmp(token, "basemodel", 9))
{
token = COM_Parse(&curr_buff);
if (!token)
{
return NULL;
}
strncpy(base_model, token, sizeof(base_model) - 1);
/* other fields is unused for now */
break;
}
}
if (base_model[0])
{
void *extradata, *base;
int base_size;
base_size = read_file(base_model, (void **)&base);
if (base_size <= 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s No base model for %s\n",
__func__, mod_name, base_model);
return NULL;
}
/* little bit recursive load */
extradata = Mod_LoadModelFile(mod_name, base, base_size,
skins, numskins,
read_file, type);
free(base);
return extradata;
}
return NULL;
}
static void *
Mod_LoadModel_MDA(const char *mod_name, const void *buffer, int modfilelen,
readfile_t read_file, struct image_s ***skins, int *numskins, modtype_t *type)
{
void *extradata;
char *text;
text = malloc(modfilelen + 1 - 4);
memcpy(text, (char *)buffer + 4, modfilelen - 4);
text[modfilelen - 4] = 0;
extradata = Mod_LoadModel_MDA_Text(mod_name, text, read_file, skins,
numskins, type);
free(text);
return extradata;
}
/* /*
================= =================
Mod_LoadSprite_SP2 Mod_LoadSprite_SP2
@ -3037,6 +3115,11 @@ Mod_LoadModelFile(const char *mod_name, const void *buffer, int modfilelen,
switch (LittleLong(*(unsigned *)buffer)) switch (LittleLong(*(unsigned *)buffer))
{ {
case MDAHEADER:
extradata = Mod_LoadModel_MDA(mod_name, buffer, modfilelen,
read_file, skins, numskins, type);
break;
case SDEFHEADER: case SDEFHEADER:
extradata = Mod_LoadModel_SDEF(mod_name, buffer, modfilelen, extradata = Mod_LoadModel_SDEF(mod_name, buffer, modfilelen,
read_file, skins, numskins, type); read_file, skins, numskins, type);

View file

@ -477,6 +477,8 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
/* call the apropriate loader */ /* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
case MDAHEADER:
/* fall through */
case SDEFHEADER: case SDEFHEADER:
/* fall through */ /* fall through */
case MDXHEADER: case MDXHEADER:

View file

@ -478,6 +478,8 @@ Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash)
/* call the apropriate loader */ /* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
case MDAHEADER:
/* fall through */
case SDEFHEADER: case SDEFHEADER:
/* fall through */ /* fall through */
case MDXHEADER: case MDXHEADER:

View file

@ -478,6 +478,8 @@ Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash)
/* call the apropriate loader */ /* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
case MDAHEADER:
/* fall through */
case SDEFHEADER: case SDEFHEADER:
/* fall through */ /* fall through */
case MDXHEADER: case MDXHEADER:

View file

@ -485,6 +485,8 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
/* call the apropriate loader */ /* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
case MDAHEADER:
/* fall through */
case SDEFHEADER: case SDEFHEADER:
/* fall through */ /* fall through */
case MDXHEADER: case MDXHEADER:

View file

@ -461,6 +461,8 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
/* call the apropriate loader */ /* call the apropriate loader */
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
case MDAHEADER:
/* fall through */
case SDEFHEADER: case SDEFHEADER:
/* fall through */ /* fall through */
case MDXHEADER: case MDXHEADER:

View file

@ -224,6 +224,7 @@ typedef struct
/* .MD2 Anachronox triangle model file format */ /* .MD2 Anachronox triangle model file format */
#define MDAHEADER (('1' << 24) + ('A' << 16) + ('D' << 8) + 'M')
#define ALIAS_ANACHRONOX_VERSION 15 #define ALIAS_ANACHRONOX_VERSION 15
typedef struct typedef struct

View file

@ -75,7 +75,7 @@ DynamicSpawn(edict_t *self, dynamicentity_t *data)
{ {
self->movetype = MOVETYPE_NONE; self->movetype = MOVETYPE_NONE;
self->solid = SOLID_BBOX; self->solid = SOLID_BBOX;
self->s.modelindex = gi.modelindex("<model_path>"/*data->model_path*/); self->s.modelindex = gi.modelindex(data->model_path);
VectorCopy(data->mins, self->mins); VectorCopy(data->mins, self->mins);
VectorCopy(data->maxs, self->maxs); VectorCopy(data->maxs, self->maxs);
@ -1810,8 +1810,14 @@ DynamicSpawnInit(void)
break; break;
} }
/* skip empty */
linesize = strspn(curr, "\n\r\t ");
curr += linesize;
/* mark end line */
linesize = strcspn(curr, "\n\r"); linesize = strcspn(curr, "\n\r");
curr[linesize] = 0; curr[linesize] = 0;
if (*curr && strncmp(curr, "//", 2) && if (*curr && strncmp(curr, "//", 2) &&
*curr != '\n' && *curr != '\r' && *curr != ';') *curr != '\n' && *curr != '\r' && *curr != ';')
{ {