Skip to content

Commit

Permalink
Refactor: Texture animation sequences are now read during game pre-init
Browse files Browse the repository at this point in the history
During pre-init the game now constructs its texture animation sequences
via a (temporary) API mechanism. The engine then autogenerates Group
definitions from this representation prior to parsing DED files.

This commit fixes the last of the issues reported in bug #2480718

Todo: It should now be possible to fix the "flashing bloodfall" issue
in Plutonia2
  • Loading branch information
danij-deng committed Nov 16, 2011
1 parent d0430ae commit 0fea949
Show file tree
Hide file tree
Showing 18 changed files with 349 additions and 167 deletions.
5 changes: 3 additions & 2 deletions doomsday/engine/api/doomsday.def
Expand Up @@ -377,8 +377,6 @@ EXPORTS
Materials_ComposeUri @494 NONAME
Materials_ResolveUri @495 NONAME
Materials_ResolveUriCString @496 NONAME
Materials_CreateAnimGroup @241 NONAME
Materials_AddAnimGroupFrame @242 NONAME

; Play: Thinkers.
DD_ThinkerAdd @86 NONAME
Expand Down Expand Up @@ -414,6 +412,9 @@ EXPORTS
R_TextureUniqueId @438 NONAME
R_TextureUniqueId2 @501 NONAME

R_CreateAnimGroup @241 NONAME
R_AddAnimGroupFrame @242 NONAME

R_PointToAngle2 @101 NONAME
R_PointInSubsector @102 NONAME
R_HSVToRGB @439 NONAME
Expand Down
6 changes: 3 additions & 3 deletions doomsday/engine/api/doomsday.h
Expand Up @@ -357,9 +357,6 @@ materialid_t Materials_ResolveUri(const Uri* uri);
materialid_t Materials_ResolveUriCString(const char* path);
Uri* Materials_ComposeUri(materialid_t materialId);

int Materials_CreateAnimGroup(int flags);
void Materials_AddAnimGroupFrame(int groupNum, struct material_s* material, int tics, int randomTics);

// Play: Thinkers.
void DD_InitThinkers(void);
void DD_RunThinkers(void);
Expand Down Expand Up @@ -413,6 +410,9 @@ Uri* R_ComposePatchUri(patchid_t id);
int R_TextureUniqueId2(const Uri* uri, boolean quiet);
int R_TextureUniqueId(const Uri* uri); /*quiet=false*/

int R_CreateAnimGroup(int flags);
void R_AddAnimGroupFrame(int groupNum, const Uri* texture, int tics, int randomTics);

colorpaletteid_t R_CreateColorPalette(const char* fmt, const char* name, const uint8_t* colorData, int colorCount);
colorpaletteid_t R_GetColorPaletteNumForName(const char* name);
const char* R_GetColorPaletteNameForNum(colorpaletteid_t id);
Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/def_data.h
Expand Up @@ -452,6 +452,7 @@ typedef struct ded_group_s {
ded_flags_t flags;
ded_count_t count;
ded_group_member_t* members;
boolean autoGenerated;
} ded_group_t;

typedef struct ded_material_layer_stage_s {
Expand Down
43 changes: 41 additions & 2 deletions doomsday/engine/portable/include/r_data.h
Expand Up @@ -393,8 +393,6 @@ boolean R_UpdateSurface(struct surface_s* suf, boolean forceUpdate);
*/
void R_PrecacheForMap(void);

void R_InitAnimGroup(ded_group_t* def);

/**
* Prepare all texture resources for the specified mobjtype.
*
Expand Down Expand Up @@ -427,4 +425,45 @@ void R_ShutdownVectorGraphics(void);
int R_TextureUniqueId2(const Uri* uri, boolean quiet);
int R_TextureUniqueId(const Uri* uri); /* quiet=false */

typedef struct animframe_s {
textureid_t texture;
ushort tics;
ushort randomTics;
} animframe_t;

typedef struct animgroup_s {
int id;
int flags;
int count;
animframe_t* frames;
} animgroup_t;

/// @return Number of animation/precache groups.
int R_AnimGroupCount(void);

/// To be called to destroy all animation groups when they are no longer needed.
void R_ClearAnimGroups(void);

/// @return AnimGroup associated with @a animGroupNum else @c NULL
const animgroup_t* R_ToAnimGroup(int animGroupNum);

/**
* Create a new animation group.
* @return Logical (unique) identifier reference associated with the new group.
*/
int R_CreateAnimGroup(int flags);

/**
* Append a new @a texture frame to the identified @a animGroupNum.
*
* @param animGroupNum Logical identifier reference to the group being modified.
* @param texture Texture frame to be inserted into the group.
* @param tics Base duration of the new frame in tics.
* @param randomTics Extra frame duration in tics (randomized on each cycle).
*/
void R_AddAnimGroupFrame(int animGroupNum, const Uri* texture, int tics, int randomTics);

/// @return @c true iff @a texture is linked to the identified @a animGroupNum.
boolean R_IsTextureInAnimGroup(const Uri* texture, int animGroupNum);

#endif /* LIBDENG_REFRESH_DATA_H */
1 change: 1 addition & 0 deletions doomsday/engine/portable/src/dd_main.c
Expand Up @@ -1079,6 +1079,7 @@ boolean DD_ChangeGame2(gameinfo_t* info, boolean allowReload)

LO_Clear();
R_DestroyObjLinks();
R_ClearAnimGroups();

P_PtcShutdown();
P_ControlShutdown();
Expand Down
7 changes: 3 additions & 4 deletions doomsday/engine/portable/src/def_data.c
Expand Up @@ -852,11 +852,10 @@ void DED_RemoveReflection(ded_t *ded, int index)
sizeof(ded_reflection_t));
}

int DED_AddGroup(ded_t *ded)
int DED_AddGroup(ded_t* ded)
{
ded_group_t *group = DED_NewEntry((void **) &ded->groups,
&ded->count.groups, sizeof(ded_group_t));

ded_group_t* group = DED_NewEntry((void **) &ded->groups, &ded->count.groups, sizeof(ded_group_t));
group->autoGenerated = false;
return group - ded->groups;
}

Expand Down
68 changes: 62 additions & 6 deletions doomsday/engine/portable/src/def_main.c
Expand Up @@ -901,6 +901,38 @@ static void readAllDefinitions(void)
VERBOSE2( Con_Message(" Done in %.2f seconds.\n", (Sys_GetRealTime() - startTime) / 1000.0f) );
}

void Def_GenerateGroupsFromAnims(void)
{
int groupCount = R_AnimGroupCount(), i;
if(!groupCount) return;

// Group ids are 1-based.
for(i = 1; i < groupCount+1; ++i)
{
const animgroup_t* anim = R_ToAnimGroup(i);
ded_group_member_t* gmbr;
ded_group_t* grp;
int idx, j;

idx = DED_AddGroup(&defs);
grp = &defs.groups[idx];
grp->autoGenerated = true;
grp->flags = anim->flags;

for(j = 0; j < anim->count; ++j)
{
const animframe_t* frame = &anim->frames[j];

idx = DED_AddGroupMember(grp);
gmbr = &grp->members[idx];
gmbr->tics = frame->tics;
gmbr->randomTics = frame->randomTics;
gmbr->material = Textures_ComposeUri(frame->texture);
Uri_SetScheme(gmbr->material, Str_Text(DD_MaterialNamespaceNameForTextureNamespace(Textures_Namespace(frame->texture))));
}
}
}

static int generateMaterialDefForPatchCompositeTexture(textureid_t texId, void* paramaters)
{
Uri* texUri = Textures_ComposeUri(texId);
Expand Down Expand Up @@ -1050,6 +1082,7 @@ void Def_Read(void)
DED_Init(&defs);

// Generate definitions.
Def_GenerateGroupsFromAnims();
Def_GenerateAutoMaterials();

// Read all definitions files and lumps.
Expand Down Expand Up @@ -1356,13 +1389,36 @@ void Def_Read(void)
defsInited = true;
}

static void initAnimGroup(ded_group_t* def)
{
int i, groupNumber = -1;
for(i = 0; i < def->count.num; ++i)
{
ded_group_member_t* gm = &def->members[i];
material_t* mat;

if(!gm->material) continue;

mat = Materials_ToMaterial(Materials_ResolveUri2(gm->material, true/*quiet please*/));
if(!mat) continue;

// Only create a group when the first texture is found.
if(groupNumber == -1)
{
groupNumber = Materials_CreateAnimGroup(def->flags);
}

Materials_AddAnimGroupFrame(groupNumber, mat, gm->tics, gm->randomTics);
}
}

void Def_PostInit(void)
{
int i, k;
ded_ptcgen_t* gen;
char name[40];
modeldef_t* modef;
ded_ptcstage_t* st;
ded_ptcstage_t* st;
ded_ptcgen_t* gen;
modeldef_t* modef;
char name[40];
int i, k;

// Particle generators: model setup.
for(i = 0, gen = defs.ptcGens; i < defs.count.ptcGens.num; ++i, gen++)
Expand Down Expand Up @@ -1449,7 +1505,7 @@ void Def_PostInit(void)
Materials_ClearAnimGroups();
for(i = 0; i < defs.count.groups.num; ++i)
{
R_InitAnimGroup(&defs.groups[i]);
initAnimGroup(&defs.groups[i]);
}
}

Expand Down

0 comments on commit 0fea949

Please sign in to comment.