I have no trouble, in either Tier, creating a file within the game (options or scores) and then reading the file again.
But, you do have to do things manually to store and retrieve the data.
I have code in both Tier 1 and Tier 2 for doing some file extraction stuff.
Tier 1:
/////////////////////////////////////////
// TYPES ////////////////////////////////
/////////////////////////////////////////
TYPE tDelPnts
ifst AS integer
ilen AS integer
ENDTYPE
/////////////////////////////////////////
// GLOBALS USED /////////////////////////
/////////////////////////////////////////
global ta_aLine AS string
global ta_oops AS string
global dim ta_aSet[200] AS string
global dim ta_delat[200] AS tDelPnts
global ta_asInd AS integer, ta_asCnt AS integer
/////////////////////////////////////////
// FUNCTIONS ////////////////////////////
/////////////////////////////////////////
RemStart
Name: ta_trimString
Variables:
instr$ - string to trim
Output:
original string with all leading and trailing spaces removed
Description:
Remove all leading and trailing spaces in a string
RemEnd
function ta_trimString(instr$)
// initialise
restr$ = instr$
// get initial length
sLen = len(restr$)
// check for done
if sLen = 0 then exitfunction restr$
// trim the right end
while mid(restr$,sLen,1) = " "
// drop the last character
restr$ = left(restr$,sLen-1)
// reset length
sLen = len(restr$)
// check for done
if sLen = 0 then exitfunction restr$
endwhile
// trim from the left
while mid(restr$,1,1) = " "
// drop the last character
restr$ = right(restr$,sLen-1)
// reset length
sLen = len(restr$)
// check for done
if sLen = 0 then exitfunction restr$
endwhile
endfunction restr$
function set_ta_oops(oops$ AS string)
ta_oops = oops$
endfunction
function there_is_a_ta_oops()
if ta_oops <> "" then exitfunction 1
endfunction 0
function show_ta_oops()
print(ta_oops)
endfunction
RemStart
Name: ta_openFile
Variables:
file$ - name of file to open
Output:
on success - the fileid of opened file
on failure - zero
Globals Used:
none
Description:
Check for a file and if it exists open it
RemEnd
function ta_openFile(file$)
// make sure the file exists
if GetFileExists(file$) = 0
ta_oops = "Missing file '"+file$+"'"
exitfunction 0
endif
// attempt to open it
ifile = OpenToRead(file$)
// make sure it opened
if FileIsOpen(ifile) = 0
ta_oops = "Failed to open '"+file$+"'"
exitfunction 0
endif
// good, return file handle
endfunction ifile
RemStart
Name: ta_getNextLine
Variables:
iFile - file id of opened file
Output:
0 - end of file reached with nothing returned
1 - a non-comment, non-blank line has been found
Globals Used:
ta_aLine - set with line found in file or blank if none found
Description:
Read a file until either end of file or a non-blank
line not starting with '#' (a comment) is found.
If a line is found it is stored in the ta_aLine global
variable.
RemEnd
function ta_getNextLine(iFilID)
ta_aLine = ""
// make sure the file is actually open
if FileIsOpen(iFilID)
// try to find a non-blank, non-comment line
while fileEOF(iFilID) = 0
// grab a line
ta_aLine = readLine(iFilID)
// check for comment
if Left(ta_aLine,1) = "#"
// set to blank
ta_aLine = ""
else
// trim it
ta_aLine = ta_trimString(ta_aLine)
endif
// check for good, if not blank exit the function indication line found
if ta_aLine <> "" then exitfunction 1
endwhile
// check for done with file
if fileEOF(iFilID) = 1
// close the ifle
closefile(iFilID)
endif
endif
// if we reach here then there were no non-blank, non-comment lines
endfunction 0
RemStart
Name: ta_getNextLineAndSplit
Variables:
iFile - file id of opened file
delim - the delimiter string
reqpec - the minimum number of required pieces, 0 if no minimum
Output:
0 - end of file reached with nothing returned
1 - a non-comment, non-blank line has been found
Globals Used:
ta_aSet - string array set with pieces in line found, untouched of no line found
ta_asCnt - number of pieces in line found in file or zero if none found
Description:
Read a file until either end of file or a non-blank
line not starting with '#' (a comment) is found.
Break up the line into pieces, seperating them
where the delimiter string occurs.
If a line is found, then the pieces are stored in the
ta_aSet global array and the number of pieces is
stored in the ta_asCnt global variable.
RemEnd
function ta_getNextLineAndSplit(iFilID AS integer, delim AS string,reqpec AS integer)
// assume nothing found
ta_oops = ""
line$ = ""
ta_asCnt = 0
ta_asInd = 0
// make sure the file is actually open
if FileIsOpen(iFilID)
// try to find a non-blank, non-comment line
while fileEOF(iFilID) = 0
// grab a line
line$ = readLine(iFilID)
// check for comment
if Left(line$,1) = "#"
// set to blank
line$ = ""
else
// trim it
line$ = ta_trimString(line$)
endif
// check for good, if not blank break out of loop
if line$ <> "" then exit
endwhile
// check for done with file
if fileEOF(iFilID) = 1
// close the ifle
closefile(iFilID)
endif
// check for line being returned
if line$ <> ""
// time to extract bits
// find how many there are
iCnt as integer
i as integer
sLen as integer
dLen as integer
iCnt = 1
sLen = len(line$)
dLen = len(delim)
// assume the whole line to start
ta_delat[0].ifst = 1
ta_delat[0].ilen = sLen
// check for others
for i = 1 to sLen
if mid(line$, i, dLen) = delim
ta_delat[iCnt].ifst = i + dLen
if iCnt > 0 then ta_delat[iCnt-1].ilen = i - ta_delat[iCnt-1].ifst
iCnt = iCnt + 1
endif
next i
// save last value
ta_delat[iCnt-1].ilen = sLen - ta_delat[iCnt-1].ifst + 1
// break up the line
if iCnt > 1
// we know where the delimiters are
for i = 0 to iCnt-1
ta_aSet[i] = ta_trimString(mid(line$,ta_delat[i].ifst,ta_delat[i].ilen))
next i
else
// only one element
ta_aSet[0] = line$
endif
// save the number of things found
ta_asCnt = iCnt
// check for minimum requirement
if reqpec > 0
if iCnt < reqpec
ta_oops = "Minimum fields is "+str(reqpec)+", but only found "+str(iCnt)+" in '"+line$+"'"
exitfunction 0
endif
endif
// got something, exit the function indicating that there are items in ta_aSet
exitfunction 1
endif
endif
// if we reach here then there were no non-blank, non-comment lines
endfunction 0
RemStart
Name: ta_resetPieces
Variables:
none
Output:
none
Globals Used:
ta_asInd - the index of the next piece to use
Description:
Reset ta_asInd to zero
RemEnd
function ta_resetPieces()
// reset to start
ta_asInd = 0
endfunction piece
function ta_morePieces()
// assume yes
i_bool = 1
// check for done
if ta_asInd >= ta_asCnt then i_bool = 0
endfunction i_bool
RemStart
Name: ta_getNextPiece
Variables:
none
Output:
if ta_asInd < (ta_asCnt-1) - return the piece at ta_asInd
else return blank
Globals Used:
ta_aSet - string array set with pieces in line found, untouched of no line found
ta_asCnt - number of pieces in line found in file or zero if none found
ta_asInd - the index of the next piece to use
Description:
Pick the next piece from ta_aSet as indicated by ta_asInd, if there is one.
Increment the index to set up for next piece.
RemEnd
function ta_getNextPiece()
// initialise return
piece$ = ""
// check for more
if ta_asInd >= ta_asCnt then exitfunction piece$
// grab the piece
piece$ = ta_aSet[ta_asInd]
// increment the index
INC ta_asInd
endfunction piece$
RemStart
Name: ta_getNextPieceAsInt
Variables:
none
Output:
if ta_asInd < (ta_asCnt-1) - return the piece at ta_asInd converted to integer
else return blank
Globals Used:
ta_aSet - string array set with pieces in line found, untouched of no line found
ta_asCnt - number of pieces in line found in file or zero if none found
ta_asInd - the index of the next piece to use
Description:
Pick the next piece from ta_aSet as indicated by ta_asInd, if there is one.
Increment the index to set up for next piece.
RemEnd
function ta_getNextPieceAsInt()
// initialise return
piece$ = ta_getNextPiece()
// convert to integer
i_piece = val(piece$)
endfunction i_piece
RemStart
Name: ta_getNextPieceAsFloat
Variables:
none
Output:
if ta_asInd < (ta_asCnt-1) - return the piece at ta_asInd converted to float
else return blank
Globals Used:
ta_aSet - string array set with pieces in line found, untouched of no line found
ta_asCnt - number of pieces in line found in file or zero if none found
ta_asInd - the index of the next piece to use
Description:
Pick the next piece from ta_aSet as indicated by ta_asInd, if there is one.
Increment the index to set up for next piece.
RemEnd
function ta_getNextPieceAsFloat()
// initialise return
piece$ = ta_getNextPiece()
// convert to float
piece# = ValFloat(piece$)
endfunction piece#
Tier 2 (gotta love OOP!).
ta_oops.h:
#ifndef _TA_OOPS_
#define _TA_OOPS_
// Link to AGK libraries
#include "agk.h"
// get some things we might need
#include <string.h>
#include <stdarg.h>
/////////////////////////////////////////
// CLASSES //////////////////////////////
/////////////////////////////////////////
class ta_oops
{
private:
static char an_oops[2048];
static bool have_oops;
public:
ta_oops() {};
static void set_ta_oops(const char* fmt, ...);
static void clear_ta_oops(void);
static bool there_is_a_ta_oops(void) {return have_oops;}
static void show_ta_oops();
static const char* get_the_oops() {return (const char*)ta_oops::an_oops;};
};
#endif
ta_oops.cpp:
#include "ta_oops.h"
char ta_oops::an_oops[2048] = "";
bool ta_oops::have_oops = false;
void ta_oops::clear_ta_oops(void)
{
// set to all blanks
memset(ta_oops::an_oops,0,1024);
ta_oops::have_oops = false;
}
void ta_oops::set_ta_oops(const char* fmt, ...)
{
// create the oops
// handle the input
va_list args;
// create our own string
va_start(args,fmt);
vsprintf(ta_oops::an_oops, fmt, args);
va_end(args);
// set the flag
ta_oops::have_oops = true;
}
void ta_oops::show_ta_oops()
{
agk::Print(ta_oops::an_oops);
}
ta_file.h:
#ifndef _TA_FILE_
#define _TA_FILE_
// Link to AGK libraries
#include "agk.h"
// get some things we might need
#include <string.h>
#include <stdarg.h>
/////////////////////////////////////////
// CLASSES //////////////////////////////
/////////////////////////////////////////
class ta_file
{
private:
// for file processing
static char mySet[50][64];
static char aBlank[2];
static int myInd;
static int myCnt;
static int myFid;
static char myFname[60];
static char myLine[1024];
static char holdLine[1024];
static int trim_line();
// for debugging
static char debLine[2048];
public:
ta_file() {};
// for file processing
static bool openFile(const char* afile);
static void closeFile(void);
static bool getAndSplitLine(const char* delim,int reqpec,bool no_blank=false);
static const char* getString();
static int getInteger();
static bool getBoolean();
static float getFloat();
};
#endif
ta_file.cpp:
// Includes, namespace and prototypes
#include "ta_file.h"
#include "ta_oops.h"
// the variables
// for file processing
char ta_file::mySet[50][64];
char ta_file::aBlank[2] = "";
int ta_file::myInd = 0;
int ta_file::myCnt = 0;
int ta_file::myFid = 0;
char ta_file::myFname[60] = "";
char ta_file::myLine[1024] = "";
char ta_file::holdLine[1024] = "";
// for debugging
char ta_file::debLine[2048] = "";
bool ta_file::openFile(const char* afile)
{
// check for a file name
if (!afile)
{
ta_oops::set_ta_oops("Missing File Name");
return false;
}
// make sure the file exists
if (!agk::GetFileExists(afile))
{
ta_oops::set_ta_oops("Missing file: %s",afile);
return false;
}
// copy the file name
strcpy(ta_file::myFname,afile);
// attempt to open it
ta_file::myFid = agk::OpenToRead(ta_file::myFname);
// make sure it opened
if (!agk::FileIsOpen(ta_file::myFid))
{
ta_oops::set_ta_oops("Failed to open %s",ta_file::myFname);
return false;
}
// all is good
return true;
}
void ta_file::closeFile(void)
{
// close the file if open
if (ta_file::myFid) {agk::CloseFile(ta_file::myFid);}
// clear the values
ta_file::myFid = 0;
ta_file::myInd = 0;
ta_file::myCnt = 0;
}
int ta_file::trim_line()
{
// we get initial length
int ilen = strlen(ta_file::myLine);
// check for empty
if (ilen<1) {return 0;}
// go from the end first
int j = ilen - 1;
for (;j>0;j--)
{
// check for a blank
if (ta_file::myLine[j] == ' ')
{
// clear it
ta_file::myLine[j] = (char)0;
// decrement count
ilen--;
} else {
// done
break;
}
}
// check for empty
if (ilen<1) {return 0;}
// go from the beginning
int k = ilen - 1;
int i;
j = -1;
while ((j<=k)&&(ilen>0))
{
// check for blank
if (ta_file::myLine[++j] != ' ') break;
// copy everything to the end
for (i=j;i<=k;i++) ta_file::myLine[i] = ta_file::myLine[i+1];
// decrement count
ilen--;
}
// all done
return ilen;
}
bool ta_file::getAndSplitLine(const char* delim,int reqpec,bool no_blank/*=false*/)
{
// local stuff
char* line = 0;
// assume nothing
ta_file::myInd = 0;
ta_file::myCnt = 0;
memset(ta_file::myLine,0,1024);
// try to find a non-blank, non-comment line
while (!agk::FileEOF(ta_file::myFid))
{
// grab a line
line = agk::ReadLine(ta_file::myFid);
// check for comment
if (line[0] == '#')
{
// set to blank
delete(line);
// go to next line
continue;
}
// clear the space and copy the line
memset(ta_file::myLine,0,1024);
strncpy(ta_file::myLine,line,1023);
// clean up
delete(line);
// trim it
if (ta_file::trim_line()) break;
}
// check for done with file
if (agk::FileEOF(ta_file::myFid)) ta_file::closeFile();
// check for line being returned
int sLen = strlen(ta_file::myLine);
if (sLen==0)
{
// if we required a line and didn't find one, that is a problem
if (no_blank) ta_oops::set_ta_oops("Missing required line in '%s'",ta_file::myFname);
// indicate no line
return false;
}
// before the next step, copy the line (the strtok overwrites things)
strcpy(ta_file::holdLine,ta_file::myLine);
// time to extract bits
// find how many there are
ta_file::myCnt = 0;
// check for a delimiter
char* pch = strtok(ta_file::myLine,delim);
if (pch != NULL)
{
while (pch != NULL)
{
// copy the piece
memset(ta_file::mySet[ta_file::myCnt],0,50);
strncpy(ta_file::mySet[ta_file::myCnt++],pch,49);
// check for another
pch = strtok (NULL,delim);
}
} else {
// it is the whole line
memset(ta_file::mySet[ta_file::myCnt],0,50);
strncpy(ta_file::mySet[ta_file::myCnt++],ta_file::myLine,49);
}
// check for minimum requirement
if (reqpec > 0)
{
if (ta_file::myCnt < reqpec)
{
ta_oops::set_ta_oops("Minimum fields is %d, but only found %d in:\n%s",reqpec,ta_file::myCnt,ta_file::holdLine);
return false;
}
}
// we have something
return true;
}
const char* ta_file::getString()
{
// check for more pieces
if (ta_file::myInd >= ta_file::myCnt) {return ta_file::aBlank;}
// return the next piece and increment index
return ta_file::mySet[ta_file::myInd++];
}
int ta_file::getInteger()
{
// return an integer value
return agk::Val(ta_file::getString());
}
bool ta_file::getBoolean()
{
// get an integer value
int i_val = agk::Val(ta_file::getString());
// return true or false
return (i_val!=0?true:false);
}
float ta_file::getFloat()
{
// return a float value
return agk::ValFloat(ta_file::getString());
}
Cheers,
Ancient Lady
AGK Community Tester