(*
 * Title  : sprite.h
 * Purpose: provide access to RISC OS sprite facilities
 *          
 *)

# ifndef __sprite_h
# define __sprite_h

# ifndef __os_h
# include "os.h"
# endif

(* 
 * This file contains functions for performing operations on sprites.
 * For brevity only a brief description is given for each call. More details
 * can be found in the Programmer's Reference manual under the section on
 * Sprite SWIs.
 *
 *)



(******** Simple operations, use no sprite area, no name/sprite pointer ***)

const
  sprite_nopalette  = 0;
  sprite_haspalette = 1;

type sprite_palflag_ptr = ^sprite_palflag;
     sprite_palflag = integer;

type sprite_factors_ptr = ^sprite_factors;
     sprite_factors =
       record
         xmag, ymag, xdiv, ydiv : integer
       end;

type sprite_pixtrans_ptr = ^sprite_pixtrans;
     sprite_pixtrans = byte;


(* ----------------------------- sprite_screensave -------------------------
 * Save the current graphics window as a sprite file, with optional palette.
 * Equivalent to *ScreenSave.
 *
 *)
procedure sprite_screensave(filename : string;
                flag : sprite_palflag) : os_error; extern;
 
(* ---------------------------- sprite_screenload --------------------------
 * Load a sprite file onto the screen. Equivalent to *ScreenLoad.
 *
 *)
procedure sprite_screenload(filename : string) : os_error; extern;


(****** Operations on either system/user area, no name/sprite pointer *****)

type sprite_area_ptr = ^sprite_area;
     sprite_area =     (* Format of a sprite area control block *)
       record
         size : integer;
         number : integer;
         sproff : integer;
         freeoff : integer
       end;

type sprite_header_ptr = ^sprite_header;
     sprite_header =   (* Format of a sprite header *)
       record
         next : integer;      (*  Offset to next sprite                *)
         name : packed array[1..11] of char;
                              (*  Sprite name                          *)
         width : integer;     (*  Width in words-1      (0..639)       *)
         height : integer;    (*  Height in scanlines-1 (0..255/511)   *)
         lbit : integer;      (*  First bit used (left end of row)     *)
         rbit : integer;      (*  Last bit used (right end of row)     *)
         image : integer;     (*  Offset to sprite image               *)
         mask : integer;      (*  Offset to transparency mask          *)
         mode : integer       (*  Mode sprite was defined in           *)
                              (*  Palette data optionally follows here *)
                              (*  in memory                            *)
       end;

const sprite_mainarea = sprite_area_ptr(0); (* Typed constants !!! *)

type sprite_ptr = pointer;


(* ------------------------ sprite_area_initialise -------------------------
 * Initialise an area of memory as a sprite area 
 *
 *)
procedure sprite_area_initialise(area : sprite_area_ptr;
                size : integer); extern;

(* ----------------------- sprite_area_readinfo ----------------------------
 * Read information from a sprite area control block
 *
 *)
procedure sprite_area_readinfo(area : sprite_area_ptr;
                resultarea : sprite_area_ptr) : os_error; extern;

(* --------------------------- sprite_area_reinit --------------------------
 * Reinitialise a sprite area.
 * If system area, then equivalent to *SNew
 *
 *)
procedure sprite_area_reinit(area : sprite_area_ptr) : os_error; extern;

(* --------------------------- sprite_area_load ----------------------------
 * Load a sprite file into a sprite area.
 * If system area, then equivalent to *SLoad
 *
 *)
procedure sprite_area_load(area : sprite_area_ptr;
                filename : string) : os_error; extern;
 
(* ---------------------------- sprite_area_merge --------------------------
 * Merge a sprite file with a sprite area.
 * If system area, then equivalent to *SMerge
 *
 *)
procedure sprite_area_merge(area : sprite_area_ptr;
                filename : string) : os_error; extern;
 
(* ---------------------------- sprite_area_save ---------------------------
 * Saves a sprite area as a sprite file.
 * If system area, then equivalent to *SSave
 *
 *)
procedure sprite_area_save(area : sprite_area_ptr;
                filename : string) : os_error; extern;

(* ---------------------------- sprite_getname -----------------------------
 * Return the name and length of name of the n'th sprite in a sprite area
 * into a buffer.
 *
 *)
procedure sprite_getname(area : sprite_area_ptr;
                buffer : pointer;
                var length : integer;
                index : integer) : os_error; extern;

(* ---------------------------- sprite_get ---------------------------------
 * Copy a rectangle of screen delimited by the last pair of graphics cursor
 * positions as a named sprite in a sprite area, optionally storing the
 * palette with the sprite.
 *
 *)
procedure sprite_get(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag) : os_error; extern;

(* ---------------------------- sprite_get_rp ------------------------------
 * Copy a rectangle of screen delimited by the last pair of graphics cursor
 * positions as a named sprite in a sprite area, optionally storing the
 * palette with the sprite. Address of sprite returned in resultaddress.
 *
 *)
procedure sprite_get_rp(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag;
                var resultaddress : sprite_ptr) : os_error; extern;

(* ---------------------------- sprite_get_given ---------------------------
 * Copy a rectangle of screen delimited by the given pair of graphics
 * coordinates as a named sprite in a sprite area, optionally storing the
 * palette with the sprite.
 *
 *)
procedure sprite_get_given(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag;
                x0, y0, x1, y1 : integer) : os_error; extern;

(* --------------------------- sprite_get_given_rp -------------------------
 * Copy a rectangle of screen delimited by the given pair of graphics
 * coordinates as a named sprite in a sprite area, optionally storing the
 * palette with the sprite. Address of sprite returned in resultaddress.
 *
 *)
procedure sprite_get_given_rp(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag;
                x0, y0, x1, y1 : integer;
                var resultaddress : sprite_ptr) : os_error; extern;

(* ------------------------------ sprite_create ----------------------------
 * Create a named sprite in a sprite area of specified size and screen mode,
 * optionally reserving space for palette data with the sprite.
 *
 *)
procedure sprite_create(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag;
                width, height, mode : integer) : os_error; extern;

(* ------------------------------ sprite_create_rp -------------------------
 * Create a named sprite in a sprite area of specified size and screen mode,
 * optionally reserving space for palette data with the sprite.Address of
 * sprite returned in resultaddress.
 *
 *)
procedure sprite_create_rp(area : sprite_area_ptr;
                name : string;
                flag : sprite_palflag;
                width, height, mode : integer;
                var resultaddress : sprite_ptr) : os_error; extern;


(*********** Operations on system/user area, name/sprite pointer **********)

const
  sprite_id_name = 0;
  sprite_id_addr = $74527053; (* 'Magic' number ("SpRt") to test against *)

type sprite_type_ptr = ^sprite_type;
     sprite_type = integer;

type sprite_id_ptr = ^sprite_id;
     sprite_id_tag = 0..1;
     sprite_id =
       record
         s : record
               case sprite_id_tag of
                 (* Can use either name of sprite or address (faster) *)
                 0 : (name : string);
                 1 : (addr : sprite_ptr)
             end;
         (* User must tag the use of this structure manually *)
         tag : sprite_type
       end;


(* ----------------------------- sprite_select -----------------------------
 * Select the specified sprite for plotting using plot(0xed,x,y).
 *
 *)
procedure sprite_select(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ----------------------------- sprite_select_rp --------------------------
 * Select the specified sprite for plotting using plot(0xed,x,y). Address of
 * sprite returned in resultaddress.
 *
 *)
procedure sprite_select_rp(area : sprite_area_ptr;
                id : sprite_id_ptr;
                var resultaddress : sprite_ptr) : os_error; extern;

(* ----------------------------- sprite_delete -----------------------------
 * Delete the specified sprite.
 *
 *)
procedure sprite_delete(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ----------------------------- sprite_rename -----------------------------
 * Rename the specified sprite within the same sprite area.
 *
 *)
procedure sprite_rename(area : sprite_area_ptr;
                id : sprite_id_ptr;
                newname : string) : os_error; extern;

(* ----------------------------- sprite_copy -------------------------------
 * Copy the specified sprite as another named sprite in the same sprite area.
 *
 *)
procedure sprite_copy(area : sprite_area_ptr;
                id : sprite_id_ptr;
                copyname : string) : os_error; extern;

(* ----------------------------- sprite_put --------------------------------
 * Plot the specified sprite using the given GCOL action.
 *
 *)
procedure sprite_put(area : sprite_area_ptr;
                id : sprite_id_ptr;
                gcol : integer) : os_error; extern;

(* ----------------------------- sprite_put_given --------------------------
 * Plot the specified sprite at (x,y) using the given GCOL action.
 *
 *)
procedure sprite_put_given(area : sprite_area_ptr;
                id : sprite_id_ptr;
                gcol, x, y : integer) : os_error; extern;

(* --------------------------- sprite_put_scaled ---------------------------
 * Plot the specified sprite at (x,y) using the given GCOL action, and scaled
 * using the given scale factors.
 *
 *)
procedure sprite_put_scaled(area : sprite_area_ptr;
                id : sprite_id_ptr;
                gcol, x, y : integer;
                factors : sprite_factors_ptr;
                pixtrans : sprite_pixtrans_ptr) : os_error; extern;

(* ---------------------------- sprite_put_greyscaled ----------------------
 * Plot the specified sprite at (x,y) using the given GCOL action, and 
 * greyscaled using the given scale factors.
 *
 *)
procedure sprite_put_greyscaled(area : sprite_area_ptr;
                id : sprite_id_ptr;
                x, y : integer;
                factors : sprite_factors_ptr;
                pixtrans : sprite_pixtrans_ptr) : os_error; extern;

(* ----------------------------- sprite_put_mask ---------------------------
 * Plot the specified sprite mask in the background colour.
 *
 *)
procedure sprite_put_mask(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ----------------------------- sprite_put_mask_given ---------------------
 * Plot the specified sprite mask at (x,y) in the background colour. 
 *
 *)
procedure sprite_put_mask_given(area : sprite_area_ptr;
                id : sprite_id_ptr;
                x, y : integer) : os_error; extern;

(* --------------------------- sprite_put_mask_scaled ----------------------
 * Plot the sprite mask at (x,y) scaled, using the background colour/action
 *
 *)
procedure sprite_put_mask_scaled(area : sprite_area_ptr;
                id : sprite_id_ptr;
                x, y : integer;
                factors : sprite_factors_ptr) : os_error; extern;

(* ----------------------------- sprite_put_char_scaled --------------------
 * Paint char scaled at (x,y)
 *
 *)
procedure sprite_put_char_scaled(ch : char;
                x, y : integer;
                factors : sprite_factors_ptr) : os_error; extern;

(* ---------------------------- sprite_create_mask -------------------------
 * Create a mask definition for the specified sprite.
 *
 *)
procedure sprite_create_mask(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ---------------------------- sprite_remove_mask -------------------------
 * Remove the mask definition from the specified sprite.
 *
 *)
procedure sprite_remove_mask(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ---------------------------- sprite_insert_row --------------------------
 * Insert a row into the specified sprite at the given row.
 *
 *)
procedure sprite_insert_row(area : sprite_area_ptr;
                id : sprite_id_ptr;
                row : integer) : os_error; extern;

(* ---------------------------- sprite_delete_row --------------------------
 * Delete the given row from the specified sprite.
 *
 *)
procedure sprite_delete_row(area : sprite_area_ptr;
                id : sprite_id_ptr;
                row : integer) : os_error; extern;

(* ---------------------------- sprite_insert_column -----------------------
 * Insert a column into the specified sprite at the given column. 
 *
 *)
procedure sprite_insert_column(area : sprite_area_ptr;
                id : sprite_id_ptr;
                column : integer) : os_error; extern;

(* ---------------------------- sprite_delete_column -----------------------
 * Delete the given column from the specified sprite.
 *
 *)
procedure sprite_delete_column(area : sprite_area_ptr;
                id : sprite_id_ptr;
                column : integer) : os_error; extern;

(* ----------------------------- sprite_flip_x -----------------------------
 * Flip the specified sprite about the x axis
 *
 *)
procedure sprite_flip_x(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;

(* ----------------------------- sprite_flip_y -----------------------------
 * Flip the specified sprite about the y axis
 *
 *)
procedure sprite_flip_y(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;


type sprite_info_ptr = ^sprite_info;
     sprite_info =
       record
         width, height, mask, mode : integer
       end;

(* -------------------------------- sprite_readsize ------------------------
 * Read the size information for the specified sprite_id
 *
 *)
procedure sprite_readsize(area : sprite_area_ptr;
                id : sprite_id_ptr;
                resultinfo : sprite_info_ptr) : os_error; extern;


type sprite_colour_ptr = ^sprite_colour;
     sprite_colour =
       record
         colour, tint : integer
       end;

(* ----------------------------- sprite_readpixel --------------------------
 * Read the colour of a given pixel in the specified sprite_id
 *
 *)
procedure sprite_readpixel(area : sprite_area_ptr;
                id : sprite_id_ptr;
                x, y : integer;
                resultcolour : sprite_colour_ptr) : os_error; extern;

(* ----------------------------- sprite_writepixel -------------------------
 * Write the colour of a given pixel in the specified sprite_id
 *
 *)
procedure sprite_writepixel(area : sprite_area_ptr;
                id : sprite_id_ptr;
                x, y : integer;
                colour : sprite_colour_ptr) : os_error; extern;


const
  sprite_masktransparent = 0;
  sprite_masksolid       = 1;

type sprite_maskstate_ptr = ^sprite_maskstate;
     sprite_maskstate = integer;

(* ------------------------------- sprite_readmask -------------------------
 * Read the state of a given pixel in the specified sprite mask
 *
 *)
procedure sprite_readmask(area : sprite_area_ptr;
        id : sprite_id_ptr;
        x, y : integer;
        var resultmaskstate : sprite_maskstate) : os_error; extern;

(* ------------------------------- sprite_writemask ------------------------
 * Write the state of a given pixel in the specified sprite mask
 *
 *)
procedure sprite_writemask(area : sprite_area_ptr;
        id : sprite_id_ptr;
        x, y : integer;
        var resultmaskstate : sprite_maskstate) : os_error; extern;


type sprite_state_ptr = ^sprite_state;
     sprite_state =
       record
         r : array[0..3] of integer
       end;

(* ----------------------------- sprite_restorestate -----------------------
 * Restores the old state after one of the sprite redirection calls
 *
 *)
procedure sprite_restorestate(state : sprite_state) : os_error; extern;


(* ---------------------------- sprite_outputtosprite ----------------------
 * Redirect VDU output to a sprite, saving old state 
 *
 *)
procedure sprite_outputtosprite(area : sprite_area_ptr;
                id : sprite_id_ptr;
                save_area : pointer;
                state : sprite_state_ptr) : os_error; extern;

(* ----------------------- sprite_outputtomask -----------------------------
 * Redirects output to a sprite's transparency mask, saving old state
 *
 *)
procedure sprite_outputtomask(area : sprite_area_ptr;
                id : sprite_id_ptr;
                save_area : pointer;
                state : sprite_state_ptr) : os_error; extern;

(* --------------------------- sprite_outputtoscreen -----------------------
 * Redirect output back to screen, saving old state
 *
 *)
procedure sprite_outputtoscreen(save_area : pointer;
               state : sprite_state_ptr) : os_error; extern;

(* --------------------------- sprite_sizeof_spritecontext -----------------
 * Get size of save area needed to save sprite context.
 *
 *)
procedure sprite_sizeof_spritecontext(area : sprite_area_ptr;
                id : sprite_id_ptr;
                var size : integer) : os_error; extern;

(* ------------------------- sprite_sizeof_screencontext -------------------
 * Get size of save area needed to save screen context.
 *
 *)
procedure sprite_sizeof_screencontext(
                var size : integer) : os_error; extern;

(* ------------------------ sprite_removewastage ---------------------------
 * Removes left hand wastage from a sprite
 *
 *)
procedure sprite_removewastage(area : sprite_area_ptr;
                id : sprite_id_ptr) : os_error; extern;


(* new SWIs *)

(* ------------------------ sprite_change_size -----------------------------
 * General insert/delete rows/columns operations
 *
 *)
procedure sprite_change_size(area : sprite_area_ptr;
                id : sprite_id_ptr;
                rows : boolean;
                at, number : integer) : os_error; extern;

(* Typedefs and functions for rotating sprites. *)

type sprite_pgm_ptr = ^sprite_pgm;
     sprite_pgm =
       record
         p0, p1, p2, p3 : array[0..1] of integer
       end;

type sprite_transmat_ptr = ^sprite_transmat;
     sprite_transmat = array[0..5] of integer;

type sprite_box_ptr = ^sprite_box;
     sprite_box =
       record
         x0, y0, x1, y1 : integer
       end;

(* ------------------------ sprite_put_mask_trans ---------------------
 * Put a box from the mask in background colours through a transformation matrix
 *
 *)
procedure sprite_put_mask_trans(area : sprite_area_ptr;
                id : sprite_id_ptr;
                matrix : sprite_transmat_ptr) : os_error; extern;

(* ------------------------ sprite_put_mask_pgm -----------------------
 * Put a box from the mask in background colours to a parallelogram
 *
 *)
procedure sprite_put_mask_pgm(area : sprite_area_ptr;
                id : sprite_id_ptr;
                box : sprite_box_ptr;
                pgm : sprite_pgm_ptr) : os_error; extern;

(* ------------------------ sprite_put_trans --------------------------
 * Put a box from the sprite through a transformation matrix
 *
 *)
procedure sprite_put_trans(area : sprite_area_ptr;
                id : sprite_id_ptr;
                gcol_action : integer;
                box : sprite_box_ptr;
                matrix : sprite_transmat_ptr;
                pixtrans : sprite_pixtrans_ptr) : os_error; extern;

(* ------------------------ sprite_put_pgm ----------------------------
 * Put a box from the sprite to a parallelogram
 *
 *)
procedure sprite_put_pgm(area : sprite_area_ptr;
                id : sprite_id_ptr;
                gcol_action : integer;
                box : sprite_box_ptr;
                pgm : sprite_pgm_ptr;
                pixtrans : sprite_pixtrans_ptr) : os_error; extern;

# endif

(* end of sprite.h *)
