Logo Search packages:      
Sourcecode: vgacardgames version File versions  Download package

ohlinux.c

/*
 * Oh Hell!
 *
 * Copyright (C) Evan Harris, 1991, 1993, 1994, 1995.
 *
 * Permission is granted to freely redistribute and modify this code,
 * providing the author(s) get credit for having written it.
 */

#include <stdlib.h>
#include <stdio.h>

#include <vga.h>
#include <vgamouse.h>

#include "vga16.h"
#include "mouse.h"
#include "key.h"
#include "ohhell.h"


#define OH_SCREENMODE G640x480x16
#define OH_SCREENWIDTH 640
#define OH_SCREENHEIGHT 480

#define OH_TEXTFG 1
#define OH_TEXTBG 0
#define OH_BUTTONFG 2
#define OH_BUTTONBG 6
#define OH_MOUSEFG 5
#define OH_MOUSEDARKFG 2

#define NUMCARDIMAGES 52
#define CARDACTUALWIDTH 53
#define CARDIMAGEWIDTH 56
#define CARDIMAGEHEIGHT 80

#define VERSION "OH HELL!  v1.3"

#ifndef CARDSFILE
#define CARDSFILE "Cards56x80"
#endif
#ifndef CARDSMOUSESAMPLERATE
#define CARDSMOUSESAMPLERATE MOUSE_DEFAULTSAMPLERATE
#endif

#define USLEEP_TIME 30000


#define CARDTOIMAGE(card)     (card % NUMCARDIMAGES)

#define BITWIDTH CARDIMAGEWIDTH /* multiple of 8 */
#define BITHEIGHT CARDIMAGEHEIGHT
#define BITSHOWLEFT 24        /* multiple of 8 */

#define OH_QUITLEFT (OH_SCREENWIDTH - 88)
#define OH_QUITRIGHT (OH_QUITLEFT + 80)
#define OH_QUITBOTTOM 76
#define OH_QUITTOP (OH_QUITBOTTOM - 16)
#define OH_NEWGAMEBOTTOM 48
#define OH_NEWGAMETOP (OH_NEWGAMEBOTTOM - 16)

#define OH_PALETTESIZE 9

int palette[OH_PALETTESIZE * 3] = {
    0x00, 0x20, 0x00,         /* green */
    0x3f, 0x3f, 0x3f,         /* white */
    0x00, 0x00, 0x00,         /* black */
    0x37, 0x00, 0x00,         /* red */
    0x00, 0x00, 0x20,         /* blue */
    0x3f, 0x3f, 0x00,         /* yellow */
    0x1a, 0x1a, 0x1a,         /* grey */
};

#define MIN(a, b) ((a) < (b) ? (a) : (b))
static void LoadCards(char *file);
static long GetMouseButton(void);
static void WhileMouseButton(void);

static unsigned char ***imageCard;
static unsigned char *blankLine;


void
InitDisplay(int argc, char **argv)
{
    vga_disabledriverreport();
    vga_init();
#if !defined(CARDSMOUSE)
    vga_setmousesupport(1);
#endif
    
    if (vga_setmode(OH_SCREENMODE) != 0) {
      fprintf(stderr, "Mode %s not available!\n",
            vga_getmodename(OH_SCREENMODE));
      exit(1);
    }

#if defined(CARDSMOUSE)
    mouse_init("/dev/mouse", vga_getmousetype(), CARDSMOUSESAMPLERATE);
    mouse_setxrange(0, OH_SCREENWIDTH - 1);
    mouse_setyrange(0, OH_SCREENHEIGHT - 1);
    mouse_setwrap(MOUSE_NOWRAP);
#endif

    vga16_init();

    LoadCards(CARDSFILE);

    blankLine = (unsigned char *)calloc(OH_SCREENWIDTH, sizeof(unsigned char));
    if (blankLine == NULL) {
      fprintf(stderr, "Error: cannot get memory for blankLine\n");
      exit(1);
    }

    vga_setpalvec(0, OH_PALETTESIZE, &palette[0]);

    vga16_text(16, OH_SCREENHEIGHT - 56, "SCORES", OH_TEXTFG, OH_TEXTBG);
    vga16_text(OH_SCREENWIDTH - 110, OH_SCREENHEIGHT - 56, "BIDS",
             OH_TEXTFG, OH_TEXTBG);
    vga16_text(OH_SCREENWIDTH - 52, OH_SCREENHEIGHT - 56, "TRICKS",
             OH_TEXTFG, OH_TEXTBG);

    vga16_text(OH_QUITLEFT, OH_QUITBOTTOM, "   QUIT   ",
             OH_BUTTONFG, OH_BUTTONBG);
    vga16_text(OH_QUITLEFT, OH_NEWGAMEBOTTOM, " NEW GAME ",
             OH_BUTTONFG, OH_BUTTONBG);

    vga16_text(OH_SCREENWIDTH - 120, 120, VERSION, OH_TEXTFG, OH_TEXTBG);
}


static void
LoadCards(char *file)
{
    int i, j, k, l, c, colour;
    FILE *f;

    f = fopen(file, "r");
    if (f == NULL) {
      fprintf(stderr, "Cannot find '%s'\n", file);
      exit(1);
    }

    imageCard = (unsigned char ***)malloc(NUMCARDIMAGES
                                * sizeof(unsigned char **));
    if (imageCard == NULL) {
      fprintf(stderr, "Error: cannot get memory for imageCard\n");
      exit(1);
    }
    for (i = 0; i < NUMCARDIMAGES; i++) {
      imageCard[i] = (unsigned char **)malloc(CARDIMAGEHEIGHT
                                    * sizeof(unsigned char *));
      if (imageCard == NULL) {
          fprintf(stderr, "Error: cannot get memory for imageCard[%d]\n",
                i);
          exit(1);
      }
      for (j = 0; j < CARDIMAGEHEIGHT; j++) {
          imageCard[i][j] = (unsigned char *)malloc(CARDIMAGEWIDTH
                                          * sizeof(unsigned char));
          if (imageCard[i][j] == NULL) { 
            fprintf(stderr,
                  "Error: cannot get memory for imageCard[%d][%d]\n",
                  i, j);
            exit(1);
          }
          
          if (SUIT(i) == SPADES || SUIT(i) == CLUBS) {
            colour = 2;
          } else {
            colour = 3;
          }
          if (TYPE(i) < JACK) {
            for (k = 0; k < CARDIMAGEWIDTH / 8; k++) {
                if ((c = getc(f)) == EOF) {
                  fprintf(stderr, "Unexpected EOF in '%s'\n", file);
                  exit(1);
                }
                for (l = 0; l < 8; l++) {
                  imageCard[i][j][8 * k + l] =
                      (c & 1 << (7 - l)) ? colour : 1;
                }
            }
            for (k = CARDACTUALWIDTH; k < CARDIMAGEWIDTH; k++) {
                imageCard[i][j][k] = 0;
            }
          } else {
            for (k = 0; k < CARDIMAGEWIDTH / 2; k++) {
                if ((c = getc(f)) == EOF) {
                  fprintf(stderr, "Unexpected EOF in '%s'\n", file);
                  exit(1);
                }
                imageCard[i][j][2 * k] = (unsigned char)c >> 4;
                imageCard[i][j][2 * k + 1] = (unsigned char)c & 0xf;
            }
          }
      }
    }

    fclose(f);
}


static int cardPosLeft[4] = { /* S, W, N, E */
    ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~(0x7),
    ((OH_SCREENWIDTH - BITWIDTH) / 8) & ~(0x7),
    ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~(0x7),
    (7 * (OH_SCREENWIDTH - BITWIDTH) / 8) & ~(0x7),
};
static int cardPosTop[4] = {  /* S, W, N, E */
    OH_SCREENHEIGHT - 2 * BITHEIGHT - 10,
    (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2,
    0,
    (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2,
};

void
ShowPlay(unsigned char card, unsigned char player)
{
    int line;
    
    for (line = 0; line < BITHEIGHT; line++) {
      vga16_drawscansegment(imageCard[CARDTOIMAGE(card)][line],
                        cardPosLeft[player], cardPosTop[player] + line,
                        BITWIDTH);
    }
}


void
RemovePlays()
{
    int player, line;
    
    for (player = 0; player < 4; player++) {
      for (line = 0; line < BITHEIGHT; line++) {
          vga16_drawscansegment(blankLine, cardPosLeft[player],
                          cardPosTop[player] + line, BITWIDTH);
      }
    }
}


static int numInDeal;


void
ShowHand(unsigned char *hand, unsigned char num)
{
    int left, top, width, line, i;

    numInDeal = num;

    left = ((OH_SCREENWIDTH - ((num - 1) * BITSHOWLEFT + BITWIDTH)) / 2)
      & ~0x7;
    top = OH_SCREENHEIGHT - BITHEIGHT;
    for (line = 0; line < BITHEIGHT; line++) {
      vga16_drawscansegment(blankLine, left, top + line,
                        BITWIDTH + (num - 1) * BITSHOWLEFT);
    }

    left += (num - 1) * BITSHOWLEFT;
    width = BITWIDTH;
    for (i = num - 1; i >= 0; i--) {
      if (hand[i] != NOCARD) {
          for (line = 0; line < BITHEIGHT; line++) {
            vga16_drawscansegment(imageCard[CARDTOIMAGE(hand[i])][line],
                              left, top + line, width);
          }
          width = BITSHOWLEFT;
      } else {
          width += BITSHOWLEFT;
          if (width > BITWIDTH) {
            width = BITWIDTH;
          }
      }
      left -= BITSHOWLEFT;
    }
}


static int winsPosLeft[4] = { /* S, W, N, E */
    OH_SCREENWIDTH - 40,
    OH_SCREENWIDTH - 56,
    OH_SCREENWIDTH - 40,
    OH_SCREENWIDTH - 24,
};
static int winsPosTop[4] = {  /* S, W, N, E */
    OH_SCREENHEIGHT - 4,
    OH_SCREENHEIGHT - 20,
    OH_SCREENHEIGHT - 36,
    OH_SCREENHEIGHT - 20,
};

void
ShowWins(unsigned char *wins)
{
    char s[4];
    int i;

    for (i = 0; i < 4; i++) {
      sprintf(s, "%2d", wins[i]);
      vga16_text(winsPosLeft[i], winsPosTop[i], s, OH_TEXTFG, OH_TEXTBG);
    }
}


static int bidPosLeft[4] = {  /* S, W, N, E */
    OH_SCREENWIDTH - 106,
    OH_SCREENWIDTH - 122,
    OH_SCREENWIDTH - 106,
    OH_SCREENWIDTH - 90,
};
static int bidPosTop[4] = {   /* S, W, N, E */
    OH_SCREENHEIGHT - 4,
    OH_SCREENHEIGHT - 20,
    OH_SCREENHEIGHT - 36,
    OH_SCREENHEIGHT - 20,
};

void
ShowBid(unsigned char bid, unsigned char location)
{
    char s[4];

    sprintf(s, "%2d", bid);
    vga16_text(bidPosLeft[location], bidPosTop[location], s,
             OH_TEXTFG, OH_TEXTBG);
}


void
RemoveBids()
{
    int i;
    
    for (i = 0; i < 4; i++) {
      vga16_text(bidPosLeft[i], bidPosTop[i], "  ", OH_TEXTFG, OH_TEXTBG);
    }
}


static int scorePosLeft[4] = {      /* S, W, N, E */
    24,
    0,
    24,
    48,
};
static int scorePosTop[4] = { /* S, W, N, E */
    OH_SCREENHEIGHT - 4,
    OH_SCREENHEIGHT - 20,
    OH_SCREENHEIGHT - 36,
    OH_SCREENHEIGHT - 20,
};

void
ShowScores(unsigned char *scores)
{
    int i;
    char s[4];

    for (i = 0; i < 4; i++) {
      sprintf(s, "%3d", scores[i]);
      vga16_text(scorePosLeft[i], scorePosTop[i], s, OH_TEXTFG, OH_TEXTBG);
    }
}


void
ShowTrumps(unsigned char card)
{
    int left, top, line;

    left = ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~0x7;
    top = (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2;

    for (line = 0; line < BITHEIGHT; line++) {
      vga16_drawscansegment(imageCard[card][line], left, top + line,
                        BITWIDTH);
    }
}


void
RemoveTrumps()
{
    int left, top, line;

    left = ((OH_SCREENWIDTH - BITWIDTH) / 2) & ~0x7;
    top = (OH_SCREENHEIGHT - 2 * BITHEIGHT - 10) / 2;

    for (line = 0; line < BITHEIGHT; line++) {
      vga16_drawscansegment(blankLine, left, top + line, BITWIDTH);
    }
}


short
GetPlayerBid(unsigned char max)
{
    char s[6];
    int i, c, left, x, y, len;
    
    vga16_text(10, 20, "Enter bid:", OH_TEXTFG, OH_TEXTBG);
    left = 100;
    for (i = 0; i <= max; i++) {
      sprintf(s, " %d ", i);
      vga16_text(left, 20, s, OH_BUTTONFG, OH_BUTTONBG);
      left += strlen(s) * 8 + 8;
    }
      
    for (c = NOCARD; c == NOCARD;) {
      c = GetMouseButton();
      if (c >= 0) {
          x = (c >> 9);
          y = (c & 0x1ff);
          if (y > 4 && y <= 20) {
            c = 0;
            x -= 100;
            while (x >= 0) {
                len = (c < 10 ? 3 : 4) * 8;
                if (x < len) {
                  break;
                }
                c++;
                x -= len + 8;
            }
            if (x < 0 || c > max) {
                c = NOCARD;
            }
          } else {
            c = NOCARD;
          }
      }
    }

    WhileMouseButton();

    for (i = 0; i < 16; i++) {
      vga16_drawscanline(20 - i, blankLine);
    }

    return c;
}


short
GetCmd()
{
    int c, i, x, y, len;

    for (c = NOCARD; c == NOCARD;) {
      c = GetMouseButton();
      if (c >= 0) {
          x = (c >> 9);
          y = (c & 0x1ff);
          if (y >= OH_SCREENHEIGHT - BITHEIGHT && y < OH_SCREENHEIGHT) {
            c = 0;
            x -= (((OH_SCREENWIDTH
                  - ((numInDeal - 1) * BITSHOWLEFT + BITWIDTH)) / 2)
                  & ~0x7);
            while (x >= 0 && c < numInDeal) {
                if (c == numInDeal - 1) {
                  len = BITWIDTH;
                } else {
                  len = BITSHOWLEFT;
                  i = c + 1;
                  while (i < numInDeal && hand[0][i] == NOCARD) {
                      if (i == numInDeal - 1) {
                        len += BITWIDTH;
                      } else {
                        len += BITSHOWLEFT;
                      }
                      i++;
                  }
                  len = MIN(len, CARDACTUALWIDTH);
                }
                if (x < len && hand[0][c] != NOCARD) {
                  break;
                }
                c++;
                x -= BITSHOWLEFT;
            }
            if (x < 0 || c >= numInDeal) {
                c = NOCARD;
            }
          } else {
            c = NOCARD;
          }
      }
    }

    WhileMouseButton();

    return c;
}


short
WaitForKey()
{
    long c;

    c = GetMouseButton();
    WhileMouseButton();
    if (c < 0) {
      return (short)c;
    } else {
      return CONTINUE;
    }
}


static int oldx = -1, oldy, oldcolour[40];

static long
GetMouseButton()
{
    int x, y, button, key;

    x = mouse_getx();
    y = mouse_gety();
    if (x != oldx || y != oldy) {
      if (oldx != -1) {
          RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
      }
      SaveUnderMousePointer(x, y, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
      RenderMousePointer(x, y, OH_MOUSEFG, OH_MOUSEDARKFG, OH_SCREENWIDTH, OH_SCREENHEIGHT);
      oldx = x;
      oldy = y;
    }
      
    for (;;) {
      usleep(USLEEP_TIME);    /* don't chew up as much CPU */

      if (mouse_update()) {
          x = mouse_getx();
          y = mouse_gety();
          button = mouse_getbutton();

          if (x != oldx || y != oldy) {
            if (oldx != -1) {
                RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
            }
            SaveUnderMousePointer(x, y, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
            RenderMousePointer(x, y, OH_MOUSEFG, OH_MOUSEDARKFG, OH_SCREENWIDTH, OH_SCREENHEIGHT);
            oldx = x;
            oldy = y;
          }
      
          if (button & MOUSE_LEFTBUTTON) {
            break;
          }
      }
      if ((key = key_getkey()) != -1) {
          switch (key) {
            case 'n':
            case 'N':
            return NEWGAME;
            case 'q':
            case 'Q':
            return QUIT;
            case '\014':
            vga16_redrawscreen();
            break;
            default:
            break;
          }
      }
    }

    if (x >= OH_QUITLEFT && x < OH_QUITRIGHT) {
      if (y > OH_NEWGAMETOP && y <= OH_NEWGAMEBOTTOM) {
          return NEWGAME;
      } else if (y > OH_QUITTOP && y <= OH_QUITBOTTOM) {
          return QUIT;
      }
    } 

    return (x << 9) | y;
}


static void
WhileMouseButton()
{
    int button = 1;
    
    while (button) {
      usleep(USLEEP_TIME);    /* don't chew up as much CPU */

      mouse_update();
      button = mouse_getbutton();
    }
    if (oldx != -1) {
      RestoreUnderMousePointer(oldx, oldy, OH_SCREENWIDTH, OH_SCREENHEIGHT, oldcolour);
    }
    oldx = -1;
}

Generated by  Doxygen 1.6.0   Back to index