Changeset - a22b6e149063
[Not reviewed]
27 3 29
HanzZ - 14 years ago 2011-09-18 11:48:00
hanzz.k@gmail.com
Finished frotz backend :)
33 files changed with 599 insertions and 343 deletions:
0 comments (0 inline, 0 general)
backends/frotz/CMakeLists.txt
Show inline comments
 
cmake_minimum_required(VERSION 2.6)
 
 
ADD_SUBDIRECTORY(dfrotz)
 
 
FILE(GLOB SRC *.c *.cpp)
 
 
ADD_EXECUTABLE(spectrum_frotz_backend ${SRC})
 
 
target_link_libraries(spectrum_frotz_backend transport pthread)
 
 
INSTALL(TARGETS spectrum_frotz_backend RUNTIME DESTINATION bin)
 
backends/frotz/dfrotz/CMakeLists.txt
Show inline comments
 
new file 100644
 
cmake_minimum_required(VERSION 2.6)
 
FILE(GLOB SRC common/*.c dumb/*.c)
 
 
ADD_EXECUTABLE(dfrotz ${SRC})
 
 
# target_link_libraries(dfrotz)
 
 
INSTALL(TARGETS dfrotz RUNTIME DESTINATION bin)
 
backends/frotz/dfrotz/README
Show inline comments
 
new file 100644
 
This is patched version of dfrotz. frotz_backend won't work with dfrotz from
 
your distribution.
 
\ No newline at end of file
backends/frotz/dfrotz/common/buffer.c
Show inline comments
 
file renamed from backends/frotz/buffer.c to backends/frotz/dfrotz/common/buffer.c
 
@@ -17,90 +17,90 @@
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
#include "frotz.h"
 

	
 
extern void stream_char (zchar);
 
extern void stream_word (const zchar *);
 
extern void stream_new_line (void);
 

	
 
static zchar buffer[TEXT_BUFFER_SIZE];
 
static int bufpos = 0;
 

	
 
static zchar prev_c = 0;
 

	
 
/*
 
 * flush_buffer
 
 *
 
 * Copy the contents of the text buffer to the output streams.
 
 *
 
 */
 

	
 
void flush_buffer (void)
 
{
 
    static int locked = FALSE;
 
    static bool locked = FALSE;
 

	
 
    /* Make sure we stop when flush_buffer is called from flush_buffer.
 
       Note that this is difficult to avoid as we might print a newline
 
       during flush_buffer, which might cause a newline interrupt, that
 
       might execute any arbitrary opcode, which might flush the buffer. */
 

	
 
    if (locked || bufpos == 0)
 
	return;
 

	
 
    /* Send the buffer to the output streams */
 

	
 
    buffer[bufpos] = 0;
 

	
 

	
 
    locked = TRUE;
 

	
 
    stream_word (buffer); 
 

	
 
#ifdef SPEECH_OUTPUT
 
    os_speech_output(buffer);
 
#endif
 

	
 
    locked = FALSE;
 

	
 
    /* Reset the buffer */
 

	
 
    bufpos = 0;
 
    prev_c = 0;
 

	
 
}/* flush_buffer */
 

	
 
/*
 
 * print_char
 
 *
 
 * High level output function.
 
 *
 
 */
 

	
 
void print_char (zchar c)
 
{
 
    static int flag = FALSE;
 
    static bool flag = FALSE;
 

	
 
    if (message || ostream_memory || enable_buffering) {
 

	
 
	if (!flag) {
 

	
 
	    /* Characters 0 and ZC_RETURN are special cases */
 

	
 
	    if (c == ZC_RETURN)
 
		{ new_line (); return; }
 
	    if (c == 0)
 
		return;
 

	
 
	    /* Flush the buffer before a whitespace or after a hyphen */
 

	
 
	    if (c == ' ' || c == ZC_INDENT || c == ZC_GAP || (prev_c == '-' && c != '-'))
 

	
 

	
 
		flush_buffer ();
 

	
 
	    /* Set the flag if this is part one of a style or font change */
 

	
 
	    if (c == ZC_NEW_FONT || c == ZC_NEW_STYLE)
 
		flag = TRUE;
 

	
backends/frotz/dfrotz/common/err.c
Show inline comments
 
file renamed from backends/frotz/err.c to backends/frotz/dfrotz/common/err.c
backends/frotz/dfrotz/common/fastmem.c
Show inline comments
 
file renamed from backends/frotz/fastmem.c to backends/frotz/dfrotz/common/fastmem.c
 
@@ -503,49 +503,49 @@ void storeb (zword addr, zbyte value)
 
/*
 
 * storew
 
 *
 
 * Write a word value to the dynamic Z-machine memory.
 
 *
 
 */
 

	
 
void storew (zword addr, zword value)
 
{
 

	
 
    storeb ((zword) (addr + 0), hi (value));
 
    storeb ((zword) (addr + 1), lo (value));
 

	
 
}/* storew */
 

	
 
/*
 
 * z_restart, re-load dynamic area, clear the stack and set the PC.
 
 *
 
 * 	no zargs used
 
 *
 
 */
 

	
 
void z_restart (void)
 
{
 
    static int first_restart = TRUE;
 
    static bool first_restart = TRUE;
 

	
 
    flush_buffer ();
 

	
 
    os_restart_game (RESTART_BEGIN);
 

	
 
    seed_random (0);
 

	
 
    if (!first_restart) {
 

	
 
	fseek (story_fp, 0, SEEK_SET);
 

	
 
	if (fread (zmp, 1, h_dynamic_size, story_fp) != h_dynamic_size)
 
	    os_fatal ("Story file read error");
 

	
 
    } else first_restart = FALSE;
 

	
 
    restart_header ();
 
    restart_screen ();
 

	
 
    sp = fp = stack + STACK_SIZE;
 
    frame_count = 0;
 

	
 
    if (h_version != V6) {
 

	
backends/frotz/dfrotz/common/files.c
Show inline comments
 
file renamed from backends/frotz/files.c to backends/frotz/dfrotz/common/files.c
 
@@ -7,84 +7,84 @@
 
 * 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.
 
 *
 
 * Frotz is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

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

	
 
#ifndef SEEK_SET
 
#define SEEK_SET 0
 
#define SEEK_CUR 1
 
#define SEEK_END 2
 
#endif
 

	
 
extern void set_more_prompts (int);
 
extern void set_more_prompts (bool);
 

	
 
extern int is_terminator (zchar);
 
extern bool is_terminator (zchar);
 

	
 
extern int read_yes_or_no (const char *);
 
extern bool read_yes_or_no (const char *);
 

	
 
char script_name[MAX_FILE_NAME + 1] = DEFAULT_SCRIPT_NAME;
 
char command_name[MAX_FILE_NAME + 1] = DEFAULT_COMMAND_NAME;
 

	
 
#ifdef __MSDOS__
 
extern char latin1_to_ibm[];
 
#endif
 

	
 
static int script_width = 0;
 

	
 
static FILE *sfp = NULL;
 
static FILE *rfp = NULL;
 
static FILE *pfp = NULL;
 

	
 
/*
 
 * script_open
 
 *
 
 * Open the transscript file. 'AMFV' makes this more complicated as it
 
 * turns transscription on/off several times to exclude some text from
 
 * the transscription file. This wasn't a problem for the original V4
 
 * interpreters which always sent transscription to the printer, but it
 
 * means a problem to modern interpreters that offer to open a new file
 
 * every time transscription is turned on. Our solution is to append to
 
 * the old transscription file in V1 to V4, and to ask for a new file
 
 * name in V5+.
 
 *
 
 */
 

	
 
void script_open (void)
 
{
 
    static int script_valid = FALSE;
 
    static bool script_valid = FALSE;
 

	
 
    char new_name[MAX_FILE_NAME + 1];
 

	
 
    h_flags &= ~SCRIPTING_FLAG;
 

	
 
    if (h_version >= V5 || !script_valid) {
 

	
 
	if (!os_read_file_name (new_name, script_name, FILE_SCRIPT))
 
	    goto done;
 

	
 
	strcpy (script_name, new_name);
 

	
 
    }
 

	
 
    /* Opening in "at" mode doesn't work for script_erase_input... */
 

	
 
    if ((sfp = fopen (script_name, "r+t")) != NULL || (sfp = fopen (script_name, "w+t")) != NULL) {
 

	
 
	fseek (sfp, 0, SEEK_END);
 

	
 
	h_flags |= SCRIPTING_FLAG;
 

	
 
	script_valid = TRUE;
 
	ostream_script = TRUE;
 
@@ -304,49 +304,49 @@ void record_open (void)
 

	
 
}/* record_open */
 

	
 
/*
 
 * record_close
 
 *
 
 * Stop recording the player's input.
 
 *
 
 */
 

	
 
void record_close (void)
 
{
 

	
 
    fclose (rfp); ostream_record = FALSE;
 

	
 
}/* record_close */
 

	
 
/*
 
 * record_code
 
 *
 
 * Helper function for record_char.
 
 *
 
 */
 

	
 
static void record_code (int c, int force_encoding)
 
static void record_code (int c, bool force_encoding)
 
{
 

	
 
    if (force_encoding || c == '[' || c < 0x20 || c > 0x7e) {
 

	
 
	int i;
 

	
 
	fputc ('[', rfp);
 

	
 
	for (i = 10000; i != 0; i /= 10)
 
	    if (c >= i || i == 1)
 
		fputc ('0' + (c / i) % 10, rfp);
 

	
 
	fputc (']', rfp);
 

	
 
    } else fputc (c, rfp);
 

	
 
}/* record_code */
 

	
 
/*
 
 * record_char
 
 *
 
 * Write a character to the command file.
 
 *
 
 */
backends/frotz/dfrotz/common/frotz.h
Show inline comments
 
file renamed from backends/frotz/frotz.h to backends/frotz/dfrotz/common/frotz.h
 
/*
 
 * frotz.h
 
 *
 
 * Global declarations and definitions
 
 *
 
 */
 

	
 
/* Unfortunately, frotz's int definition conflicts with that of curses.
 
/* Unfortunately, frotz's bool definition conflicts with that of curses.
 
   But since no os_* function uses it, it's safe to let the frotz core see
 
   this definition, but have the unix port see the curses version. */
 

	
 
/* #include "../config.h" */
 

	
 
#ifndef __UNIX_PORT_FILE
 
#include <signal.h>
 

	
 
#ifdef __cplusplus
 
extern "C" {
 
#endif
 
typedef int bool;
 

	
 
#ifndef TRUE
 
#define TRUE 1
 
#endif
 

	
 
#ifndef FALSE
 
#define FALSE 0
 
#endif
 

	
 
#endif /* __UNIX_PORT_FILE */
 

	
 

	
 
#include <stdio.h>
 

	
 

	
 
typedef unsigned char zbyte;
 
typedef unsigned short zword;
 

	
 
enum story {
 
    BEYOND_ZORK,
 
    SHERLOCK,
 
    ZORK_ZERO,
 
    SHOGUN,
 
    ARTHUR,
 
@@ -334,65 +331,65 @@ extern zbyte h_standard_low;
 
extern zword h_alphabet;
 
extern zword h_extension_table;
 
extern zbyte h_user_name[8];
 

	
 
extern zword hx_table_size;
 
extern zword hx_mouse_x;
 
extern zword hx_mouse_y;
 
extern zword hx_unicode_table;
 

	
 
/*** Various data ***/
 

	
 
extern char *story_name;
 

	
 
extern enum story story_id;
 
extern long story_size;
 

	
 
extern zword stack[STACK_SIZE];
 
extern zword *sp;
 
extern zword *fp;
 
extern zword frame_count;
 

	
 
extern zword zargs[8];
 
extern int zargc;
 

	
 
extern int ostream_screen;
 
extern int ostream_script;
 
extern int ostream_memory;
 
extern int ostream_record;
 
extern int istream_replay;
 
extern int message;
 
extern bool ostream_screen;
 
extern bool ostream_script;
 
extern bool ostream_memory;
 
extern bool ostream_record;
 
extern bool istream_replay;
 
extern bool message;
 

	
 
extern int cwin;
 
extern int mwin;
 

	
 
extern int mouse_x;
 
extern int mouse_y;
 

	
 
extern int enable_wrapping;
 
extern int enable_scripting;
 
extern int enable_scrolling;
 
extern int enable_buffering;
 
extern bool enable_wrapping;
 
extern bool enable_scripting;
 
extern bool enable_scrolling;
 
extern bool enable_buffering;
 

	
 

	
 
extern char *option_zcode_path;	/* dg */
 

	
 
extern long reserve_mem;
 

	
 

	
 
/*** Blorb stuff ***/
 
/*
 
bb_err_t       blorb_err;
 
bb_map_t       *blorb_map;
 
*/
 

	
 
/*** Z-machine opcodes ***/
 

	
 
void 	z_add (void);
 
void 	z_and (void);
 
void 	z_art_shift (void);
 
void 	z_buffer_mode (void);
 
void 	z_call_n (void);
 
void 	z_call_s (void);
 
void 	z_catch (void);
 
void 	z_check_arg_count (void);
 
void	z_check_unicode (void);
 
@@ -557,80 +554,64 @@ void	runtime_error (int);
 
#define ERR_REPORT_ONCE (1)
 
#define ERR_REPORT_ALWAYS (2)
 
#define ERR_REPORT_FATAL (3)
 

	
 
#define ERR_DEFAULT_REPORT_MODE ERR_REPORT_ONCE
 

	
 

	
 
/*** Various global functions ***/
 

	
 
zchar	translate_from_zscii (zbyte);
 
zbyte	translate_to_zscii (zchar);
 

	
 
void 	flush_buffer (void);
 
void	new_line (void);
 
void	print_char (zchar);
 
void	print_num (zword);
 
void	print_object (zword);
 
void 	print_string (const char *);
 

	
 
void 	stream_mssg_on (void);
 
void 	stream_mssg_off (void);
 

	
 
void	ret (zword);
 
void 	store (zword);
 
void 	branch (int);
 
void 	branch (bool);
 

	
 
void	storeb (zword, zbyte);
 
void	storew (zword, zword);
 

	
 
/*** Interface functions ***/
 

	
 
void 	os_beep (int);
 
int  	os_char_width (zchar);
 
void 	os_display_char (zchar);
 
void 	os_display_string (const zchar *);
 
void 	os_draw_picture (int, int, int);
 
void 	os_erase_area (int, int, int, int);
 
void 	os_fatal (const char *);
 
void 	os_finish_with_sample (int);
 
int  	os_font_data (int, int *, int *);
 
void 	os_init_screen (void);
 
void 	os_more_prompt (void);
 
int  	os_peek_colour (void);
 
int  	os_picture_data (int, int *, int *);
 
void 	os_prepare_sample (int);
 
void 	os_process_arguments (int, char *[]);
 
int	os_random_seed (void);
 
int  	os_read_file_name (char *, const char *, int);
 
zchar	os_read_key (int, int);
 
zchar	os_read_line (int, zchar *, int, int, int);
 
void 	os_reset_screen (void);
 
void 	os_restart_game (int);
 
void 	os_scroll_area (int, int, int, int, int);
 
void 	os_set_colour (int, int);
 
void 	os_set_cursor (int, int);
 
void 	os_set_font (int);
 
void 	os_set_text_style (int);
 
void 	os_start_sample (int, int, int, zword);
 
void 	os_stop_sample (int);
 
int  	os_string_width (const zchar *);
 
void	os_init_setup (void);
 
int	os_speech_output(const zchar *);
 

	
 
void init_buffer(void);
 
void init_process(void);
 
void init_sound(void);
 
void init_memory(void);
 
void init_undo(void);
 
void interpret(void);
 
void reset_memory(void);
 

	
 
char *frotz_get_array();
 
void frotz_reset_array();
 
void dumb_show_screen(int show_cursor);
 

	
 
#include "setup.h"
 

	
 
#ifdef __cplusplus
 
}
 
#endif
backends/frotz/dfrotz/common/getopt.c
Show inline comments
 
file renamed from backends/frotz/getopt.c to backends/frotz/dfrotz/common/getopt.c
backends/frotz/dfrotz/common/hotkey.c
Show inline comments
 
file renamed from backends/frotz/hotkey.c to backends/frotz/dfrotz/common/hotkey.c
 
@@ -3,254 +3,254 @@
 
 *
 
 * This file is part of Frotz.
 
 *
 
 * Frotz 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.
 
 *
 
 * Frotz is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
#include "frotz.h"
 

	
 
extern int restore_undo (void);
 

	
 
extern int read_number (void);
 

	
 
extern int read_yes_or_no (const char *);
 
extern bool read_yes_or_no (const char *);
 

	
 
extern void replay_open (void);
 
extern void replay_close (void);
 
extern void record_open (void);
 
extern void record_close (void);
 

	
 
extern void seed_random (int);
 

	
 
/*
 
 * hot_key_debugging
 
 *
 
 * ...allows user to toggle cheating options on/off.
 
 *
 
 */
 

	
 
static int hot_key_debugging (void)
 
static bool hot_key_debugging (void)
 
{
 

	
 
    print_string ("Debugging options\n");
 

	
 
    f_setup.attribute_assignment = read_yes_or_no ("Watch attribute assignment");
 
    f_setup.attribute_testing = read_yes_or_no ("Watch attribute testing");
 

	
 
    f_setup.object_movement = read_yes_or_no ("Watch object movement");
 
    f_setup.object_locating = read_yes_or_no ("Watch object locating");
 

	
 
    return FALSE;
 

	
 
}/* hot_key_debugging */
 

	
 
/*
 
 * hot_key_help
 
 *
 
 * ...displays a list of all hot keys.
 
 *
 
 */
 

	
 
static int hot_key_help (void) {
 
static bool hot_key_help (void) {
 

	
 
    print_string ("Help\n");
 

	
 
    print_string (
 
	"\n"
 
	"Alt-D  debugging options\n"
 
	"Alt-H  help\n"
 
	"Alt-N  new game\n"
 
	"Alt-P  playback on\n"
 
	"Alt-R  recording on/off\n"
 
	"Alt-S  seed random numbers\n"
 
	"Alt-U  undo one turn\n"
 
	"Alt-X  exit game\n");
 

	
 
    return FALSE;
 

	
 
}/* hot_key_help */
 

	
 
/*
 
 * hot_key_playback
 
 *
 
 * ...allows user to turn playback on.
 
 *
 
 */
 

	
 
static int hot_key_playback (void)
 
static bool hot_key_playback (void)
 
{
 

	
 
    print_string ("Playback on\n");
 

	
 
    if (!istream_replay)
 
	replay_open ();
 

	
 
    return FALSE;
 

	
 
}/* hot_key_playback */
 

	
 
/*
 
 * hot_key_recording
 
 *
 
 * ...allows user to turn recording on/off.
 
 *
 
 */
 

	
 
static int hot_key_recording (void)
 
static bool hot_key_recording (void)
 
{
 

	
 
    if (istream_replay) {
 
	print_string ("Playback off\n");
 
	replay_close ();
 
    } else if (ostream_record) {
 
	print_string ("Recording off\n");
 
	record_close ();
 
    } else {
 
	print_string ("Recording on\n");
 
	record_open ();
 
    }
 

	
 
    return FALSE;
 

	
 
}/* hot_key_recording */
 

	
 
/*
 
 * hot_key_seed
 
 *
 
 * ...allows user to seed the random number seed.
 
 *
 
 */
 

	
 
static int hot_key_seed (void)
 
static bool hot_key_seed (void)
 
{
 

	
 
    print_string ("Seed random numbers\n");
 

	
 
    print_string ("Enter seed value (or return to randomize): ");
 
    seed_random (read_number ());
 

	
 
    return FALSE;
 

	
 
}/* hot_key_seed */
 

	
 
/*
 
 * hot_key_undo
 
 *
 
 * ...allows user to undo the previous turn.
 
 *
 
 */
 

	
 
static int hot_key_undo (void)
 
static bool hot_key_undo (void)
 
{
 

	
 
    print_string ("Undo one turn\n");
 

	
 
    if (restore_undo ()) {
 

	
 
	if (h_version >= V5) {		/* for V5+ games we must */
 
	    store (2);			/* store 2 (for success) */
 
	    return TRUE;		/* and abort the input   */
 
	}
 

	
 
	if (h_version <= V3) {		/* for V3- games we must */
 
	    z_show_status ();		/* draw the status line  */
 
	    return FALSE;		/* and continue input    */
 
	}
 

	
 
    } else print_string ("No more undo information available.\n");
 

	
 
    return FALSE;
 

	
 
}/* hot_key_undo */
 

	
 
/*
 
 * hot_key_restart
 
 *
 
 * ...allows user to start a new game.
 
 *
 
 */
 

	
 
static int hot_key_restart (void)
 
static bool hot_key_restart (void)
 
{
 

	
 
    print_string ("New game\n");
 

	
 
    if (read_yes_or_no ("Do you wish to restart")) {
 

	
 
	z_restart ();
 
	return TRUE;
 

	
 
    } else return FALSE;
 

	
 
}/* hot_key_restart */
 

	
 
/*
 
 * hot_key_quit
 
 *
 
 * ...allows user to exit the game.
 
 *
 
 */
 

	
 
static int hot_key_quit (void)
 
static bool hot_key_quit (void)
 
{
 

	
 
    print_string ("Exit game\n");
 

	
 
    if (read_yes_or_no ("Do you wish to quit")) {
 

	
 
	z_quit ();
 
	return TRUE;
 

	
 
    } else return FALSE;
 

	
 
}/* hot_key_quit */
 

	
 
/*
 
 * handle_hot_key
 
 *
 
 * Perform the action associated with a so-called hot key. Return
 
 * true to abort the current input action.
 
 *
 
 */
 

	
 
int handle_hot_key (zchar key)
 
bool handle_hot_key (zchar key)
 
{
 

	
 
    if (cwin == 0) {
 

	
 
	int aborting;
 
	bool aborting;
 

	
 
	aborting = FALSE;
 

	
 
	print_string ("\nHot key -- ");
 

	
 
	switch (key) {
 
	    case ZC_HKEY_RECORD: aborting = hot_key_recording (); break;
 
	    case ZC_HKEY_PLAYBACK: aborting = hot_key_playback (); break;
 
	    case ZC_HKEY_SEED: aborting = hot_key_seed (); break;
 
	    case ZC_HKEY_UNDO: aborting = hot_key_undo (); break;
 
	    case ZC_HKEY_RESTART: aborting = hot_key_restart (); break;
 
	    case ZC_HKEY_QUIT: aborting = hot_key_quit (); break;
 
	    case ZC_HKEY_DEBUG: aborting = hot_key_debugging (); break;
 
	    case ZC_HKEY_HELP: aborting = hot_key_help (); break;
 
	}
 

	
 
	if (aborting)
 
	    return TRUE;
 

	
 
	print_string ("\nContinue input...\n");
 

	
 
    }
 

	
 
    return FALSE;
backends/frotz/dfrotz/common/input.c
Show inline comments
 
file renamed from backends/frotz/input.c to backends/frotz/dfrotz/common/input.c
 
/* input.c - High level input functions
 
 *	Copyright (c) 1995-1997 Stefan Jokisch
 
 *
 
 * This file is part of Frotz.
 
 *
 
 * Frotz 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.
 
 *
 
 * Frotz is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
#include "frotz.h"
 

	
 
extern int save_undo (void);
 

	
 
extern zchar stream_read_key (zword, zword, int);
 
extern zchar stream_read_input (int, zchar *, zword, zword, int, int);
 
extern zchar stream_read_key (zword, zword, bool);
 
extern zchar stream_read_input (int, zchar *, zword, zword, bool, bool);
 

	
 
extern void tokenise_line (zword, zword, zword, int);
 
extern void tokenise_line (zword, zword, zword, bool);
 

	
 
/*
 
 * is_terminator
 
 *
 
 * Check if the given key is an input terminator.
 
 *
 
 */
 

	
 
int is_terminator (zchar key)
 
bool is_terminator (zchar key)
 
{
 

	
 
    if (key == ZC_TIME_OUT)
 
	return TRUE;
 
    if (key == ZC_RETURN)
 
	return TRUE;
 
    if (key >= ZC_HKEY_MIN && key <= ZC_HKEY_MAX)
 
	return TRUE;
 

	
 
    if (h_terminating_keys != 0)
 

	
 
	if (key >= ZC_ARROW_MIN && key <= ZC_MENU_CLICK) {
 

	
 
	    zword addr = h_terminating_keys;
 
	    zbyte c;
 

	
 
	    do {
 
		LOW_BYTE (addr, c)
 
		if (c == 255 || key == translate_from_zscii (c))
 
		    return TRUE;
 
		addr++;
 
	    } while (c != 0);
 

	
 
	}
 
@@ -69,49 +69,49 @@ int is_terminator (zchar key)
 
 *
 
 * 	zargs[0] = number of menu
 
 *	zargs[1] = table of menu entries or 0 to remove menu
 
 *
 
 */
 

	
 
void z_make_menu (void)
 
{
 

	
 
    /* This opcode was only used for the Macintosh version of Journey.
 
       It controls menus with numbers greater than 2 (menus 0, 1 and 2
 
       are system menus). Frotz doesn't implement menus yet. */
 

	
 
    branch (FALSE);
 

	
 
}/* z_make_menu */
 

	
 
/*
 
 * read_yes_or_no
 
 *
 
 * Ask the user a question; return true if the answer is yes.
 
 *
 
 */
 

	
 
int read_yes_or_no (const char *s)
 
bool read_yes_or_no (const char *s)
 
{
 
    zchar key;
 

	
 
    print_string (s);
 
    print_string ("? (y/n) >");
 

	
 
    key = stream_read_key (0, 0, FALSE);
 

	
 
    if (key == 'y' || key == 'Y') {
 
	print_string ("y\n");
 
	return TRUE;
 
    } else {
 
	print_string ("n\n");
 
	return FALSE;
 
    }
 

	
 
}/* read_yes_or_no */
 

	
 
/*
 
 * read_string
 
 *
 
 * Read a string from the current input stream.
 
 *
 
 */
backends/frotz/dfrotz/common/main.c
Show inline comments
 
new file 100644
 
/* main.c - Frotz V2.40 main function
 
 *	Copyright (c) 1995-1997 Stefan Jokisch
 
 *
 
 * This file is part of Frotz.
 
 *
 
 * Frotz 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.
 
 *
 
 * Frotz is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
/*
 
 * This is an interpreter for Infocom V1 to V6 games. It also supports
 
 * the recently defined V7 and V8 games. Please report bugs to
 
 *
 
 *    s.jokisch@avu.de
 
 *
 
 */
 

	
 
#include "frotz.h"
 

	
 
#ifndef MSDOS_16BIT
 
#define cdecl
 
#endif
 

	
 
extern void interpret (void);
 
extern void init_memory (void);
 
extern void init_undo (void);
 
extern void reset_memory (void);
 

	
 
/* Story file name, id number and size */
 

	
 
char *story_name = 0;
 

	
 
enum story story_id = UNKNOWN;
 
long story_size = 0;
 

	
 
/* Story file header data */
 

	
 
zbyte h_version = 0;
 
zbyte h_config = 0;
 
zword h_release = 0;
 
zword h_resident_size = 0;
 
zword h_start_pc = 0;
 
zword h_dictionary = 0;
 
zword h_objects = 0;
 
zword h_globals = 0;
 
zword h_dynamic_size = 0;
 
zword h_flags = 0;
 
zbyte h_serial[6] = { 0, 0, 0, 0, 0, 0 };
 
zword h_abbreviations = 0;
 
zword h_file_size = 0;
 
zword h_checksum = 0;
 
zbyte h_interpreter_number = 0;
 
zbyte h_interpreter_version = 0;
 
zbyte h_screen_rows = 0;
 
zbyte h_screen_cols = 0;
 
zword h_screen_width = 0;
 
zword h_screen_height = 0;
 
zbyte h_font_height = 1;
 
zbyte h_font_width = 1;
 
zword h_functions_offset = 0;
 
zword h_strings_offset = 0;
 
zbyte h_default_background = 0;
 
zbyte h_default_foreground = 0;
 
zword h_terminating_keys = 0;
 
zword h_line_width = 0;
 
zbyte h_standard_high = 1;
 
zbyte h_standard_low = 0;
 
zword h_alphabet = 0;
 
zword h_extension_table = 0;
 
zbyte h_user_name[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 

	
 
zword hx_table_size = 0;
 
zword hx_mouse_x = 0;
 
zword hx_mouse_y = 0;
 
zword hx_unicode_table = 0;
 

	
 
/* Stack data */
 

	
 
zword stack[STACK_SIZE];
 
zword *sp = 0;
 
zword *fp = 0;
 
zword frame_count = 0;
 

	
 
/* IO streams */
 

	
 
bool ostream_screen = TRUE;
 
bool ostream_script = FALSE;
 
bool ostream_memory = FALSE;
 
bool ostream_record = FALSE;
 
bool istream_replay = FALSE;
 
bool message = FALSE;
 

	
 
/* Current window and mouse data */
 

	
 
int cwin = 0;
 
int mwin = 0;
 

	
 
int mouse_y = 0;
 
int mouse_x = 0;
 

	
 
/* Window attributes */
 

	
 
bool enable_wrapping = FALSE;
 
bool enable_scripting = FALSE;
 
bool enable_scrolling = FALSE;
 
bool enable_buffering = FALSE;
 

	
 
/* User options */
 

	
 
/*
 
int option_attribute_assignment = 0;
 
int option_attribute_testing = 0;
 
int option_context_lines = 0;
 
int option_object_locating = 0;
 
int option_object_movement = 0;
 
int option_left_margin = 0;
 
int option_right_margin = 0;
 
int option_ignore_errors = 0;
 
int option_piracy = 0;
 
int option_undo_slots = MAX_UNDO_SLOTS;
 
int option_expand_abbreviations = 0;
 
int option_script_cols = 80;
 
int option_save_quetzal = 1;
 
*/
 

	
 
int option_sound = 1;
 
char *option_zcode_path;
 

	
 

	
 
/* Size of memory to reserve (in bytes) */
 

	
 
long reserve_mem = 0;
 

	
 
/*
 
 * z_piracy, branch if the story file is a legal copy.
 
 *
 
 *	no zargs used
 
 *
 
 */
 

	
 
void z_piracy (void)
 
{
 

	
 
    branch (!f_setup.piracy);
 

	
 
}/* z_piracy */
 

	
 
/*
 
 * main
 
 *
 
 * Prepare and run the game.
 
 *
 
 */
 

	
 
int cdecl main (int argc, char *argv[])
 
{
 

	
 
    os_init_setup ();
 

	
 
    os_process_arguments (argc, argv);
 

	
 
    init_buffer ();
 

	
 
    init_err ();
 

	
 
    init_memory ();
 

	
 
    init_process ();
 

	
 
    init_sound ();
 

	
 
    os_init_screen ();
 

	
 
    init_undo ();
 

	
 
    z_restart ();
 

	
 
    interpret ();
 

	
 
    reset_memory ();
 

	
 
    os_reset_screen ();
 

	
 
    return 0;
 

	
 
}/* main */
backends/frotz/dfrotz/common/math.c
Show inline comments
 
file renamed from backends/frotz/math.c to backends/frotz/dfrotz/common/math.c
backends/frotz/dfrotz/common/object.c
Show inline comments
 
file renamed from backends/frotz/object.c to backends/frotz/dfrotz/common/object.c
backends/frotz/dfrotz/common/process.c
Show inline comments
 
file renamed from backends/frotz/process.c to backends/frotz/dfrotz/common/process.c
 
@@ -425,49 +425,49 @@ void ret (zword value)
 
	*--sp = value;
 

	
 
    /* Stop main loop for direct calls */
 

	
 
    if (ct == 2)
 
	finished++;
 

	
 
}/* ret */
 

	
 
/*
 
 * branch
 
 *
 
 * Take a jump after an instruction based on the flag, either true or
 
 * false. The branch can be short or long; it is encoded in one or two
 
 * bytes respectively. When bit 7 of the first byte is set, the jump
 
 * takes place if the flag is true; otherwise it is taken if the flag
 
 * is false. When bit 6 of the first byte is set, the branch is short;
 
 * otherwise it is long. The offset occupies the bottom 6 bits of the
 
 * first byte plus all the bits in the second byte for long branches.
 
 * Uniquely, an offset of 0 means return false, and an offset of 1 is
 
 * return true.
 
 *
 
 */
 

	
 
void branch (int flag)
 
void branch (bool flag)
 
{
 
    long pc;
 
    zword offset;
 
    zbyte specifier;
 
    zbyte off1;
 
    zbyte off2;
 

	
 
    CODE_BYTE (specifier)
 

	
 
    off1 = specifier & 0x3f;
 

	
 
    if (!flag)
 
	specifier ^= 0x80;
 

	
 
    if (!(specifier & 0x40)) {		/* it's a long branch */
 

	
 
	if (off1 & 0x20)		/* propagate sign bit */
 
	    off1 |= 0xc0;
 

	
 
	CODE_BYTE (off2)
 

	
 
	offset = (off1 << 8) | off2;
 

	
 
    } else offset = off1;		/* it's a short branch */
backends/frotz/dfrotz/common/quetzal.c
Show inline comments
 
file renamed from backends/frotz/quetzal.c to backends/frotz/dfrotz/common/quetzal.c
 
@@ -78,61 +78,61 @@ static zword frames[STACK_SIZE/4+1];
 
#define GOT_HEADER	0x01
 
#define GOT_STACK	0x02
 
#define GOT_MEMORY	0x04
 
#define GOT_NONE	0x00
 
#define GOT_ALL		0x07
 
#define GOT_ERROR	0x80
 

	
 
/*
 
 * Macros used to write the files.
 
 */
 

	
 
#define write_byte(fp,b) (put_c (b, fp) != EOF)
 
#define write_bytx(fp,b) write_byte (fp, (b) & 0xFF)
 
#define write_word(fp,w) \
 
    (write_bytx (fp, (w) >>  8) && write_bytx (fp, (w)))
 
#define write_long(fp,l) \
 
    (write_bytx (fp, (l) >> 24) && write_bytx (fp, (l) >> 16) && \
 
     write_bytx (fp, (l) >>  8) && write_bytx (fp, (l)))
 
#define write_chnk(fp,id,len) \
 
    (write_long (fp, (id))      && write_long (fp, (len)))
 
#define write_run(fp,run) \
 
    (write_byte (fp, 0)         && write_byte (fp, (run)))
 

	
 
/* Read one word from file; return TRUE if OK. */
 
static int read_word (FILE *f, zword *result)
 
static bool read_word (FILE *f, zword *result)
 
{
 
    int a, b;
 

	
 
    if ((a = get_c (f)) == EOF) return FALSE;
 
    if ((b = get_c (f)) == EOF) return FALSE;
 

	
 
    *result = ((zword) a << 8) | (zword) b;
 
    return TRUE;
 
}
 

	
 
/* Read one long from file; return TRUE if OK. */
 
static int read_long (FILE *f, zlong *result)
 
static bool read_long (FILE *f, zlong *result)
 
{
 
    int a, b, c, d;
 

	
 
    if ((a = get_c (f)) == EOF) return FALSE;
 
    if ((b = get_c (f)) == EOF) return FALSE;
 
    if ((c = get_c (f)) == EOF) return FALSE;
 
    if ((d = get_c (f)) == EOF) return FALSE;
 

	
 
    *result = ((zlong) a << 24) | ((zlong) b << 16) |
 
	      ((zlong) c <<  8) |  (zlong) d;
 
    return TRUE;
 
}
 

	
 
/*
 
 * Restore a saved game using Quetzal format. Return 2 if OK, 0 if an error
 
 * occurred before any damage was done, -1 on a fatal error.
 
 */
 

	
 
zword restore_quetzal (FILE *svf, FILE *stf)
 
{
 
    zlong ifzslen, currlen, tmpl;
 
    zlong pc;
 
    zword i, tmpw;
 
    zword fatal = 0;	/* Set to -1 when errors must be fatal. */
backends/frotz/dfrotz/common/random.c
Show inline comments
 
file renamed from backends/frotz/random.c to backends/frotz/dfrotz/common/random.c
backends/frotz/dfrotz/common/redirect.c
Show inline comments
 
file renamed from backends/frotz/redirect.c to backends/frotz/dfrotz/common/redirect.c
 
@@ -19,49 +19,49 @@
 
 */
 

	
 
#include "frotz.h"
 

	
 
#define MAX_NESTING 16
 

	
 
extern zword get_max_width (zword);
 

	
 
static int depth = -1;
 

	
 
static struct {
 
    zword xsize;
 
    zword table;
 
    zword width;
 
    zword total;
 
} redirect[MAX_NESTING];
 

	
 
/*
 
 * memory_open
 
 *
 
 * Begin output redirection to the memory of the Z-machine.
 
 *
 
 */
 

	
 
void memory_open (zword table, zword xsize, int buffering)
 
void memory_open (zword table, zword xsize, bool buffering)
 
{
 

	
 
    if (++depth < MAX_NESTING) {
 

	
 
	if (!buffering)
 
	    xsize = 0xffff;
 
	if (buffering && (short) xsize <= 0)
 
	    xsize = get_max_width ((zword) (- (short) xsize));
 

	
 
	storew (table, 0);
 

	
 
	redirect[depth].table = table;
 
	redirect[depth].width = 0;
 
	redirect[depth].total = 0;
 
	redirect[depth].xsize = xsize;
 

	
 
	ostream_memory = TRUE;
 

	
 
   } else runtime_error (ERR_STR3_NESTING);
 

	
 
}/* memory_open */
 

	
 
/*
 
 * memory_new_line
backends/frotz/dfrotz/common/screen.c
Show inline comments
 
file renamed from backends/frotz/screen.c to backends/frotz/dfrotz/common/screen.c
 
@@ -21,52 +21,52 @@
 
#include "frotz.h"
 

	
 
extern void set_header_extension (int, zword);
 

	
 
extern int direct_call (zword);
 

	
 
static struct {
 
    enum story story_id;
 
    int pic;
 
    int pic1;
 
    int pic2;
 
} mapper[] = {
 
    { ZORK_ZERO,  5, 497, 498 },
 
    { ZORK_ZERO,  6, 501, 502 },
 
    { ZORK_ZERO,  7, 499, 500 },
 
    { ZORK_ZERO,  8, 503, 504 },
 
    {    ARTHUR, 54, 170, 171 },
 
    {    SHOGUN, 50,  61,  62 },
 
    {   UNKNOWN,  0,   0,   0 }
 
};
 

	
 
static int font_height = 1;
 
static int font_width = 1;
 

	
 
static int input_redraw = FALSE;
 
static int more_prompts = TRUE;
 
static int discarding = FALSE;
 
static int cursor = TRUE;
 
static bool input_redraw = FALSE;
 
static bool more_prompts = TRUE;
 
static bool discarding = FALSE;
 
static bool cursor = TRUE;
 

	
 
static int input_window = 0;
 

	
 
static struct {
 
    zword y_pos;
 
    zword x_pos;
 
    zword y_size;
 
    zword x_size;
 
    zword y_cursor;
 
    zword x_cursor;
 
    zword left;
 
    zword right;
 
    zword nl_routine;
 
    zword nl_countdown;
 
    zword style;
 
    zword colour;
 
    zword font;
 
    zword font_size;
 
    zword attribute;
 
    zword line_count;
 
} wp[8], *cwp;
 

	
 

	
 
/*
 
@@ -136,49 +136,49 @@ static void update_cursor (void)
 
 */
 

	
 
static void reset_cursor (zword win)
 
{
 
    int lines = 0;
 

	
 
    if (h_version <= V4 && win == 0)
 
	lines = wp[0].y_size / hi (wp[0].font_size) - 1;
 

	
 
    wp[win].y_cursor = hi (wp[0].font_size) * lines + 1;
 
    wp[win].x_cursor = wp[win].left + 1;
 

	
 
    if (win == cwin)
 
	update_cursor ();
 

	
 
}/* reset_cursor */
 

	
 
/*
 
 * set_more_prompts
 
 *
 
 * Turn more prompts on/off.
 
 *
 
 */
 

	
 
void set_more_prompts (int flag)
 
void set_more_prompts (bool flag)
 
{
 

	
 
    if (flag && !more_prompts)
 
	cwp->line_count = 0;
 

	
 
    more_prompts = flag;
 

	
 
}/* set_more_prompts */
 

	
 
/*
 
 * units_left
 
 *
 
 * Return the #screen units from the cursor to the end of the line.
 
 *
 
 */
 

	
 
static int units_left (void)
 
{
 

	
 
    return cwp->x_size - cwp->right - cwp->x_cursor + 1;
 

	
 
}/* units_left */
 

	
 
/*
 
@@ -418,49 +418,49 @@ void screen_erase_input (const zchar *buf)
 
	int width = os_string_width (buf);
 

	
 
	zword y;
 
	zword x;
 

	
 
	cwp->x_cursor -= width;
 

	
 
	y = cwp->y_pos + cwp->y_cursor - 1;
 
	x = cwp->x_pos + cwp->x_cursor - 1;
 

	
 
	os_erase_area (y, x, y + font_height - 1, x + width - 1);
 
	os_set_cursor (y, x);
 

	
 
    }
 

	
 
}/* screen_erase_input */
 

	
 
/*
 
 * console_read_input
 
 *
 
 * Read an input line from the keyboard and return the terminating key.
 
 *
 
 */
 

	
 
zchar console_read_input (int max, zchar *buf, zword timeout, int continued)
 
zchar console_read_input (int max, zchar *buf, zword timeout, bool continued)
 
{
 
    zchar key;
 
    int i;
 

	
 
    /* Make sure there is some space for input */
 

	
 
    if (cwin == 0 && units_left () + os_string_width (buf) < 10 * font_width)
 
	screen_new_line ();
 

	
 
    /* Make sure the input line is visible */
 

	
 
    if (continued && input_redraw)
 
	screen_write_input (buf, -1);
 

	
 
    input_window = cwin;
 
    input_redraw = FALSE;
 

	
 
    /* Get input line from IO interface */
 

	
 
    cwp->x_cursor -= os_string_width (buf);
 
    key = os_read_line (max, buf, timeout, units_left (), continued);
 
    cwp->x_cursor += os_string_width (buf);
 

	
 
    if (key != ZC_TIME_OUT)
 
@@ -774,49 +774,49 @@ void restart_screen (void)
 

	
 
    wp[0].x_size = h_screen_width;
 
    wp[1].x_size = h_screen_width;
 

	
 
    if (h_version <= V3)
 
	wp[7].x_size = h_screen_width;
 

	
 
    os_restart_game (RESTART_WPROP_SET);
 

	
 
    /* Clear the screen, unsplit it and select window 0 */
 

	
 
    erase_screen ((zword) (-1));
 

	
 
}/* restart_screen */
 

	
 
/*
 
 * validate_click
 
 *
 
 * Return false if the last mouse click occured outside the current
 
 * mouse window; otherwise write the mouse arrow coordinates to the
 
 * memory of the header extension table and return true.
 
 *
 
 */
 

	
 
int validate_click (void)
 
bool validate_click (void)
 
{
 

	
 
    if (mwin >= 0) {
 

	
 
	if (mouse_y < wp[mwin].y_pos || mouse_y >= wp[mwin].y_pos + wp[mwin].y_size)
 
	    return FALSE;
 
	if (mouse_x < wp[mwin].x_pos || mouse_x >= wp[mwin].x_pos + wp[mwin].x_size)
 
	    return FALSE;
 

	
 
	hx_mouse_y = mouse_y - wp[mwin].y_pos + 1;
 
	hx_mouse_x = mouse_x - wp[mwin].x_pos + 1;
 

	
 
    } else {
 

	
 
	if (mouse_y < 1 || mouse_y > h_screen_height)
 
	    return FALSE;
 
	if (mouse_x < 1 || mouse_x > h_screen_width)
 
	    return FALSE;
 

	
 
	hx_mouse_y = mouse_y;
 
	hx_mouse_x = mouse_x;
 

	
 
    }
 

	
 
@@ -1135,49 +1135,49 @@ void z_move_window (void)
 
    wp[win].y_pos = zargs[1];
 
    wp[win].x_pos = zargs[2];
 

	
 
    if (win == cwin)
 
	update_cursor ();
 

	
 
}/* z_move_window */
 

	
 
/*
 
 * z_picture_data, get information on a picture or the graphics file.
 
 *
 
 *	zargs[0] = number of picture or 0 for the graphics file
 
 *	zargs[1] = address to write information to
 
 *
 
 */
 

	
 
void z_picture_data (void)
 
{
 
    zword pic = zargs[0];
 
    zword table = zargs[1];
 

	
 
    int height, width;
 
    int i;
 

	
 
    int avail = os_picture_data (pic, &height, &width);
 
    bool avail = os_picture_data (pic, &height, &width);
 

	
 
    for (i = 0; mapper[i].story_id != UNKNOWN; i++)
 

	
 
	if (story_id == mapper[i].story_id) {
 

	
 
	    if (pic == mapper[i].pic) {
 

	
 
		int height2, width2;
 

	
 
		avail &= os_picture_data (mapper[i].pic1, &height2, &width2);
 
		avail &= os_picture_data (mapper[i].pic2, &height2, &width2);
 

	
 
		height += height2;
 

	
 
	    } else if (pic == mapper[i].pic1 || pic == mapper[i].pic2)
 

	
 
		avail = FALSE;
 
	}
 

	
 
    storew ((zword) (table + 0), (zword) (height));
 
    storew ((zword) (table + 2), (zword) (width));
 

	
 
    branch (avail);
 

	
 
@@ -1560,49 +1560,49 @@ static void pad_status_line (int column)
 

	
 
    spaces = units_left () / os_char_width (' ') - column;
 

	
 
    /* while (spaces--) */
 
    /* Justin Wesley's fix for narrow displays (Agenda PDA) */
 
    while (spaces-- > 0)
 
	screen_char (' ');
 

	
 
}/* pad_status_line */
 

	
 
/*
 
 * z_show_status, display the status line for V1 to V3 games.
 
 *
 
 *	no zargs used
 
 *
 
 */
 

	
 
void z_show_status (void)
 
{
 
    zword global0;
 
    zword global1;
 
    zword global2;
 
    zword addr;
 

	
 
    int brief = FALSE;
 
    bool brief = FALSE;
 

	
 
    /* One V5 game (Wishbringer Solid Gold) contains this opcode by
 
       accident, so just return if the version number does not fit */
 

	
 
    if (h_version >= V4)
 
	return;
 

	
 
    /* Read all relevant global variables from the memory of the
 
       Z-machine into local variables */
 

	
 
    addr = h_globals;
 
    LOW_WORD (addr, global0)
 
    addr += 2;
 
    LOW_WORD (addr, global1)
 
    addr += 2;
 
    LOW_WORD (addr, global2)
 

	
 
    /* Frotz uses window 7 for the status line. Don't forget to select
 
       reverse and fixed width text style */
 

	
 
    set_window (7);
 

	
 
    print_char (ZC_NEW_STYLE);
 
    print_char (REVERSE_STYLE | FIXED_WIDTH_STYLE);
backends/frotz/dfrotz/common/setup.h
Show inline comments
 
file renamed from backends/frotz/setup.h to backends/frotz/dfrotz/common/setup.h
backends/frotz/dfrotz/common/sound.c
Show inline comments
 
file renamed from backends/frotz/sound.c to backends/frotz/dfrotz/common/sound.c
 
@@ -15,50 +15,50 @@
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
#include "frotz.h"
 

	
 
#ifdef DJGPP
 
#include "djfrotz.h"
 
#endif
 

	
 
#define EFFECT_PREPARE 1
 
#define EFFECT_PLAY 2
 
#define EFFECT_STOP 3
 
#define EFFECT_FINISH_WITH 4
 

	
 
extern int direct_call (zword);
 

	
 
static zword routine = 0;
 

	
 
static int next_sample = 0;
 
static int next_volume = 0;
 

	
 
static int locked = FALSE;
 
static int playing = FALSE;
 
static bool locked = FALSE;
 
static bool playing = FALSE;
 

	
 
/*
 
 * init_sound
 
 *
 
 * Initialize sound variables.
 
 *
 
 */
 

	
 
void init_sound (void)
 
{
 
    locked = FALSE;
 
    playing = FALSE;
 
} /* init_sound */
 

	
 

	
 
/*
 
 * start_sample
 
 *
 
 * Call the IO interface to play a sample.
 
 *
 
 */
 

	
 
static void start_sample (int number, int volume, int repeats, zword eos)
 
{
backends/frotz/dfrotz/common/stream.c
Show inline comments
 
file renamed from backends/frotz/stream.c to backends/frotz/dfrotz/common/stream.c
 
/* stream.c - IO stream implementation
 
 *	Copyright (c) 1995-1997 Stefan Jokisch
 
 *
 
 * This file is part of Frotz.
 
 *
 
 * Frotz 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.
 
 *
 
 * Frotz is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU General Public License
 
 * along with this program; if not, write to the Free Software
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
 */
 

	
 
#include "frotz.h"
 

	
 
extern int handle_hot_key (zchar);
 
extern bool handle_hot_key (zchar);
 

	
 
extern int validate_click (void);
 
extern bool validate_click (void);
 

	
 
extern void replay_open (void);
 
extern void replay_close (void);
 
extern void memory_open (zword, zword, int);
 
extern void memory_open (zword, zword, bool);
 
extern void memory_close (void);
 
extern void record_open (void);
 
extern void record_close (void);
 
extern void script_open (void);
 
extern void script_close (void);
 

	
 
extern void memory_word (const zchar *);
 
extern void memory_new_line (void);
 
extern void record_write_key (zchar);
 
extern void record_write_input (const zchar *, zchar);
 
extern void script_char (zchar);
 
extern void script_word (const zchar *);
 
extern void script_new_line (void);
 
extern void script_write_input (const zchar *, zchar);
 
extern void script_erase_input (const zchar *);
 
extern void script_mssg_on (void);
 
extern void script_mssg_off (void);
 
extern void screen_char (zchar);
 
extern void screen_word (const zchar *);
 
extern void screen_new_line (void);
 
extern void screen_write_input (const zchar *, zchar);
 
extern void screen_erase_input (const zchar *);
 
extern void screen_mssg_on (void);
 
extern void screen_mssg_off (void);
 

	
 
extern zchar replay_read_key (void);
 
extern zchar replay_read_input (zchar *);
 
extern zchar console_read_key (zword);
 
extern zchar console_read_input (int, zchar *, zword, int);
 
extern zchar console_read_input (int, zchar *, zword, bool);
 

	
 
extern int direct_call (zword);
 

	
 
/*
 
 * stream_mssg_on
 
 *
 
 * Start printing a "debugging" message.
 
 *
 
 */
 

	
 
void stream_mssg_on (void)
 
{
 

	
 
    flush_buffer ();
 

	
 
    if (ostream_screen)
 
	screen_mssg_on ();
 
    if (ostream_script && enable_scripting)
 
	script_mssg_on ();
 

	
 
    message = TRUE;
 

	
 
}/* stream_mssg_on */
 

	
 
@@ -211,49 +211,49 @@ void stream_new_line (void)
 
 *	zargs[0] = input stream to be selected
 
 *
 
 */
 

	
 
void z_input_stream (void)
 
{
 

	
 
    flush_buffer ();
 

	
 
    if (zargs[0] == 0 && istream_replay)
 
	replay_close ();
 
    if (zargs[0] == 1 && !istream_replay)
 
	replay_open ();
 

	
 
}/* z_input_stream */
 

	
 
/*
 
 * stream_read_key
 
 *
 
 * Read a single keystroke from the current input stream.
 
 *
 
 */
 

	
 
zchar stream_read_key ( zword timeout, zword routine,
 
			int hot_keys )
 
			bool hot_keys )
 
{
 
    zchar key = ZC_BAD;
 

	
 
    flush_buffer ();
 

	
 
    /* Read key from current input stream */
 

	
 
continue_input:
 

	
 
    do {
 

	
 
	if (istream_replay)
 
	    key = replay_read_key ();
 
	else
 
	    key = console_read_key (timeout);
 

	
 
    } while (key == ZC_BAD);
 

	
 
    /* Verify mouse clicks */
 

	
 
    if (key == ZC_SINGLE_CLICK || key == ZC_DOUBLE_CLICK)
 
	if (!validate_click ())
 
	    goto continue_input;
 

	
 
@@ -275,50 +275,50 @@ continue_input:
 
	if (h_version == V4 && key == ZC_HKEY_UNDO)
 
	    goto continue_input;
 
	if (!handle_hot_key (key))
 
	    goto continue_input;
 

	
 
	return ZC_BAD;
 

	
 
    }
 

	
 
    /* Return key */
 

	
 
    return key;
 

	
 
}/* stream_read_key */
 

	
 
/*
 
 * stream_read_input
 
 *
 
 * Read a line of input from the current input stream.
 
 *
 
 */
 

	
 
zchar stream_read_input ( int max, zchar *buf,
 
			  zword timeout, zword routine,
 
			  int hot_keys,
 
			  int no_scripting )
 
			  bool hot_keys,
 
			  bool no_scripting )
 
{
 
    zchar key = ZC_BAD;
 

	
 
    flush_buffer ();
 

	
 
    /* Remove initial input from the transscript file or from the screen */
 

	
 
    if (ostream_script && enable_scripting && !no_scripting)
 
	script_erase_input (buf);
 
    if (istream_replay)
 
	screen_erase_input (buf);
 

	
 
    /* Read input line from current input stream */
 

	
 
continue_input:
 

	
 
    do {
 

	
 
	if (istream_replay)
 
	    key = replay_read_input (buf);
 
	else
 
	    key = console_read_input (max, buf, timeout, key != ZC_BAD);
 

	
 
    } while (key == ZC_BAD);
backends/frotz/dfrotz/common/table.c
Show inline comments
 
file renamed from backends/frotz/table.c to backends/frotz/dfrotz/common/table.c
backends/frotz/dfrotz/common/text.c
Show inline comments
 
file renamed from backends/frotz/text.c to backends/frotz/dfrotz/common/text.c
 
@@ -551,66 +551,65 @@ void z_print (void)
 
/*
 
 * z_print_addr, print a string from the lower 64KB.
 
 *
 
 *	zargs[0] = address of string to print
 
 *
 
 */
 

	
 
void z_print_addr (void)
 
{
 

	
 
    decode_text (LOW_STRING, zargs[0]);
 

	
 
}/* z_print_addr */
 

	
 
/*
 
 * z_print_char print a single ZSCII character.
 
 *
 
 *	zargs[0] = ZSCII character to be printed
 
 *
 
 */
 

	
 
void z_print_char (void)
 
{
 

	
 

	
 
    print_char (translate_from_zscii (zargs[0]));
 

	
 
}/* z_print_char */
 

	
 
/*
 
 * z_print_form, print a formatted table.
 
 *
 
 *	zargs[0] = address of formatted table to be printed
 
 *
 
 */
 

	
 
void z_print_form (void)
 
{
 
    zword count;
 
    zword addr = zargs[0];
 

	
 
    int first = TRUE;
 
    bool first = TRUE;
 

	
 
    for (;;) {
 

	
 
	LOW_WORD (addr, count)
 
	addr += 2;
 

	
 
	if (count == 0)
 
	    break;
 

	
 
	if (!first)
 
	    new_line ();
 

	
 
	while (count--) {
 

	
 
	    zbyte c;
 

	
 
	    LOW_BYTE (addr, c)
 
	    addr++;
 

	
 
	    print_char (translate_from_zscii (c));
 

	
 
	}
 

	
 
	first = FALSE;
 
@@ -770,49 +769,49 @@ void z_print_unicode (void)
 
 *
 
 * Scan a dictionary searching for the given word. The first argument
 
 * can be
 
 *
 
 * 0x00 - find the first word which is >= the given one
 
 * 0x05 - find the word which exactly matches the given one
 
 * 0x1f - find the last word which is <= the given one
 
 *
 
 * The return value is 0 if the search fails.
 
 *
 
 */
 

	
 
static zword lookup_text (int padding, zword dct)
 
{
 
    zword entry_addr;
 
    zword entry_count;
 
    zword entry;
 
    zword addr;
 
    zbyte entry_len;
 
    zbyte sep_count;
 
    int resolution = (h_version <= V3) ? 2 : 3;
 
    int entry_number;
 
    int lower, upper;
 
    int i;
 
    int sorted;
 
    bool sorted;
 

	
 
    encode_text (padding);
 

	
 
    LOW_BYTE (dct, sep_count)		/* skip word separators */
 
    dct += 1 + sep_count;
 
    LOW_BYTE (dct, entry_len)		/* get length of entries */
 
    dct += 1;
 
    LOW_WORD (dct, entry_count)		/* get number of entries */
 
    dct += 2;
 

	
 
    if ((short) entry_count < 0) {	/* bad luck, entries aren't sorted */
 

	
 
	entry_count = - (short) entry_count;
 
	sorted = FALSE;
 

	
 
    } else sorted = TRUE;		/* entries are sorted */
 

	
 
    lower = 0;
 
    upper = entry_count - 1;
 

	
 
    while (lower <= upper) {
 

	
 
	if (sorted)                             /* binary search */
 
	    entry_number = (lower + upper) / 2;
 
@@ -852,87 +851,87 @@ static zword lookup_text (int padding, zword dct)
 
    if (padding == 0x05)
 
	return 0;
 

	
 
    entry_number = (padding == 0x00) ? lower : upper;
 

	
 
    if (entry_number == -1 || entry_number == entry_count)
 
	return 0;
 

	
 
    return dct + entry_number * entry_len;
 

	
 
}/* lookup_text */
 

	
 
/*
 
 * tokenise_text
 
 *
 
 * Translate a single word to a token and append it to the token
 
 * buffer. Every token consists of the address of the dictionary
 
 * entry, the length of the word and the offset of the word from
 
 * the start of the text buffer. Unknown words cause empty slots
 
 * if the flag is set (such that the text can be scanned several
 
 * times with different dictionaries); otherwise they are zero.
 
 *
 
 */
 

	
 
static void tokenise_text (zword text, zword length, zword from, zword parse, zword dct, int flag)
 
static void tokenise_text (zword text, zword length, zword from, zword parse, zword dct, bool flag)
 
{
 
    zword addr;
 
    zbyte token_max, token_count;
 

	
 
    LOW_BYTE (parse, token_max)
 
    parse++;
 
    LOW_BYTE (parse, token_count)
 

	
 
    if (token_count < token_max) {	/* sufficient space left for token? */
 

	
 
	storeb (parse++, token_count + 1);
 

	
 
	load_string ((zword) (text + from), length);
 

	
 
	addr = lookup_text (0x05, dct);
 

	
 
	if (addr != 0 || !flag) {
 

	
 
	    parse += 4 * token_count;
 

	
 
	    storew ((zword) (parse + 0), addr);
 
	    storeb ((zword) (parse + 2), length);
 
	    storeb ((zword) (parse + 3), from);
 

	
 
	}
 

	
 
    }
 

	
 
}/* tokenise_text */
 

	
 
/*
 
 * tokenise_line
 
 *
 
 * Split an input line into words and translate the words to tokens.
 
 *
 
 */
 

	
 
void tokenise_line (zword text, zword token, zword dct, int flag)
 
void tokenise_line (zword text, zword token, zword dct, bool flag)
 
{
 
    zword addr1;
 
    zword addr2;
 
    zbyte length;
 
    zbyte c;
 

	
 
    length = 0;		/* makes compilers shut up */
 

	
 
    /* Use standard dictionary if the given dictionary is zero */
 

	
 
    if (dct == 0)
 
	dct = h_dictionary;
 

	
 
    /* Remove all tokens before inserting new ones */
 

	
 
    storeb ((zword) (token + 1), 0);
 

	
 
    /* Move the first pointer across the text buffer searching for the
 
       beginning of a word. If this succeeds, store the position in a
 
       second pointer. Move the first pointer searching for the end of
 
       the word. When it is found, "tokenise" the word. Continue until
 
       the end of the buffer is reached. */
 

	
 
    addr1 = text;
backends/frotz/dfrotz/common/variable.c
Show inline comments
 
file renamed from backends/frotz/variable.c to backends/frotz/dfrotz/common/variable.c
backends/frotz/dfrotz/dumb/dumb_frotz.h
Show inline comments
 
file renamed from backends/frotz/dumb_frotz.h to backends/frotz/dfrotz/dumb/dumb_frotz.h
 
/* dumb-frotz.h
 
 * $Id: dumb-frotz.h,v 1.1.1.1 2002/03/26 22:38:34 feedle Exp $
 
 * Frotz os functions for a standard C library and a dumb terminal.
 
 * Now you can finally play Zork Zero on your Teletype.
 
 *
 
 * Copyright 1997, 1998 Alembic Petrofsky <alembic@petrofsky.berkeley.ca.us>.
 
 * Any use permitted provided this notice stays intact.
 
 */
 
#include "frotz.h"
 
#include "../common/frotz.h"
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <errno.h>
 
#include <string.h>
 
#include <ctype.h>
 
#include <time.h>
 

	
 
#define VERSION "1.0"
 

	
 
/* from ../common/setup.h */
 
extern f_setup_t f_setup;
 
extern void spectrum_get_line(char *s);
 

	
 
/* From input.c.  */
 
int is_terminator (zchar);
 
bool is_terminator (zchar);
 

	
 
/* dumb-input.c */
 
int dumb_handle_setting(const char *setting, int show_cursor, int startup);
 
bool dumb_handle_setting(const char *setting, bool show_cursor, bool startup);
 
void dumb_init_input(void);
 

	
 
/* dumb-output.c */
 
void dumb_init_output(void);
 
int dumb_output_handle_setting(const char *setting, int show_cursor,
 
				int startup);
 
void dumb_show_screen(int show_cursor);
 
void dumb_show_prompt(int show_cursor, char line_type);
 
bool dumb_output_handle_setting(const char *setting, bool show_cursor,
 
				bool startup);
 
void dumb_show_screen(bool show_cursor);
 
void dumb_show_prompt(bool show_cursor, char line_type);
 
void dumb_dump_screen(void);
 
void dumb_display_user_input(char *);
 
void dumb_discard_old_input(int num_chars);
 
void dumb_elide_more_prompt(void);
 
void dumb_set_picture_cell(int row, int col, char c);
 

	
 
/* dumb-pic.c */
 
void dumb_init_pictures(char *graphics_filename);
backends/frotz/dfrotz/dumb/dumb_init.c
Show inline comments
 
file renamed from backends/frotz/dumb_init.c to backends/frotz/dfrotz/dumb/dumb_init.c
 
/* dumb-init.c
 
 * $Id: dumb-init.c,v 1.1.1.1 2002/03/26 22:38:34 feedle Exp $
 
 *
 
 * Copyright 1997,1998 Alva Petrofsky <alva@petrofsky.berkeley.ca.us>.
 
 * Any use permitted provided this notice stays intact.
 
 */
 

	
 
#include "dumb_frotz.h"
 

	
 
#define VERSION 1.0
 

	
 
f_setup_t f_setup;
 

	
 
#define INFORMATION "\
 
An interpreter for all Infocom and other Z-Machine games.\n\
 
Complies with standard 1.0 of Graham Nelson's specification.\n\
 
\n\
 
Syntax: dfrotz [options] story-file\n\
 
  -a   watch attribute setting \t -Q   use old-style save format\n\
 
  -A   watch attribute testing \t -R xxx  do runtime setting \\xxx\n\
 
  -h # screen height           \t    before starting (can be used repeatedly)\n\
 
  -i   ignore fatal errors     \t -s # random number seed value\n\
 
  -I # interpreter number      \t -S # transscript width\n\
 
  -o   watch object movement   \t -t   set Tandy bit\n\
 
  -O   watch object locating   \t -u # slots for multiple undo\n\
 
  -p   plain ASCII output only \t -w # screen width\n\
 
  -P   alter piracy opcode     \t -x   expand abbreviations g/x/z"
 

	
 
/*
 
static char usage[] = "\
 
\n\
 
FROTZ V2.32 - interpreter for all Infocom games. Complies with standard\n\
 
1.0 of Graham Nelson's specification. Written by Stefan Jokisch in 1995-7.\n\
 
\n\
 
DUMB-FROTZ V2.32R1 - port for all platforms.  Somewhat complies with standard\n\
 
@@ -75,58 +73,57 @@ static int zgetopt (int argc, char *argv[], const char *options)
 
    if (argv[zoptind][pos] == 0)
 
	{ pos = 1; zoptind++; }
 
    p = strchr (options, zoptopt);
 
    if (zoptopt == ':' || p == NULL) {
 
	fputs ("illegal option -- ", stderr);
 
	goto error;
 
    } else if (p[1] == ':')
 
	if (zoptind >= argc) {
 
	    fputs ("option requires an argument -- ", stderr);
 
	    goto error;
 
	} else {
 
	    zoptarg = argv[zoptind];
 
	    if (pos != 1)
 
		zoptarg += pos;
 
	    pos = 1; zoptind++;
 
	}
 
    return zoptopt;
 
error:
 
    fputc (zoptopt, stderr);
 
    fputc ('\n', stderr);
 
    return '?';
 
}/* zgetopt */
 

	
 
static int user_screen_width = 75;
 
static int user_screen_height = 100;
 
static int user_screen_height = 24;
 
static int user_interpreter_number = -1;
 
static int user_random_seed = -1;
 
static int user_tandy_bit = 0;
 
static char *graphics_filename = NULL;
 
static int plain_ascii = FALSE;
 
static bool plain_ascii = FALSE;
 

	
 
void os_process_arguments(int argc, char *argv[]) 
 
{
 
	return;
 
    int c;
 

	
 
    /* Parse the options */
 
    do {
 
	c = zgetopt(argc, argv, "aAh:iI:oOpPQs:R:S:tu:w:xZ:");
 
	switch(c) {
 
	  case 'a': f_setup.attribute_assignment = 1; break;
 
	  case 'A': f_setup.attribute_testing = 1; break;
 
	case 'h': user_screen_height = atoi(zoptarg); break;
 
	  case 'i': f_setup.ignore_errors = 1; break;
 
	  case 'I': f_setup.interpreter_number = atoi(zoptarg); break;
 
	  case 'o': f_setup.object_movement = 1; break;
 
	  case 'O': f_setup.object_locating = 1; break;
 
	  case 'P': f_setup.piracy = 1; break;
 
	case 'p': plain_ascii = 1; break;
 
	  case 'Q': f_setup.save_quetzal = 0; break;
 
	case 'R': dumb_handle_setting(zoptarg, FALSE, TRUE); break;
 
	case 's': user_random_seed = atoi(zoptarg); break;
 
	  case 'S': f_setup.script_cols = atoi(zoptarg); break;
 
	case 't': user_tandy_bit = 1; break;
 
	  case 'u': f_setup.undo_slots = atoi(zoptarg); break;
 
	case 'w': user_screen_width = atoi(zoptarg); break;
 
	  case 'x': f_setup.expand_abbreviations = 1; break;
 
	  case 'Z': f_setup.err_report_mode = atoi(zoptarg);
 
@@ -177,49 +174,49 @@ void os_init_screen(void)
 
     * graphics files for), but don't use it for v5 (or Beyond Zork
 
     * will try to use funky characters).  */
 
    h_interpreter_number = h_version == 6 ? INTERP_MSDOS : INTERP_DEC_20;
 
  }
 
  h_interpreter_version = 'F';
 

	
 
  dumb_init_input();
 
  dumb_init_output();
 
  dumb_init_pictures(graphics_filename);
 
}
 

	
 
int os_random_seed (void)
 
{
 
  if (user_random_seed == -1)
 
    /* Use the epoch as seed value */
 
    return (time(0) & 0x7fff);
 
  else return user_random_seed;
 
}
 

	
 
void os_restart_game (int stage) {}
 

	
 
void os_fatal (const char *s)
 
{
 
  fprintf(stderr, "\nFatal error: %s\n", s);
 
//   exit(1);
 
  exit(1);
 
}
 

	
 
FILE *os_path_open(const char *name, const char *mode)
 
{
 
	FILE *fp;
 
	char buf[FILENAME_MAX + 1];
 
	char *p;
 

	
 
	/* Let's see if the file is in the currect directory */
 
	/* or if the user gave us a full path. */
 
	if ((fp = fopen(name, mode))) {
 
		return fp;
 
	}
 
	/* Sorry, but dumb frotz is too dumb to care about searching paths. */
 
	return NULL;
 
}
 

	
 
void os_init_setup(void)
 
{
 
	f_setup.attribute_assignment = 0;
 
	f_setup.attribute_testing = 0;
 
	f_setup.context_lines = 0;
 
	f_setup.object_locating = 0;
 
	f_setup.object_movement = 0;
backends/frotz/dfrotz/dumb/dumb_input.c
Show inline comments
 
file renamed from backends/frotz/dumb_input.c to backends/frotz/dfrotz/dumb/dumb_input.c
 
@@ -33,76 +33,88 @@ static char runtime_usage[] =
 
  "    \\mp      Toggle use of MORE prompts\n"
 
  "    \\ln      Toggle display of line numbers.\n"
 
  "    \\lt      Toggle display of the line type identification chars.\n"
 
  "    \\vb      Toggle visual bell.\n"
 
  "    \\pb      Toggle display of picture outline boxes.\n"
 
  "    (Toggle commands can be followed by a 1 or 0 to set value ON or OFF.)\n"
 
  "  Character Escapes:\n"
 
  "    \\\\  backslash    \\#  backspace    \\[  escape    \\_  return\n"
 
  "    \\< \\> \\^ \\.  cursor motion        \\1 ..\\0  f1..f10\n"
 
  "    \\D ..\\X   Standard Frotz hotkeys.  Use \\H (help) to see the list.\n"
 
  "  Line Type Identification Characters:\n"
 
  "    Input lines:\n"
 
  "      untimed  timed\n"
 
  "      >        T      A regular line-oriented input\n"
 
  "      )        t      A single-character input\n"
 
  "      }        D      A line input with some input before the cursor.\n"
 
  "                         (Use \\d to discard it.)\n"
 
  "    Output lines:\n"
 
  "      ]     Output line that contains the cursor.\n"
 
  "      .     A blank line emitted as part of span compression.\n"
 
  "            (blank) Any other output line.\n"
 
;
 

	
 
static float speed = 1;
 
static int do_more_prompts = FALSE;
 
static bool do_more_prompts = FALSE;
 

	
 
enum input_type {
 
  INPUT_CHAR,
 
  INPUT_LINE,
 
  INPUT_LINE_CONTINUED,
 
};
 

	
 
/* get a character.  Exit with no fuss on EOF.  */
 
static int xgetchar(void)
 
{
 
  int c = getchar();
 
  if (c == EOF) {
 
    if (feof(stdin)) {
 
      fprintf(stderr, "\nEOT\n");
 
      exit(0);
 
    }
 
    os_fatal(strerror(errno));
 
  }
 
  return c;
 
}
 

	
 
/* Read one line, including the newline, into s.  Safely avoids buffer
 
 * overruns (but that's kind of pointless because there are several
 
 * other places where I'm not so careful).  */
 
static void getline_(char *s)
 
{
 
 spectrum_get_line(s);
 
	fflush(stdout);
 
  int c;
 
  char *p = s;
 
  while (p < s + INPUT_BUFFER_SIZE - 1)
 
    if ((*p++ = xgetchar()) == '\n') {
 
      *p = '\0';
 
      return;
 
    }
 
  p[-1] = '\n';
 
  p[0] = '\0';
 
  while ((c = xgetchar()) != '\n')
 
    ;
 
  printf("Line too long, truncated to %s\n", s - INPUT_BUFFER_SIZE);
 
}
 

	
 
/* Translate in place all the escape characters in s.  */
 
static void translate_special_chars(char *s)
 
{
 
  char *src = s, *dest = s;
 
  while (*src)
 
    switch(*src++) {
 
    default: *dest++ = src[-1]; break;
 
    case '\n': *dest++ = ZC_RETURN; break;
 
    case '\\':
 
      switch (*src++) {
 
      case '\n': *dest++ = ZC_RETURN; break;
 
      case '\\': *dest++ = '\\'; break;
 
      case '?': *dest++ = ZC_BACKSPACE; break;
 
      case '[': *dest++ = ZC_ESCAPE; break;
 
      case '_': *dest++ = ZC_RETURN; break;
 
      case '^': *dest++ = ZC_ARROW_UP; break;
 
      case '.': *dest++ = ZC_ARROW_DOWN; break;
 
      case '<': *dest++ = ZC_ARROW_LEFT; break;
 
      case '>': *dest++ = ZC_ARROW_RIGHT; break;
 
      case 'R': *dest++ = ZC_HKEY_RECORD; break;
 
      case 'P': *dest++ = ZC_HKEY_PLAYBACK; break;
 
      case 'S': *dest++ = ZC_HKEY_SEED; break;
 
@@ -110,102 +122,103 @@ static void translate_special_chars(char *s)
 
      case 'N': *dest++ = ZC_HKEY_RESTART; break;
 
      case 'X': *dest++ = ZC_HKEY_QUIT; break;
 
      case 'D': *dest++ = ZC_HKEY_DEBUG; break;
 
      case 'H': *dest++ = ZC_HKEY_HELP; break;
 
      case '1': case '2': case '3': case '4':
 
      case '5': case '6': case '7': case '8': case '9':
 
	*dest++ = ZC_FKEY_MIN + src[-1] - '0' - 1; break;
 
      case '0': *dest++ = ZC_FKEY_MIN + 9; break;
 
      default:
 
	fprintf(stderr, "DUMB-FROTZ: unknown escape char: %c\n", src[-1]);
 
	fprintf(stderr, "Enter \\help to see the list\n");
 
      }
 
    }
 
  *dest = '\0';
 
}
 

	
 

	
 
/* The time in tenths of seconds that the user is ahead of z time.  */
 
static int time_ahead = 0;
 

	
 
/* Called from os_read_key and os_read_line if they have input from
 
 * a previous call to dumb_read_line.
 
 * Returns TRUE if we should timeout rather than use the read-ahead.
 
 * (because the user is further ahead than the timeout).  */
 
static int check_timeout(int timeout)
 
static bool check_timeout(int timeout)
 
{
 
  if ((timeout == 0) || (timeout > time_ahead))
 
    time_ahead = 0;
 
  else
 
    time_ahead -= timeout;
 
  return time_ahead != 0;
 
}
 

	
 
/* If val is '0' or '1', set *var accordingly, otherwise toggle it.  */
 
static void toggle(int *var, char val)
 
static void toggle(bool *var, char val)
 
{
 
  *var = val == '1' || (val != '0' && !*var);
 
}
 

	
 
/* Handle input-related user settings and call dumb_output_handle_setting.  */
 
int dumb_handle_setting(const char *setting, int show_cursor, int startup)
 
bool dumb_handle_setting(const char *setting, bool show_cursor, bool startup)
 
{
 
  if (!strncmp(setting, "sf", 2)) {
 
    speed = atof(&setting[2]);
 
    printf("Speed Factor %g\n", speed);
 
  } else if (!strncmp(setting, "mp", 2)) {
 
    toggle(&do_more_prompts, setting[2]);
 
    printf("More prompts %s\n", do_more_prompts ? "ON" : "OFF");
 
  } else {
 
    if (!strcmp(setting, "set")) {
 
      printf("Speed Factor %g\n", speed);
 
      printf("More Prompts %s\n", do_more_prompts ? "ON" : "OFF");
 
    }
 
    return dumb_output_handle_setting(setting, show_cursor, startup);
 
  }
 
  return TRUE;
 
}
 

	
 
/* Read a line, processing commands (lines that start with a backslash
 
 * (that isn't the start of a special character)), and write the
 
 * first non-command to s.
 
 * Return true if timed-out.  */
 
static int dumb_read_line(char *s, char *prompt, int show_cursor,
 
static bool dumb_read_line(char *s, char *prompt, bool show_cursor,
 
			   int timeout, enum input_type type,
 
			   zchar *continued_line_chars)
 
{
 
  time_t start_time;
 
  
 

	
 
  if (timeout) {
 
    if (time_ahead >= timeout) {
 
      time_ahead -= timeout;
 
      return TRUE;
 
    }
 
    timeout -= time_ahead;
 
    start_time = time(0);
 
  }
 
  time_ahead = 0;
 

	
 
  dumb_show_screen(show_cursor);
 
  for (;;) {
 
    char *command;
 
    if (prompt)
 
      fputs(prompt, stdout);
 
    else
 
      dumb_show_prompt(show_cursor, (timeout ? "tTD" : ")>}")[type]);
 
    getline_(s);
 
    if ((s[0] != '\\') || ((s[1] != '\0') && !islower(s[1]))) {
 
      /* Is not a command line.  */
 
      translate_special_chars(s);
 
      if (timeout) {
 
	int elapsed = (time(0) - start_time) * 10 * speed;
 
	if (elapsed > timeout) {
 
	  time_ahead = elapsed - timeout;
 
	  return TRUE;
 
	}
 
      }
 
      return FALSE;
 
    }
 
    /* Commands.  */
 

	
 
    /* Remove the \ and the terminating newline.  */
 
    command = s + 1;
 
    command[strlen(command) - 1] = '\0';
 
@@ -263,83 +276,83 @@ static int dumb_read_line(char *s, char *prompt, int show_cursor,
 
    } else if (!dumb_handle_setting(command, show_cursor, FALSE)) {
 
      fprintf(stderr, "DUMB-FROTZ: unknown command: %s\n", s);
 
      fprintf(stderr, "Enter \\help to see the list of commands\n");
 
    }
 
  }
 
}
 

	
 
/* Read a line that is not part of z-machine input (more prompts and
 
 * filename requests).  */
 
static void dumb_read_misc_line(char *s, char *prompt)
 
{
 
  dumb_read_line(s, prompt, 0, 0, 0, 0);
 
  /* Remove terminating newline */
 
  s[strlen(s) - 1] = '\0';
 
}
 

	
 
/* For allowing the user to input in a single line keys to be returned
 
 * for several consecutive calls to read_char, with no screen update
 
 * in between.  Useful for traversing menus.  */
 
static char read_key_buffer[INPUT_BUFFER_SIZE];
 

	
 
/* Similar.  Useful for using function key abbreviations.  */
 
static char read_line_buffer[INPUT_BUFFER_SIZE];
 

	
 
zchar os_read_key (int timeout, int show_cursor)
 
zchar os_read_key (int timeout, bool show_cursor)
 
{
 
  char c;
 
  int timed_out;
 

	
 
  /* Discard any keys read for line input.  */
 
  read_line_buffer[0] = '\0';
 

	
 
  if (read_key_buffer[0] == '\0') {
 
    timed_out = dumb_read_line(read_key_buffer, NULL, show_cursor, timeout,
 
			       INPUT_CHAR, NULL);
 
    /* An empty input line is reported as a single CR.
 
     * If there's anything else in the line, we report only the line's
 
     * contents and not the terminating CR.  */
 
    if (strlen(read_key_buffer) > 1)
 
      read_key_buffer[strlen(read_key_buffer) - 1] = '\0';
 
  } else
 
    timed_out = check_timeout(timeout);
 
    
 
  if (timed_out)
 
    return ZC_TIME_OUT;
 

	
 
  c = read_key_buffer[0];
 
  memmove(read_key_buffer, read_key_buffer + 1, strlen(read_key_buffer));
 

	
 
  /* TODO: error messages for invalid special chars.  */
 

	
 
  return c;
 
}
 

	
 
zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
 
{
 
  char *p;
 
  int terminator;
 
  static int timed_out_last_time;
 
  static bool timed_out_last_time;
 
  int timed_out;
 

	
 
  /* Discard any keys read for single key input.  */
 
  read_key_buffer[0] = '\0';
 

	
 
  /* After timing out, discard any further input unless we're continuing.  */
 
  if (timed_out_last_time && !continued)
 
    read_line_buffer[0] = '\0';
 

	
 
  if (read_line_buffer[0] == '\0')
 
    timed_out = dumb_read_line(read_line_buffer, NULL, TRUE, timeout,
 
			       buf[0] ? INPUT_LINE_CONTINUED : INPUT_LINE,
 
			       buf);
 
  else
 
    timed_out = check_timeout(timeout);
 
  
 
  if (timed_out) {
 
    timed_out_last_time = TRUE;
 
    return ZC_TIME_OUT;
 
  }
 
    
 
  /* find the terminating character.  */
 
  for (p = read_line_buffer;; p++) {
 
    if (is_terminator(*p)) {
 
@@ -349,68 +362,67 @@ zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
 
    }
 
  }
 

	
 
  /* TODO: Truncate to width and max.  */
 

	
 
  /* copy to screen */
 
  dumb_display_user_input(read_line_buffer);
 

	
 
  /* copy to the buffer and save the rest for next time.  */
 
  strcat(buf, read_line_buffer);
 
  p = read_line_buffer + strlen(read_line_buffer) + 1;
 
  memmove(read_line_buffer, p, strlen(p) + 1);
 
    
 
  /* If there was just a newline after the terminating character,
 
   * don't save it.  */
 
  if ((read_line_buffer[0] == '\r') && (read_line_buffer[1] == '\0'))
 
    read_line_buffer[0] = '\0';
 

	
 
  timed_out_last_time = FALSE;
 
  return terminator;
 
}
 

	
 
int os_read_file_name (char *file_name, const char *default_name, int flag)
 
{
 
	return FALSE;
 
  char buf[INPUT_BUFFER_SIZE], prompt[INPUT_BUFFER_SIZE];
 
  FILE *fp;
 

	
 
  sprintf(prompt, "Please enter a filename [%s]: ", default_name);
 
  dumb_read_misc_line(buf, prompt);
 
  if (strlen(buf) > MAX_FILE_NAME) {
 
    printf("Filename too long\n");
 
    return FALSE;
 
  }
 

	
 
  strcpy (file_name, buf[0] ? buf : default_name);
 

	
 
  /* Warn if overwriting a file.  */
 
  if ((flag == FILE_SAVE || flag == FILE_SAVE_AUX || flag == FILE_RECORD)
 
      && ((fp = fopen(file_name, "rb")) != NULL)) {
 
    fclose (fp);
 
    dumb_read_misc_line(buf, "Overwrite existing file? ");
 
    return(tolower(buf[0]) == 'y');
 
  }
 
//   if ((flag == FILE_SAVE || flag == FILE_SAVE_AUX || flag == FILE_RECORD)
 
//       && ((fp = fopen(file_name, "rb")) != NULL)) {
 
//     fclose (fp);
 
//     dumb_read_misc_line(buf, "Overwrite existing file? ");
 
//     return(tolower(buf[0]) == 'y');
 
//   }
 
  return TRUE;
 
}
 

	
 
void os_more_prompt (void)
 
{
 
  if (do_more_prompts) {
 
    char buf[INPUT_BUFFER_SIZE];
 
    dumb_read_misc_line(buf, "***MORE***");
 
  } else
 
    dumb_elide_more_prompt();
 
}
 

	
 
void dumb_init_input(void)
 
{
 
  if ((h_version >= V4) && (speed != 0))
 
    h_config |= CONFIG_TIMEDINPUT;
 

	
 
  if (h_version >= V5)
 
    h_flags &= ~(MOUSE_FLAG | MENU_FLAG);
 
}
 

	
 
zword os_read_mouse(void)
 
{
 
	/* NOT IMPLEMENTED */
backends/frotz/dfrotz/dumb/dumb_output.c
Show inline comments
 
file renamed from backends/frotz/dumb_output.c to backends/frotz/dfrotz/dumb/dumb_output.c
 
/* dumb-output.c
 
 * $Id: dumb-output.c,v 1.2 2002/03/26 22:52:31 feedle Exp $
 
 *
 
 * Copyright 1997,1998 Alfresco Petrofsky <alfresco@petrofsky.berkeley.edu>.
 
 * Any use permitted provided this notice stays intact.
 
 */
 

	
 
#include "dumb_frotz.h"
 

	
 
f_setup_t f_setup;
 

	
 
static int show_line_numbers = FALSE;
 
static int show_line_types = -1;
 
static int show_pictures = TRUE;
 
static int visual_bell = TRUE;
 
static int plain_ascii = FALSE;
 
static bool show_line_numbers = FALSE;
 
static bool show_line_types = -1;
 
static bool show_pictures = TRUE;
 
static bool visual_bell = TRUE;
 
static bool plain_ascii = FALSE;
 

	
 
static char latin1_to_ascii[] =
 
  "    !   c   L   >o< Y   |   S   ''  C   a   <<  not -   R   _   "
 
  "^0  +/- ^2  ^3  '   my  P   .   ,   ^1  o   >>  1/4 1/2 3/4 ?   "
 
  "A   A   A   A   Ae  A   AE  C   E   E   E   E   I   I   I   I   "
 
  "Th  N   O   O   O   O   Oe  *   O   U   U   U   Ue  Y   Th  ss  "
 
  "a   a   a   a   ae  a   ae  c   e   e   e   e   i   i   i   i   "
 
  "th  n   o   o   o   o   oe  :   o   u   u   u   ue  y   th  y   "
 
;
 

	
 
/* h_screen_rows * h_screen_cols */
 
static int screen_cells;
 

	
 
/* The in-memory state of the screen.  */
 
/* Each cell contains a style in the upper byte and a char in the lower. */
 
typedef unsigned short cell;
 
static cell *screen_data;
 

	
 
static cell make_cell(int style, char c) {return (style << 8) | (0xff & c);}
 
static char cell_char(cell c) {return c & 0xff;}
 
static int cell_style(cell c) {return c >> 8;}
 

	
 

	
 
/* A cell's style is REVERSE_STYLE, normal (0), or PICTURE_STYLE.
 
@@ -51,66 +51,48 @@ static char *screen_changes;
 

	
 
static int cursor_row = 0, cursor_col = 0;
 

	
 
/* Compression styles.  */
 
static enum {
 
  COMPRESSION_NONE, COMPRESSION_SPANS, COMPRESSION_MAX,
 
} compression_mode = COMPRESSION_SPANS;
 
static char *compression_names[] = {"NONE", "SPANS", "MAX"};
 
static int hide_lines = 0;
 

	
 
/* Reverse-video display styles.  */
 
static enum {
 
  RV_NONE, RV_DOUBLESTRIKE, RV_UNDERLINE, RV_CAPS,
 
} rv_mode = RV_NONE;
 
static char *rv_names[] = {"NONE", "DOUBLESTRIKE", "UNDERLINE", "CAPS"};
 
static char rv_blank_char = ' ';
 

	
 
static cell *dumb_row(int r) {return screen_data + r * h_screen_cols;}
 

	
 
static char *dumb_changes_row(int r)
 
{
 
  return screen_changes + r * h_screen_cols;
 
}
 

	
 
static char array[15000];
 
static char *array_ptr = &array;
 

	
 
char *frotz_get_array() {
 
	return &array;
 
}
 

	
 
void frotz_reset_array() {
 
	array_ptr = &array;
 
	*array_ptr = 0;
 
}
 

	
 
static void myputchar(char c) {
 
	*array_ptr = c;
 
	array_ptr++;
 
	*array_ptr = 0;
 
}
 

	
 
int os_char_width (zchar z)
 
{
 
  if (plain_ascii && z >= ZC_LATIN1_MIN && z <= ZC_LATIN1_MAX) {
 
    char *p = latin1_to_ascii + 4 * (z - ZC_LATIN1_MIN);
 
    return strchr(p, ' ') - p;
 
  }
 
  return 1;
 
}
 

	
 
int os_string_width (const zchar *s)
 
{
 
  int width = 0;
 
  zchar c;
 

	
 
  while ((c = *s++) != 0)
 
    if (c == ZC_NEW_STYLE || c == ZC_NEW_FONT)
 
      s++;
 
    else
 
      width += os_char_width(c);
 

	
 
  return width;
 
}
 

	
 
void os_set_cursor(int row, int col)
 
@@ -236,141 +218,140 @@ void os_scroll_area (int top, int left, int bottom, int right, int units)
 
    for (row = bottom; row >= top - units; row--)
 
      for (col = left; col <= right; col++)
 
	dumb_copy_cell(row, col, row + units, col);
 
    os_erase_area(top + 1, left + 1, top - units, right + 1);
 
  }
 
}
 

	
 
int os_font_data(int font, int *height, int *width)
 
{
 
    if (font == TEXT_FONT) {
 
      *height = 1; *width = 1; return 1;
 
    }
 
    return 0;
 
}
 

	
 
void os_set_colour (int x, int y) {}
 
void os_set_font (int x) {}
 

	
 
/* Print a cell to stdout.  */
 
static void show_cell(cell cel)
 
{
 
  char c = cell_char(cel);
 
  switch (cell_style(cel)) {
 
  case 0:
 
    myputchar(c);
 
    putchar(c);
 
    break;
 
  case PICTURE_STYLE:
 
    myputchar(show_pictures ? c : ' ');
 
    putchar(show_pictures ? c : ' ');
 
    break;
 
  case REVERSE_STYLE:
 
    if (c == ' ')
 
      myputchar(rv_blank_char);
 
      putchar(rv_blank_char);
 
    else
 
      switch (rv_mode) {
 
      case RV_NONE: myputchar(c); break;
 
      case RV_CAPS: myputchar(toupper(c)); break;
 
      case RV_UNDERLINE: myputchar('_'); myputchar('\b'); myputchar(c); break;
 
      case RV_DOUBLESTRIKE: myputchar(c); myputchar('\b'); myputchar(c); break;
 
      case RV_NONE: putchar(c); break;
 
      case RV_CAPS: putchar(toupper(c)); break;
 
      case RV_UNDERLINE: putchar('_'); putchar('\b'); putchar(c); break;
 
      case RV_DOUBLESTRIKE: putchar(c); putchar('\b'); putchar(c); break;
 
      }
 
    break;
 
  }
 
}
 

	
 
static int will_print_blank(cell c)
 
static bool will_print_blank(cell c)
 
{
 
  return (((cell_style(c) == PICTURE_STYLE) && !show_pictures)
 
	  || ((cell_char(c) == ' ')
 
	      && ((cell_style(c) != REVERSE_STYLE) || (rv_blank_char == ' '))));
 
}
 

	
 
static void show_line_prefix(int row, char c)
 
{
 
  if (show_line_numbers)
 
    printf((row == -1) ? ".." : "%02d", (row + 1) % 100);
 
  if (show_line_types)
 
    myputchar(c);
 
    putchar(c);
 
  /* Add a separator char (unless there's nothing to separate).  */
 
  if (show_line_numbers || show_line_types)
 
    myputchar(' ');
 
    putchar(' ');
 
}
 

	
 
/* Print a row to stdout.  */
 
static void show_row(int r)
 
{
 
  if (r == -1) {
 
    show_line_prefix(-1, '.');
 
  } else {
 
    int c, last;
 
    show_line_prefix(r, (r == cursor_row) ? ']' : ' ');
 
    /* Don't print spaces at end of line.  */
 
    /* (Saves bandwidth and printhead wear.)  */
 
    /* TODO: compress spaces to tabs.  */
 
    for (last = h_screen_cols - 1; last >= 0; last--)
 
      if (!will_print_blank(dumb_row(r)[last]))
 
	  break;
 
    for (c = 0; c <= last; c++)
 
      show_cell(dumb_row(r)[c]);
 
  }
 
  myputchar('\n');
 
  putchar('\n');
 
}
 

	
 
/* Print the part of the cursor row before the cursor.  */
 
void dumb_show_prompt(int show_cursor, char line_type)
 
void dumb_show_prompt(bool show_cursor, char line_type)
 
{
 
return;
 
  int i;
 
  show_line_prefix(show_cursor ? cursor_row : -1, line_type);
 
  if (show_cursor)
 
    for (i = 0; i < cursor_col; i++)
 
      show_cell(dumb_row(cursor_row)[i]);
 
}
 

	
 
static void mark_all_unchanged(void)
 
{
 
  memset(screen_changes, 0, screen_cells);
 
}
 

	
 
/* Check if a cell is a blank or will display as one.
 
 * (Used to help decide if contents are worth printing.)  */
 
static int is_blank(cell c)
 
static bool is_blank(cell c)
 
{
 
  return ((cell_char(c) == ' ')
 
	  || ((cell_style(c) == PICTURE_STYLE) && !show_pictures));
 
}
 

	
 
/* Show the current screen contents, or what's changed since the last
 
 * call.
 
 *
 
 * If compressing, and show_cursor is true, and the cursor is past the
 
 * last nonblank character on the last line that would be shown, then
 
 * don't show that line (because it will be redundant with the prompt
 
 * line just below it).  */
 
void dumb_show_screen(int show_cursor)
 
void dumb_show_screen(bool show_cursor)
 
{
 
  int r, c, first, last;
 
  char changed_rows[0x100]; 
 
  printf("show_screen\n");
 

	
 
  /* Easy case */
 
  if (compression_mode == COMPRESSION_NONE) {
 
    for (r = hide_lines; r < h_screen_rows; r++)
 
      show_row(r);
 
    mark_all_unchanged();
 
    return;
 
  }
 

	
 
  /* Check which rows changed, and where the first and last change is.  */
 
  first = last = -1;
 
  memset(changed_rows, 0, h_screen_rows);
 
  for (r = hide_lines; r < h_screen_rows; r++) { 
 
    for (c = 0; c < h_screen_cols; c++)
 
      if (dumb_changes_row(r)[c] && !is_blank(dumb_row(r)[c]))
 
	break;
 
    changed_rows[r] = (c != h_screen_cols);
 
    if (changed_rows[r]) {
 
      first = (first != -1) ? first : r;
 
      last = r;
 
    }
 
  }
 

	
 
  if (first == -1)
 
    return;
 
@@ -413,68 +394,68 @@ void dumb_dump_screen(void)
 
  int r;
 
  for (r = 0; r < h_screen_height; r++)
 
    show_row(r);
 
}
 

	
 
/* Called when it's time for a more prompt but user has them turned off.  */
 
void dumb_elide_more_prompt(void)
 
{
 
  dumb_show_screen(FALSE);
 
  if (compression_mode == COMPRESSION_SPANS && hide_lines == 0) {
 
    show_row(-1);
 
  }
 
}
 

	
 
void os_reset_screen(void)
 
{
 
  dumb_show_screen(FALSE);
 
}
 

	
 
void os_beep (int volume)
 
{
 
  if (visual_bell)
 
    printf("[%s-PITCHED BEEP]\n", (volume == 1) ? "HIGH" : "LOW");
 
  else
 
    myputchar('\a'); /* so much for dumb.  */
 
    putchar('\a'); /* so much for dumb.  */
 
}
 

	
 

	
 
/* To make the common code happy */
 

	
 
void os_prepare_sample (int a) {}
 
void os_finish_with_sample (int a) {}
 
void os_start_sample (int a, int b, int c, zword d) {}
 
void os_stop_sample (int a) {}
 

	
 

	
 
/* if val is '0' or '1', set *var accordingly, else toggle it.  */
 
static void toggle(int *var, char val)
 
static void toggle(bool *var, char val)
 
{
 
  *var = val == '1' || (val != '0' && !*var);
 
}
 

	
 
int dumb_output_handle_setting(const char *setting, int show_cursor,
 
				int startup)
 
bool dumb_output_handle_setting(const char *setting, bool show_cursor,
 
				bool startup)
 
{
 
  char *p;
 
  int i;
 

	
 
  if (!strncmp(setting, "pb", 2)) {
 
    toggle(&show_pictures, setting[2]);
 
    printf("Picture outlines display %s\n", show_pictures ? "ON" : "OFF");
 
    if (startup)
 
      return TRUE;
 
    for (i = 0; i < screen_cells; i++)
 
      screen_changes[i] = (cell_style(screen_data[i]) == PICTURE_STYLE);
 
    dumb_show_screen(show_cursor);
 

	
 
  } else if (!strncmp(setting, "vb", 2)) {
 
    toggle(&visual_bell, setting[2]);
 
    printf("Visual bell %s\n", visual_bell ? "ON" : "OFF");
 
    os_beep(1); os_beep(2);
 

	
 
  } else if (!strncmp(setting, "ln", 2)) {
 
    toggle(&show_line_numbers, setting[2]);
 
    printf("Line numbering %s\n", show_line_numbers ? "ON" : "OFF");
 

	
 
  } else if (!strncmp(setting, "lt", 2)) {
 
    toggle(&show_line_types, setting[2]);
 
@@ -483,66 +464,66 @@ int dumb_output_handle_setting(const char *setting, int show_cursor,
 
  } else if (*setting == 'c') {
 
    switch (setting[1]) {
 
    case 'm': compression_mode = COMPRESSION_MAX; break;
 
    case 's': compression_mode = COMPRESSION_SPANS; break;
 
    case 'n': compression_mode = COMPRESSION_NONE; break;
 
    case 'h': hide_lines = atoi(&setting[2]); break;
 
    default: return FALSE;
 
    }
 
    printf("Compression mode %s, hiding top %d lines\n",
 
	   compression_names[compression_mode], hide_lines);
 

	
 
  } else if (*setting == 'r') {
 
    switch (setting[1]) {
 
    case 'n': rv_mode = RV_NONE; break;
 
    case 'o': rv_mode = RV_DOUBLESTRIKE; break;
 
    case 'u': rv_mode = RV_UNDERLINE; break;
 
    case 'c': rv_mode = RV_CAPS; break;
 
    case 'b': rv_blank_char = setting[2] ? setting[2] : ' '; break;
 
    default: return FALSE;
 
    }
 
    printf("Reverse-video mode %s, blanks reverse to '%c': ",
 
	   rv_names[rv_mode], rv_blank_char);
 
    for (p = "sample reverse text"; *p; p++)
 
      show_cell(make_cell(REVERSE_STYLE, *p));
 
    myputchar('\n');
 
    putchar('\n');
 
    for (i = 0; i < screen_cells; i++)
 
      screen_changes[i] = (cell_style(screen_data[i]) == REVERSE_STYLE);
 
    dumb_show_screen(show_cursor);
 

	
 
  } else if (!strcmp(setting, "set")) {
 
    printf("Compression Mode %s, hiding top %d lines\n",
 
	   compression_names[compression_mode], hide_lines);
 
    printf("Picture Boxes display %s\n", show_pictures ? "ON" : "OFF");
 
    printf("Visual Bell %s\n", visual_bell ? "ON" : "OFF");
 
    os_beep(1); os_beep(2);
 
    printf("Line Numbering %s\n", show_line_numbers ? "ON" : "OFF");
 
    printf("Line-Type display %s\n", show_line_types ? "ON" : "OFF");
 
    printf("Reverse-Video mode %s, Blanks reverse to '%c': ",
 
	   rv_names[rv_mode], rv_blank_char);
 
    for (p = "sample reverse text"; *p; p++)
 
      show_cell(make_cell(REVERSE_STYLE, *p));
 
    myputchar('\n');
 
    putchar('\n');
 
  } else
 
    return FALSE;
 
  return TRUE;
 
}
 

	
 
void dumb_init_output(void)
 
{
 
  if (h_version == V3) {
 
    h_config |= CONFIG_SPLITSCREEN;
 
    h_flags &= ~OLD_SOUND_FLAG;
 
  }
 

	
 
  if (h_version >= V5) {
 
    h_flags &= ~SOUND_FLAG;
 
  }
 

	
 
  h_screen_height = h_screen_rows;
 
  h_screen_width = h_screen_cols;
 
  screen_cells = h_screen_rows * h_screen_cols;
 

	
 
  h_font_width = 1; h_font_height = 1;
 

	
 
  if (show_line_types == -1)
 
    show_line_types = h_version > 3;
backends/frotz/dfrotz/dumb/dumb_pic.c
Show inline comments
 
file renamed from backends/frotz/dumb_pic.c to backends/frotz/dfrotz/dumb/dumb_pic.c
 
@@ -80,49 +80,49 @@ void dumb_init_pictures (char *filename)
 
  if (file)
 
    fclose(file);
 
  if (raw_info)
 
    free(raw_info);
 
  if (success)
 
    h_config |= CONFIG_PICTURES;
 
  else
 
    {
 
      h_flags &= ~GRAPHICS_FLAG;
 
      if (filename)
 
	fprintf(stderr, "Warning: could not read graphics file %s\n", filename);
 
    }
 
}
 

	
 
/* Convert a Z picture number to an index into pict_info.  */
 
static int z_num_to_index(int n)
 
{
 
  int i;
 
  for (i = 0; i <= num_pictures; i++)
 
    if (pict_info[i].z_num == n)
 
      return i;
 
  return -1;
 
}
 

	
 
int os_picture_data(int num, int *height, int *width)
 
bool os_picture_data(int num, int *height, int *width)
 
{
 
  int index;
 

	
 
  *height = 0;
 
  *width = 0;
 

	
 
  if (!pict_info)
 
    return FALSE;
 

	
 
  if ((index = z_num_to_index(num)) == -1)
 
    return FALSE;
 

	
 
  *height = pict_info[index].height;
 
  *width = pict_info[index].width;
 

	
 
  return TRUE;
 
}
 

	
 
void os_draw_picture (int num, int row, int col)
 
{
 
  int width, height, r, c;
 
  if (!os_picture_data(num, &height, &width) || !width || !height)
 
    return;
 
  col--, row--;
backends/frotz/main.cpp
Show inline comments
 
/*
 
 * Copyright (C) 2008-2009 J-P Nurmi jpnurmi@gmail.com
 
 *
 
 * This example is free, and not covered by LGPL license. There is no
 
 * restriction applied to their modification, redistribution, using and so on.
 
 * You can study them, modify them, use them in your own program - either
 
 * completely or partially. By using it you may give me some credits in your
 
 * program, but you don't have to.
 
 */
 

	
 
#include "transport/config.h"
 
#include "transport/networkplugin.h"
 
#include "frotz.h"
 

	
 
#ifndef MSDOS_16BIT
 
#define cdecl
 
#endif
 

	
 
#include <boost/filesystem.hpp>
 
#include "unistd.h"
 
#include "signal.h"
 
#include "sys/wait.h"
 
#include "sys/signal.h"
 
Swift::SimpleEventLoop *loop_;
 

	
 
extern "C" void spectrum_get_line(char *s);
 

	
 
char input[15000];
 

	
 
void send_array();
 

	
 
void spectrum_get_line(char *s) {
 
	std::cout << "running event loop\n";
 
	dumb_show_screen(FALSE);
 
	send_array();
 
// 	while(strlen(input) == 0) {
 
		loop_->run();
 
// 	}
 
	strcpy(s, input);
 
	strcpy(input, "");
 
	std::cout << "got message " << s << "\n";
 
}
 

	
 
using namespace boost::program_options;
 
using namespace Transport;
 

	
 
extern void interpret (void);
 
extern void init_memory (void);
 
extern void init_undo (void);
 
extern void reset_memory (void);
 

	
 
/* Story file name, id number and size */
 

	
 
char *story_name = "zork.z5";
 

	
 
enum story story_id = UNKNOWN;
 
long story_size = 0;
 

	
 
/* Story file header data */
 

	
 
zbyte h_version = 0;
 
zbyte h_config = 0;
 
zword h_release = 0;
 
zword h_resident_size = 0;
 
zword h_start_pc = 0;
 
zword h_dictionary = 0;
 
zword h_objects = 0;
 
zword h_globals = 0;
 
zword h_dynamic_size = 0;
 
zword h_flags = 0;
 
zbyte h_serial[6] = { 0, 0, 0, 0, 0, 0 };
 
zword h_abbreviations = 0;
 
zword h_file_size = 0;
 
zword h_checksum = 0;
 
zbyte h_interpreter_number = 0;
 
zbyte h_interpreter_version = 0;
 
zbyte h_screen_rows = 0;
 
zbyte h_screen_cols = 0;
 
zword h_screen_width = 0;
 
zword h_screen_height = 0;
 
zbyte h_font_height = 1;
 
zbyte h_font_width = 1;
 
zword h_functions_offset = 0;
 
zword h_strings_offset = 0;
 
zbyte h_default_background = 0;
 
zbyte h_default_foreground = 0;
 
zword h_terminating_keys = 0;
 
zword h_line_width = 0;
 
zbyte h_standard_high = 1;
 
zbyte h_standard_low = 0;
 
zword h_alphabet = 0;
 
zword h_extension_table = 0;
 
zbyte h_user_name[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 

	
 
zword hx_table_size = 0;
 
zword hx_mouse_x = 0;
 
zword hx_mouse_y = 0;
 
zword hx_unicode_table = 0;
 

	
 
/* Stack data */
 

	
 
zword stack[STACK_SIZE];
 
zword *sp = 0;
 
zword *fp = 0;
 
zword frame_count = 0;
 

	
 
/* IO streams */
 

	
 
int ostream_screen = TRUE;
 
int ostream_script = FALSE;
 
int ostream_memory = FALSE;
 
int ostream_record = FALSE;
 
int istream_replay = FALSE;
 
int message = FALSE;
 

	
 
/* Current window and mouse data */
 

	
 
int cwin = 0;
 
int mwin = 0;
 

	
 
int mouse_y = 0;
 
int mouse_x = 0;
 

	
 
/* Window attributes */
 

	
 
int enable_wrapping = FALSE;
 
int enable_scripting = FALSE;
 
int enable_scrolling = FALSE;
 
int enable_buffering = FALSE;
 

	
 
/* User options */
 

	
 
/*
 
int option_attribute_assignment = 0;
 
int option_attribute_testing = 0;
 
int option_context_lines = 0;
 
int option_object_locating = 0;
 
int option_object_movement = 0;
 
int option_left_margin = 0;
 
int option_right_margin = 0;
 
int option_ignore_errors = 0;
 
int option_piracy = 0;
 
int option_undo_slots = MAX_UNDO_SLOTS;
 
int option_expand_abbreviations = 0;
 
int option_script_cols = 80;
 
int option_save_quetzal = 1;
 
*/
 

	
 
int option_sound = 1;
 
char *option_zcode_path;
 

	
 

	
 
/* Size of memory to reserve (in bytes) */
 
class FrotzNetworkPlugin;
 
FrotzNetworkPlugin * np = NULL;
 

	
 
long reserve_mem = 0;
 
#define	PARENT_READ	p.readpipe[0]
 
#define	CHILD_WRITE	p.readpipe[1]
 
#define CHILD_READ	p.writepipe[0]
 
#define PARENT_WRITE	p.writepipe[1]
 

	
 
typedef struct dfrotz_ {
 
	pid_t pid;
 
	std::string game;
 
	int readpipe[2];
 
	int writepipe[2];
 
} dfrotz;
 

	
 
using namespace boost::filesystem;
 

	
 
static const char *howtoplay = "To move around, just type the direction you want to go.  Directions can be\n"
 
"abbreviated:  NORTH to N, SOUTH to S, EAST to E, WEST to W, NORTHEAST to\n"
 
"NE, NORTHWEST to NW, SOUTHEAST to SE, SOUTHWEST to SW, UP to U, and DOWN\n"
 
"to D.  IN and OUT will also work in certain places.\n"
 
"\n"
 
"There are many differnet kinds of sentences used in Interactive Fiction.\n"
 
"Here are some examples:\n"
 
"\n"
 
"> WALK TO THE NORTH\n"
 
"> WEST\n"
 
"> NE\n"
 
"> DOWN\n"
 
"> TAKE THE BIRDCAGE\n"
 
"> READ ABOUT DIMWIT FLATHEAD\n"
 
"> LOOK UP MEGABOZ IN THE ENCYCLOPEDIA\n"
 
"> LIE DOWN IN THE PINK SOFA\n"
 
"> EXAMINE THE SHINY COIN\n"
 
"> PUT THE RUSTY KEY IN THE CARDBOARD BOX\n"
 
"> SHOW MY BOW TIE TO THE BOUNCER\n"
 
"> HIT THE CRAWLING CRAB WITH THE GIANT NUTCRACKER\n"
 
"> ASK THE COWARDLY KING ABOUT THE CROWN JEWELS\n"
 
"\n"
 
"You can use multiple objects with certain verbs if you separate them by\n"
 
"the word \"AND\" or by a comma.  Here are some examples:\n"
 
"\n"
 
"> TAKE THE BOOK AND THE FROG\n"
 
"> DROP THE JAR OF PEANUT BUTTER, THE SPOON, AND THE LEMMING FOOD\n"
 
"> PUT THE EGG AND THE PENCIL IN THE CABINET\n"
 
"\n"
 
"You can include several inputs on one line if you separate them by the\n"
 
"word \"THEN\" or by a period.  Each input will be handled in order, as\n"
 
"though you had typed them individually at seperate prompts.  For example,\n"
 
"you could type all of the following at once, before pressing the ENTER (or\n"
 
"RETURN) key:\n"
 
"\n"
 
"> TURN ON THE LIGHT. TAKE THE BOOK THEN READ ABOUT THE JESTER IN THE BOOK\n"
 
"\n"
 
"If the story doesn't understand one of the sentences on your input line,\n"
 
"or if an unusual event occurs, it will ignore the rest of your input line.\n"
 
"\n"
 
"The words \"IT\" and \"ALL\" can be very useful.  For example:\n"
 
"\n"
 
"> EXAMINE THE APPLE.  TAKE IT.  EAT IT\n"
 
"> CLOSE THE HEAVY METAL DOOR.  LOCK IT\n"
 
"> PICK UP THE GREEN BOOT.  SMELL IT.  PUT IT ON.\n"
 
"> TAKE ALL\n"
 
"> TAKE ALL THE TOOLS\n"
 
"> DROP ALL THE TOOLS EXCEPT THE WRENCH AND MINIATURE HAMMER\n"
 
"> TAKE ALL FROM THE CARTON\n"
 
"> GIVE ALL BUT THE RUBY SLIPPERS TO THE WICKED WITCH\n"
 
"\n"
 
"The word \"ALL\" refers to every visible object except those inside\n"
 
"something else.  If there were an apple on the ground and an orange inside\n"
 
"a cabinet, \"TAKE ALL\" would take the apple but not the orange.\n"
 
"\n"
 
"There are three kinds of questions you can ask:  \"WHERE IS (something)\",\n"
 
"\"WHAT IS (something)\", and \"WHO IS (someone)\".  For example:\n"
 
"\n"
 
"> WHO IS LORD DIMWIT?\n"
 
"> WHAT IS A GRUE?\n"
 
"> WHERE IS EVERYBODY?\n"
 
"\n"
 
"When you meet intelligent creatures, you can talk to them by typing their\n"
 
"name, then a comma, then whatever you want to say to them.  Here are some\n"
 
"examples:\n"
 
"\n"
 
"> JESTER, HELLO\n"
 
"> GUSTAR WOOMAX, TELL ME ABOUT THE COCONUT\n"
 
"> UNCLE OTTO, GIVE ME YOUR WALLET\n"
 
"> HORSE, WHERE IS YOUR SADDLE?\n"
 
"> BOY, RUN HOME THEN CALL THE POLICE\n"
 
"> MIGHTY WIZARD, TAKE THIS POISONED APPLE.  EAT IT\n"
 
"\n"
 
"Notice that in the last two examples, you are giving the characters more\n"
 
"than one command on the same input line.  Keep in mind, however, that many\n"
 
"creatures don't care for idle chatter; your actions will speak louder than\n"
 
"your words.  \n";
 

	
 

	
 
static void start_dfrotz(dfrotz &p, const std::string &game) {
 
// 	p.writepipe[0] = -1;
 

	
 
	if (pipe(p.readpipe) < 0 || pipe(p.writepipe) < 0) {
 
	}
 

	
 
/*
 
 * z_piracy, branch if the story file is a legal copy.
 
 *
 
 *	no zargs used
 
 *
 
 */
 
	std::cout << "dfrotz -p " << game << "\n";
 

	
 
void z_piracy (void)
 
{
 
	if ((p.pid = fork()) < 0) {
 
		/* FATAL: cannot fork child */
 
	}
 
	else if (p.pid == 0) {
 
		close(PARENT_WRITE);
 
		close(PARENT_READ);
 

	
 
    branch (!f_setup.piracy);
 
		dup2(CHILD_READ,  0);  close(CHILD_READ);
 
		dup2(CHILD_WRITE, 1);  close(CHILD_WRITE);
 

	
 
}/* z_piracy */
 
		execlp("dfrotz", "-p", game.c_str(), NULL);
 

	
 
class FrotzNetworkPlugin;
 
FrotzNetworkPlugin * np = NULL;
 
	}
 
	else {
 
		close(CHILD_READ);
 
		close(CHILD_WRITE);
 
	}
 
}
 

	
 
class FrotzNetworkPlugin : public NetworkPlugin {
 
	public:
 
		FrotzNetworkPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin(loop, host, port) {
 
			this->config = config;
 
		}
 

	
 
		void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
 
			m_user = user;
 
			np->handleConnected(user);
 
			Swift::StatusShow status;
 
			np->handleBuddyChanged(user, "zork", "Zork", "Games", status.getType());
 
			sleep(1);
 
			np->handleMessage(np->m_user, "zork", first_msg);
 
			np->handleBuddyChanged(user, "zcode", "ZCode", "ZCode", status.getType());
 
// 			sleep(1);
 
// 			np->handleMessage(np->m_user, "zork", first_msg);
 
		}
 

	
 
		void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
 
			exit(0);
 
			if (games.find(user) != games.end()) {
 
				kill(games[user].pid, SIGTERM);
 
				games.erase(user);
 
			}
 
// 			exit(0);
 
		}
 

	
 
		void readMessage(const std::string &user) {
 
			static char buf[15000];
 
			buf[0] = 0;
 
			int repeated = 0;
 
			while (strlen(buf) == 0) {
 
				ssize_t len = read(games[user].readpipe[0], buf, 15000);
 
				if (len > 0) {
 
					buf[len] = 0;
 
				}
 
				usleep(1000);
 
				repeated++;
 
				if (repeated > 30)
 
					return;
 
			}
 
			np->handleMessage(user, "zcode", buf);
 

	
 
			std::string msg = "save\n";
 
			write(games[user].writepipe[1], msg.c_str(), msg.size());
 

	
 
			msg = user + "_" + games[user].game + ".save\n";
 
			write(games[user].writepipe[1], msg.c_str(), msg.size());
 
			ignoreMessage(user);
 
		}
 

	
 
		void ignoreMessage(const std::string &user) {
 
			usleep(1000000);
 
			static char buf[15000];
 
			buf[0] = 0;
 
			int repeated = 0;
 
			while (strlen(buf) == 0) {
 
				ssize_t len = read(games[user].readpipe[0], buf, 15000);
 
				if (len > 0) {
 
					buf[len] = 0;
 
				}
 
				usleep(1000);
 
				repeated++;
 
				if (repeated > 30)
 
					return;
 
			}
 

	
 
			std::cout << "ignoring: " << buf << "\n";
 
		}
 

	
 
		std::vector<std::string> getGames() {
 
			std::vector<std::string> games;
 
			path p(".");
 
			directory_iterator end_itr;
 
			for (directory_iterator itr(p); itr != end_itr; ++itr) {
 
				if (extension(itr->path()) == ".z5") {
 
					games.push_back(itr->path().leaf().string());
 
				}
 
			}
 
			return games;
 
		}
 

	
 
		void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &/*xhtml*/) {
 
			std::string msg = message + "\n";
 
			strcpy(input, msg.c_str());
 
			loop_->stop();
 
			if (message.find("start") == 0) {
 
				std::string game = message.substr(6);
 
				std::vector<std::string> lst = getGames();
 
				if (std::find(lst.begin(), lst.end(), game) == lst.end()) {
 
					np->handleMessage(user, "zcode", "Unknown game");
 
					return;
 
				}
 
				np->handleMessage(user, "zcode", "Starting the game");
 

	
 
				dfrotz d;
 
				d.game = game;
 
				start_dfrotz(d, game);
 
				games[user] = d;
 
				fcntl(games[user].readpipe[0], F_SETFL, O_NONBLOCK);
 

	
 
				if (boost::filesystem::exists(user + "_" + games[user].game + ".save")) {
 

	
 
					std::string msg = "restore\n";
 
					write(games[user].writepipe[1], msg.c_str(), msg.size());
 

	
 
					msg = user + "_" + games[user].game + ".save\n";
 
					write(games[user].writepipe[1], msg.c_str(), msg.size());
 

	
 
					ignoreMessage(user);
 

	
 
					msg = "l\n";
 
					write(games[user].writepipe[1], msg.c_str(), msg.size());
 
				}
 

	
 
				readMessage(user);
 
			}
 
			else if (message == "stop" && games.find(user) != games.end()) {
 
				kill(games[user].pid, SIGTERM);
 
				games.erase(user);
 
				np->handleMessage(user, "zcode", "Game stopped");
 
			}
 
			else if (message == "howtoplay") {
 
				np->handleMessage(user, "zcode", howtoplay);
 
			}
 
			else if (games.find(user) != games.end()) {
 
				std::string msg = message + "\n";
 
				write(games[user].writepipe[1], msg.c_str(), msg.size());
 
				readMessage(user);
 
			}
 
			else {
 
				std::string games;
 
				BOOST_FOREACH(const std::string &game, getGames()) {
 
					games += game + "\n";
 
				}
 
				np->handleMessage(user, "zcode", "Games are saved/loaded automatically. Use \"restart\" to restart existing game. Emulator commands are:\nstart <game>\nstop\nhowtoplay\n\nList of games:\n" + games);
 
			}
 
		}
 

	
 
		void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
 
		}
 

	
 
		void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
 
		}
 

	
 
		std::string m_user;
 
		std::map<std::string, dfrotz> games;
 
		std::string first_msg;
 
	private:
 
		
 
		Config *config;
 
};
 

	
 
void send_array() {
 
	if (np->first_msg.empty())
 
		np->first_msg = frotz_get_array();
 
	else
 
		np->handleMessage(np->m_user, "zork", frotz_get_array());
 
	frotz_reset_array();
 
static void spectrum_sigchld_handler(int sig)
 
{
 
	int status;
 
	pid_t pid;
 

	
 
	do {
 
		pid = waitpid(-1, &status, WNOHANG);
 
	} while (pid != 0 && pid != (pid_t)-1);
 

	
 
	if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
 
		char errmsg[BUFSIZ];
 
		snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
 
		perror(errmsg);
 
	}
 
}
 

	
 

	
 
int main (int argc, char* argv[]) {
 
	std::string host;
 
	int port;
 

	
 
	if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
 
		std::cout << "SIGCHLD handler can't be set\n";
 
		return -1;
 
	}
 

	
 
	boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <config_file.cfg>\nAllowed options");
 
	desc.add_options()
 
		("host,h", value<std::string>(&host), "host")
 
		("port,p", value<int>(&port), "port")
 
		;
 
	try
 
	{
 
		boost::program_options::variables_map vm;
 
		boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
 
		boost::program_options::notify(vm);
 
	}
 
	catch (std::runtime_error& e)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 
	catch (...)
 
	{
 
		std::cout << desc << "\n";
 
		exit(1);
 
	}
 

	
 

	
 
	if (argc < 5) {
 
		return 1;
 
	}
 

	
 
// 	QStringList channels;
 
// 	for (int i = 3; i < argc; ++i)
 
// 	{
 
// 		channels.append(argv[i]);
 
// 	}
 
// 
 
// 	MyIrcSession session;
 
// 	session.setNick(argv[2]);
 
// 	session.setAutoJoinChannels(channels);
 
// 	session.connectToServer(argv[1], 6667);
 

	
 
	Config config;
 
	if (!config.load(argv[5])) {
 
		std::cerr << "Can't open " << argv[1] << " configuration file.\n";
 
		return 1;
 
	}
 

	
 
	Swift::SimpleEventLoop eventLoop;
 
	loop_ = &eventLoop;
 
	np = new FrotzNetworkPlugin(&config, &eventLoop, host, port);
 

	
 
	os_init_setup ();
 
	os_process_arguments (argc, argv);
 
	init_buffer ();
 
	init_err ();
 
	init_memory ();
 
	init_process ();
 
	init_sound ();
 
	os_init_screen ();
 
	init_undo ();
 
	z_restart ();
 
	interpret ();
 
	reset_memory ();
 
	os_reset_screen ();
 
	loop_->run();
 

	
 
	return 0;
 
}
backends/frotz/soundcard.h
Show inline comments
 
deleted file
spectrum/src/sample.cfg
Show inline comments
 
[service]
 
jid = localhost
 
password = secret
 
server = 127.0.0.1
 
port = 5222
 
server_mode = 1
 
backend_host=localhost # < this option doesn't work yet
 
backend_port=10001
 
admin_username=admin
 
admin_password=test
 
#cert=server.pfx #patch to PKCS#12 certificate
 
#cert_password=test #password to that certificate if any
 
users_per_backend=10
 
backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum_libpurple_backend
 
#backend=/home/hanzz/code/libtransport/backends/libpurple/spectrum_libpurple_backend
 
backend=/home/hanzz/code/libtransport/backends/frotz/spectrum_frotz_backend
 
#backend=../../backends/libircclient-qt/spectrum_libircclient-qt_backend
 
#protocol=prpl-msn
 
protocol=any
 
#protocol=prpl-icq
 

	
 
[backend]
 
#default_avatar=catmelonhead.jpg
 
#no_vcard_fetch=true
 

	
 
[logging]
 
#config=logging.cfg # log4cxx/log4j logging configuration file
 
#backend_config=backend_logging.cfg # log4cxx/log4j logging configuration file for backends
 

	
 
[database]
 
type = none # or "none" without database backend
 
database = test.sql
 
prefix=icq
0 comments (0 inline, 0 general)