1325 lines
61 KiB
HolyC
Executable File
1325 lines
61 KiB
HolyC
Executable File
/*Sprites were created with <CTRL-r>
|
||
and can be edited by moving the
|
||
cursor on top and pressing <CTRL-r>.
|
||
|
||
<CTRL-t> to see the num of the sprite
|
||
and <CTRL-t> again to get back. Nums
|
||
are assigned by the editor.
|
||
*/
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<1>",BI=1$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<2>",BI=2$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<3>",BI=3$
|
||
|
||
|
||
|
||
$SP,"<4>",BI=4$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<5>",BI=5$
|
||
|
||
|
||
|
||
$SP,"<6>",BI=6$
|
||
|
||
//See $LK,"::/Doc/Credits.DD"$.
|
||
|
||
|
||
|
||
$SP,"<7>",BI=7$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<8>",BI=8$
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
$SP,"<9>",BI=9$
|
||
|
||
RegDft("TempleOS/BlackDiamond","I64 best_score=9999;\n");
|
||
RegExe("TempleOS/BlackDiamond");
|
||
|
||
#define MAP_HEIGHT 3000
|
||
#define OBJS_NUM 128
|
||
|
||
I64 x,y,scrn_top_y,penalty,chair_lift_num;
|
||
I64 obj_x[OBJS_NUM],obj_y[OBJS_NUM],obj_types[OBJS_NUM],
|
||
obj_saved_x[OBJS_NUM],obj_saved_y[OBJS_NUM];
|
||
Bool game_over;
|
||
|
||
#define T_TREE 0
|
||
#define T_LITTLE_ROCK 1
|
||
#define T_BIG_ROCK 2
|
||
#define T_WOLF 3
|
||
#define T_CHAIR_LIFT 4
|
||
U8 *imgs[5]={$IB,"<3>",BI=3$,$IB,"<4>",BI=4$,$IB,"<5>",BI=5$,$IB,"<6>",BI=6$,$IB,"<9>",BI=9$};
|
||
|
||
#define DC_WOLF_WIDTH 48
|
||
#define DC_WOLF_HEIGHT 38
|
||
U0 DrawRunningWolf(CDC *dc,I64 i)
|
||
{//Draw wolf on small DC so bottom gets clipped looking like sunk into snow.
|
||
//Then, copy onto main DC.
|
||
U8 *tmps;
|
||
CDC *dc_wolf=DCNew(DC_WOLF_WIDTH,DC_WOLF_HEIGHT);
|
||
DCFill(dc_wolf);
|
||
if (x<obj_x[i]) {
|
||
dc_wolf->flags|=DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR;
|
||
DCSymmetrySet(dc_wolf,DC_WOLF_WIDTH/2,0,DC_WOLF_WIDTH/2,1);
|
||
}
|
||
if (tS%1.0<0.5)
|
||
tmps=$IB,"<6>",BI=6$;
|
||
else
|
||
tmps=$IB,"<7>",BI=7$;
|
||
Sprite3ZB(dc_wolf,DC_WOLF_WIDTH/2,0.85*DC_WOLF_HEIGHT,
|
||
0,tmps,0.4*Sin(7*tS));
|
||
GrBlot(dc,obj_x[i]-DC_WOLF_WIDTH/2,
|
||
obj_y[i]-scrn_top_y-0.85*DC_WOLF_HEIGHT,dc_wolf);
|
||
DCDel(dc_wolf);
|
||
if (0<=(obj_y[i]-scrn_top_y)<GR_HEIGHT)
|
||
obj_x[i]+=3*SignI64(x-obj_x[i]);
|
||
}
|
||
|
||
U0 DrawMan(CDC *dc)
|
||
{
|
||
if(dc->collision_cnt)
|
||
Sprite3(dc,x,y-scrn_top_y,0,$IB,"<2>",BI=2$); //Red man
|
||
else
|
||
Sprite3(dc,x,y-scrn_top_y,0,$IB,"<1>",BI=1$); //Normal man
|
||
}
|
||
|
||
#define WIRE_HEIGHT 595
|
||
#define WIRE_WIDTH 121
|
||
#define WIRE_DIP 800
|
||
#define PULLY_WIDTH 13
|
||
U0 DrawUpperChairLift(CDC *dc)
|
||
{
|
||
I64 i=chair_lift_num,x,x1,y=obj_y[i]-scrn_top_y-WIRE_HEIGHT,y1;
|
||
Sprite3(dc,obj_x[i],y+13,0,$IB,"<8>",BI=8$);
|
||
dc->thick=2;
|
||
for (x=-WIRE_WIDTH/2;x<GR_WIDTH+WIRE_WIDTH/2;x+=2) { //Pen width is 2, step 2.
|
||
x1=x-obj_x[i];
|
||
y1=y-WIRE_DIP/2+Cosh(Ln(WIRE_DIP)+(Abs(x1)-PULLY_WIDTH)/10000.0)+0.1*x1;
|
||
if (!(-PULLY_WIDTH<x1<PULLY_WIDTH)) {
|
||
GrPlot3(dc,x-WIRE_WIDTH/2,y1,0);
|
||
GrPlot3(dc,x+WIRE_WIDTH/2,y1,0);
|
||
}
|
||
}
|
||
dc->thick=1;
|
||
}
|
||
|
||
U0 DrawIt(CTask *,CDC *dc)
|
||
{
|
||
I64 i;
|
||
Bool man_drawn=FALSE;
|
||
|
||
for (i=0;i<OBJS_NUM;i++)
|
||
if (obj_y[i]-32<=y<=obj_y[i]) {
|
||
if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
|
||
DrawRunningWolf(dc,i);
|
||
else
|
||
Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
|
||
}
|
||
|
||
dc->collision_cnt=0;
|
||
dc->color=ROP_COLLISION;
|
||
dc->bkcolor=WHITE;
|
||
Sprite3(dc,x,y-scrn_top_y,0,$IB,"<1>",BI=1$);
|
||
if (!game_over) {
|
||
if(dc->collision_cnt) {
|
||
Snd(58);
|
||
penalty++; //Time is irregular. Scoring is imperfect. 30fps more or less.
|
||
} else
|
||
Snd;
|
||
}
|
||
|
||
dc->color=ROP_EQU;
|
||
for (i=0;i<OBJS_NUM;i++) {
|
||
if (!man_drawn && obj_y[i]>=y) {
|
||
DrawMan(dc);
|
||
man_drawn=TRUE;
|
||
}
|
||
if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
|
||
DrawRunningWolf(dc,i);
|
||
else
|
||
Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
|
||
}
|
||
if (!man_drawn)
|
||
DrawMan(dc);
|
||
DrawUpperChairLift(dc);
|
||
|
||
dc->color=BLACK;
|
||
GrPrint(dc,0,0,"Penalty:%d Best:%d",penalty,best_score);
|
||
if (game_over && Blink) {
|
||
dc->color=RED;
|
||
GrPrint(dc,(Fs->pix_width-9*FONT_WIDTH)/2,
|
||
(Fs->pix_height-FONT_HEIGHT)/2,"Game Over");
|
||
}
|
||
}
|
||
|
||
I64 Compare(I64 e1,I64 e2)
|
||
{
|
||
return e1-e2;
|
||
}
|
||
|
||
U0 Init()
|
||
{
|
||
I64 i,j;
|
||
for (i=0;i<OBJS_NUM;i++) {
|
||
obj_saved_y[i]=RandU32%MAP_HEIGHT;
|
||
obj_saved_x[i]=RandU32%GR_WIDTH;
|
||
j=RandU16;
|
||
if (j&7)
|
||
obj_types[i]=T_TREE;
|
||
else if (j&31)
|
||
obj_types[i]=T_LITTLE_ROCK;
|
||
else if (j&63)
|
||
obj_types[i]=T_BIG_ROCK;
|
||
else
|
||
obj_types[i]=T_WOLF;
|
||
}
|
||
QSortI64(obj_saved_y,OBJS_NUM,&Compare); //Break associations. Doesn't matter.
|
||
|
||
chair_lift_num=RandU16%OBJS_NUM;
|
||
obj_types[chair_lift_num]=T_CHAIR_LIFT;
|
||
}
|
||
|
||
U0 BlackDiamond()
|
||
{
|
||
I64 ch,sc;
|
||
|
||
MenuPush(
|
||
"File {"
|
||
" New(,'\n');"
|
||
" Restart(,CH_SPACE);"
|
||
" Abort(,CH_SHIFT_ESC);"
|
||
" Exit(,CH_ESC);"
|
||
"}"
|
||
"Play {"
|
||
" Up(,,SC_CURSOR_UP);"
|
||
" Down(,,SC_CURSOR_DOWN);"
|
||
" Left(,,SC_CURSOR_LEFT);"
|
||
" Right(,,SC_CURSOR_RIGHT);"
|
||
"}"
|
||
);
|
||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||
AutoComplete;
|
||
WinBorder;
|
||
WinMax;
|
||
DocCursor;
|
||
DocClear;
|
||
Fs->draw_it=&DrawIt;
|
||
|
||
Init;
|
||
try {
|
||
while (TRUE) {
|
||
bd_restart:
|
||
MemCpy(obj_x,obj_saved_x,sizeof(obj_x)); //Wolves move. We must reset the
|
||
MemCpy(obj_y,obj_saved_y,sizeof(obj_y)); //wolves if running same game.
|
||
|
||
game_over=FALSE;
|
||
scrn_top_y=0;
|
||
x=Fs->pix_width>>1; y=0;
|
||
penalty=0;
|
||
while (TRUE) {
|
||
if (ScanKey(&ch,&sc)) {
|
||
switch (ch) {
|
||
case 0:
|
||
if (!game_over)
|
||
switch (sc.u8[0]) {
|
||
case SC_CURSOR_RIGHT:
|
||
x+=10;
|
||
if (x>=Fs->pix_width) x-=Fs->pix_width;
|
||
break;
|
||
case SC_CURSOR_LEFT:
|
||
x-=10;
|
||
if (x<0) x+=Fs->pix_width;
|
||
break;
|
||
case SC_CURSOR_UP:
|
||
y-=10;
|
||
break;
|
||
case SC_CURSOR_DOWN:
|
||
y+=10;
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case CH_ESC:
|
||
case CH_SHIFT_ESC:
|
||
goto bd_done;
|
||
|
||
case '\n':
|
||
Init;
|
||
goto bd_restart;
|
||
|
||
case CH_SPACE:
|
||
game_over=TRUE;
|
||
while (scrn_top_y>0||y>0) {//Animate going back to top.
|
||
scrn_top_y=MaxI64(0,scrn_top_y-4);
|
||
y=MaxI64(0,y-4);
|
||
x+=SignI64(Fs->pix_width>>1-x);
|
||
Sleep(1);
|
||
}
|
||
Snd;
|
||
goto bd_restart;
|
||
}
|
||
//Don't want keystrokes building-up in the buf.
|
||
FlushMsgs;
|
||
}
|
||
if (!game_over) {
|
||
y+=2;
|
||
scrn_top_y++;
|
||
if (y-scrn_top_y>Fs->pix_height) {//Animate scrolling scrn.
|
||
while (y-scrn_top_y>Fs->pix_height>>1) {
|
||
scrn_top_y+=2;
|
||
Sleep(1);
|
||
}
|
||
}
|
||
if (y>=MAP_HEIGHT) {
|
||
game_over=TRUE;
|
||
Beep;
|
||
if (penalty<=best_score) {
|
||
best_score=penalty;
|
||
Beep;
|
||
}
|
||
}
|
||
}
|
||
Sleep(10);
|
||
}
|
||
}
|
||
bd_done:
|
||
} catch
|
||
PutExcept;
|
||
SettingsPop;
|
||
MenuPop;
|
||
RegWrite("TempleOS/BlackDiamond","I64 best_score=%d;\n",best_score);
|
||
}
|
||
|
||
BlackDiamond; //Start game when #included.
|
||
|