/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for 
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #                                      
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Sprite.h
    Author:  Copyright  1992, 1993, 1994 John Winters, Jason Williams, 
                                          Jason Howat
             and sundry contributors
    Version: 0.29 (02 Sep 1995)
    Purpose: Sprite-SWI interfaces.
             This version of the Sprite library only includes the most common
             sprite operations, and only on "user" sprite areas, and "named"
             sprites. (i.e. not pointers-to-sprites)
             More Sprite operations may appear as the moderator gets time
             to include them into the library.
    
    Mods:    02 Sep 1995 JH Desk_Sprite_MemorySize now works in 'double pixel' 
                            modes (see 'Libraries.Sprite.c.MemSize' for the 
                            details).
                            Added Desk_Sprite_Select.
*/


#ifndef __Desk_Sprite_h
#define __Desk_Sprite_h

#ifdef __cplusplus
	extern "C" {
#endif

#include <stdarg.h>

#ifndef __Desk_Core_h
	#include "Desk.Core.h"
#endif

#ifndef __Desk_Wimp_h
	#include "Desk.Wimp.h"
#endif

#ifndef __Desk_Coord_h
	#include "Desk.Coord.h"
#endif



#define Desk_sprite_MAXNAME    12

#define Desk_spritepool_SYSTEM 0
#define Desk_spritepool_WIMP   1


typedef struct {
    unsigned int areasize ;
    unsigned int numsprites ;
    unsigned int firstoffset ;
    unsigned int freeoffset ;
} Desk_sprite_areainfo ;

typedef Desk_sprite_areainfo *Desk_sprite_area;

typedef struct {
    unsigned int width ;
    unsigned int height ;
    unsigned int maskstatus ;
    unsigned int mode ;
} Desk_sprite_info ;

typedef Desk_sprite_info *sprite;


typedef struct {
    int          callno ;
    Desk_sprite_area  spritearea ;
    sprite       sprite ;
    void         *savearea ;
} Desk_sprite_outputstate ;


typedef struct
{
  int  Desk_offset_next;
  char name[Desk_sprite_MAXNAME];
  int  width;
  int  height;
  int  leftbit;
  int  rightbit;
  int  imageoffset;
  int  maskoffset;
  int  screenmode;
} Desk_sprite_header;


typedef struct
{
  Desk_wimp_point multiply;
  Desk_wimp_point divide;
} Desk_sprite_scalefactors;


extern void	Desk_Sprite_ScreenSave(const char *filename, Desk_bool savepalette);
 /* Save the screen as a sprite file - SpriteOp 2 */


extern void	Desk_Sprite_ScreenLoad(const char *filename);
 /* ScreenLoad a sprite file - SpriteOp 3 */

extern void	Desk_Sprite_InitArea(Desk_sprite_area area);
 /* Initialise a sprite area - SpriteOp 9 */

extern void	Desk_Sprite_Load(Desk_sprite_area area, const char *filename) ;
 /* Load a file into a sprite area - SpriteOp 10 */

extern void	Desk_Sprite_Merge(Desk_sprite_area area, const char *filename);
 /* Merge a file into a sprite area - SpriteOp 11 */

extern void	Desk_Sprite_Save(Desk_sprite_area area, const char *filename);
 /* Save a sprite area into a file - SpriteOp 12 */


extern void	Desk_Sprite_Create(Desk_sprite_area area, const char *name, int haspalette,
                               int width, int height, int screenmode);
/*
 *  Desk_Sprite_Create() - SpriteOp 15
 *    Creates a sprite according to the parameters.
 */

extern void	Desk_Sprite_Select(Desk_sprite_area area, const char *name,
                               Desk_sprite_header **spriteptr);
/*
 *  Desk_Sprite_Select() - SpriteOp 24
 *    Selects the given sprite.
 */

extern void	Desk_Sprite_Delete(Desk_sprite_area area, const char *name);
/*
 *  Desk_Sprite_Delete() - SpriteOp 25
 *    Deletes the given sprite
 */


extern void	Desk_Sprite_Rename(Desk_sprite_area area, const char *oldname, const char *newname);
/*
 *  Desk_Sprite_Rename() and Desk_Sprite_Copy() - SpriteOps 25, 26
 *    Unsurprisingly, these rename and copy a sprite, respectively.
 */

extern void	Desk_Sprite_Copy(Desk_sprite_area area, const char *oldname, const char *newname);
/*
 *  Desk_Sprite_Rename() and Desk_Sprite_Copy() - SpriteOps 25, 26
 *    Unsurprisingly, these rename and copy a sprite, respectively.
 */



extern void	Desk_Sprite_Get(Desk_sprite_area area, const char *name, int Desk_with_palette,
                            int left, int bottom, int right, int top,
                            sprite *Desk_sprite_ptr);
/*
 *  Desk_Sprite_Get() - SpriteOp 16
 *    Gets (creates and copies) a sprite from the given screen rectangle
 *  Note that the given coordinates are /all/ /inclusive/.
 */



extern void	Desk_Sprite_Plot(Desk_sprite_area area, const char *name,  /* "PutUser" */
                             int x, int y, int Desk_plot_action);
/*
 *  Desk_Sprite_Plot() - SpriteOp 34
 *    Plots a sprite with it's bottom-left corners at the given coordinate,
 *    using the given GCOL plot action (see GFX.h for plot actions)
 */


extern void	Desk_Sprite_ReadInfo(Desk_sprite_area area, const char *name,
                                 Desk_sprite_info *info);
 /* Reads sprite information - SpriteOp 40 */


extern void	Desk_Sprite_Redirect(Desk_sprite_area area, const char *name,
                                 void *savearea, Desk_sprite_outputstate *oldstate);
 /* redirects VDU output into the named sprite - SpriteOp 60 */


extern void	Desk_Sprite_UnRedirect(Desk_sprite_outputstate *oldstate);
 /* Un-redirects VDU output back to the saved state - SpriteOp 60 */



extern void	Desk_Sprite_ReadSaveAreaSize(Desk_sprite_area area, const char *name,
                                         int *saveareasize);
 /*  Desk_Sprite_ReadSaveAreaSize
  *  Given a sprite area and a sprite name, returns the save area size needed
  *  for the given sprite. (SpriteOp 62 veneer)
  */


/* Desk_Sprite_ReadControl (8)
 * Read information about sprite area
 * Returns number of sprites in area
 * If you aren't interested in any of the returned variables, then put NULL
 * pointers in
 */
extern int Desk_Sprite_ReadControl(Desk_sprite_area area, int *size, sprite *firstsprite,
                              void *firstfree);

extern int Desk_Sprite_GetName(Desk_sprite_area area, char *name, int spritenumber);
/* Desk_Sprite_GetName (13)
 * Read name of sprite, given number (starts from 1)
 * Buffer passed in 'name' must be at least 13 chars long
 * Returns length of name.
 */

extern void	Desk_Sprite_CreateMask(Desk_sprite_area area, const char *name);
/* Desk_Sprite_CreateMask (29)
 * Creates a mask for a sprite
 */

extern void	Desk_Sprite_RemoveMask(Desk_sprite_area area, const char *name);
/* Desk_Sprite_RemoveMask (30)
 * Removes a mask from a sprite
 */

extern void	Desk_Sprite_InsertRow(Desk_sprite_area area, const char *name, int pos);
/* Desk_Sprite_InsertRow (31)
 * Inserts a row at the specified row, and shuffles the rest on
 */

extern void	Desk_Sprite_DeleteRow(Desk_sprite_area area, const char *name, int pos);
/* Desk_Sprite_DeleteRow (32)
 * Deletes a row at the specified row, and shuffles the rest on
 */

extern void	Desk_Sprite_FlipX(Desk_sprite_area area, const char *name);
/* Desk_Sprite_FlipX (33)
 * Flips sprite about x axis (top<>bottom)
 */

extern void	Desk_Sprite_Append(Desk_sprite_area area, const char *name1, const char *name2,
                               int dir);
/* Desk_Sprite_Append (35)
 * Glues two sprites together
 * Sprite 2 is deleted, and sprite 1 becomes them both added together
 * Sprites must be the same width if appending vertically, or the same height if
 * appending horizontally
 * 'dir' is 0 for horizontal, 1 for vertical
 */

extern int Desk_Sprite_CreatePalette(Desk_sprite_area area, const char *name, Desk_bool big);
/* Desk_Sprite_CreatePalette (37)
 * Returns size of palette created
 * If 'big' is true, then a 256 entry palette is created (RO3 only)
 */

extern void	Desk_Sprite_RemovePalette(Desk_sprite_area area, const char *name);
/* Desk_Sprite_RemovePalette (37)
 */

extern int Desk_Sprite_ReadPixel(Desk_sprite_area area, const char *name, const Desk_wimp_point *pos);
/* Desk_Sprite_ReadPixel (41)
 * Returns colour
 * Tint is returned, so long as 'tint' isn't NULL (0)
 */

extern void	Desk_Sprite_WritePixel(Desk_sprite_area area, const char *name,
                                   const Desk_wimp_point *pos, int colour, int tint);
/* Desk_Sprite_WritePixel (42)
 */

extern Desk_bool Desk_Sprite_ReadMask(Desk_sprite_area area, const char *name, const Desk_wimp_point *pos);
/* Desk_Sprite_ReadMask (43)
 * Returns Desk_bool_TRUE if solid
 */

extern void	Desk_Sprite_WriteMask(Desk_sprite_area area, const char *name, const Desk_wimp_point *pos,
                                  Desk_bool solid);
/* Desk_Sprite_WriteMask (43)
 */

extern void	Desk_Sprite_InsertColumn(Desk_sprite_area area, const char *name, int pos);
/* Desk_Sprite_InsertColumn (45)
 * Inserts a column at the specified column, and shuffles the rest on
 */

extern void	Desk_Sprite_DeleteColumn(Desk_sprite_area area, const char *name, int pos);
/* Desk_Sprite_DeleteColumn (46)
 * Deletes a column at the specified column, and shuffles the rest on
 */

extern void	Desk_Sprite_FlipY(Desk_sprite_area area, const char *name);
/* Desk_Sprite_FlipY (47)
 * Flips sprite about y axis (left<>right)
 */

extern void	Desk_Sprite_PlotMask(Desk_sprite_area area, const char *name, const Desk_wimp_point *pos);
/* Desk_Sprite_PlotMask (49)
 */

extern void	Desk_Sprite_PlotMaskScaled(Desk_sprite_area area, const char *name,
                                       const Desk_wimp_point *pos, Desk_sprite_scalefactors sc);
/* Desk_Sprite_PlotMaskScaled (50)
 */

extern void	Desk_Sprite_PlotScaled(Desk_sprite_area area, const char *name,
                                   const Desk_wimp_point *pos, const Desk_sprite_scalefactors *scale,
                                   const void *pixtrans);
/* Desk_Sprite_PlotScaled (52)
 * pixtrans can be up to 16 bytes long, it's left as a void * so that you can
 * use a char *, or a pixtrans * if one gets defined in the future
 */

extern void	Desk_Sprite_PlotGrey(Desk_sprite_area area, const char *name,
                                 const Desk_wimp_point *pos, Desk_sprite_scalefactors scale,
                                 const void *pixtrans);
/* Desk_Sprite_PlotGrey (53)
 * pixtrans should be a greyscale for the antialiasing to work properly
 * (or a blue scale or whatever)
 */

extern void	Desk_Sprite_WimpPlot(Desk_sprite_area area, const char *name, const Desk_wimp_point *pos,
                                 const Desk_convert_block *convert, int Desk_plot_action);
/* Desk_Sprite_WimpPlot
 * Plots a sprite in a window.
 * 'pos' should be work area coordinates, and convert is the convert block for
 * the window.
 * All relevant scaling/colour translating is taken to plot the sprite at 1:1 in
 * the current mode
 */


/* Sprite manipulation functions ------------------------------------------ */

typedef enum
{
  Desk_sprite_HASNOMASKPAL = 0x00,             /* Sprite has no mask or palette */
  Desk_sprite_HASNOPALMASK = 0x00,
  Desk_sprite_HASMASK      = 0x01,             /* Sprite has a mask only        */
  Desk_sprite_HASPAL       = 0x02,             /* Sprite has a palette only     */
  Desk_sprite_HASMASKPAL   = 0x03,             /* Has both mask and palette     */
  Desk_sprite_HASPALMASK   = 0x03
} Desk_spritemem_flags;


extern int Desk_Sprite_MemorySize(int width, int height, int mode,
                             Desk_spritemem_flags flags);
 /*  Desk_Sprite_MemorySize
  *  Returns the amount of memory to malloc to hold the sprite
  *  defined by the parameters.
  *
  *  -- Example, create sprite area large enough for 3 identical sprites
  *     which are mode 12, 34x17, and have their own palettes.
  *
  *    Desk_sprite_areainfo *pUserSprites;
  *
  *    size = 3 * Desk_Sprite_MemorySize( 34, 17, 12, Desk_sprite_HASPAL );
  *    size += sizeof( Desk_sprite_areainfo );
  *    pUserSprites = (Desk_sprite_areainfo*) malloc( size );
  */


extern int Desk_Sprite_IconMemorySize(const Desk_window_block *pWinBlock, Desk_icon_handle icon,
                                 int mode, Desk_spritemem_flags flags,
                                 Desk_wimp_point *dimensions);
 /*  Desk_Sprite_IconMemorySize
  *  This takes the given WIMP icon, and calculates the size of the sprite
  *  needed to exactly fill it, by calling Desk_Sprite_MemorySize for you.
  *  If 'dimensions' is not NULL, then it will be filled in with the needed
  *  size (width/height) of the sprite in pixels.
  *
  *  The window is passed in as a Desk_window_block so that this can be applied
  *  to templates as well as open windows.
  *
  *  Example:
  *  {
  *    Desk_window_info winfo;
  *    int         s;
  *
  *    Desk_Window_GetInfo(mainwindow, &winfo);
  *    s = Desk_Sprite_IconMemorySize(&winfo.block, 5, |* Get info for icon 5    *|
  *                          Desk_screen_mode,         |* in current screen mode *|
  *                          Desk_sprite_HASNOMASKPAL, |* with no mask/palette   *|
  *                          NULL);               |* Don't return dimensions*|
  */


extern Desk_sprite_area Desk_Sprite_LoadFile(const char *filename);
/*  Desk_Sprite_LoadFile
 *  This loads the given sprite file into a sprite area, & returns a pointer to
 *  it.  The memory is automatically allocated with malloc(), so to free it
 *  later, simply call free() on the returned pointer.
 */



extern Desk_sprite_area Desk_Sprite_LoadFiles(int nooffiles, ...);
/*
  Purpose:  - Loads any number of sprite files into sprite area
  Inputs:   - nooffiles - number of files to be loaded
              ...       - pointers to pathnames of files to be loaded
  Returns:  - pointer to sprite area
  SeeAlso:  - Desk_Sprite_LoadFile

****************************************************************************/


#ifdef __cplusplus
}
#endif
  

#endif
