home *** CD-ROM | disk | FTP | other *** search
- /*
- * MKSoft SnakePit Copyright (c) 1988 by Michael Sinz
- *
- * Main Game-Playing part...
- */
-
- #include "Snake.h"
-
- #define SCREEN_BONUS 250L
- #define FOOD_BONUS 125L
- #define SHRINK_BONUS 5L
-
- #define SlowSound (-200)
- #define SoundSpeedUp 7
-
- #define SOUND_3 35
- #define SOUND_2 25
- #define SOUND_6 15
- #define SOUND_4 5
-
- #define BIGNUM 20000
-
- #define ExitSpeed 30000L
-
- /*
- * START_LOOKING is the number of loops without a move before the system
- * starts looking for an out. After NO_MOVE_FOUND, it kills the snake.
- */
- #define START_LOOKING 9
- #define NO_MOVE_FOUND 18
-
- /* This is the interval of the speed changes */
- /* MAX Value: 100,000 MIN Value: 50 */
- #define SPEED_UP 28000L
- /* SPEED_UP_LEVEL should be 1/16th of SPEED_UP */
- #define SPEED_UP_LEVEL (SPEED_UP>>4L)
-
- #define FADE_SPEED 50000L
- #define FLASH_SPEED 1000L
-
- #define SET_DIR(x,y,z) (((x+1)<<2)+(y+1)+((z & 0x0F)<<4))
-
- #define DIR_UP 0x04
- #define DIR_DN 0x06
- #define DIR_LF 0x01
- #define DIR_RT 0x09
-
- #define DIR_UP_LF 0x14
- #define DIR_DN_LF 0x16
- #define DIR_LF_UP 0x41
- #define DIR_RT_UP 0x49
- #define DIR_UP_RT 0x94
- #define DIR_DN_RT 0x96
- #define DIR_LF_DN 0x61
- #define DIR_RT_DN 0x69
-
- #define DONE 2
- #define DEAD 3
- #define OK 1
- #define AM_HERE 32
-
- static short Play_Pointer[6] = {0x0000,0x0000,0x8000,0x8000,0x0000,0x0000};
-
- static short Play_Level;
- static short Lives;
- static long Score;
-
- static short Food_Count;
-
- static short Snake_X[1024];
- static short Snake_Y[1024];
- static short Snake_P[1024];
-
- static short Snake_Head;
- static short Snake_Tail;
- static short Snake_Size;
-
- static short Stall_Flag;
-
- static short Direction_X;
- static short Direction_Y;
-
- static long MicroSpeed;
-
- static Pit_Screen Play_Screen;
-
- static short SoundSpeed;
-
- static VOID Display_At(x,y,p) register short x;
- register short y;
- register short p;
- {
- register struct Image *i=&Empty;
-
- switch (p)
- {
- case DROP_BRICK:
- case NORMAL_BRICK: i=&Brick; break;
- case MOVING_BRICK: i=&MoveBrick; break;
- case GROW_FOOD: i=&GrowFood; break;
- case SHRINK_FOOD: i=&ShrinkFood; break;
- }
- DrawImage(MyWindow->RPort,i,((long)x<<3L),((long)y<<3L));
- }
-
- static VOID Do_Wait(microSpeed) register ULONG microSpeed;
- {
- Time_Req.tr_time.tv_secs=0;
- Time_Req.tr_time.tv_micro=microSpeed;
- DoIO(&Time_Req.tr_node);
- }
-
- VOID Do_Fade()
- {
- register short x;
-
- for(x=0;x<15;x++)
- {
- Set_Color_Level(x);
- Do_Wait(FADE_SPEED);
- }
- Set_Color_Level(15);
- }
-
- VOID UnDo_Fade()
- {
- register short x;
-
- for(x=15;x>0;x--)
- {
- Set_Color_Level(x);
- Do_Wait(FADE_SPEED);
- }
- Set_Color_Level(0);
- }
-
- static VOID SetUp_Screen()
- {
- register short x;
- register short y;
-
- Set_Color_Level(15);
- Play_Level--;
- Food_Count=0;
- for(x=0;x<NUM_COL;x++) for(y=0;y<NUM_ROW;y++)
- {
- Display_At(x,y,Play_Screen[x][y]=All_Pit_Screens[Play_Level][x][y]);
- if (Play_Screen[x][y]==GROW_FOOD) Food_Count++;
- }
- Play_Level++;
- UpDate_Status(Play_Level,Score,Lives);
- UnDo_Fade();
- }
-
- static VOID Drop_Bricks()
- {
- register short x;
- register short y;
-
- for(x=0;x<NUM_COL;x++) for(y=0;y<NUM_ROW;y++) if (Play_Screen[x][y]==DROP_BRICK) Display_At(x,y,Play_Screen[x][y]=EMPTY_SQUARE);
- }
-
- static VOID Move_Tail()
- {
- register struct Image *i;
- register short x;
- register short y;
- register short p;
-
- Snake_Size--;
- if (Snake_P[Snake_Tail])
- {
- p=(Play_Screen[x=Snake_X[Snake_Tail]][y=Snake_Y[Snake_Tail]])&31;
- Play_Screen[x][y]=p;
- Display_At(x,y,p);
- }
- Snake_Tail++;
- Snake_Tail&=1023;
- if (Snake_P[Snake_Tail])
- {
- switch (15 & Snake_P[Snake_Tail])
- {
- case DIR_RT: i=&Tail[0]; break;
- case DIR_UP: i=&Tail[1]; break;
- case DIR_LF: i=&Tail[2]; break;
- case DIR_DN: i=&Tail[3]; break;
- }
- DrawImage(MyWindow->RPort,i,((long)Snake_X[Snake_Tail]<<3L),((long)Snake_Y[Snake_Tail]<<3L));
- }
- }
-
- static VOID Display_Snake_Head()
- {
- register struct Image *i;
-
- switch (15 & Snake_P[Snake_Head])
- {
- case DIR_RT: i=&Head[0]; break;
- case DIR_UP: i=&Head[1]; break;
- case DIR_LF: i=&Head[2]; break;
- case DIR_DN: i=&Head[3]; break;
- }
- DrawImage(MyWindow->RPort,i,((long)Snake_X[Snake_Head]<<3L),((long)Snake_Y[Snake_Head]<<3L));
- }
-
- static VOID Move_Head(New_X,New_Y) register short New_X;
- register short New_Y;
- {
- register short New_Head;
- register struct Image *i;
-
- Stall_Flag=0;
- Score++;
- Snake_Size++;
- Direction_X=New_X;
- Direction_Y=New_Y;
- New_Head=(Snake_Head+1)&1023;
- Play_Screen[Snake_X[New_Head]=Snake_X[Snake_Head]+New_X][Snake_Y[New_Head]=Snake_Y[Snake_Head]+New_Y]|=AM_HERE;
- Snake_P[New_Head]=SET_DIR(New_X,New_Y,0);
- switch (Snake_P[Snake_Head]=SET_DIR(New_X,New_Y,Snake_P[Snake_Head]))
- {
- case DIR_UP_LF:
- case DIR_RT_DN: i=&Turn[0]; break;
- case DIR_UP_RT:
- case DIR_LF_DN: i=&Turn[1]; break;
- case DIR_DN_RT:
- case DIR_LF_UP: i=&Turn[2]; break;
- case DIR_DN_LF:
- case DIR_RT_UP: i=&Turn[3]; break;
- default: i=&Body[(New_X ? (1-New_X) : (New_Y+2))]; break;
- }
- DrawImage(MyWindow->RPort,i,((long)Snake_X[Snake_Head]<<3L),((long)Snake_Y[Snake_Head]<<3L));
- Snake_Head=New_Head;
- Display_Snake_Head();
- }
-
- static VOID New_Snake()
- {
- register short x;
- register short y;
- register short found_x=1;
- register short found_y=0;
-
- Direction_X=0;
- Direction_Y=1;
- Snake_Size=1;
- Snake_Head=2;
- Snake_Tail=0;
- Snake_P[0]=Snake_P[1]=0;
- for(x=0;x<NUM_COL;x+=NUM_COL-1) for(y=1;y<(NUM_ROW-1);y++) if (Play_Screen[x][y]==POPUP_BRICK)
- {
- found_x=x;
- found_y=y;
- Direction_Y=0;
- Direction_X=(x ? (-1):(1) );
- }
- for(x=1;x<(NUM_COL-1);x++) for(y=0;y<NUM_ROW;y+=NUM_ROW-1) if (Play_Screen[x][y]==POPUP_BRICK)
- {
- found_x=x;
- found_y=y;
- Direction_X=0;
- Direction_Y=(y ? (-1):(1) );
- }
- Play_Screen[found_x][found_y]=NORMAL_BRICK | AM_HERE;
- Snake_X[Snake_Head]=found_x;
- Snake_Y[Snake_Head]=found_y;
- Snake_P[Snake_Head]=SET_DIR(Direction_X,Direction_Y,0);
- Display_Snake_Head();
- }
-
- static short Move_Snake(New_X,New_Y) register short New_X;
- register short New_Y;
- {
- register short x;
- register short y;
- short x1;
- short y1;
- short flag=FALSE;
-
- if ((New_X!=Direction_X)||(New_Y!=Direction_Y))
- {
- if ((-New_X!=Direction_X)&&(-New_Y!=Direction_Y))
- {
- x=Snake_X[Snake_Head]+New_X;
- y=Snake_Y[Snake_Head]+New_Y;
- if ((x>=0)&&(y>=0)&&(x<NUM_COL)&&(y<NUM_ROW))
- {
- switch (Play_Screen[x][y])
- {
- case POPUP_BRICK:
- case EMPTY_SQUARE:
- case GROW_FOOD:
- case SHRINK_FOOD:
- case MOVING_BRICK: break;
- default: New_X=Direction_X;
- New_Y=Direction_Y;
- break;
- }
- }
- }
- else
- {
- New_X=Direction_X;
- New_Y=Direction_Y;
- }
- }
- x=Snake_X[Snake_Head]+New_X;
- y=Snake_Y[Snake_Head]+New_Y;
- if ((x<0)||(y<0)||(x>=NUM_COL)||(y>=NUM_ROW)) return(DONE);
- if (Play_Screen[x][y]>=AM_HERE) return(DEAD);
- if (Play_Screen[x][y]==MOVING_BRICK)
- {
- x1=x+New_X;
- y1=y+New_Y;
- if ((x1>=0)&&(y1>=0)&&(x1<NUM_COL)&&(y1<NUM_ROW))
- {
- if (Play_Screen[x1][y1]==EMPTY_SQUARE)
- {
- Display_At(x1,y1,Play_Screen[x1][y1]=Play_Screen[x][y]);
- Play_Screen[x][y]=EMPTY_SQUARE;
- }
- }
- }
- switch (Play_Screen[x][y])
- {
- case SHRINK_FOOD: Play_Screen[x][y]=EMPTY_SQUARE;
- Score+=SHRINK_BONUS;
- Move_Tail();
- Sound_Eat(x);
- if (Snake_Size)
- {
- Move_Head(New_X,New_Y);
- Move_Tail();
- }
- else return(DEAD);
- break;
- case GROW_FOOD: Play_Screen[x][y]=EMPTY_SQUARE;
- Score+=FOOD_BONUS;
- Food_Count--;
- Move_Head(New_X,New_Y);
- Sound_Eat(x);
- switch (Food_Count)
- {
- case SOUND_2: Sound_Play(2,BIGNUM,SoundSpeed-SOUND_2); break;
- case SOUND_3: Sound_Play(3,BIGNUM,SoundSpeed-SOUND_3); break;
- case SOUND_4: Sound_Play(4,BIGNUM,SoundSpeed-SOUND_4); break;
- case SOUND_6: Sound_Play(6,BIGNUM,SoundSpeed-SOUND_6); break;
- }
- if (!Food_Count) Drop_Bricks();
- break;
- case POPUP_BRICK: Play_Screen[x][y]=NORMAL_BRICK;
- case EMPTY_SQUARE: Move_Head(New_X,New_Y);
- Sound_Move(x);
- Move_Tail();
- break;
- }
- return(OK);
- }
-
- static VOID Do_Kill_Snake()
- {
- Sound_Dead();
- while (Snake_Size) Move_Tail();
- Move_Tail();
- Snake_P[(Snake_Tail+1)&1023]=0;
- Move_Tail();
- Do_Fade();
- }
-
- static VOID Do_Play()
- {
- register struct IntuiMessage *msg;
- register struct MsgPort *MyPort;
- register short New_X;
- register short New_Y;
- register UBYTE tmp;
- short flag;
- short move_flag;
- short t_move;
-
- MyPort=MyWindow->UserPort;
- while(Lives)
- {
- SoundSpeed+=SoundSpeedUp;
- if ((SoundPeriod-SoundSpeed)<80) SoundSpeed=SoundPeriod-80;
- Sound_Play(2,BIGNUM,SlowSound);
- SetUp_Screen();
- New_Snake();
- while (msg=(struct IntuiMessage *)GetMsg(MyPort)) ReplyMsg(msg);
-
- flag=FALSE;
- while(!flag)
- {
- WaitPort(MyPort);
- msg=(VOID *)(MyPort->mp_MsgList.lh_Head);
- if (msg->ExecMessage.mn_Node.ln_Succ)
- {
- if ((msg->Class==RAWKEY)||(msg->Class==MENUPICK)) flag=TRUE;
- else ReplyMsg(GetMsg(MyPort));
- }
- }
-
- /*
- * This is the start of the playing of a single screen/man. After
- * some I/O is received, we get to here and start the snake...
- */
- Sound_Play(1,BIGNUM,SoundSpeed-Food_Count);
- New_X=Direction_X;
- New_Y=Direction_Y;
- Stall_Flag=0;
- while(flag)
- {
- UpDate_Status(Play_Level,Score,Lives);
- Do_Wait(MicroSpeed);
- if (Score) Score--;
- Cycle_Colors();
- Stall_Flag++;
- if (Stall_Flag>START_LOOKING)
- {
- New_X=New_Y=0;
- switch ((Stall_Flag+(Score>>3))&3)
- {
- case 0: New_X=-1; break;
- case 1: New_X= 1; break;
- case 2: New_Y= 1; break;
- case 3: New_Y=-1; break;
- }
- }
- while(msg=(struct IntuiMessage *)GetMsg(MyPort))
- {
- if (msg->Class==RAWKEY)
- {
- tmp=(UBYTE)msg->Code;
- if (tmp==KeyList[0].raw)
- {
- New_X=0;
- New_Y=-1;
- }
- else if (tmp==KeyList[1].raw)
- {
- New_X=0;
- New_Y=1;
- }
- else if (tmp==KeyList[2].raw)
- {
- New_X=-1;
- New_Y=0;
- }
- else if (tmp==KeyList[3].raw)
- {
- New_X=1;
- New_Y=0;
- }
- }
- if ((msg->Class==MENUPICK)||(tmp==RAW_ESC))
- {
- ClearPointer(MyWindow);
- tmp=Request_Pause();
- SetPointer(MyWindow,Play_Pointer,1L,1L,-1L,0L);
- if (tmp>1)
- {
- Lives--;
- flag=FALSE;
- }
- if (tmp>2)
- {
- Sound_Dead();
- Lives=0;
- }
- }
- ReplyMsg(msg);
- }
- if (Stall_Flag>NO_MOVE_FOUND)
- {
- Do_Kill_Snake();
- Lives--;
- flag=FALSE;
- }
- if (flag)
- {
- move_flag=Move_Snake(New_X,New_Y);
- if (move_flag==DONE)
- {
- DrawImage(MyWindow->RPort,&Body[(Direction_X ? (1-Direction_X) : (Direction_Y+2))],((long)Snake_X[Snake_Head]<<3L),((long)Snake_Y[Snake_Head]<<3L));
- Sound_Finish();
- while (Snake_Size)
- {
- Move_Tail();
- Cycle_Colors();
- Score+=SCREEN_BONUS;
- UpDate_Status(Play_Level,Score,Lives);
- Do_Wait(ExitSpeed);
- }
- Move_Tail();
- Snake_P[(Snake_Tail+1)&1023]=0;
- Do_Wait(MicroSpeed); Move_Tail();
- Do_Fade();
- Score+=SCREEN_BONUS;
- flag=FALSE;
- Lives++;
- Play_Level++;
- UpDate_Status(Play_Level,Score,Lives);
- if (MicroSpeed>SPEED_UP_LEVEL) MicroSpeed-=SPEED_UP_LEVEL;
- if (Play_Level>MAX_LEVEL) Play_Level=1;
- }
- else if (move_flag==DEAD)
- {
- Do_Kill_Snake();
- Lives--;
- flag=FALSE;
- }
- }
- }
- }
- }
-
- VOID Play_Game(UserSpeed) short UserSpeed;
- {
- register ULONG tmpIDCMP;
-
- OffMenu(MyWindow,SHIFTMENU(0)|SHIFTITEM(NOITEM)|SHIFTSUB(NOSUB) );
- OffMenu(MyWindow,SHIFTMENU(1)|SHIFTITEM(NOITEM)|SHIFTSUB(NOSUB) );
-
- tmpIDCMP=MyWindow->IDCMPFlags;
- ModifyIDCMP(MyWindow,RAWKEY|MENUPICK);
-
- ClearPointer(MyWindow);
- Play_Level=Request_SelectLevel(0);
- Sound_Play(2,BIGNUM,SlowSound);
- Lives=5;
- Score=NULL;
- SetRast(MyWindow->RPort,0L);
- UpDate_Status(Play_Level,Score,Lives);
- MicroSpeed=(10L-((long)UserSpeed))*SPEED_UP;
- SoundSpeed=0;
- SetPointer(MyWindow,Play_Pointer,1L,1L,-1L,0L);
- Do_Play();
- Sound_Play(2,BIGNUM,0);
- ClearPointer(MyWindow);
- Set_Color_Level(0);
- Request_HighScores(Score);
- ShowWait();
-
- ModifyIDCMP(MyWindow,tmpIDCMP);
-
- OnMenu (MyWindow,SHIFTMENU(1)|SHIFTITEM(NOITEM)|SHIFTSUB(NOSUB) );
- OnMenu (MyWindow,SHIFTMENU(0)|SHIFTITEM(NOITEM)|SHIFTSUB(NOSUB) );
- }
-