mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
658 lines
13 KiB
C
658 lines
13 KiB
C
#include "cpyrt.h" /* DRI copyright message */
|
||
/****************************************************************************/
|
||
/* */
|
||
/* The source code contained in this listing is a proprietary trade */
|
||
/* secret of Digital Research Inc., Pacific Grove, California and is */
|
||
/* copyrighted as an unpublished work pursuant to Section 408 of */
|
||
/* Title 17 of the United States Code. Unauthorized copying, */
|
||
/* adaptation, distribution, use or display is prohibited by law. */
|
||
/* */
|
||
/* Author: xxxxxxxxxxx */
|
||
/* PRODUCT: MAZE VidLink Program */
|
||
/* Module: mazefn */
|
||
/* */
|
||
/****************************************************************************/
|
||
|
||
/****************************************************************************/
|
||
/* */
|
||
/* MAZE Module: MAZEFN, Maze Function */
|
||
/* ----------------------------- */
|
||
/* */
|
||
/* This is the MAZE function module. This module */
|
||
/* provides the VidLink Maze Program functions. */
|
||
/* */
|
||
/* The following routines are present: */
|
||
/* */
|
||
/* maze MAZE function */
|
||
/* */
|
||
/* The following routines are called: */
|
||
/* */
|
||
/* xxxxxxxxx xxxxxxxxxxxxxxxx */
|
||
/* */
|
||
/* Revision History: */
|
||
/* */
|
||
/* 06/20/84 by xxxxxxxxxxxx */
|
||
/* */
|
||
/****************************************************************************/
|
||
|
||
/*
|
||
* Include Files
|
||
*/ /****************************/
|
||
#include "portab.h" /* DRI portable coding conv */
|
||
/****************************/
|
||
#include "ascii.h" /* ASCII character defines */
|
||
/****************************/
|
||
#include "color.h" /* color defines */
|
||
/****************************/
|
||
#include "graph.h" /* graphics chars */
|
||
/****************************/
|
||
|
||
/*#page*/
|
||
/*
|
||
* External Data/Functions:
|
||
*/
|
||
|
||
#include "vcrt.d"
|
||
|
||
#include "mazex.d" /* maze function extrnl data*/
|
||
|
||
EXTERN WORD vdpiof();
|
||
|
||
EXTERN WORD VIOSTAT();
|
||
|
||
|
||
/*#page*/
|
||
/*
|
||
* Local Data/Functions:
|
||
*/
|
||
#define MAX_PLAYERS 6
|
||
#define QMAX 4000 /* size of question buffer */
|
||
#define AMAX 40 /* size of answer buffer */
|
||
#define RETURN 0x0d /* carriage return */
|
||
#define BACKSP 0x09 /* backspace ?? */
|
||
|
||
struct scene =
|
||
{
|
||
UWORD start;
|
||
UWORD finish;
|
||
BYTE right;
|
||
BYTE wrong;
|
||
};
|
||
|
||
struct scene intro [] =
|
||
{
|
||
/* 01 */ 00150, 01482, 02, 00,
|
||
/* 02 */ 01800, 02120, 00, 00
|
||
};
|
||
|
||
struct scene nightmare_castle [] =
|
||
{
|
||
/ * 01 */ 02138, 02202, 02, 01
|
||
};
|
||
|
||
struct scene blast_off [] =
|
||
{
|
||
/* 01 */ 00000, 00000, 00, 00
|
||
};
|
||
|
||
struct scene first_and_ten [] =
|
||
{
|
||
/* 01 */ 00000, 00000, 00, 00
|
||
};
|
||
|
||
struct scene shoot_out [] =
|
||
{
|
||
/* 01 */ 00000, 00000, 00, 00
|
||
};
|
||
|
||
struct player_state =
|
||
{
|
||
BYTE score;
|
||
UBYTE adventure;
|
||
UBYTE scene;
|
||
UBYTE group;
|
||
BOOLEAN bonus;
|
||
};
|
||
|
||
struct player_state player [MAX_PLAYERS];
|
||
|
||
BYTE c_scene; /* current scene */
|
||
BYTE c_player; /* current player */
|
||
BYTE last_player; /* last player number */
|
||
|
||
UBYTE row; /* current row */
|
||
|
||
UBYTE q_buffer[QMAX]; /* question buffer */
|
||
UBYTE eoq; /* TRUE if end of question file */
|
||
UWORD q_size; /* size of q_buffer (normally QMAX) */
|
||
UWORD q_next; /* next q_buffer to fill */
|
||
UWORD g_next; /* next group number */
|
||
UWORD g_count; /* group count */
|
||
UWORD g_base; /* group base */
|
||
UBYTE g_max; /* used to find next question */
|
||
|
||
UBYTE ans[AMAX]; /* answer buffer */
|
||
UBYTE a_size; /* current answer size */
|
||
|
||
/*#page*/
|
||
/****************************************************************************/
|
||
/* */
|
||
/* xxxxxxxx */
|
||
/* -------- */
|
||
/* */
|
||
/* This subroutine performs the xxxxxxxxxxxxxxxxxxxxxxxx. */
|
||
/* */
|
||
/****************************************************************************/
|
||
GLOBAL maze(argc,argv)
|
||
/****************************/
|
||
WORD argc; /* cmd tail argument count */
|
||
CHAR *argv[]; /* cmd tail string pointers */
|
||
{ /***** begin maze *****/
|
||
CHAR c;
|
||
|
||
|
||
#ifdef CPU_65
|
||
d_ouchar(14); /* switch to lower case */
|
||
#endif
|
||
clear();
|
||
sign_on();
|
||
vdpiof("VC");
|
||
p_inchar();
|
||
|
||
clear();
|
||
set_row(5);
|
||
l_outstr(" Do you want to see");
|
||
set_row(6);
|
||
l_outstr(" the Introduction (y/n)? ");
|
||
c = p_inchar();
|
||
if ((c == 'Y') || (c == 'y'))
|
||
{
|
||
clear();
|
||
set_row(5);
|
||
l_outstr(" Insert Maze Mania Side #1 ");
|
||
set_row(6);
|
||
l_outstr(" Strike any key to continue ");
|
||
c = p_inchar();
|
||
vdpiof("FR1SE");
|
||
if (VIOSTAT())
|
||
{ /* not in play mode */
|
||
while (!VIOSTAT())
|
||
;
|
||
while (vdpiof("PL"))
|
||
{
|
||
set_row(8);
|
||
l_outstr(" Please insert disc.");
|
||
}
|
||
set_row(9);
|
||
l_outstr(" Thank-you.");
|
||
while (!VIOSTAT())
|
||
;
|
||
vdpiof("PA");
|
||
}
|
||
else
|
||
while (!VIOSTAT())
|
||
;
|
||
clear();
|
||
set_row(5);
|
||
l_outstr(" Introduction Part #1 ");
|
||
vdpiof("VOVP");
|
||
|
||
if (!sequence((UWORD)150,(UWORD)1482))
|
||
{
|
||
vdpiof("VC");
|
||
p_move(6,0);
|
||
l_outstr(" Introduction Part #2 ");
|
||
vdpiof("VP");
|
||
sequence((UWORD)1800,(UWORD)2120);
|
||
}
|
||
vdpiof("VC");
|
||
}
|
||
|
||
init_players();
|
||
c_scene = 1;
|
||
c_player = 0;
|
||
g_next = 0;
|
||
g_count = 0;
|
||
q_size = QMAX;
|
||
while (select_player())
|
||
ask_question();
|
||
|
||
/* saved for reference
|
||
p_clear();
|
||
p_move(9,0);
|
||
l_outstr(" Sequence test.");
|
||
p_move(10,0);
|
||
l_outstr(" Strike any key to abort.");
|
||
vdpiof("VP");
|
||
while (!sequence((UWORD)12450,(UWORD)12500))
|
||
;
|
||
*/
|
||
|
||
#ifdef CPU_65
|
||
d_ouchar(142); /* switch to upper case */
|
||
#endif
|
||
} /***** end maze *****/
|
||
|
||
/*#page*/
|
||
/****************************************************************************/
|
||
/* */
|
||
/* xxxxxxxx */
|
||
/* -------- */
|
||
/* */
|
||
/* This subroutine performs the xxxxxxxxxxxxxxxxxxxxxxxx. */
|
||
/* */
|
||
/****************************************************************************/
|
||
MLOCAL sign_on()
|
||
{
|
||
UBYTE i;
|
||
UBYTE j;
|
||
UBYTE k;
|
||
|
||
p_color(BLUE);
|
||
i = 0;
|
||
j = (p_crt.rows - h_so_maze) >> 1;
|
||
k = (p_crt.cols - w_so_maze) >> 1;
|
||
|
||
while (so_maze[i])
|
||
{
|
||
p_move(i+j,k);
|
||
l_outstr(so_maze[i++]);
|
||
}
|
||
}
|
||
|
||
GLOBAL l_outstr(s)
|
||
|
||
CHAR *s;
|
||
{
|
||
#ifdef CPU_65
|
||
CHAR c;
|
||
|
||
while (c = *s++)
|
||
{
|
||
if ((c >= 'a') && (c <= 'z')) /* if lower case */
|
||
c = c & 0xdf; /* then to upper */
|
||
else
|
||
if ((c >= 'A') && (c <= 'Z')) /* if upper case */
|
||
c = c | 0x20; /* then to lower */
|
||
d_ouchar(c);
|
||
}
|
||
#else
|
||
p_outstr(s);
|
||
#endif
|
||
}
|
||
|
||
newline()
|
||
{
|
||
set_row(row+1);
|
||
}
|
||
|
||
set_row(r)
|
||
|
||
UBYTE r;
|
||
{
|
||
p_move(row = r, 0);
|
||
}
|
||
|
||
clear()
|
||
{
|
||
row = 0;
|
||
p_clear();
|
||
}
|
||
|
||
stop_display()
|
||
{
|
||
UWORD i;
|
||
for (i = 0; i < 30000; i++);
|
||
}
|
||
|
||
BOOLEAN read_group()
|
||
{
|
||
UWORD q, k, k_loc;
|
||
UBYTE n, n1, n2;
|
||
if (eoq || (eoq = !(n = gn_num())))
|
||
return;
|
||
q_next = g_next;
|
||
put_q(n);
|
||
while (n--)
|
||
{
|
||
n1 = gn_num();
|
||
n2 = gn_num();
|
||
k_loc = q_next;
|
||
put_q(0);
|
||
put_q(0);
|
||
k = 0;
|
||
while (n1--)
|
||
k += gn_nstr();
|
||
put_q('\0');
|
||
while (n2--)
|
||
k += gn_nstr();
|
||
put_q('\0');
|
||
k += 2;
|
||
put_nq(k_loc, k & 0xff);
|
||
put_nq(k_loc+1, k >> 16);
|
||
if (q_next >= q_size - 2)
|
||
return (FALSE);
|
||
g_next = q_next;
|
||
g_count++;
|
||
return (TRUE);
|
||
}
|
||
}
|
||
|
||
UBYTE gn_num()
|
||
{
|
||
UBYTE x, d;
|
||
x = 0;
|
||
while ((d = gnc()) == ' ' || d == ',')
|
||
;
|
||
while (d = d - '0') <= 9)
|
||
x = x * 10 + d;
|
||
return (x);
|
||
}
|
||
|
||
UWORD gn_nstr()
|
||
{
|
||
UWORD d;
|
||
UBYTE c;
|
||
d = 1;
|
||
while (gnc() != '"')
|
||
;
|
||
while ((c = gnc()) != '"')
|
||
{
|
||
put_q(c);
|
||
d++;
|
||
}
|
||
put_q('\n');
|
||
return (d);
|
||
}
|
||
|
||
UBYTE gnc()
|
||
{
|
||
if (eoq)
|
||
return ('"');
|
||
/* note: read next character */
|
||
return ('#');
|
||
}
|
||
|
||
put_q(x)
|
||
|
||
UBYTE x;
|
||
{
|
||
put_nq(q_next,x);
|
||
}
|
||
|
||
put_nq(loc,x)
|
||
|
||
UWORD loc;
|
||
UBYTE x;
|
||
{
|
||
if (loc >= q_size)
|
||
return;
|
||
q_buffer[loc] = x;
|
||
if (loc >= q_next)
|
||
q_next = loc + 1;
|
||
}
|
||
|
||
UBYTE rand_q(g)
|
||
|
||
UBYTE g;
|
||
{
|
||
/* return random number between 1 and g */
|
||
return (1);
|
||
}
|
||
|
||
next_question()
|
||
{
|
||
UWORD q;
|
||
q = rand_q(g_max = get_q(g_base));
|
||
q_next = 1;
|
||
while (q--)
|
||
gn_qpos();
|
||
for (q = 1; q < g_max; q++)
|
||
{
|
||
if (!(get_q(q_base+1) & 0x80))
|
||
break;
|
||
gn_qpos();
|
||
}
|
||
if (q >= g_max)
|
||
{
|
||
for (q = 1; q < g_count; q++)
|
||
{
|
||
put_q(q_base+1,get_q(q_base+1) | 0x80);
|
||
gn_qpos();
|
||
}
|
||
}
|
||
}
|
||
|
||
gn_qpos()
|
||
{
|
||
q_base +=
|
||
gnq(q_base) | ((gnq(q_base+1) & 0x7f) << 8);
|
||
if (++q_next > g_max)
|
||
{
|
||
q_base = g_base + 1;
|
||
q_next = 1;
|
||
}
|
||
}
|
||
|
||
display_question()
|
||
{
|
||
set_row(4);
|
||
l_outstr(" Here's the question:");
|
||
newline();
|
||
write_q(&q_buffer[q_base]);
|
||
}
|
||
|
||
write_q(q)
|
||
|
||
UBYTE *q;
|
||
{
|
||
while (*q)
|
||
{
|
||
if (*q == '\n')
|
||
{
|
||
newline();
|
||
l_outstr(" ");
|
||
}
|
||
else
|
||
d_outchar(*q);
|
||
q++;
|
||
}
|
||
}
|
||
|
||
BOOLEAN get_answer()
|
||
{
|
||
UBYTE c;
|
||
newline();
|
||
newline();
|
||
l_outstr(" What's your answer?");
|
||
a_size = 0;
|
||
while ((c = p_inchar()) != RETURN)
|
||
if (c == BACKSP)
|
||
{
|
||
if (a_size > 0)
|
||
{
|
||
d_outchar(BACKSP);
|
||
d_outchar(' ');
|
||
d_outchar(BACKSP);
|
||
}
|
||
}
|
||
else
|
||
if (a_size < AMAX)
|
||
d_outchar(ans[a_size++] = c);
|
||
while (get_q(q_base))
|
||
{
|
||
if match_q()
|
||
return (TRUE);
|
||
while (get_q(q_base++) != '\n')
|
||
;
|
||
}
|
||
return (FALSE);
|
||
}
|
||
|
||
BOOLEAN match_q()
|
||
{
|
||
UBYTE a;
|
||
for (a = 0; a < a_size; a++)
|
||
if (toupper(get_q(q_base)) != toupper(ans[a]))
|
||
if (get_q(q_base) == '\n')
|
||
return (FALSE);
|
||
return (get_q(q_base) == '\n');
|
||
}
|
||
|
||
ask_question()
|
||
{
|
||
UBYTE p, g, r, w;
|
||
BOOLEAN a;
|
||
UWORD s;
|
||
if (player.bonus[c_player])
|
||
vdpiof("ST");
|
||
else
|
||
vdpiof("AL");
|
||
clear();
|
||
set_row(3);
|
||
l_outstr(" Player ");
|
||
outBYTE(c_player);
|
||
l_outstr(" has ");
|
||
outBYTE(p = player.score[c_player]);
|
||
l_outstr(" points");
|
||
g = player.group[c_player];
|
||
a = TRUE;
|
||
while (a)
|
||
{
|
||
/* select next question from group */
|
||
if (g > g_count)
|
||
if (!read_group())
|
||
g = 1;
|
||
/* note: make g_base absolute q_buffer address from group g */
|
||
next_question();
|
||
display_question();
|
||
if (a = get_answer())
|
||
{
|
||
g += 1;
|
||
if ((p += 5) > 100)
|
||
p = 100;
|
||
s = nightmare.right[scene];
|
||
}
|
||
else
|
||
{
|
||
if ((p -= 3) < 0)
|
||
p = 0;
|
||
s = nightmare.wrong[scene];
|
||
}
|
||
/* set frame display for bonus questions later */
|
||
play_scene(scene);
|
||
clear();
|
||
set_row(3);
|
||
if ((r = nightmare.right[scene]) + (w = nightmare.wrong[scene]) == 0)
|
||
{
|
||
l_outstr(" Congratulations! You made");
|
||
newline();
|
||
l_outstr(" it through the maze");
|
||
s = 0;
|
||
a = FALSE;
|
||
}
|
||
else
|
||
if (r == 0)
|
||
{
|
||
l_outstr(" Sorry, DEAD END");
|
||
s = w;
|
||
}
|
||
if (a)
|
||
{
|
||
l_outstr(" Correct!");
|
||
/* display bonus question info later */
|
||
s = r;
|
||
}
|
||
else
|
||
{
|
||
l_outstr(" Oops! You got the");
|
||
newline();
|
||
l_outstr(" question wrong");
|
||
}
|
||
stop_display();
|
||
}
|
||
player.score[c_player] = p;
|
||
player.scene[c_player] = s;
|
||
player.group[c_player] = g;
|
||
}
|
||
|
||
|
||
|
||
play_scene(s)
|
||
|
||
UBYTE s;
|
||
{
|
||
/* should test for abort from sequence */
|
||
while (TRUE)
|
||
{
|
||
sequence(nightmare.start[s],nightmare.finish[s]);
|
||
if (nightmare.wrong[s] != 0)
|
||
return;
|
||
if ((s = nightmare.right[s]) == 0)
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
GLOBAL BOOLEAN sequence(start,stop)
|
||
|
||
UWORD start;
|
||
UWORD stop;
|
||
{
|
||
UBYTE str[10];
|
||
UBYTE stp[10];
|
||
BOOLEAN key;
|
||
|
||
sprintf(str,"%d",start);
|
||
sprintf(stp,"%d",stop-1);
|
||
|
||
vdpiof("VO");
|
||
vdpiof("FR");
|
||
vdpiof(str);
|
||
vdpiof("SE");
|
||
while (!VIOSTAT())
|
||
;
|
||
vdpiof("MF");
|
||
vdpiof(stp);
|
||
vdpiof("SE");
|
||
/*
|
||
if (VIOSTAT())
|
||
while (VIOSTAT())
|
||
;
|
||
*/
|
||
while (!VIOSTAT())
|
||
;
|
||
vdpiof("VNPL");
|
||
/*
|
||
if (VIOSTAT())
|
||
while (VIOSTAT())
|
||
;
|
||
*/
|
||
while (!VIOSTAT())
|
||
;
|
||
key = FALSE;
|
||
/*
|
||
while (VIOSTAT())
|
||
if (key = p_instat())
|
||
{
|
||
p_inchar();
|
||
break;
|
||
}
|
||
*/
|
||
while (1)
|
||
{
|
||
if (!VIOSTAT())
|
||
if (!VIOSTAT())
|
||
if (!VIOSTAT())
|
||
if (!VIOSTAT())
|
||
break;
|
||
if (key = p_instat())
|
||
{
|
||
p_inchar();
|
||
break;
|
||
}
|
||
}
|
||
vdpiof("PA");
|
||
return(key);
|
||
}
|
||
|