ZealOS/src/Demo/Games/BigGuns.CC

326 lines
No EOL
6.1 KiB
HolyC
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.CC"$.
class MyMass:CMass
{
Bool collision;
};
#define MAP_WIDTH 2048
#define MAP_HEIGHT (GR_HEIGHT-3*FONT_HEIGHT)
I64 gun_x,gun_y,active_map=0,gun_recoil;
F64 gun_é;
CDC *map_dcs[2]={NULL,NULL};
I16 elevs[MAP_WIDTH];
F64 wind_x;
#define DUST_NUM 512
I64 dust_x[DUST_NUM],dust_y[DUST_NUM];
CMathODE *ode=NULL;
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
U0 DrawIt(CTask *task,CDC *dc)
{
CDC *map=map_dcs[active_map&1];
MyMass *tmpm;
F64 é=gun_é;
I64 i,x,y,w,
h=-task->horz_scroll.pos,
v=-task->vert_scroll.pos;
task->horz_scroll.min=0;
task->horz_scroll.max=MAP_WIDTH-task->pix_width;
task->vert_scroll.min=0;
task->vert_scroll.max=MAP_HEIGHT-task->pix_height;
map->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,h,v,map);
Sprite3(dc,gun_x+h,gun_y+v,0,$IB,"<2>",BI=2$);
if (é<-ã/2) {
dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
DCSymmetrySet(dc,gun_x+h,0,gun_x+h,1);
é=-ã-é;
}
Sprite3ZB(dc,
gun_x+h-gun_recoil*Cos(é),
gun_y+v-gun_recoil*Sin(é)-10,0,$IB,"<1>",BI=1$,é);
dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
tmpm=ode->next_mass;
dc->color=BLACK;
map->color=ROP_COLLISION;
map->bkcolor=LTCYAN;
while (tmpm!=&ode->next_mass) {
map->collision_count=0;
GrCircle(map,tmpm->x,tmpm->y,2);
if (map->collision_count)
tmpm->collision=TRUE;
GrCircle(dc,tmpm->x+h,tmpm->y+v,2);
tmpm=tmpm->next;
}
dc->color=LTGRAY;
w=tS*wind_x;
for (i=0;i<DUST_NUM;i++) {
x=(dust_x[i]+w)%MAP_WIDTH;
y=dust_y[i];
if (y<elevs[x])
GrPlot(dc,x+h,y+v);
}
}
U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
{
MyMass *tmpm=ode->next_mass;
while (tmpm!=&ode->next_mass) {
tmpm->DstateDt->DyDt+=1000.0*tmpm->mass;
tmpm->DstateDt->DxDt+=25.0*wind_x;
tmpm=tmpm->next;
}
}
U0 DrawMap()
{
CDC *map=map_dcs[(active_map+1)&1];
I64 x;
map->color=LTCYAN;
GrRect(map,0,0,MAP_WIDTH,MAP_HEIGHT);
map->color=BLACK;
for (x=1;x<MAP_WIDTH;x++)
GrLine(map,x-1,elevs[x-1],x,elevs[x]);
map->color=BROWN;
GrFloodFill(map,0,MAP_HEIGHT-1,FALSE);
active_map++;
}
U0 FireTask(I64)
{
MyMass *tmpm;
I64 i;
if (gun_recoil) return;
tmpm=CAlloc(sizeof(MyMass),Fs->parent_task);
tmpm->mass=10.0;
tmpm->drag_profile_factor=0.1;
tmpm->x=gun_x+27*Cos(gun_é);
tmpm->y=gun_y-15+27*Sin(gun_é);
tmpm->DxDt=600.0*Cos(gun_é);
tmpm->DyDt=600.0*Sin(gun_é);
tmpm->collision=FALSE;
while (sys_task_being_screen_updated==Fs->parent_task)
Yield;
QueueInsert(tmpm,ode->last_mass);
Fs->task_end_cb=&SoundTaskEndCB;
for (i=0;i<60;i++) {
Sound(50*Rand+10);
Sleep(2);
gun_recoil=i/12;
}
for (i=0;i<=60;i++) {
Sleep(1);
gun_recoil=5-i/12;
}
}
U0 ManageShots()
{
I64 i;
MyMass *tmpm,*tmpm1;
Bool chged=FALSE;
tmpm=ode->next_mass;
while (tmpm!=&ode->next_mass) {
tmpm1=tmpm->next;
if (!(0<=tmpm->x<MAP_WIDTH) ||
tmpm->collision) {
QueueRemove(tmpm);
for (i=tmpm->x-4;i<=tmpm->x+4;i++)
if (0<=i<MAP_WIDTH)
elevs[i]=ClampI64(elevs[i]+10-2*AbsI64(i-tmpm->x),0,MAP_HEIGHT-2);
Free(tmpm);
chged=TRUE;
}
tmpm=tmpm1;
}
if (chged)
DrawMap;
}
U0 MoveTask(I64)
{
static F64 quit_time=0;
if (quit_time)
quit_time=tS+0.1;
else {
Sound(34);
Fs->task_end_cb=&SoundTaskEndCB;
quit_time=tS+0.1;
while (quit_time>tS)
Yield;
quit_time=0;
}
}
U0 Init()
{
CDC *map;
I64 i,x,y,dy;
if (!map_dcs[0])
map_dcs[0]=DCNew(MAP_WIDTH,MAP_HEIGHT);
if (!map_dcs[1])
map_dcs[1]=DCNew(MAP_WIDTH,MAP_HEIGHT);
map=map_dcs[active_map&1];
Fs->horz_scroll.pos=0;
Fs->vert_scroll.pos=0;
y=ToI64(0.7*MAP_HEIGHT)<<32;
dy=0;
for (x=0;x<MAP_WIDTH;x++) {
dy=ClampI64(SignI64(RandI16)<<30+dy,-3<<32,3<<32);
y=ClampI64(y+dy,ToI64(0.3*MAP_HEIGHT)<<32,(MAP_HEIGHT-2)<<32);
elevs[x]=y.i32[1];
}
gun_x=RandU32%(MAP_WIDTH-100)+50;
gun_y=elevs[gun_x];
gun_é=0;
gun_recoil=0;
for (x=gun_x-20;x<=gun_x+20;x++)
elevs[x]=gun_y;
wind_x=RandI16/250.0;
for (i=0;i<DUST_NUM;i++) {
dust_x[i]=RandU16%MAP_WIDTH;
dust_y[i]=RandU16%MAP_HEIGHT;
}
ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
ode->derive=&MyDerivative;
ode->drag_v2=0.002;
ode->drag_v3=0.0001;
ode->acceleration_limit=5e5;
QueueInsert(ode,Fs->last_ode);
Fs->horz_scroll.min=0;
Fs->horz_scroll.max=MAP_WIDTH-Fs->pix_width;
Fs->horz_scroll.pos=gun_x-Fs->pix_width/2;
Fs->vert_scroll.min=0;
Fs->vert_scroll.max=MAP_HEIGHT-Fs->pix_height;
Fs->vert_scroll.pos=0;
TaskDerivedValsUpdate;
DrawMap;
}
U0 CleanUp(CMathODE *ode)
{
if (ode) {
QueueRemove(ode);
QueueDel(&ode->next_mass,TRUE);
ODEDel(ode);
}
}
U0 BigGuns()
{
I64 ch,sc;
PopUpOk(
"I refuse to rip-off the original\n"
"so this is intentionally crappy\n"
"and included for demonstration\n"
"purposes.\n\n"
"Write games, don't play them.\n");
PopUpOk("The map scrolls.\n");
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Fire(,CH_SPACE);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
"}"
);
AutoComplete;
WinBorder(ON);
WinMax;
DocCursor;
DocClear;
DocScroll;
Init;
Fs->draw_it=&DrawIt;
try {
while (TRUE) {
while (KeyScan(&ch,&sc))
switch (ch) {
case 0:
switch (sc.u8[0]) {
case SC_CURSOR_RIGHT:
gun_é+=2.0*ã/180;
if (gun_é>0)
gun_é=0;
else
Spawn(&MoveTask,NULL,"Move",,Fs);
break;
case SC_CURSOR_LEFT:
gun_é-=2.0*ã/180;
if (gun_é<-ã)
gun_é=-ã;
else
Spawn(&MoveTask,NULL,"Move",,Fs);
break;
}
break;
case '\n':
CleanUp(ode);
Init;
break;
case CH_SPACE:
Spawn(&FireTask,NULL,"Fire",,Fs);
break;
case CH_SHIFT_ESC:
case CH_ESC:
goto bg_done;
}
ManageShots;
Refresh;
}
bg_done:
} catch
PutExcept;
SettingsPop;
DCDel(map_dcs[0]); map_dcs[0]=NULL;
DCDel(map_dcs[1]); map_dcs[1]=NULL;
CleanUp(ode);
MenuPop;
}
BigGuns;
;

þÿÿÿ
þÿÿÿ
n
ñÿÿÿýÿÿÿ
ýÿÿÿúÿÿÿþÿÿÿ
úÿÿÿþÿÿÿðÿÿÿ
õÿÿÿÿÿÿÿ ÿÿÿÿ
óÿÿÿýÿÿÿ
ôÿÿÿ