diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 609ec1721..121c0fb27 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2403,22 +2403,23 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size) //========================================================================== // -// PClass:: Extend +// PClass :: Extend // -// Add bytes to the end of this class. Returns the previous -// size of the class. +// Add bytes to the end of this class and possibly more to meet +// alignment restrictions. Returns the start of the extended block. // //========================================================================== -unsigned int PClass::Extend(unsigned int extension) +unsigned int PClass::Extend(unsigned int extension, unsigned int alignment) { assert(this->bRuntimeClass); unsigned int oldsize = Size; - Size += extension; + unsigned int padto = (oldsize + alignment - 1) & ~(alignment - 1); + Size = padto + extension; Defaults = (BYTE *)M_Realloc(Defaults, Size); - memset(Defaults + oldsize, 0, extension); - return oldsize; + memset(Defaults + oldsize, 0, Size - oldsize); + return padto; } //========================================================================== diff --git a/src/dobjtype.h b/src/dobjtype.h index b482efe45..05097795b 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -660,7 +660,8 @@ public: void InsertIntoHash(); DObject *CreateNew() const; PClass *CreateDerivedClass(FName name, unsigned int size); - unsigned int Extend(unsigned int extension); + unsigned int Extend(unsigned int extension, unsigned int alignment); + unsigned int Extend(const PType *type) { return Extend(type->Size, type->Align); } void InitializeActorInfo(); void BuildFlatPointers(); const PClass *NativeClass() const; diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 97e22dc8c..cc2c71e34 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -531,14 +531,14 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl sc.ScriptError("Native classes may not have user variables"); } - // Read the type and make sure it's int. + // Read the type and make sure it's acceptable. sc.MustGetAnyToken(); - if (sc.TokenType != TK_Int) + if (sc.TokenType != TK_Int && sc.TokenType != TK_Float) { - sc.ScriptMessage("User variables must be of type int"); + sc.ScriptMessage("User variables must be of type 'int' or 'float'"); FScriptPosition::ErrorCounter++; } - type = TypeSInt32; + type = sc.TokenType == TK_Int ? (PType *)TypeSInt32 : (PType *)TypeFloat64; sc.MustGetToken(TK_Identifier); // For now, restrict user variables to those that begin with "user_" to guarantee @@ -585,7 +585,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl sc.MustGetToken(';'); PField *sym = new PField(symname, type, 0); - sym->Offset = cls->Extend(sizeof(int) * maxelems); + sym->Offset = cls->Extend(type); if (symt->AddSymbol(sym) == NULL) { delete sym;