home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FreeWare Collection 3
/
FreeSoftwareCollection3pd199x-jp.img
/
pao
/
ms_dos
/
game
/
src
/
lc2d.c
< prev
next >
Wrap
Text File
|
1980-01-02
|
18KB
|
700 lines
/* << MSC V5.1 >> *************************************************************
**
** Light Cycle 2D
**
** CREATE : 1990.09.20
** FINISH : 1990.09.23
**
** < NOTE >
** TABS = 4
** FMTOWNS/FMR-70の切り換えは、GRP.H を修正しリコンパイルすればよい。
**
** < HISTIRY >
** 1990.09.20 : CREATE
** 1990.09.27 : 線を消す処理が無限ループにならないようにした。
** 1990.10.02 : BREAKキーの入力可能場所を増やした。
** : YES/NO ? の時に、ESCキーは NO が選択された時と同様とした。
**
** All Rights Reserved, Copyright (C) Y.Hirata 1990.
**
** Programed by Y.Hirata ( Nifty ID : NAB03321 )
**
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "kyb.h"
#include "grp.h"
#define TITLE "陣屋<2D> V0.60 (c) パオパオ 1990."
#define TEXTPAGE 0
#define GAMEPAGE 1
#define NUSER 6 /* 最大プレイヤー数 */
#define DOT_ON 30 /* スピード制御(表示) */
#define SPEEDUP 3 /* アップスピード */
#define TURBO 300 /* スピードアップ制御 */
#define BEEP_TIME 20 /* BEEP時間 x 10 ms */
#define BEEP_COUNT 192 /* 19200 / ? Hz */
#define BEEP_COUNT2 10 /* 19200 / ? Hz */
#define TURNLEFT 2
#define TURNRIGHT 1
#define NOTURN 0
#define D_UP 1
#define D_RIGHT 2
#define D_DOWN 3
#define D_LEFT 4
struct _USER_STATUS {
short x ; /* 現在の X 座標 */
short y ; /* 現在の Y 座標 */
short x2 ; /* 次の X 座標 */
short y2 ; /* 次の Y 座標 */
short d ; /* 現在の進行方向 : 1-UP, 2-RIGHT, 3-DOWN, 4-LEFT */
short d2 ; /* 変更したい方向 : 1-RIGHT, 2-LEFT */
int count ; /* スピード制御 */
int spcount ; /* スピード制御 */
char turn ; /* 方向変更あり? */
char dead ; /* 負けたか? */
short point ; /* 今回の得点 */
long tpoint ; /* いままでの合計得点 */
} ;
struct _USER_STATUS User[NUSER] ;
#ifdef FMR70 /* FMR-70(24ドット用) */
struct _USER_STATUS User_data[NUSER] = {
{ 280, 375, 280, 375, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 839, 375, 839, 375, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 280, 195, 280, 195, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 839, 195, 839, 195, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 280, 555, 280, 555, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 839, 555, 839, 555, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l }
} ;
#else /* FMTOWNS(16ドット用) */
struct _USER_STATUS User_data[NUSER] = {
{ 150, 200, 150, 200, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 489, 200, 489, 200, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 150, 100, 150, 100, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 489, 100, 489, 100, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 150, 300, 150, 300, D_RIGHT, 0, 0, 0, FALSE, FALSE, 0, 0l },
{ 489, 300, 489, 300, D_LEFT, 0, 0, 0, FALSE, FALSE, 0, 0l }
} ;
#endif
struct _USER_PARA {
short color ; /* color */
char left ; /* 左方向キー */
char speed ; /* スピードキー */
char right ; /* 右方向キー */
} ;
struct _USER_PARA Upara[NUSER] = {
{ C_GREEN, KEY_1, KEY_2, KEY_3 },
{ C_SKYBLUE, KEY_GT, KEY_QUEST, KEY_UNDERBER },
{ C_RED, KEY_G, KEY_H, KEY_J },
{ C_YELLOW, KEY_8, KEY_9, KEY_0 },
{ C_PURPLE, KEY_Z, KEY_X, KEY_C },
{ C_WHITE, TKEY_1, TKEY_2, TKEY_3 }
} ;
typedef struct _USER_TRACE {
short x ;
short y ;
char d ;
} USER_TRACE ;
USER_TRACE *Utrace[NUSER] ;
short Nturn[NUSER] ;
char *UserKey[] = {
"1 2 3",
"> ? _",
"G H J",
"8 9 0",
"Z X C",
"T1 T2 T3"
} ;
int Nplayer = 6 ; /* プレイヤー数 */
int Resplayer ; /* 残りプレイヤー数 */
short Backcolor = 0 ; /* 背景色番号 */
long Backpixel = 0x203030l ; /* 背景色 : r0g0b0 */
char Continueflg = FALSE ;
char Breakflg = FALSE ;
#define RANDINIT srand((unsigned int)time(NULL)) /* 乱数初期化 */
#define RANDOM(x) (rand()%(x)) /* 乱数 : 0~x */
/*************************** USER Parameter init ***************************/
void play_init()
{
int c ;
Resplayer = Nplayer ;
for ( c=0; c<NUSER; c++ ) {
User[c].x = User_data[c].x ;
User[c].y = User_data[c].y ;
User[c].x2 = User_data[c].x2 ;
User[c].y2 = User_data[c].y2 ;
User[c].d = User_data[c].d ;
User[c].d2 = User_data[c].d2 ;
User[c].count = User_data[c].count ;
User[c].spcount = User_data[c].spcount ;
User[c].turn = User_data[c].turn ;
User[c].dead = User_data[c].dead ;
Nturn[c] = 0 ;
}
}
/**************************** Yes/No キー入力する ****************************/
int yesno()
{
int ret ;
char matrix[16] ;
char keyend ;
ret = 0 ;
keyend = FALSE ;
Breakflg = FALSE ;
do {
KEY_bufcls() ;
KEY_matrix( matrix ) ;
if ( KEY_test( matrix,KEY_N ) ||
KEY_test( matrix,KEY_ESC ) ) {
ret = FALSE ;
keyend = KEY_N ;
KEY_break( KEY_N ) ;
KEY_break( KEY_ESC ) ;
} else if ( KEY_test( matrix,KEY_Y ) ||
KEY_test( matrix,KEY_CR ) ||
KEY_test( matrix,TKEY_CR ) ||
KEY_test( matrix,KEY_EXEC ) ) {
ret = TRUE ;
keyend = KEY_Y ;
KEY_break( KEY_Y ) ;
KEY_break( KEY_CR ) ;
KEY_break( TKEY_CR ) ;
KEY_break( KEY_EXEC ) ;
} else if ( KEY_test( matrix,KEY_BREAK ) ) {
ret = FALSE ;
keyend = KEY_BREAK ;
KEY_break( KEY_BREAK ) ;
Breakflg = TRUE ;
}
} while ( !keyend ) ;
KEY_bufcls() ;
return( ret ) ;
}
/******************************* DOT ERACE *********************************/
void erace( short uno )
{
short px, py, pcol, pd ;
long pturn ;
px = User_data[uno].x ;
py = User_data[uno].y ;
pd = User_data[uno].d ;
pturn = 0 ;
GRP_color( Backcolor ) ;
pcol = GRP_getpixel( px,py ) ;
if ( pcol == Upara[uno].color ) {
GRP_pset( px,py ) ;
} else {
return ;
}
while ( TRUE ) {
if ( Nturn[uno] > 0 ) {
if ( Utrace[uno][pturn].x == px &&
Utrace[uno][pturn].y == py ) {
pd = Utrace[uno][pturn].d ;
pturn ++ ;
}
}
if ( pturn > Nturn[uno] ) break ;
switch ( pd ) { /* 次の座標 */
case D_UP :
py -- ;
break ;
case D_RIGHT :
px ++ ;
break ;
case D_DOWN :
py ++ ;
break ;
case D_LEFT :
px -- ;
break ;
}
if ( px == User[uno].x && py == User[uno].y ) break ;
GRP_pset( px,py ) ;
}
}
/******************************* DEAD CHECK ********************************/
void dead_check()
{
int c, cc, ndead ;
short color ;
char deadflg[NUSER] ;
GRP_color( Backcolor ) ;
ndead = 0 ;
for ( c=0; c<Nplayer; c++ ) {
deadflg[c] = FALSE ;
color = GRP_getpixel( User[c].x2,User[c].y2 ) ;
if ( User[c].dead == TRUE ) { /* ぶつかった */
deadflg[c] = TRUE ;
ndead ++ ;
} else if ( !User[c].dead ) {
if ( c < ( Nplayer - 1 ) ) {
for ( cc=c+1; cc<Nplayer; cc++ ) {
if ( User[cc].dead == TRUE &&
User[c].x2 == User[cc].x2 &&
User[c].y2 == User[cc].y2 ) { /* 共倒れ */
deadflg[c] = TRUE ;
ndead ++ ;
GRP_pset( User[c].x2,User[c].y2 ) ;
}
}
}
if ( !deadflg[c] ) { /* 生存 */
User[c].x = User[c].x2 ;
User[c].y = User[c].y2 ;
}
}
}
for ( c=0; c<Nplayer; c++ ) {
if ( !User[c].dead || User[c].dead == TRUE ) {
if ( deadflg[c] ) {
GRP_beep( BEEP_TIME,BEEP_COUNT ) ;
User[c].dead = TRUE + 1 ;
User[c].point = ( Nplayer - Resplayer ) ;
User[c].tpoint += (long)User[c].point ;
GRP_pset( User[c].x,User[c].y ) ;
erace( c ) ;
}
}
}
Resplayer -= ndead ;
}
/********************************* BOMB 発生 *******************************/
void bomb()
{
short x, y ;
GRP_beep( BEEP_TIME,BEEP_COUNT2 ) ;
x = RANDOM( VIEW_XE-6 ) + 3 ;
y = RANDOM( VIEW_YE-6 ) + 3 ;
GRP_color( C_WHITE ) ;
GRP_rectangle( x-2,y-2,x+2,y+2,FALSE ) ;
GRP_rectangle( x-1,y-1,x+1,y+1,FALSE ) ;
}
/****************************** PLAYER CHECK *******************************/
void player_check( char *matrix )
{
int c ;
char dotonflg ;
char bombflg[NUSER] ;
short color ;
static int dotcount=0 ;
dotonflg = FALSE ;
for ( c=0; c<Nplayer; c++ ) {
bombflg[c] = FALSE ;
if ( !User[c].dead ) {
if ( KEY_test( matrix,Upara[c].speed ) ) { /* SPEED UP*/
User[c].spcount ++ ;
if ( User[c].spcount > TURBO ) {
User[c].count += (SPEEDUP*2) ;
} else {
User[c].count += SPEEDUP ;
}
} else {
if ( User[c].spcount > 1 ) {
User[c].spcount -= 2 ;
if ( User[c].spcount > TURBO ) {
User[c].count += SPEEDUP ;
} else {
User[c].spcount = 0 ;
User[c].count ++ ;
}
} else {
User[c].spcount = 0 ;
User[c].count ++ ;
}
}
if ( KEY_test( matrix,Upara[c].left ) ) { /* LEFT */
if ( !KEY_test( matrix,Upara[c].right ) ) {
if ( !User[c].turn ) {
User[c].d2 = TURNLEFT ;
User[c].turn = TRUE ;
}
} else {
User[c].d2 = NOTURN ;
User[c].turn = FALSE ;
bombflg[c] = TRUE ;
}
} else if ( KEY_test( matrix,Upara[c].right ) ) { /* RIGHT */
if ( !User[c].turn ) {
User[c].d2 = TURNRIGHT ;
User[c].turn = TRUE ;
}
} else {
User[c].d2 = NOTURN ;
User[c].turn = FALSE ;
}
if ( User[c].count > DOT_ON ) {
dotonflg = TRUE ;
User[c].count = 0 ;
if ( User[c].d2 == TURNLEFT ) User[c].d-- ;
if ( User[c].d2 == TURNRIGHT ) User[c].d++ ;
if ( User[c].d < D_UP ) User[c].d = D_LEFT ;
if ( User[c].d > D_LEFT ) User[c].d = D_UP ;
switch ( User[c].d ) {
case D_UP : /* UP */
User[c].x2 = User[c].x ;
User[c].y2 = User[c].y - 1 ;
break ;
case D_RIGHT : /* RIGHT */
User[c].x2 = User[c].x + 1 ;
User[c].y2 = User[c].y ;
break ;
case D_DOWN : /* DOWN */
User[c].x2 = User[c].x ;
User[c].y2 = User[c].y + 1 ;
break ;
case D_LEFT : /* LEFT */
User[c].x2 = User[c].x - 1 ;
User[c].y2 = User[c].y ;
break ;
default :
User[c].x2 = User[c].x ;
User[c].y2 = User[c].y ;
break ;
}
if ( User[c].d2 != NOTURN ) {
Utrace[c][Nturn[c]].x = User[c].x ;
Utrace[c][Nturn[c]].y = User[c].y ;
Utrace[c][Nturn[c]].d = User[c].d ;
Nturn[c] ++ ;
}
User[c].d2 = NOTURN ;
color = GRP_getpixel( User[c].x2,User[c].y2 ) ;
GRP_color( Upara[c].color ) ;
if ( color != Backcolor ) {
User[c].dead = TRUE ;
} else {
GRP_line( User[c].x,User[c].y,User[c].x2,User[c].y2 ) ;
if ( bombflg[c] && dotcount == 0 ) {
bomb() ;
}
}
}
}
}
if ( dotonflg ) {
dotcount ++ ;
if ( dotcount > 30 ) dotcount = 0 ;
dead_check() ;
}
}
/************************** 何人でプレイするのか? *************************/
int inplayer()
{
char matrix[16] ; /* キーマトリクス取得用 */
int ret ;
Breakflg = FALSE ;
while( TRUE ) {
KEY_bufcls() ;
KEY_matrix( matrix ) ;
if ( KEY_test( matrix,KEY_BREAK ) ) { /* BREAK キー ON */
ret = 0 ;
Breakflg = TRUE ;
KEY_break( KEY_BREAK ) ;
break ;
} else if ( KEY_test( matrix,KEY_ESC ) ) {
ret = 0 ;
KEY_break( KEY_ESC ) ;
break ;
} else if ( KEY_test( matrix,KEY_2 ) ||
KEY_test( matrix,TKEY_2 ) ) { /* 2人 */
ret = 2 ;
break ;
} else if ( KEY_test( matrix,KEY_3 ) ||
KEY_test( matrix,TKEY_3 ) ) { /* 3人 */
ret = 3 ;
break ;
} else if ( KEY_test( matrix,KEY_4 ) ||
KEY_test( matrix,TKEY_4 ) ) { /* 4人 */
ret = 4 ;
break ;
} else if ( KEY_test( matrix,KEY_5 ) ||
KEY_test( matrix,TKEY_5 ) ) { /* 5人 */
ret = 5 ;
break ;
} else if ( KEY_test( matrix,KEY_6 ) ||
KEY_test( matrix,TKEY_6 ) ) { /* 6人 */
ret = 6 ;
break ;
}
}
return( ret ) ;
}
/******************************* GAME READY ********************************/
int ready()
{
int c, nplay ;
char msg[80] ;
char readyflg ;
short x, y ;
GRP_writePage( GAMEPAGE ) ;
GRP_color( C_BLACK ) ;
GRP_clearScreen( CLEARSCREEN ) ;
GRP_displayPage( GAMEPAGE ) ;
GRP_color( C_WHITE ) ;
GRP_rectangle( VIEW_XS,VIEW_YS,VIEW_XE,VIEW_YE,FALSE ) ;
GRP_locate( 2,4 ) ;
GRP_textcolor( C_GREEN ) ;
GRP_outtext( TITLE ) ;
for ( c=0; c<NUSER; c++ ) {
sprintf( msg,"Player %d",c+1 ) ;
GRP_locate( User_data[c].y/YDOTS-1,User_data[c].x/XDOTS+1-5 ) ;
GRP_textcolor( Upara[c].color ) ;
GRP_outtext( msg ) ;
GRP_locate( User_data[c].y/YDOTS,User_data[c].x/XDOTS+1-5 ) ;
GRP_outtext( UserKey[c] ) ;
}
GRP_textcolor( C_WHITE ) ;
readyflg = 0 ;
GRP_cursor( TRUE ) ;
nplay = Nplayer ;
do {
if ( readyflg == 0 && !Continueflg ) {
GRP_locate( 3,4 ) ;
for ( c=0; c<80; c++ ) msg[c] = ' ' ;
msg[79] = '\0' ;
GRP_outtext( msg ) ;
GRP_locate( 3,4 ) ;
GRP_outtext( "何人でプレイしますか? ( 2 ~ 6 ) " ) ;
nplay = inplayer() ;
if ( nplay ) {
readyflg = 1 ;
} else {
if ( Breakflg ) {
return( FALSE ) ; /* 中断 */
} else {
Continueflg = TRUE ; /* 人数設定キャンセル */
}
}
}
if ( nplay ) {
sprintf( msg,"GAME START ! ( %d player ) Are you ready ? (Y/N) ",
nplay) ;
} else {
sprintf( msg,"GAME START ! ( %d player ) Are you ready ? (Y/N) ",
Nplayer) ;
}
GRP_locate( 3,4 ) ;
GRP_outtext( msg ) ;
if ( !yesno() ) { /* NOT READY */
readyflg = 0 ;
Continueflg = FALSE ;
if ( Breakflg ) return( FALSE ) ; /* 中断 */
} else { /* READY GO! */
readyflg = 2 ;
}
} while ( readyflg != 2 ) ;
GRP_cursor( FALSE ) ;
if ( nplay && Nplayer != nplay ) { /* 前回と人数が異なる */
Nplayer = nplay ;
for ( c=0; c<NUSER; c++ ) { /* 得点クリア */
User[c].point = 0 ;
User[c].tpoint = 0 ;
}
}
GRP_clearScreen( CLEARTEXT ) ;
return( TRUE ) ;
}
/******************************* GAME START ********************************/
int play_start()
{
char matrix[16] ; /* キーマトリクス取得用 */
char endflg ; /* 終了フラグ */
int c ;
if ( !ready() ) return( FALSE ) ;
play_init() ;
endflg = FALSE ;
do {
KEY_bufcls() ;
KEY_matrix( matrix ) ;
if ( KEY_test( matrix,KEY_BREAK ) ) { /* BREAK キー ON */
endflg = TRUE ;
for ( c=0; c<Nplayer; c++ ) {
if ( !User[c].dead ) {
User[c].point = ( Nplayer - Resplayer ) ;
User[c].tpoint += (long)User[c].point ;
}
}
KEY_break( KEY_BREAK ) ;
break ;
} else {
player_check( matrix ) ;
if ( Resplayer == 1 ) {
for ( c=0; c<Nplayer; c++ ) {
if ( !User[c].dead ) {
User[c].point = ( Nplayer - Resplayer ) ;
User[c].tpoint += (long)User[c].point ;
break ;
}
}
}
if ( Resplayer <= 1 ) {
endflg = TRUE ;
}
}
} while ( !endflg ) ;
return( TRUE ) ;
}
/************************ char 0-f(F) -> int 0-15 **************************/
int ctoi( c )
char c ;
{
int i ;
i = 0 ;
if ( c >= '0' && c <= '9' ) {
i = c - '0' ;
} else {
if ( c >= 'A' && c <= 'F' )
i = 10 + c - 'A' ;
if ( c >= 'a' && c <= 'f' )
i = 10 + c - 'a' ;
}
return( i ) ;
}
/********************************* メイン 処理 ********************************/
void main( int ac,char *av[] )
{
int c ;
char msg[80] ;
long pixel ; /* r0g0b0 */
char playon ;
pixel = 0l ;
if ( ac > 1 ) { /* 引数あり */
if ( strlen( av[1] ) == 3 ) {
c = ctoi( *(av[1]+1) ) ; /* RED */
c <<= 4 ;
pixel |= (long)c ;
c = ctoi( *(av[1]+2) ) ; /* GREEN */
c <<= 4 ;
pixel <<= 8 ;
pixel |= (long)c ;
c = ctoi( *av[1] ) ; /* BLUE */
c <<= 4 ;
pixel <<= 8 ;
pixel |= (long)c ;
}
}
/*
** 初期処理
**
** GAME は、Page 1
** TEXT は、Page 0
*/
printf("program start!\n") ;
INT23_init() ;
GRP_init() ;
GRP_palette( Backcolor,Backpixel ) ;
for ( c=0; c<NUSER; c++ ) { /* 得点クリア */
User[c].point = 0 ;
User[c].tpoint = 0 ;
}
RANDINIT ;
playon = TRUE ;
for ( c=0; c<NUSER; c++ ) {
Utrace[c] = (USER_TRACE *)malloc( sizeof(USER_TRACE)*4096 ) ;
if ( Utrace[c] == NULL ) {
printf("メモリ不足です。\n") ;
playon = FALSE ;
break ;
} ;
}
/*
** キー入力処理
*/
while( TRUE && playon ) {
if ( play_start() ) {
GRP_clearScreen( CLEARTEXT ) ;
GRP_textcolor( C_WHITE ) ;
GRP_locate( 4,25 ) ;
GRP_outtext( "GAME OVER !" ) ;
for ( c=0; c<Nplayer; c++ ) {
sprintf( msg,"Player %d : %d < TOTAL : %ld >",
c+1,User[c].point,User[c].tpoint ) ;
GRP_locate( 6+c,25 ) ;
GRP_textcolor( Upara[c].color ) ;
GRP_outtext( msg ) ;
}
GRP_textcolor( C_WHITE ) ;
GRP_locate( 13,25 ) ;
GRP_outtext( "CONTINUE ? (Y/N) " ) ;
GRP_cursor( TRUE ) ;
Continueflg = yesno() ;
}
if ( !Continueflg ) { /* NOT CONTINUE */
GRP_clearScreen( CLEARTEXT ) ;
GRP_textcolor( C_WHITE ) ;
GRP_locate( 3,4 ) ;
GRP_outtext( "GAME を終了してもよろしいですか? (Y/N) " ) ;
if ( yesno() ) break ;
for ( c=0; c<NUSER; c++ ) { /* 得点クリア */
User[c].point = 0 ;
User[c].tpoint = 0 ;
}
}
GRP_cursor( FALSE ) ;
}
/*
** 終了処理
*/
GRP_clearScreen( CLEARGRAPH ) ;
GRP_end() ;
GRP_palette( Backcolor,pixel ) ;
INT23_release() ;
printf("プログラム終了\n") ;
}