This is tui_backend.c in view mode; [Download] [Up]
/*
* tui_backend.c - MS-DOS backend for the text-based user interface.
*
* Written by
* Ettore Perazzoli (ettore@comm2000.it)
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include "vice.h"
#include <sys/farptr.h>
#include <go32.h>
#include <strings.h>
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
#include <pc.h>
#include <keys.h>
#include <stdarg.h>
#include <unistd.h>
#include <allegro.h>
#include "tui.h"
#include "utils.h"
typedef BYTE attr_t;
attr_t current_attr;
struct tui_area {
int width, height;
BYTE *mem;
};
struct text_info text_mode_info;
/* ------------------------------------------------------------------------- */
static attr_t make_attr(int foreground_color, int background_color, int blink)
{
return foreground_color | (background_color << 4) | (blink ? 0x80 : 0);
}
static unsigned long screen_addr(int x, int y)
{
return 0xb8000 + 2 * (x + y * text_mode_info.screenwidth);
}
/* ------------------------------------------------------------------------- */
void tui_init(void)
{
set_gfx_mode(GFX_TEXT, 80, 25, 0, 0);
/* FIXME: this should be made more flexible, to handle other screen modes
automatically. */
_set_screen_lines(25);
gettextinfo(&text_mode_info);
/* _setcursortype(_NOCURSOR); */
}
int tui_num_lines(void)
{
if (text_mode_info.screenheight == 0)
tui_init();
return text_mode_info.screenheight;
}
int tui_num_cols(void)
{
if (text_mode_info.screenwidth == 0)
tui_init();
return text_mode_info.screenwidth;
}
void tui_set_attr(int foreground_color, int background_color,
int blink)
{
current_attr = make_attr(foreground_color, background_color, blink);
}
void tui_put_char(int x, int y, BYTE c)
{
unsigned long addr = screen_addr(x, y);
BYTE attr_byte = (BYTE)current_attr;
_farsetsel(_dos_ds);
_farnspokeb(addr, c);
_farnspokeb(addr + 1, attr_byte);
}
void tui_hline(int x, int y, BYTE c, int count)
{
unsigned long addr = screen_addr(x, y);
BYTE attr_byte = (BYTE)current_attr;
int i;
_farsetsel(_dos_ds);
for (i = 0; i < count; i++) {
_farnspokeb(addr, c);
_farnspokeb(addr + 1, attr_byte);
addr += 2;
}
}
void tui_vline(int x, int y, BYTE c, int count)
{
unsigned long addr = screen_addr(x, y);
BYTE attr_byte = (BYTE)current_attr;
int i;
_farsetsel(_dos_ds);
for (i = 0; i < count; i++) {
_farnspokeb(addr, c);
_farnspokeb(addr + 1, attr_byte);
addr += tui_num_cols();
}
}
void tui_gotoxy(int x, int y)
{
gotoxy(x + 1, y + 1);
}
void tui_flush_keys(void)
{
while (kbhit())
getkey();
}
void tui_display(int x, int y, int len, const char *format, ...)
{
BYTE attr_byte = (BYTE)current_attr;
unsigned long addr = screen_addr(x, y);
static char buf[4096];
int i, buf_len;
va_list vl;
va_start(vl, format);
buf_len = vsprintf(buf, format, vl);
if (len == 0)
len = buf_len;
else if (buf_len > len)
buf_len = len;
_farsetsel(_dos_ds);
for (i = 0; i < buf_len; i++) {
_farnspokeb(addr, buf[i]);
_farnspokeb(addr + 1, attr_byte);
addr += 2;
}
for (; i < len; i++) {
_farnspokeb(addr, ' ');
_farnspokeb(addr + 1, attr_byte);
addr += 2;
}
}
void tui_beep(void)
{
sound(2000);
/* usleep(40000); */
nosound();
}
void tui_area_get(tui_area_t *a, int x, int y, int width, int height)
{
BYTE *p;
int i, j;
if (*a == NULL) {
*a = xmalloc(sizeof (struct tui_area));
(*a)->mem = xmalloc(2 * width * height);
} else {
(*a)->mem = xrealloc((*a)->mem, 2 * width * height);
}
(*a)->width = width;
(*a)->height = height;
_farsetsel(_dos_ds);
for (p = (*a)->mem, i = 0; i < height; i++) {
int addr = screen_addr(x, y + i);
for (j = 0; j < 2 * width; j++)
*(p++) = _farnspeekb(addr + j);
}
}
void tui_area_put(tui_area_t a, int x, int y)
{
BYTE *p = a->mem;
int i, j;
_farsetsel(_dos_ds);
for (i = 0; i < a->height; i++) {
int addr = screen_addr(x, y + i);
for (j = 0; j < 2 * a->width; j++)
_farnspokeb(addr + j, *(p++));
}
}
void tui_area_free(tui_area_t a)
{
if (a != NULL) {
free(a->mem);
free(a);
}
}
void tui_clear_screen(void)
{
int i;
_setcursortype(_NOCURSOR);
tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0);
#ifndef UNSTABLE
tui_display(0, 0, tui_num_cols(), "VICE version %s", VERSION);
#else
tui_display(0, 0, tui_num_cols(), "VICE version %s (unstable)", VERSION);
#endif
tui_set_attr(BACKPATTERN_FORE, BACKPATTERN_BACK, 0);
for (i = 1; i < tui_num_lines() - 1; i++)
tui_hline(0, i, BACKCHAR, tui_num_cols());
}
void tui_make_shadow(int x, int y, int width, int height)
{
int i, j;
_farsetsel(_dos_ds);
for (i = 0; i < height; i++) {
int addr = screen_addr(x, y + i) + 1;
for (j = 0; j < width; j++, addr += 2) {
_farnspokeb(addr, make_attr(DARKGRAY, BLACK, 0));
}
}
}
void tui_display_window(int x, int y, int width, int height,
int foreground_color, int background_color,
const char *title, tui_area_t *backing_store)
{
int i;
if (backing_store != NULL) {
/* 2 more chars on right, 1 more on bottom because of the "shadow". */
tui_area_get(backing_store, x, y, width + 2, height + 1);
}
tui_make_shadow(x + 2, y + 1, width, height);
tui_set_attr(foreground_color, background_color, 0);
tui_put_char(x, y, 0xc9);
tui_hline(x + 1, y, 0xcd, width - 2);
tui_put_char(x + width - 1, y, 0xbb);
tui_put_char(x, y + height - 1, 0xc8);
tui_hline(x + 1, y + height - 1, 0xcd, width - 2);
tui_put_char(x + width - 1, y + height - 1, 0xbc);
for (i = 0; i < height - 2; i++) {
tui_put_char(x, y + i + 1, 0xba);
tui_hline(x + 1, y + i + 1, ' ', width - 2);
tui_put_char(x + width - 1, y + i + 1, 0xba);
}
if (title != NULL && *title != '\0') {
int title_x, title_length;
title_length = strlen(title);
title_x = x + (width - title_length - 4) / 2;
tui_display(title_x, y, 0, "\x10 %s \x11", title);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.