Weaver: A Game Engine for GNU/Linux

Documentation Tutorial Examples Download

Weaver Reference Guide

This page lists all functions and data structures defined in Weaver API. We use the following icons to help you check some properties of the variables in Weaver API:

Index

  1. Basic Functions and Variables
    1. Variables
      1. W
      2. W.game
      3. W.pending_files
      4. W.t
      5. W.dt
    2. Functions
      1. Walloc
      2. Wexit
      3. Wexit_loop
      4. Wfree
      5. Winit
      6. Wloop
      7. Wsubloop
  2. Numeric Functions and Variables
    1. Functions
      1. W.random
  3. Window and Screen
    1. Variables
      1. W.framerate
      2. W.height
      3. W.resolution_x
      4. W.resolution_y
      5. W.width
      6. W.x
      7. W.y
    2. Functions
      1. W.change_resolution
      2. W.move_window
  4. User Input
    1. Variables
      1. W.keyboard
      2. W.mouse
    2. Functions
      1. W.hide_cursor
  5. Scheduling
    1. Scheduling Functions
      1. W.cancel
      2. W.period
      3. W.run_futurelly
      4. W.run_periodically
  6. Plugins
    1. Plugin Functions
      1. W.disable_plugin
      2. W.enable_plugin
      3. W.get_plugin
      4. W.get_plugin_data
      5. W.is_plugin_enabled
      6. W.reload_all_plugins
      7. W.reload_plugin
      8. W.set_plugin_data
  7. Interfaces
    1. Records
      1. struct interface
    2. Interface Functions
      1. W.copy_interface
      2. W.destroy_interface
      3. W.move_interface
      4. W.new_interface
      5. W.resize_interface
      6. W.rotate_interface
  8. Shaders
    1. Shader Variables
      1. W.final_shader_integer
    2. Shader Functions
      1. W.change_final_shader
  9. Sound
    1. Sound Records
      1. struct sound
    2. Sound Variables
      1. W.number_of_sound_devices
      2. W.sound_device_name
    3. Sound Functions
      1. W.current_sound_device
      2. W.destroy_sound
      3. W.get_volume
      4. W.increase_volume
      5. W.new_sound
      6. W.pause_music
      7. W.play_music
      8. W.play_sound
      9. W.select_sound_device
      10. W.stop_music
  10. Data
    1. Data Functions
      1. W.delete_all
      2. W.delete_float
      3. W.delete_integer
      4. W.delete_string
      5. W.read_float
      6. W.read_float
      7. W.read_string
      8. W.write_float
      9. W.write_integer
      10. W.write_string

Basic Functions and Variables

Variables

struct W

The W struct is a struct where you can find almost all the variables and functions defined by Weaver API. It's main function is act as a namespace, avoiding conflicts between user variable names and the API names. Almost all variables and functions listed in this page is inside W.

Another advantage of defining almost all variables and functions inside this struct it's that we can pass the struct to plugins and then they can have access to all Weaver functions and variables.

Usually you shouldn't worry about the W struct and never should need to pass it directly to some function. You just invoke it's functions and access it's variables.

struct _game_struct *W.game

This is just a pointer to the struct defined at src/game.h in your project. You decide which variables you create and define in this struct. This user-defined struct is a way to store your game's global variables and also where you put data that should be accessible for plugins.

unsigned int W.pending_files

When you ask to Weaver open some kind of files like sound effect files, sometimes it opens and reads the file in a parallel thread, even when you compile your game to a web browser. This variable holds how many files Weaver is still reading.

unsigned long long W.t

This variable hold the times in microseconds since the program's initialization. A microsecond is 0.000001 second. So if you wish to know the value in seconds, you should divide it by 1,000,000.

As this value is at least 64-bits long, this would overflow only after more than 500,000 years.

unsigned long long W.dt

This variable holds the time in microseconds between the current main loop iteration and the previous loop iteration. As Weaver uses a fixed time step to run C code in the game loop, it's value should always be about 40,000, wich means that your C-code is running at 25 frames per second (but the game probably is rendering at a higher rate).

If you check this value and it has a value much higher than 40,000, it means that your game is running slowly. You should then do something like render less things, lower the resolution or the ammount of calculations in each frame.

Functions

void *Walloc(size_t size)

This function is like malloc, but the memory allocated is handled by Weaver's memory manager and usually don't need to be manually freed. The gargage collector will take away the memory allocated when you exit the current main loop.

You should free the memory only if you use this function outside a main loop. Or if you just allocated the memory but won't need it anymore. In this case, use the Wfree function.

Weaver garbage collector runs when you call the functions Wloop (except in the first invocation) and Wexit_loop.

Tip: Avoid calling Walloc in a main loop body. This leads to memory leaks. It's better to allocate a pool of objects in the loop initialization and then in the loop body you check which objects in the pool are initialized and should be handled.

void Wexit(void)

This function exits the game immediately. The game window is closed and the program exits if applicable. You can't access any variable or function listed here after calling Wexit.

void Wexit_loop(void)

This function exits the current main loop, remove it from the stack and resume the execution of the next main loop in the stack. If there's just one main loop in the stack when this function is called, then it just exits the game.

The garbage collector frees all the memory allocated in a loop when you call this function. To know more about main loops, please check Weaver Main Loops.

void Wfree(void *memory)

This function frees the memory allocated with Walloc. Call this only if the memory was allocated outside a main loop or it was allocated in the same main loop where we currently are. Otherwise, you risk calling the function in a memory already freed by the garbage collector.

When in doubt, don't use Wfree. Just let the garbage collector do the work. If your macro W_DEBUG_LEVEL is greater than 0, then Weaver will print a warning in the screen if it detects a memory leak while exiting the game.

To check how the garbage collector and the memory in Weaver works, check Weaver Main Loops.

void Winit(void)

This is the first function you should call in a Weaver program. Only after calling this function you can call any other function listed here or read any Weaver variable.

This is the function who creates a new window according with the configurations in conf/conf.h.

void Wloop(MAIN_LOOP (*loop)(void))

If this function is called outside a main loop, it puts the loop received as argument in the loop stack and executes it. If this function is called inside a main loop, it stops the execution of the current loop, removes it from the stack, put the received loop in the stack and executes it. In other words, it substitute the current loop by the loop passed as argument.

A main loop is where a game spends almost all the time, where we can get player's input and update the screen showing the objects created.

To know more how main loops work in Weaver, check Weaver Main Loops.

void Wsubloop(MAIN_LOOP (*loop)(void))

This function pauses the execution of the current main loop, put the loop received as argument in the loop stack and executes it.

It doesn't destroy the previous loop. So the garbage collector won't free the memory allocated in that loop.

To know more how main loops work in Weaver, check Weaver Main Loops.

Numeric Variables and Functions

Numeric Functions

unsigned long W.random(void)

This function uses a variation of the Mersenne Twister algorithm to generate a 32-bits pseudo-random number. If you want your game to always use the same seed, set the macro W_SEED at conf/conf.h, otherwise Weaver tries to use an unpredictable seed, as a value read from /dev/urandom or the current time in milisseconds.

Window and Screen

Window and Screen Variables

int W.framerate

This variable holds the screen frame rate, the frequency at which consecutive images are displayed in your screen. Usually it's value is 60, which means that your screen is updated once each 0.017 second. Of course there are machines where this value can be different.

Don't trust in this variable f your game was compiled to a web browser. There's no reliable way to discover the frame rate inside a web browser and so Weaver just guesses the value as 60.

int W.height

This variable holds the height your game have in pixels. It starts with the value defined in macro W_HEIGHT. The value will keep updated if your window changes the size (either because the user resized the window or because you called the function W.resize_window).

If your game was compiled to a Web Browser, this variable holds the height of the canvas where your game is being drawn.

int W.resolution_x

This variable holds your screen horizontal resolution. The width a full screen window would have in the screen. If your program is running in a web browser, this variable holds the width of the web browser window excluding toolbars and scrollbars (the same value present in Javascript's window.innerWidth).

This variable doesn't change when you use W.change_resolution. This variable keeps the resolution of your window manager or your browser body area. This is the amximum resolution your game can have. The function W.change_resolution changes the resolution in the game internal renderer.

int W.resolution_y

This variable holds your screen vertical resolution. The height a full screen window would have in the screen. If your program is running in a web browser, this variable holds the height of the web browser window excluding toolbars and scrollbars (the same value present in Javascript's window.innerHeight).

This variable doesn't change when you use W.change_resolution. This variable keeps the resolution of your window manager or your browser body area. This is the amximum resolution your game can have. The function W.change_resolution changes the resolution in the game internal renderer.

int W.width

This variable holds the width your game have in pixels. It starts with the value defined in macro W_WIDTH. The value will keep updated if your window changes the size (either because the user resized the window or because you called the function W.resize_window).

If your game was compiled to a Web Browser, this variable holds the widtht of the canvas where your game is being drawn.

int W.x

This variable holds the horizontal position of your game window in the screen. This position is defined as the column where the pixel in the center of your window is. The leftmost column is the column 0 and the rightmost colummn has the number W.resolution_x-1.

Inside a web browser, your game canvas can't move, so this variable is always assumed to have the value W.resolution_x/2 (Weaver assumes that the game canvas is centralized).

Don't change this variable. If you want to move your window, call the function W.move_window.

int W.y

This variable holds the vertical position of your game window in the screen. This position is defined as the line where the pixel in the center of your window is. The bottom line is the line 0 and the top lline has the number W.resolution_y-1.

Inside a web browser, your game canvas can't move, so this variable is always assumed to have the value W.resolution_y/2 (Weaver assumes that the game canvas is centralized).

Don't change this variable. If you want to move your window, call the function W.move_window.

Window Functions

void W.change_resolution(int horizontal, int vertical)

This changes the resolution of your game window. If you are not in fullscreen mode, this just changes the window size. Otherwise, it changes the game renderer to show your game in the desired resolution.

void W.move_window(int x, int y)

This function moves your game window for the giver coordinate. The position x and y are in pixels and the position (0, 0) is in the left lower part of your screen while the coordinate (W.resolution.x-1, W.resolution.y-1) is the right upper part of your screen.

Moving a window to a coordinate means placing it's center in this coordinate.

This function does nothing in a game compiled to a web browser.

User Input

User Input Variables

long W.keyboard[]

This array stores information about the user interaction with the keyboard. Each key has it's own position in the array. There's a set of macros created to help finding the right position in the array. To check if the key "A" is pressed, for example. check W.keyboard[W_A].

Besides W_A, you can check also for W_B, W_C, and all other letters, you can also check the digits W_0, W_1 and others. The keys F1, F2, F3 and others are W_F1, W_F2, W_F3 and so on. The arrow keys are W_UP, W_RIGHT, W_LEFT and W_DOWN. The Esc key is W_ESC. The Enter key is W_ENTER, the spacebar is W_SPACEBAR and the backspace is W_BACKSPACE. You also have W_TAB, W_PAUSE, W_DELETE, W_SCROLL_LOCK, W_HOME, W_PAGE_UP, W_PAGE_DOWN, W_END, W_INSERT and W_NUM_LOCK for keys Tab, Home, Page Up, Page Down, End, Insert and Num Lock. And there's the W_PLUS for "+" and W_MINUS for "-".

The keys Shift, Ctrl and Alt are a little different because they have a left and a right variety. If you don't care if the key pressed is left or right, you can check W_SHIFT, W_CTRL and W_ALT. If you want to check for the right version of these keys, check for W_RIGHT_SHIFT, W_RIGHT_CTRL and W_RIGHT_ALT. If you want to check the left variety, check W_LEFT_SHIFT, W_LEFT_CTRL and W_LEFT_ALT.

You can also check if any key was pressed checking the position W_ANY in the array.

If a key is not pressed, it's position in the keyboard array will have the value 0.

If a key just started to be pressed in this frame (in this iteration in the main loop), it's position will store the value 1.

If a key is being pressed, but the user didn't start to press it in this frame, it's position will store the number of microseconds since the user is pressing the key.

If the user released a key in this frame, it's position will store (just in this frame) a negative value witch is -1 multiplyed by the number of microseconds that the key was kept pressed.

struct W.mouse

The mouse is represented by the following struct:

struct{
  long buttons[];
  int x, y, dx, dy, ddx, ddy;
} W.mouse;

Weaver assumes a mouse can have 5 buttons. You can check if some of these keys are being pressed checking the positions W_MOUSE_LEFT (mouse left button), W_MOUSE_MIDDLE (mouse middle button), W_MOUSE_RIGHT (mouse right button) and the aditional buttons W_MOUSE_B1 and W_MOUSE_B2 in the array W.mouse.buttons. Keep in mind that not everybody have access to all the buttons. And if the game was compiled to a web browser, we may not to be able to check for buttons W_MOUSE_B1 and W_MOUSE_B2.

If a mouse button is not pressed, it will have the value 0 in the array.

If a mouse button starts to get pressed in this frame, it will have the value 1 in the array. But remember that mouse clicks can be really fast and sometimes the user click and release the button in the same frame. If this happens, you detect just the button being released, so it won't start with the value 1.

If a mouse button is getting pressed for more than 1 frame, it will have the value of microseconds since the key started to be pressed.

And if a mouse button is released in this frame, it will have a negative value of -1 multiplied by the number of microseconds that the button was kept pressed. If the button is pressed and released really fast, in the same frame, the first value different than 0 detected is the value -1, not 1.

The variables W.mouse.x and W.mouse.y stores thw mouse position in our game window. We considet the x axis as the horizontal axis and the y axis as the vertical axis. The position in the lower left of the window is (0,0) and the position in the upper right is (W.width-1, W.height-1).

You can get the horizontal and vertical speed of the mouse in pixels per second checking the variables W.mouse.dx and W.mouse.dy.

You can get the horizontal and vertical acceleration of the mouse in pixels per second squared checking the variables W.mouse.ddx and W.mouse.ddy.

User Input Functions

void W.hide_cursor(void)

Makes the cursor hidden.

Scheduling

Scheduling Functions

float W.cancel(void (*f)(void))

If you asked Weaver to run some function f periodically with W.run_periodically or in some moment in the future with W.run_futurelly, you can cancel this passing the function f to W.cancel.

The function returns the time in seconds in which the function would be executed if it wasn't cancelled.

If you pass a function not scheduled for future execution or an invalid pointer for this function, nothing happens and it returns NaN (Not a Number). The same happens if you try to cancel a function scheduled to be executed only once and which already executed.

float W.period(void (*f)(void))

If f is a function scheduled to be run periodically using W.run_periodically, this function returns the function period in seconds.

If f is a function scheduled to be run once in some moment in the future with W.run_futurelly, this function returns INFINITY.

Otherwise, this function returns NaN.

void W.run_futurelly(void (*f)(void), float s)

Run the function f in the future. Waits the number of seconds s passed as argument before executing the function.

If the function f was already scheduled for execution, the entry in the scheduler is updated to transform the function in a non-periodic function.

This function won't work if your scheduler has more than W_MAX_SCHEDULING waiting for execution.

void W.run_periodically(void (*f)(void), float s)

Run the function f periodically, every s seconds. The first execution will be s seconds after you call this function.

If the function f was already scheduled for execution, the entry in the scheduler is updated to transform the function in a periodic function and it's period is also updated.

This function won't work if your scheduler has more than W_MAX_SCHEDULING waiting for execution.

Plugins

Plugin Functions

bool W.disable_plugin(int id)

This function disables a plugin given it's id number and returns true if the opperation was successful. This function fails if a plugin id is invalid and returns false.

Trying to disable an already disabled plugin does nothing (but the function returns true anyway.

Immediately before the plugin is disabled, it executes it's function _disable_plugin_PLUGIN_NAME. A disabled plugin won't run it's function _run_plugin_PLUGIN_NAME every iteration in the main loop. Check Weaver Plugins for more info.

bool W.enable_plugin(int id)

This function enables a plugin given it's id number and returns true if the opperation was successful. This function fails if a plugin id is invalid and returns false.

Trying to enable an already enabled plugin does nothing. But the function returns true anyway.

Immediately after the plugin is enabled, it executes it's function _enable_plugin_PLUGIN_NAME. An enabled plugin will run it's function _run_plugin_PLUGIN_NAME every iteration in the main loop. Check Weaver Plugins for more info.

int W.get_plugin(char *plugin_name)

Get a plugin id number given it's name. If a plugin is not found, this function returns -1.

void *W.get_plugin_data(int id)

This function stores some data previously stored with W.set_plugin_data, given a plugin id number.

This function should be called by plugins, not by your program. It's how plugins should store data that should be preserved, even if the plugin is disabled or if the plugin is reloaded.

bool W.is_plugin_enabled(int id)

A simple test which returns true if a plugin is enabled and returns false otherwise. The plugin is identified by it's id number.

void W.reload_all_plugins(void)

This function reloads all the existing plugins, updating them if they were recompiled. It also checks the directory W_PLUGIN_PATH if there are new plugins. If it finds a new plugin, the function makes it accessible by W.get_plugin, allowing you to enable or disable the plugin.

This function always is called before you enter in a new main loop.

This function does nothing if your game is compiled for a web browser.

void W.reload_plugin(int id)

This function checks if a plugin was recompiled since it was loaded. In this case, it reloads the plugin, updating all the changes made to him.

This function does nothing if your game was compiled to a web browser.

bool W.set_plugin_data(int id, void *data)

This function stores data in the place reserved for a plugin identified by it's id number. You can put any kind of data there. If you wast to retrieve data stored with this function, use W.get_plugiin_data.

This function should be used by plugins, not your main program. It's how plugins can store data that is preserved, even after they are disabled and enabled again or if they are reloaded.

Interfaces

Interface Records

struct interface

An "interface" is a record (what C calls "struct") which stores information about a graphical element which usually appears in the screen. This element can be manipulated by built-in functions to move it in the screen, rotate and resize. But there's no built-in functions to make it interact with other objects, even other interfaces. This record was created to represent user interface elements.

An interface is defined roughly as:

struct interface{
  int type;
  int integer;
  int number_of_frames;
  int current_frame;
  int max_repetition;
  float x,y;
  float rotation;
  float r, g, b, a;
  float width, height;
  bool visible;
  bool animate;
}

An interface record is created with the function W.new_interface or W.copy_interface and can be destroyed by W.destroy_interface.

Every interface record has the following variables:

int type

How the interface should be rendered. If it's a positive integer, then it's the number of the shader which will render the interface in the screen. It can also have the value W_INTERFACE_SQUARE (if it should be rendered as a solid rectangle) or W_INTERFACE_PERIMETER (if it should be rendered as the perimeter of a rectangle).

Interfaces with the same type are rendered together. If he interface type is user-defined (its value is a positive integer), interfaces with greater type numbers will be rendered first. Knowing this may be useful if you want to render correctly translucent interfaces (interfaces with parts not completely opaque nor completely transparent). In this case, you need to ensure that the translucent interfaces are rendered after the others.

int integer

An integer which will be passed to the shader. You have freedom to change and use this value as you wish in your shaders. Weaver sets this variable as 0 in the initialization and never changes it again. The built-in shaders never uses this variable.

int number_of_frames

If this interface was created from an animated GIF, this stores asn integer greater than 1 which orresponds to the number of frames in the animation. Otherwise, the value is 1.

int current_frame

If this is an animated interface read from an animated GIF file, then his variable have a value between 0 and (number_of_frames-1). It stores which frame should appear in the screen. In not animated interfaces, the value is always 0. Never put in this variable (number_of_frames) or greater.

int max_repetition

How many times should we repeat the animation if this is an animated interface. A value of -1 means that the animation will repeat forever. A 0 means that the animation is frozen in the last frame. Avalue greater than 0 means that the animation is running, but the value will decrement each time the animation shows its last frame. In a not animated interface, the value is ignored.

float x, y

The interface position in the screen. The interface position is defined as the position of the interface's central pixel. The bottom left position in the window is the position x=0.0, y=0.0. The upper right position in the screen in the window is the position x=(float)W.width-1, y=(float)W.height-1.

If you want to change an interface position, don't try to set directly it's x and y variable. Use the function W.move_interface instead.

float rotation

This is the angle in which the interface is rotated counter clockwise in radians.

If you want to change an interface rotation, don't try to set directly it's rotation variable. Use the function W.rotate_interface instead.

float r, g, b, a

These variables are passed as the color in the shader. Built-in shaders will treat this value as the interface color whem applicable. You can create custom shaders which use these variables in different ways.

float width, height

This is the interface width and height in pixels.

If you want to change an interface size, don't try to set directly it's width and height variables. Use the function W.resize_interface instead.

The interface width and height will also change if you change resolution with W.change_resolution. During a resolution change the interfaces will keep their proportions with the window size in pixels.

bool visible

This variable sets if the interface is visible and should be rendered or if it's invisible. This is set as true by default.

bool animate

This variable enables and disables the interface animation if the interface was created from an animated GIF. Enabling animation in other kind of interfaces has no effect.

Interface Functions

struct interface *W.copy_interface(struct interface *i)

This function creates a new interface record which is a copy of the interface record pointed by the argument. It returns a pointer for the new interface record created. If some error happened (you can't create more interfaces in this main loop because of W_MAX_INTERFACES or the creation of some mutex failed), this function returns NULL.

The interface passed as argument can be an interface created in another main loop. But the new interface created will be created in the current main loop.

bool W.destroy_interface(struct interface *i)

This function destroys the interface passed as argument if we are in the same main loop that the interface was created. Use this function only if you need more space for new interfaces in the current loop. Otherwise, let the garbage collector erase interfaces not used anymore.

This function returns if the opperation was successful. If you pass an invalid pointer or a pointer to an interface created in another main loop, the function does nothing and returns false.

void W.move_interface(struct interface *i, float x, float y)

This function changes the interface position. It puts the center of the interface in position (x, y) passed as argument, where the bottom left corner of the window is position (0,0) and the upper right corner is position (W.width-1, W.height-1).

struct interface *W.new_interface(int type, int x, int y, int width, int height, ...)

This function creates a new interface record and returns a pointer for it. In case of error (you can't create more interfaces in the current main loop because of W_MAX_INTERFACES or the creation of some mutex failed), this function returns NULL.

The arguments x, y, width and height determines the initial position and size of the interface in the screen. More arguments can be passed depending of the interface type.

If type is a positive integer, then the interface will be rendered using a custom shader created by you and identified by that number. You should pass than an argument with the filename of the texture that should be sent as "texture1" for your shader or NULL or an empty string if no texture should be passed.

If type is W_INTERFACE_SQUARE or W_INTERFACE_PERIMETER, then you must pass 4 more values which represent the interface color. These 4 values should be floating point numbers between 0.0 and 1.0 and they represent the color RGBA value.

void W.resize_interface(struct interface *i, float width, float height)

Resize an existing interface. It's width and height becames the value passed as argument in pixels.

void W.rotate_interface(struct interface *i, float angle)

This function changes how the interface should be rotated comparing with it's original position. The second argument is the counter clockwise rotation angle in radians.

Shaders

Shader Variables

int W.final_shader_integer

If you enable 2-pass rendering, where you first render your game to a texture, and then use a custom shader to render it in the screen using W.change_final_shader, then you can set this variable to pass any integer you wish for this custom shader.

Changes to this variable are always local to a main loop. When you enter in a main loop this variable is set to 0 again. And if you exit from a subloop, this variable recover the value it had before entering in the last subloop.

Shader Functions

void W.change_final_shader(int shader_id)

This function activate the 2-pass rendering, where you first render all your game to a texture, and then render it to the screen with a custom shader, whose id number you pass as argument for this function.

Please, ensure that you pass the id of an existing shader for this function. Passing an invalid id number is a fatal error.

When you change the final shader, the change is always local to the main loop where the function is invoked.

Sound

Sound Records

struct sound

This record stores information about sound effects in your game. Not long audio like music, but small sound effects which should be stored in memory for fast playing.

A sound record is defined roughly as:

struct sound{
  unsigned long size;
  int channels, freq, bitrate;
  bool loaded;
};

A new sound record is created by function W.new_sound and can be destroyed by function W.destroy_sound (but if you created a sound inside a main loop, you should let the garbage collector destroy the record).

Every sound record has the following variables:

unsigned long size

The sound size in bytes.

int channels

The number of channels. If the sound in monoaural (1), stereo (2) or have even more channels.

int freq

The sampling frequency. Usually it's value is 44100, because it's the sampling frequency of Compact Disks.

int bitrate

The bit rate, or the number of bits per second that should be converted to sound and played.

bool loaded

If the sound was properly loaded or not. If this variable is false, it means that Weaver still is loading the sound asynchronously. Or the code which should load the sound asynchronously failed for some reason and the sound won't load. You can try to play the sound with W.play_sound, but this function will fail silenly when asked to play a non-loaded sound.

You can check the value of the variable W.pending_files if you want to know if Weaver still is loading your files. If it's value is 0, it means that Weaver isn't loading any file and if your sound have the variable loaded set as false, then the loading failed.

Sound Variables

int W.number_of_sound_devices

This variable holds the number of detected sound devices in your system. It's useful to know the size of the array W.sound_device_name and to know which values you can pass to function W.select_sound_device.

char* W.sound_device_name[ ]

This is an array of strings with the name of each sound device detected in the system. The array has W.number_of_sound_devices elements and if you wish to choose one of them as the default sound device, pass it's position to the function W.select_sound_device. If you want to know the position of the current sound device (if we can detect), call function W.current_sound_device.

If we didn't detect any sound device, this variabel is set as NULL.

Sound Functions

int W.current_sound_device(void)

This function identify if possible which sound device we are using in the list W.sound_device_name. The function return the position of the sound device name in that list, or -1 if it isn't able to detect the current device.

void W.destroy_sound(struct sound *snd)

This function frees the memory previously allocated by W.new_sound. Usually you don't need to use this function because the garbage collector will free the memory when you exit the main loop where the sound was allocated. But if you allocated the sound outside a main loop, you need this function to avoid a memory leak.

float W.get_volume(char *filename)

If the music file at music directory is loaded and playing or paused, this function returns it's volume as a floating pont number between 0 and 1. If the music isn't playing, it returns -1.0.

float W.get_volume(char *filename, float increment)

If the music found in the given filename at music directory is playing or is paused, this function increases its volume by the value passed as the second argument. the value can be negative if you want to lower the volume.

If the function would change a volume to a value greater than 1, it changes the value to 1 instead. If the function woulkd change a volume to a value lesser than 0, it changes to 0 instead.

The function returns the new volume after the change or returns -1.0 if the music wasn't loaded.

struct sound *W.new_sound(char *filename)

This function opens a sound file in the sound/ directory given it's filename. Then it parses and extract the file content as a sound record.

Weaver can return from this function before finishing to extact the file. The engine prefers to extract files asynchronously in a thread if possible. You can check if a sound was really extracted checking it's variable loaded.

Currently Weaver is able to extract WAVE and MP3 files. If Weaver can't extract a sound file, it returns NULL.

bool W.pause_music(char *filename)

Pauses the music which is being played and whose contents are being read from the file in the music directory whose name is passed as argument.

The function returns if the operation was successful. If the given music wasn't loaded, doesn't exist or was already paused, the function returns false. Otherwise, it returns true.

bool W.play_music(char *filename, bool loop)

Start to play the music or sound effect in the filename passed as first argument inside the music directory. If the music is already loaded, but was paused (with W.pause_music), the music resumes playing. The second argument defines if the music should loop after it ends.

Currently Weaver can only play music encoded as MP3.

If Weaver can't play the music (or it's already playing), the function returns false. Otherwise, it returns true.

bool W.play_sound(struct sound *snd)

Play a sound created by W.new_sound and then returns if it was possible to play the sound. If the sound was already playing, if we are already playing the maximum number of music (defined by macro W_MAX_MUSIC), or if the file was not found this function returns false. Otherwise, it returns true.

bool W.select_sound_device(int id)

This function selects a detected sound device to play our audio. You should pass for this function the position of the chosen audio in the array W.sound_device_name.

If you pass an invalid number or this function fails for some other reason, it returns false.

bool W.stop_music(char *filename)

Stops playing a music identified by the filename passed as argument and inside the music directory. The music is also unloaded from memory and a different music can be played in its place.

The function returns if the operation was successful. If the music doesn' exist, or it wasn't loaded, it returns false. Otherwise, it returns true.

Data

Here you will find functions created to store, read and delete data which should be preserved, even after your program ends. If the game is running natively, the data is stored using Sqlite3. If the game is running in a web browser with Web Assembly, the data is stored in cookies with a very long expiration date.

Data Functions

void W.delete_all(void)

This function erases all saved data in your game. Anything stored with W.write_float, W.write_integer or W.write_string will be erased.

void W.delete_float(char *name)

This function erases the saved data stored as a floating point number with W.write_float and identified by the name passed as argument. If the data doesn't exist, this function doesn't nothing.

void W.delete_integer(char *name)

This function erases the saved data stored as an integer number with W.write_integer and identified by the name passed as argument. If the data doesn't exist, this function doesn't nothing.

void W.delete_string(char *name)

This function erases the saved data stored as a string with W.write_string and identified by the name passed as argument. If the data doesn't exist, this function doesn't nothing.

bool W.read_float(char *name, float *value)

This functions reads a floating point number stored in the past with W.write_float function and identified with the name passed as the first argument. If the number is found, it's stored in the pointer passed as second argument and the function returns true. Otherwise, the second argument is ignored and the function returns false.

bool W.read_integer(char *name, int *value)

This functions reads an integer number stored in the past with W.write_integer function and identified with the name passed as the first argument. If the number is found, it's stored in the pointer passed as second argument and the function returns true. Otherwise, the second argument is ignored and the function returns false.

bool W.read_string(char *name, char *value, int n)

This functions reads the string stored in the past with W.write_string function and identified with the name passed as the first argument. If the string is found, it's copied in the array passed as second argument, but not more than n bytes are copied and the function returns true. Otherwise, the second argument is ignored and the function returns false.

void W.write_float(char *name, float value)

This function stores a floating point number and identifies it with the name passed as argument. The value is preserved even after the program exits. The value can be overwritten calling this function again passing the same name as argument. If you want to delete the number and it's identifier, call W.delete_float.

void W.write_integer(char *name, int value)

This function stores an integer number and identifies it with the name passed as argument. The value is preserved even after the program exits. The value can be overwritten calling this function again passing the same name as argument. If you want to delete the number and it's identifier, call W.delete_integer.

void W.write_string(char *name, char *value)

This function stores a string and identifies it with the name passed as argument. The value is preserved even after the program exits. The value can be overwritten calling this function again passing the same name as argument. If you want to delete the string and it's identifier, call W.delete_string.