/***************************************************************************
Kompletan source igre Corny. Sva grafika je podrzana s XLIB 5.0 cije ime
mora biti u .prj fileu. Grafika za igru su RLE kompresirane slike i
seditor kompatibilni spriteovi.
Zadnja promjena 15.12.1994.
***************************************************************************/
#include <string.h>
#include <mem.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <alloc.h>
#include "xlib.h"
#include "xline.h"
#include "xtext.h"
#include "xpbitmap.h"
#include "xcbitmap.h"
#include "xfileio.h"
#include "xrletool.h"
#include "xrect.h"
#include "xpal.h"
#define NrLevels 12
typedef struct
{
int x, y, xoth, yoth, newx, newy;
BYTE duz, vis;
char far *sbmp;
BYTE far *back;
BYTE far *both;
BYTE visible;
} sprite;
typedef struct
{
char name [ 20 ];
long hisc;
int l;
} filedscore;
void interrupt (*old09) ( void );
void interrupt (*oldtimer ) ( void );
char *lvlbkgs [ NrLevels ] = { "lvl1.bkg", "lvl2.bkg", "lvl3.bkg", "lvl4.bkg",
"lvl5.bkg", "lvl6.bkg", "lvl7.bkg", "lvl8.bkg",
"lvl9.bkg", "lvl10.bkg", "lvl11.bkg", "lvl12.bkg" };
char *lvlnames [ NrLevels ] = { "By the sea", "On the beach", "Last glance at the sea",
"On the road again ...", "Waiting for the bus",
"At the airport", "St. Mark's Church",
"The Lotrscak Tower", "Banski Dvori", "Finally home",
"Lights of Zagreb", "Just pick 'em" };
char credits [ 145 ] = "Programming: Tin Blaskovic Graphics: Jasna & Tin Blaskovic Special thanks: Davor Krivdic, Themie Gouthas Long live me! Seeya.";
sprite sprites [ 10 ];
filedscore hiscores [ 10 ];
char far *sbmps [ 15 ];
int levelsprites [ 8 ] = { 9, 8, 10, 11, 12, 13, 5, 14 };
BYTE as [ 7 ] = { 10, 11, 12, 13, 14, 15, 16 };
BYTE jaws [ 7 ] = { 0, 0, 0, 0, 0, 0, 0 };
BYTE uzorak [ 16 ] = { 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35 };
char far *varswisl;
BYTE far *background, far *titlescr;
BYTE far *pal1, far *pal2, far *pal3;
int cornyx = 95, cornyy = 170;
int birdiex1 = 5, birdiey1 = 20;
int birdiespt1 = 3;
int birdiedir1 = 0;
int birdiecount1 = 0;
int vdir1 = 1;
int birdiex2 = 100, birdiey2 = 1;
int birdiespt2 = 3;
int birdiedir2 = 3;
int birdiecount2 = 0;
int vdir2 = 0;
int *inprogress = NULL, *request = NULL;
int soundidx, pauseidx;
int pausecount, soundsplayed, nrsounds;
int catch [ 5 ] = { 1, 0, 100, 1, 110 };
int fall [ 5 ] = { 1, 0, 50, 1, 25 };
int endlevel [ 29 ] = { 13, 1, 52, 1, 59, 1, 66, 1, 52, 1, 52, 1, 59, 1, 66, 1, 52,
1, 66, 1, 70, 2, 78, 1, 66, 1, 70, 2, 78 };
int lostlife [ 15 ] = { 6, 1, 39, 0, 44, 1, 39, 1, 35, 1, 33, 1, 35, 1, 39 };
BYTE gameend;
int delaytime;
int lives = 3;
long score = 0;
int scoredec = 0;
int consec = 0;
int levelparcels = 0;
int levelnorm;
int level = 1;
int lvlprob = 250;
int active;
int levelactive;
int smjer, sz;
int palettesteps;
int levelgoody, levelbady;
BYTE intensity;
int far *keybuffb, far *keybuffe;
BYTE ESC = 0, RIGHT = 0, LEFT = 0, ENTER = 0, xsz, ysz;
void Fade_Out_Palette ( void )
{
palettesteps = 0;
intensity = 255;
while ( x_cpcontrast_pal_struc ( pal1, pal2, intensity -- ) )
{
x_put_pal_struc ( pal2 );
palettesteps ++ ;
}
}
void Fade_In_Palette ( void )
{
int j;
for ( j = 0 ; j < palettesteps ; j ++ )
{
x_cpcontrast_pal_struc ( pal1, pal2, intensity ++ );
x_put_pal_struc ( pal2 );
}
}
void Terminate ( int exitcode )
{
if ( exitcode == 1 )
{
x_text_mode ( );
printf ( "File I/O error.\n" );
exit ( 1 );
}
else
{
x_text_mode ( );
printf ( "Insufficient memory.\n" );
exit ( 2 );
}
}
int collided ( int s )
{
if ( abs ( sprites [ s ].x - cornyx ) < 8 && sprites [ s ].y > 155 &&
sprites [ s ].y < 195 )
return 1;
return 0;
}
void initsprites ( void )
{
int i;
for ( i = 0 ; i < 10 ; i ++ )
sprites [ i ].visible = 0;
}
void closesprites ( void )
{
int i;
for ( i = 0 ; i < 10 ; i ++ )
if ( sprites [ i ].visible )
{
farfree ( sprites [ i ].back );
farfree ( sprites [ i ].both );
}
}
void assignsprite ( int spriteid, char far *bitmap )
{
sprites [ spriteid ].sbmp = bitmap + 2;
sprites [ spriteid ].duz = *bitmap;
sprites [ spriteid ].vis = *(bitmap + 1);
}
int movesprites ( void )
{
int i;
BYTE far *helpptr;
for ( i = 9 ; i >= 0 ; i -- )
if ( sprites [ i ].visible )
{
x_put_pbm ( sprites [ i ].xoth, sprites [ i ].yoth, HiddenPageOffs,
sprites [ i ].both );
sprites [ i ].xoth = sprites [ i ].x;
sprites [ i ].yoth = sprites [ i ].y;
sprites [ i ].x = sprites [ i ].newx;
sprites [ i ].y = sprites [ i ].newy;
helpptr = sprites [ i ].back;
sprites [ i ].back = sprites [ i ].both;
sprites [ i ].both = helpptr;
}
for ( i = 0 ; i < 10 ; i ++ )
if ( sprites [ i ].visible )
{
x_get_pbm ( sprites [ i ].x, sprites [ i ].y, sprites [ i ].duz / 4,
sprites [ i ].vis, HiddenPageOffs, sprites [ i ].back );
x_put_cbitmap ( sprites [ i ].x, sprites [ i ].y,
HiddenPageOffs, sprites [ i ].sbmp );
}
x_page_flip ( 0, 0 );
delay ( delaytime );
return 1;
}
int putsprite ( int spriteid, int x, int y )
{
int duz, vis, ssize;
duz = sprites [ spriteid ].duz;
vis = sprites [ spriteid ].vis;
if ( sprites [ spriteid ].visible )
return 0;
sprites [ spriteid ].x = sprites [ spriteid ].xoth = x;
sprites [ spriteid ].y = sprites [ spriteid ].yoth = y;
sprites [ spriteid ].newx = x;
sprites [ spriteid ].newy = y;
ssize = duz * vis + 2;
sprites [ spriteid ].back = (BYTE far *) farmalloc ( ssize );
sprites [ spriteid ].both = (BYTE far *) farmalloc ( ssize );
if ( sprites [ spriteid ].back == NULL || sprites [ spriteid ].both == NULL )
Terminate ( 2 );
x_get_pbm ( x, y, duz / 4, vis, VisiblePageOffs, sprites [ spriteid ].back );
x_get_pbm ( x, y, duz / 4, vis, HiddenPageOffs, sprites [ spriteid ].both );
x_put_cbitmap ( x, y, VisiblePageOffs, sprites [ spriteid ].sbmp );
x_put_cbitmap ( x, y, HiddenPageOffs, sprites [ spriteid ].sbmp );
sprites [ spriteid ].visible = 1;
return 1;
}
void interrupt Timer ( void )
{
if ( request != NULL )
{
inprogress = request;
request = NULL;
soundidx = 2;
pauseidx = 1;
nrsounds = *inprogress;
pausecount = 0;
soundsplayed = 0;
sound ( *(inprogress + soundidx) * 10 );
goto procend;
}
if ( inprogress != NULL )
{
pausecount ++ ;
if ( pausecount > *(inprogress + pauseidx) )
{
soundsplayed ++ ;
if ( soundsplayed > nrsounds )
{
inprogress = NULL;
nosound ( );
goto procend;
}
soundidx += 2;
pauseidx += 2;
pausecount = 0;
sound ( *(inprogress + soundidx) * 10 );
}
}
procend:
oldtimer ( );
}
void interrupt Keyboard_Handler ( void )
{
int keypressed;
BYTE b1, b2;
b1 = inportb ( 0x61 );
b2 = b1;
b1 |= 0x80;
outportb ( 0x61, b1 );
b1 = b2;
outportb ( 0x61, b1 );
outportb ( 0x20, 0x20 );
keypressed = inp ( 0x60 );
switch ( keypressed )
{
case 28: ENTER = 1;
break;
case 156:ENTER = 0;
break;
case 1: ESC = 1;
break;
case 129:ESC = 0;
break;
case 77: RIGHT = 1;
break;
case 205:RIGHT = 0;
break;
case 75: LEFT = 1;
break;
case 203:LEFT = 0;
break;
case 225:outp ( 0x60, 15 );
break;
}
}
void New_Level ( void )
{
int f, i;
score -= scoredec;
scoredec = 0;
x_bgprintf ( 210, 20, VisiblePageOffs, 10, 4, " %ld ", score );
x_bgprintf ( 210, 20, HiddenPageOffs, 10, 4, " %ld ", score );
request = endlevel;
while ( inprogress != NULL )
;
if ( level + 1 <= NrLevels )
{
Fade_Out_Palette ( );
level ++ ;
for ( i = 0 ; i < 10 ; i ++ )
sprites [ i ].newy = 205;
movesprites ( );
movesprites ( );
f = f_open ( lvlbkgs [ level - 1 ], F_RDONLY );
if ( f == FILE_ERR )
Terminate ( 1 );
x_file_RLDecode ( f, background );
f_close ( f );
x_put_pbm ( 0, 0, VisiblePageOffs, background );
x_put_pbm ( 0, 0, HiddenPageOffs, background );
x_get_pbm ( 0, 70, 80, 60, VisiblePageOffs, background );
x_rect_pattern ( 0, 70, 319, 129, VisiblePageOffs, MK_FP ( _DS, uzorak ) );
x_bgprintf ( 140, 75, VisiblePageOffs, 1, 10, "Level %d", level );
x_bgprintf ( 110, 95, VisiblePageOffs, 1, 10, lvlnames [ level - 1 ] );
x_bgprintf ( 120, 115, VisiblePageOffs, 4, 12, "Hit <Enter> ..." );
Fade_In_Palette ( );
while ( !ENTER )
{
x_rot_pal_struc ( pal3, 1 );
x_put_pal_struc ( pal3 );
delay ( 50 );
}
x_put_pbm ( 0, 70, VisiblePageOffs, background );
cornyx = 95; cornyy = 170;
birdiex1 = 5; birdiey1 = 20;
birdiespt1 = 3;
birdiedir1 = 0;
birdiecount1 = 0;
vdir1 = 1;
birdiex2 = 100; birdiey2 = 1;
birdiespt2 = 3;
birdiedir2 = 3;
birdiecount2 = 0;
vdir2 = 0;
if ( (level - 1) % 3 == 0 )
{
levelnorm = 50 + ((level - 1) / 3) * 10;
lvlprob = 250;
levelactive ++ ;
levelgoody += 2;
levelbady += 2;
}
else
{
if ( level != 12 )
{
lvlprob += 250;
levelnorm -= 10;
}
else
{
lvlprob = 0;
levelnorm = 100;
}
}
as [ 0 ] = 10; as [ 1 ] = 11; as [ 2 ] = 12;
as [ 3 ] = 13; as [ 4 ] = 14; as [ 5 ] = 15;
as [ 6 ] = 16;
jaws [ 0 ] = jaws [ 1 ] = jaws [ 2 ] = jaws [ 3 ] = 0;
jaws [ 4 ] = jaws [ 5 ] = jaws [ 6 ] = 0;
sprites [ 9 ].newy = cornyy;
sprites [ 9 ].newx = cornyx;
sprites [ 8 ].newy = birdiey2;
sprites [ 8 ].newx = birdiex2;
sprites [ 7 ].newy = birdiey1;
sprites [ 7 ].newx = birdiex1;
assignsprite ( 0, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 1, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 2, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 3, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 4, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 5, sbmps [ levelsprites [ levelgoody ] ] );
assignsprite ( 6, sbmps [ levelsprites [ levelgoody ] ] );
movesprites ( );
consec = 0;
x_bgprintf ( 210, 80, VisiblePageOffs, 10, 4, " %d ", level );
x_bgprintf ( 210, 80, HiddenPageOffs, 10, 4, " %d ", level );
x_bgprintf ( 210, 110, VisiblePageOffs, 10, 4, " %d ", levelnorm );
x_bgprintf ( 210, 110, HiddenPageOffs, 10, 4, " %d ", levelnorm );
levelparcels = 0;
}
else
gameend = 1;
}
void Packets ( void )
{
int i;
static int lastbird = 1;
BYTE new = 0;
active = 0;
for ( i = 0 ; i < 7 ; i ++ )
{
if ( as [ i ] < 10 )
{
if ( collided ( as [ i ] ) )
{
if ( !jaws [ i ] )
{
request = catch;
consec = 0;
levelparcels ++ ;
sprites [ as [ i ] ].newy = 205;
as [ i ] += 10;
score += 100;
new = 1;
if ( levelparcels == levelnorm )
New_Level ( );
}
else
{
request = lostlife;
lives -- ;
sprites [ as [ i ] ].newy = 205;
assignsprite ( as [ i ], sbmps [ levelsprites [ levelgoody ] ] );
jaws [ i ] = 0;
as [ i ] += 10;
new = 1;
}
}
else
if ( sprites [ as [ i ] ].y > 200 )
if ( !jaws [ i ] )
{
request = fall;
consec ++ ;
sprites [ as [ i ] ].newy = 205;
as [ i ] += 10;
scoredec += 200;
}
else
{
sprites [ as [ i ] ].newy = 205;
jaws [ i ] = 0;
assignsprite ( as [ i ], sbmps [ levelsprites [ levelgoody ] ] );
as [ i ] += 10;
}
}
}
if ( consec >= 2 )
{
request = lostlife;
lives -- ;
new = 1;
consec = 0;
}
for ( i = 0 ; i < 7 ; i ++ )
if ( as[ i ] < 10 )
{
sprites [ as [ i ] ].newy = 1 + sprites [ as [ i ] ].y;
active ++ ;
}
i = 0;
if ( active < levelactive )
{
while ( as [ i ] < 10 )
i ++ ;
as [ i ] -= 10;
if ( random ( 1000 ) < lvlprob )
{
jaws [ i ] = 1;
assignsprite ( as [ i ], sbmps [ levelsprites [ levelbady ] ] );
}
if ( lastbird == 2 )
{
sprites [ as [ i ] ].newx = birdiex1;
sprites [ as [ i ] ].newy = birdiey1 + 18;
lastbird = 1;
}
else
{
sprites [ as [ i ] ].newx = birdiex2;
sprites [ as [ i ] ].newy = birdiey2 + 18;
lastbird = 2;
}
}
if ( new )
{
x_bgprintf ( 210, 20, VisiblePageOffs, 10, 4, " %ld ", score );
x_bgprintf ( 210, 20, HiddenPageOffs, 10, 4, " %ld ", score );
x_bgprintf ( 210, 110, VisiblePageOffs, 10, 4, " %d ", levelnorm - levelparcels );
x_bgprintf ( 210, 110, HiddenPageOffs, 10, 4, " %d ", levelnorm - levelparcels );
x_bgprintf ( 210, 50, VisiblePageOffs, 10, 4, "%d", lives );
x_bgprintf ( 210, 50, HiddenPageOffs, 10, 4, "%d", lives );
}
}
void Move_Birdie1 ( void )
{
assignsprite ( 8, sbmps [ birdiespt1 + birdiedir1 ] );
if ( birdiedir1 )
if ( (birdiex1 > 5) && (random ( 1000 ) > 10) )
birdiex1 -- ;
else
birdiedir1 = 0;
else
if ( (birdiex1 < 180) && (random ( 1000 ) > 10) )
birdiex1 ++ ;
else
birdiedir1 = 3;
if ( vdir1 )
if ( birdiey1 > 2 )
birdiey1 -= random ( 3 );
else
vdir1 = 0;
else
if ( birdiey1 < 30 )
birdiey1 += random ( 3 );
else
vdir1 = 1;
sprites [ 8 ].newx = birdiex1;
sprites [ 8 ].newy = birdiey1;
birdiecount1 ++ ;
if ( birdiecount1 == 5 )
{
birdiespt1 ++ ;
birdiecount1 = 0;
}
if ( birdiespt1 > 4 )
birdiespt1 = 3;
}
void Move_Birdie2 ( void )
{
assignsprite ( 7, sbmps [ birdiespt2 + birdiedir2 ] );
if ( birdiedir2 )
if ( birdiex2 > 5 )
birdiex2 -- ;
else
birdiedir2 = 0;
else
if ( birdiex2 < 180 )
birdiex2 ++ ;
else
birdiedir2 = 3;
if ( vdir2 )
if ( birdiey2 > 2 )
birdiey2 -= random ( 3 );
else
vdir2 = 0;
else
if ( birdiey2 < 30 )
birdiey2 += random ( 3 );
else
vdir2 = 1;
sprites [ 7 ].newx = birdiex2;
sprites [ 7 ].newy = birdiey2;
birdiecount2 ++ ;
if ( birdiecount2 == 5 )
{
birdiespt2 ++ ;
birdiecount2 = 0;
}
if ( birdiespt2 > 4 )
birdiespt2 = 3;
}
void Step_Corny_Right ( void )
{
Move_Birdie1 ( );
Move_Birdie2 ( );
Packets ( );
assignsprite ( 9, sbmps [ 2 ] );
if ( cornyx < 188 )
{
cornyx += 2;
sprites [ 9 ].newx = cornyx;
}
movesprites ( );
Move_Birdie1 ( );
Move_Birdie2 ( );
Packets ( );
assignsprite ( 9, sbmps [ 0 ] );
if ( cornyx < 190 )
{
cornyx += 2;
sprites [ 9 ].newx = cornyx;
}
movesprites ( );
}
void Step_Corny_Left ( void )
{
Move_Birdie1 ( );
Move_Birdie2 ( );
Packets ( );
assignsprite ( 9, sbmps [ 1 ] );
if ( cornyx > 10 )
{
cornyx -= 2;
sprites [ 9 ].newx = cornyx;
}
movesprites ( );
Move_Birdie1 ( );
Move_Birdie2 ( );
Packets ( );
assignsprite ( 9, sbmps [ 0 ] );
if ( cornyx > 10 )
{
cornyx -= 2;
sprites [ 9 ].newx = cornyx;
}
movesprites ( );
}
void Game_Over ( void )
{