Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - AGKorson

Pages: [1] 2
I'm working on a demo game to show off some advanced AGI coding techniques. But I need a bit of help with the art.

SPOILER ALERT: Imagine native support (i.e. no hacked interpreter files needed) in AGI for things like mouse support, 80 column text mode, MIDI and FM synth (e.g. Adlib, SoundBlaster) sound support, extended characters, full control of color palette, dynamic menus, data file input/output, customizable status line, and much more! Just drop the AGI Power Pack logic script into your game, and you get it all! Without using any resource memory!

I am not an artist. (If you've seen the WinAGI template game rooms you know what I mean.) So I'm looking for someone to help with 8 - 10 rooms so this demo will not look like a two-year old drew it with crayons.

The setting is an office building- I need some offices, a reception area, hallways, stairwells, a closet, stuff like that. If this is something you can help me with, send me a PM.


AGI Development Tools / WinAGI 2.2.3 goes International (sort of)
« on: June 04, 2022, 07:52:17 PM »
Here's the newest version of WinAGI:

The big change in this version is support for non-English MSDOS codepages, which makes it much easier to edit resources in other languages. If you never intend on using extended characters or working in a language other than English, there's no reason to change from the default MSDOS codepage (437). (But I would still advise upgrading to this version; it also fixes a few more minor bugs, including the issue that causes it to fail on older versions of Windows.)

AGI doesn't contain any native support for non-English text/fonts. And showing extended characters on screen (other than in the text.screen mode) is not normally possible. So why bother adding this feature to WinAGI?

Using the string hack technique, it is possible to get AGI (when running on DOSBox, or on an actual MSDOS machine) to show all characters in whatever codepage the environment is set to. You can also get AGI to allow inputting letters with diacritics on the input line to let players use non-English words to play a game.

The logic code needed to make this work is very complicated, and formatting foreign words in your WORDS.TOK file is also quite complicated, but if you are interested in doing this, WinAGI now lets you edit your resources in the same codepage that your game will use, making translations (or creating new games in non-English) much simpler. It will also create word lists with non-English words (which are simply ignored in 'normal' AGI but work perfectly when paired with the codepage string hack technique).

AGI Development Tools / WinAGI Version 2.1.16 Available for Download
« on: March 15, 2022, 10:53:33 PM »
Version 2.1.16, which fixes the Import Game feature so games with invalid directories or resources will now load all other correctly formatted resources and provide feedback (warnings) on any invalid resources, is available here.

AGI Development Tools / WinAGI Version 2.1.15 Available for Download
« on: February 15, 2022, 02:26:14 AM »
Version 2.1.15, which fixes the 'New from Template' bug, is available here.

This version includes a bunch of other minor bugfixes. The help file has also been significantly enhanced to provide more detail on AGI.

If you encounter any more bugs, please let me know. I don't plan on any more feature updates to the VB-created version, but if there are significant bugs that need attention, I will continue to provide bug fix updates.

For those that are interested, I am still working on a C# version of WinAGI that hopefully will be able to be ported to other platforms. But it is VERY slow going; there is still a lot about C# programming (especially dealing with the user interface - forms, controls, etc) that I don't understand very well. I'll try to keep going, but I have to admit there are times where I feel like I should just give up and let someone else take over, if there's anyone out there that would even want to. There are a lot of other things that compete for my free time, and I'm beginning to feel like I need to scale back 'AGI' time for some of those other things I enjoy.

For what it's worth, I haven't given up yet, and as much as I can I'll continue pressing forward.

In another thread, I was asked about the custom algorithm I created to move objects in a straight line, instead of AGI's default (that moves objects diagonally, then horizontally).

To demonstrate how it actually works, I created this little demo game - Flag Quest.

Flag Quest is a simple arcade-style game, where the object is to collect the flags on the screen while avoiding bombs that are shot at you by a roving saucer.

To play the game, you'll need your own interpreter files. It needs to be a version that supports menus and multiplication/division (MSDOS version 2.411 or higher on DOSBox). I haven't tested it on NAGI or SCUMMVM, but I think it should work just fine on those platforms too.

The bomb object (I guess I could have called it a missile, but I'm not much of an artist, and a simple pulsating 'bomb' graphic is about the best I could draw!) uses what I call the 'move.straight' custom movement method, instead of AGI's built-in 'move.obj' method. This custom method moves the object in the straightest possible line, so it looks more natural on the screen.

I developed this algorithm independently, but it is basically an implementation of the Bresenham line-drawing algorithm (which I only recently learned of). It uses signed 16-bit integer math to do the calculations that control the object movement. This means that some math 'tricks' are necessary to get AGI's unsigned 8-bit variables to mimic 16-bit signed numbers. The source code contains a lot of detailed comments explaining exactly how to do it.

The game also includes a detailed example of the custom status line feature that I discussed in this post. It's actually pretty easy to create any kind of status line that you want. Again, detailed comments are in the source code.

Speaking of the source code, Flag Quest was developed on WinAGI, so if you want to open it in AGIStudio, you will need to add include statements for the globals.txt file and reserved.txt file to every logic (WinAGI does that automatically). With a bit of minor tweaking, you should be able to get a version of this to compile in AGIStudio. But of course, because it's so much better, I'm sure you'll just use WinAGI anyway! :-)

In addition to the source code, I'm also attaching a copy of just the game files, if all you want to do is play the game without looking at the source code.

If you have any questions at all about how either technique ('move.straight' method and custom status line) works, just ask! I'd be happy to answer any questions!.

Oh, and if you encounter any bugs in the game, let me know! I did as much testing as I could, but it's always hard to get all the bugs out without an extra set of eyes doing the testing.

Enjoy! (And post a screen shot of your highest score. I'm curious to see that - I haven't made it past level 5!)

AGI Development Tools / Sierra's AGI Compiler (CG.EXE) Disassembled
« on: January 12, 2022, 12:57:29 AM »
I finally finished disassembling an early version of the AGI compiler, 'CG.EXE' to better understand the syntax and structure of original AGI source code. There are quite a few differences between this compiler's syntax and the currently accepted AGI syntax used by most modern compilers (such as WinAGI and AGIStudio) i.e. 'canon'. Here is a detailed discussion of the CG compiler (to act as a future reference) and I'll follow with a discussion on the most significant differences between 'canon' and what the original Sierra compiler actually supported.

The CG version I disassembled is version 3.14, from 1984 (I don't have the original file date; it got lost after moving/copying it over the past few years). But since it says it's from 1984, it appears to be a very early version 2 compiler. (If anybody has any more information on the exact date of this file, or what versions it may be specifically targeted to, that would be very helpful. Also, if you know of a more recent version of CG.EXE, I'd love to have it to do some comparisons.)

Running the compiler:
The compiler is a native MSDOS program (obviously, I think- but maybe not...) The usage form is
Code: [Select]
cg room [room...] [-o output_directory] [-b buffer_size] [-v]There are three possible command switches:
  • -o to set the output directory (where the compiled logic files will be saved) - The default is the current directory. The output directory can be any legal MSDOS directory name, including relative paths. If the path is not valid, the compiler will quit with an error. If the argument following the -o switch is missing, the current directory is used. If the argument is a valid directory, but does not exist, the compiler will run, but will raise an error at the end when it can't write the output files.
  • -b to adjust buffer size - The default is 1000h (4K). There's really no reason to change this, but it can be adjusted if you really want to. If the argument following the -b switch is non-numeric or missing, a value of zero is used, which will cause the compiler to fail immediately. Larger values means disk writes are minimized, but take up more memory. This was more of a concern in the 1980s than on today's systems.
  • -v to set 'verbose' mode - This switch does not take an argument. When used, it causes the output to display additional information, including the number of symbols and messages found in the source file, and information on the symbol hash table (explained below).

Arguments (command switches and source files) can be in any order. Each argument, including source code files ('room') must be separated by one or more spaces. Filenames have to be valid MSDOS filenames (no long-filenames) and can include path info and wildcard characters ('?' and '*').

If no arguments are passed, the usage information is displayed. If no source files are passed (only one or more command switch) the program switches to console mode, and source files can then be typed in separately. Pressing ENTER adds a file to the list, pressing CTRL+Z and then ENTER sends that list to the program, which are then processed.

Source filenames without an extension are assumed to have the '.cg' extension. If specified, any extension will work just fine. You can also pass a list of files by preceding the file that has the list with the '@' symbol; i.e. 'cg @roomlist.txt' will open the file 'roomlist.txt' and read each line as an input source file name. You can also specify DOS environment variables 'HEAD' and 'TAIL', which are added to the beginning and end of the file list passed on the command line. (I don't know what value that might have; it may be a generic feature that was automatically added when the cg.exe file was built.)

Source filename (not extension) must include a number, or the compiler will throw an error. The output file for a source is always the sourcefile truncated at the first number, with the number as the extension. For example, '' output is 'logic.1', 'log2a3.txt' becomes 'log.2', etc.

The maximum number of source files (including those specified by name, by wildcard and in file lists) is 200, which seems odd since AGI allows up to 256 logics in a game.

General compiler behavior:
In general, Sierra's compiler is intentionally designed to allow for changes/additions to the action and test commands without needing to rebuild the compiler itself. The compiler only manages the syntax used to access the commands; the commands themselves all need to be declared for the compiler every time it is run. The compiler only has a small number of keywords that are hard coded in the program. Because of this, even this early compiler can compile all versions of AGI source code. (With the exception of support for shorthand syntax for multiplication and division. More on that later.)

The compiler processes each source file separately. The sequence of actions is
  • parse input file name, build output file name
  • reset compiler parameters
  • open source file and assign to buffer space
  • create output file (overwriting any existing file) and assign to buffer space
  • initialize the hash table, adding predefined symbols
  • allocate space for output, and for AGI messages
  • compile the source (errors are displayed as they are encountered)
  • close the output file
  • display results, including total number of errors encountered
  • repeat for next source file

The compiler uses a single pass when compiling source; I may use the term 'preprocessor' occasionally through out this article, but keep in mind that unlike more modern compilers, all input is compiled linearly, in a single pass; so all declarations and defines need to be listed BEFORE they show up in source code.

The compiler converts all text fields (symbols) it encounters into a hash value (by summing the ascii values of all characters in the symbol, and then returning that value MOD 203). This value is then compared against entries in the compiler's symbol hash table to determine what it represents. If more than one symbol has the same hash value, the compiler creates linked lists for each hash value to avoid conflicts. If the number of symbols is too large such that all memory is used up to hold them, the compiler will throw an error and quit. (I have no idea what that maximum number might be, but on legacy equipment, memory was often a problem so it had to be closely monitored.) For obvious reasons, no duplicate symbols are allowed; if a duplicate is detected, the compiler throws an error. Symbols are case sensitive.

I don't know why the hash table is limited to 203 entries. There may be some valid mathematical reason for picking 203, but I don't know what it is. Regardless, the compiler easily handles that, by linking all symbols with the same hash value, and then using text comparisons when searching for a symbol that shares a hash value with other symbols.

The use of the hash table appears to be a speed enhancer; after converting each symbol to a hash number, it is very fast to then search for the matching number and extract relevant symbol information, instead of doing multiple string comparisons every time a symbol is encountered in source code. On modern CPUs, this wouldn't be a big deal, but in the 1980s, this would likely have been noticeable in showing increased compile speed.

On startup, the following symbols are added to the hash table: %include, %tokens, %test, %action, %flag, %var, %object, %define, %message, %view, #include, #tokens, #test, #action, #flag, #var, #object, #define, #message, #view, goto, if, else, FLAG, OBJECT, MSG, WORD, NUM, MSGNUM, VIEW, VAR, ANY, WORDLIST. These can be broken down into three groups:

  • 'Preprocessor' symbols:
    The symbols starting with '%' or '#' are compiler commands that add symbols to the hash table which tell the compiler how to handle other symbols it will encounter later. Note that there are two versions of each, with either the '#' or '%' character to start. There is no difference between them; the compiler just offers the flexibility to use either format. I will only refer to the '%' version even though either version is perfectly acceptable to the compiler. (I assume that in early MSDOS compilers, there may have been a difference between commands starting with either symbol, but this compiler doesn't care which is used).
    • %include: This symbol is used to include another source or header file. Syntax is:
           %include "filename.ext"

      The filename must be enclosed in double-quotes. It can include path information, but not wildcards. Included files can be nested, but there is a limit of 5 layers of nesting. More than that will cause an error.
    • %tokens: This symbol is used to load the WORDS.TOK file. Syntax is:
           %tokens "WORDS.TOK"

      The filename doesn't have to be WORDS.TOK, but it must be a valid AGI word file. It must be enclosed in double-quotes. It can include path information, but not wildcards. If you do not assign a WORDS.TOK file with the %tokens command, the compiler will enter an infinite loop if it tries process a 'said' command.
    • %test/%action: These symbols are used to declare AGI command symbols. None of the AGI commands are hard coded into the compiler; they must be declared at the beginning of the source code, typically in a header file that is included with the %include command. Syntax is:
           %test testname([arg1, arg2, ...]) cmdnum
           %action actionname([arg1, arg2, ...]) cmdnum

      The names of commands are well established by precedent (and by example from released original game code), but you can assign any name you want for any command. The arguments must be enclosed in parentheses, separated by commas. If no arguments, empty parentheses must be included. Arguments must be one of the pre-defined argument types (see below). The number of the command (the byte value that goes into the compiled logic) must follow the command declaration. It is imperative that the arguments assigned match exactly with the AGI command associated with the byte command number; the compiler will happily create code that has any combination of command byte values and arguments, but if they don't match what the interpreter expects, the code won't run.
    • %flag/%var/%object/%view: Flags, variables, screen objects and views can be assigned symbols using its designated preprocessor command. Note that there isn't a symbol command for numbers; the compiler doesn't convert numbers into a symbol. Syntax is:
           %flag flagname flagnum
           %var variablename varnum
           %object objname objnum
           %view viewname viewnum

      These symbol types correspond to the expected argument types that are used in command declarations. For example, if a command is declared with %action as '%action assignn(VAR, NUM)', a symbol of type %var must be passed as the first argument, and a number must be passed as the second argument. Note that these types are completely arbitrary, meaning as long as the command declaration matches the argument type passed in source code, the compiler won't have any problem. For example:
           %action assignv(VIEW, OBJECT) 3
           %view   a_view     5
           %object an_object 10
           assignv(a_view, an_object);

      will compile, and when run in AGI it would assign variable 10 to variable 5. Of course there is little practical value in using constructs such as this.
      The OBJECT argument type is used in most original Sierra game source for both screen objects and inventory objects. Care must be taken by the programmer to keep them straight, because the compiler won't do it for you.
    • %define: The generic define command allows you to assign a symbol to a number, text, or another symbol. This allows you to do things like:
           %var v0      0
           %define currentroom v0

           %var v200   200
           %define lvar1  v200
           %define counter  lvar1
           addn(counter, 1); [ same as addn(lvar1, 1) or addn(v200, 1)

      Symbols can be nested in this manner as deep as you want. As long as each symbol is defined before it is referenced, the compiler will continue substituting define values until it reaches a non-text symbol type (var, num, flag, msgnum, etc.)
    • %message: message symbols are just a bit different from other symbol assignments. Syntax is:
           %message msgnum "message text"
      Note that the number precedes the text value, unlike other symbols, where the number is last. The message text must be included in quotes. It cannot be split, i.e. the compiler will not automatically concatenate multi-line strings. The message text can be a symbol that was previously %defined to be a string value. For example
           %define aboutmsg "AGI Game, by Author"
           %message 1 aboutmsg

      will compile with no errors.
  • Keywords:
    There are only three key words that the compiler recognizes - 'if', 'else' and 'goto'. The syntax for 'if' and 'else' used by the compiler is identical to the AGI 'canon' syntax. 'if' statements must be in parentheses, curly brackets separate code blocks, etc. The 'and' and 'or' features are the same ('&&' and '||' as operators, and 'or'ed tests must be in parentheses). The exclamation point '!' is used for negation of test commands.
    The goto command does not use parentheses. Using parentheses will cause an error. The syntax is:
         goto label
    Labels are defined with a colon followed by the label name, with no space between them. If there is a space between them, the compiler will create a label using a null string (""), and the following text will be interpreted by the compiler as the next command symbol.
  • Argument types:
    Arguments used in action and test commands must be designated as one of ten different argument types. When declaring a command, the compiler expects a symbol with a type that matches the argument type, and it must be one of the predefined argument types for each argument. They are case sensitive, so 'var' is not the same as 'VAR'. With the exception of numbers and vocabulary words (from WORDS.TOK), all arguments must be passed as a symbol that was previously declared using the appropriate 'preproccessor' command. For example, if an argument is of type FLAG, you must pass a symbol declared with the '%flag' command.
    • FLAG: Use this argument type when you want a command to use a flag argument.
    • OBJECT: Use this argument type when you want a command to use a screen object argument.
    • MSG: This argument type is not used by AGI; it appears to be a legacy type that no longer works. The internal value assigned to it will actually create an error if you try to use this argument type in a command declaration.
    • WORD: This is another legacy argument type. If used, the compiler will expect a single word from the WORDS.TOK file. There are no AGI commands that take a single word as an argument. (Earlier versions of AGI did use a 'said' command that took a single word as an argument.)
    • NUM: Use this argument type when you want a command to use a numeric argument value.
    • MSGNUM: Use this argument type when you want a command to use a message number as an argument value. The message must be properly declared with %message before it is used in a command.
    • VIEW: Use this argument type when you want a command to use a view argument.
    • VAR: Use this argument type when you want a command to use a variable argument.
    • ANY: This argument type should not be used in command declarations. It is an internal type that is used when the compiler is handling shorthand syntax such as 'v0 = v1;'. Technically, you could use this in a command declaration, in which case, any valid symbol would be compiled. But using strict argument typing helps prevent bugs by forcing the game programmer to use correct argument types.
    • WORDLIST: This argument type is only used by the 'said' command. It acts as a placeholder for one or more words from the WORDS.TOK file. Its placement at the end of the list suggests it was added after the 'said' command was changed from having a single word argument to a variable number of arguments. Unlike modern AGI compilers (WinAGI and AGIStudio for example), argument values are not passed as double-quoted strings; instead they are passed quote free, and the dollar sign ($) is used in place of spaces. For example, if your word in WORDS.TOK is 'save game', it would look like this in a 'said' command:
Shorthand Syntax:
The compiler provides limited support for shorthand syntax in lieu of command names. But instead of just recognizing the shorthand command and directly adding the appropriate byte code, the compiler actually inserts the matching command symbol into the data stream, as if it had been typed in the source code and then compiles that symbol. This means the declarations of shorthand commands must exactly match the internal spelling. For example, you can't create a custom action command for the assignn function (byte code 3); you must declare it as 'assignn'. (You could create a #define value to assign another different command text value to assignn though.) The supported shorthand commands are:
  • '++' and '--' can be used as shorthand for increment/decrement. The operators must precede the variable being modified. So
         ++variable1; [ OK
    will compile, but
         variable1++; [ syntax error
    will throw an error
  • assignn/assignv, addn/addv and subn/subv can be replaced with 'v# = #/v#', 'v# += ##/v#' and 'v# -= ##/v#'. For addition and subtraction you can't use the longer notation 'v# = v# + ##'. For example:
         v1 = v2;  [ OK, same as assignv(v1, v2);
         v1 += 1;  [ OK, same as addn(v1, 1);
         v1 -= v3; [ OK  same as subv(v1, v3);
         v1 = v1 + 2; [ NOT OK, syntax error
  • left and right indirection can be replaced with '@v# = #/v#' and 'v# = @v#'. Note this is different from modern compilers that use the asterisk/star character (*). For example:
         @v1 = 1;   [ OK, same as lindirectn(v1, 1);
         @v2 = v3;  [ OK, same as lindirectv(v2, v3);
         v4 = @v5;  [ OK, same as rindirect(v4, v5);
         *v1 = 1;   [ NOT OK, wrong indirect symbol
  • for test commands, '==', '>',  and '<', can be used in place of  equaln/equalv, greatern/greaterv and lessn/lessv. '!=', '>=' and '<=' can be used in place of the negated versions of these commands.
  • flags can be tested by their name; i.e. 'if(flag1)' will compile as if it were 'if(isset(flag1)'.
  • variables can also be tested by name; 'if(var1)' will compile as if it were 'if(greatern(var1, 0)'
This compiler version (3.1.4) does not include shorthand for multiplication or division, which makes me believe it's probably an early AGI version 2 tool (multiplication and division weren't added until version 2.411).

Miscellaneous Syntax Information:
Commas and semi-colons are completely interchangeable. You can use either to separate arguments in a command, or to mark the end of a line.

The compiler does not require the end of line marker. Commands can be separated by one or more spaces, a line feed (not a carriage return), a semi-colon, or a comma. Line feeds (ascii value 10) but not carriage returns (ascii value 13) mark new lines. Carriage returns are completely ignored.For example:
     assignn(v1, 1); [ OK
     assignn(v2; 2) ,, assignn(v3;3)  [ OK
     [ OK; same as first line

For numeric arguments, the compiler does not enforce unsigned byte values. If a number value is greater than 255, the compiler uses number MOD 256. Negative numbers will also compile without error; the compiler converts them to 2s-complement (and will also MOD it if result is > 8 bits).

The only supported comment tag is the open square bracket ([). Double-slash (//) is not supported by the compiler, nor are block comments.

A 'return' command (byte code 0) is automatically added by the compiler. If the source code ends with a 'return' command, the resulting compiled logic will in fact end with two return byte codes.

Syntax Differences:
So what are the biggest differences between original Sierra AGI syntax (as enforced by the CG.EXE compiler) and current fan-based 'canon' syntax? And do any of them warrant adjusting what modern compilers enforce?
  • The additional argument declaration types, as well as the action and test declarations, do give more flexibility to writing source code. WinAGI and AGIStudio have built-in command declarations, and manage argument types by prefix. That's probably sufficient, although adding the ability to declare your own command names as an override (overload?) is something I think I might add to the next iteration of WinAGI.
  • WinAGI already supports negative numbers, which I think should be added to the 'canon' syntax.
  • Sierra's CG compiler doesn't use double-quoted strings for 'said' command arguments. The more I think about it, the more I like that idea, because I think it would make source code a bit easier on the eyes, allowing you to quickly tell the difference between actual message text and said command arguments. I might add this as an option for future WinAGI releases.
  • Indirection is also one that's different (using the '@' instead of '*'), but I don't think it's worth making any changes/additions to 'canon' syntax rules; the star is probably a lot more intuitive to modern programmers.
  • Although original compiler is very liberal with how it manages separations (allowing commas and semi-colons to be treated the same for example), I think the stricter enforcement in the 'canon' syntax is actually a good thing.
  • Labels, and increment/decrement having their operators BEFORE the symbol is something that WinAGI already supports, even though current 'canon' syntax doesn't include it. I don't think the post-fix versions should be eliminated, but I do believe the canon rules should be changed to allow the pre-fix versions as well.
  • Long-hand arithmetic (i.e. v1 = v1 + 1; instead of v1 += 1;) is also something that I think is fine to leave in 'canon' even though not supported by original Sierra compiler. Using goto like an AGI command (by requiring the destination to be enclosed in parentheses) is also something that should remain in 'canon', despite not being supported by the original.

OK, that was quite a bit of information! Honestly, though, it was mostly a thought exercise - I enjoy taking apart the binary code of AGI tools to get to the learn all the inner workings. The AGI community doesn't seem particularly strong these days, so I don't really expect there's much discussion to be had around any kind of 'official' or 'canon' AGI syntax. I'll probably just add those things that I think are worth it into the next WinAGI without worrying too much about whether it would be compatible with AGIStudio or any other compiler.

Anyway, feel free to comment/discuss/correct any of the above information. I'd be happy to respond.

AGI Development Tools / Mouse move target question
« on: September 29, 2021, 02:44:21 PM »
This is really a more generic question, but I'll ask here because it relates to a current AGI project.

When a mouse is used to move ego, you click a spot on the screen, and ego moves to that spot. However, since ego has a non-zero width, what is the best way to position ego horizontally (in the X plane)? I can think of three options:

  • Easiest option is to just set ego's position to the targetX, regardless of where target is. But this means if you click to the RIGHT of ego, ego's left edge will move to the clicked location. This feels weird though - I expect ego's right edge to go where I click in that case.
  • Another option is to set ego's position to the targetX if clicking to LEFT of ego, but set it to targetX-width if clicking to RIGHT. If clicking in between left /right edges, ego's center is moved to target location. This feels a lot better to me than option 1.
  • A third option, similar to second, but instead of moving the center of ego to the targetX when clicking in between left/right edges of ego, just move ego vertically (ignore targetX in that case).

Any opinions on which option is best? I am leaning toward option 2, but I wonder if option 3 feels more natural to a player. Any other suggestions on positioning ego in the X-plane?

AGI Development Tools / WinAGI Version 2.1.10
« on: March 06, 2021, 02:29:37 AM »
The console mode that I added in version 2.1.6 was a bit of a hack, and I just couldn't leave it that way. So here's an update that includes a separate executable, conWAGI.exe for running a windowless console mode. It's a much cleaner implementation and it supports importing games (creating WinAGI game files from an existing AGI game) and all three compile options. (The main app also includes a couple minor bug fixes.)

You can get the latest version from the AGI wiki. Here's a direct link to the install file:

I am still working on a C# version of WinAGI. I got the all the basic AGI library functions moved over, and have a working app that can display all resources. There are no resource editors or tools added yet, and it's not real stable; there are a ton of bugs, and it's easy to crash right now.

If anyone is interested, I guess I could share a link to the git files. Just don't make fun of my poor C# coding skills...

AGI Development Tools / WinAGI Version 2.1.6
« on: February 14, 2021, 11:31:06 AM »
OK, here's an update that addresses a couple bugs found in 2.1.5 and also adds a couple requested features.

Link to install file

- Fixed bug in settings functions that would not save MsgByNumber value
- Added menu item and toolbar button to show character map dialog on logic and text editors
- Modified error messages when read-only files are encountered so it is more clear to user
- Added command line switches to compile games without running the user interface
- Modified the GameID property to allow lower case letters

AGI Development Tools / WinAGI Version 2.1.5
« on: February 09, 2021, 10:12:13 PM »
This version adds an option to decompile logics with message argument tokens (m1, m2, etc.) instead of literal strings. Also addresses two minor bugs found by pierrelapin (when opening words.tok files with no group zero words and views with bad description pointers).

Link is here:

AGI Development Tools / WinAGI Version 2.1.4 Is Available
« on: December 02, 2020, 02:48:20 AM »
Here it is - the latest update to WinAGI. This version fixes a TON of bugs, a lot of enhancements, and some new features that I've heard folks asking about. I spent a lot of time testing, re-testing and testing again, so hopefully there aren't too many bugs left! :)

Link to the install file is here:

Here's a partial list of the new features:
  • Fixes bug in v 2.1.3 Picture Editor that disabled absolute line draws
  • Support for Apple IIgs sounds- both types of IIgs sounds (PCM sound samples and embedded MIDI) can now be previewed and exported as their native format (.wav and .mid).
  • A new LISTBOX option to display game resources (similar to the old AGI Studio look)- a number of people commented that they didn't like the tree list; now you can choose whichever display works best for you
  • NAVIGATION BUTTONS - when browsing through in game resources, there are now navigation buttons that let you quickly go back to previously previewed resources, and then forward again
  • improved support for multiple monitors; the program's position/size will now be correctly restored on systems with more than one monitor
  • the logic editor now highlights AGI commands as keywords, for improved readability
  • support for code snippets - shortcuts you can use to insert frequently used blocks of code to make coding go faster
  • ability to open resources for editing from within the logic editor; right-click on any resource ID to show the open command in the context menu
  • global defines (aka the 'defines.txt' included file) can now have individual comments for each define entry
  • option to export picture resources as an animated gif to see the picture drawn step by step
  • layout editor is synched to the resource list, making it easy to find a room on the layout editor when your layout is large and complex
  • DIR files now expand or contract based on number of resources, instead of being automatically expanded to full size; this helps keep memory usage to a minimum, since DIR files are part of the room.0 memory block
  • Much improved Help file, especially in the AGI Reference section; more in-depth analysis of the disassembled interpreter has resulted in a lot more knowledge of how the interpreter really works; the help file is now the real definitive source of information on AGI
  • a lot of other minor enhancements/improvements too numerous to mention

I was also able to do some testing with Linux. WinAGI actually runs virtually bug-free when run in the WINE environment. It does require a configuration fix in WineTricks (due to a bug in WINE's implementation of riched.dll), but once that's done, it runs just fine. So Linux users have access to WinAGI too.

Things seem to have really quieted down around here, especially in the AGI forums. I fear that the golden age of fan games may be at an end. I'm hoping that tools like WinAGI will help people who might be interested in creating their own games, but didn't know where to start.

So if there is anybody out there who still has interest in AGI, please take a look at this latest release. I think you'll be pleased with how much it helps in creating your next AGI masterpiece.

I have a new version of WinAGI mostly ready for release. But I would like some fresh eyes on it before I call it good.

Here's a list of the biggest changes/upgrades:
  • LISTBOX option to display resources (in addition to the original treelist option)
  • DIR files expand/contract as resources are added/removed (instead of staying expanded to full size)
  • application size/position saved correctly on systems with more than one monitor
  • NAVIGATION BUTTONS to allow user to step backward and forward through selected resources in the resource list; right-click/hold to scroll through the list
  • all agi commands are now highlighted as 'keyword' type in logics when using syntax highlighting
  • MANY fixes to the rich text box used in logic editor, so it does a better job of handling selections/edits/highlights
  • right-click on a resource ID in a source file, and you now have the option to open it from within the logic editor
  • SNIPPETS! you can use shortcut codes to insert 'snippets' (code fragments) of frequently used code
  • you can right-click on a word in a 'said' command to show a list of all synonyms of the selected word
  • transparency color of a cel is now shown on palette on view editor (ctrl+click to change transparency color)
  • added comment column to the global editor so you can add comments to each defined term
  • searching for vocab words in logics now has option to include search for all synonyms
  • added setting that syncs the resource list to the layout editor; selecting a resource in the list will automatically scroll the layout view so the selected room is centered in the window
  • hold down shift key with left mouse to drag the entire layout drawing surface
  • Find/Replace supports multi-line values
  • ... plus a TON of other minor enhancements, and countless bug fixes

I would like to have the new version ready for release in the next two weeks. So if you are interested in helping with one last good look to make sure there are no glaring issues, please PM me, and I'll send you a link to the install file.

AGI Community How To's & Tutorials / Creating a Custom Status Line
« on: June 24, 2020, 05:03:00 AM »
I got asked by a new user for help with creating a custom status line, as part of an effort to translate AGI games into other languages.  I thought I'd post my reply here in case anyone else has the same question.

It's not too tough to create a custom status line, but there are a few things that you need to consider to have your custom status bar behave exactly the same as the built in one.

To start with, you need a way to let AGI know whether or not you want the status line to show up or not. A flag is the obvious choice - say fStatusOn

With this flag, you can add code that runs in every interpreter cycle that uses the display() command to show your custom status line when fStatusOn is set, or clear it when the flag is not set.

While this is a good start, you will find that your status line will flicker, because it gets drawn in every cycle, even when there are no changes. To solve this, a second flag, fUpdateStatus, can be used to control when to draw the status line.  You can check this flag, and then only display or remove the status line when fUpdateStatus is true.

When you do need to update the status line (for example, score has changed), set fUpdateStatus to true.

This solves the flickering problem. And the result will work almost exactly the same as the built in status line. But there are still a couple more things you need to do to handle a few edge cases.

The first is dealing with the menu. When the menu.input() command is called, AGI will display the menu at the start of the next interpreter cycle. Assuming your menu is on the same line as your status line (as is the case with almost all Sierra AGI games), it will overwrite your status line. After dismissing the menu, your status line is erased. The way to solve this is to use fUpdateStatus after the menu.input() command. To reduce flickering, you also should place your code that draws your status line BEFORE the menu.input() command.

The second thing to consider is any code that implements the text mode. That would be the status() and text.screen() commands. You will need to force your status line to redraw after either of these commands run, because your status line will get erased when AGI switches modes.

A sample logic is attached that contains code (with lots of comments) that demonstrates this. Using this approach, you can create your own status line that is as complex or as simple as you like.

I've been experimenting more with the use of the StringHack to improve AGI's functionality. For those of you who wish to use extended characters in messages (for example, French or Spanish), I have written a logic that will modify how AGI displays characters so that the extended characters display correctly.

All you need to do is add the logic (see next post, below) to your game, and run it once when the game first loads. After that, all characters, including extended characters will display correctly in print() messages.

Here's some sample output to see it in action:

A couple of caveats:
  • this will ONLY work with the original DOS interpreter (through DOSBOX or running on native DOS system); it won't work with NAGI, SCUMMVM or any other modern interpreter.
  • this will ONLY work with AGI interpreter verison 2.917. Each version has slightly different addresses for its internal functions; this logic is hard coded to version 2.917. (If you want to use this on a different interpreter version, let me know; I can help you tweak it so it works).
  • There is one character, 0x80 (which is a capital 'C' with cedilla[that's the squiggly tail]) that won't display; it will always show as a black box. This is because AGI uses that code to manage the shading and inversion of characters on menus; the code needed to fix that is too complicated (at least for now). All other extended characters display longer a restriction; see post below
Finally, WinAGI v1.2.7 is the only dev environment that supports the use of extended characters while authoring a game. Use CTRL+INSERT to display a popup window in the logic editor to insert any extended character. You can also use "\x" codes to insert hexadecimal characters (which is what I typically do when using string hacks; it's just easier to read and manage code).

AGI Development Tools / String Hack
« on: August 15, 2019, 07:47:21 PM »
Sierra was notorious for not including error checks and buffer overflow checks in AGI. Even simple mistakes in source code can result in situations that cause unexpected results and crashing AGI.

But this can actually be used to your advantage to do some really cool advanced coding to 'hack' the interpreter on the fly from within your AGI game.

The key lies in the set.string(str sA, msg mB) command. It's no surprise that AGI does not validate the string number A; it will write the value of mB wherever sA points to. This means that using values larger than 23 will let you overwrite program memory. Of course, this usually crashes AGI, but if you know what's in those areas past the string table and you are careful, you can modify the underlying code to make the interpreter do what you want.

One area that is easy to manipulate is the command function offset table; it is located in memory around the spot where strings '26' through '43' would be. Each command function table entry consists of a two byte offset followed by a byte that tells how many arguments, and another byte with a bit field to tell what kind of argument (number or variable). The only value that AGI uses is the offset; the argument info is not used so you don't need to worry about overwriting those two bytes. By writing a string value that replaces just the two bytes of the offset of the command you want to hijack, you can easily redirect those commands to anywhere in program memory.

To take advantage of this, you can use the set.string command to add bytes anywhere in memory to create a new function, then change the offset in the command table.

I've attached a logic file that you can add to a test game to see this work first hand. A couple of important things to keep in mind:

  • the code will only compile in WinAGI 1.2.5 or later; other compilers cannot handle creating logics that have messages with special characters (less than 0x20 or greater than 0x7F)
  • this will ONLY work on the original DOS interpeter; if you try to run this in NAGI, SCUMMVM or any other non-Sierra interpreter it will not work
  • the code is VERY MUCH version specific; do not try to run this with any interpreter other than v2.917. Each version has slightly different address values for internal functions and data storage
  • the set.string command has two quirks to it that you need to be aware of; first of all, you can't write a string longer than 40 characters; if you try, AGI will truncate the string at 39 characters and add a single null character (0x00) to the end; secondly, if the string is less than 40 characters, AGI adds TWO null characters to the end; this makes it a bit trickier to create custom functions (the sample code shows an easy workaround to both of these limitations)
  • all string copying gets terminated when a null character (0x00) is found; to create custom functions that have zeros in it, you need to use a series of strings that work backwards, which lets you then control where the null characters show up (the sample code demonstrates this)

If you want to see this in action, create a sample game, setting it's version to 2.917. Find a copy of Sierra's AGI files from that version to run your game in a DOSBox setting. Then import the StringHack.lgc logic into your game, and call it from logic 0 just before calling the game setup logic.

The demo does four things:

  • it replaces the init.disk command with a function that prints the value of string s9
  • it replaces the set.string command with a modified version that is not limited to 40 characters, and also does not add extra null characters
  • it modifies the message displayed when you quit the game
  • it modifies the command so you can set your game ID without causing AGI to quit (save a game to see it in action)

There really is no limit to what you could do with this hack. The set.string command only lets you modify code following the string table, but you could easily create a bootstrap function there that then lets you modify code anywhere in program memory. You could then completely modify AGI on the fly. Two examples I can think of that this could be useful for would be the AGIMOUSE and the AGIPAL hacks; a single logic, run once at game load up could include all the code needed without needing a special interpeter!

If you have questions about the details on how this works, let me know, I'd be happy to explain the whole thing in more depth. And if you create any hacks that you think others might be interested, it'd be nice to share your code so others can use it too.

Happy hacking!

Pages: [1] 2

SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.178 seconds with 19 queries.