// C Source File
// Created 9/4/2004; 2:22:32 PM

// Delete or comment out the items you do not need.
/*
#define COMMENT_STRING         "Place your comment here."
#define COMMENT_PROGRAM_NAME   "Place your program name here."
#define COMMENT_VERSION_STRING "Place your version string here."
#define COMMENT_VERSION_NUMBER 0,0,0,0 */ /** major, minor, revision, subrevision */
/*#define COMMENT_BW_ICON \
	{0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000}
#define COMMENT_GRAY_ICON \
	{0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000}, \
	{0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000, \
	 0b0000000000000000}*/
	 
#include "C:\Documents and Settings\Owner\My Documents\Gregs Stuff\Calculator\Software\Projects\SMB89\MainHeader.h"

//MARIOS PIMP ASS DEFINITION
MARIOCHAR Mario;

//THE CURRENT MAP DEF
MAPDATA CurrentMap;

//THE CHEAT STATUS
CHEATS Cheats;

//SOME FUNCTION DECLARATIONS
void MainLoop();
void keys_DoKeys();
void Do_LevelEnd();

//SOME PROGRAM VARIABLES
char ExitApp=0;
char LevelComplete;

//char *Map;
/*char Map[16][501];*//*=
char *Map*/
char Map[16][501]=
{
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,12,11,0,0,0,0,0,0,0,0,0,6,6,6,6,6,6,6,6,0,0,0,6,6,6,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,0,0,0,0,6,6,6,0,0,0,0,6,2,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,14,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,9,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,14,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,0,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,64,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,0,0,0,0,0,0,0,0,14,0},
	{0,0,0,0,0,0,5,103,0,106,0,0,108,5,0,0,0,0,0,0,0,104,0,105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,12,12,12,12,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,14,0},
	{0,0,0,0,0,0,6,6,6,6,6,6,6,6,0,0,2,0,0,0,6,90,6,2,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,0,0,0,0,0,24,25,0,0,0,0,119,0,0,0,0,24,25,0,0,0,0,0,0,0,0,64,64,10,64,64,0,0,0,0,0,6,90,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,0,0,0,0,0,6,91,0,0,0,0,2,0,0,2,0,0,2,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,6,6,0,0,0,0,0,0,5,0,0,5,0,0,0,0,0,0,0,0,0,0,5,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,6,6,2,6,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,14,0},
	{0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,111,0,0,0,0,0,0,0,0,0,24,25,0,0,0,0,0,0,26,27,0,121,23,102,0,0,0,0,0,26,27,0,0,0,0,0,0,0,0,64,7,9,8,64,0,0,0,0,0,0,0,0,0,0,0,0,5,65,65,65,65,65,65,65,65,65,5,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,5,5,0,0,0,0,23,0,0,0,5,5,5,0,0,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,0,0,0,0,23,0,0,0,14,0},
	{0,1,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,24,25,0,0,107,0,108,0,0,0,26,27,114,0,122,0,115,0,26,27,0,20,21,22,0,120,102,0,0,26,27,0,0,0,0,0,0,5,0,64,7,10,8,64,0,0,0,0,0,0,0,0,0,0,0,5,5,0,0,0,0,0,0,0,0,0,5,5,0,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,5,5,5,0,0,20,21,22,0,5,5,5,5,0,0,5,5,5,0,0,0,23,0,24,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,25,0,5,5,5,5,5,5,5,5,0,0,0,20,21,22,0,0,14,0},
	{20,21,21,21,22,117,117,117,117,0,0,16,18,18,18,19,20,21,22,102,0,0,0,0,16,18,19,0,0,26,27,0,106,0,0,0,0,109,0,26,27,0,16,54,17,19,0,26,27,20,21,62,21,22,0,0,0,0,26,27,16,17,17,17,19,20,21,22,64,7,9,8,64,17,19,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,16,17,17,19,0,5,5,5,21,21,21,22,0,0,0,0,0,0,16,17,17,17,19,20,21,22,0,0,0,0,16,17,19,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,17,17,5,5,5,5,20,21,21,21,5,5,5,5,5,0,0,5,5,5,5,19,20,21,22,26,27,0,0,16,17,19,0,0,0,0,0,0,0,0,0,26,27,5,5,5,5,5,5,5,5,5,0,0,20,21,21,21,22,0,5,0},
	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};

short Warps[40];


short BumpX, BumpY; //holds which tile your head smacked
short Particle[14][7];
short Enemy[30][7];
short Time, ScrollX, ScrollY;

//holds the list of maps to play..
char MapQueue[100][10];

//for debub
BOOL CheatsOn, dbvar2;

short *ScenePtr;

//Main Function
void _main(void)
{
	short x;
	
	//makes sure the file exists, if not, exit early
	HSym hsym2=SymFind(SYMSTR("msprites"));
	if(hsym2.folder==0)
	{
		ST_helpMsg("Missing Sprite File");
		return;
	}
	
	//get pointer to map sprites..
	FILE *f = fopen("msprites", "rb");

	fread(MapSprites,sizeof(MapSprites),1,f);
	fread(MarioSprites,sizeof(MarioSprites),1,f);
	fread(BigMarioSprites,sizeof(BigMarioSprites),1,f);
	fread(FireMarioSprites,sizeof(FireMarioSprites),1,f);
	fread(SmallSprites,sizeof(SmallSprites),1,f);
	fread(WideSprites,sizeof(WideSprites),1,f);
	fread(SmallTallSprites,sizeof(SmallTallSprites),1,f);
	
	//fgetpos(f,(unsigned long*)MapSprites);
	fclose (f);

	//load map
	/*FILE *f2 = fopen("map1", "rb");
	fread(Map,sizeof(Map),1,f2);
	fclose(f2);*/
	
	//put map in ram
	/*Map=malloc(sizeof(TheMap));
	memcpy(Map,TheMap,sizeof(TheMap));*/
	
	//save old auto ints
  INT_HANDLER save_1 = GetIntVec(AUTO_INT_1); 
  INT_HANDLER save_5 = GetIntVec(AUTO_INT_5);  
  
  // Sets It Up For _keytest usage..
	SetIntVec(AUTO_INT_1, DUMMY_HANDLER); 
	SetIntVec(AUTO_INT_5, DUMMY_HANDLER); 
	
	// Place your code here.
	//clear our screen
	ClearScreen();
	
	//turns gs on
	GGrayOn();
	
	//for debug.. init the default map
	CurrentMap.Length=200;
	CurrentMap.BackColor=col_White;
	CurrentMap.Number=0;
	
	//init mario
	Mario.YCmp=0;
	Mario.x=50;
	Mario.y=50;
	Mario.Direction=RIGHT;
	Mario.Score=0;
	Mario.Invincible=0;
	Mario.Momentum=0;
	Mario.Swimming=0;
	Mario.Lives=3;
	
	//init the particles
	for(x=0;x<Max_Particles;x++)
	{
		Particle[x][p_Type]=-1;
		Particle[x][p_LastX]=-1;
	}
	
	for(x=0;x<Max_Enemies;x++)
	{
		Enemy[x][e_Type]=-1;
		Enemy[x][e_Ani]=-1;
	}
	
	//nuthings been completed yet
	LevelComplete=0;
	
	//init time
	Time=2033;
		
	//jump into the main loopage
	MainLoop();

	//kills the gs
	GGrayOff();
	
	//resets some stuff
	SetIntVec(AUTO_INT_1, save_1); 
	SetIntVec(AUTO_INT_5, save_5); 
}



//THE GAMES MAIN LOOP
void MainLoop()
{
	static short Scene=scn_Title;

	//grab a pointer to the scene var
	ScenePtr = &Scene;
	
	//loop until meant to exit
	while(ExitApp==false)
	{
		//loopage stuff
		//if no keys are being pressed, mario must be facing left or right (standing) (or jumping..)
		short MDir=Mario.Direction;
		if(Mario.IsJumping==false)
		{
			if(MDir==LEFT)
				Mario.Animation=mss_StandLeft;
			else
				Mario.Animation=mss_StandRight;
		}else
		{
			if(MDir==LEFT)
				Mario.Animation=mss_JumpLeft;
			else
				Mario.Animation=mss_JumpRight;
		}//end if

		//if time is <-10 then its actually the splash screen
		if(Time<-10)
			Scene=scn_Splash;
			
		if(Scene==scn_Game)
		{
			//if time is up
			if(Time<=0 && !LevelComplete)
			{
				//lock time at 0
				Time=0;
				
				//if mario isnt dead already, do the evil deed
				if(Mario.State!=m_Dead)
					KillMario();
			}
			
			//if the user presses ESCAPE, return them to the main menu
			if(_keytest(RR_ESC))
			{
				//wait for key_up
				while(_keytest(RR_ESC));
				
				//return to main menu
				*ScenePtr=scn_MainMenu;
			}
	
			//responds to key presses, unless the level is over, then just sit there
			if(!LevelComplete)
				keys_DoKeys();
			else
			{
				Do_LevelEnd();
			}
				
			//does physics
			phys_DoPhys();
			
			//tests for collision shit
			coll_DoCollision();		
		}else if (Scene==scn_Title)
		{
			//no time elapses on the title screen
			Time=10;
			
			//OLD COMMENT - if they press 2nd, then start game
			//if(_keytest(RR_2ND))
			//	DoSplash();
			
			//if they press 2nd, then take them to the main menu
			if(_keytest(RR_2ND))
			{
				//wait for the release, so it doesnt skip it
				while(_keytest(RR_2ND));
				
				Scene=scn_MainMenu;
			}
	
		}else if (Scene==scn_MainMenu)
		{
			//no time elapses on the main menu
			Time=10;
			
			//if they press 2nd, then start game
			//if(_keytest(RR_2ND))
			//	DoSplash();
		}else if (Scene==scn_Splash)
		{
			//if its over, move to game
			if(Time<-50)
			{
				Scene=scn_Game;
				RestartLevel();
			}	
		}else if (Scene==scn_GameOver)
		{
			//if its over goto title screen
			if(Time<-50)
				//the game over leaves you on the title screen
				Scene=scn_Title;
				
				Time--;
		}
		

		//draws the screen
		gfx_DrawScene(Scene);

		//removes a eigth second from the clock, if the level hasnt yet been comleted
		if(!LevelComplete)
			Time--;
	}//wend
}






//MAIN KEY HANDNLING SUB
void keys_DoKeys()
{
	static char SECONDDOWN=false;
	static char DIAMONDDOWN=false;
	static short HeldRight=0, HeldLeft=0;
	
	//disable input whilst mario is dead
	if(Mario.State==m_Dead)
		return;
		
	//if the user is holding shift, then allow them to scroll with udlr
	if(_keytest(RR_SHIFT))
	{
		if(_keytest(RR_DOWN))
			ScrollY--;
		if(_keytest(RR_UP))
			ScrollY++;
		if(_keytest(RR_RIGHT))
			ScrollX--;
		if(_keytest(RR_LEFT))
			ScrollX++;
			
		//make sure the scrolly doesnt let you see too far
		if(ScrollY>15) ScrollY=15;
		if(ScrollY<-15) ScrollY=-15;
		if(ScrollX>6) ScrollX=6;
		if(ScrollX<-6) ScrollX=-6;
		
		//exit sub to prevent other actions
		return;
	}else //if shift ISNT held, then make sure there is no scroll
	{
		ScrollX=0;
		ScrollY=0;
	}
	
	
	//if mario is on a vine
	if(Mario.OnVine)
	{
		//if they press up
		if(_keytest(RR_UP))
		{
			//move mario up
			Mario.y-=3;
		}//end if key_up
		
		//if they press down
		if(_keytest(RR_DOWN))
		{
			//move mario up
			Mario.y+=3;
		}//end if key_down
		
	
		//if key left
		if(_keytest(RR_LEFT))
		{
			//increment the time held
			HeldLeft++;
			
			//if mario is facing RIGHT, and held is over 10, make him face left
			if(Mario.Direction==LEFT && HeldLeft>10)
			{
				Mario.Direction=RIGHT;
				HeldLeft=0;
			}
					
			//if its over 10, then mario exit the vine
			if(HeldLeft>10)
			{
				Mario.x-=23;
				HeldLeft=0;
			}
					

		}else
			HeldLeft=0;
			
		
		//if key right
		if(_keytest(RR_RIGHT))
		{
			//increment the time held
			HeldRight++;
			
			//if mario is facing RIGHT, and held is over 10, make him face left
			if(Mario.Direction==RIGHT && HeldRight>10)
			{
				Mario.Direction=LEFT;
				HeldRight=0;
			}
					
			//if its over 10, then mario exist the vine
			if(HeldRight>10)
			{
				Mario.x+=10;
				HeldRight=0;
			}
				
		}else
			HeldRight=0;
			
		//give mario the proper animation
		//if small mario is climbing...
		if(_keytest(RR_UP) || _keytest(RR_DOWN))
		{
				if(Mario.State==m_Small)
					{
						if(Mario.Direction==LEFT)
							Mario.Animation=mss_ClimbLeft;
						else
							Mario.Animation=mss_ClimbRight;
					}else //else mario is big, fire, or dead
					{
						if(Mario.Direction==LEFT)
							Mario.Animation=msb_ClimbLeft;
						else
							Mario.Animation=msb_ClimbRight;
					}
			}else//else he is just grabbing
			{
					//if small mario is climbing...
					if(Mario.State==m_Small)
					{
						if(Mario.Direction==LEFT)
							Mario.Animation=mss_GrabLeft;
						else
							Mario.Animation=mss_GrabRight;
					}else //else mario is big, fire, or dead
					{
						if(Mario.Direction==LEFT)
							Mario.Animation=msb_GrabLeft;
						else
							Mario.Animation=msb_GrabRight;
					}
			}
		}//end if up or down

	//test for UDLR, if mario isnt on a vine
	if(!Mario.OnVine)
	{
			//if the user presses DOWN
			if(_keytest(RR_DOWN))
				{
					//if mario is big, make him crouch
					if(Mario.State==m_Big || Mario.State==m_Fire)
					{
						if(Mario.Direction==RIGHT)
							Mario.Animation=msb_CrouchRight;
						else
							Mario.Animation=msb_CrouchLeft;
					}
				}
				
			//if the user presses LEFT
			if(_keytest(RR_LEFT))
			{
				//If pressing down left... exit and freeze mario
				if(_keytest(RR_DOWN))
					{
						Mario.Direction=LEFT;
						Mario.Animation=mss_StandLeft;
						Mario.Momentum=0;
						return;
					}
				
				//if mario is in transition, freze him
				if(Mario.Transition)
					return;
					
				//move mario left..
				Mario.x-=3;
				
				//give mario left momentum
				Mario.Momentum--;
				if(_keytest(RR_DIAMOND)) Mario.Momentum--;
				if(Mario.Momentum<-16)
					Mario.Momentum=-16;
					
				//move mario based on his momentum
				if(Mario.Momentum>6)
				{
					Mario.x+=(short)Mario.Momentum/4;
					Mario.x+=2;
				}
					
					
				//if run is pressed, and mario isnt airborn, make go faster
				if(_keytest(RR_DIAMOND) && !Mario.Airborn)
					Mario.x-=3;
					
				//if jumping..
				if(Mario.IsJumping)
					if(Mario.JDir==RIGHT)
					{
						if(Mario.JDir2>0)
							Mario.x+=2;
						else
							Mario.x+=1;
					}
					
				Mario.Animation=mss_WalkLeft;
				//special case, if mario had been going right, show switch
				if(Mario.Direction==RIGHT || Mario.Momentum>8)
					Mario.Animation=mss_SwitchRight;
				//set the new \ same direction
				if(!Mario.IsJumping || Mario.Swimming) Mario.Direction=LEFT;
			}
			
			//if the user presses RIGHT
			if(_keytest(RR_RIGHT))
			{
				//If pressing down right... exit and freeze mario
				if(_keytest(RR_DOWN))
					{
						Mario.Direction=RIGHT;
						Mario.Animation=mss_StandRight;
						Mario.Momentum=0;
						return;
					}
					
				//if mario is in transition, freze him
				if(Mario.Transition)
					return;
					
				//move mario right..
				Mario.x+=3;
				
				//give mario right momentum
				Mario.Momentum++;
				if(_keytest(RR_DIAMOND)) Mario.Momentum++;
				if(Mario.Momentum>16)
					Mario.Momentum=16;
					
				//move mario based on his momentum
				if(Mario.Momentum<-6)
				{
					Mario.x+=(short)Mario.Momentum/4;
					Mario.x-=2;
				}
					
				//if run is pressed and mario isnt airborn.., make go faster
				if(_keytest(RR_DIAMOND) && !Mario.Airborn)
					Mario.x+=3;
					
				//if jumping..
				if(Mario.IsJumping)
					if(Mario.JDir==LEFT)
					{
						if(Mario.JDir2<0)
							Mario.x-=2;
						else
							Mario.x-=1;
					}
					
				Mario.Animation=mss_WalkRight;
				//special case, if mario had ben going left, show switch
				if(Mario.Direction==LEFT || Mario.Momentum<-8)
					Mario.Animation=mss_SwitchLeft;
				//set the new \ same direction
				if(!Mario.IsJumping || Mario.Swimming) Mario.Direction=RIGHT;
			}
			
			//If the user doesnt press left or right, but mario has momentum
			if(!(_keytest(RR_LEFT)) && !(_keytest(RR_RIGHT)) && Mario.Momentum!=0)
			{
				short Momentum=Mario.Momentum;
				
				//move mario
				Mario.x+=(short)Momentum/4;
				
				//lower momentum
				if(Momentum<0)
				{
					Mario.Momentum++;
					if(Momentum<-8 && !_keytest(RR_DOWN)) Mario.Animation=mss_WalkLeft;
				}
				else
				{
					Mario.Momentum--;
					if(Momentum>8 && !_keytest(RR_DOWN)) Mario.Animation=mss_WalkRight;
				}
					
			}
	}
	
	

		
	//if the user presses SECOND
	if(_keytest(RR_2ND) && SECONDDOWN==false)
	{
		//if mario isnt already jumping, make him jump
		if((Mario.IsJumping==false && Mario.YCmp==0) || Mario.Swimming)
			{
				if(_keytest(RR_LEFT) && !Mario.Swimming)
					phys_MarioJump(-2);
				else if(_keytest(RR_RIGHT) && !Mario.Swimming)
				  phys_MarioJump(2);
				else
					phys_MarioJump(0);
			}
	}
	
	//if the user presses SECOND
	if(_keytest(RR_2ND))
		SECONDDOWN=true;
	else
		SECONDDOWN=false;
		
	
	//if the user presses DIAMOND
	if(_keytest(RR_DIAMOND) && DIAMONDDOWN==false)
	{
		//if fire mario, shoot a fire ball
		if(Mario.State==m_Fire)
		{
			//dont shoot a fire ball, if both are in use
			if(Particle[8][p_Type]!=-1 && Particle[9][p_Type]!=-1)
				return;
				
			//shoot a fire ball
			phys_ShootBall();
			
			//change mario to the throwing position
			if(Mario.Direction==RIGHT)
				Mario.Animation=msb_ThrowRight;
			else
				Mario.Animation=msb_ThrowLeft;
		}
	}

	//if the user presses DIAMOND
	if(_keytest(RR_DIAMOND))
		DIAMONDDOWN=true;
	else
		DIAMONDDOWN=false;
		
	//debug / cheats crap
	if(CheatsOn)
	{
		if(_keytest(RR_PLUS))
		  Mario.State=m_Big;
		if(_keytest(RR_MINUS))
			Mario.State=m_Small;
		if(_keytest(RR_MULTIPLY))
			Mario.State=m_Fire;
		if(_keytest(RR_POWER))
			Mario.Invincible=220;
		if(_keytest(RR_PAREN_OPEN))
			CurrentMap.BackColor++;
		if(_keytest(RR_PAREN_CLOSE))
			CurrentMap.BackColor--;
		if(_keytest(RR_CLEAR))
			Mario.Swimming=!Mario.Swimming;
		if(_keytest(RR_BCKSPC))
			KillMario();
		if(_keytest(RR_4))
			DoSplash();
		if(_keytest(RR_0))
			Time=10;
		if(_keytest(RR_1))
			CurrentMap.Number--;
		if(_keytest(RR_2))
			CurrentMap.Number++;
		if(_keytest(RR_HOME))
		{
			Cheats.Invincible=!Cheats.Invincible;
			printf_xy(5,10,"Invunerability %d", Cheats.Invincible);
		}
	}
	
	if(_keytest(RR_F1) && _keytest(RR_F2) /*&& _keytest(RR_F3) && _keytest(RR_F4) && _keytest(RR_F5)*/)
	{
		//wait for at least one fkey release
		while(_keytest(RR_F1));
		
		//enable cheats
		CheatsOn=!CheatsOn;
		
		printf_xy(5,10,"Cheats: %d", CheatsOn);
	}
	
	//Toggle cheats on / off
	
	/*if(_keytest(RR_1))
		memcpy(Map,Level1,sizeof(Map));
	if(_keytest(RR_2))
		memcpy(Map,Level2,sizeof(Map));
	if(_keytest(RR_3))
		memcpy(Map,Level3,sizeof(Map));
	if(_keytest(RR_4))
		memcpy(Map,Level4,sizeof(Map));
	if(_keytest(RR_5))
		memcpy(Map,Level5,sizeof(Map));
	if(_keytest(RR_1) || _keytest(RR_2) || _keytest(RR_3) || _keytest(RR_4) || _keytest(RR_5))
	{
		Time=400*8;
		Mario.x=48;
		Mario.y=0;
	}*/
}



//UPDATES MARIOS SCORE BASED ON WHAT TYPE OF ENEMY IT WAS, AND HOW IT WAS KILLED
//{eGoomba, eKoopa, eAirKoopa, eBuzzy, eLakutu, eSpiny, eSpinyEgg, eHammer, eCheep, eAirCheep, eBullet, eSquid,
//ePlant, ePodobo, eShell, eFlameCW45, eFlameCW315, eFlameCW225, eFlameCW135, eFlameCCW45, eFlameCCW315, eFlameCCW225, eFlameCCW135, eCannon, eBuzzyShell}
void SCORE(short Type, short x, short y, short KillMethod)
{
	//a table for the scores you receive to killing an enemy of each different way
	//sc_Stomp, sc_Fire, sc_Knock, sc_Invince
	short ScoreTable[4][25]=
	{
		{100, 100, 400, 100, 800, -1, -1, 1000, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
		{100, 200, 200, -1, 200, 200, 200, 1000, 200, 200, -1, 200, 200, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
		{100, 100, -1, 100, -1, -1, -1, 1000, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
		{100, 200, 200, 200, 1000, 200, 100, 1000, 200, 200, 200, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
	};
	
	//spawn a score particle, exit if invalid score
	if(ScoreTable[KillMethod][Type]==-1)
		return;
		
	//update marios score
	Mario.Score+=ScoreTable[KillMethod][Type];

	//spawn a code
	SpawnScore(x, y-6, ScoreTable[KillMethod][Type]);
}

//SPAWNS A SCORE AT THE POS X,Y, FOR VALU SCORE. DOES NOT CHANGE MARIOS SCORE
void SpawnScore(short x, short y, short Score)
{
	short z, E=0; //looping varaible
	
	//find free particle
	for(z=0;z<Max_Particles;z++)
	{
		//if the particle is unused, then save it for the score
		if(Particle[z][p_Type]==-1)
			E=z;
	}//next x
	
	//set up the score
	Particle[E][p_X]=-(Mario.x-75)+ScrollX*16+x;
	Particle[E][p_Y]=y;
	Particle[E][p_Type]=p_Score;
	Particle[E][p_Dir]=Score;
	Particle[E][p_Life]=20;
}

//KILLS MARIO
void KillMario()
{
	//removes a life from mario
	Mario.Lives--;
	
	//powers down mario
	Mario.State=m_Small;
	
	//Shoot mario up for a sec
	Mario.YCmp=-13;
	
	//Make mario dead
	Mario.State=m_Dead;
}


//RESTARTS THE CURRENT LEVEL
void RestartLevel()
{
	short x; //looping variable

	//init mario
	Mario.YCmp=0;
	Mario.x=50;
	Mario.y=50;
	Mario.Direction=RIGHT;
	Mario.Invincible=0;
	Mario.Momentum=0;
	Mario.Swimming=0;
	
	//level is no longer over
	LevelComplete=0;
	
	//init the particles
	for(x=0;x<Max_Particles;x++)
	{
		Particle[x][p_Type]=-1;
		Particle[x][p_LastX]=-1;
	}
	
	for(x=0;x<Max_Enemies;x++)
	{
		Enemy[x][e_Type]=-1;
		Enemy[x][e_Ani]=-1;
	}
	
	//init time
	Time=3200;
}

//START THE SPLASH SCREEN
void DoSplash()
{
	char ToLoad[20];
	
	//splash starts at < -10
	Time=-11;
	
	//if the number of lives you have left is less than 1 then show game over
	if(Mario.Lives<1)
	{
		//set teh scene to game over
		*ScenePtr=scn_GameOver;
		
		//exit, nothing left to do here
		return;	
	}
	//make sure it doesnt go over bounds
	if(strcmp(MapQueue[CurrentMap.Number],"")==0)
		CurrentMap.Number=0;
		
	//build the map-to-load string
	strcpy(ToLoad,"MARIOMAP\\");
	strcat(ToLoad,MapQueue[CurrentMap.Number]);
	
	//reload / preload the level
	//load map

	FILE *f2 = fopen(ToLoad, "rb");
	
	//read the map
	fread(Map,sizeof(Map),1,f2);
  
	//fseek(f2,sizeof(Map),2);
	
	//read the warps
	fread(Warps,sizeof(Warps),1,f2);
	
	//fseek(f2,sizeof(Warps),2);
	
	//read the alloted time
	fread(&Time,sizeof(short),1,f2);
	
	//fseek(f2,sizeof(short),2);
	
	//read the map backcolor
	fread(&CurrentMap.BackColor,sizeof(short),1,f2);
	
	//fseek(f2,sizeof(short),2);
	
	//read the map type
	fread(&CurrentMap.Type, sizeof(short),1,f2);
	
	//close the map file...
	fclose(f2);
	
	
	
	//okay so if its a water map, then mario has to swim... otherwise mario walks
	if(CurrentMap.Type==1)
		Mario.Swimming=true;
	else
		Mario.Swimming=false;
		
	//nuthings been completed yet
	LevelComplete=0;

	//the scene is now the splash scene
	*ScenePtr = scn_Splash;
	
	//if mario is dead, switch him to small
	if(Mario.State==m_Dead)
		Mario.State=m_Small;
		
	//makre sure mario isnt jumping or anything
	Mario.IsJumping=false;
	Mario.Animation=mss_StandLeft;
}

//EXITS TEH GAME
void ExitGame()
{
	ExitApp=true;
}



//DOES ALL THE TECHNICALY JUNK FOR WHEN A LEVEL IS AT ITS END (FLAGPOLE, SCORE, FIREWORKS, ETC..)
void Do_LevelEnd()
{
	short x;
	static short FireWorks=-1;
	
	if(LevelComplete==1)
		Mario.YCmp=6;
		
	//complete level 2: mario runs to the door
	if(LevelComplete==2)
	{
		
		Mario.Direction=RIGHT;
		Mario.x+=3;		
		Mario.Animation=mss_WalkRight;
		
		//calculate the fireworks
		x=(short)(Time/8);
		while(x>100)
			x-=100;
		while(x>10)
			x-=10;
		
		switch(x)
		{
			case 1:
				FireWorks=0;
				break;
			case 3:
				FireWorks=200;
				break;
			case 6:
				FireWorks=500;
				break;
			default:
				FireWorks=-1;
		}
	}
	
	//complete level 3: score is totaled, and it scrolls up
	if(LevelComplete==3)
	{
		//add time bonus score
		if(Time>0)
			{
				Time-=8*3;
				Mario.Score+=30;
			}
		
		if(Time<0)
			Time=0;
			
		if(Mario.y>175)
		{
			Mario.y--;
		}
		
		//if time is 0 (score caclulated, and screen has scrolled) then show fireworks...
		if(Time==0 && Mario.y<176)
			LevelComplete=4;
	}
	
	//complete level 4: fireworks show, if any
	if(LevelComplete==4)
	{
		//if FireWorks%0 then add firework
		if(FireWorks%100==0)
		{
			//{p_X, p_Y, p_Type, p_YCmp, p_Dir, p_LastX, p_Life};
			//spawn a firework
			randomize();
			
			Particle[0][p_Type]=p_Explosion;
			Particle[0][p_Life]=0;
			Particle[0][p_X]=Mario.x + (random(3)-1)*32;
			Particle[0][p_Y]=120 - (random(2)-1)*16;

			Mario.Score+=100;
		}
		
		
		
		//decrement fireworks
		if(FireWorks>0)
			FireWorks-=5;
		else
		{
			LevelComplete=5;
			FireWorks=50;
		}
			
	}
	
	//complete level 5: wait around after fireworks, before the next map / what not
	if(LevelComplete==5)
	{
		if(FireWorks>0)
			FireWorks--;
		else
			LevelComplete=6;
		
		//printf_xy(10,20,"%d",FireWorks);
	}
	
	//complete level 6: take player to next level, or end of game screen
	if(LevelComplete==6)
	{
		//increment the map number
		CurrentMap.Number++;
		
		//just let "do splash" do it
		//kill level completeness
		//LevelComplete=0;
		
		//printf_xy(10,20,"66666666666");
		
		//restart, sicne fireworks and evertying is hella over
		DoSplash();
	}
}