📄 ship.txt
字号:
/* 这里把三个文件放在了一起,编译时需要把本文件分成三 */
/*部分,文件名分别为:13H.H,TIMER.H,SHIP.C。其中13H.H是 */
/*VGA 13H 模式下作图的一些基本函数。本程序用申请的64000 */
/*字节作为后台活动页,作图完成后一次性拷贝到显示缓冲区。 */
/*TIMER.H是整个程序的时钟系统。SHIP.C是主程序。 */
/*********************************************************/
/* 文件:13H.H */
/*********************************************************/
/*********************************************************/
/* 此处定义了一些通用的宏 */
# define BYTE unsigned char
# define BOOL BYTE
# define WORD unsigned int
# define DWORD unsigned long
# define TRUE 1
# define FALSE !TRUE
/* BIOS 8*8 西文字库的段地址和偏移量 */
WORD FONT_SEG;
WORD FONT_OFF;
/* 显示后台活动页地址 */
void far * Video;
/* 获取BIOS 8*8 西文字库的段地址和偏移量 */
void GetFontAdd()
{
struct REGPACK regs;
regs.r_bx=0x0300;
regs.r_ax=0x1130;
intr(0x10,®s);
FONT_SEG=regs.r_es;
FONT_OFF=regs.r_bp;
}
/* 向后台活动页写像素 */
void Pset(int x,int y,BYTE color)
{
if ((x>=0)&&(x<320)&&(y>=0)&&(y<200))
*((BYTE far*)Video+y*320+x)=color;
}
/* 等待键盘输入 */
void wait()
{
_AX=0;
geninterrupt(0x16);
}
/* 设置VGA 13H模式 */
void setmode()
{
_AX=0x13;
geninterrupt(0x10);
GetFontAdd();
}
/* 设置文本模式 */
void closemode()
{
_AX=0x3;
geninterrupt(0x10);
}
/* 设置调色板 */
void setpal(int Color,BYTE r,BYTE g,BYTE b)
{
outportb(0x3c8,Color);
outportb(0x3c9,r);
outportb(0x3c9,g);
outportb(0x3c9,b);
}
/* 屏幕定位(用于输出字符)*/
void locate(int Line,int Col)
{
_DH=Line;
_DL=Col;
_AH=2;
_BX=0;
geninterrupt(0x10);
}
/* 从键盘缓冲区内直接读出扫描码 */
BYTE ScanKey(void)
{
int start,end;
WORD key=0;
start=peek(0,0x41a);
end=peek(0,0x41c);
if (start==end) return(0);
else
{
key=peek(0x40,start);
start+=2;
if (start==0x3e) start=0x1e;
poke(0x40,0x1a,start);
return(key/256);
}
}
/* 画背景 */
void ClearScreen()
{
int x,y;
for (y=0;y<5;y++) for (x=0;x<320;x++) Pset(x,y,16);
for (y=5;y<10;y++) for (x=0;x<320;x++) Pset(x,y,104);
for (y=10;y<15;y++) for (x=0;x<320;x++) Pset(x,y,33);
for (y=15;y<20;y++) for (x=0;x<320;x++) Pset(x,y,103);
for (y=20;y<25;y++) for (x=0;x<320;x++) Pset(x,y,32);
for (y=25;y<30;y++) for (x=0;x<320;x++) Pset(x,y,64);
for (y=30;y<40;y++) for (x=0;x<320;x++) Pset(x,y,99);
for (y=40;y<60;y++) for (x=0;x<320;x++) Pset(x,y,97);
for (y=60;y<100;y++) for (x=0;x<320;x++) Pset(x,y,53);
for (y=100;y<200;y++) for (x=0;x<320;x++) Pset(x,y,2);
}
/* 刷新屏幕 */
void ReFresh(void)
{
movedata(FP_SEG(Video),FP_OFF(Video),0xa000,0,64000);
}
/* 输出字符到显示后台活动页 */
void OutChar(int x0,int y0,int ch,BYTE Color)
{
int x,y;
BYTE c;
for (y=0;y<8;y++)
{
c=peekb(FONT_SEG,FONT_OFF+ch*8+y);
for (x=0;x<8;x++)
{
if (c&(1<<(7-x))) Pset(x+x0*8,y+y0*8,Color);
}
}
}
/* 输出字符串到显示后台活动页 */
void OutString(int x,int y,char *p,BYTE Color)
{
while (*p)
{
OutChar(x++,y,*p++,Color);
if (x==40)
{
x=0;
y++;
}
}
}
/*********************************************************/
/* 文件:TIMER.H */
/*********************************************************/
/*********************************************************/
/* 系统可用计时器的最大数目 */
# define MAXTIMER 10
/* 计时器结构 */
struct TM
{
DWORD Interval; /* 间隔 */
DWORD LastTimer; /* 上次时间发生时间*/
BOOL Enable; /* 活动 */
BOOL Used; /* 可用 */
void (*Pointer)(); /* 事件远指针 */
};
struct TM tmTM[MAXTIMER+1];
int TimerUsed=0;
/* 获取BIOS计数器数值 */
DWORD BiosTimer(void)
{
DWORD BIOSTIMER=0;
BIOSTIMER=peek(0x0,0x46e);
BIOSTIMER<<=8;
BIOSTIMER+=peek(0x0,0x46c);
return (BIOSTIMER);
}
/* 时间事件(时钟系统核心) */
void TimerEvent()
{
int i;
DWORD TimerDiff;
for (i=1;i<=MAXTIMER;i++)
{
if (tmTM[i].Used&&tmTM[i].Enable)
{
TimerDiff=BiosTimer()-tmTM[i].LastTimer;
if (tmTM[i].Interval<=TimerDiff)
{
tmTM[i].Pointer();
tmTM[i].LastTimer=BiosTimer();
}
}
}
}
/* 创建一个时钟(成功返回时钟的句柄,否则返回NULL) */
int CreateTimer(DWORD Interval,void (*Pointer)())
{
int i=0;
if (TimerUsed==MAXTIMER) return NULL;
while (tmTM[++i].Used);
tmTM[i].Pointer=Pointer;
tmTM[i].Interval=Interval;
tmTM[i].Enable=TRUE;
tmTM[i].Used=TRUE;
tmTM[i].LastTimer=BiosTimer();
TimerUsed++;
return i;
}
/* 删除一个时钟 */
void KillTimer(int *TimerID)
{
if (tmTM[*TimerID].Used)
{
TimerUsed--;
tmTM[*TimerID].Used=FALSE;
}
*TimerID=0;
}
/* 删除所有时钟 */
void KillAllTimer()
{
int i;
for (i=0;i<=MAXTIMER;i++) tmTM[i].Used=FALSE;
TimerUsed=0;
}
/*********************************************************/
/* 文件:SHIP.C */
/*********************************************************/
/*********************************************************/
# include <dos.h>
# include "13h.h"
# include <time.h>
# include <stdio.h>
# include "timer.h"
# include <alloc.h>
# include <stdlib.h>
struct stBOMB
{
int x;
int y;
BOOL Used;
};
struct stEXPL
{
int x;
int y;
BYTE Num;
BOOL Used;
};
struct stSHIP
{
int x;
int y;
BOOL Used;
BYTE Dir;
BYTE Type;
};
struct stTORP
{
int x;
int y;
BOOL Used;
};
struct stBOMB bbBomb[21];
struct stSHIP spShip[21];
struct stTORP tpTorp[21];
struct stEXPL elExpl[21];
int BombUsed=0;
int ShipUsed=0;
int TorpUsed=0;
int ExplUsed=0;
int MAXBOMB=5;
int MAXSHIP=3;
int MAXTORP=5;
int MAXEXPL=5;
int ID_Timer[MAXTIMER+1];
int ID_Bomb[21];
int ID_Ship[21];
int ID_Torp[21];
int ID_Expl[21];
BOOL DISP=TRUE;
BOOL CLS=FALSE;
BOOL bPaint=FALSE;
BOOL ALIVE=TRUE;
BOOL SOUND=TRUE;
BOOL Flash=FALSE;
BOOL DONE=FALSE;
BYTE SHIP[2][32][64];
BYTE BOMB[32][32];
BYTE TORP[16][16];
BYTE PAL[256][3];
BYTE STR[80];
BYTE far * PIC_EXPL;
BYTE far * PIC_SHIP;
void far * Back1;
void far * Back2;
int MyX=0;
int MyY=0;
int Life=3;
int Score=25;
int LevelScore=25;
int Level=0;
int Step=0;
char *Info="\
\
\
Welcome to play this game!\
\n\
\n\
\n\
In this game,you will drive a warship to fight with\n\
the submarines.\n\n\
KEYS:\n\
'Left' and 'Right' keys to move your warship.\n\
'Space bar' or 'Ctrl' key to send bombs.\n\
'S' key is a sound switch.\n\
'D' key is a state switch.\n\n\
\n\
\n\n\
GOOD LUCK!\0";
/* 调色板渐入 */
void StepIn()
{
int i;
for (i=0;i<256;i++) setpal(i,PAL[i][0]*Step/64,PAL[i][1]*Step/64,PAL[i][2]*Step/64);
Step++;
if (Step>64) KillAllTimer();
}
/* 调色板渐出 */
void StepOut()
{
int i;
for (i=0;i<256;i++) setpal(i,PAL[i][0]*Step/64,PAL[i][1]*Step/64,PAL[i][2]*Step/64);
Step--;
if (Step<1) KillAllTimer();
}
void OutInfo()
{
if (*Info++)
{
sound(1000);
printf("%c",*(Info-1));
nosound();
}
else
KillAllTimer();
}
/* 显示开始画面 */
void Logo()
{
FILE *bmp;
int i,r,g,b,x,y;
setmode();
bmp=fopen("logo.bmp","rb");
fseek(bmp,54,SEEK_SET);
for (i=0;i<256;i++)
{
PAL[i][2]=fgetc(bmp)>>2;
PAL[i][1]=fgetc(bmp)>>2;
PAL[i][0]=fgetc(bmp)>>2;
fgetc(bmp);
setpal(i,0,0,0);
}
for (y=0;y<200;y++)
for (x=0;x<320;x++) pokeb(0xa000,y*320+x,fgetc(bmp));
fclose(bmp);
CreateTimer(1,StepIn);
while (ScanKey()!=57&&TimerUsed) TimerEvent();
Step=64;
StepIn();
wait();
CreateTimer(1,StepOut);
while (ScanKey()!=57&&TimerUsed) TimerEvent();
Step=0;
StepOut();
closemode();
CreateTimer(2,OutInfo);
locate(6,26);
while (ScanKey()!=57&&TimerUsed) TimerEvent();
while (*Info++) printf("%c",*(Info-1));
wait();
}
void KillSelf()
{
if (SOUND)
{
sound(1000);
delay(1000);
nosound();
}
Life--;
if (Life<0) ALIVE=FALSE;
}
/* 设置系统所有调色板 */
void SetAllPal()
{
FILE *act;
int i,r,g,b;
act=fopen("comm.act","rb");
for (i=0;i<256;i++)
{
r=fgetc(act)>>2;
g=fgetc(act)>>2;
b=fgetc(act)>>2;
setpal(i,r,g,b);
}
fclose(act);
}
/* 从位图中读出各个物体的形状 */
void readboat()
{
FILE *bmp;
int x,y;
bmp=fopen("boat.bmp","rb");
fseek(bmp,1078,SEEK_SET);
for (y=0;y<32;y++)
{
for (x=0;x<64;x++) SHIP[0][31-y][x]=fgetc(bmp);
for (x=0;x<64;x++) SHIP[1][31-y][x]=fgetc(bmp);
}
fclose(bmp);
}
void readbomb()
{
FILE *bmp;
int x,y;
bmp=fopen("bomb.bmp","rb");
fseek(bmp,516,SEEK_SET);
for (y=0;y<32;y++)
for (x=0;x<32;x++) BOMB[31-y][x]=fgetc(bmp);
fclose(bmp);
}
void readtorp()
{
FILE *bmp;
int x,y;
bmp=fopen("torp.bmp","rb");
fseek(bmp,516,SEEK_SET);
for (y=0;y<16;y++)
for (x=0;x<16;x++) TORP[15-y][x]=fgetc(bmp);
fclose(bmp);
}
void readship()
{
FILE *bmp;
long i;
PIC_SHIP=Back2;
bmp=fopen("ship.bmp","rb");
fseek(bmp,1078,SEEK_SET);
for (i=0;i<10080;i++)
*PIC_SHIP++=fgetc(bmp);
fclose(bmp);
}
void readexpl()
{
FILE *bmp;
long i;
PIC_EXPL=Back1;
bmp=fopen("expl.bmp","rb");
fseek(bmp,1078,SEEK_SET);
for (i=0;i<59520;i++)
*PIC_EXPL++=fgetc(bmp);
fclose(bmp);
}
void bomb(int xx,int yy)
{
int y,x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -