Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions src/IDs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,28 @@
#include"command.h"
#include"ExpandingArray.h"

class IDs:public Guintp{
class IDs {
public:
std::vector<uint> flags;
SINGLETON(IDs);
};

IDs::IDs(){
FILE*pFile=myfopen(IDs);
_p=new uint[MaxFeature()+1];
for(uint i=0;i<=MaxFeature();i++)
_p[i]=GetCheckWord(IDs);
flags.resize(MaxFeature() + 1);
for (auto &flag : flags)
flag = GetCheckWord(IDs);
fclose(pFile);
}

class TextIDs{
public:
uint idClasses[0x20],numspecials;
uint idClasses[0x20];
bool CheckID(uint,uint);
void Define(uint);
bool IsDefined(uint);
static void Clear();
AUTO_ARRAY(uchar);
std::vector<uchar> specials;
SINGLETON(TextIDs);
private:
static Expanding0Array<bool> _m;
Expand All @@ -67,8 +68,8 @@ TextIDs::TextIDs(){
uint i=0;
for(;i<0x20;i++)
idClasses[i]=GetCheckWord(TextIDs);
_p=new uchar[numspecials=GetCheckByte(TextIDs)];
myfread(_p,numspecials,TextIDs);
specials.resize(GetCheckByte(TextIDs));
myfread(specials.data(), specials.size(), TextIDs);
fclose(pFile);
}

Expand All @@ -79,8 +80,8 @@ bool TextIDs::CheckID(uint feature,uint ID){
}
if(feature==0x49&&ID==0xC7FF)return true;
if(idClasses[ID>>11]==0xFFFF){
for(uint i=0;i<numspecials;i++)if(ID>>8==_p[i])return true;
return false;
auto it = std::ranges::find(specials, ID >> 8);
return it != specials.end();
}
return(ID&0x7FF)<idClasses[ID>>11];
}
Expand Down Expand Up @@ -127,7 +128,7 @@ bool CheckID(uint feature,uint ID){
* is the first new GRF version after that, so use that as minimum
* threshold for allowing the higher IDs. Even though this is not
* actually tied to GRF version 8.*/
uint maxID=_grfver>=8&&feature<=0x03?0xFFFF:IDs::Instance()[feature];
uint maxID = _grfver >= 8 && feature <= 0x03 ? 0xFFFF : IDs::Instance().flags.at(feature);
if(ID>maxID){
IssueMessage(ERROR,INVALID_ID,ID,feature==0x0C?0x49:0,maxID);
return false;
Expand Down
83 changes: 43 additions & 40 deletions src/act0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,30 +98,30 @@ char FF is undef
typedef std::basic_string<uchar> ustring;
typedef std::vector<int> int_str;

class PropData:public auto_array<PropData>{
class PropData{
public:
PropData(){}
void Init(FILE*,bool);
uchar GetData(uint)const;
uint GetLength()const{return(uint)length.length();}
const PropData*GetVarLength(int)const;
const PropData &GetVarLength(int) const;
uint GetValue(uint&,const int_str&)const;
uint maxfirst(int prop){return idRange[prop]&0xFF;}
uint maxlast(int prop){return (idRange[prop]>>8)&0xFF;}
uint maxfirst(int prop) const { return idRange[prop] & 0xFF; }
uint maxlast(int prop) const { return (idRange[prop] >> 8) & 0xFF; }
std::vector<PropData> data;
private:
ustring length;
std::vector<uint> idRange;
void readString(FILE*,bool);
int CountFE();
void operator=(const PropData&);
PropData(const PropData&);
};

class Check0:public auto_array<PropData>{
class Check0 {
public:
void Check(PseudoSprite&);
static Check0&Instance(){static Check0 obj;return obj;}
uint GetFeat8(){return _p[8].GetLength();}
uint GetFeat8() { return data.at(8).GetLength(); }
std::vector<PropData> data;
private:
Check0();
bool CheckVar(uint&,PseudoSprite&,const PropData&,bool addblank,bool,int_str =int_str())const;
Expand All @@ -137,11 +137,11 @@ uchar PropData::GetData(unsigned int prop)const{
return prop<length.length()?length[prop]:(uchar)0xFF;
}

const PropData*PropData::GetVarLength(int prop)const{
PropData*ret=_p;
const PropData &PropData::GetVarLength(int prop) const {
auto ret = data.begin();
for(int i=0;i<prop;i++)
if(length[i]==0xFE)ret++;
return ret;
return *ret;
}

uint PropData::GetValue(uint&len_off,const int_str&decoded)const{
Expand Down Expand Up @@ -172,9 +172,9 @@ void PropData::Init(FILE*pFile, bool withIDs){
readString(pFile, withIDs);
int j=CountFE();
if(j){
_p=new PropData[j];
data.clear();
for(int k=0;k<j;k++)
_p[k].Init(pFile, false);
data.emplace_back().Init(pFile, false);
}
}

Expand Down Expand Up @@ -355,7 +355,7 @@ void Check0::Check(PseudoSprite&str){
}
if(feature==8 && prop==9)
CargoTransTable(IDs-1);
len=_p[feature].GetData(prop);
len = data.at(feature).GetData(prop);
if(prop==8)// Mark prop 08 as set, if necessary.
for(uint i=firstID;i<=maxID;i++)
Prop08Tracking::Set(feature,i);
Expand All @@ -373,18 +373,19 @@ void Check0::Check(PseudoSprite&str){
return;
}
if(feature==8){
if(firstID>_p[feature].maxfirst(prop))
IssueMessage(ERROR,INVALID_ID,firstID,0,_p[feature].maxfirst(prop));
if(IDs&&maxID>_p[feature].maxlast(prop))
IssueMessage(ERROR,INVALID_ID,maxID,0,_p[feature].maxlast(prop));
const PropData &prop_data = data.at(feature);
if (firstID > prop_data.maxfirst(prop))
IssueMessage(ERROR, INVALID_ID, firstID, 0, prop_data. maxfirst(prop));
if (IDs && maxID > prop_data.maxlast(prop))
IssueMessage(ERROR, INVALID_ID, maxID, 0, prop_data. maxlast(prop));
}
if(propLoc[prop]&&!(len&0x80))
IssueMessage(WARNING2,REPEATED_PROP,i,prop,propLoc[prop]);
propLoc[prop]=i++;
if(len==0xFE){
const PropData*data=_p[feature].GetVarLength(prop);
const PropData &prop_data = data.at(feature).GetVarLength(prop);
for(j=0;j<IDs;j++){
if(!CheckVar(i,str,*data,j+1<IDs,true))return;
if (!CheckVar(i, str, prop_data, j + 1 < IDs, true)) return;
while (lengthlist.size()) {
const uint loc = lengthlist.back(),
val = str.ExtractDword(loc),
Expand All @@ -408,7 +409,7 @@ void Check0::Check(PseudoSprite&str){
IssueMessage(ERROR,INSUFFICIENT_DATA2,i-str.Length(),prop);
else{
if(i<str.Length()){
len=_p[feature].GetData(str.ExtractByte(4+str.ExtendedLen(4)));
len = data.at(feature).GetData(str.ExtractByte(4 + str.ExtendedLen(4)));
if(_autocorrect&&str.ExtractByte(2)==1&&GetWidth(len)<5){
// If setting one property, assume setting same prop for more IDs
while(i+(GetWidth(len)==3?str.ExtendedLen(i):GetWidth(len))<=str.Length()&&IDs<0xFF){
Expand All @@ -426,14 +427,15 @@ void Check0::Check(PseudoSprite&str){
}
if(!GetState(LINEBREAKS))return;
bool linebreaks=(IDs>1||GetState(LINEBREAKS)==3)&&str.ExtractByte(2)>1;
const PropData &prop_data = data.at(feature);
uint data;
for(i=0;i<propLoc.size();i++)
linebreaks |= propLoc[i] && _p[feature].GetData(i)==0xFE;
linebreaks |= propLoc[i] && prop_data.GetData(i) == 0xFE;
if(!linebreaks)return;
for(i=0;i<propLoc.size();i++){
if(!propLoc[i])continue;
str.SetEol(propLoc[i]-1,1);
if((data=_p[feature].GetData(i))==0xFE)continue;
if ((data = prop_data.GetData(i)) == 0xFE) continue;
for(uint j=IDs;j;j--)
str.ColumnAfter(propLoc[i]+GetWidth(data)*j);
}
Expand All @@ -457,9 +459,9 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
continue;
}
switch(ch){
case'|':return true;
case'l':
case'm':{
case '|':return true;
case 'l':
case 'm':{
uint len=(ch=='m'?vdata.GetData(++i):1);
for(uint k=0;k<len;k++){
/* Check for a specific raw data value.
Expand All @@ -475,11 +477,11 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
}
break;
}
case'e':
case'n':{
case 'e':
case 'n':{
uint lhs=vdata.GetValue(++i,decoded);
uint rhs=vdata.GetValue(++i,decoded);
const PropData*vdata2=vdata.GetVarLength(i);
const PropData &vdata2 = vdata.GetVarLength(i);
uchar data=vdata.GetData(++i);
if ((lhs == rhs) == (ch == 'n')) break;
if(data=='a'){
Expand All @@ -489,7 +491,7 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
str_loc=orig_loc;
findPipe=true;
}else if(data==0xFE){
if(!CheckVar(str_loc,str,*vdata2,false,false,pass))return false;
if (!CheckVar(str_loc, str, vdata2, false, false, pass)) return false;
}else if(GetWidth(data)<5){
FormatSprite(str,str_loc,data,1);
}else{
Expand All @@ -498,22 +500,23 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
}
break;
}
case'r':{
const PropData*vdata2=vdata.GetVarLength(i);
case 'r':{
const PropData &vdata2 = vdata.GetVarLength(i);
uchar repeat_data=vdata.GetData(++i);
uint times=vdata.GetValue(++i,decoded);
if(repeat_data==0xFE){
for(uint j=0;j<times;j++)
if(!CheckVar(str_loc,str,*vdata2,false,false,pass))return false;
if (!CheckVar(str_loc, str, vdata2, false, false, pass)) return false;
}else if(GetWidth(repeat_data)<5){
FormatSprite(str,str_loc,repeat_data,times);
}else{
IssueMessage(0,INVALID_DATAFILE,"0.dat",DAT2,'r',repeat_data);
exit(EDATA);
}
break;
}case'*':{
const PropData*vdata2=vdata.GetVarLength(i);
}
case '*':{
const PropData &vdata2 = vdata.GetVarLength(i);
uchar repeat_data=vdata.GetData(++i);
int term_len=vdata.GetData(++i);
uint term;
Expand Down Expand Up @@ -542,7 +545,7 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
try{
if(repeat_data==0xFE){
while((str.*ExtractTerm)(str_loc)!=term)
if(!CheckVar(str_loc,str,*vdata2,false,false,pass))return false;
if (!CheckVar(str_loc, str, vdata2, false, false, pass)) return false;
}else if(GetWidth(repeat_data)<5){
while((str.*ExtractTerm)(str_loc)!=term)
FormatSprite(str,str_loc,repeat_data);
Expand All @@ -561,7 +564,7 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca
pass.push_back(vdata.GetValue(++i,decoded));
break;
case 0xFE:
CheckVar(str_loc,str,*vdata.GetVarLength(i),false,false,pass);
CheckVar(str_loc, str, vdata.GetVarLength(i), false, false, pass);
break;
default:
switch(GetWidth(ch)){
Expand Down Expand Up @@ -594,8 +597,8 @@ bool Check0::CheckVar(uint&str_loc,PseudoSprite&str,const PropData&vdata,bool ca

Check0::Check0(){
FILE*pFile=myfopen(0);
_p=new PropData[MaxFeature()+1];
for(uint i=0;i<=MaxFeature();i++)
_p[i].Init(pFile,i==8);
data.resize(MaxFeature() + 1);
for (uint i = 0; i < data.size(); i++)
data[i].Init(pFile, i == 8);
fclose(pFile);
}
2 changes: 1 addition & 1 deletion src/act123.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void invalidate_act3(){

void CheckCallback(uint offs,uint feature,uint cb){
Callbacks&cbs=Callbacks::Instance();
if(cb&&(cb>=cbs.numcallbacks||cb<0x10||(cbs[cb]&0x80000000?!(cbs[cb]&(1<<feature)):feature!=cbs[cb])))
if (cb && (cb >= cbs.flags.size() || cb < 0x10 || (cbs.flags.at(cb) & 0x80000000 ? !(cbs.flags.at(cb) & (1 << feature)) : feature != cbs.flags.at(cb))))
IssueMessage(ERROR,INVALID_CALLBACK,offs,cb);
}

Expand Down
9 changes: 5 additions & 4 deletions src/act123.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include <vector>
#include "singleton.h"
#include "message_mgr.h"

Expand Down Expand Up @@ -86,7 +87,7 @@ class Check2v{
SINGLETON(Check2v)
private:
ExpandingArray<VarData>globvars;
auto_array<FeatData>_p;
std::vector<FeatData> data;
uint maxop;
uint MaxParam(uint feature, uint var)const;
uint GetWidth(uint feature, uint var)const;
Expand Down Expand Up @@ -119,7 +120,7 @@ class rand2{
struct rand2info{
uint bits[2],numtriggers;
};
auto_array<rand2info>_p;
std::vector<rand2info> data;
public:
void CheckRand(uint feat,uint type,uint triggers,uint first,uint nrand);
SINGLETON(rand2);
Expand All @@ -137,9 +138,9 @@ class Define2{
bool checks1C;
};

class Callbacks:public auto_array<uint>{
class Callbacks {
public:
uint numcallbacks;
std::vector<uint> flags;
SINGLETON(Callbacks);
};

Loading