Log in

View Full Version : Cannot load ini-files in the game



Ultra
28-11-2003, 06:32 PM
Hi all!

I'm making a space shooter game. In the game I want to have a simple form of dialog. This is simply a text that shows after x frames have passed and it shows for y frames.


type
TDialog = record
Name: String; // identifier used by the editor
StartFrame, NumOfFrames: Integer;
Text1, Text2, Text3: String; // text to display
end;
TDialogs = array of TDialog;


To store this information I've decided to use ini files (I may use a TStream later, but during development ini files are more flexible). The save and load procedures look like this:


procedure SaveDialogToIni(var Dialog: TDialogs; const FileName: String);
var
Ini: TIniFile;
i: Integer;
begin
Ini := TIniFile.Create(FileName);
try
Ini.WriteInteger('General', 'NumOfDlg', Length(Dialog));
for i := 0 to High(Dialog) do
begin
Ini.WriteString ('Dialog'+IntToStr(i+1), 'Name' , Dialog[i].Name );
Ini.WriteInteger('Dialog'+IntToStr(i+1), 'StartFrame' , Dialog[i].StartFrame );
Ini.WriteInteger('Dialog'+IntToStr(i+1), 'NumOfFrames', Dialog[i].NumOfFrames);
Ini.WriteString ('Dialog'+IntToStr(i+1), 'Text1' , Dialog[i].Text1 );
Ini.WriteString ('Dialog'+IntToStr(i+1), 'Text2' , Dialog[i].Text2 );
Ini.WriteString ('Dialog'+IntToStr(i+1), 'Text3' , Dialog[i].Text3 );
end;
finally
Ini.Free;
end;
end;

procedure LoadDialogFromIni(var Dialog: TDialogs; const FileName: String);
var
Ini: TIniFile;
i, len: Integer;
begin
Dialog := nil;

Ini := TIniFile.Create(FileName);
try
len := Ini.ReadInteger('General', 'NumOfDlg', 0);
SetLength(Dialog, len);
for i := 0 to len - 1 do
begin
Dialog[i].Name := Ini.ReadString ('Dialog'+IntToStr(i+1), 'Name' , '');
Dialog[i].StartFrame := Ini.ReadInteger('Dialog'+IntToStr(i+1), 'StartFrame' , 0 );
Dialog[i].NumOfFrames := Ini.ReadInteger('Dialog'+IntToStr(i+1), 'NumOfFrames', 0 );
Dialog[i].Text1 := Ini.ReadString ('Dialog'+IntToStr(i+1), 'Text1' , '');
Dialog[i].Text2 := Ini.ReadString ('Dialog'+IntToStr(i+1), 'Text2' , '');
Dialog[i].Text3 := Ini.ReadString ('Dialog'+IntToStr(i+1), 'Text3' , '');
end;
finally
Ini.Free;
end;
end;


I use the same dialog-unit in two programs (the game and the dialog editor). In the editor everything the following loads the info and everything is fine:

if OpenDialog1.Execute then
begin
ListBox1.Clear;

LoadDialogFromIni(Dialog, OpenDialog1.FileName);

for i := 0 to High(Dialog) do
ListBox1.Items.Add(Dialog[i].Name);
end;


However in the game I use:

LoadDialogFromIni(Dialog, AName + '.dlg');

and it doesn't load. :(

Any ideas?

Useless Hacker
28-11-2003, 07:11 PM
I can't see anything major that is wrong. What exactly happens when you call the load function in the game?

At the begining of the load function you have Dialog := nil; which I don't think you need.

cairnswm
29-11-2003, 09:31 AM
Setting Dialog to Nil is actually really bad :)

In a var section if you define a variable to be a record it allocates the memory for the record equal tot he size of the record, (unlike objects in which only space for a pointer is created which is then allocated when you create the object - the pointer then points to the object somewhere).

By setting the record to Nil you are leaving all the memory currently used by the record still in memory with nothing indicating to the program where it is.

Then the record doesn't have any memory and you are trying to put something into it - think of it like trying to pour water into a non exstant glass - the water is going to go somewhere you dont expect - so the values that you are allocating to Dialog ar not being put anywhere (except maybe over the OS memory segment) and you are probably getting access violations (though delphi isn't too good at picking up non pointer based access violations).

Hope that all makes sense :)

Ultra
29-11-2003, 02:09 PM
Nothing happens when I call the function in the game. High(Dialog) return -1 so it's like the file didn't exist (or had no info in it). Anyway, FileExists returns true so it should be there.

@cairnswm
Yup, that makes sense. :wink:

WILL
30-11-2003, 07:17 PM
Just so you know...

When you do this
Dialog := nil;
...this is how you would deallocate dynamically assigned memory blocks and objects aswell.

ie. if you were to declare Dialog and use it like this
TDialog = class(TObject)
a: Integer;
b: String[12];
end;

...

var Dialog: TDialog;

...

Dialog := TDialog.Create;

...

You could then destroy the object by assigning 'Nil' to it.