Finished frotz backend :)
This commit is contained in:
parent
64a0a5d6b5
commit
a22b6e1490
33 changed files with 603 additions and 347 deletions
|
@ -1,4 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
ADD_SUBDIRECTORY(dfrotz)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum_frotz_backend ${SRC})
|
||||
|
|
9
backends/frotz/dfrotz/CMakeLists.txt
Normal file
9
backends/frotz/dfrotz/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
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)
|
||||
|
2
backends/frotz/dfrotz/README
Normal file
2
backends/frotz/dfrotz/README
Normal file
|
@ -0,0 +1,2 @@
|
|||
This is patched version of dfrotz. frotz_backend won't work with dfrotz from
|
||||
your distribution.
|
|
@ -38,7 +38,7 @@ static zchar prev_c = 0;
|
|||
|
||||
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
|
||||
|
@ -79,7 +79,7 @@ void flush_buffer (void)
|
|||
|
||||
void print_char (zchar c)
|
||||
{
|
||||
static int flag = FALSE;
|
||||
static bool flag = FALSE;
|
||||
|
||||
if (message || ostream_memory || enable_buffering) {
|
||||
|
|
@ -524,7 +524,7 @@ void storew (zword addr, zword value)
|
|||
|
||||
void z_restart (void)
|
||||
{
|
||||
static int first_restart = TRUE;
|
||||
static bool first_restart = TRUE;
|
||||
|
||||
flush_buffer ();
|
||||
|
|
@ -28,11 +28,11 @@
|
|||
#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;
|
||||
|
@ -63,7 +63,7 @@ static FILE *pfp = NULL;
|
|||
|
||||
void script_open (void)
|
||||
{
|
||||
static int script_valid = FALSE;
|
||||
static bool script_valid = FALSE;
|
||||
|
||||
char new_name[MAX_FILE_NAME + 1];
|
||||
|
||||
|
@ -325,7 +325,7 @@ void record_close (void)
|
|||
*
|
||||
*/
|
||||
|
||||
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) {
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* 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. */
|
||||
|
||||
|
@ -13,10 +13,7 @@
|
|||
|
||||
#ifndef __UNIX_PORT_FILE
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef int bool;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
|
@ -355,12 +352,12 @@ 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;
|
||||
|
@ -368,10 +365,10 @@ 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 */
|
||||
|
@ -578,7 +575,7 @@ 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);
|
||||
|
@ -617,20 +614,4 @@ 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
|
|
@ -24,7 +24,7 @@ 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);
|
||||
|
@ -40,7 +40,7 @@ extern void seed_random (int);
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_debugging (void)
|
||||
static bool hot_key_debugging (void)
|
||||
{
|
||||
|
||||
print_string ("Debugging options\n");
|
||||
|
@ -62,7 +62,7 @@ static int hot_key_debugging (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_help (void) {
|
||||
static bool hot_key_help (void) {
|
||||
|
||||
print_string ("Help\n");
|
||||
|
||||
|
@ -88,7 +88,7 @@ static int hot_key_help (void) {
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_playback (void)
|
||||
static bool hot_key_playback (void)
|
||||
{
|
||||
|
||||
print_string ("Playback on\n");
|
||||
|
@ -107,7 +107,7 @@ static int hot_key_playback (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_recording (void)
|
||||
static bool hot_key_recording (void)
|
||||
{
|
||||
|
||||
if (istream_replay) {
|
||||
|
@ -132,7 +132,7 @@ static int hot_key_recording (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_seed (void)
|
||||
static bool hot_key_seed (void)
|
||||
{
|
||||
|
||||
print_string ("Seed random numbers\n");
|
||||
|
@ -151,7 +151,7 @@ static int hot_key_seed (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_undo (void)
|
||||
static bool hot_key_undo (void)
|
||||
{
|
||||
|
||||
print_string ("Undo one turn\n");
|
||||
|
@ -181,7 +181,7 @@ static int hot_key_undo (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_restart (void)
|
||||
static bool hot_key_restart (void)
|
||||
{
|
||||
|
||||
print_string ("New game\n");
|
||||
|
@ -202,7 +202,7 @@ static int hot_key_restart (void)
|
|||
*
|
||||
*/
|
||||
|
||||
static int hot_key_quit (void)
|
||||
static bool hot_key_quit (void)
|
||||
{
|
||||
|
||||
print_string ("Exit game\n");
|
||||
|
@ -224,12 +224,12 @@ static int hot_key_quit (void)
|
|||
*
|
||||
*/
|
||||
|
||||
int handle_hot_key (zchar key)
|
||||
bool handle_hot_key (zchar key)
|
||||
{
|
||||
|
||||
if (cwin == 0) {
|
||||
|
||||
int aborting;
|
||||
bool aborting;
|
||||
|
||||
aborting = FALSE;
|
||||
|
|
@ -22,10 +22,10 @@
|
|||
|
||||
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
|
||||
|
@ -34,7 +34,7 @@ extern void tokenise_line (zword, zword, zword, int);
|
|||
*
|
||||
*/
|
||||
|
||||
int is_terminator (zchar key)
|
||||
bool is_terminator (zchar key)
|
||||
{
|
||||
|
||||
if (key == ZC_TIME_OUT)
|
||||
|
@ -90,7 +90,7 @@ void z_make_menu (void)
|
|||
*
|
||||
*/
|
||||
|
||||
int read_yes_or_no (const char *s)
|
||||
bool read_yes_or_no (const char *s)
|
||||
{
|
||||
zchar key;
|
||||
|
197
backends/frotz/dfrotz/common/main.c
Normal file
197
backends/frotz/dfrotz/common/main.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/* 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 */
|
|
@ -446,7 +446,7 @@ void ret (zword value)
|
|||
*
|
||||
*/
|
||||
|
||||
void branch (int flag)
|
||||
void branch (bool flag)
|
||||
{
|
||||
long pc;
|
||||
zword offset;
|
|
@ -99,7 +99,7 @@ static zword frames[STACK_SIZE/4+1];
|
|||
(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;
|
||||
|
||||
|
@ -111,7 +111,7 @@ static int read_word (FILE *f, zword *result)
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
|
@ -40,7 +40,7 @@ static struct {
|
|||
*
|
||||
*/
|
||||
|
||||
void memory_open (zword table, zword xsize, int buffering)
|
||||
void memory_open (zword table, zword xsize, bool buffering)
|
||||
{
|
||||
|
||||
if (++depth < MAX_NESTING) {
|
|
@ -42,10 +42,10 @@ static struct {
|
|||
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;
|
||||
|
||||
|
@ -157,7 +157,7 @@ static void reset_cursor (zword win)
|
|||
*
|
||||
*/
|
||||
|
||||
void set_more_prompts (int flag)
|
||||
void set_more_prompts (bool flag)
|
||||
{
|
||||
|
||||
if (flag && !more_prompts)
|
||||
|
@ -439,7 +439,7 @@ void screen_erase_input (const zchar *buf)
|
|||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
|
@ -795,7 +795,7 @@ void restart_screen (void)
|
|||
*
|
||||
*/
|
||||
|
||||
int validate_click (void)
|
||||
bool validate_click (void)
|
||||
{
|
||||
|
||||
if (mwin >= 0) {
|
||||
|
@ -1156,7 +1156,7 @@ void z_picture_data (void)
|
|||
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++)
|
||||
|
||||
|
@ -1581,7 +1581,7 @@ void z_show_status (void)
|
|||
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 */
|
|
@ -36,8 +36,8 @@ 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
|
|
@ -20,13 +20,13 @@
|
|||
|
||||
#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);
|
||||
|
@ -55,7 +55,7 @@ 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);
|
||||
|
||||
|
@ -232,7 +232,7 @@ void z_input_stream (void)
|
|||
*/
|
||||
|
||||
zchar stream_read_key ( zword timeout, zword routine,
|
||||
int hot_keys )
|
||||
bool hot_keys )
|
||||
{
|
||||
zchar key = ZC_BAD;
|
||||
|
||||
|
@ -296,8 +296,8 @@ continue_input:
|
|||
|
||||
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;
|
||||
|
|
@ -572,7 +572,6 @@ void z_print_addr (void)
|
|||
void z_print_char (void)
|
||||
{
|
||||
|
||||
|
||||
print_char (translate_from_zscii (zargs[0]));
|
||||
|
||||
}/* z_print_char */
|
||||
|
@ -589,7 +588,7 @@ void z_print_form (void)
|
|||
zword count;
|
||||
zword addr = zargs[0];
|
||||
|
||||
int first = TRUE;
|
||||
bool first = TRUE;
|
||||
|
||||
for (;;) {
|
||||
|
||||
|
@ -791,7 +790,7 @@ static zword lookup_text (int padding, zword dct)
|
|||
int entry_number;
|
||||
int lower, upper;
|
||||
int i;
|
||||
int sorted;
|
||||
bool sorted;
|
||||
|
||||
encode_text (padding);
|
||||
|
||||
|
@ -873,7 +872,7 @@ static zword lookup_text (int padding, zword dct)
|
|||
*
|
||||
*/
|
||||
|
||||
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;
|
||||
|
@ -911,7 +910,7 @@ static void tokenise_text (zword text, zword length, zword from, zword parse, zw
|
|||
*
|
||||
*/
|
||||
|
||||
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;
|
|
@ -6,7 +6,7 @@
|
|||
* 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>
|
||||
|
@ -14,23 +14,24 @@
|
|||
#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);
|
|
@ -7,8 +7,6 @@
|
|||
|
||||
#include "dumb_frotz.h"
|
||||
|
||||
#define VERSION 1.0
|
||||
|
||||
f_setup_t f_setup;
|
||||
|
||||
#define INFORMATION "\
|
||||
|
@ -96,16 +94,15 @@ error:
|
|||
}/* 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 */
|
||||
|
@ -198,7 +195,7 @@ 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)
|
|
@ -54,7 +54,7 @@ static char runtime_usage[] =
|
|||
;
|
||||
|
||||
static float speed = 1;
|
||||
static int do_more_prompts = FALSE;
|
||||
static bool do_more_prompts = FALSE;
|
||||
|
||||
enum input_type {
|
||||
INPUT_CHAR,
|
||||
|
@ -81,7 +81,19 @@ static int xgetchar(void)
|
|||
* 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. */
|
||||
|
@ -131,7 +143,7 @@ static int time_ahead = 0;
|
|||
* 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;
|
||||
|
@ -141,13 +153,13 @@ static int check_timeout(int timeout)
|
|||
}
|
||||
|
||||
/* 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]);
|
||||
|
@ -169,12 +181,12 @@ int dumb_handle_setting(const char *setting, int show_cursor, int startup)
|
|||
* (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;
|
||||
|
@ -185,6 +197,7 @@ static int dumb_read_line(char *s, char *prompt, int show_cursor,
|
|||
}
|
||||
time_ahead = 0;
|
||||
|
||||
dumb_show_screen(show_cursor);
|
||||
for (;;) {
|
||||
char *command;
|
||||
if (prompt)
|
||||
|
@ -284,7 +297,7 @@ 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;
|
||||
|
@ -318,7 +331,7 @@ 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. */
|
||||
|
@ -370,7 +383,6 @@ zchar os_read_line (int max, zchar *buf, int timeout, int width, int continued)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -384,12 +396,12 @@ int os_read_file_name (char *file_name, const char *default_name, int flag)
|
|||
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;
|
||||
}
|
||||
|
|
@ -9,11 +9,11 @@
|
|||
|
||||
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 _ "
|
||||
|
@ -72,24 +72,6 @@ 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) {
|
||||
|
@ -257,26 +239,26 @@ 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) == ' ')
|
||||
|
@ -288,10 +270,10 @@ 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. */
|
||||
|
@ -311,13 +293,12 @@ static void show_row(int r)
|
|||
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)
|
||||
|
@ -332,7 +313,7 @@ static void mark_all_unchanged(void)
|
|||
|
||||
/* 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));
|
||||
|
@ -345,11 +326,11 @@ static int is_blank(cell c)
|
|||
* 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++)
|
||||
|
@ -434,7 +415,7 @@ 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. */
|
||||
}
|
||||
|
||||
|
||||
|
@ -447,13 +428,13 @@ 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;
|
||||
|
@ -504,7 +485,7 @@ int dumb_output_handle_setting(const char *setting, int show_cursor,
|
|||
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);
|
||||
|
@ -521,7 +502,7 @@ int dumb_output_handle_setting(const char *setting, int show_cursor,
|
|||
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;
|
|
@ -101,7 +101,7 @@ static int z_num_to_index(int n)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int os_picture_data(int num, int *height, int *width)
|
||||
bool os_picture_data(int num, int *height, int *width)
|
||||
{
|
||||
int index;
|
||||
|
|
@ -10,162 +10,139 @@
|
|||
|
||||
#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) */
|
||||
|
||||
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 */
|
||||
|
||||
class FrotzNetworkPlugin;
|
||||
FrotzNetworkPlugin * np = NULL;
|
||||
|
||||
#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) {
|
||||
}
|
||||
|
||||
std::cout << "dfrotz -p " << game << "\n";
|
||||
|
||||
if ((p.pid = fork()) < 0) {
|
||||
/* FATAL: cannot fork child */
|
||||
}
|
||||
else if (p.pid == 0) {
|
||||
close(PARENT_WRITE);
|
||||
close(PARENT_READ);
|
||||
|
||||
dup2(CHILD_READ, 0); close(CHILD_READ);
|
||||
dup2(CHILD_WRITE, 1); close(CHILD_WRITE);
|
||||
|
||||
execlp("dfrotz", "-p", game.c_str(), 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) {
|
||||
|
@ -173,22 +150,128 @@ class FrotzNetworkPlugin : public NetworkPlugin {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -197,25 +280,38 @@ class FrotzNetworkPlugin : public NetworkPlugin {
|
|||
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()
|
||||
|
@ -264,20 +360,7 @@ int main (int argc, char* argv[]) {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* This file automatically generated by findsound.sh which run by the
|
||||
* Makefile found in the Unix Frotz 2.43 source distribution.
|
||||
* Copying this nasty hack to find headers which may be in any of several
|
||||
* places is not recommended. I don't want to use autoconf just yet for
|
||||
* this project.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/soundcard.h>
|
|
@ -11,7 +11,8 @@ 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
|
||||
|
|
Loading…
Add table
Reference in a new issue