mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
GLK: TADS2: Yet more volumous code additions
This commit is contained in:
@@ -92,9 +92,11 @@ MODULE_OBJS := \
|
||||
scott/detection.o \
|
||||
scott/scott.o \
|
||||
tads/detection.o \
|
||||
tads/os_banners.o \
|
||||
tads/os_buffer.o \
|
||||
tads/os_glk.o \
|
||||
tads/os_frob_tads.o \
|
||||
tads/os_parse.o \
|
||||
tads/tads.o \
|
||||
tads/tads2/built_in.o \
|
||||
tads/tads2/character_map.o \
|
||||
@@ -106,6 +108,7 @@ MODULE_OBJS := \
|
||||
tads/tads2/error_message.o \
|
||||
tads/tads2/execute_command.o \
|
||||
tads/tads2/file_io.o \
|
||||
tads/tads2/get_string.o \
|
||||
tads/tads2/line_source_file.o \
|
||||
tads/tads2/list.o \
|
||||
tads/tads2/ltk.o \
|
||||
|
||||
@@ -0,0 +1,812 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glk/tads/os_banners.h"
|
||||
#include "glk/tads/os_buffer.h"
|
||||
#include "glk/tads/tads.h"
|
||||
#include "glk/glk_api.h"
|
||||
#include "glk/window_text_buffer.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
|
||||
struct os_banner_t;
|
||||
struct banner_contents_t;
|
||||
typedef os_banner_t *osbanid_t;
|
||||
typedef banner_contents_t *contentid_t;
|
||||
|
||||
/* for tracking banner windows */
|
||||
struct os_banner_t {
|
||||
uint id; /* unique identifier */
|
||||
uint valid; /* banner status */
|
||||
|
||||
osbanid_t prev; /* previous sibling */
|
||||
osbanid_t next; /* next sibling */
|
||||
osbanid_t children; /* child's descendents */
|
||||
osbanid_t parent; /* child's parent */
|
||||
|
||||
uint method; /* glk window method */
|
||||
uint size; /* glk window size */
|
||||
uint type; /* glk window type */
|
||||
uint status; /* glk status style */
|
||||
|
||||
uint cheight; /* glk char height */
|
||||
uint cwidth; /* glk char width */
|
||||
|
||||
uint fgcolor; /* foreground color */
|
||||
uint bgcolor; /* background color */
|
||||
uint fgcustom; /* custom colors */
|
||||
uint bgcustom;
|
||||
uint bgtrans;
|
||||
|
||||
contentid_t contents; /* window contents */
|
||||
uint style; /* active Glk style value */
|
||||
uint newline; /* active newline */
|
||||
uint move, x, y; /* active cursor position */
|
||||
|
||||
winid_t win; /* glk window object */
|
||||
};
|
||||
|
||||
/* for reprinting banner contents */
|
||||
struct banner_contents_t {
|
||||
osbanid_t banner; /* content owner */
|
||||
contentid_t next; /* next set of contents */
|
||||
|
||||
uint style; /* stored contents style */
|
||||
uint newline; /* stored newline */
|
||||
uint move, x, y; /* stored cursor position */
|
||||
|
||||
char *chars;
|
||||
uint len;
|
||||
};
|
||||
|
||||
static osbanid_t os_banners = NULL;
|
||||
static uint os_banner_count = 999;
|
||||
|
||||
extern winid_t mainwin;
|
||||
extern winid_t statuswin;
|
||||
|
||||
extern uint mainfg;
|
||||
extern uint mainbg;
|
||||
|
||||
extern uint statusfg;
|
||||
extern uint statusbg;
|
||||
|
||||
void banner_contents_display(contentid_t contents);
|
||||
|
||||
/* Implementation-specific functions for managing banner windows */
|
||||
/*
|
||||
os_banner_init();
|
||||
os_banner_insert();
|
||||
os_banner_styles_apply();
|
||||
os_banner_styles_reset();
|
||||
os_banners_close();
|
||||
os_banners_open();
|
||||
os_banners_redraw();
|
||||
*/
|
||||
|
||||
osbanid_t os_banner_init() {
|
||||
osbanid_t instance;
|
||||
instance = (osbanid_t)malloc(sizeof(os_banner_t));
|
||||
if (!instance)
|
||||
return 0;
|
||||
|
||||
instance->id = ++ os_banner_count;
|
||||
instance->valid = 1;
|
||||
|
||||
instance->prev = 0;
|
||||
instance->next = 0;
|
||||
instance->children = 0;
|
||||
instance->parent = 0;
|
||||
|
||||
instance->method = 0;
|
||||
instance->size = 0;
|
||||
instance->type = 0;
|
||||
instance->status = 0;
|
||||
|
||||
instance->cheight = 0;
|
||||
instance->cwidth = 0;
|
||||
|
||||
instance->contents = 0;
|
||||
instance->style = style_Normal;
|
||||
instance->newline = 0;
|
||||
instance->move = 0;
|
||||
instance->x = 0;
|
||||
instance->y = 0;
|
||||
|
||||
instance->win = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
osbanid_t os_banner_insert(osbanid_t parent, uint operation, osbanid_t other,
|
||||
uint method, uint size, uint type, uint status)
|
||||
{
|
||||
if (!parent || !(parent->valid))
|
||||
return 0;
|
||||
|
||||
if (operation == OS_BANNER_BEFORE || operation == OS_BANNER_AFTER)
|
||||
if (!other || !(other->valid) || !(other->parent == parent))
|
||||
operation = OS_BANNER_LAST;
|
||||
|
||||
osbanid_t baby = os_banner_init();
|
||||
if (!baby)
|
||||
return 0;
|
||||
baby->parent = parent;
|
||||
|
||||
if (!(parent->children))
|
||||
{
|
||||
parent->children = baby;
|
||||
}
|
||||
else
|
||||
{
|
||||
osbanid_t child = parent->children;
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case OS_BANNER_FIRST:
|
||||
parent->children = baby;
|
||||
baby->next = child;
|
||||
child->prev = baby;
|
||||
break;
|
||||
|
||||
case OS_BANNER_BEFORE:
|
||||
while (child != other && child->next)
|
||||
child = child->next;
|
||||
|
||||
if (child->prev)
|
||||
{
|
||||
child->prev->next = baby;
|
||||
baby->prev = child->prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent->children = baby;
|
||||
}
|
||||
|
||||
baby->next = child;
|
||||
child->prev = baby;
|
||||
break;
|
||||
|
||||
case OS_BANNER_LAST:
|
||||
while(child->next)
|
||||
child = child->next;
|
||||
|
||||
baby->prev = child;
|
||||
child->next = baby;
|
||||
break;
|
||||
|
||||
case OS_BANNER_AFTER:
|
||||
while (child != other && child->next)
|
||||
child = child->next;
|
||||
|
||||
if (child->next)
|
||||
{
|
||||
child->next->prev = baby;
|
||||
baby->next = child->next;
|
||||
}
|
||||
|
||||
baby->prev = child;
|
||||
child->next = baby;
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
baby->method = method;
|
||||
baby->size = size;
|
||||
baby->type = type;
|
||||
baby->status = status;
|
||||
|
||||
return baby;
|
||||
}
|
||||
|
||||
void os_banner_styles_apply (osbanid_t banner)
|
||||
{
|
||||
if (!banner || !(banner->valid))
|
||||
return;
|
||||
|
||||
uint propval = banner->status ? 0 : (banner->type == wintype_TextGrid ? 0 : 1);
|
||||
uint bgcustom = banner->bgtrans ? banner->bgcolor : banner->bgcustom;
|
||||
|
||||
/* font style: monospace for text grid and tab aligned buffers, else proportional */
|
||||
g_vm->glk_stylehint_set(banner->type, style_Alert, stylehint_Proportional, propval);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Subheader, stylehint_Proportional, propval);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Emphasized, stylehint_Proportional, propval);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Normal, stylehint_Proportional, propval);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User1, stylehint_Proportional, propval);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User2, stylehint_Proportional, propval);
|
||||
|
||||
/* foreground color: user1 reverse, user2 custom */
|
||||
g_vm->glk_stylehint_set(banner->type, style_Alert, stylehint_TextColor, banner->fgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Subheader, stylehint_TextColor, banner->fgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Emphasized, stylehint_TextColor, banner->fgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Normal, stylehint_TextColor, banner->fgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User1, stylehint_TextColor, banner->bgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User2, stylehint_TextColor, banner->fgcustom);
|
||||
|
||||
/* background color: user1 reverse, user2 custom */
|
||||
g_vm->glk_stylehint_set(banner->type, style_Alert, stylehint_BackColor, banner->bgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Subheader, stylehint_BackColor, banner->bgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Emphasized, stylehint_BackColor, banner->bgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_Normal, stylehint_BackColor, banner->bgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User1, stylehint_BackColor, banner->fgcolor);
|
||||
g_vm->glk_stylehint_set(banner->type, style_User2, stylehint_BackColor, bgcustom);
|
||||
|
||||
}
|
||||
|
||||
void os_banner_styles_reset (void)
|
||||
{
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Alert, stylehint_Proportional);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Subheader, stylehint_Proportional);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Emphasized, stylehint_Proportional);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Normal, stylehint_Proportional);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User1, stylehint_Proportional);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User2, stylehint_Proportional);
|
||||
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Alert, stylehint_TextColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Subheader, stylehint_TextColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Emphasized, stylehint_TextColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Normal, stylehint_TextColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User1, stylehint_TextColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User2, stylehint_TextColor);
|
||||
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Alert, stylehint_BackColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Subheader, stylehint_BackColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Emphasized, stylehint_BackColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_Normal, stylehint_BackColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User1, stylehint_BackColor);
|
||||
g_vm->glk_stylehint_clear(wintype_AllTypes, style_User2, stylehint_BackColor);
|
||||
|
||||
#ifdef GARGLK
|
||||
/* reset our default colors with a superfluous hint */
|
||||
g_vm->glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_TextColor, mainfg);
|
||||
g_vm->glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_BackColor, mainbg);
|
||||
#endif /* GARGLK */
|
||||
}
|
||||
|
||||
void os_banners_close(osbanid_t banner)
|
||||
{
|
||||
if (!banner)
|
||||
return;
|
||||
|
||||
os_banners_close(banner->children);
|
||||
os_banners_close(banner->next);
|
||||
|
||||
if (banner->win && (banner->win != mainwin))
|
||||
{
|
||||
g_vm->glk_window_close(banner->win, 0);
|
||||
banner->win = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void os_banners_open(osbanid_t banner)
|
||||
{
|
||||
if (!banner)
|
||||
return;
|
||||
|
||||
if (banner->valid)
|
||||
{
|
||||
if (banner->size && banner->parent && banner->parent->win)
|
||||
{
|
||||
os_banner_styles_apply(banner);
|
||||
banner->win = g_vm->glk_window_open(banner->parent->win, banner->method,
|
||||
banner->size, banner->type, banner->id);
|
||||
banner_contents_display(banner->contents);
|
||||
}
|
||||
os_banners_open(banner->children);
|
||||
}
|
||||
|
||||
os_banners_open(banner->next);
|
||||
}
|
||||
|
||||
void os_banners_redraw()
|
||||
{
|
||||
if (!os_banners)
|
||||
return;
|
||||
|
||||
os_banners_close(os_banners);
|
||||
os_banners_open(os_banners);
|
||||
os_banner_styles_reset();
|
||||
}
|
||||
|
||||
/* Implementation-specific functions for managing banner contents */
|
||||
/*
|
||||
banner_contents_init();
|
||||
banner_contents_insert();
|
||||
banner_contents_display();
|
||||
banner_contents_clear();
|
||||
*/
|
||||
|
||||
contentid_t banner_contents_init(void)
|
||||
{
|
||||
contentid_t instance;
|
||||
instance = (contentid_t)malloc(sizeof(banner_contents_t));
|
||||
if (!instance)
|
||||
return 0;
|
||||
|
||||
instance->banner = 0;
|
||||
instance->next = 0;
|
||||
|
||||
instance->style = style_Normal;
|
||||
instance->newline = 0;
|
||||
instance->move = 0;
|
||||
instance->x = 0;
|
||||
instance->y = 0;
|
||||
|
||||
instance->chars = 0;
|
||||
instance->len = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void banner_contents_insert(contentid_t contents, const char *txt, size_t len)
|
||||
{
|
||||
if (!contents)
|
||||
return;
|
||||
|
||||
contents->chars = (char *)malloc(sizeof(char) * (len + 1));
|
||||
if (!(contents->chars))
|
||||
return;
|
||||
|
||||
memcpy(contents->chars, txt, len);
|
||||
|
||||
contents->chars[len] = '\0';
|
||||
contents->len = len;
|
||||
}
|
||||
|
||||
void banner_contents_display(contentid_t contents)
|
||||
{
|
||||
if (!contents || !(contents->banner))
|
||||
return;
|
||||
|
||||
winid_t win = contents->banner->win;
|
||||
uint len = contents->len;
|
||||
|
||||
g_vm->glk_set_window(win);
|
||||
|
||||
if (contents->newline)
|
||||
{
|
||||
char ch = '\n';
|
||||
os_put_buffer(&ch, 1);
|
||||
}
|
||||
|
||||
if (len && (contents->chars[len-1] == '\n'))
|
||||
{
|
||||
len --;
|
||||
contents->banner->newline = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
contents->banner->newline = 0;
|
||||
}
|
||||
|
||||
if (contents->move)
|
||||
{
|
||||
g_vm->glk_window_move_cursor(win, contents->x, contents->y);
|
||||
contents->banner->move = 0;
|
||||
contents->banner->x = 0;
|
||||
contents->banner->y = 0;
|
||||
}
|
||||
|
||||
g_vm->glk_set_style(contents->style);
|
||||
os_put_buffer(contents->chars, len);
|
||||
g_vm->glk_set_window(mainwin);
|
||||
banner_contents_display(contents->next);
|
||||
}
|
||||
|
||||
void banner_contents_clear(contentid_t contents)
|
||||
{
|
||||
if (!contents)
|
||||
return;
|
||||
|
||||
banner_contents_clear(contents->next);
|
||||
|
||||
if (contents->chars)
|
||||
free(contents->chars);
|
||||
|
||||
free(contents);
|
||||
}
|
||||
|
||||
/* Banner API functions */
|
||||
|
||||
void *os_banner_create(void *parent, int where, void *other, int wintype,
|
||||
int align, int siz, int siz_units,
|
||||
unsigned long style)
|
||||
{
|
||||
osbanid_t gparent = (osbanid_t)parent;
|
||||
osbanid_t gbanner;
|
||||
uint gwinmeth = 0;
|
||||
uint gwinsize = siz;
|
||||
uint gwintype = 0;
|
||||
uint gstatus = (style & OS_BANNER_STYLE_TAB_ALIGN);
|
||||
|
||||
if (gparent && !(gparent->valid))
|
||||
return 0;
|
||||
|
||||
if (!os_banners)
|
||||
{
|
||||
os_banners = os_banner_init();
|
||||
if (!os_banners)
|
||||
return 0;
|
||||
os_banners->win = mainwin;
|
||||
}
|
||||
|
||||
if (!gparent)
|
||||
gparent = os_banners;
|
||||
|
||||
switch (wintype)
|
||||
{
|
||||
case OS_BANNER_TYPE_TEXT: gwintype = wintype_TextBuffer; break;
|
||||
case OS_BANNER_TYPE_TEXTGRID: gwintype = wintype_TextGrid; break;
|
||||
default: gwintype = wintype_TextGrid; break;
|
||||
}
|
||||
|
||||
switch (align)
|
||||
{
|
||||
case OS_BANNER_ALIGN_TOP: gwinmeth = winmethod_Above; break;
|
||||
case OS_BANNER_ALIGN_BOTTOM: gwinmeth = winmethod_Below; break;
|
||||
case OS_BANNER_ALIGN_LEFT: gwinmeth = winmethod_Left; break;
|
||||
case OS_BANNER_ALIGN_RIGHT: gwinmeth = winmethod_Right; break;
|
||||
default: gwinmeth = winmethod_Above; break;
|
||||
}
|
||||
|
||||
switch (siz_units)
|
||||
{
|
||||
case OS_BANNER_SIZE_PCT: gwinmeth |= winmethod_Proportional; break;
|
||||
case OS_BANNER_SIZE_ABS: gwinmeth |= winmethod_Fixed; break;
|
||||
default: gwinmeth |= winmethod_Fixed; break;
|
||||
}
|
||||
|
||||
gbanner = os_banner_insert(gparent, where, (osbanid_t)other, gwinmeth, gwinsize, gwintype, gstatus);
|
||||
|
||||
if (gbanner)
|
||||
{
|
||||
gbanner->fgcolor = gstatus ? statusbg : mainfg;
|
||||
gbanner->bgcolor = gstatus ? statusfg : mainbg;
|
||||
gbanner->fgcustom = gbanner->fgcolor;
|
||||
gbanner->bgcustom = gbanner->bgcolor;
|
||||
gbanner->bgtrans = 1;
|
||||
}
|
||||
|
||||
os_banners_redraw();
|
||||
|
||||
return gbanner;
|
||||
}
|
||||
|
||||
void os_banner_set_size(void *banner_handle, int siz, int siz_units, int is_advisory)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
|
||||
if (!banner || !banner->valid)
|
||||
return;
|
||||
|
||||
uint gwinsize = siz;
|
||||
uint gwinmeth = 0;
|
||||
|
||||
gwinmeth = banner->method &
|
||||
(winmethod_Above | winmethod_Below |
|
||||
winmethod_Left | winmethod_Right);
|
||||
|
||||
switch (siz_units)
|
||||
{
|
||||
case OS_BANNER_SIZE_PCT: gwinmeth |= winmethod_Proportional; break;
|
||||
case OS_BANNER_SIZE_ABS: gwinmeth |= winmethod_Fixed; break;
|
||||
default: gwinmeth |= winmethod_Fixed; break;
|
||||
}
|
||||
|
||||
banner->method = gwinmeth;
|
||||
banner->size = gwinsize;
|
||||
|
||||
os_banners_redraw();
|
||||
}
|
||||
|
||||
void os_banner_size_to_contents(void *banner_handle)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return;
|
||||
|
||||
#ifdef GARGLK
|
||||
if (banner->type == wintype_TextBuffer)
|
||||
{
|
||||
TextBufferWindow *win = dynamic_cast<TextBufferWindow *>(banner->win);
|
||||
assert(win);
|
||||
int size = win->_scrollMax;
|
||||
if (win->_numChars)
|
||||
size++;
|
||||
os_banner_set_size(banner, size, OS_BANNER_SIZE_ABS, 0);
|
||||
}
|
||||
#endif /* GARGLK */
|
||||
}
|
||||
|
||||
void os_banner_delete(void *banner_handle)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !(banner->valid))
|
||||
return;
|
||||
|
||||
banner->valid = 0;
|
||||
os_banners_redraw();
|
||||
|
||||
if (banner->parent && banner->parent->children == banner)
|
||||
banner->parent->children = banner->next;
|
||||
|
||||
if (banner->next)
|
||||
banner->next->prev = banner->prev;
|
||||
|
||||
if (banner->prev)
|
||||
banner->prev->next = banner->next;
|
||||
|
||||
banner_contents_clear(banner->contents);
|
||||
|
||||
free(banner);
|
||||
}
|
||||
|
||||
void os_banner_orphan(void *banner_handle)
|
||||
{
|
||||
os_banner_delete(banner_handle);
|
||||
}
|
||||
|
||||
int os_banner_getinfo(void *banner_handle, os_banner_info_t *info)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return 1;
|
||||
|
||||
//winid_t win = banner->win;
|
||||
uint gwintype = banner->type;
|
||||
uint gwinmeth = banner->method;
|
||||
uint gstyletab = banner->status;
|
||||
|
||||
if (gwinmeth & winmethod_Above)
|
||||
info->align = OS_BANNER_ALIGN_TOP;
|
||||
if (gwinmeth & winmethod_Below)
|
||||
info->align = OS_BANNER_ALIGN_BOTTOM;
|
||||
if (gwinmeth & winmethod_Left)
|
||||
info->align = OS_BANNER_ALIGN_LEFT;
|
||||
if (gwinmeth & winmethod_Right)
|
||||
info->align = OS_BANNER_ALIGN_RIGHT;
|
||||
|
||||
info->style = gstyletab ? OS_BANNER_STYLE_TAB_ALIGN : 0;
|
||||
|
||||
g_vm->glk_window_get_size(banner->win, &(banner->cwidth), &(banner->cheight));
|
||||
|
||||
info->rows = banner->cheight;
|
||||
info->columns = banner->cwidth;
|
||||
|
||||
info->pix_width = 0;
|
||||
info->pix_height = 0;
|
||||
|
||||
info->os_line_wrap = gstyletab ? 0 : (gwintype == wintype_TextBuffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int os_banner_get_charwidth(void *banner_handle)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return 0;
|
||||
|
||||
g_vm->glk_window_get_size(banner->win, &(banner->cwidth), &(banner->cheight));
|
||||
|
||||
return banner->cwidth;
|
||||
}
|
||||
|
||||
int os_banner_get_charheight(void *banner_handle)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return 0;
|
||||
|
||||
g_vm->glk_window_get_size(banner->win, &(banner->cwidth), &(banner->cheight));
|
||||
|
||||
return banner->cheight;
|
||||
}
|
||||
|
||||
void os_banner_clear(void *banner_handle)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid)
|
||||
return;
|
||||
|
||||
if (banner->win)
|
||||
{
|
||||
winid_t win = banner->win;
|
||||
g_vm->glk_window_clear(win);
|
||||
}
|
||||
|
||||
banner_contents_clear(banner->contents);
|
||||
banner->contents = 0;
|
||||
banner->newline = 0;
|
||||
banner->move = 0;
|
||||
banner->x = 0;
|
||||
banner->y = 0;
|
||||
}
|
||||
|
||||
void os_banner_disp(void *banner_handle, const char *txt, size_t len)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return;
|
||||
|
||||
contentid_t update = banner_contents_init();
|
||||
if (!update)
|
||||
return;
|
||||
update->banner = banner;
|
||||
|
||||
if (!(banner->contents))
|
||||
{
|
||||
banner->contents = update;
|
||||
}
|
||||
else
|
||||
{
|
||||
contentid_t contents = banner->contents;
|
||||
while (contents->next)
|
||||
contents = contents->next;
|
||||
contents->next = update;
|
||||
}
|
||||
|
||||
update->style = banner->style;
|
||||
update->newline = banner->newline;
|
||||
update->move = banner->move;
|
||||
update->x = banner->x;
|
||||
update->y = banner->y;
|
||||
|
||||
banner_contents_insert(update, txt, len);
|
||||
banner_contents_display(update);
|
||||
}
|
||||
|
||||
void os_banner_goto(void *banner_handle, int row, int col)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid || !banner->win)
|
||||
return;
|
||||
|
||||
if (banner->type == wintype_TextGrid)
|
||||
{
|
||||
banner->move = 1;
|
||||
banner->x = col;
|
||||
banner->y = row;
|
||||
}
|
||||
}
|
||||
|
||||
void os_banner_set_attr(void *banner_handle, int attr)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid)
|
||||
return;
|
||||
|
||||
if (attr & OS_ATTR_BOLD && attr & OS_ATTR_ITALIC)
|
||||
banner->style = style_Alert;
|
||||
else if (attr & OS_ATTR_BOLD)
|
||||
banner->style = style_Subheader;
|
||||
else if (attr & OS_ATTR_ITALIC)
|
||||
banner->style = style_Emphasized;
|
||||
else
|
||||
banner->style = style_Normal;
|
||||
}
|
||||
|
||||
void os_banner_set_color(void *banner_handle, os_color_t fg, os_color_t bg)
|
||||
{
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid)
|
||||
return;
|
||||
|
||||
uint reversed = 0;
|
||||
uint normal = 0;
|
||||
uint transparent = 0;
|
||||
|
||||
/* evaluate parameters */
|
||||
|
||||
if (os_color_is_param(fg))
|
||||
{
|
||||
switch(fg)
|
||||
{
|
||||
case OS_COLOR_P_TEXTBG:
|
||||
case OS_COLOR_P_STATUSBG:
|
||||
reversed = 1;
|
||||
break;
|
||||
|
||||
case OS_COLOR_P_TEXT:
|
||||
case OS_COLOR_P_STATUSLINE:
|
||||
case OS_COLOR_P_INPUT:
|
||||
normal = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (os_color_is_param(bg))
|
||||
{
|
||||
switch (bg)
|
||||
{
|
||||
case OS_COLOR_P_TRANSPARENT:
|
||||
transparent = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* choose a style */
|
||||
|
||||
if (normal && transparent)
|
||||
banner->style = style_Normal;
|
||||
else if (reversed)
|
||||
banner->style = style_User1;
|
||||
else
|
||||
banner->style = style_User2;
|
||||
|
||||
/* process our custom color */
|
||||
|
||||
if (banner->style == style_User2)
|
||||
{
|
||||
/* store current settings */
|
||||
uint oldfg = banner->fgcustom;
|
||||
uint oldbg = banner->bgcustom;
|
||||
uint oldtr = banner->bgtrans;
|
||||
|
||||
/* reset custom color parameters */
|
||||
banner->fgcustom = banner->fgcolor;
|
||||
banner->bgcustom = banner->bgcolor;
|
||||
banner->bgtrans = 1;
|
||||
|
||||
if (!normal)
|
||||
banner->fgcustom = fg;
|
||||
|
||||
if (!transparent)
|
||||
{
|
||||
banner->bgcustom = bg;
|
||||
banner->bgtrans = 0;
|
||||
}
|
||||
|
||||
if (!(banner->fgcustom == oldfg
|
||||
&& banner->bgcustom == oldbg
|
||||
&& banner->bgtrans == oldtr))
|
||||
os_banners_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void os_banner_set_screen_color(void *banner_handle, os_color_t color) {
|
||||
osbanid_t banner = (osbanid_t)banner_handle;
|
||||
if (!banner || !banner->valid)
|
||||
return;
|
||||
|
||||
if (!(os_color_is_param(color)))
|
||||
banner->bgcolor = color;
|
||||
|
||||
os_banners_redraw();
|
||||
}
|
||||
|
||||
void os_banner_flush(void *banner_handle) {}
|
||||
void os_banner_start_html(void *banner_handle) {}
|
||||
void os_banner_end_html(void *banner_handle) {}
|
||||
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
@@ -0,0 +1,631 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* TADS OS interface file type definitions
|
||||
*
|
||||
* Defines certain datatypes used in the TADS operating system interface
|
||||
*/
|
||||
|
||||
#ifndef GLK_TADS_OS_BANNERS
|
||||
#define GLK_TADS_OS_BANNERS
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "glk/tads/os_glk.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/*
|
||||
* External Banner Interface. This interface provides the ability to
|
||||
* divide the display window into multiple sub-windows, each with its own
|
||||
* independent contents.
|
||||
*
|
||||
* To determine where a new banner is displayed, we look at the banners as
|
||||
* a tree, rooted at the "main window," the special banner that the system
|
||||
* automatically creates initially for the main game text. We start by
|
||||
* allocating the entire display (or the entire application window, if
|
||||
* we're running on a GUI system) to the main window. We then traverse
|
||||
* the tree, starting with the root window's children. For each child
|
||||
* window, we allocate space for the child out of the parent window's
|
||||
* area, according to the child's alignment and size settings, and deduct
|
||||
* this space from the parent window's size. We then lay out the children
|
||||
* of the child.
|
||||
*
|
||||
* For each banner window, we take its requested space out of the parent
|
||||
* window's area by starting at the edge of the parent window rectangle as
|
||||
* indicated by the banner's alignment, and taking the requested `width
|
||||
* (for a left/right banner) or height (for a top/bottom banner), limiting
|
||||
* to the available width/height in the parent window's space. Give the
|
||||
* banner the full extent of the parent's space in its other dimension (so
|
||||
* a left/right banner gets the full height of the parent space, and a
|
||||
* top/bottom banner gets the full width).
|
||||
*
|
||||
* Note that the layout proceeds exclusively down the tree (i.e., from the
|
||||
* root to children to grandchildren, and so on). It *appears* that a
|
||||
* child affects its parent, because of the deduction step: a child
|
||||
* acquires screen space by carving out a chunk of its parent. The right
|
||||
* way to think about this, though, is that the parent's full area is the
|
||||
* union of the parent window and all of its children; when viewed this
|
||||
* way, the parent's full area is fully determined the instant the parent
|
||||
* is laid out, and never changes as its children are laid out. Note in
|
||||
* particular that a child can never make a parent larger; the only thing
|
||||
* a child can do to a parent is carve out a chunk of the parent for
|
||||
* itself, which doesn't affect the boundaries of the union of the parent
|
||||
* plus its children.
|
||||
*
|
||||
* Note also that if the banner has a border, and the implementation
|
||||
* actually draws borders, the border must be drawn for the *full* area of
|
||||
* the banner, as defined above. For example, suppose we have two
|
||||
* borders: banner A is a child of the main window, is top-aligned, and
|
||||
* has a border. Banner B is a child of banner A, right-aligned, with no
|
||||
* border. Obviously, without considering banner B, banner A's space runs
|
||||
* across the entire width of the main window, so its border (at the
|
||||
* bottom of its area) runs across the entire width of the main window.
|
||||
* Banner B carves out some space from A's right side for itself, so
|
||||
* banner A's actual on-screen area runs from the left edge of the main
|
||||
* window to banner B's left edge. However, even though banner A itself
|
||||
* no longer runs the full width of the main window, banner A's *full*
|
||||
* area - that is, the union of banner A's on-screen area and all of its
|
||||
* children's full areas - does still run the entire width of the main
|
||||
* window, hence banner A's border must still run the full width of the
|
||||
* main window. The simple way of looking at this is that a banner's
|
||||
* border is always to be drawn exactly the same way, regardless of
|
||||
* whether or not the banner has children - simply draw the banner as it
|
||||
* would be drawn if the banner had no children.
|
||||
*
|
||||
* Each time a banner is added or removed, we must recalculate the layout
|
||||
* of the remaining banners and main text area. The os_banner_xxx()
|
||||
* implementation is responsible for this layout refiguring.
|
||||
*
|
||||
* The entire external banner window interface is optional, although the
|
||||
* functions must at least be defined as dummies to avoid linker errors
|
||||
* when building. If a platform doesn't implement this feature,
|
||||
* os_banner_create() should simply return null, and the other routines
|
||||
* can do nothing.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a banner window. 'info' gives the desired parameters for the new
|
||||
* banner.
|
||||
*
|
||||
* Note that certain requested parameter settings might or might not be
|
||||
* respected, depending on the capabilities of the platform and user
|
||||
* preferences. os_banner_getinfo() can be used after creation to
|
||||
* determine which parameter settings are actually used in the new banner.
|
||||
*
|
||||
* 'parent' gives the parent of this banner; this is the banner handle of
|
||||
* another banner window, or null. If 'parent' is null, then the new
|
||||
* banner is a child of the main window, which the system creates
|
||||
* automatically at startup and which contains the main input/output
|
||||
* transcript. The new banner's on-screen area is carved out of the
|
||||
* parent's space, according to the alignment and size settings of the new
|
||||
* window, so this determines how the window is laid out on the screen.
|
||||
*
|
||||
* 'where' is OS_BANNER_FIRST to make the new window the first child of its
|
||||
* parent; OS_BANNER_LAST to make it the last child of its parent;
|
||||
* OS_BANNER_BEFORE to insert it immediately before the existing banner
|
||||
* identified by handle in 'other'; or OS_BANNER_AFTER to insert
|
||||
* immediately after 'other'. When BEFORE or AFTER is used, 'other' must
|
||||
* be another child of the same parent; if it is not, the routine should
|
||||
* act as though 'where' were given as OS_BANNER_LAST.
|
||||
*
|
||||
* 'other' is a banner handle for an existing banner window. This is used
|
||||
* to specify the relative position among children of the new banner's
|
||||
* parent, if 'where' is either OS_BANNER_BEFORE or OS_BANNER_AFTER. If
|
||||
* 'where' is OS_BANNER_FIRST or OS_BANNER_LAST, 'other' is ignored.
|
||||
*
|
||||
* 'wintype' is the type of the window. This is one of the
|
||||
* OS_BANNER_TYPE_xxx codes indicating what kind of window is desired.
|
||||
*
|
||||
* 'align' is the banner's alignment, given as an OS_BANNER_ALIGN_xxx
|
||||
* value. Top/bottom banners are horizontal: they run across the full
|
||||
* width of the existing main text area. Left/right banners are vertical:
|
||||
* they run down the full height of the existing main text area.
|
||||
*
|
||||
* 'siz' is the requested size of the new banner. The meaning of 'siz'
|
||||
* depends on the value of 'siz_units', which can be OS_BANNER_SIZE_PCT to
|
||||
* set the size as a percentage of the REMAINING space, or
|
||||
* OS_BANNER_SIZE_ABS to set an absolute size in the "natural" units of the
|
||||
* window. The natural units vary by window type: for text and text grid
|
||||
* windows, this is in rows/columns of '0' characters in the default font
|
||||
* for the window. Note that when OS_BANNER_SIZE_ABS is used in a text or
|
||||
* text grid window, the OS implementation MUST add the space needed for
|
||||
* margins and borders when determining the actual pixel size of the
|
||||
* window; in other words, the window should be large enough that it can
|
||||
* actually display the given number or rows or columns.
|
||||
*
|
||||
* The size is interpreted as a width or height according to the window's
|
||||
* orientation. For a TOP or BOTTOM banner, the size is the height; for a
|
||||
* LEFT or RIGHT banner, the size is the width. A banner has only one
|
||||
* dimension's size given, since the other dimension's size is determined
|
||||
* automatically by the layout rules.
|
||||
*
|
||||
* Note that the window's size can be changed later using
|
||||
* banner_size_to_contents() or banner_set_size().
|
||||
*
|
||||
* 'style' is a combination of OS_BANNER_STYLE_xxx flags - see below. The
|
||||
* style flags give the REQUESTED style for the banner, which might or
|
||||
* might not be respected, depending on the platform's capabilities, user
|
||||
* preferences, and other factors. os_banner_getinfo() can be used to
|
||||
* determine which style flags are actually used.
|
||||
*
|
||||
* Returns the "handle" to the new banner window, which is an opaque value
|
||||
* that is used in subsequent os_banner_xxx calls to operate on the window.
|
||||
* Returns null if the window cannot be created. An implementation is not
|
||||
* required to support this functionality at all, and can subset it if it
|
||||
* does support it (for example, an implementation could support only
|
||||
* top/bottom-aligned banners, but not left/right-aligned), so callers must
|
||||
* be prepared for this routine to return null.
|
||||
*/
|
||||
void *os_banner_create(void *parent, int where, void *other, int wintype,
|
||||
int align, int siz, int siz_units,
|
||||
unsigned long style);
|
||||
|
||||
|
||||
/*
|
||||
* insertion positions
|
||||
*/
|
||||
#define OS_BANNER_FIRST 1
|
||||
#define OS_BANNER_LAST 2
|
||||
#define OS_BANNER_BEFORE 3
|
||||
#define OS_BANNER_AFTER 4
|
||||
|
||||
/*
|
||||
* banner types
|
||||
*/
|
||||
|
||||
/*
|
||||
* Normal text stream window. This is a text stream that behaves
|
||||
* essentially like the main text window: text is displayed to this
|
||||
* through os_banner_disp(), always in a stream-like fashion by adding new
|
||||
* text to the end of any exiting text.
|
||||
*
|
||||
* Systems that use proportional fonts should usually simply use the same
|
||||
* font they use by default in the main text window. However, note that
|
||||
* the OS_BANNER_STYLE_TAB_ALIGN style flag might imply that a fixed-pitch
|
||||
* font should be used even when proportional fonts are available, because
|
||||
* a fixed-pitch font will allow the calling code to rely on using spaces
|
||||
* to align text within the window.
|
||||
*/
|
||||
#define OS_BANNER_TYPE_TEXT 1
|
||||
|
||||
/*
|
||||
* "Text grid" window. This type of window is similar to an normal text
|
||||
* window (OS_BANNER_TYPE_TEXT), but is guaranteed to arrange its text in
|
||||
* a regular grid of character cells, all of the same size. This means
|
||||
* that the output position can be moved to an arbitrary point within the
|
||||
* window at any time, so the calling program can precisely control the
|
||||
* layout of the text in the window.
|
||||
*
|
||||
* Because the output position can be moved to arbitrary positions in the
|
||||
* window, it is possible to overwrite text previously displayed. When
|
||||
* this happens, the old text is completely obliterated by the new text,
|
||||
* leaving no trace of the overwritten text.
|
||||
*
|
||||
* In order to guarantee that character cells are all the same size, this
|
||||
* type of window does not allow any text attributes. The implementation
|
||||
* should simply ignore any attempts to change text attributes in this
|
||||
* type of window. However, colors can be used to the same degree they
|
||||
* can be used in an ordinary text window.
|
||||
*
|
||||
* To guarantee the regular spacing of character cells, all
|
||||
* implementations must use fixed-pitch fonts for these windows. This
|
||||
* applies even to platforms where proportional fonts are available.
|
||||
*/
|
||||
#define OS_BANNER_TYPE_TEXTGRID 2
|
||||
|
||||
|
||||
/*
|
||||
* banner alignment types
|
||||
*/
|
||||
#define OS_BANNER_ALIGN_TOP 0
|
||||
#define OS_BANNER_ALIGN_BOTTOM 1
|
||||
#define OS_BANNER_ALIGN_LEFT 2
|
||||
#define OS_BANNER_ALIGN_RIGHT 3
|
||||
|
||||
/*
|
||||
* size units
|
||||
*/
|
||||
#define OS_BANNER_SIZE_PCT 1
|
||||
#define OS_BANNER_SIZE_ABS 2
|
||||
|
||||
|
||||
/*
|
||||
* banner style flags
|
||||
*/
|
||||
|
||||
/*
|
||||
* The banner has a visible border; this indicates that a line is to be
|
||||
* drawn to separate the banner from the adjacent window or windows
|
||||
* "inside" the banner. So, a top-aligned banner will have its border
|
||||
* drawn along its bottom edge; a left-aligned banner will show a border
|
||||
* along its right edge; and so forth.
|
||||
*
|
||||
* Note that character-mode platforms generally do NOT respect the border
|
||||
* style, since doing so takes up too much screen space.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_BORDER 0x00000001
|
||||
|
||||
/*
|
||||
* The banner has a vertical/horizontal scrollbar. Character-mode
|
||||
* platforms generally do not support scrollbars.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_VSCROLL 0x00000002
|
||||
#define OS_BANNER_STYLE_HSCROLL 0x00000004
|
||||
|
||||
/*
|
||||
* Automatically scroll the banner vertically/horizontally whenever new
|
||||
* text is displayed in the window. In other words, whenever
|
||||
* os_banner_disp() is called, scroll the window so that the text that the
|
||||
* new cursor position after the new text is displayed is visible in the
|
||||
* window.
|
||||
*
|
||||
* Note that this style is independent of the presence of scrollbars.
|
||||
* Even if there are no scrollbars, we can still scroll the window's
|
||||
* contents programmatically.
|
||||
*
|
||||
* Implementations can, if desired, keep an internal buffer of the
|
||||
* window's contents, so that the contents can be recalled via the
|
||||
* scrollbars if the text displayed in the banner exceeds the space
|
||||
* available in the banner's window on the screen. If the implementation
|
||||
* does keep such a buffer, we recommend the following method for managing
|
||||
* this buffer. If the AUTO_VSCROLL flag is not set, then the banner's
|
||||
* contents should be truncated at the bottom when the contents overflow
|
||||
* the buffer; that is, once the banner's internal buffer is full, any new
|
||||
* text that the calling program attempts to add to the banner should
|
||||
* simply be discarded. If the AUTO_VSCROLL flag is set, then the OLDEST
|
||||
* text should be discarded instead, so that the most recent text is
|
||||
* always retained.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_AUTO_VSCROLL 0x00000008
|
||||
#define OS_BANNER_STYLE_AUTO_HSCROLL 0x00000010
|
||||
|
||||
/*
|
||||
* Tab-based alignment is required/supported. On creation, this is a hint
|
||||
* to the implementation that is sometimes necessary to determine what
|
||||
* kind of font to use in the new window, for non-HTML platforms. If this
|
||||
* flag is set on creation, the caller is indicating that it wants to use
|
||||
* <TAB> tags to align text in the window.
|
||||
*
|
||||
* Character-mode implementations that use a single font with fixed pitch
|
||||
* can simply ignore this. These implementations ALWAYS have a working
|
||||
* <TAB> capability, because the portable output formatter provides <TAB>
|
||||
* interpretation for a fixed-pitch window.
|
||||
*
|
||||
* Full HTML TADS implementations can also ignore this. HTML TADS
|
||||
* implementations always have full <TAB> support via the HTML
|
||||
* parser/renderer.
|
||||
*
|
||||
* Text-only implementations on GUI platforms (i.e., implementations that
|
||||
* are not based on the HTML parser/renderer engine in HTML TADS, but
|
||||
* which run on GUI platforms with proportionally-spaced text) should use
|
||||
* this flag to determine the font to display. If this flag is NOT set,
|
||||
* then the caller doesn't care about <TAB>, and the implementation is
|
||||
* free to use a proportionally-spaced font in the window if desired.
|
||||
*
|
||||
* When retrieving information on an existing banner, this flag indicates
|
||||
* that <TAB> alignment is actually supported on the window.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_TAB_ALIGN 0x00000020
|
||||
|
||||
/*
|
||||
* Use "MORE" mode in this window. By default, a banner window should
|
||||
* happily allow text to overflow the vertical limits of the window; the
|
||||
* only special thing that should happen on overflow is that the window
|
||||
* should be srolled down to show the latest text, if the auto-vscroll
|
||||
* style is set. With this flag, though, a banner window acts just like
|
||||
* the main text window: when the window fills up vertically, we show a
|
||||
* MORE prompt (using appropriate system conventions), and wait for the
|
||||
* user to indicate that they're ready to see more text. On most systems,
|
||||
* the user acknowledges a MORE prompt by pressing a key or scrolling with
|
||||
* the mouse, but it's up to the system implementor to decide what's
|
||||
* appropriate for the system.
|
||||
*
|
||||
* Note that MORE mode in ANY banner window should generally override all
|
||||
* other user input focus. In other words, if the game in the main window
|
||||
* would like to read a keystroke from the user, but one of the banner
|
||||
* windows is pausing with a MORE prompt, any keyboard input should be
|
||||
* directed to the banner paused at the MORE prompt, not to the main
|
||||
* window; the main window should not receive any key events until the MORE
|
||||
* prompt has been removed.
|
||||
*
|
||||
* This style requires the auto-vscroll style. Implementations should
|
||||
* assume auto-vscroll when this style is set. This style can be ignored
|
||||
* with text grid windows.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_MOREMODE 0x00000040
|
||||
|
||||
/*
|
||||
* This banner is a horizontal/vertical "strut" for sizing purposes. This
|
||||
* means that the banner's content size is taken into account when figuring
|
||||
* the content size of its *parent* banner. If the banner has the same
|
||||
* orientation as the parent, its content size is added to its parent's
|
||||
* internal content size to determine the parent's overall content size.
|
||||
* If the banner's orientation is orthogonal to the parent's, then the
|
||||
* parent's overall content size is the larger of the parent's internal
|
||||
* content size and this banner's content size.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_HSTRUT 0x00000080
|
||||
#define OS_BANNER_STYLE_VSTRUT 0x00000100
|
||||
|
||||
|
||||
/*
|
||||
* Delete a banner. This removes the banner from the display, which
|
||||
* requires recalculating the entire screen's layout to reallocate this
|
||||
* banner's space to other windows. When this routine returns, the banner
|
||||
* handle is invalid and can no longer be used in any os_banner_xxx
|
||||
* function calls.
|
||||
*
|
||||
* If the banner has children, the children will no longer be displayed,
|
||||
* but will remain valid in memory until deleted. A child window's
|
||||
* display area always comes out of its parent's space, so once the parent
|
||||
* is gone, a child has no way to acquire any display space; resizing the
|
||||
* child won't help, since it simply has no way to obtain any screen space
|
||||
* once its parent has been deleted. Even though the window's children
|
||||
* will become invisible, their banner handles will remain valid; the
|
||||
* caller is responsible for explicitly deleting the children even after
|
||||
* deleting their parent.
|
||||
*/
|
||||
void os_banner_delete(void *banner_handle);
|
||||
|
||||
/*
|
||||
* "Orphan" a banner. This tells the osifc implementation that the caller
|
||||
* wishes to sever all of its ties with the banner (as part of program
|
||||
* termination, for example), but that the calling program does not
|
||||
* actually require that the banner's on-screen display be immediately
|
||||
* removed.
|
||||
*
|
||||
* The osifc implementation can do one of two things:
|
||||
*
|
||||
* 1. Simply call os_banner_delete(). If the osifc implementation
|
||||
* doesn't want to do anything extra with the banner, it can simply delete
|
||||
* the banner, since the caller has no more use for it.
|
||||
*
|
||||
* 2. Take ownership of the banner. If the osifc implementation wishes
|
||||
* to continue displaying the final screen configuration after a program
|
||||
* has terminated, it can simply take over the banner and leave it on the
|
||||
* screen. The osifc subsystem must eventually delete the banner itself
|
||||
* if it takes this routine; for example, if the osifc subsystem allows
|
||||
* another client program to be loaded into the same window after a
|
||||
* previous program has terminated, it would want to delete any orphaned
|
||||
* banners from the previous program when loading a new program.
|
||||
*/
|
||||
void os_banner_orphan(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Banner information structure. This is filled in by the system-specific
|
||||
* implementation in os_banner_getinfo().
|
||||
*/
|
||||
struct os_banner_info_t
|
||||
{
|
||||
/* alignment */
|
||||
int align;
|
||||
|
||||
/* style flags - these indicate the style flags actually in use */
|
||||
unsigned long style;
|
||||
|
||||
/*
|
||||
* Actual on-screen size of the banner, in rows and columns. If the
|
||||
* banner is displayed in a proportional font or can display multiple
|
||||
* fonts of different sizes, this is approximated by the number of "0"
|
||||
* characters in the window's default font that will fit in the
|
||||
* window's display area.
|
||||
*/
|
||||
int rows;
|
||||
int columns;
|
||||
|
||||
/*
|
||||
* Actual on-screen size of the banner in pixels. This is meaningful
|
||||
* only for full HTML interpreter; for text-only interpreters, these
|
||||
* are always set to zero.
|
||||
*
|
||||
* Note that even if we're running on a GUI operating system, these
|
||||
* aren't meaningful unless this is a full HTML interpreter. Text-only
|
||||
* interpreters should always set these to zero, even on GUI OS's.
|
||||
*/
|
||||
int pix_width;
|
||||
int pix_height;
|
||||
|
||||
/*
|
||||
* OS line wrapping flag. If this is set, the window uses OS-level
|
||||
* line wrapping because the window uses a proportional font, so the
|
||||
* caller does not need to (and should not) perform line breaking in
|
||||
* text displayed in the window.
|
||||
*
|
||||
* Note that OS line wrapping is a PERMANENT feature of the window.
|
||||
* Callers can note this information once and expect it to remain
|
||||
* fixed through the window's lifetime.
|
||||
*/
|
||||
int os_line_wrap;
|
||||
};
|
||||
typedef struct os_banner_info_t os_banner_info_t;
|
||||
|
||||
/*
|
||||
* Get information on the banner - fills in the information structure with
|
||||
* the banner's current settings. Note that this should indicate the
|
||||
* ACTUAL properties of the banner, not the requested properties; this
|
||||
* allows callers to determine how the banner is actually displayed, which
|
||||
* depends upon the platform's capabilities and user preferences.
|
||||
*
|
||||
* Returns true if the information was successfully obtained, false if
|
||||
* not. This can return false if the underlying OS window has already
|
||||
* been closed by a user action, for example.
|
||||
*/
|
||||
int os_banner_getinfo(void *banner_handle, os_banner_info_t *info);
|
||||
|
||||
/*
|
||||
* Get the character width/height of the banner, for layout purposes. This
|
||||
* gives the size of the banner in character cells.
|
||||
*
|
||||
* These are not meaningful when the underlying window uses a proportional
|
||||
* font or varying fonts of different sizes. When the size of text varies
|
||||
* in the window, the OS layer is responsible for word-wrapping and other
|
||||
* layout, in which case these simply return zero.
|
||||
*
|
||||
* Note that these routines might appear to be redundant with the 'rows'
|
||||
* and 'columns' information returned from os_banner_getinfo(), but these
|
||||
* have two important distinctions. First, these routines return only the
|
||||
* width and height information, so they can be implemented with less
|
||||
* overhead than os_banner_getinfo(); this is important because formatters
|
||||
* might need to call these routines frequently while formatting text.
|
||||
* Second, these routines are not required to return an approximation for
|
||||
* windows using proportional fonts, as os_banner_getinfo() does; these can
|
||||
* simply return zero when a proportional font is in use.
|
||||
*/
|
||||
int os_banner_get_charwidth(void *banner_handle);
|
||||
int os_banner_get_charheight(void *banner_handle);
|
||||
|
||||
/* clear the contents of a banner */
|
||||
void os_banner_clear(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Display output on a banner. Writes the output to the window on the
|
||||
* display at the current output position.
|
||||
*
|
||||
* The following special characters should be recognized and handled:
|
||||
*
|
||||
* '\n' - newline; move output position to the start of the next line.
|
||||
*
|
||||
* '\r' - move output position to start of current line; subsequent text
|
||||
* overwrites any text previously displayed on the current line. It is
|
||||
* permissible to delete the old text immediately on seeing the '\r',
|
||||
* rather than waiting for additional text to actually overwrite it.
|
||||
*
|
||||
* All other characters should simply be displayed as ordinary printing
|
||||
* text characters. Note that tab characters should not be passed to this
|
||||
* routine, but if they are, they can simply be treated as ordinary spaces
|
||||
* if desired. Other control characters (backspace, escape, etc) should
|
||||
* never be passed to this routine; the implementation is free to ignore
|
||||
* any control characters not listed above.
|
||||
*
|
||||
* If any text displayed here overflows the current boundaries of the
|
||||
* window on the screen, the text MUST be "clipped" to the current window
|
||||
* boundaries; in other words, anything this routine tries to display
|
||||
* outside of the window's on-screen rectangle must not actually be shown
|
||||
* on the screen.
|
||||
*
|
||||
* Text overflowing the display boundaries MUST also be retained in an
|
||||
* internal buffer. This internal buffer can be limited to the actual
|
||||
* maximum display size of the terminal screen or application window, if
|
||||
* desired. It is necessary to retain clipped text, because this allows a
|
||||
* window to be expanded to the size of its contents AFTER the contents
|
||||
* have already been displayed.
|
||||
*
|
||||
* If the banner does its own line wrapping, it must indicate this via the
|
||||
* os_line_wrap flag in the os_banner_getinfo() return data. If the
|
||||
* banner doesn't indicate this flag, then it must not do any line
|
||||
* wrapping at all, even if the caller attempts to write text beyond the
|
||||
* right edge of the window - any text overflowing the width of the window
|
||||
* must simply be clipped.
|
||||
*
|
||||
* Text grid banners must ALWAYS clip - these banners should never perform
|
||||
* any line wrapping.
|
||||
*/
|
||||
void os_banner_disp(void *banner_handle, const char *txt, size_t len);
|
||||
|
||||
/*
|
||||
* Set the text attributes in a banner, for subsequent text displays.
|
||||
* 'attr' is a (bitwise-OR'd) combination of OS_ATTR_xxx values.
|
||||
*/
|
||||
void os_banner_set_attr(void *banner_handle, int attr);
|
||||
|
||||
/*
|
||||
* Set the text color in a banner, for subsequent text displays. The 'fg'
|
||||
* and 'bg' colors are given as RGB or parameterized colors; see the
|
||||
* definition of os_color_t for details.
|
||||
*
|
||||
* If the underlying renderer is HTML-enabled, then this should not be
|
||||
* used; the appropriate HTML code should simply be displayed to the
|
||||
* banner instead.
|
||||
*/
|
||||
void os_banner_set_color(void *banner_handle, os_color_t fg, os_color_t bg);
|
||||
|
||||
/*
|
||||
* Set the screen color in the banner - this is analogous to the screen
|
||||
* color in the main text area.
|
||||
*
|
||||
* If the underlying renderer is HTML-enabled, then this should not be
|
||||
* used; the HTML <BODY> tag should be used instead.
|
||||
*/
|
||||
void os_banner_set_screen_color(void *banner_handle, os_color_t color);
|
||||
|
||||
/* flush output on a banner */
|
||||
void os_banner_flush(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Set the banner's size. The size has the same meaning as in
|
||||
* os_banner_create().
|
||||
*
|
||||
* 'is_advisory' indicates whether the sizing is required or advisory only.
|
||||
* If this flag is false, then the size should be set as requested. If
|
||||
* this flag is true, it means that the caller intends to call
|
||||
* os_banner_size_to_contents() at some point, and that the size being set
|
||||
* now is for advisory purposes only. Platforms that support
|
||||
* size-to-contents may simply ignore advisory sizing requests, although
|
||||
* they might want to ensure that they have sufficient off-screen buffer
|
||||
* space to keep track of the requested size of display, so that the
|
||||
* information the caller displays in preparation for calling
|
||||
* size-to-contents will be retained. Platforms that do not support
|
||||
* size-to-contents should set the requested size even when 'is_advisory'
|
||||
* is true.
|
||||
*/
|
||||
void os_banner_set_size(void *banner_handle, int siz, int siz_units,
|
||||
int is_advisory);
|
||||
|
||||
/*
|
||||
* Set the banner to the size of its current contents. This can be used
|
||||
* to set the banner's size after some text (or other material) has been
|
||||
* displayed to the banner, so that the size can be set according to the
|
||||
* banner's actual space requirements.
|
||||
*
|
||||
* This changes the banner's "requested size" to match the current size.
|
||||
* Subsequent calls to os_banner_getinfo() will thus indicate a requested
|
||||
* size according to the size set here.
|
||||
*/
|
||||
void os_banner_size_to_contents(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Turn HTML mode on/off in the banner window. If the underlying renderer
|
||||
* doesn't support HTML, these have no effect.
|
||||
*/
|
||||
void os_banner_start_html(void *banner_handle);
|
||||
void os_banner_end_html(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Set the output coordinates in a text grid window. The grid window is
|
||||
* arranged into character cells numbered from row zero, column zero for
|
||||
* the upper left cell. This function can only be used if the window was
|
||||
* created with type OS_BANNER_TYPE_TEXTGRID; the request should simply be
|
||||
* ignored by other window types.
|
||||
*
|
||||
* Moving the output position has no immediate effect on the display, and
|
||||
* does not itself affect the "content size" for the purposes of
|
||||
* os_banner_size_to_contents(). This simply sets the coordinates where
|
||||
* any subsequent text is displayed.
|
||||
*/
|
||||
void os_banner_goto(void *banner_handle, int row, int col);
|
||||
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
#endif
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "glk/tads/os_buffer.h"
|
||||
#include "glk/tads/os_parse.h"
|
||||
#include "glk/tads/tads.h"
|
||||
|
||||
namespace Glk {
|
||||
@@ -50,10 +51,6 @@ char *os_fill_buffer(char *buf, size_t len)
|
||||
static uint32 *input = 0;
|
||||
static uint max = 0;
|
||||
|
||||
extern uint os_parse_chars(const char *buf, uint buflen, uint32 *out, uint outlen);
|
||||
|
||||
extern uint os_prepare_chars(uint32 *buf, uint buflen, char *out, uint outlen);
|
||||
|
||||
void os_put_buffer(const char *buf, size_t len) {
|
||||
uint *out;
|
||||
uint outlen;
|
||||
@@ -66,7 +63,7 @@ void os_put_buffer(const char *buf, size_t len) {
|
||||
return;
|
||||
outlen = len;
|
||||
|
||||
outlen = os_parse_chars(buf, len, out, outlen);
|
||||
outlen = os_parse_chars((const unsigned char *)buf, len, out, outlen);
|
||||
|
||||
if (outlen)
|
||||
g_vm->glk_put_buffer_uni(out, outlen);
|
||||
@@ -81,13 +78,13 @@ void os_get_buffer(char *buf, size_t len, size_t init) {
|
||||
max = len;
|
||||
|
||||
if (init)
|
||||
os_parse_chars(buf, init + 1, input, len);
|
||||
os_parse_chars((const unsigned char *)buf, init + 1, input, len);
|
||||
|
||||
g_vm->glk_request_line_event_uni(mainwin, input, len - 1, init);
|
||||
}
|
||||
|
||||
char *os_fill_buffer(char *buf, size_t len) {
|
||||
uint res = os_prepare_chars(input, len, buf, max);
|
||||
uint res = os_prepare_chars(input, len, (unsigned char *)buf, max);
|
||||
buf[res] = '\0';
|
||||
|
||||
free(input);
|
||||
|
||||
@@ -44,6 +44,11 @@ uint mainbg;
|
||||
uint statusfg;
|
||||
uint statusbg;
|
||||
|
||||
int G_os_pagelength;
|
||||
int G_os_linewidth;
|
||||
int G_os_moremode;
|
||||
char G_os_gamename[OSFNMAX];
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
@@ -993,10 +998,106 @@ long os_get_sys_clock_ms() {
|
||||
return g_system->getMillis();
|
||||
}
|
||||
|
||||
void os_xlat_html4(unsigned int html4_char, char *result, size_t result_len) {
|
||||
/* Return all standard Latin-1 characters as-is */
|
||||
if (html4_char <= 128 || (html4_char >= 160 && html4_char <= 255))
|
||||
result[0] = (unsigned char)html4_char;
|
||||
else {
|
||||
switch (html4_char) {
|
||||
case 130: /* single back quote */
|
||||
result[0] = '`'; break;
|
||||
case 132: /* double back quote */
|
||||
result[0] = '\"'; break;
|
||||
case 153: /* trade mark */
|
||||
strcpy(result, "(tm)"); return;
|
||||
case 140: /* OE ligature */
|
||||
case 338: /* OE ligature */
|
||||
strcpy(result, "OE"); return;
|
||||
case 339: /* oe ligature */
|
||||
strcpy(result, "oe"); return;
|
||||
case 159: /* Yuml */
|
||||
result[0] = (char)255;
|
||||
case 376: /* Y with diaresis */
|
||||
result[0] = 'Y'; break;
|
||||
case 352: /* S with caron */
|
||||
result[0] = 'S'; break;
|
||||
case 353: /* s with caron */
|
||||
result[0] = 's'; break;
|
||||
case 150: /* en dash */
|
||||
case 8211: /* en dash */
|
||||
result[0] = '-'; break;
|
||||
case 151: /* em dash */
|
||||
case 8212: /* em dash */
|
||||
strcpy(result, "--"); return;
|
||||
case 145: /* left single quote */
|
||||
case 8216: /* left single quote */
|
||||
result[0] = '`'; break;
|
||||
case 146: /* right single quote */
|
||||
case 8217: /* right single quote */
|
||||
case 8218: /* single low-9 quote */
|
||||
result[0] = '\''; break;
|
||||
case 147: /* left double quote */
|
||||
case 148: /* right double quote */
|
||||
case 8220: /* left double quote */
|
||||
case 8221: /* right double quote */
|
||||
case 8222: /* double low-9 quote */
|
||||
result[0] = '\"'; break;
|
||||
case 8224: /* dagger */
|
||||
case 8225: /* double dagger */
|
||||
case 8240: /* per mille sign */
|
||||
result[0] = ' '; break;
|
||||
case 139: /* single left-pointing angle quote */
|
||||
case 8249: /* single left-pointing angle quote */
|
||||
result[0] = '<'; break;
|
||||
case 155: /* single right-pointing angle quote */
|
||||
case 8250: /* single right-pointing angle quote */
|
||||
result[0] = '>'; break;
|
||||
case 8482: /* small tilde */
|
||||
result[0] = '~'; break;
|
||||
|
||||
default:
|
||||
/* unmappable character - return space */
|
||||
result[0] = (unsigned char)' ';
|
||||
}
|
||||
}
|
||||
result[1] = 0;
|
||||
}
|
||||
|
||||
#ifndef os_tzset
|
||||
void os_tzset() {}
|
||||
#endif
|
||||
|
||||
void os_nonstop_mode(int flag) {}
|
||||
|
||||
void os_advise_load_charmap(const char *id, const char *ldesc, const char *sysinfo) {}
|
||||
|
||||
void os_gen_charmap_filename(char *filename, char *internal_id, char *argv0) {}
|
||||
|
||||
int os_input_dialog(int icon_id, const char *prompt, int standard_button_set,
|
||||
const char **buttons, int button_count, int default_index, int cancel_index) {
|
||||
// CUrrently unsupported
|
||||
return 0;
|
||||
}
|
||||
|
||||
void os_flush() {
|
||||
g_vm->glk_tick();
|
||||
}
|
||||
|
||||
char *os_strlwr(char *s) {
|
||||
for (char *p = s; *p; ++p)
|
||||
*p = tolower(*p);
|
||||
return s;
|
||||
}
|
||||
|
||||
void os_expause() {
|
||||
#ifdef USE_EXPAUSE
|
||||
os_printz("(Strike any key to exit...)");
|
||||
os_flush();
|
||||
os_waitc();
|
||||
#endif /* USE_EXPAUSE */
|
||||
}
|
||||
|
||||
void os_plain(void) {}
|
||||
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
+2
-595
@@ -42,6 +42,7 @@ namespace TADS {
|
||||
#define OSPATHURL "/"
|
||||
#define OSPATHSEP ':'
|
||||
#define OS_NEWLINE_SEQ "\n"
|
||||
#define DBG_OFF
|
||||
|
||||
/* maximum width (in characters) of a line of text */
|
||||
#define OS_MAXWIDTH 255
|
||||
@@ -2802,8 +2803,7 @@ void os_xlat_html4(unsigned int html4_char,
|
||||
* This parameter is provided so that the system code can look for
|
||||
* mapping files in the original TADS executables directory, if desired.
|
||||
*/
|
||||
void os_gen_charmap_filename(char *filename, char *internal_id,
|
||||
char *argv0);
|
||||
void os_gen_charmap_filename(char *filename, char *internal_id, char *argv0);
|
||||
|
||||
/*
|
||||
* Receive notification that a character mapping file has been loaded.
|
||||
@@ -2912,599 +2912,6 @@ void os_get_charmap(char *mapname, int charmap_id);
|
||||
*/
|
||||
#define OS_CHARMAP_CMDLINE 4
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/*
|
||||
* External Banner Interface. This interface provides the ability to
|
||||
* divide the display window into multiple sub-windows, each with its own
|
||||
* independent contents.
|
||||
*
|
||||
* To determine where a new banner is displayed, we look at the banners as
|
||||
* a tree, rooted at the "main window," the special banner that the system
|
||||
* automatically creates initially for the main game text. We start by
|
||||
* allocating the entire display (or the entire application window, if
|
||||
* we're running on a GUI system) to the main window. We then traverse
|
||||
* the tree, starting with the root window's children. For each child
|
||||
* window, we allocate space for the child out of the parent window's
|
||||
* area, according to the child's alignment and size settings, and deduct
|
||||
* this space from the parent window's size. We then lay out the children
|
||||
* of the child.
|
||||
*
|
||||
* For each banner window, we take its requested space out of the parent
|
||||
* window's area by starting at the edge of the parent window rectangle as
|
||||
* indicated by the banner's alignment, and taking the requested `width
|
||||
* (for a left/right banner) or height (for a top/bottom banner), limiting
|
||||
* to the available width/height in the parent window's space. Give the
|
||||
* banner the full extent of the parent's space in its other dimension (so
|
||||
* a left/right banner gets the full height of the parent space, and a
|
||||
* top/bottom banner gets the full width).
|
||||
*
|
||||
* Note that the layout proceeds exclusively down the tree (i.e., from the
|
||||
* root to children to grandchildren, and so on). It *appears* that a
|
||||
* child affects its parent, because of the deduction step: a child
|
||||
* acquires screen space by carving out a chunk of its parent. The right
|
||||
* way to think about this, though, is that the parent's full area is the
|
||||
* union of the parent window and all of its children; when viewed this
|
||||
* way, the parent's full area is fully determined the instant the parent
|
||||
* is laid out, and never changes as its children are laid out. Note in
|
||||
* particular that a child can never make a parent larger; the only thing
|
||||
* a child can do to a parent is carve out a chunk of the parent for
|
||||
* itself, which doesn't affect the boundaries of the union of the parent
|
||||
* plus its children.
|
||||
*
|
||||
* Note also that if the banner has a border, and the implementation
|
||||
* actually draws borders, the border must be drawn for the *full* area of
|
||||
* the banner, as defined above. For example, suppose we have two
|
||||
* borders: banner A is a child of the main window, is top-aligned, and
|
||||
* has a border. Banner B is a child of banner A, right-aligned, with no
|
||||
* border. Obviously, without considering banner B, banner A's space runs
|
||||
* across the entire width of the main window, so its border (at the
|
||||
* bottom of its area) runs across the entire width of the main window.
|
||||
* Banner B carves out some space from A's right side for itself, so
|
||||
* banner A's actual on-screen area runs from the left edge of the main
|
||||
* window to banner B's left edge. However, even though banner A itself
|
||||
* no longer runs the full width of the main window, banner A's *full*
|
||||
* area - that is, the union of banner A's on-screen area and all of its
|
||||
* children's full areas - does still run the entire width of the main
|
||||
* window, hence banner A's border must still run the full width of the
|
||||
* main window. The simple way of looking at this is that a banner's
|
||||
* border is always to be drawn exactly the same way, regardless of
|
||||
* whether or not the banner has children - simply draw the banner as it
|
||||
* would be drawn if the banner had no children.
|
||||
*
|
||||
* Each time a banner is added or removed, we must recalculate the layout
|
||||
* of the remaining banners and main text area. The os_banner_xxx()
|
||||
* implementation is responsible for this layout refiguring.
|
||||
*
|
||||
* The entire external banner window interface is optional, although the
|
||||
* functions must at least be defined as dummies to avoid linker errors
|
||||
* when building. If a platform doesn't implement this feature,
|
||||
* os_banner_create() should simply return null, and the other routines
|
||||
* can do nothing.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create a banner window. 'info' gives the desired parameters for the new
|
||||
* banner.
|
||||
*
|
||||
* Note that certain requested parameter settings might or might not be
|
||||
* respected, depending on the capabilities of the platform and user
|
||||
* preferences. os_banner_getinfo() can be used after creation to
|
||||
* determine which parameter settings are actually used in the new banner.
|
||||
*
|
||||
* 'parent' gives the parent of this banner; this is the banner handle of
|
||||
* another banner window, or null. If 'parent' is null, then the new
|
||||
* banner is a child of the main window, which the system creates
|
||||
* automatically at startup and which contains the main input/output
|
||||
* transcript. The new banner's on-screen area is carved out of the
|
||||
* parent's space, according to the alignment and size settings of the new
|
||||
* window, so this determines how the window is laid out on the screen.
|
||||
*
|
||||
* 'where' is OS_BANNER_FIRST to make the new window the first child of its
|
||||
* parent; OS_BANNER_LAST to make it the last child of its parent;
|
||||
* OS_BANNER_BEFORE to insert it immediately before the existing banner
|
||||
* identified by handle in 'other'; or OS_BANNER_AFTER to insert
|
||||
* immediately after 'other'. When BEFORE or AFTER is used, 'other' must
|
||||
* be another child of the same parent; if it is not, the routine should
|
||||
* act as though 'where' were given as OS_BANNER_LAST.
|
||||
*
|
||||
* 'other' is a banner handle for an existing banner window. This is used
|
||||
* to specify the relative position among children of the new banner's
|
||||
* parent, if 'where' is either OS_BANNER_BEFORE or OS_BANNER_AFTER. If
|
||||
* 'where' is OS_BANNER_FIRST or OS_BANNER_LAST, 'other' is ignored.
|
||||
*
|
||||
* 'wintype' is the type of the window. This is one of the
|
||||
* OS_BANNER_TYPE_xxx codes indicating what kind of window is desired.
|
||||
*
|
||||
* 'align' is the banner's alignment, given as an OS_BANNER_ALIGN_xxx
|
||||
* value. Top/bottom banners are horizontal: they run across the full
|
||||
* width of the existing main text area. Left/right banners are vertical:
|
||||
* they run down the full height of the existing main text area.
|
||||
*
|
||||
* 'siz' is the requested size of the new banner. The meaning of 'siz'
|
||||
* depends on the value of 'siz_units', which can be OS_BANNER_SIZE_PCT to
|
||||
* set the size as a percentage of the REMAINING space, or
|
||||
* OS_BANNER_SIZE_ABS to set an absolute size in the "natural" units of the
|
||||
* window. The natural units vary by window type: for text and text grid
|
||||
* windows, this is in rows/columns of '0' characters in the default font
|
||||
* for the window. Note that when OS_BANNER_SIZE_ABS is used in a text or
|
||||
* text grid window, the OS implementation MUST add the space needed for
|
||||
* margins and borders when determining the actual pixel size of the
|
||||
* window; in other words, the window should be large enough that it can
|
||||
* actually display the given number or rows or columns.
|
||||
*
|
||||
* The size is interpreted as a width or height according to the window's
|
||||
* orientation. For a TOP or BOTTOM banner, the size is the height; for a
|
||||
* LEFT or RIGHT banner, the size is the width. A banner has only one
|
||||
* dimension's size given, since the other dimension's size is determined
|
||||
* automatically by the layout rules.
|
||||
*
|
||||
* Note that the window's size can be changed later using
|
||||
* banner_size_to_contents() or banner_set_size().
|
||||
*
|
||||
* 'style' is a combination of OS_BANNER_STYLE_xxx flags - see below. The
|
||||
* style flags give the REQUESTED style for the banner, which might or
|
||||
* might not be respected, depending on the platform's capabilities, user
|
||||
* preferences, and other factors. os_banner_getinfo() can be used to
|
||||
* determine which style flags are actually used.
|
||||
*
|
||||
* Returns the "handle" to the new banner window, which is an opaque value
|
||||
* that is used in subsequent os_banner_xxx calls to operate on the window.
|
||||
* Returns null if the window cannot be created. An implementation is not
|
||||
* required to support this functionality at all, and can subset it if it
|
||||
* does support it (for example, an implementation could support only
|
||||
* top/bottom-aligned banners, but not left/right-aligned), so callers must
|
||||
* be prepared for this routine to return null.
|
||||
*/
|
||||
void *os_banner_create(void *parent, int where, void *other, int wintype,
|
||||
int align, int siz, int siz_units,
|
||||
unsigned long style);
|
||||
|
||||
|
||||
/*
|
||||
* insertion positions
|
||||
*/
|
||||
#define OS_BANNER_FIRST 1
|
||||
#define OS_BANNER_LAST 2
|
||||
#define OS_BANNER_BEFORE 3
|
||||
#define OS_BANNER_AFTER 4
|
||||
|
||||
/*
|
||||
* banner types
|
||||
*/
|
||||
|
||||
/*
|
||||
* Normal text stream window. This is a text stream that behaves
|
||||
* essentially like the main text window: text is displayed to this
|
||||
* through os_banner_disp(), always in a stream-like fashion by adding new
|
||||
* text to the end of any exiting text.
|
||||
*
|
||||
* Systems that use proportional fonts should usually simply use the same
|
||||
* font they use by default in the main text window. However, note that
|
||||
* the OS_BANNER_STYLE_TAB_ALIGN style flag might imply that a fixed-pitch
|
||||
* font should be used even when proportional fonts are available, because
|
||||
* a fixed-pitch font will allow the calling code to rely on using spaces
|
||||
* to align text within the window.
|
||||
*/
|
||||
#define OS_BANNER_TYPE_TEXT 1
|
||||
|
||||
/*
|
||||
* "Text grid" window. This type of window is similar to an normal text
|
||||
* window (OS_BANNER_TYPE_TEXT), but is guaranteed to arrange its text in
|
||||
* a regular grid of character cells, all of the same size. This means
|
||||
* that the output position can be moved to an arbitrary point within the
|
||||
* window at any time, so the calling program can precisely control the
|
||||
* layout of the text in the window.
|
||||
*
|
||||
* Because the output position can be moved to arbitrary positions in the
|
||||
* window, it is possible to overwrite text previously displayed. When
|
||||
* this happens, the old text is completely obliterated by the new text,
|
||||
* leaving no trace of the overwritten text.
|
||||
*
|
||||
* In order to guarantee that character cells are all the same size, this
|
||||
* type of window does not allow any text attributes. The implementation
|
||||
* should simply ignore any attempts to change text attributes in this
|
||||
* type of window. However, colors can be used to the same degree they
|
||||
* can be used in an ordinary text window.
|
||||
*
|
||||
* To guarantee the regular spacing of character cells, all
|
||||
* implementations must use fixed-pitch fonts for these windows. This
|
||||
* applies even to platforms where proportional fonts are available.
|
||||
*/
|
||||
#define OS_BANNER_TYPE_TEXTGRID 2
|
||||
|
||||
|
||||
/*
|
||||
* banner alignment types
|
||||
*/
|
||||
#define OS_BANNER_ALIGN_TOP 0
|
||||
#define OS_BANNER_ALIGN_BOTTOM 1
|
||||
#define OS_BANNER_ALIGN_LEFT 2
|
||||
#define OS_BANNER_ALIGN_RIGHT 3
|
||||
|
||||
/*
|
||||
* size units
|
||||
*/
|
||||
#define OS_BANNER_SIZE_PCT 1
|
||||
#define OS_BANNER_SIZE_ABS 2
|
||||
|
||||
|
||||
/*
|
||||
* banner style flags
|
||||
*/
|
||||
|
||||
/*
|
||||
* The banner has a visible border; this indicates that a line is to be
|
||||
* drawn to separate the banner from the adjacent window or windows
|
||||
* "inside" the banner. So, a top-aligned banner will have its border
|
||||
* drawn along its bottom edge; a left-aligned banner will show a border
|
||||
* along its right edge; and so forth.
|
||||
*
|
||||
* Note that character-mode platforms generally do NOT respect the border
|
||||
* style, since doing so takes up too much screen space.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_BORDER 0x00000001
|
||||
|
||||
/*
|
||||
* The banner has a vertical/horizontal scrollbar. Character-mode
|
||||
* platforms generally do not support scrollbars.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_VSCROLL 0x00000002
|
||||
#define OS_BANNER_STYLE_HSCROLL 0x00000004
|
||||
|
||||
/*
|
||||
* Automatically scroll the banner vertically/horizontally whenever new
|
||||
* text is displayed in the window. In other words, whenever
|
||||
* os_banner_disp() is called, scroll the window so that the text that the
|
||||
* new cursor position after the new text is displayed is visible in the
|
||||
* window.
|
||||
*
|
||||
* Note that this style is independent of the presence of scrollbars.
|
||||
* Even if there are no scrollbars, we can still scroll the window's
|
||||
* contents programmatically.
|
||||
*
|
||||
* Implementations can, if desired, keep an internal buffer of the
|
||||
* window's contents, so that the contents can be recalled via the
|
||||
* scrollbars if the text displayed in the banner exceeds the space
|
||||
* available in the banner's window on the screen. If the implementation
|
||||
* does keep such a buffer, we recommend the following method for managing
|
||||
* this buffer. If the AUTO_VSCROLL flag is not set, then the banner's
|
||||
* contents should be truncated at the bottom when the contents overflow
|
||||
* the buffer; that is, once the banner's internal buffer is full, any new
|
||||
* text that the calling program attempts to add to the banner should
|
||||
* simply be discarded. If the AUTO_VSCROLL flag is set, then the OLDEST
|
||||
* text should be discarded instead, so that the most recent text is
|
||||
* always retained.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_AUTO_VSCROLL 0x00000008
|
||||
#define OS_BANNER_STYLE_AUTO_HSCROLL 0x00000010
|
||||
|
||||
/*
|
||||
* Tab-based alignment is required/supported. On creation, this is a hint
|
||||
* to the implementation that is sometimes necessary to determine what
|
||||
* kind of font to use in the new window, for non-HTML platforms. If this
|
||||
* flag is set on creation, the caller is indicating that it wants to use
|
||||
* <TAB> tags to align text in the window.
|
||||
*
|
||||
* Character-mode implementations that use a single font with fixed pitch
|
||||
* can simply ignore this. These implementations ALWAYS have a working
|
||||
* <TAB> capability, because the portable output formatter provides <TAB>
|
||||
* interpretation for a fixed-pitch window.
|
||||
*
|
||||
* Full HTML TADS implementations can also ignore this. HTML TADS
|
||||
* implementations always have full <TAB> support via the HTML
|
||||
* parser/renderer.
|
||||
*
|
||||
* Text-only implementations on GUI platforms (i.e., implementations that
|
||||
* are not based on the HTML parser/renderer engine in HTML TADS, but
|
||||
* which run on GUI platforms with proportionally-spaced text) should use
|
||||
* this flag to determine the font to display. If this flag is NOT set,
|
||||
* then the caller doesn't care about <TAB>, and the implementation is
|
||||
* free to use a proportionally-spaced font in the window if desired.
|
||||
*
|
||||
* When retrieving information on an existing banner, this flag indicates
|
||||
* that <TAB> alignment is actually supported on the window.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_TAB_ALIGN 0x00000020
|
||||
|
||||
/*
|
||||
* Use "MORE" mode in this window. By default, a banner window should
|
||||
* happily allow text to overflow the vertical limits of the window; the
|
||||
* only special thing that should happen on overflow is that the window
|
||||
* should be srolled down to show the latest text, if the auto-vscroll
|
||||
* style is set. With this flag, though, a banner window acts just like
|
||||
* the main text window: when the window fills up vertically, we show a
|
||||
* MORE prompt (using appropriate system conventions), and wait for the
|
||||
* user to indicate that they're ready to see more text. On most systems,
|
||||
* the user acknowledges a MORE prompt by pressing a key or scrolling with
|
||||
* the mouse, but it's up to the system implementor to decide what's
|
||||
* appropriate for the system.
|
||||
*
|
||||
* Note that MORE mode in ANY banner window should generally override all
|
||||
* other user input focus. In other words, if the game in the main window
|
||||
* would like to read a keystroke from the user, but one of the banner
|
||||
* windows is pausing with a MORE prompt, any keyboard input should be
|
||||
* directed to the banner paused at the MORE prompt, not to the main
|
||||
* window; the main window should not receive any key events until the MORE
|
||||
* prompt has been removed.
|
||||
*
|
||||
* This style requires the auto-vscroll style. Implementations should
|
||||
* assume auto-vscroll when this style is set. This style can be ignored
|
||||
* with text grid windows.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_MOREMODE 0x00000040
|
||||
|
||||
/*
|
||||
* This banner is a horizontal/vertical "strut" for sizing purposes. This
|
||||
* means that the banner's content size is taken into account when figuring
|
||||
* the content size of its *parent* banner. If the banner has the same
|
||||
* orientation as the parent, its content size is added to its parent's
|
||||
* internal content size to determine the parent's overall content size.
|
||||
* If the banner's orientation is orthogonal to the parent's, then the
|
||||
* parent's overall content size is the larger of the parent's internal
|
||||
* content size and this banner's content size.
|
||||
*/
|
||||
#define OS_BANNER_STYLE_HSTRUT 0x00000080
|
||||
#define OS_BANNER_STYLE_VSTRUT 0x00000100
|
||||
|
||||
|
||||
/*
|
||||
* Delete a banner. This removes the banner from the display, which
|
||||
* requires recalculating the entire screen's layout to reallocate this
|
||||
* banner's space to other windows. When this routine returns, the banner
|
||||
* handle is invalid and can no longer be used in any os_banner_xxx
|
||||
* function calls.
|
||||
*
|
||||
* If the banner has children, the children will no longer be displayed,
|
||||
* but will remain valid in memory until deleted. A child window's
|
||||
* display area always comes out of its parent's space, so once the parent
|
||||
* is gone, a child has no way to acquire any display space; resizing the
|
||||
* child won't help, since it simply has no way to obtain any screen space
|
||||
* once its parent has been deleted. Even though the window's children
|
||||
* will become invisible, their banner handles will remain valid; the
|
||||
* caller is responsible for explicitly deleting the children even after
|
||||
* deleting their parent.
|
||||
*/
|
||||
void os_banner_delete(void *banner_handle);
|
||||
|
||||
/*
|
||||
* "Orphan" a banner. This tells the osifc implementation that the caller
|
||||
* wishes to sever all of its ties with the banner (as part of program
|
||||
* termination, for example), but that the calling program does not
|
||||
* actually require that the banner's on-screen display be immediately
|
||||
* removed.
|
||||
*
|
||||
* The osifc implementation can do one of two things:
|
||||
*
|
||||
* 1. Simply call os_banner_delete(). If the osifc implementation
|
||||
* doesn't want to do anything extra with the banner, it can simply delete
|
||||
* the banner, since the caller has no more use for it.
|
||||
*
|
||||
* 2. Take ownership of the banner. If the osifc implementation wishes
|
||||
* to continue displaying the final screen configuration after a program
|
||||
* has terminated, it can simply take over the banner and leave it on the
|
||||
* screen. The osifc subsystem must eventually delete the banner itself
|
||||
* if it takes this routine; for example, if the osifc subsystem allows
|
||||
* another client program to be loaded into the same window after a
|
||||
* previous program has terminated, it would want to delete any orphaned
|
||||
* banners from the previous program when loading a new program.
|
||||
*/
|
||||
void os_banner_orphan(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Banner information structure. This is filled in by the system-specific
|
||||
* implementation in os_banner_getinfo().
|
||||
*/
|
||||
struct os_banner_info_t
|
||||
{
|
||||
/* alignment */
|
||||
int align;
|
||||
|
||||
/* style flags - these indicate the style flags actually in use */
|
||||
unsigned long style;
|
||||
|
||||
/*
|
||||
* Actual on-screen size of the banner, in rows and columns. If the
|
||||
* banner is displayed in a proportional font or can display multiple
|
||||
* fonts of different sizes, this is approximated by the number of "0"
|
||||
* characters in the window's default font that will fit in the
|
||||
* window's display area.
|
||||
*/
|
||||
int rows;
|
||||
int columns;
|
||||
|
||||
/*
|
||||
* Actual on-screen size of the banner in pixels. This is meaningful
|
||||
* only for full HTML interpreter; for text-only interpreters, these
|
||||
* are always set to zero.
|
||||
*
|
||||
* Note that even if we're running on a GUI operating system, these
|
||||
* aren't meaningful unless this is a full HTML interpreter. Text-only
|
||||
* interpreters should always set these to zero, even on GUI OS's.
|
||||
*/
|
||||
int pix_width;
|
||||
int pix_height;
|
||||
|
||||
/*
|
||||
* OS line wrapping flag. If this is set, the window uses OS-level
|
||||
* line wrapping because the window uses a proportional font, so the
|
||||
* caller does not need to (and should not) perform line breaking in
|
||||
* text displayed in the window.
|
||||
*
|
||||
* Note that OS line wrapping is a PERMANENT feature of the window.
|
||||
* Callers can note this information once and expect it to remain
|
||||
* fixed through the window's lifetime.
|
||||
*/
|
||||
int os_line_wrap;
|
||||
};
|
||||
typedef struct os_banner_info_t os_banner_info_t;
|
||||
|
||||
/*
|
||||
* Get information on the banner - fills in the information structure with
|
||||
* the banner's current settings. Note that this should indicate the
|
||||
* ACTUAL properties of the banner, not the requested properties; this
|
||||
* allows callers to determine how the banner is actually displayed, which
|
||||
* depends upon the platform's capabilities and user preferences.
|
||||
*
|
||||
* Returns true if the information was successfully obtained, false if
|
||||
* not. This can return false if the underlying OS window has already
|
||||
* been closed by a user action, for example.
|
||||
*/
|
||||
int os_banner_getinfo(void *banner_handle, os_banner_info_t *info);
|
||||
|
||||
/*
|
||||
* Get the character width/height of the banner, for layout purposes. This
|
||||
* gives the size of the banner in character cells.
|
||||
*
|
||||
* These are not meaningful when the underlying window uses a proportional
|
||||
* font or varying fonts of different sizes. When the size of text varies
|
||||
* in the window, the OS layer is responsible for word-wrapping and other
|
||||
* layout, in which case these simply return zero.
|
||||
*
|
||||
* Note that these routines might appear to be redundant with the 'rows'
|
||||
* and 'columns' information returned from os_banner_getinfo(), but these
|
||||
* have two important distinctions. First, these routines return only the
|
||||
* width and height information, so they can be implemented with less
|
||||
* overhead than os_banner_getinfo(); this is important because formatters
|
||||
* might need to call these routines frequently while formatting text.
|
||||
* Second, these routines are not required to return an approximation for
|
||||
* windows using proportional fonts, as os_banner_getinfo() does; these can
|
||||
* simply return zero when a proportional font is in use.
|
||||
*/
|
||||
int os_banner_get_charwidth(void *banner_handle);
|
||||
int os_banner_get_charheight(void *banner_handle);
|
||||
|
||||
/* clear the contents of a banner */
|
||||
void os_banner_clear(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Display output on a banner. Writes the output to the window on the
|
||||
* display at the current output position.
|
||||
*
|
||||
* The following special characters should be recognized and handled:
|
||||
*
|
||||
* '\n' - newline; move output position to the start of the next line.
|
||||
*
|
||||
* '\r' - move output position to start of current line; subsequent text
|
||||
* overwrites any text previously displayed on the current line. It is
|
||||
* permissible to delete the old text immediately on seeing the '\r',
|
||||
* rather than waiting for additional text to actually overwrite it.
|
||||
*
|
||||
* All other characters should simply be displayed as ordinary printing
|
||||
* text characters. Note that tab characters should not be passed to this
|
||||
* routine, but if they are, they can simply be treated as ordinary spaces
|
||||
* if desired. Other control characters (backspace, escape, etc) should
|
||||
* never be passed to this routine; the implementation is free to ignore
|
||||
* any control characters not listed above.
|
||||
*
|
||||
* If any text displayed here overflows the current boundaries of the
|
||||
* window on the screen, the text MUST be "clipped" to the current window
|
||||
* boundaries; in other words, anything this routine tries to display
|
||||
* outside of the window's on-screen rectangle must not actually be shown
|
||||
* on the screen.
|
||||
*
|
||||
* Text overflowing the display boundaries MUST also be retained in an
|
||||
* internal buffer. This internal buffer can be limited to the actual
|
||||
* maximum display size of the terminal screen or application window, if
|
||||
* desired. It is necessary to retain clipped text, because this allows a
|
||||
* window to be expanded to the size of its contents AFTER the contents
|
||||
* have already been displayed.
|
||||
*
|
||||
* If the banner does its own line wrapping, it must indicate this via the
|
||||
* os_line_wrap flag in the os_banner_getinfo() return data. If the
|
||||
* banner doesn't indicate this flag, then it must not do any line
|
||||
* wrapping at all, even if the caller attempts to write text beyond the
|
||||
* right edge of the window - any text overflowing the width of the window
|
||||
* must simply be clipped.
|
||||
*
|
||||
* Text grid banners must ALWAYS clip - these banners should never perform
|
||||
* any line wrapping.
|
||||
*/
|
||||
void os_banner_disp(void *banner_handle, const char *txt, size_t len);
|
||||
|
||||
/*
|
||||
* Set the text attributes in a banner, for subsequent text displays.
|
||||
* 'attr' is a (bitwise-OR'd) combination of OS_ATTR_xxx values.
|
||||
*/
|
||||
void os_banner_set_attr(void *banner_handle, int attr);
|
||||
|
||||
/*
|
||||
* Set the text color in a banner, for subsequent text displays. The 'fg'
|
||||
* and 'bg' colors are given as RGB or parameterized colors; see the
|
||||
* definition of os_color_t for details.
|
||||
*
|
||||
* If the underlying renderer is HTML-enabled, then this should not be
|
||||
* used; the appropriate HTML code should simply be displayed to the
|
||||
* banner instead.
|
||||
*/
|
||||
void os_banner_set_color(void *banner_handle, os_color_t fg, os_color_t bg);
|
||||
|
||||
/*
|
||||
* Set the screen color in the banner - this is analogous to the screen
|
||||
* color in the main text area.
|
||||
*
|
||||
* If the underlying renderer is HTML-enabled, then this should not be
|
||||
* used; the HTML <BODY> tag should be used instead.
|
||||
*/
|
||||
void os_banner_set_screen_color(void *banner_handle, os_color_t color);
|
||||
|
||||
/* flush output on a banner */
|
||||
void os_banner_flush(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Set the banner's size. The size has the same meaning as in
|
||||
* os_banner_create().
|
||||
*
|
||||
* 'is_advisory' indicates whether the sizing is required or advisory only.
|
||||
* If this flag is false, then the size should be set as requested. If
|
||||
* this flag is true, it means that the caller intends to call
|
||||
* os_banner_size_to_contents() at some point, and that the size being set
|
||||
* now is for advisory purposes only. Platforms that support
|
||||
* size-to-contents may simply ignore advisory sizing requests, although
|
||||
* they might want to ensure that they have sufficient off-screen buffer
|
||||
* space to keep track of the requested size of display, so that the
|
||||
* information the caller displays in preparation for calling
|
||||
* size-to-contents will be retained. Platforms that do not support
|
||||
* size-to-contents should set the requested size even when 'is_advisory'
|
||||
* is true.
|
||||
*/
|
||||
void os_banner_set_size(void *banner_handle, int siz, int siz_units,
|
||||
int is_advisory);
|
||||
|
||||
/*
|
||||
* Set the banner to the size of its current contents. This can be used
|
||||
* to set the banner's size after some text (or other material) has been
|
||||
* displayed to the banner, so that the size can be set according to the
|
||||
* banner's actual space requirements.
|
||||
*
|
||||
* This changes the banner's "requested size" to match the current size.
|
||||
* Subsequent calls to os_banner_getinfo() will thus indicate a requested
|
||||
* size according to the size set here.
|
||||
*/
|
||||
void os_banner_size_to_contents(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Turn HTML mode on/off in the banner window. If the underlying renderer
|
||||
* doesn't support HTML, these have no effect.
|
||||
*/
|
||||
void os_banner_start_html(void *banner_handle);
|
||||
void os_banner_end_html(void *banner_handle);
|
||||
|
||||
/*
|
||||
* Set the output coordinates in a text grid window. The grid window is
|
||||
* arranged into character cells numbered from row zero, column zero for
|
||||
* the upper left cell. This function can only be used if the window was
|
||||
* created with type OS_BANNER_TYPE_TEXTGRID; the request should simply be
|
||||
* ignored by other window types.
|
||||
*
|
||||
* Moving the output position has no immediate effect on the display, and
|
||||
* does not itself affect the "content size" for the purposes of
|
||||
* os_banner_size_to_contents(). This simply sets the coordinates where
|
||||
* any subsequent text is displayed.
|
||||
*/
|
||||
void os_banner_goto(void *banner_handle, int row, int col);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/*
|
||||
* Get system information. 'code' is a SYSINFO_xxx code, which
|
||||
|
||||
@@ -0,0 +1,989 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glk/tads/os_parse.h"
|
||||
#include "glk/glk_types.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
|
||||
#ifdef GLK_MODULE_UNICODE
|
||||
|
||||
enum CHARMAPS { OS_UTF8, OS_CP1251, OS_CP1252, OS_MACROMAN, OS_UNKNOWN };
|
||||
|
||||
static uint os_charmap = OS_UTF8;
|
||||
|
||||
uint is_cyrillic(unsigned char ch)
|
||||
{
|
||||
if (ch >= 0xBC)
|
||||
return 1;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x83:
|
||||
case 0x8A:
|
||||
case 0x8C:
|
||||
case 0x8D:
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
case 0x90:
|
||||
case 0x9A:
|
||||
case 0x9C:
|
||||
case 0x9D:
|
||||
case 0x9E:
|
||||
case 0x9F:
|
||||
case 0xA1:
|
||||
case 0xA2:
|
||||
case 0xA3:
|
||||
case 0xA5:
|
||||
case 0xA8:
|
||||
case 0xAA:
|
||||
case 0xAF:
|
||||
case 0xB2:
|
||||
case 0xB3:
|
||||
case 0xB4:
|
||||
case 0xB8:
|
||||
case 0xBA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint is_macroman (unsigned char ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
/* trademarks */
|
||||
case 0xA8:
|
||||
case 0xAA:
|
||||
return 1;
|
||||
|
||||
/* dashes and right quotes */
|
||||
case 0xD0:
|
||||
case 0xD1:
|
||||
case 0xD3:
|
||||
case 0xD5:
|
||||
return 1;
|
||||
|
||||
/* accents */
|
||||
case 0x8E:
|
||||
case 0x8F:
|
||||
case 0x9A:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint is_cp1252 (unsigned char ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
/* trademarks */
|
||||
case 0x99:
|
||||
case 0xAE:
|
||||
return 1;
|
||||
|
||||
/* dashes and right quotes */
|
||||
case 0x92:
|
||||
case 0x94:
|
||||
case 0x96:
|
||||
case 0x97:
|
||||
return 1;
|
||||
|
||||
/* accents */
|
||||
case 0xE8:
|
||||
case 0xE9:
|
||||
case 0xF6:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint identify_chars(const unsigned char *buf, uint buflen, uint32 *out, uint outlen) {
|
||||
uint pos = 0;
|
||||
uint val = 0;
|
||||
uint count_macroman = 0;
|
||||
uint count_cp1252 = 0;
|
||||
uint wordlen = 0;
|
||||
uint cyrilen = 0;
|
||||
uint charmap = OS_UNKNOWN;
|
||||
|
||||
while (pos < buflen)
|
||||
{
|
||||
val = buf[pos++];
|
||||
|
||||
count_macroman += is_macroman(val);
|
||||
count_cp1252 += is_cp1252(val);
|
||||
|
||||
if (val != 0x20)
|
||||
{
|
||||
wordlen++;
|
||||
cyrilen += is_cyrillic(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wordlen == cyrilen)
|
||||
{
|
||||
charmap = OS_CP1251;
|
||||
break;
|
||||
}
|
||||
wordlen = 0;
|
||||
cyrilen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (charmap == OS_CP1251)
|
||||
os_charmap = OS_CP1251;
|
||||
else if (count_cp1252 >= count_macroman)
|
||||
os_charmap = OS_CP1252;
|
||||
else
|
||||
os_charmap = OS_MACROMAN;
|
||||
|
||||
return os_parse_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
|
||||
uint parse_utf8(const unsigned char *buf, uint buflen, uint32 *out, uint outlen)
|
||||
{
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
uint val0, val1, val2, val3;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
val0 = buf[pos++];
|
||||
|
||||
if (val0 < 0x80)
|
||||
{
|
||||
res = val0;
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((val0 & 0xe0) == 0xc0)
|
||||
{
|
||||
if (pos+1 > buflen)
|
||||
{
|
||||
//printf("incomplete two-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
val1 = buf[pos++];
|
||||
if ((val1 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed two-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
res = (val0 & 0x1f) << 6;
|
||||
res |= (val1 & 0x3f);
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((val0 & 0xf0) == 0xe0)
|
||||
{
|
||||
if (pos+2 > buflen)
|
||||
{
|
||||
//printf("incomplete three-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
val1 = buf[pos++];
|
||||
val2 = buf[pos++];
|
||||
if ((val1 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed three-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
if ((val2 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed three-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
res = (((val0 & 0xf)<<12) & 0x0000f000);
|
||||
res |= (((val1 & 0x3f)<<6) & 0x00000fc0);
|
||||
res |= (((val2 & 0x3f)) & 0x0000003f);
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((val0 & 0xf0) == 0xf0)
|
||||
{
|
||||
if ((val0 & 0xf8) != 0xf0)
|
||||
{
|
||||
//printf("malformed four-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
if (pos+3 > buflen)
|
||||
{
|
||||
//printf("incomplete four-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
val1 = buf[pos++];
|
||||
val2 = buf[pos++];
|
||||
val3 = buf[pos++];
|
||||
if ((val1 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed four-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
if ((val2 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed four-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
if ((val3 & 0xc0) != 0x80)
|
||||
{
|
||||
//printf("malformed four-byte character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
res = (((val0 & 0x7)<<18) & 0x1c0000);
|
||||
res |= (((val1 & 0x3f)<<12) & 0x03f000);
|
||||
res |= (((val2 & 0x3f)<<6) & 0x000fc0);
|
||||
res |= (((val3 & 0x3f)) & 0x00003f);
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
//printf("malformed character\n");
|
||||
return identify_chars(buf, buflen, out, outlen);
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
uint prepare_utf8(const uint32 *buf, uint buflen, unsigned char *out, uint outlen)
|
||||
{
|
||||
uint i=0, k=0;
|
||||
|
||||
/*convert UTF-32 to UTF-8 */
|
||||
while (i < buflen && k < outlen)
|
||||
{
|
||||
if ((buf[i] < 0x80))
|
||||
{
|
||||
out[k] = buf[i];
|
||||
k++;
|
||||
}
|
||||
else if ((buf[i] < 0x800) && (k < outlen - 1))
|
||||
{
|
||||
out[k ] = (0xC0 | ((buf[i] & 0x7C0) >> 6));
|
||||
out[k+1] = (0x80 | (buf[i] & 0x03F) );
|
||||
k = k + 2;
|
||||
}
|
||||
else if ((buf[i] < 0x10000) && (k < outlen - 2))
|
||||
{
|
||||
out[k ] = (0xE0 | ((buf[i] & 0xF000) >> 12));
|
||||
out[k+1] = (0x80 | ((buf[i] & 0x0FC0) >> 6));
|
||||
out[k+2] = (0x80 | (buf[i] & 0x003F) );
|
||||
k = k + 3;
|
||||
}
|
||||
else if ((buf[i] < 0x200000) && (k < outlen - 3))
|
||||
{
|
||||
out[k ] = (0xF0 | ((buf[i] & 0x1C0000) >> 18));
|
||||
out[k+1] = (0x80 | ((buf[i] & 0x03F000) >> 12));
|
||||
out[k+2] = (0x80 | ((buf[i] & 0x000FC0) >> 6));
|
||||
out[k+3] = (0x80 | (buf[i] & 0x00003F) );
|
||||
k = k + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[k] = '?';
|
||||
k++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/* http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT */
|
||||
|
||||
static const uint CP1251ToUnicode[128] = {
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021, 0x20AC, 0x2030,
|
||||
0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F, 0x0452, 0x2018, 0x2019, 0x201C,
|
||||
0x201D, 0x2022, 0x2013, 0x2014, 0x003F, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C,
|
||||
0x045B, 0x045F, 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407, 0x00B0, 0x00B1,
|
||||
0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7, 0x0451, 0x2116, 0x0454, 0x00BB,
|
||||
0x0458, 0x0405, 0x0455, 0x0457, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
|
||||
0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429,
|
||||
0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432, 0x0433,
|
||||
0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D,
|
||||
0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
|
||||
};
|
||||
|
||||
uint parse_cp1251(const unsigned char *buf, uint buflen, uint32 *out, uint outlen) {
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
out[outpos++] = res;
|
||||
else
|
||||
out[outpos++] = CP1251ToUnicode[res - 0x80];
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
uint prepare_cp1251(const uint *buf, uint buflen,
|
||||
unsigned char *out, uint outlen)
|
||||
{
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
{
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case 0x0402: out[outpos++] = 0x80; break;
|
||||
case 0x0403: out[outpos++] = 0x81; break;
|
||||
case 0x201A: out[outpos++] = 0x82; break;
|
||||
case 0x0453: out[outpos++] = 0x83; break;
|
||||
case 0x201E: out[outpos++] = 0x84; break;
|
||||
case 0x2026: out[outpos++] = 0x85; break;
|
||||
case 0x2020: out[outpos++] = 0x86; break;
|
||||
case 0x2021: out[outpos++] = 0x87; break;
|
||||
case 0x20AC: out[outpos++] = 0x88; break;
|
||||
case 0x2030: out[outpos++] = 0x89; break;
|
||||
case 0x0409: out[outpos++] = 0x8A; break;
|
||||
case 0x2039: out[outpos++] = 0x8B; break;
|
||||
case 0x040A: out[outpos++] = 0x8C; break;
|
||||
case 0x040C: out[outpos++] = 0x8D; break;
|
||||
case 0x040B: out[outpos++] = 0x8E; break;
|
||||
case 0x040F: out[outpos++] = 0x8F; break;
|
||||
|
||||
case 0x0452: out[outpos++] = 0x90; break;
|
||||
case 0x2018: out[outpos++] = 0x91; break;
|
||||
case 0x2019: out[outpos++] = 0x92; break;
|
||||
case 0x201C: out[outpos++] = 0x93; break;
|
||||
case 0x201D: out[outpos++] = 0x94; break;
|
||||
case 0x2022: out[outpos++] = 0x95; break;
|
||||
case 0x2013: out[outpos++] = 0x96; break;
|
||||
case 0x2014: out[outpos++] = 0x97; break;
|
||||
case 0x2122: out[outpos++] = 0x99; break;
|
||||
case 0x0459: out[outpos++] = 0x9A; break;
|
||||
case 0x203A: out[outpos++] = 0x9B; break;
|
||||
case 0x045A: out[outpos++] = 0x9C; break;
|
||||
case 0x045C: out[outpos++] = 0x9D; break;
|
||||
case 0x045B: out[outpos++] = 0x9E; break;
|
||||
case 0x045F: out[outpos++] = 0x9F; break;
|
||||
|
||||
case 0x00A0: out[outpos++] = 0xA0; break;
|
||||
case 0x040E: out[outpos++] = 0xA1; break;
|
||||
case 0x045E: out[outpos++] = 0xA2; break;
|
||||
case 0x0408: out[outpos++] = 0xA3; break;
|
||||
case 0x00A4: out[outpos++] = 0xA4; break;
|
||||
case 0x0490: out[outpos++] = 0xA5; break;
|
||||
case 0x00A6: out[outpos++] = 0xA6; break;
|
||||
case 0x00A7: out[outpos++] = 0xA7; break;
|
||||
case 0x0401: out[outpos++] = 0xA8; break;
|
||||
case 0x00A9: out[outpos++] = 0xA9; break;
|
||||
case 0x0404: out[outpos++] = 0xAA; break;
|
||||
case 0x00AB: out[outpos++] = 0xAB; break;
|
||||
case 0x00AC: out[outpos++] = 0xAC; break;
|
||||
case 0x00AD: out[outpos++] = 0xAD; break;
|
||||
case 0x00AE: out[outpos++] = 0xAE; break;
|
||||
case 0x0407: out[outpos++] = 0xAF; break;
|
||||
|
||||
case 0x00B0: out[outpos++] = 0xB0; break;
|
||||
case 0x00B1: out[outpos++] = 0xB1; break;
|
||||
case 0x0406: out[outpos++] = 0xB2; break;
|
||||
case 0x0456: out[outpos++] = 0xB3; break;
|
||||
case 0x0491: out[outpos++] = 0xB4; break;
|
||||
case 0x00B5: out[outpos++] = 0xB5; break;
|
||||
case 0x00B6: out[outpos++] = 0xB6; break;
|
||||
case 0x00B7: out[outpos++] = 0xB7; break;
|
||||
case 0x0451: out[outpos++] = 0xB8; break;
|
||||
case 0x2116: out[outpos++] = 0xB9; break;
|
||||
case 0x0454: out[outpos++] = 0xBA; break;
|
||||
case 0x00BB: out[outpos++] = 0xBB; break;
|
||||
case 0x0458: out[outpos++] = 0xBC; break;
|
||||
case 0x0405: out[outpos++] = 0xBD; break;
|
||||
case 0x0455: out[outpos++] = 0xBE; break;
|
||||
case 0x0457: out[outpos++] = 0xBF; break;
|
||||
|
||||
case 0x0410: out[outpos++] = 0xC0; break;
|
||||
case 0x0411: out[outpos++] = 0xC1; break;
|
||||
case 0x0412: out[outpos++] = 0xC2; break;
|
||||
case 0x0413: out[outpos++] = 0xC3; break;
|
||||
case 0x0414: out[outpos++] = 0xC4; break;
|
||||
case 0x0415: out[outpos++] = 0xC5; break;
|
||||
case 0x0416: out[outpos++] = 0xC6; break;
|
||||
case 0x0417: out[outpos++] = 0xC7; break;
|
||||
case 0x0418: out[outpos++] = 0xC8; break;
|
||||
case 0x0419: out[outpos++] = 0xC9; break;
|
||||
case 0x041A: out[outpos++] = 0xCA; break;
|
||||
case 0x041B: out[outpos++] = 0xCB; break;
|
||||
case 0x041C: out[outpos++] = 0xCC; break;
|
||||
case 0x041D: out[outpos++] = 0xCD; break;
|
||||
case 0x041E: out[outpos++] = 0xCE; break;
|
||||
case 0x041F: out[outpos++] = 0xCF; break;
|
||||
|
||||
case 0x0420: out[outpos++] = 0xD0; break;
|
||||
case 0x0421: out[outpos++] = 0xD1; break;
|
||||
case 0x0422: out[outpos++] = 0xD2; break;
|
||||
case 0x0423: out[outpos++] = 0xD3; break;
|
||||
case 0x0424: out[outpos++] = 0xD4; break;
|
||||
case 0x0425: out[outpos++] = 0xD5; break;
|
||||
case 0x0426: out[outpos++] = 0xD6; break;
|
||||
case 0x0427: out[outpos++] = 0xD7; break;
|
||||
case 0x0428: out[outpos++] = 0xD8; break;
|
||||
case 0x0429: out[outpos++] = 0xD9; break;
|
||||
case 0x042A: out[outpos++] = 0xDA; break;
|
||||
case 0x042B: out[outpos++] = 0xDB; break;
|
||||
case 0x042C: out[outpos++] = 0xDC; break;
|
||||
case 0x042D: out[outpos++] = 0xDD; break;
|
||||
case 0x042E: out[outpos++] = 0xDE; break;
|
||||
case 0x042F: out[outpos++] = 0xDF; break;
|
||||
|
||||
case 0x0430: out[outpos++] = 0xE0; break;
|
||||
case 0x0431: out[outpos++] = 0xE1; break;
|
||||
case 0x0432: out[outpos++] = 0xE2; break;
|
||||
case 0x0433: out[outpos++] = 0xE3; break;
|
||||
case 0x0434: out[outpos++] = 0xE4; break;
|
||||
case 0x0435: out[outpos++] = 0xE5; break;
|
||||
case 0x0436: out[outpos++] = 0xE6; break;
|
||||
case 0x0437: out[outpos++] = 0xE7; break;
|
||||
case 0x0438: out[outpos++] = 0xE8; break;
|
||||
case 0x0439: out[outpos++] = 0xE9; break;
|
||||
case 0x043A: out[outpos++] = 0xEA; break;
|
||||
case 0x043B: out[outpos++] = 0xEB; break;
|
||||
case 0x043C: out[outpos++] = 0xEC; break;
|
||||
case 0x043D: out[outpos++] = 0xED; break;
|
||||
case 0x043E: out[outpos++] = 0xEE; break;
|
||||
case 0x043F: out[outpos++] = 0xEF; break;
|
||||
|
||||
case 0x0440: out[outpos++] = 0xF0; break;
|
||||
case 0x0441: out[outpos++] = 0xF1; break;
|
||||
case 0x0442: out[outpos++] = 0xF2; break;
|
||||
case 0x0443: out[outpos++] = 0xF3; break;
|
||||
case 0x0444: out[outpos++] = 0xF4; break;
|
||||
case 0x0445: out[outpos++] = 0xF5; break;
|
||||
case 0x0446: out[outpos++] = 0xF6; break;
|
||||
case 0x0447: out[outpos++] = 0xF7; break;
|
||||
case 0x0448: out[outpos++] = 0xF8; break;
|
||||
case 0x0449: out[outpos++] = 0xF9; break;
|
||||
case 0x044A: out[outpos++] = 0xFA; break;
|
||||
case 0x044B: out[outpos++] = 0xFB; break;
|
||||
case 0x044C: out[outpos++] = 0xFC; break;
|
||||
case 0x044D: out[outpos++] = 0xFD; break;
|
||||
case 0x044E: out[outpos++] = 0xFE; break;
|
||||
case 0x044F: out[outpos++] = 0xFF; break;
|
||||
|
||||
default:
|
||||
/* undefined */
|
||||
out[outpos++] = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
/* http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT */
|
||||
|
||||
static const uint CP1252ToUnicode[128] = {
|
||||
0x20AC, 0x003F, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030,
|
||||
0x0160, 0x2039, 0x0152, 0x003F, 0x017D, 0x003F, 0x003F, 0x2018, 0x2019, 0x201C,
|
||||
0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x003F,
|
||||
0x017E, 0x0178, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1,
|
||||
0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB,
|
||||
0x00BC, 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5,
|
||||
0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9,
|
||||
0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3,
|
||||
0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED,
|
||||
0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
uint parse_cp1252(const unsigned char *buf, uint buflen, uint32 *out, uint outlen) {
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
out[outpos++] = res;
|
||||
else
|
||||
out[outpos++] = CP1252ToUnicode[res - 0x80];
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
uint prepare_cp1252(const uint *buf, uint buflen,
|
||||
unsigned char *out, uint outlen)
|
||||
{
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
{
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case 0x20AC: out[outpos++] = 0x80; break;
|
||||
case 0x201A: out[outpos++] = 0x82; break;
|
||||
case 0x0192: out[outpos++] = 0x83; break;
|
||||
case 0x201E: out[outpos++] = 0x84; break;
|
||||
case 0x2026: out[outpos++] = 0x85; break;
|
||||
case 0x2020: out[outpos++] = 0x86; break;
|
||||
case 0x2021: out[outpos++] = 0x87; break;
|
||||
case 0x02C6: out[outpos++] = 0x88; break;
|
||||
case 0x2030: out[outpos++] = 0x89; break;
|
||||
case 0x0160: out[outpos++] = 0x8A; break;
|
||||
case 0x2039: out[outpos++] = 0x8B; break;
|
||||
case 0x0152: out[outpos++] = 0x8C; break;
|
||||
case 0x017D: out[outpos++] = 0x8E; break;
|
||||
|
||||
case 0x2018: out[outpos++] = 0x91; break;
|
||||
case 0x2019: out[outpos++] = 0x92; break;
|
||||
case 0x201C: out[outpos++] = 0x93; break;
|
||||
case 0x201D: out[outpos++] = 0x94; break;
|
||||
case 0x2022: out[outpos++] = 0x95; break;
|
||||
case 0x2013: out[outpos++] = 0x96; break;
|
||||
case 0x2014: out[outpos++] = 0x97; break;
|
||||
case 0x02DC: out[outpos++] = 0x98; break;
|
||||
case 0x2122: out[outpos++] = 0x99; break;
|
||||
case 0x0161: out[outpos++] = 0x9A; break;
|
||||
case 0x203A: out[outpos++] = 0x9B; break;
|
||||
case 0x0153: out[outpos++] = 0x9C; break;
|
||||
case 0x017E: out[outpos++] = 0x9E; break;
|
||||
case 0x0178: out[outpos++] = 0x9F; break;
|
||||
|
||||
case 0x00A0: out[outpos++] = 0xA0; break;
|
||||
case 0x00A1: out[outpos++] = 0xA1; break;
|
||||
case 0x00A2: out[outpos++] = 0xA2; break;
|
||||
case 0x00A3: out[outpos++] = 0xA3; break;
|
||||
case 0x00A4: out[outpos++] = 0xA4; break;
|
||||
case 0x00A5: out[outpos++] = 0xA5; break;
|
||||
case 0x00A6: out[outpos++] = 0xA6; break;
|
||||
case 0x00A7: out[outpos++] = 0xA7; break;
|
||||
case 0x00A8: out[outpos++] = 0xA8; break;
|
||||
case 0x00A9: out[outpos++] = 0xA9; break;
|
||||
case 0x00AA: out[outpos++] = 0xAA; break;
|
||||
case 0x00AB: out[outpos++] = 0xAB; break;
|
||||
case 0x00AC: out[outpos++] = 0xAC; break;
|
||||
case 0x00AD: out[outpos++] = 0xAD; break;
|
||||
case 0x00AE: out[outpos++] = 0xAE; break;
|
||||
case 0x00AF: out[outpos++] = 0xAF; break;
|
||||
|
||||
case 0x00B0: out[outpos++] = 0xB0; break;
|
||||
case 0x00B1: out[outpos++] = 0xB1; break;
|
||||
case 0x00B2: out[outpos++] = 0xB2; break;
|
||||
case 0x00B3: out[outpos++] = 0xB3; break;
|
||||
case 0x00B4: out[outpos++] = 0xB4; break;
|
||||
case 0x00B5: out[outpos++] = 0xB5; break;
|
||||
case 0x00B6: out[outpos++] = 0xB6; break;
|
||||
case 0x00B7: out[outpos++] = 0xB7; break;
|
||||
case 0x00B8: out[outpos++] = 0xB8; break;
|
||||
case 0x00B9: out[outpos++] = 0xB9; break;
|
||||
case 0x00BA: out[outpos++] = 0xBA; break;
|
||||
case 0x00BB: out[outpos++] = 0xBB; break;
|
||||
case 0x00BC: out[outpos++] = 0xBC; break;
|
||||
case 0x00BD: out[outpos++] = 0xBD; break;
|
||||
case 0x00BE: out[outpos++] = 0xBE; break;
|
||||
case 0x00BF: out[outpos++] = 0xBF; break;
|
||||
|
||||
case 0x00C0: out[outpos++] = 0xC0; break;
|
||||
case 0x00C1: out[outpos++] = 0xC1; break;
|
||||
case 0x00C2: out[outpos++] = 0xC2; break;
|
||||
case 0x00C3: out[outpos++] = 0xC3; break;
|
||||
case 0x00C4: out[outpos++] = 0xC4; break;
|
||||
case 0x00C5: out[outpos++] = 0xC5; break;
|
||||
case 0x00C6: out[outpos++] = 0xC6; break;
|
||||
case 0x00C7: out[outpos++] = 0xC7; break;
|
||||
case 0x00C8: out[outpos++] = 0xC8; break;
|
||||
case 0x00C9: out[outpos++] = 0xC9; break;
|
||||
case 0x00CA: out[outpos++] = 0xCA; break;
|
||||
case 0x00CB: out[outpos++] = 0xCB; break;
|
||||
case 0x00CC: out[outpos++] = 0xCC; break;
|
||||
case 0x00CD: out[outpos++] = 0xCD; break;
|
||||
case 0x00CE: out[outpos++] = 0xCE; break;
|
||||
case 0x00CF: out[outpos++] = 0xCF; break;
|
||||
|
||||
case 0x00D0: out[outpos++] = 0xD0; break;
|
||||
case 0x00D1: out[outpos++] = 0xD1; break;
|
||||
case 0x00D2: out[outpos++] = 0xD2; break;
|
||||
case 0x00D3: out[outpos++] = 0xD3; break;
|
||||
case 0x00D4: out[outpos++] = 0xD4; break;
|
||||
case 0x00D5: out[outpos++] = 0xD5; break;
|
||||
case 0x00D6: out[outpos++] = 0xD6; break;
|
||||
case 0x00D7: out[outpos++] = 0xD7; break;
|
||||
case 0x00D8: out[outpos++] = 0xD8; break;
|
||||
case 0x00D9: out[outpos++] = 0xD9; break;
|
||||
case 0x00DA: out[outpos++] = 0xDA; break;
|
||||
case 0x00DB: out[outpos++] = 0xDB; break;
|
||||
case 0x00DC: out[outpos++] = 0xDC; break;
|
||||
case 0x00DD: out[outpos++] = 0xDD; break;
|
||||
case 0x00DE: out[outpos++] = 0xDE; break;
|
||||
case 0x00DF: out[outpos++] = 0xDF; break;
|
||||
|
||||
case 0x00E0: out[outpos++] = 0xE0; break;
|
||||
case 0x00E1: out[outpos++] = 0xE1; break;
|
||||
case 0x00E2: out[outpos++] = 0xE2; break;
|
||||
case 0x00E3: out[outpos++] = 0xE3; break;
|
||||
case 0x00E4: out[outpos++] = 0xE4; break;
|
||||
case 0x00E5: out[outpos++] = 0xE5; break;
|
||||
case 0x00E6: out[outpos++] = 0xE6; break;
|
||||
case 0x00E7: out[outpos++] = 0xE7; break;
|
||||
case 0x00E8: out[outpos++] = 0xE8; break;
|
||||
case 0x00E9: out[outpos++] = 0xE9; break;
|
||||
case 0x00EA: out[outpos++] = 0xEA; break;
|
||||
case 0x00EB: out[outpos++] = 0xEB; break;
|
||||
case 0x00EC: out[outpos++] = 0xEC; break;
|
||||
case 0x00ED: out[outpos++] = 0xED; break;
|
||||
case 0x00EE: out[outpos++] = 0xEE; break;
|
||||
case 0x00EF: out[outpos++] = 0xEF; break;
|
||||
|
||||
case 0x00F0: out[outpos++] = 0xF0; break;
|
||||
case 0x00F1: out[outpos++] = 0xF1; break;
|
||||
case 0x00F2: out[outpos++] = 0xF2; break;
|
||||
case 0x00F3: out[outpos++] = 0xF3; break;
|
||||
case 0x00F4: out[outpos++] = 0xF4; break;
|
||||
case 0x00F5: out[outpos++] = 0xF5; break;
|
||||
case 0x00F6: out[outpos++] = 0xF6; break;
|
||||
case 0x00F7: out[outpos++] = 0xF7; break;
|
||||
case 0x00F8: out[outpos++] = 0xF8; break;
|
||||
case 0x00F9: out[outpos++] = 0xF9; break;
|
||||
case 0x00FA: out[outpos++] = 0xFA; break;
|
||||
case 0x00FB: out[outpos++] = 0xFB; break;
|
||||
case 0x00FC: out[outpos++] = 0xFC; break;
|
||||
case 0x00FD: out[outpos++] = 0xFD; break;
|
||||
case 0x00FE: out[outpos++] = 0xFE; break;
|
||||
case 0x00FF: out[outpos++] = 0xFF; break;
|
||||
|
||||
default:
|
||||
/* undefined */
|
||||
out[outpos++] = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
/* http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT */
|
||||
|
||||
static const uint MacRomanToUnicode[128] = {
|
||||
0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1, 0x00E0, 0x00E2,
|
||||
0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8, 0x00EA, 0x00EB, 0x00ED, 0x00EC,
|
||||
0x00EE, 0x00EF, 0x00F1, 0x00F3, 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9,
|
||||
0x00FB, 0x00FC, 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
|
||||
0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8, 0x221E, 0x00B1,
|
||||
0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211, 0x220F, 0x03C0, 0x222B, 0x00AA,
|
||||
0x00BA, 0x03A9, 0x00E6, 0x00F8, 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248,
|
||||
0x2206, 0x00AB, 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
|
||||
0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA, 0x00FF, 0x0178,
|
||||
0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02, 0x2021, 0x00B7, 0x201A, 0x201E,
|
||||
0x2030, 0x00C2, 0x00CA, 0x00C1, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC,
|
||||
0x00D3, 0x00D4, 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
|
||||
0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7
|
||||
};
|
||||
|
||||
uint parse_mac(const unsigned char *buf, uint buflen, uint32 *out, uint outlen) {
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
out[outpos++] = res;
|
||||
else
|
||||
out[outpos++] = MacRomanToUnicode[res - 0x80];
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
uint prepare_mac(const uint *buf, uint buflen, unsigned char *out, uint outlen) {
|
||||
uint pos = 0;
|
||||
uint outpos = 0;
|
||||
uint res;
|
||||
|
||||
while (outpos < outlen)
|
||||
{
|
||||
if (pos >= buflen)
|
||||
break;
|
||||
|
||||
res = buf[pos++];
|
||||
|
||||
if (res < 0x80)
|
||||
{
|
||||
out[outpos++] = res;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (res)
|
||||
{
|
||||
case 0x00C4: out[outpos++] = 0x80; break;
|
||||
case 0x00C5: out[outpos++] = 0x81; break;
|
||||
case 0x00C7: out[outpos++] = 0x82; break;
|
||||
case 0x00C9: out[outpos++] = 0x83; break;
|
||||
case 0x00D1: out[outpos++] = 0x84; break;
|
||||
case 0x00D6: out[outpos++] = 0x85; break;
|
||||
case 0x00DC: out[outpos++] = 0x86; break;
|
||||
case 0x00E1: out[outpos++] = 0x87; break;
|
||||
case 0x00E0: out[outpos++] = 0x88; break;
|
||||
case 0x00E2: out[outpos++] = 0x89; break;
|
||||
case 0x00E4: out[outpos++] = 0x8A; break;
|
||||
case 0x00E3: out[outpos++] = 0x8B; break;
|
||||
case 0x00E5: out[outpos++] = 0x8C; break;
|
||||
case 0x00E7: out[outpos++] = 0x8D; break;
|
||||
case 0x00E9: out[outpos++] = 0x8E; break;
|
||||
case 0x00E8: out[outpos++] = 0x8F; break;
|
||||
|
||||
case 0x00EA: out[outpos++] = 0x90; break;
|
||||
case 0x00EB: out[outpos++] = 0x91; break;
|
||||
case 0x00ED: out[outpos++] = 0x92; break;
|
||||
case 0x00EC: out[outpos++] = 0x93; break;
|
||||
case 0x00EE: out[outpos++] = 0x94; break;
|
||||
case 0x00EF: out[outpos++] = 0x95; break;
|
||||
case 0x00F1: out[outpos++] = 0x96; break;
|
||||
case 0x00F3: out[outpos++] = 0x97; break;
|
||||
case 0x00F2: out[outpos++] = 0x98; break;
|
||||
case 0x00F4: out[outpos++] = 0x99; break;
|
||||
case 0x00F6: out[outpos++] = 0x9A; break;
|
||||
case 0x00F5: out[outpos++] = 0x9B; break;
|
||||
case 0x00FA: out[outpos++] = 0x9C; break;
|
||||
case 0x00F9: out[outpos++] = 0x9D; break;
|
||||
case 0x00FB: out[outpos++] = 0x9E; break;
|
||||
case 0x00FC: out[outpos++] = 0x9F; break;
|
||||
|
||||
case 0x2020: out[outpos++] = 0xA0; break;
|
||||
case 0x00B0: out[outpos++] = 0xA1; break;
|
||||
case 0x00A2: out[outpos++] = 0xA2; break;
|
||||
case 0x00A3: out[outpos++] = 0xA3; break;
|
||||
case 0x00A7: out[outpos++] = 0xA4; break;
|
||||
case 0x2022: out[outpos++] = 0xA5; break;
|
||||
case 0x00B6: out[outpos++] = 0xA6; break;
|
||||
case 0x00DF: out[outpos++] = 0xA7; break;
|
||||
case 0x00AE: out[outpos++] = 0xA8; break;
|
||||
case 0x00A9: out[outpos++] = 0xA9; break;
|
||||
case 0x2122: out[outpos++] = 0xAA; break;
|
||||
case 0x00B4: out[outpos++] = 0xAB; break;
|
||||
case 0x00A8: out[outpos++] = 0xAC; break;
|
||||
case 0x2260: out[outpos++] = 0xAD; break;
|
||||
case 0x00C6: out[outpos++] = 0xAE; break;
|
||||
case 0x00D8: out[outpos++] = 0xAF; break;
|
||||
|
||||
case 0x221E: out[outpos++] = 0xB0; break;
|
||||
case 0x00B1: out[outpos++] = 0xB1; break;
|
||||
case 0x2264: out[outpos++] = 0xB2; break;
|
||||
case 0x2265: out[outpos++] = 0xB3; break;
|
||||
case 0x00A5: out[outpos++] = 0xB4; break;
|
||||
case 0x00B5: out[outpos++] = 0xB5; break;
|
||||
case 0x2202: out[outpos++] = 0xB6; break;
|
||||
case 0x2211: out[outpos++] = 0xB7; break;
|
||||
case 0x220F: out[outpos++] = 0xB8; break;
|
||||
case 0x03C0: out[outpos++] = 0xB9; break;
|
||||
case 0x222B: out[outpos++] = 0xBA; break;
|
||||
case 0x00AA: out[outpos++] = 0xBB; break;
|
||||
case 0x00BA: out[outpos++] = 0xBC; break;
|
||||
case 0x03A9: out[outpos++] = 0xBD; break;
|
||||
case 0x00E6: out[outpos++] = 0xBE; break;
|
||||
case 0x00F8: out[outpos++] = 0xBF; break;
|
||||
|
||||
case 0x00BF: out[outpos++] = 0xC0; break;
|
||||
case 0x00A1: out[outpos++] = 0xC1; break;
|
||||
case 0x00AC: out[outpos++] = 0xC2; break;
|
||||
case 0x221A: out[outpos++] = 0xC3; break;
|
||||
case 0x0192: out[outpos++] = 0xC4; break;
|
||||
case 0x2248: out[outpos++] = 0xC5; break;
|
||||
case 0x2206: out[outpos++] = 0xC6; break;
|
||||
case 0x00AB: out[outpos++] = 0xC7; break;
|
||||
case 0x00BB: out[outpos++] = 0xC8; break;
|
||||
case 0x2026: out[outpos++] = 0xC9; break;
|
||||
case 0x00A0: out[outpos++] = 0xCA; break;
|
||||
case 0x00C0: out[outpos++] = 0xCB; break;
|
||||
case 0x00C3: out[outpos++] = 0xCC; break;
|
||||
case 0x00D5: out[outpos++] = 0xCD; break;
|
||||
case 0x0152: out[outpos++] = 0xCE; break;
|
||||
case 0x0153: out[outpos++] = 0xCF; break;
|
||||
|
||||
case 0x2013: out[outpos++] = 0xD0; break;
|
||||
case 0x2014: out[outpos++] = 0xD1; break;
|
||||
case 0x201C: out[outpos++] = 0xD2; break;
|
||||
case 0x201D: out[outpos++] = 0xD3; break;
|
||||
case 0x2018: out[outpos++] = 0xD4; break;
|
||||
case 0x2019: out[outpos++] = 0xD5; break;
|
||||
case 0x00F7: out[outpos++] = 0xD6; break;
|
||||
case 0x25CA: out[outpos++] = 0xD7; break;
|
||||
case 0x00FF: out[outpos++] = 0xD8; break;
|
||||
case 0x0178: out[outpos++] = 0xD9; break;
|
||||
case 0x2044: out[outpos++] = 0xDA; break;
|
||||
case 0x20AC: out[outpos++] = 0xDB; break;
|
||||
case 0x2039: out[outpos++] = 0xDC; break;
|
||||
case 0x203A: out[outpos++] = 0xDD; break;
|
||||
case 0xFB01: out[outpos++] = 0xDE; break;
|
||||
case 0xFB02: out[outpos++] = 0xDF; break;
|
||||
|
||||
case 0x2021: out[outpos++] = 0xE0; break;
|
||||
case 0x00B7: out[outpos++] = 0xE1; break;
|
||||
case 0x201A: out[outpos++] = 0xE2; break;
|
||||
case 0x201E: out[outpos++] = 0xE3; break;
|
||||
case 0x2030: out[outpos++] = 0xE4; break;
|
||||
case 0x00C2: out[outpos++] = 0xE5; break;
|
||||
case 0x00CA: out[outpos++] = 0xE6; break;
|
||||
case 0x00C1: out[outpos++] = 0xE7; break;
|
||||
case 0x00CB: out[outpos++] = 0xE8; break;
|
||||
case 0x00C8: out[outpos++] = 0xE9; break;
|
||||
case 0x00CD: out[outpos++] = 0xEA; break;
|
||||
case 0x00CE: out[outpos++] = 0xEB; break;
|
||||
case 0x00CF: out[outpos++] = 0xEC; break;
|
||||
case 0x00CC: out[outpos++] = 0xED; break;
|
||||
case 0x00D3: out[outpos++] = 0xEE; break;
|
||||
case 0x00D4: out[outpos++] = 0xEF; break;
|
||||
|
||||
case 0xF8FF: out[outpos++] = 0xF0; break;
|
||||
case 0x00D2: out[outpos++] = 0xF1; break;
|
||||
case 0x00DA: out[outpos++] = 0xF2; break;
|
||||
case 0x00DB: out[outpos++] = 0xF3; break;
|
||||
case 0x00D9: out[outpos++] = 0xF4; break;
|
||||
case 0x0131: out[outpos++] = 0xF5; break;
|
||||
case 0x02C6: out[outpos++] = 0xF6; break;
|
||||
case 0x02DC: out[outpos++] = 0xF7; break;
|
||||
case 0x00AF: out[outpos++] = 0xF8; break;
|
||||
case 0x02D8: out[outpos++] = 0xF9; break;
|
||||
case 0x02D9: out[outpos++] = 0xFA; break;
|
||||
case 0x02DA: out[outpos++] = 0xFB; break;
|
||||
case 0x00B8: out[outpos++] = 0xFC; break;
|
||||
case 0x02DD: out[outpos++] = 0xFD; break;
|
||||
case 0x02DB: out[outpos++] = 0xFE; break;
|
||||
case 0x02C7: out[outpos++] = 0xFF; break;
|
||||
|
||||
default:
|
||||
/* undefined */
|
||||
out[outpos++] = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return outpos;
|
||||
}
|
||||
|
||||
uint os_parse_chars(const unsigned char *buf, uint buflen, uint32 *out, uint outlen) {
|
||||
switch (os_charmap)
|
||||
{
|
||||
case OS_UTF8:
|
||||
return parse_utf8(buf, buflen, out, outlen);
|
||||
|
||||
case OS_CP1251:
|
||||
return parse_cp1251(buf, buflen, out, outlen);
|
||||
|
||||
case OS_CP1252:
|
||||
return parse_cp1252(buf, buflen, out, outlen);
|
||||
|
||||
case OS_MACROMAN:
|
||||
return parse_mac(buf, buflen, out, outlen);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint os_prepare_chars(const uint32 *buf, uint buflen, unsigned char *out, uint outlen) {
|
||||
switch (os_charmap) {
|
||||
case OS_UTF8:
|
||||
return prepare_utf8(buf, buflen, out, outlen);
|
||||
|
||||
case OS_CP1251:
|
||||
return prepare_cp1251(buf, buflen, out, outlen);
|
||||
|
||||
case OS_CP1252:
|
||||
return prepare_cp1252(buf, buflen, out, outlen);
|
||||
|
||||
case OS_MACROMAN:
|
||||
return prepare_mac(buf, buflen, out, outlen);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GLK_MODULE_UNICODE */
|
||||
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
@@ -0,0 +1,43 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/* TADS OS interface file type definitions
|
||||
*
|
||||
* Defines certain datatypes used in the TADS operating system interface
|
||||
*/
|
||||
|
||||
#ifndef GLK_TADS_OS_PARSE
|
||||
#define GLK_TADS_OS_PARSE
|
||||
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
|
||||
extern uint os_parse_chars(const unsigned char *buf, uint buflen, uint32 *out, uint outlen);
|
||||
|
||||
extern uint os_prepare_chars(const uint32 *buf, uint buflen, unsigned char *out, uint outlen);
|
||||
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
#endif
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "glk/tads/tads2/lib.h"
|
||||
#include "glk/tads/tads2/object.h"
|
||||
#include "glk/tads/os_glk.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
@@ -181,7 +182,7 @@ void dbgclin(struct tokcxdef *tokctx, objnum objn, uint ofs);
|
||||
* the program define the appropriate implementation through the linker.
|
||||
*/
|
||||
#ifdef DBG_OFF
|
||||
#define dbgpresent() (FALSE)
|
||||
#define dbgpresent() (false)
|
||||
#else
|
||||
int dbgpresent();
|
||||
#endif
|
||||
@@ -545,22 +546,22 @@ void trcsho(void);
|
||||
*/
|
||||
|
||||
#ifdef DBG_OFF
|
||||
# define dbgenter(ctx, bp, self, target, prop, binum, argc)
|
||||
# define dbgleave(ctx, exittype)
|
||||
# define dbgdump(ctx)
|
||||
# define dbgrst(ctx) ((void)0)
|
||||
# define dbgframe(ctx, frofs, linofs)
|
||||
# define dbgssi(ctx, ofs, instr, err, p)
|
||||
#define dbgenter(ctx, bp, self, target, prop, binum, argc)
|
||||
#define dbgleave(ctx, exittype)
|
||||
#define dbgdump(ctx) ((void)0)
|
||||
#define dbgrst(ctx) ((void)0)
|
||||
#define dbgframe(ctx, frofs, linofs)
|
||||
#define dbgssi(ctx, ofs, instr, err, p) ((void)0)
|
||||
#else /* DBG_OFF */
|
||||
# define dbgenter(ctx, bp, self, target, prop, binum, argc) \
|
||||
#define dbgenter(ctx, bp, self, target, prop, binum, argc) \
|
||||
dbgent(ctx, bp, self, target, prop, binum, argc)
|
||||
# define dbgleave(ctx, exittype) dbglv(ctx, exittype)
|
||||
# define dbgdump(ctx) dbgds(ctx)
|
||||
# define dbgrst(ctx) ((ctx)->dbgcxfcn = (ctx)->dbgcxdep = 0)
|
||||
# define dbgframe(ctx, frofs, linofs) \
|
||||
#define dbgleave(ctx, exittype) dbglv(ctx, exittype)
|
||||
#define dbgdump(ctx) dbgds(ctx)
|
||||
#define dbgrst(ctx) ((ctx)->dbgcxfcn = (ctx)->dbgcxdep = 0)
|
||||
#define dbgframe(ctx, frofs, linofs) \
|
||||
(((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgffr = (frofs)), \
|
||||
((ctx)->dbgcxfrm[(ctx)->dbgcxfcn - 1].dbgflin = (linofs)))
|
||||
# define dbgssi(ctx, ofs, instr, err, p) dbgss(ctx, ofs, instr, err, p)
|
||||
#define dbgssi(ctx, ofs, instr, err, p) dbgss(ctx, ofs, instr, err, p)
|
||||
#endif /* DBG_OFF */
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
@@ -27,58 +27,42 @@ namespace Glk {
|
||||
namespace TADS {
|
||||
namespace TADS2 {
|
||||
|
||||
|
||||
/*--------------------------------- lerini ---------------------------------*/
|
||||
/*
|
||||
* lerini - allocate and initialize an error context. Returns a
|
||||
* pointer to an initialized error context if successful, 0 otherwise.
|
||||
*/
|
||||
errcxdef *lerini() {
|
||||
errcxdef *errcx; /* error context */
|
||||
errcxdef *errcx; /* error context */
|
||||
|
||||
/* allocate an error context */
|
||||
if (!(errcx = (errcxdef *)ltk_suballoc(sizeof(errcxdef))))
|
||||
{
|
||||
/* failure */
|
||||
return((errcxdef *)0);
|
||||
}
|
||||
// allocate an error context
|
||||
if (!(errcx = (errcxdef *)ltk_suballoc(sizeof(errcxdef)))) {
|
||||
// failure
|
||||
return((errcxdef *)0);
|
||||
}
|
||||
|
||||
/* initialize the error context */
|
||||
errcx->errcxfp = (osfildef *)0; /* no error file handle */
|
||||
errcx->errcxofs = 0; /* no offset in argument buffer */
|
||||
errcx->errcxlog = ltk_errlog; /* error logging routine */
|
||||
errcx->errcxlgc = errcx; /* error logging context */
|
||||
// initialize the error context
|
||||
errcx->errcxfp = (osfildef *)0; /* no error file handle */
|
||||
errcx->errcxofs = 0; /* no offset in argument buffer */
|
||||
errcx->errcxlog = ltk_errlog; /* error logging routine */
|
||||
errcx->errcxlgc = errcx; /* error logging context */
|
||||
|
||||
/* return the new context */
|
||||
return(errcx);
|
||||
// return the new context
|
||||
return errcx;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------- lerfre ---------------------------------*/
|
||||
/*
|
||||
* lerfre - FREe error context allocated by errini.
|
||||
*/
|
||||
void lerfre(errcxdef *errcx) {
|
||||
/* free the context */
|
||||
ltk_subfree(errcx);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------- errmsg ---------------------------------*/
|
||||
/*
|
||||
* errmsg - format error message number 'err' into the given buffer.
|
||||
*/
|
||||
void errmsg(errcxdef *ctx, char *outbuf, int outbufl, uint err) {
|
||||
sprintf(outbuf, "Error #%d occured.", err);
|
||||
}
|
||||
|
||||
/*--------------------------------- errini ---------------------------------*/
|
||||
/*
|
||||
* errini - initialize error system.
|
||||
*/
|
||||
void errini(errcxdef *ctx, char *arg0) {
|
||||
VARUSED(ctx);
|
||||
VARUSED(arg0);
|
||||
VARUSED(ctx);
|
||||
VARUSED(arg0);
|
||||
}
|
||||
|
||||
void errini(errcxdef *ctx, osfildef *fp) {
|
||||
VARUSED(ctx);
|
||||
VARUSED(fp);
|
||||
}
|
||||
|
||||
void lerfre(errcxdef *errcx) {
|
||||
// free the context
|
||||
ltk_subfree(errcx);
|
||||
}
|
||||
|
||||
void errmsg(errcxdef *ctx, char *outbuf, uint outbufl, uint err) {
|
||||
sprintf(outbuf, "Error #%d occured.", err);
|
||||
}
|
||||
|
||||
} // End of namespace TADS2
|
||||
|
||||
@@ -1769,6 +1769,12 @@ ret_error:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fioxor(uchar *p, uint siz, uint seed, uint inc)
|
||||
{
|
||||
for (; siz; seed += inc, --siz)
|
||||
*p++ ^= (uchar)seed;
|
||||
}
|
||||
|
||||
} // End of namespace TADS2
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glk/tads/tads2/character_map.h"
|
||||
#include "glk/tads/tads2/text_io.h"
|
||||
#include "glk/tads/tads2/os.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace TADS {
|
||||
namespace TADS2 {
|
||||
|
||||
|
||||
/*
|
||||
* Global variable with the current command logging file. If this is
|
||||
* not null, we'll log each command that we read to this file.
|
||||
*/
|
||||
osfildef *cmdfile;
|
||||
|
||||
/*
|
||||
* External global with the current script input file. If this is
|
||||
* non-null, we'll read commands from this file rather than from the
|
||||
* keyboard.
|
||||
*/
|
||||
extern osfildef *scrfp;
|
||||
|
||||
/*
|
||||
* External global indicating script echo status. If we're reading from
|
||||
* a script input file (i.e., scrfp is non-null), and this variable is
|
||||
* true, it indicates that we're in "quiet" mode reading the script, so
|
||||
* we will not echo commands that we read from the script file to the
|
||||
* display.
|
||||
*/
|
||||
extern int scrquiet;
|
||||
|
||||
/*
|
||||
* getstring reads a string from the keyboard, doing all necessary
|
||||
* output flushing. Prompting is to be done by the caller. This
|
||||
* routine should be called instead of os_gets.
|
||||
*/
|
||||
int getstring(char *prompt, char *buf, int bufl)
|
||||
{
|
||||
char *result;
|
||||
int savemoremode;
|
||||
int retval = 0;
|
||||
|
||||
/* show prompt if one was given and flush output */
|
||||
savemoremode = setmore(0);
|
||||
if (prompt != 0)
|
||||
{
|
||||
/* display the prompt text */
|
||||
outformat(prompt);
|
||||
|
||||
/* make sure it shows up in the log file as well */
|
||||
out_logfile_print(prompt, FALSE);
|
||||
}
|
||||
outflushn(0);
|
||||
outreset();
|
||||
|
||||
/* read from the command input file if we have one */
|
||||
if (scrfp != 0)
|
||||
{
|
||||
int quiet = scrquiet;
|
||||
|
||||
/* try reading from command input file */
|
||||
if ((result = qasgets(buf, bufl)) == 0)
|
||||
{
|
||||
/*
|
||||
* End of command input file; return to reading the
|
||||
* keyboard. If we didn't already show the prompt, show it
|
||||
* now.
|
||||
*
|
||||
* Note that qasgets() will have closed the script file
|
||||
* before returning eof, so we won't directly read the
|
||||
* command here but instead handle it later when we check to
|
||||
* see if we need to read from the keyboard.
|
||||
*/
|
||||
if (quiet && prompt != 0)
|
||||
outformat(prompt);
|
||||
outflushn(0);
|
||||
outreset();
|
||||
|
||||
/*
|
||||
* Guarantee that moremode is turned back on. (moremode can
|
||||
* be turned off for one of two reasons: we're printing the
|
||||
* prompt, or we're reading from a script with no pauses.
|
||||
* In either case, moremode should be turned back on at this
|
||||
* point. -CDN)
|
||||
*/
|
||||
savemoremode = 1;
|
||||
|
||||
/* turn off NONSTOP mode now that we're done with the script */
|
||||
os_nonstop_mode(FALSE);
|
||||
}
|
||||
|
||||
/* success */
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
/* if we don't have a script file, read from the keyboard */
|
||||
if (scrfp == 0)
|
||||
{
|
||||
/* update the status line */
|
||||
runstat();
|
||||
|
||||
/* read a line from the keyboard */
|
||||
result = (char *)os_gets((uchar *)buf, bufl);
|
||||
|
||||
/*
|
||||
* if the result is null, we're at eof, so return a non-zero
|
||||
* value; otherwise, we successfully read a command, so return
|
||||
* zero
|
||||
*/
|
||||
retval = (result == 0);
|
||||
}
|
||||
|
||||
/* restore the original "more" mode */
|
||||
setmore(savemoremode);
|
||||
|
||||
/* check the result */
|
||||
if (retval != 0)
|
||||
{
|
||||
/* we got an error reading the command - return the error */
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* we got a command, or at least a partial command (if we timed
|
||||
* out, we may still have a partial line in the buffer) - write
|
||||
* the input line to the log and/or command files, as
|
||||
* appropriate
|
||||
*/
|
||||
out_logfile_print(buf, TRUE);
|
||||
if (cmdfile != 0)
|
||||
{
|
||||
os_fprintz(cmdfile, ">");
|
||||
os_fprintz(cmdfile, buf);
|
||||
os_fprintz(cmdfile, "\n");
|
||||
}
|
||||
|
||||
/* translate the input to the internal character set */
|
||||
for (p = buf ; *p != '\0' ; ++p)
|
||||
*p = cmap_n2i(*p);
|
||||
|
||||
/* success */
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace TADS2
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
@@ -130,15 +130,15 @@ void ltk_free(void *mem) {
|
||||
* ltk_errlog - ERRor LOGging function. Logs an error from the LER
|
||||
* system.
|
||||
*/
|
||||
void ltk_errlog(void *ctx, char *fac, int errno, int argc, erradef *argv) {
|
||||
void ltk_errlog(void *ctx, char *fac, int errCode, int argc, erradef *argv) {
|
||||
char buf[128]; /* formatted error buffer */
|
||||
char msg[128]; /* message buffer */
|
||||
|
||||
/* $$$ filter out error #504 $$$ */
|
||||
if (errno == 504) return;
|
||||
if (errCode == 504) return;
|
||||
|
||||
/* get the error message into msg */
|
||||
errmsg((errcxdef *)ctx, msg, sizeof(msg), errno);
|
||||
errmsg((errcxdef *)ctx, msg, sizeof(msg), errCode);
|
||||
|
||||
/* format the error message */
|
||||
errfmt(buf, (int)sizeof(buf), msg, argc, argv);
|
||||
|
||||
@@ -3554,6 +3554,33 @@ void out_set_doublespace(int dbl)
|
||||
doublespace = dbl;
|
||||
}
|
||||
|
||||
int tio_askfile(const char *prompt, char *reply, int replen, int prompt_type, os_filetype_t file_type) {
|
||||
// let the OS layer handle it
|
||||
return os_askfile(prompt, reply, replen, prompt_type, file_type);
|
||||
}
|
||||
|
||||
int tio_input_dialog(int icon_id, const char *prompt, int standard_button_set,
|
||||
const char **buttons, int button_count,
|
||||
int default_index, int cancel_index) {
|
||||
// call the OS implementation
|
||||
return os_input_dialog(icon_id, prompt, standard_button_set,
|
||||
buttons, button_count,
|
||||
default_index, cancel_index);
|
||||
}
|
||||
|
||||
void outfmt(tiocxdef *ctx, uchar *txt) {
|
||||
uint len;
|
||||
|
||||
VARUSED(ctx);
|
||||
|
||||
/* read the length prefix */
|
||||
len = osrp2(txt) - 2;
|
||||
txt += 2;
|
||||
|
||||
/* write out the string */
|
||||
tioputslen(ctx, (char *)txt, len);
|
||||
}
|
||||
|
||||
} // End of namespace TADS2
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
@@ -28,6 +28,38 @@ namespace Glk {
|
||||
namespace TADS {
|
||||
namespace TADS2 {
|
||||
|
||||
void supcont(void *ctx, objnum obj, prpnum prp) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void supivoc(supcxdef *ctx) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void supfind(errcxdef *ctx, tokthdef *tab, voccxdef *voc,
|
||||
objnum *preinit, int warnlevel, int casefold) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void suprsrv(supcxdef *sup, void(*bif[])(struct bifcxdef *, int),
|
||||
toktdef *tab, int fncntmax, int v1compat, char *new_do, int casefold) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void supbif(supcxdef *sup, void(*bif[])(struct bifcxdef *, int), int bifsiz) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void sup_log_undefobj(mcmcxdef *mctx, errcxdef *ec, int err,
|
||||
char *sym_name, int sym_name_len, objnum objn) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
void supivoc1(supcxdef *sup, voccxdef *ctx, vocidef *v, objnum target,
|
||||
int inh_from_obj, int flags) {
|
||||
// No implementation
|
||||
}
|
||||
|
||||
} // End of namespace TADS2
|
||||
} // End of namespace TADS
|
||||
} // End of namespace Glk
|
||||
|
||||
@@ -46,34 +46,34 @@ struct supcxdef {
|
||||
};
|
||||
|
||||
/* set up contents list for one object for demand-on-load */
|
||||
inline void supcont(void *ctx, objnum obj, prpnum prp);
|
||||
extern void supcont(void *ctx, objnum obj, prpnum prp);
|
||||
|
||||
/* set up inherited vocabulary (called before executing game) */
|
||||
inline void supivoc(supcxdef *ctx);
|
||||
extern void supivoc(supcxdef *ctx);
|
||||
|
||||
/* find required objects/functions */
|
||||
inline void supfind(errcxdef *ctx, tokthdef *tab, voccxdef *voc,
|
||||
extern void supfind(errcxdef *ctx, tokthdef *tab, voccxdef *voc,
|
||||
objnum *preinit, int warnlevel, int casefold);
|
||||
|
||||
/* set up reserved words */
|
||||
inline void suprsrv(supcxdef *sup, void (*bif[])(struct bifcxdef *, int),
|
||||
extern void suprsrv(supcxdef *sup, void (*bif[])(struct bifcxdef *, int),
|
||||
toktdef *tab, int fncntmax, int v1compat, char *new_do,
|
||||
int casefold);
|
||||
|
||||
/* set up built-in functions without symbol table (for run-time) */
|
||||
inline void supbif(supcxdef *sup, void (*bif[])(struct bifcxdef *, int),
|
||||
extern void supbif(supcxdef *sup, void (*bif[])(struct bifcxdef *, int),
|
||||
int bifsiz);
|
||||
|
||||
/* log an undefined-object error */
|
||||
inline void sup_log_undefobj(mcmcxdef *mctx, errcxdef *ec, int err,
|
||||
extern void sup_log_undefobj(mcmcxdef *mctx, errcxdef *ec, int err,
|
||||
char *sym_name, int sym_name_len, objnum objn);
|
||||
|
||||
/* set up inherited vocabulary for a particular object */
|
||||
inline void supivoc1(supcxdef *sup, voccxdef *ctx, vocidef *v, objnum target,
|
||||
extern void supivoc1(supcxdef *sup, voccxdef *ctx, vocidef *v, objnum target,
|
||||
int inh_from_obj, int flags);
|
||||
|
||||
/* get name of an object out of symbol table */
|
||||
inline void supgnam(char *buf, tokthdef *tab, objnum objn);
|
||||
extern void supgnam(char *buf, tokthdef *tab, objnum objn);
|
||||
|
||||
/* table of built-in functions */
|
||||
struct supbidef {
|
||||
|
||||
@@ -53,6 +53,84 @@ void tok_read_defines(tokcxdef *tctx, osfildef *fp, errcxdef *ec)
|
||||
}
|
||||
|
||||
/* dummy debugger functions */
|
||||
|
||||
int dbgbpset(dbgcxdef *ctx, char *addr, int *bpnum) { return 0; }
|
||||
|
||||
int dbgbpat(dbgcxdef *ctx, objnum objn, objnum self,
|
||||
uint ofs, int *bpnum, char *bpname, int toggle,
|
||||
char *condition, int *did_set) { return 0; }
|
||||
|
||||
int dbgbpatid(dbgcxdef *ctx, int bpnum, objnum target, objnum self,
|
||||
uint ofs, char *bpname, int toggle, char *cond,
|
||||
int *did_set) { return 0; }
|
||||
|
||||
int dbgisbp(dbgcxdef *ctx, objnum target, objnum self, uint ofs, int *bpnum) { return 0; }
|
||||
|
||||
int dbgisbpena(dbgcxdef *ctx, int bpnum) { return 0; }
|
||||
|
||||
int dbgbpdel(dbgcxdef *ctx, int bpnum) { return 0; }
|
||||
|
||||
int dbgbpdis(dbgcxdef *ctx, int bpnum, int disable) { return 0; }
|
||||
|
||||
int dbgbpsetcond(dbgcxdef *ctx, int bpnum, char *cond) { return 0; }
|
||||
|
||||
void dbgbplist(dbgcxdef *ctx, void(*dispfn)(void *ctx, const char *str, int len), void *dispctx) {}
|
||||
|
||||
void dbgbpenum(dbgcxdef *ctx, void(*cbfunc)(void *cbctx, int bpnum, const char *desc,
|
||||
const char *cond, int disabled), void *cbctx) {}
|
||||
|
||||
void dbgbpeach(dbgcxdef *ctx, void(*fn)(void *, int, uchar *, uint), void *fnctx) {}
|
||||
|
||||
int dbgbpgetinfo(dbgcxdef *ctx, int bpnum, char *descbuf, size_t descbuflen,
|
||||
char *condbuf, size_t condbuflen) { return 0; }
|
||||
|
||||
int dbgeval(dbgcxdef *ctx, char *expr,
|
||||
void(*dispfn)(void *dispctx, const char *str, int strl),
|
||||
void *dispctx, int level, int showtype) { return 0; }
|
||||
|
||||
int dbgevalext(dbgcxdef *ctx, char *expr,
|
||||
void(*dispfn)(void *dispctx, const char *str, int strl),
|
||||
void *dispctx, int level, int showtype, dattyp *dat,
|
||||
void(*aggcb)(void *aggctx, const char *subname,
|
||||
int subnamelen, const char *relationship),
|
||||
void *aggctx, int speculative) { return 0 ;}
|
||||
|
||||
void dbgenumlcl(dbgcxdef *ctx, int level,
|
||||
void(*func)(void *ctx, const char *lclnam, size_t lclnamlen),
|
||||
void *cbctx) {}
|
||||
|
||||
int dbgcompile(dbgcxdef *ctx, char *expr, dbgfdef *fr, objnum *objn,
|
||||
int speculative) { return 0; }
|
||||
|
||||
void dbgwhere(dbgcxdef *ctx, char *buf) {}
|
||||
|
||||
int dbgwxset(dbgcxdef *ctx, char *expr, int *wxnum, int level) { return 0; }
|
||||
|
||||
int dbgwxdel(dbgcxdef *ctx, int wxnum) { return 0; }
|
||||
|
||||
void dbgwxupd(dbgcxdef *ctx,
|
||||
void(*dispfn)(void *dispctx, const char *txt, int len),
|
||||
void *dispctx) {}
|
||||
|
||||
void dbgswitch(struct lindef **linp, struct lindef *newlin) {}
|
||||
|
||||
void dbguini(dbgcxdef *ctx, const char *game_filename) {}
|
||||
|
||||
void dbguini2(dbgcxdef *ctx) {}
|
||||
|
||||
int dbgu_err_resume(dbgcxdef *ctx) { return 0; }
|
||||
|
||||
int dbgu_find_src(const char *origname, int origlen,
|
||||
char *fullname, size_t full_len, int must_find_file) { return 0; }
|
||||
|
||||
void dbgucmd(dbgcxdef *ctx, int bphit, int err, unsigned int *exec_ofs) {}
|
||||
|
||||
void dbguquitting(dbgcxdef *ctx) {}
|
||||
|
||||
void dbguterm(dbgcxdef *ctx) {}
|
||||
|
||||
void dbguerr(dbgcxdef *ctx, int errnum, char *msg) {}
|
||||
|
||||
void trchid(void) {}
|
||||
void trcsho(void) {}
|
||||
|
||||
|
||||
@@ -212,8 +212,7 @@ void out_set_doublespace(int dbl);
|
||||
* call directly for graphical implementations. We'll use formatted
|
||||
* text for text-only implementations.
|
||||
*/
|
||||
int tio_askfile(const char *prompt, char *fname_buf, int fname_buf_len,
|
||||
int prompt_type, os_filetype_t file_type);
|
||||
int tio_askfile(const char *prompt, char *reply, int replen, int prompt_type, os_filetype_t file_type);
|
||||
|
||||
/*
|
||||
* Display a dialog, using a system-defined dialog (via os_input_dialog)
|
||||
|
||||
Reference in New Issue
Block a user