/*
    ####             #    #     # #
    #   #            #    #       #          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 GFX_Mode, GFX_SetOrigin.
*/


#ifndef __dl_gfx_h
#define __dl_gfx_h

#ifdef __cplusplus
extern "C" {
#endif


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

#define  plot_SOLIDBOTH       0x00
#define  plot_SOLIDEXFINAL    0x08
#define  plot_DOTTEDBOTH      0x10
#define  plot_DOTTEDEXFINAL   0x18
#define  plot_SOLIDEXINIT     0x20
#define  plot_SOLIDEXBOTH     0x28
#define  plot_DOTTEDEXINIT    0x30
#define  plot_DOTTEDEXBOTH    0x38
#define  plot_POINT           0x40
#define  plot_HHORZLINEFILLNB 0x48
#define  plot_TRIANGLEFILL    0x50
#define  plot_HORIZLINEFILLB  0x58
#define  plot_RECTANGLEFILL   0x60
#define  plot_HORIZLINEFILLF  0x68
#define  plot_PARALLELFILL    0x70
#define  plot_HORIZLINEFILLNF 0x78
#define  plot_FLOODTOBACK     0x80
#define  plot_FLOODTOFORE     0x88
#define  plot_CIRCLE          0x90
#define  plot_CIRCLEFILL      0x98
#define  plot_CIRCLEARC       0xA0
#define  plot_SEGMENT         0xA8
#define  plot_SECTOR          0xB0
#define  plot_BLOCK           0xB8
#define  plot_ELLIPSE         0xC0
#define  plot_ELLIPSEFILL     0xC8
#define  plot_GRAPHICSCHAR    0xD0
#define  plot_SPRITE          0xE8

/* Within each block of eight the offset from the base number means: */
#define  plot_MOVECURSORREL   0
#define  plot_DRAWRELFORE     1
#define  plot_DRAWRELINVERSE  2
#define  plot_DRAWRELBACK     3
#define  plot_MOVECURSORABS   4
#define  plot_DRAWABSFORE     5
#define  plot_DRAWABSINVERSE  6
#define  plot_DRAWABSBACK     7


/* The above applies except for plot_BLOCK where the codes are as follows: */
#define  plot_BMOVEREL        0
#define  plot_BMOVERECTREL    1
#define  plot_BCOPYRECTREL    2
 
#define  plot_BMOVEABS        4
#define  plot_BMOVERECTABS    5
#define  plot_BCOPYRECTABS    6


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



/*  GFX_ miscellaneous drawing macros ------------------------------
 *
 *  Below are some macros using 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.
 *
 *  GFX_Move(X, Y)  Moves the graphics cursor to the OS co-ordinates X, Y
 *  GFX_Plot(X, Y)  Plots a pixel at the specified position
 *  GFX_Draw(X, Y)  Draws a line from the current cursor position to x,y
 */

#define GFX_Move(x, y) GFX_Plot(plot_SOLIDBOTH + plot_MOVECURSORABS, x, y)
#define GFX_MoveBy(x, y) GFX_Plot(plot_SOLIDBOTH + plot_MOVECURSORREL, x, y)
#define GFX_PlotPoint(x, y) GFX_Plot(plot_POINT + plot_DRAWABSFORE, x, y)
#define GFX_PlotPointBy(x, y) GFX_Plot(plot_POINT + plot_DRAWRELFORE, x, y)
#define GFX_Draw(x, y) GFX_Plot(plot_SOLIDBOTH + plot_DRAWABSFORE, x, y)
#define GFX_DrawBy(x, y) GFX_Plot(plot_SOLIDBOTH + plot_DRAWRELFORE, x, y)


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

#define GFX_RectangleFill(x, y, w, h)                       \
  {                                                         \
    GFX_Move(x, y);                                         \
    GFX_Plot(plot_RECTANGLEFILL + plot_DRAWRELFORE, w, h);  \
  }
/*
Draws a filled rectangle
*/

#define GFX_Circle(x, y, r)                                 \
  {                                                         \
    GFX_Move(x, y);                                         \
    GFX_Plot(plot_CIRCLE + plot_DRAWRELFORE, (r), 0);       \
  }
/*
Draw circle outline
*/

#define GFX_CircleFill(x, y, r)                             \
  {                                                         \
    GFX_Move(x, y);                                         \
    GFX_Plot(plot_CIRCLEFILL + plot_DRAWRELFORE, (r), 0);   \
  }
/*
Draw filled circle
*/


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


extern void GFX_VDU(char ch);
/*    (An 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 GFX_VDU()
 */

#define VDU(C) GFX_VDU(C)


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


#define GFX_Mode(M) {GFX_VDU(22); GFX_VDU(M);}
/*
 *    Sets screen mode.
 */


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


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


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


extern void GFX_Wait(void);
/*
 *  [equivalent to WAIT, *FX 19, 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 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
