root/games/dab/ttyscrn.cc
/*      $NetBSD: ttyscrn.cc,v 1.6 2021/12/05 09:22:45 rillig Exp $      */

/*-
 * Copyright (c) 2003 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Christos Zoulas.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Curses screen implementation for dots
 */

#include "defs.h"
RCSID("$NetBSD: ttyscrn.cc,v 1.6 2021/12/05 09:22:45 rillig Exp $")

#include <stdio.h>
#include <curses.h>
#include <sys/ioctl.h>

#include "player.h"
#include "ttyscrn.h"

void TTYSCRN::clean(void)
{
    clear();
}

void TTYSCRN::moveto(size_t y, size_t x)
{
    move(y + TTYSCRN::offsy, x + TTYSCRN::offsx);
}

void TTYSCRN::addsym(const int sym)
{
    addch(sym);
}

void TTYSCRN::addedge(const int sym)
{
    int nsym;
#ifdef A_ALTCHARSET
    if (_acs) {
        switch (sym) {
        case GS_HLINE:
            nsym = ACS_HLINE;
            break;
        case GS_VLINE:
            nsym = ACS_VLINE;
            break;
        case GS_ULCORNER:
            nsym = ACS_ULCORNER;
            break;
        case GS_URCORNER:
            nsym = ACS_URCORNER;
            break;
        case GS_LLCORNER:
            nsym = ACS_LLCORNER;
            break;
        case GS_LRCORNER:
            nsym = ACS_LRCORNER;
            break;
        case GS_LTEE:
            nsym = ACS_LTEE;
            break;
        case GS_RTEE:
            nsym = ACS_RTEE;
            break;
        case GS_TTEE:
            nsym = ACS_TTEE;
            break;
        case GS_BTEE:
            nsym = ACS_BTEE;
            break;
        case GS_PLUS:
            nsym = ACS_PLUS;
            break;
        case ' ':
            addsym(' ');
            return;
        default:
            ::abort();
        }
        attron(A_ALTCHARSET);
        addch(nsym);
        attroff(A_ALTCHARSET);
        return;
    }
#endif
    switch (sym) {
    case GS_HLINE:
        nsym = '-';
        break;
    case GS_VLINE:
        nsym = '|';
        break;
    case GS_ULCORNER:
        nsym = '.';
        break;
    case GS_URCORNER:
        nsym = '.';
        break;
    case GS_LLCORNER:
        nsym = '.';
        break;
    case GS_LRCORNER:
        nsym = '.';
        break;
    case GS_LTEE:
        nsym = '.';
        break;
    case GS_RTEE:
        nsym = '.';
        break;
    case GS_TTEE:
        nsym = '.';
        break;
    case GS_BTEE:
        nsym = '.';
        break;
    case GS_PLUS:
        nsym = '+';
        break;
    case ' ':
        addsym(' ');
        return;
    default:
        ::abort();
    }
    addsym(nsym);
}

void TTYSCRN::redraw(void)
{
    refresh();
    doupdate();
}

void TTYSCRN::bell(void)
{
    putc('\007', stdout);
}

int TTYSCRN::getinput(void)
{
    return getch();
}

void TTYSCRN::score(size_t s, const PLAYER& p)
{
    mvwprintw(stdscr, _sy + s + TTYSCRN::offsscore, _sx, "S %c:%5zd", p.getWho(),
              p.getScore());
}

void TTYSCRN::total(size_t s, const PLAYER& p)
{
    mvwprintw(stdscr, _sy + s + TTYSCRN::offstotal, _sx, "T %c:%5zd", p.getWho(),
              p.getTotal());
}

void TTYSCRN::games(size_t s, const PLAYER& p)
{
    mvwprintw(stdscr, _sy + s + TTYSCRN::offsgames, _sx, "G %c:%5zd", p.getWho(),
              p.getGames());
}

void TTYSCRN::ties(const PLAYER& p)
{
    mvwprintw(stdscr, _sy + TTYSCRN::offsties, _sx, "G =:%5zd", p.getTies());
}

TTYSCRN* TTYSCRN::create(int acs, size_t *y, size_t *x)
{
    int tx, ty;

    initscr();

    tx = getmaxx(stdscr);
    ty = getmaxy(stdscr);

    if (tx == ERR || ty == ERR
        || static_cast<size_t>(tx) < *x * 2 + TTYSCRN::offsx + 14
        || static_cast<size_t>(ty) < *y * 2 + TTYSCRN::offsy) {
        endwin();
        return NULL;
    }
    if (*x == 0)
        *x = (tx - 14 - TTYSCRN::offsx) / 2;
    if (*y == 0)
        *y = (ty - TTYSCRN::offsy) / 2;
    cbreak();
    noecho();


    TTYSCRN* that = new TTYSCRN;

    that->_tx = tx;
    that->_ty = ty;
    that->_sx = tx - 12;
    that->_sy = TTYSCRN::offsy;
    that->_acs = acs;

    return that;
}

TTYSCRN::~TTYSCRN(void)
{
    nocbreak();
    echo();
    endwin();
}