/*
Copyright (c) 1998 Michael Haar, Ulrich Haar, Michael Thayer,
  Tobias Mueller, Tobias Lenz
All rights reserved.
Terroid Programming by Michael Haar, Michael Thayer, Ulrich Haar
Terroid Graphics by Ulrich Haar, Michael Haar
Terroid Music by Michael Thayer
Terroid Level design by Michael Haar, Ulrich Haar, Tobias Lenz
Terroid Beta testing by Tobias Mueller, Tobias Lenz

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice and credits, this unmodified list of conditions and the
   following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice and credits, this unmodified list of conditions and the
   following disclaimer in the documentation and/or other materials
   provided with the distribution.
3. Any credits displayed during programme execution must include the
   above or an equivalent credit list.
4. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.
5. The authors Michael Thayer and Michael Haar are to be informed,
   preferable by electronic mail, when this software is distributed
   commercially.  A single notification is required for any given
   distribution, and explicit copies of that distribution (e.g. for all
   resellers of a given Linux distribution).
6. If any modifications are made to the software, then a description of them
   must be included when the software is redistributed, or alternatively,
   the distributed binary or source code must be described as a product
   based on source code by Michael Haar, Michael Thayer and Ulrich Haar.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/****************************************/
/* Spiel (C) April 1996 by Michael Haar */
/* another DIGITAL Nightmares prod.     */
/****************************************/

#include <stdlib.h>
#include <string.h>

#include <dn.h>
#include "mjt_func.h"
#include "DEFS.H"
#include "FUNCS.H"
#include "VARS.H"

/************************************************************************************************************************/
/************************************************************************************************************************/
#define DEMOVERSION
//#define EDITOR
#define INTRO
/************************************************************************************************************************/
/************************************************************************************************************************/

/* globale Variablen */
BOOLEAN ende;
PLAYMODE game_mode;
int sounddevice;
int game_scrollgeschw;
ENDMONSTER endmonster;
BOOLEAN no_music;
int main_counter;
GAMEVIEW game_view;
int savepics = 0;
RGB whitepal[256];
char cheatmode[] =
{
	' ', ' ', ' ', ' ', ' ', ' ', '\0'
};
// H    E    L    P    M    E
// I    A    M    G    O    D
char gamepath[1024] = "";

FLI * fliptr;
BOOLEAN do_draw ;
int overall_time = 1, main_loop_count = 1 ;
int last_bomb ;
long t ;
BOOLEAN is_demo = TRUE ;

extern EXTRA extra[MAX_EXTRAS];

/* Funktionsprototypen */
void globale_tasten(void);
void paused_effect();
BOOLEAN play_fli(char *fname, BOOLEAN endlos, long wait_time);
void do_game_loop(void) ;
void do_redraw(void) ;

/* Funktionen */
void paused_effect()
{
	int x, y;

	for(y = 0; y < screen_height; y++)
		for(x = y % 2; x < screen_width; x += 2)
			*(char *)((long)screen_addr + x + y * screen_width) = 0;
}

void globale_tasten(void)
{
	char txt[80];
#ifdef EDITOR
	int i;
#endif

	if(keyTest(KEY_ESC))
		spieler.leben = -1;
	else if(keyTest(KEY_P))
	{
		while(keyTest(KEY_P))
			;
		paused_effect();
		objput(screen_width / 2 - pausedpix.w / 2, screen_height / 2 - pausedpix.h / 2, &pausedpix);
		Copy2Screen();
		while(!keyTest(KEY_P))
			;
		while(keyTest(KEY_P))
			;
		t = timer() ;
	}
	else if(keyTest(KEY_F8) && (sounddevice != 4))
	{
		if(no_music)
		{
			no_music = FALSE;

			stop_sound();
			free_mod();
			md_numchn = 4;
			sprintf(txt, "LEVEL%d.XM", (game_level % ANZ_MODS) + 1);
			mymod = ML_LoadFN(txt);
			md_numchn += mymod->numchn;
			start_mod(TRUE, 100, 0);
		}
		else
		{
			no_music = TRUE;
			stop_sound();
			free_mod();
			md_numchn = 4;
			MD_PlayStart();
		}
		while(keyTest(KEY_F8))
			;
	}
#ifdef EDITOR
	else if(keyTest(KEY_HOME))
	{
		game_level--;
		naechstes_level();
	}
	else if(keyTest(KEY_F10))
	{
		if(game_mode == PLAY)
		{
			game_mode = EDIT;
			init_editor();
		}
		else
		{
			game_mode = PLAY;
			for(i = 0; i < MAX_OBJEKTE; i++)
				objekt[i].nr = 0;
			level_over = 100;
			endmonster.energie_max = 0;
			endmonster.art_da = 0;
			endmonster.start_x = 0;
			for(i = 0; i < MAX_EXTRAS; i++)
				extra[i].komm_zaehler = 99;
		}
		while(keyTest(KEY_F10))
			;
	}
#endif

	if(game_mode == PLAY)
	{
		if(keyTest(KEY_RSHIFT))
		{
			sprintf(txt, "%sTERRDU%d.PCX", gamepath, savepics++);
			save_pic(txt, screen_addr, gamepal);
		}
	}

	if((game_mode == EDIT) || !strcmp(cheatmode, "HELPME") || !strcmp(cheatmode, "IAMGOD"))
	{
		if(keyTest(KEY_0))
		{
			spieler.leben++;
			while(keyTest(KEY_0))
				;
		}
		if(keyTest(KEY_1) && (spieler.waffe[1] < ANZ_LASERSTUFEN))
		{
			spieler.waffe[1]++;
			while(keyTest(KEY_1))
				;
		}
		if(keyTest(KEY_2) && (spieler.waffe[2] < 3))
		{
			spieler.waffe[2]++;
			while(keyTest(KEY_2))
				;
		}
		if(keyTest(KEY_3) && (spieler.waffe[3] < 3))
		{
			spieler.waffe[3]++;
			while(keyTest(KEY_3))
				;
		}
		if(keyTest(KEY_4) && (spieler.waffe[4] < MAX_PLAYERMINES))
		{
			spieler.waffe[4]++;
			while(keyTest(KEY_4))
				;
		}
		if(keyTest(KEY_5))
		{
			spieler.smartbomb = 16;
			while(keyTest(KEY_5))
				;
		}
		if(keyTest(KEY_6))
		{
			spieler.schild += 250 * SPEED_FAC;
			while(keyTest(KEY_6))
				;
		}
		if(keyTest(KEY_7))
		{
			level_over = 1;
			game_level -= 2;
			if(game_level < -1)
				game_level = -1;
			while(keyTest(KEY_7))
				;
		}
		else if(keyTest(KEY_8))
		{
			level_over = 1;
			while(keyTest(KEY_8))
				;
		}
		else if(keyTest(KEY_9))
		{
			spieler.punkte += 11111;
			while(keyTest(KEY_9))
				;
		}

#ifdef EDITOR
		if(game_mode == EDIT)
			editor_tasten();
#endif
	}
}

void palette_sets()
{
	// Schild ...
	if(spieler.schild < 0)
	{
		if(spieler.schild == -1)
			SetColors(gamepal, 0, 256);
		else
			SetColors(redpal[-spieler.schild - 2], 0, 256);
		spieler.schild++;       // getroffen
	}
	// Bombe ...
	if (spieler.smartbomb > last_bomb)
	  {
	    last_bomb = 16 ;
	  }
	if ((last_bomb == 16) && (spieler.smartbomb < 16))
	  {
	    memset(whitepal, 63, sizeof(RGB) * 256);
	    pal_setup_fade(gamepal, whitepal) ;
	  }
	if((spieler.smartbomb > 8) && (spieler.smartbomb < 16))
	  {
	    pal_do_fade(alt_rgb, 32 * (last_bomb - spieler.smartbomb)) ;
	    SetColors(alt_rgb, 0, 256);
	    last_bomb = spieler.smartbomb ;
	  }
	else if(last_bomb > 8)
	  {
	    SetColors(gamepal, 0, 256) ;
	    last_bomb = 8 ;
	  }
}

void dn_presents()
{
	RGB pal[256];
	int i, c;
	void *pix;

	cls(0);
	Copy2Screen();

	pix = malloc(64000);
	load_pic("DNLOGO.PIX", pix, alt_rgb);
	memcpy(pal, alt_rgb, sizeof(RGB) * 256);
	memset(&alt_rgb[128], 0, 32 * sizeof(RGB));
	memset(&alt_rgb[192], 0, 32 * sizeof(RGB));
	SetPalette(alt_rgb);
	if (sounddevice != 4) start_sample(donnersnd, md_numchn - 1);
	pixel_in(pix);
	free(pix);

	delay(250);

	for(i = 0; i < 64; i++)
	{
		for(c = 128; c < 128 + 32; c++)
		{
			if(alt_rgb[c].r < pal[c].r)
				alt_rgb[c].r++;
			if(alt_rgb[c].g < pal[c].g)
				alt_rgb[c].g++;
			if(alt_rgb[c].b < pal[c].b)
				alt_rgb[c].b++;
		}
		for(c = 192; c < 192 + 32; c++)
		{
			if(alt_rgb[c].r < pal[c].r)
				alt_rgb[c].r++;
			if(alt_rgb[c].g < pal[c].g)
				alt_rgb[c].g++;
			if(alt_rgb[c].b < pal[c].b)
				alt_rgb[c].b++;
		}

		SetPalette(alt_rgb);
		delay(50);
	}
}

#ifdef msdos
void do_configuration()
{
	char txt[80];

	// Soundkarte erstmal nur so:
	no_music = FALSE;
	sounddevice = 0;
	switch(config.soundcard.art)
	{
		case GUS:
			sounddevice = 2;
			sprintf(txt, "%d,%d,%d,%d,%d", config.soundcard.port, 0, config.soundcard.dma, config.soundcard.irq, 0);
			setenv("ULTRASND", txt, 1);
			break;
		case SB:
			sounddevice = 3;
			if(config.soundcard.mix > 5)
				sprintf(txt, "A%d I%d D%d H%d T%d", config.soundcard.port, config.soundcard.irq, config.soundcard.dma, config.soundcard.hidma, config.soundcard.mix);
			else
				sprintf(txt, "A%d I%d D%d T%d", config.soundcard.port, config.soundcard.irq, config.soundcard.dma, config.soundcard.mix);
			setenv("BLASTER", txt, 1);
			break;
		case SS:
			sounddevice = 1;
			break;
		case NONE:
			sounddevice = 4;
			no_music = TRUE;
			break;
	}

	// Controller
	if(config.control == KEYBOARD)
		joystick = FALSE;
	else if(config.control == JOYSTICK)
		joystick = TRUE;
}
#endif

BOOLEAN play_fli(char * fname, BOOLEAN endlos, long wait_time)
{
	long t, speed;
	BOOLEAN ende;
//	int i;

  fliptr = load_fli(fname, FLI_DISK);

	if(fliptr == NULL)
		return(FALSE);

	t = timer();
	ende = FALSE;
	while(!ende)
	{
		if(keyTest(KEY_ESC) || keyTest(KEY_SPACE) || keyTest(KEY_ENTER) || keyTest(KEY_RCTRL) || keyTest(KEY_LCTRL) || joy1_b1())
			ende = TRUE;
		if(wait_time > 0)
			if(timer() - t >= wait_time)
				ende = TRUE;
		if(!endlos)
			if(fliptr->current >= fliptr->frames - 1)
				ende = TRUE;

		speed = timer();
		// play next frame of the fli/flc
		play_frame(fliptr, (char *) screen_addr, 320);

		while(timer() - speed < fliptr->speed * 2)
			;

		wait_retrace();
 		Copy2Screen();
	}

	// close the fli in case we were reading from disk, free all the memory
	close_fli(fliptr);

	return(TRUE);
}

#ifdef msdos
void find_gamepath(char *gamepath)
{
	FILE *datei;
	char txt[1024];

	strcpy(gamepath, "");

	// In Autoexec.bat nachsehen
	datei = fopen("C:\\AUTOEXEC.BAT", "rt");
	if(datei != NULL)
	{
		do
		{
			fgets(txt, 1024, datei);
			txt[1023] = 0;
		}
		while(!feof(datei) && strnicmp(txt, "SET TERROID=", 12));
		fclose(datei);

		// Es gibt sie, aber ist nicht aktiv!
		if(!strnicmp(txt, "SET TERROID=", 12))
			strcpy(gamepath, &txt[12]);
	}

	if(!strcmp(gamepath, ""))
	{
		if(getenv("TERROID") != NULL)
			strcpy(gamepath, getenv("TERROID"));
		else
			getcwd(gamepath, 1024);
	}

	if(strcmp(gamepath, ""))
		if(gamepath[strlen(gamepath) - 1] != '\\')
			strcat(gamepath, "\\");
}
#endif

/* Hauptprogramm */
// int main(int argc, const char *argv[])

int main(void)
{
	void *pix;
	FILE * test_file ;
//#ifdef DEMOVERSION
	GFXBLK demopix;
//#endif

#ifdef msdos
	// Konfiguration
	find_gamepath(gamepath);
	init_config(gamepath);
	do_configuration();
#else
	set_caption("Terroid") ;
	test_file = open_file("dnlogo.pix") ;
	if (! test_file)
	  {
	    chdir("/usr/lib/terroid") ;
	    test_file = open_file("dnlogo.pix") ;
	    if (! test_file)
	      {
		chdir("/usr/local/lib/terroid") ;
		test_file = open_file("dnlogo.pix") ;
		if (! test_file)
		  {
		    chdir("/usr/games/terroid") ;
		    test_file = open_file("dnlogo.pix") ;
		    if (! test_file)
		      {
			chdir("/usr/local/games/terroid") ;
			test_file = open_file("dnlogo.pix") ;
			if (! test_file)
			  {
			    printf("Sorry, I can't start the game - there are files missing.\n") ;
			    return(1) ;
			  }
		      }
		  }
	      }
	  }
	fclose (test_file) ;
#endif

	// Grafikmodus usw. Start
	test_file = open_file("hinter36.pix") ;
	if (test_file)
	  {
	    is_demo = FALSE ;
	    fclose(test_file) ;
	  }
	no_music = FALSE ;
	sounddevice = 0 ; /* 4 until I've sorted the sh*te out! */
	if(!init_game())
		return(-1);

	if(!no_music)
	{
		// Music on
		stop_sound();
		md_numchn = 4;
		if((mymod = ML_LoadFN("TERROID.XM")))
			md_numchn += mymod->numchn;
		start_mod(TRUE, 100, 0);
	}

	memset(whitepal, 63, sizeof(RGB) * 256);
#ifdef INTRO
	if(!play_fli("DNPRESEN.FLI", FALSE, 0))
	{
		dn_presents();
		PaletteFadeOut(alt_rgb);
		ClearPalette(alt_rgb);
		SetPalette(alt_rgb);
		cls(0);
		Copy2Screen();
	}
	else
	{
		if (sounddevice != 4) start_sample(donnersnd, md_numchn - 1);
		SetPalette(whitepal);
	}

//	if(!play_fli("TTITEL.FLI", FALSE, 0))
//	{
//#ifdef DEMOVERSION
		load_pic("DEMOVERS.PIX", screen_addr, alt_rgb);
//		demopix.mem = NULL;
		get(0, 0, 319, 199, &demopix);
//#endif
		// Titel einblenden
		load_pic("TITEL.PIX", screen_addr, alt_rgb);
		copy_frame_buffer();
		PaletteFadeIn(alt_rgb);
//#ifdef DEMOVERSION
            if (is_demo)
              {
		objput(0, 0, &demopix);
		Copy2Screen();
              }
//#endif
		press_key(1000);
		PaletteFadeOut(alt_rgb);
/*	}
	else
	{
		press_key(500);
		GetPalette(alt_rgb);
		PaletteFadeOut(alt_rgb);
	} */
#endif

	ClearPalette(alt_rgb);
	SetPalette(alt_rgb);
	cls(0);
	Copy2Screen();

	game_view = FULL;

	// Menuprogrammschleife
	do
	{
		// Falls Menüende mit ESC
		spieler.leben = 1;
		game_level = 0;
		/* Menü */
		if(!(ende = startmenu()))
		{
/*			if(game_mode == DEMO)
			{
				// Introgeschichte
				story();
			} */

			if(game_mode != DEMO)
			{
					schwierigkeit();
//#ifdef DEMOVERSION
				    if (is_demo)
				      {
				    do
				      {
					schwierigkeit() ;
					if(game_difficulty == TRAINING)
					{
						while(joy1_b1() || keyTest(KEY_ESC) || keyTest(KEY_SPACE) || keyTest(KEY_RCTRL) || keyTest(KEY_ESC) || keyTest(KEY_ENTER) || keyTest(KEY_RALT))
							;
						cls(0);
						Copy2Screen();
						pix = malloc(64000);
						load_pic("DEMO.PIX", pix, alt_rgb);
						SetPalette(alt_rgb);
						if (sounddevice != 4) start_sample(warningsnd, md_numchn - 1);
						pixel_in(pix);
						free(pix);
//						memcpy(screen_addr, (void *)0xA0000, 64000);
	// (unnoetig, aber naja ...) findest du auch?
						press_key(1000);
					}
				      }
				    while(game_difficulty == TRAINING);
			      }
//#endif
				stop_sound();

				if(game_difficulty != TRAINING)
				{
					PaletteFadeOut(alt_rgb);
					cls(0);
					Copy2Screen();
					orbit_story();
				}
				else
				{
					PaletteFadeOut(alt_rgb);
					cls(0);
					Copy2Screen();
					training_story();
				}
			}
			else
				game_difficulty = NORMAL;

			endmonster.energie_max = 0;
			start_game(game_level);
		}
		else
			spieler.leben = 1; // Kein gameoverpix!

		// Continueschleife
		do
		{
			// Hauptschleife
			main_counter = 0;
			t = timer();
			while(!ende && (spieler.leben >= 0))
			{
				if(timer() - t > 1)
				{
					t = timer();
	
					main_counter += (overall_time /
						main_loop_count) ;
	
					// Levelende
					if(level_over < 100)
					{
						SoundFading(-5);
	
						if(--level_over == 0)
						{
//	#ifdef DEMOVERSION
						    if (is_demo
						      && (game_level == 1))
								spieler.leben = -1;
							else
							{
//	#endif
								if(game_level == MAX_LEVEL)
								{
									ende = TRUE;
									stop_sound();
								}
								else
								{
									// Bonusspiel
									if((game_level == 2) || (game_level == 5))
									{
										SoundFading(5);
										bonusgame(game_level);
									}
									stop_sound();

									// Filme
									if(game_level == 2)
										wueste_story();
									else if(game_level == 5)
										city_story();

									naechstes_level();
								}
//	#ifdef DEMOVERSION
							}
//	#endif
						}
					}
					
					globale_tasten();
					
					if((game_mode == PLAY) || (game_mode == DEMO))
					  {
						do_game_loop() ;
					  }
					else if(game_mode == EDIT)
					{
						background();
						sterne();
						plattformen();
	
						show_starts();
						show_ketten();
						zeige_kette();
						editor_info();
						wait_retrace(); 
						Copy2Screen();
					}
	
					palette_sets();
	
				}
			}
		}
		while(buy_continue());

		// zum weissfaden
		memcpy(whitepal, gamepal, sizeof(RGB) * 256);

//#ifdef DEMOVERSION
	if (is_demo)
	  {
		// Demobild
		if((game_level == 1) && (level_over == 0) && !ende)
		{
			while(joy1_b1() || keyTest(KEY_ESC) || keyTest(KEY_SPACE) || keyTest(KEY_RCTRL) || keyTest(KEY_ESC) || keyTest(KEY_ENTER) || keyTest(KEY_RALT))
				;
			cls(0);
			Copy2Screen();
			if (sounddevice != 4) start_sample(warningsnd, md_numchn - 1);
			demo_story() ;
			free(pix);
//			memcpy(screen_addr, (void *)0xA0000, 64000);
	// (unnoetig, aber naja ...) => siehe oben

			// zum weissfaden <= ???
			memcpy(whitepal, alt_rgb, sizeof(RGB) * 256);
			spieler.leben = 1 ;
			stop_sound() ;
			hiscore() ;
		}
	  }
//#endif
        
		// Gameover
		if(spieler.leben < 0)
		{
			while(joy1_b1() || keyTest(KEY_ESC) || keyTest(KEY_SPACE) || keyTest(KEY_RCTRL) || keyTest(KEY_ESC) || keyTest(KEY_ENTER) || keyTest(KEY_RALT))
				;

			pix = malloc(screen_width * screen_height);
			load_pic("GAMEOVER.PIX", pix, alt_rgb);
			// Nach weiss ausfaden
			PaletteWhiteOut(whitepal);
			putvollbild(pix);
			Copy2Screen();
			// Und wieder einfaden
			PaletteWhiteIn(alt_rgb);
			free(pix);
			press_key(1000);

			SoundFading(-5);
			PaletteFadeOut(alt_rgb);
			// music off    
			stop_sound();
			spieler.leben = 1;	// Damit bei ESC kein Gameoverbild!

			hiscore();
		}
		else if(game_level == MAX_LEVEL)
		{
			ende_story();

			SoundFading(-5);
			PaletteFadeOut(alt_rgb);
			// music off    
			stop_sound();
			spieler.leben = 1;	// Damit bei ESC kein Gameoverbild!

			hiscore();

			ende = FALSE;
		}
	}
	while(!ende);

#ifdef INTRO
//#ifdef DEMOVERSION
	if (is_demo)
	  {
		cls(0);
		Copy2Screen();

		pix = malloc(64000);
		load_pic("SCREENSH.PIX", pix, alt_rgb);
		SetPalette(alt_rgb);
		if (sounddevice != 4) start_sample(warningsnd, md_numchn - 1);
		pixel_in(pix);
		free(pix);
		press_key(100000);
	  }
//#endif
	
		cls(0);
		Copy2Screen();
		ClearPalette(alt_rgb);
		SetPalette(alt_rgb);
//		play_fli("SPIEL.FLI", FALSE, 0);
		do_intro();
		GetPalette(alt_rgb);
//		extro();

		SoundFading(-5);
		PaletteFadeOut(alt_rgb);
#endif

	exit_game();

#ifdef INTRO
  puts("\nThank you for playing TERROID!\n");
//#ifdef DEMOVERSION
if (is_demo)	/* it isn't */
  {
    puts("TERROID for Linux is SHAREWARE. This means that you are encouraged, if you") ;
    puts("like the game, to purchase the FULL VERSION from us. The full version includes") ;
    puts("seven additional action-packed levels, with lots of extra graphics and sound,") ;
    puts("as well as a special training mode to help you hone your skills. Surprise") ;
    puts("me, and register! Let me see that Linux is a serious commercial platform ;-)\n") ;
    puts("Read the file \"REGISTER\" for more information.\n") ;
    puts("You are welcome to distribute copies of this demo!\n") ;
  }
else		/* lucky you, it's the full version! */
  {
    puts("If you like this game, you are very much encouraged to send a contribution");
    puts("(any amount) to me at the address below.  From the number of contributions");
    puts("I have received up until now (zero), I assume that everyone hates this game.");
    puts("Enjoy the further torture of playing it!");
  }
//#endif
  puts("Our homepage on the Internet: http://www.informatik.uni-oldenburg.de/~miha/\n");
/*		puts("email to: michael.haar@informatik.uni-oldenburg.de OR fam.haar@t-online.de");
		puts("or write to:\n   Michael Haar");
		puts("   Am Schuetzenholz 29");
		puts("   29643 Neuenkirchen");
		puts("   Germany");
*/
  puts("Converted to Linux by Michael Thayer") ;
  puts("Contact address:") ;
  puts("  Neckarhalde 8\n  72070 Tübingen\n  Germany") ;
  puts("Email (prefered to post): michael.thayer@student.uni-tuebingen.de\n") ;
#endif

	return(0);
}


/* Main loop inside game - move everything a little, handle timing, the jazz */

void do_game_loop(void)
{
	int i, j, t, c ;

	c = timer() - 1 ;
	j = overall_time / main_loop_count * 3 ;
	for (i = 1 ; i <= j ; i++) {
		if (i == j) {
			do_draw = TRUE ;
			t = timer() ;
		}
		do_keyboard(c + i) ;
		endmonster.energie_aktuell = 0;
		game_scrollpos += game_scrollgeschw;
		do_redraw() ;
		if (i == j) {
			overall_time += min((timer() - t), 1) ;
			main_loop_count++ ;
		}
	}
	do_draw = FALSE ;
}


/* Actually do the redrawing / moving */

void do_redraw(void)
{
	clip_y1 = 12 ;
	background();
	sterne();
	plattformen();
	if(endmonster.art_da != 50)
	neue_objekte();
	objekte();
	extras();
	explosionen();
	spieleraction();
	wolken();
	clip_y1 = 0 ;
	infobalken();
	if(game_difficulty == TRAINING)
	show_attack();
	if (do_draw) {
		wait_retrace(); 
		Copy2Screen();
	}
}
