/*
** DRAW.C                     Put text on the color text screen
**
** Place text strings on the color text screen by fabricating a pointer to
** the video memory area.
**
** These video routines are probably about as slow as they come, and are
** not intended to reflect real graphics routines.
**
** "Well I know my name is Simon, and I like to do drawings..."
*/



#include "player.h"
#include <stdio.h>
#include <string.h>



/*
** screen                     Fabricated pointer to video memory
*/
#ifdef __FLAT__
typedef char* PSCREEN;
static PSCREEN screen = (PSCREEN)0xB8000;
#else
typedef char far* PSCREEN;
static PSCREEN screen = (PSCREEN)0xB8000000L;
#endif



/*
** ClearScreen()              Clears the screen
*/
void ClearScreen(void)
  {
  PSCREEN ps = screen;
  while (ps < screen + 25*80*2)
    {
    *ps++ = ' ';
    *ps++ = 7;
    }
  return;
  }



/*
** TextOut(ps,str,attr)       Display string with attribute
*/
static void TextOut(PSCREEN ps, char* str, unsigned char attr)
  {
  while (*str)
    {
    *ps++ = *str;
    *ps++ = attr;
    str++;
    }
  return;
  }



/*
** TextLeft(str,y,attr)       Left justify str at y with attribute attr
*/
void TextLeft(char* str, int y, unsigned char attr)
  {
  PSCREEN ps;
  ps = screen + (((y*80)+0)*2);
  TextOut(ps, str, attr);
  return;
  }



/*
** TextRight(str,x,y,attr)    Right justify str at y with attribute attr
*/
void TextRight(char* str, int y, unsigned char attr)
  {
  PSCREEN ps;
  ps = screen + (((y*80)+79-(strlen(str)-1))*2);
  TextOut(ps, str, attr);
  return;
  }



/*
** TextCenter(str,x,y,attr)   Center str at x,y with attribute attr
*/
void TextCenter(char* str, int y, unsigned char attr)
  {
  PSCREEN ps;
  ps = screen + (((y*80)+39-(strlen(str)-1)/2)*2);
  TextOut(ps, str, attr);
  return;
  }



/*
** DrawPlayer(play)           Update a player's display
*/
static void DrawPlayer(int play)
  {
  char buf[50];
  int row = play*8 + 6;
  PLAYER* p = &player[play];

  // Draw the player banner
  sprintf(buf, "PLAYER N\xF8 %d", play+1);
  TextCenter(buf, row, 5);
  sprintf(buf, "%s %s in slot %d  [F%d to change]",
          p->vendor, p->product, p->slot, play*4+1);
  if (p->state == STATE_SELECT)
    TextCenter(buf, row+1, 131);
  else
    TextCenter(buf, row+1, 3);

  // Draw the first button
  if (p->left.state == STATE_NORMAL)
    sprintf(buf, "<BUTTON %s>", p->left.name);
  else
    sprintf(buf, "<BUTTON ?>");
  if (p->left.state == STATE_SELECT)
    {
    TextLeft(buf, row+3, 143);
    }
  else
    {
    TextLeft(buf, row+3, (p->left.value) ? 15 : 3);
    sprintf(buf, "[F%d to change]", play*4+2);
    TextLeft(buf, row+4, 9);
    }

  // Draw the second button
  if (p->right.state == STATE_NORMAL)
    sprintf(buf, "<BUTTON %s>", p->right.name);
  else
    sprintf(buf, "<BUTTON ?>");
  if (p->right.state == STATE_SELECT)
    {
    TextRight(buf, row+3, 143);
    }
  else
    {
    TextRight(buf, row+3, (p->right.value) ? 15 : 3);
    sprintf(buf, "[F%d to change]", play*4+4);
    TextRight(buf, row+4, 9);
    }

  // Draw the axis
  sprintf(buf, "[----------------------------------------]");
  buf[p->pos+1] = '*';
  TextCenter(buf, row+3, 3);
  if (p->axis.state == STATE_NORMAL)
    sprintf(buf, "AXIS %s [F%d to change]", p->axis.name, play*4+3);
  else
    sprintf(buf, "AXIS ? [F%d to change]", play*4+3);
  if (p->axis.state == STATE_SELECT)
    TextCenter(buf, row+4, 143);
  else
    TextCenter(buf, row+4, 9);
  }



/*
** RefreshDisplay()           Update the display
*/
void RefreshDisplay(void)
  {
  int i;

  // Clear the screen
  ClearScreen();

  // Print a banner
  TextCenter("G R A V I S", 0, 11);
  TextCenter("GrIP API Demonstration Program", 1, 7);
  TextCenter("Version 2.10", 2, 7);
  TextRight("Advanced GRAVIS", 23, 13);

  // Print some brief instructions
  TextLeft("Press an F-Key to change parameters", 22, 3);
  TextLeft("or hit ESC or F10 to return to DOS.", 23, 3);

  // Draw the players
  for (i = 0; i < PLAYER_MAX; i++)
    DrawPlayer(i);

  return;
  }

