Top | Prev | Next
In order to create an interactive application, IRIS/IRIS++ needs to be extended to support input/output features so that it can obtain user inputs, or display graphics on screen. IRIS/IRIS++ does not have a built-in feature like this, but the Virtual Machine can mount such engine that supports input/output. So how does IRIS/IRIS++ can be extended? As described in Using The Macro, we use the compile-time modifiers to define objects and commands that are implemented in the Virtual Machine. The Virtual Machine provided by Ulysses Records (ulyvm.exe) already has a built-in game library (called UlyGL) that supports developing basic games.
Depending on the application architecture, there are 2 ways of implementing a game engine: (1) Executable-Based or (2) Script-Based. The first one mounts the game engine in the main executable (or in dynamic libraries), and the script is more like an assistant feature for the game engine (e.g. defining and calling literal data, like character dialog messages, default position coordinates, etc). Take an example with RPGs. When the player moves around a field and encounters an enemy, he/she enters a battle scene, which in another words, the battle system implemented in the main executable's game engine is called. For (2), instead of implementing the battle system in the main executable, we implement the system in our script.
We cannot really say which is better, because it just depends on how the developer wants to design his game engine. Good thing about (1) is that it is easier to implement a game engine in the main executable rather than in a script. If we were to implement the game engine in a script, the script needs to support quite a few number of input/output functions and must be designed to be interpreted in light speed. However, a script-based game engine has few good points as well. One is that it is easy to be modified. Compiling the main executable might take ages if the game engine is huge, but compiling a script could be done in few seconds. Another advantage is the portability. If you write the script once, then you will never have to touch the code again when moving to a different platform (like Windows to Linux). The only thing we need to develop is the Virtual Machine, which is just an implementation of input/output libraries. Whereas, if you program all your game engine in the main executable, you might need to re-examine and code the game engine again when you migrate to different platforms.
Since IRIS/IRIS++ is designed to be interpreted quite fast and is extensible, we have chosen (2) Script-Based architecture. In this section, all extended features built into the Virtual Machine can be referenced.
IRIS/IRIS++ has a mechanism of referring Virtual Machine objects. Strictly speaking, objects used in scripts are not objects - they are commands, but we will describe them as an object just to make things easily understood.
Each object has an instruction set called "commands". Commands are called to manage the behavior of objects. Object has an underscore before the object name and each child objects are separated by :: (e.g. _screen::_red::set(0);). There are few commands that allows a single parameter to be set. The parameters are set inside the brackets as numeric values, strings, or registers. If parameters are omitted, the internal string buffer managed by the Virtual Machine will be assigned to the command automatically.
The top most parent object controls the virtual machine. The object is described as blank with a trailing ::
Example:
// Set Application title _identifier::set("IRIS DEMO"); // Set width and height of main screen _screen::_width::set(640); _screen::_height::set(480); // Initialize game engine ::initialize();
Controls the application's identifier.
UlyGL game engine enables you to read external XML files in the data/ext directory. On initialization, the game engine searches for all XML files under the data/ext directory and stores the file name into the extension object as an array. From those obtained extension files, you may read them using the xml object functions. The extension object can hold up to 256 xml file names.
[Sample: XML file contents] <?xml version="1.0"?> <iga> <extension> <title>ILLUSION GARDEN</title> <author>TOMOHIRO KADONO</author> <img>illusiongarden\\illusiongarden.bmp</img> <init_script>illusiongarden_init.bin</init_script> </extension> </iga> [Sample: IRIS/IRIS++ code] // Pre-read all extension files function open_extension_file() { // Check if extension exists let $_rgb = _extension::count(); if($_rgb == 0) { return; } let $_rga = 0; do { // Increment, because index 0 is used by settings.xml let $_rga++; _xml::use($_rga); let $_rga--; // Get extension file name CLB _extension::seek($_rga); // Get the extension file name into internal string buffer _extension::get(); // Open the extension file name that was read into the internal string buffer _xml::open(); let $_rga++; } until $_rga == $_rgb loop; // Make sure to use settings.xml after reading is done _xml::use(0); return; }
xml object enables you to manipulate XML files for input/output and document data search functions. Tags with attributes are not supported. Also, multiple tags that spread across a single line might not be recognized in some cases. Therefore, you need to enter a carriage return after each ending tag.
// Open XML file _xml::open("data\\settings.xml"); // Set the XML path _xml::_path::set("iga::settings::is_window"); // At this point, $_ret stores the value of iga::settings::is_window let $_ret = _xml::read();
xml::path object stores the xml path for reading and writing to xml files.
The memory object manages the static memory that is allocated by the Virtual Machine when the application is initialized. The memory object contains 4096 32 bit integer value for you to freely use. For instance, you may segment the memory space within your code by separating them into eight 512 units. These memory data can be saved as a data file or read the data from file back into the memory. Furthermore, the data can be encrypted by XORing using the specified encryption key.
// Set all values of memory to 0 _memory::initialize(); // Set encryption key _memory::encrypt(61827); // Clear internal string buffer and set data file to read CLB ATB "data\\save\\save.data" // Read the data file name from buffer and store the values in memory _memory::read(); // Seek to address 0 and get the value at that position into register A _memory::seek(0); let $_rga = _memory::get();
Object that manages the internal string buffer (NOTE: Does not manage the blit buffer). You may use it as an assistant with screen::text.
The screen object manages all objects that is displayed on screen. Before using the screen object or its child objects, you will need to initialize the screen object.
// Load screen _screen::load(); // Set screen color to black _screen::_red::set(0); _screen::_green::set(0); _screen::_blue::set(0); // Update screen _screen::refresh(); // Clear the screen with black _screen::clear(); // Begin blitting _screen::begin(); // Display image or text here _screen::end(); // Unload to release memory _screen::unload();
Object that holds information about the value of frames per second (normally 60 FPS).
// Get the current frame count let $_rga = _screen::_frame::get(); // Every time the frame count reaches 10, execute the following statement if($_rga == 10) { // Do something }
Object that holds information about the window state whether it is full screen or windowed.
Object that holds information about the window width.
Object that holds information about the window height.
Object that holds information about the screen's red color value.
Object that holds information about the screen's green color value.
Object that holds information about the screen's blue color value.
Object that manages displaying texts that uses font sprite to blit fast. Note that the Virtual Machine holds 2 internal string buffers. One is managed by IRIS which uses the buffer to manipulate on all kinds of strings, and the other is managed by the game library's Screen class instance, which is the blit buffer. Normally, to draw a text on screen, we need to transfer the contents in the internal string buffer to the blit buffer. The screen::text object commands will do the job automatically for you, but in some cases, you might need to transfer the string to the blit buffer explicitly (e.g. when using CLB instruction to clear the internal string buffer then, transferring the contents to the blit buffer) by using the screen::text::buffer command.
// Create 2 font sprites _screen::_text::create(2); // Load small size font _screen::_text::use(0); _screen::_text::_size::set(1024); _screen::_text::load("font_small.lfd"); // Load normal size font _screen::_text::use(1); _screen::_text::_size::set(2048); _screen::_text::load("font_normal.lfd"); // Use small size font _screen::_text::use(0); // Show animated text at position X=0, Y=0 _screen::_text::_x::set(0); _screen::_text::_y::set(0); _screen::_text::set("ANIMATED TEXT"); _screen::_text::play(10); // Use normal size font _screen::_text::use(0); // Show text at position X=248, Y=352 _screen::_text::_x::set(248); _screen::_text::_y::set(352); _screen::_text::set("NEW GAME\n\nCONTINUE"); _screen::_text::show(0); // Unload text _screen::_text::unload(); [Note: Due to the limitation of IRIS specification, you cannot assign an empty string.] [Therefore, you must use CLB to clear the internal buffer and then transfer it to the blit buffer.] // Clear internal string buffer CLB // Transfer internal string buffer to blit buffer _screen::_text::buffer();
Object that holds information about the font sprite's alpha (transparency) value of range 0 to 255.
Object that holds information about the X coordinate position value of text.
Object that holds information about the Y coordinate position value of text.
Object that holds information about the size of the font sprite. Increase the size to support huge number of font images.
Object that manages displaying sprites (images). UlyGL has a built-in sprite manager that can be controlled via script. Sprites are textures painted on a plain 3D surface where you can move them around, change size and so on.
// Create 2 sprites _screen::_sprite::create(2); _screen::_sprite::use(0); _screen::_sprite::load("background.bmp"); _screen::_sprite::_x::set(0); _screen::_sprite::_y::set(0); _screen::_sprite::_width::set(512); _screen::_sprite::_height::set(256); _screen::_sprite::_left::set(0); _screen::_sprite::_top::set(0); _screen::_sprite::_right::set(512); _screen::_sprite::_bottom::set(256); _screen::_sprite::_alpha::set(255); _screen::_sprite::use(1); _screen::_sprite::load("image.bmp"); _screen::_sprite::_x::set(0); _screen::_sprite::_y::set(0); _screen::_sprite::_width::set(640); _screen::_sprite::_height::set(480); _screen::_sprite::_left::set(0); _screen::_sprite::_top::set(0); _screen::_sprite::_right::set(640); _screen::_sprite::_bottom::set(480); _screen::_sprite::_alpha::set(200);
Object that holds information about the sprite's alpha (transparency) value of range 0 to 255.
Object that holds information about the X coordinate position value of a sprite.
Object that holds information about the Y coordinate position value of a sprite.
Object that holds information about the width of a sprite.
Object that holds information about the height of a sprite.
Object that holds information about the visible starting top position of a sprite's base image.
Object that holds information about the visible starting left position of a sprite's base image.
Object that holds information about the visible right position of a sprite's base image. The right position is not the coordinate, but the width from where the left position starts.
Object that holds information about the visible bottom position of a sprite's base image. The bottom position is not the coordinate, but the height from where the top position starts.
Object that holds information about the duration the sprite (e.g. using the duration information to play the next animation frame, etc).
Object that holds information about the number of animation image the sprite has. When a sequence is set along with the maximum duration (wait), the sprite automatically animates it self. Note that the sequence of images must have the same size and must be sequenced from top to bottom in the base image.
Object that holds information about the fade status of a sprite. By setting the fade to true, the fade flag becomes 1 and if false, 0. Using this object it self does not achieve a fade-in/fade-out effect. You will need to code your own fading routines by using this object.
// An example of a fade-in/fade-out function in IRIS (To make it usable when included as library) // Fade out sprite image // $_rga : Sprite ID // $_rgb : Fade amount @fade_out_sprite_img: _screen::_sprite::use($_rga); REG $_rga _screen::_sprite::_fade::get(); SKE 1 RET _screen::_sprite::_alpha::get(); SKN 0 RET // Fade out SBT $_rgb _screen::_sprite::_alpha::set($_rga); SKE 0 RET _screen::_sprite::_alpha::set(0); _screen::_sprite::_fade::set(0); RET // Fade in sprite image // $_rga : Sprite ID // $_rgb : Fade amount @fade_in_sprite_img: _screen::_sprite::use($_rga); REG $_rga _screen::_sprite::_fade::get(); SKE 1 RET _screen::_sprite::_alpha::get(); SKN 255 RET // Fade in SUM $_rgb _screen::_sprite::_alpha::set($_rga); SKL 256 RET _screen::_sprite::_alpha::set(255); _screen::_sprite::_fade::set(0); RET
Command cursor's are made up of 3 different objects. First is the sprite image that points to a certain command. Second is the device input that allows user input. Third is the sound effect that the cursor makes during user input. As command cursor functionalities could be complicated to code in IRIS/IRIS++, UlyGL provides a cursor object that manages the behavior of command cursors. Normally, you will create a set of libraries to initialize, get user input, and to move command cursors around. See cmd_cursor.iris script in the UlyGL game engine for the list of available library functions.
Manages the command cursor's sprite object. The cursor sprite is inherited from the sprite object (e.g. To set the cursor sprite's alpha value, you will use screen::cursor::sprite::alpha).
Object that holds information about the horizontal properties of a cursor.
Object that holds information about the vertical properties of a cursor.
Object that holds information about the maximum number of horizontal movement steps a cursor is allowed to move.
Object that holds information about the maximum number of vertical movement steps a cursor is allowed to move.
Object that holds information about the maximum horizontal distance (in pixels) a cursor is allowed to move in a single step.
Object that holds information about the maximum vertical distance (in pixels) a cursor is allowed to move in a single step.
Object that holds information about the current horizontal step the cursor is located at (in step units).
Object that holds information about the current vertical step the cursor is located at (in step units).
Object that holds information about the duration between each command cursor input (in frame units).
Object that controls the enabling or disabling state of the command cursor's user input. 0=disable, 1=enable.
Object that manages the 3D models.
Object that manages the 3D model x coordinate objects.
Object that manages the 3D model y coordinate objects.
Object that manages the 3D model z coordinate objects.
Object that manages the 3D model's x-axes scale.
Object that manages the 3D model's y-axes scale.
Object that manages the 3D model's z-axes scale.
Object that manages the 3D model's x-axes angle.
Object that manages the 3D model's y-axes angle.
Object that manages the 3D model's z-axes angle.
Object that manages the 3D model's x-axes position.
Object that manages the 3D model's y-axes position.
Object that manages the 3D model's z-axes position.
Object that manages the 3D scene camera.
Object that manages the camera's x coordinate objects.
Object that manages the camera's y coordinate objects.
Object that manages the camera's z coordinate objects.
Object that manages the camera's x-axes angle.
Object that manages the camera's y-axes angle.
Object that manages the camera's z-axes angle.
Object that manages the camera's x-axes position.
Object that manages the camera's y-axes position.
Object that manages the camera's z-axes position.
Manages the media objects such as sound and music.
Object that manages playing sound(s).
// Load Media _media::load(); // Load 1 Sound for BGM _media::_sound::create(1); // Load and play BGM with looping _media::_sound::use(0); _media::_sound::load("my_bgm.ogg"); _media::_sound::play(1); ... // Unload sound _media::_sound::unload(); // Unload media _media::unload();
Object that manages playing music using midi files.
Object that manages the external devices such as keyboard and game pads. Normally, you should write a library to manage these objects. See device_input.iris script in the UlyGL game engine for the available library functions.
Object that manages the keyboard inputs.
Object that manages the keyboard keys. You can use up to 8 key objects ranging from 0 to 7. For instance, you could assign key 'Z' to key object 0 and 'X' to key object 1.
Object that manages the keyboard key states. If key is active (i.e. pressed) then returns 1, else 0.
Object that manages the joystick inputs. Normally, you should write a library to manage these objects. See device_input.iris script in the UlyGL game engine for the available library functions.
Object that manages the joystick x-axes.
Object that manages the joystick y-axes.
Object that manages the joystick buttons. You can use up to 8 button objects ranging from 0 to 7.
Object that manages the joystick button states. If button is active (i.e. pressed) then returns 1, else 0.