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

    File:    GFX.gfx.h
    Author:  Copyright  1992, 1993 Edouard Poor, Jason Williams, Jason Howat
    Version: 0.71 (02 Sep 1995)
    Purpose: Graphics manipulation commands
    Mods:    02 Sep 1995 JH Added Desk_GFX_Mode, Desk_GFX_SetOrigin.
*/


#ifndef __Desk_GFX_h
#define __Desk_GFX_h

#ifdef __cplusplus
	extern "C" {
#endif


/* Plot codes to be used with the Desk_GFX_Plot function. */

#define  Desk_plot_SOLIDBOTH       0x00
#define  Desk_plot_SOLIDEXFINAL    0x08
#define  Desk_plot_DOTTEDBOTH      0x10
#define  Desk_plot_DOTTEDEXFINAL   0x18
#define  Desk_plot_SOLIDEXINIT     0x20
#define  Desk_plot_SOLIDEXBOTH     0x28
#define  Desk_plot_DOTTEDEXINIT    0x30
#define  Desk_plot_DOTTEDEXBOTH    0x38
#define  Desk_plot_POINT           0x40
#define  Desk_plot_HHORZLINEFILLNB 0x48
#define  Desk_plot_TRIANGLEFILL    0x50
#define  Desk_plot_HORIZLINEFILLB  0x58
#define  Desk_plot_RECTANGLEFILL   0x60
#define  Desk_plot_HORIZLINEFILLF  0x68
#define  Desk_plot_PARALLELFILL    0x70
#define  Desk_plot_HORIZLINEFILLNF 0x78
#define  Desk_plot_FLOODTOBACK     0x80
#define  Desk_plot_FLOODTOFORE     0x88
#define  Desk_plot_CIRCLE          0x90
#define  Desk_plot_CIRCLEFILL      0x98
#define  Desk_plot_CIRCLEARC       0xA0
#define  Desk_plot_SEGMENT         0xA8
#define  Desk_plot_SECTOR          0xB0
#define  Desk_plot_BLOCK           0xB8
#define  Desk_plot_ELLIPSE         0xC0
#define  Desk_plot_ELLIPSEFILL     0xC8
#define  Desk_plot_GRAPHICSCHAR    0xD0
#define  Desk_plot_SPRITE          0xE8

/* Within each block of eight the offset from the base number means: */
#define  Desk_plot_MOVECURSORREL   0
#define  Desk_plot_DRAWRELFORE     1
#define  Desk_plot_DRAWRELINVERSE  2
#define  Desk_plot_DRAWRELBACK     3
#define  Desk_plot_MOVECURSORABS   4
#define  Desk_plot_DRAWABSFORE     5
#define  Desk_plot_DRAWABSINVERSE  6
#define  Desk_plot_DRAWABSBACK     7


/* The above applies except for Desk_plot_BLOCK where the codes are as follows: */
#define  Desk_plot_BMOVEREL        0
#define  Desk_plot_BMOVERECTREL    1
#define  Desk_plot_BCOPYRECTREL    2
 
#define  Desk_plot_BMOVEABS        4
#define  Desk_plot_BMOVERECTABS    5
#define  Desk_plot_BCOPYRECTABS    6


enum	{
	Desk_gfx_action_OVERWRITE	= 0,
	Desk_gfx_action_OR,
	Desk_gfx_action_AND,
	Desk_gfx_action_XOR,
	Desk_gfx_action_INVERT,
	Desk_gfx_action_LEAVE,
	Desk_gfx_action_ANDNOT,
	Desk_gfx_action_ORNOT,
	
	Desk_gfx_action_TRANSPARENTBACKGROUND	= 8,
	
	Desk_gfx_action_COLOURPATTERN_1		= 16,
	Desk_gfx_action_COLOURPATTERN_2		= 32,
	Desk_gfx_action_COLOURPATTERN_3		= 48,
	Desk_gfx_action_COLOURPATTERN_4		= 64,
	Desk_gfx_action_COLOURPATTERN_GIANT		= 80
	};
/*
Graphics plot actions. Use with Desk_GFX_GCOL and Desk_ColourTrans_SetGCOL.
See PRM 1-566.
 */

extern void Desk_GFX_Plot(int plotcode, int x, int y);
/*
 *    Executes one Desk_OS_Plot command.
 *      plotcode is the Plot code (as above)
 *      x and y are the X and Y screen coordinates to use
 */



/*  Desk_GFX_ miscellaneous drawing macros ------------------------------
 *
 *  Below are some macros using Desk_GFX_Plot to make life easier for you.
 *  the "By" form (MoveBy, etc) moves/draws relative to the current cursor
 *  position, while the other form draws in absolute OS coords.
 *
 *  Desk_GFX_Move(X, Y)  Moves the graphics cursor to the OS co-ordinates X, Y
 *  Desk_GFX_Plot(X, Y)  Plots a pixel at the specified position
 *  Desk_GFX_Draw(X, Y)  Draws a line from the current cursor position to x, y
 */

#define Desk_GFX_Move(x, y) Desk_GFX_Plot(Desk_plot_SOLIDBOTH + Desk_plot_MOVECURSORABS, x, y)
#define Desk_GFX_MoveBy(x, y) Desk_GFX_Plot(Desk_plot_SOLIDBOTH + Desk_plot_MOVECURSORREL, x, y)
#define Desk_GFX_PlotPoint(x, y) Desk_GFX_Plot(Desk_plot_POINT + Desk_plot_DRAWABSFORE, x, y)
#define Desk_GFX_PlotPointBy(x, y) Desk_GFX_Plot(Desk_plot_POINT + Desk_plot_DRAWRELFORE, x, y)
#define Desk_GFX_Draw(x, y) Desk_GFX_Plot(Desk_plot_SOLIDBOTH + Desk_plot_DRAWABSFORE, x, y)
#define Desk_GFX_DrawBy(x, y) Desk_GFX_Plot(Desk_plot_SOLIDBOTH + Desk_plot_DRAWRELFORE, x, y)


extern void Desk_GFX_Rectangle(int x, int y, int w, int h);
/*
Draws a rectangle outline
*/

#define Desk_GFX_RectangleFill(x, y, w, h)                       \
  {                                                         \
    Desk_GFX_Move(x, y);                                         \
    Desk_GFX_Plot(Desk_plot_RECTANGLEFILL + Desk_plot_DRAWRELFORE, w, h);  \
  }
/*
Draws a filled rectangle
*/

#define Desk_GFX_Circle(x, y, r)                                 \
  {                                                         \
    Desk_GFX_Move(x, y);                                         \
    Desk_GFX_Plot(Desk_plot_CIRCLE + Desk_plot_DRAWRELFORE, (r), 0);       \
  }
/*
Draw circle outline
*/

#define Desk_GFX_CircleFill(x, y, r)                             \
  {                                                         \
    Desk_GFX_Move(x, y);                                         \
    Desk_GFX_Plot(Desk_plot_CIRCLEFILL + Desk_plot_DRAWRELFORE, (r), 0);   \
  }
/*
Draw filled circle
*/


extern void Desk_GFX_CLG(void);
/*
 *    Clears the current graphics window to the current background colour
 */


extern void Desk_GFX_VDU(char ch);
/*    (An Desk_OS_WriteC veneer)
 *    Writes the given ASCII character to the VDU stream
 *    A macro is defined to allow use of the form VDU() as well as Desk_GFX_VDU()
 */

#define VDU(C) Desk_GFX_VDU(C)


#define Desk_GFX_GCOL(A, C) {Desk_GFX_VDU(18); Desk_GFX_VDU(A); Desk_GFX_VDU(C);}
/*    Sets graphics colour and action.
 *    A macro which emits a VDU sequence to change graphics colours
 */


#define Desk_GFX_Mode(M) {Desk_GFX_VDU(22); Desk_GFX_VDU(M);}
/*
 *    Sets screen mode.
 */


#define Desk_GFX_SetOrigin(x, y) {short a=(x), b=(y); Desk_GFX_VDU(29); \
                            Desk_GFX_VDU(a & 0xff); Desk_GFX_VDU((a>>8) & 0xff); \
                            Desk_GFX_VDU(b & 0xff); Desk_GFX_VDU((b>>8) & 0xff);}
/*
 *    Sets the graphics origin.
 */


extern void Desk_GFX_Write0( const char *string);
/*
 *    Writes the given zero-terminated string to the VDU stream
 *    (veneer for SWI "Desk_OS_Write0")
 */


extern void Desk_GFX_WriteN( const char *string, int numchars);
/*
 *    Writes 'numchars' characters from the given string to the VDU stream
 *    (veneer for SWI "Desk_OS_WriteN")
 */


extern void Desk_GFX_Wait(void);
/*
 *  [equivalent to WAIT, *FX 19, Desk_OS_Byte 19]
 *
 *    This call does not return until the vertical refresh has finished.
 *    This means that you get control back after the hardware has
 *    finshed updating the screen so if you do any drawing immediately
 *    after this call it will be done while the screen is not being
 *    drawn. This helps reduce flicker. Calling this procedure in Wimp
 *    applications should be only used sparingly as overuse will slow down
 *    screen output to an unacceptable level. Generally only use by
 *    experimentation--write your graphics code, if it flickers too much try
 *    putting in a Desk_GFX_Wait() and see if it help. If it does and the update
 *    speed isn't adversly affected then leave it in.
 */

#ifdef __cplusplus
}
#endif


#endif
