AGS v2.7 Final: Yet Another Edition

Started by Pumaman, Sat 13/11/2004 21:02:00

Previous topic - Next topic

Snarky

But true/false are just #defines for 1 and 0, right? There's no boolean data type.

Gilbert

I'd rather there be NO specific boolean type, I never have problem with non-zero being true and 0 being false, I just don't wanna script with a language too restricted by its format and rules.

strazer

No, they're enums.
Just open the roomedit.clb file in a text editor and scroll down to view all the goodness.

Alynn

Ok... sorry for the Kudos... but Damn... I go to Iraq for awhile and Puma gets all OO on me... not that I mind... now if I switch from Java to AGS (which I do often, I get bored with one code snip, then switch to another)...

I have a tendoncy to not be able to pull my brain out of OO mode heh...

But good stuff Chris, I may wait to start back work on STR to use all the goodies in here (sure it means recoding... but hey... who has never done a little recoding in their lives)

MUAHAHHAAHHAH

Thanks again... you made my life livable again.... Not that it wasn't before.... I just wanted to give you a warm feeling inside.

RickJ

Quote
Ideally I would like to completely OO-ise it, but practically speaking I don't think I will. Global functions like SetScreenTransition, while you could argue should be a static member function like  Game.SetScreenTransition, doesn't really bring any benefit in doing it that way; whereas things like characters, objects, GUIs, etc really lend themselves intuitively to OO.
As people get acustomed to the OO way of doing things there are sure to be future requets for more.   A Game object would make more sense if one could do something like Game.ScreenTransition = eDisolve or myvar = Game.ScreenTransition.  It would be a clean way of  handling  the GetGameParameter() type of items that seem like are always requested and would eliminat need for many Set/Get functions.  What do you think?

Quote
Yeah, I am still pondering pointers... I definitely would like to add them once I've worked out how to take care of the technical issues.
From some of your previos comments I am guessing that you probably will need to use pointers to entries in some sort of symbol table rather than memory pointers to the actual variable or object.   When I worked at GE I helped develop a Relay Ladder Language, a script language of sorts as it was byte code interpreted.  Pointers were handled in a manner that was simpler and somewhat more restrictive than in C/C++

  • There was only one type of pointer, pointer to variable implemented as an offset into the symbol table.

  • There wasn't a reference operator.  A simple assignment statement  such as pointer_var=myvar would assign the reference to the pointer variable.

  • There wasn't a dereference operator.  The language consisted of asm function library and a handful of boolean operators.  Dereferencing and other pointer operations, were done within the library asm functions. 

  • The command line monitor program, when asked to display or modify a pointer variable, would automatically convert variable table offsets to symbol names so that the end user would work with symbol names.  This seemed to make the concept of pointers easier to grasp and their use less error prone for factory electricians and other non-programmeres.   

    I don't meam to suggest that the above is an optimal, complete, or even an apporpiate solution for AGS.  I thought that perhaps a different perspective would be of some help to you in your efforts with pointers. 

    I'm looking forward to updating BlueGui using the  new methodology.  Can't wait ...

Pumaman

Quote from: Radiant on Mon 29/11/2004 23:38:19
it seems to me that any default value should be zero, for clarity's sake - so the parameter may have to be called 'background' rather than 'blocking'.

Personally, I disagree with this ... I think the default value should simply be whatever people are most likely to use. The default value should cater for the majority of calls to the function.

Yes, there is a "bool" enum with "true" and "false" values. Currently they just map to 1 and 0, and I'm not planning on doing a Java-style strictness where you can't convert int to bool.

QuoteOk... sorry for the Kudos... but Damn... I go to Iraq for awhile and Puma gets all OO on me...

Hehe, hope you get to come home soon, you've been out there quite a while now ;)

QuoteAs people get acustomed to the OO way of doing things there are sure to be future requets for more.   A Game object would make more sense if one could do something like Game.ScreenTransition = eDisolve or myvar = Game.ScreenTransition.

Oooh good point, why didn't I think of that? A better example then is probably a function like DeleteSaveSlot or GetTime, which doesn't really map to object-ness in any way, and I can't see a benefit from trying to do so.

QuoteFrom some of your previos comments I am guessing that you probably will need to use pointers to entries in some sort of symbol table rather than memory pointers to the actual variable or object.

Thanks for your ideas. Yeah, I think it'll have to be some form of quasi-pointer because of the need to save the game. If there was no need for save/restore, pointers would be an easy matter of just storing the memory address, but no such luck ;)

Java and .NET have good ideas on how to do pointers -- they're actually stored as memory handles which get resolved to the actual memory address at runtime, and that sort of approach can probably work with AGS.

Anyway, I'll have a tinker at the weekend.

RickJ

Quote
Java and .NET have good ideas on how to do pointers -- they're actually stored as memory handles which get resolved to the actual memory address at runtime, and that sort of approach can probably work with AGS.

Just a bit more thingking about pointers.  You already have characters and objects in a table format.  Why couldn't you implement pointers using somthing like the following construct?

struct POINTER {
     int type;    ///  OBJECT, CHARACTER, GUI, USER, ....
     int id;
}

The "type" component would identify which table to look into and the "id" component would be the offset.   So you have a situation like so:

POINTER ptr;
ptr = object[7];

would result in:
ptr.type == eOBJECT
pty.id == 7

AGS would, of course,  need to use this info to get at the actual mem pointers...   hmmm,  or would it?   I mean internally wouldn't it just be a couple of extra steps to decopose such a pointer into object[7] and then just continue as is done currently.   

This may also may be a sensible way to deal with pointers in the script.  Everyone is fairly familiar with the concept of things having id numbers.  So for them a pointer would just be the id number bundled with the type of thing it is.   

I'll be interested in seeing what you come up with this weekend.  Cheers!


RickJ

#87
CJ,

Tried converting some of my current stuff and got the following error message when trying to test the game.   

An exception 0xC0000005   ...
ACWIN.EXE at EIP = 0xBFF8C158 ...
program ptr is -189
ACI Version 2.63.786

I have a safe copy so I'm not in a bind or anything.  Thought you might want to know about this.  If you want a copy of the source that produced the error just let me know. 

[edit]
String Types with in Oobjects

I may have found another problem accessing strings within an object.   I believe the statement StrCopy(this.filename, filename); causes the exception.   I don't know if you intended strings to be supported by the new object stuff or not, but I don't think it works at this point.  There is an example below.

Script Header
Code: ags

#define CFG_SIZE 500

struct IniFile {
   int    fp;            // file handle 
   char   modified;      // TRUE if changed, FALSE otherwise
   string filename;
   char   db[CFG_SIZE];
   import function Open(string filename);
   import function ReadInt(string section, string option);
   import function ReadStr(string section, string option,string value);
   import function WriteInt(string section, string option,int value);
   import function WriteStr(string section, string option,string value);
   import function Close();
};


Global Script
Code: ags

function IniFile::Open(string filename) {
   // Read in an INI type config file 
  
   // Open the file
   this.fp = FileOpen(filename, FILE_READ);
   StrCopy(this.filename, filename);       // Execution of this line seems 
                                                              // to cause a fata error

   // :
   // : 
}


Room Script
Code: ags

function room_b () {   // any click on hotspot

   IniFile Cfg;
   Cfg.Open();
}



Oobjects in Room Scripts
I tried this and then read the docs at the beginning of the thread.  I was hoping to be able to do this at some point in the future.  This would allow all of the loop/view/id stuff to be embedded in an Oobject so that, for example,  to implement a specific door in a specific room one could simply have something like door.open() or door.close.    In another room  there could also be door.open, door.close but would work in different manner (i.e. different views, ids, etc, or functionality). 

Is this something that is planned or should I just put it out of my mind ?   :)


Pumaman

Hmm that's strange -- if it's reproducible then yes, could you please send me a copy of the gmae that causes the problem.

RickJ

#89
Ok here is a link to the converted game that causes a problem. 

http://www.gaia-spa.com/project/ags/Test.ZIP

Please re-read my previous post as I added two more questions while you were responding to it.  Thanks

*** Edit



One more OO question please.   Have you considered about allowing OOobjects to have both private and public functions?   If so perhaps just replace the "import" directive with "private" or something. 
 
Code: ags

Rui 'Trovatore' Pires

I keep meaning to say this, but I keep forgetting. About auto-complete again. You say, CJ, that we no longer have to remember every single thing, due to the way it works now. That is true, and most welcome it is too, but let's take AnimeObject. Let's say I type "AnimeObject(" and then PASTE the coordinates I've previously gotten from the room. Auto-complete no longer will show, and will not give us those so nice extra "eBlock" and "eRepeat". Can this be changed?
Reach for the moon. Even if you miss, you'll land among the stars.

Kneel. Now.

Never throw chicken at a Leprechaun.

Pumaman

Rick: I tried your test game but I didn't get a crash. All I got was it ran through the first room and then got an Array Index Out of Bounds error on global script line 1075.
At what point does it crash for you?

QuoteI may have found another problem accessing strings within an object.   I believe the statement StrCopy(this.filename, filename); causes the exception.

Yes, strings within structs are not supported. This is the main reason why structs are an undocumented feature. I'll update the compiler to give an error message if you do this, to clarify matters.
The workaround is to do:
char filename[200];

QuoteOobjects in Room Scripts
I tried this and then read the docs at the beginning of the thread.  I was hoping to be able to do this at some point in the future.  This would allow all of the loop/view/id stuff to be embedded in an Oobject so that, for example,  to implement a specific door in a specific room one could simply have something like door.open() or door.close.   

I'm not entirely sure what you're getting at here. If you're referring to inheritance so that you could add methods to an object then I can't make any promises about that I'm afraid.

QuoteOne more OO question please.   Have you considered about allowing OOobjects to have both private and public functions?   If so perhaps just replace the "import" directive with "private" or something. 

That's a possibility for future -- for now I just want to get the basics all working in OO-fashion for 2.7.

QuoteI keep meaning to say this, but I keep forgetting. About auto-complete again. You say, CJ, that we no longer have to remember every single thing, due to the way it works now. That is true, and most welcome it is too, but let's take AnimeObject. Let's say I type "AnimeObject(" and then PASTE the coordinates I've previously gotten from the room. Auto-complete no longer will show, and will not give us those so nice extra "eBlock" and "eRepeat". Can this be changed?

Assuming you mean MoveObject (since Animate doesn't use coordinates), then if you were to paste in the X/Y co-ordinates, then when you press the comma key autocomplete should automatically re-appear as usual. The ( and , keys should trigger autocomplete.

RickJ

#92
Quote
I tried your test game but I didn't get a crash. All I got was it ran through the first room and then got an Array Index Out of Bounds error on global script line 1075.
At what point does it crash for you?
It crashes right at startup.  I may even happen before the video mode is switched etc.  I happens both when I do a Test or when I execute the exe directly.   I didn't have any problems with V2.62.   

I guess I'll go check line 1075 and see what's going on there and let you know if I can get it to work.  Maybe I'll just start doing surgery until the problem goes away.  If you can't repoduce the problem then there probably isn't much you can do on your end.   If you have any other ideas or things you would like me to try just let me know.

Quote
Yes, strings within structs are not supported. This is the main reason why structs are an undocumented feature. I'll update the compiler to give an error message if you do this, to clarify matters.  The workaround is to do:
char filename[200];
I didn't know if you had intentions to support them as part of the OO stuff or not.     I don't mind the workaround much because it is less wasteful of memory.  Conversions between string  and char[] is a bit inconvient at the moment though.  Maybe some day I'll ask you to add a couple of functions; one to copy a string to a char buffer and another to do the reverse. 

Quote
I'm not entirely sure what you're getting at here. If you're referring to inheritance so that you could add methods to an object then I can't make any promises about that I'm afraid.
I wasn't thinking of inheritance at all but rather scope.  I would like to define  OObjects that have scope only within a specific room.   Specifically I would like to declare the struct and methods/functions within a Room Script so that they would only have scope within the room.   So that in the room script I could do someting like this. 

Code: ags

function room_b() {
   FrontDoor.Open();
   BackDoor.Close();
}


All of the object, view, loop, and sound id numbers could be embedded in the OObject definition, making the game/interaction logic cleaner and easier to read.  Anyway that's what I was askin about.

Quote
That's a possibility for future -- for now I just want to get the basics all working in OO-fashion for 2.7.
I understand.  I have been playing with that read/write INI file thing using the OOisms.  In several instances I found opportunities to excise code and put it into  utility functions.  I haven't done so, so as to keep everything as part of the object.  Private functions would have ben ideal for this. 

The other thing I wish were available is a way to initialize an object in some way.   I don't mean this in the sense of constructor/destructor functions.  A flag would be enough so that when the object is created (i.e. MyObjDef  MyObj;)  the flag would be set to a known value (i.e. 0 would work just fine) and not just a random value.  The methods then could be able to know if this is the first time they are running.   I know, :)  the workaround is to simply call the init method before doing anything else. 

Anyway these are just a couple of things that occured to me while I have been trying out the "make your own object" stuff.  I really like it and I am looking forward to upgrading the BlueGui and AnimationEngine. 




*** Edit

I think I saw something above about the editor and the auto indent feature.  I am finding that pressing ENTER after a closing brace "}"  causes it to unindent to the next outer level of indentation.....

Never mind :-[ operator error.   It's because I was manually backing up the brace to align with the "if" on the previous line and then of course pressing enter after that casues it to backup again.  Now that I know how to use it  ::) it works just fine for me.   

Pumaman

QuoteIt crashes right at startup.  I may even happen before the video mode is switched etc.  I happens both when I do a Test or when I execute the exe directly.   I didn't have any problems with V2.62.   

Hmm yeah, EIP -189 is the free disk space check, which is done before any of the game scripts are loaded. I don't know why on earth that should suddenly start crashing.

The only thing I can think of is that the call to GetDiskFreeSpaceEx is for some reason crashing the game, but it's been there for ages and I've never seen a problem with it before. Bit of a mystery, I have to say.

QuoteI didn't know if you had intentions to support them as part of the OO stuff or not.     I don't mind the workaround much because it is less wasteful of memory.  Conversions between string  and char[] is a bit inconvient at the moment though.  Maybe some day I'll ask you to add a couple of functions; one to copy a string to a char buffer and another to do the reverse. 

It's not something I'm planning on implementing particularly soon, but it'd be handy to have one day. As for converting between them, StrCopy accepts a char array for either parameter, so it shouldn't be a big deal.

QuoteI wasn't thinking of inheritance at all but rather scope.  I would like to define  OObjects that have scope only within a specific room.   Specifically I would like to declare the struct and methods/functions within a Room Script so that they would only have scope within the room.

You can place the struct definition in the room script rather than the script header, and that should then make it local to the room.

QuoteThe other thing I wish were available is a way to initialize an object in some way.

Global variables are always initialized to 0; but local variables don't have any way of knowing at present.

QuoteAnyway these are just a couple of things that occured to me while I have been trying out the "make your own object" stuff.  I really like it and I am looking forward to upgrading the BlueGui and AnimationEngine. 

Thanks for your comments :)

Radiant

Quote from: Pumaman on Sat 04/12/2004 12:26:36
Hmm yeah, EIP -189 is the free disk space check, which is done before any of the game scripts are loaded. I don't know why on earth that should suddenly start crashing.
Er, maybe his disk is full? Windows does tend to behave very strangely when confronted with limited resources.

QuoteGlobal variables are always initialized to 0; but local variables don't have any way of knowing at present.
I believe it would be nice for local variables to also get initialized to zero (since the alternative is making them 'undefined'...)

RickJ

#95
Quote
EIP -189 is the free disk space check, which is done before any of the game scripts are loaded .... Bit of a mystery, I have to say.
I only have 2GB free disk space :( but since AGS doesn't mind when starting games then I suppose this is enough.  Right, so I'm back to dismantling the offending program to see if I can find the problem by the process of elimination.   

Quote
StrCopy accepts a char array for either parameter...
:o  No s#@%t!  Well that's all I need!   
***** EDIT ******
I got a type mismatch error when a character array is specified as the destination in the statement "StrCopy(this.name, name)" .   

Actually, if this were to work, then all I need would be a StrnCopy() function added some day.   
****************

Quote
You can place the struct definition in the room script rather than the script header, and that should then make it local to the room.
I get a compile error  "Error (line 7): Variable 'TestObj::Init' is already imported " when I do this ....
Code: ags

// room script file
struct TestObj {
   int    var;
   import function Init();
};

function TestObj::Init() {
   this.var = 0;
}

TestObj MyObj;

#sectionstart room_a  // DO NOT EDIT OR REMOVE THIS LINE
function room_a() {
   // script for room: Player enters screen (after fadein)  
   MyObj.Init();
   SetCursorMode(6);
}
#sectionend room_a  // DO NOT EDIT OR REMOVE THIS LINE


Quote
I believe it would be nice for local variables to also get initialized to zero (since the alternative is making them 'undefined'...)
Radiant, I don't usually depend on variables being initialized to anything and normally prefer initializing them in the declaration (i.e. int var=0).   My point was that there doesn't appear to be a way of doing this with variables that are contained within a user defined OObject.

Pumaman

Quote from: Radiant on Sat 04/12/2004 13:05:18
I believe it would be nice for local variables to also get initialized to zero (since the alternative is making them 'undefined'...)

Actually, I've just checked the code and it looks like they do -- well, basic types, anyway. Structs don't, which is a bit inconsistent I guess.

QuoteI only have 2GB free disk space  but since AGS doesn't mind when starting games then I suppose this is enough.  Right, so I'm back to dismantling the offending program to see if I can find the problem by the process of elimination.   

Is it just this particular game that causes the problem?

QuoteI got a type mismatch error when a character array is specified as the destination in the statement "StrCopy(this.name, name)"

I just gave it a quick test with this:
StrCopy(character[EGO].name, "Roger");
and it compiled fine. How's your struct declared?

QuoteI get a compile error  "Error (line 7): Variable 'TestObj::Init' is already imported " when I do this ....

Ah yeah, that will happen in a room script, sorry I forgot about that.

Alice12

Can AGS add the support for multibyte in the TTF Font?
thx....

Pumaman

Alice: I know you're keen to have this, and the last time you asked I did say it'd be in 2.62, but other priorities have taken over for now, it's still on my to-do list.

Anyway, beta 5 is now up! This adds pointer support. What does that mean? Well, it means that for one the "player" variable is now always kept up to date with the player character so it's actually useful! Also, there are new named character objects for each character -- the naming is like this:
cEgo

ie. "c" for character, followed by the script name in sentence case. So:

cEgo.Walk(10, 40);

is identical to:

character[EGO].Walk(10, 40);

For the next version I'm aiming to add something similar for objects and for GUI items.

The new File I/O functions now demonstrate another use for the pointers support -- it's now much more intuitive than having to pass the handle around everywhere.

Can you do your own pointers? Well, yes and no.
You can create a pointer to any of the AGS types (characters, objects, files), but not to your own structs. You can also only have local variables as pointers -- globals are not supported. This is because supporting global pointers throws up save game issues and makes it possible for your script to have memory leaks; I'll think a bit further about whether to implement this.

Anyway, have a play and most importantly, let me know if anything doesn't work properly. Play about with pointers -- for example, you can have a custom function take a character rather than a CHARID as its parameter:

function FaceLeft(GameCharacter *theChar) {
  theChar.FaceLocation(-100, theChar.y);
}


Finally, I've decided to start adding icons to the editor menus. Donations welcome!!! Menu item icons must be 16x17 pixels (and make sure to leave a 1-pixel border within that, or it'll look strange).

Snarky

Sweet! AGS is becoming quite the powerful programming language...

What icons are you looking to add? Posting from a work computer, I can't really go and install AGS here.

SMF spam blocked by CleanTalk