;/*
if not exists ZangiefData.o
	sc DATA=FAR ZangiefData.c
endif
sc RESOPT IGNORE=73 DATA=NEAR NMINC UCHAR CONSTLIB STREQ STRMERGE NOSTKCHK NOSTDIO OPTIMIZE OPTSIZE Zangief.c
slink from LIB:c.o Zangief.o ZangiefData.o to ///Clients/Zangief LIB LIB:sc.lib LIB:amiga.lib //lib/client.lib SC SD NOICONS STRIPDEBUG
quit

 Zangief 1.1  (Client for BServer)

 Copyright © 1995 by Stefano Reksten of 3AM - The Three Amigos!!!
 All rights reserved.
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>

#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/icon.h>
#include <clib/alib_protos.h>

#include <stdio.h>

#include "//include/client.h"
#include "//include/bitmap/bitmap.h"
#include "//include/bitmap/bitmap_pragmas.h"

extern ULONG zangief_cmap32[16][3];

#define IMGW 0x79
#define IMGH 0x8D

#define BITPLSIZE ((((IMGW+15)>>4)<<1)*IMGH)

extern UWORD walk1_imgdata[], walk2_imgdata[], walk3_imgdata[], walk4_imgdata[],
             stand1_imgdata[], stand2_imgdata[], stand3_imgdata[],
             hit_imgdata[], kick_imgdata[], punch1_imgdata[], punch2_imgdata[],
             punch3_imgdata[], win_imgdata[], win2_imgdata[], win3_imgdata[],
             walk1_mask[], walk2_mask[], walk3_mask[], walk4_mask[],
             stand1_mask[], stand2_mask[], stand3_mask[],
             hit_mask[], kick_mask[], punch1_mask[], punch2_mask[],
             punch3_mask[], win_mask[], win2_mask[], win3_mask[];

extern UWORD brk1_imgdata[], brk2_imgdata[],
             brk3_imgdata[], brk4_imgdata[],
             brk5_imgdata[], brk6_imgdata[],
             brk7_imgdata[], brk8_imgdata[];

char *ver = "$VER: Zangief 1.1 "__AMIGADATE__;

struct { UWORD *frame, *mask; } FrameAndMask[] = {
	{ walk1_imgdata, walk1_mask }, { walk2_imgdata, walk2_mask },
	{ walk3_imgdata, walk3_mask }, { walk4_imgdata, walk4_mask },
	{ stand1_imgdata, stand1_mask }, { stand2_imgdata, stand2_mask },
	{ stand3_imgdata, stand3_mask }, { hit_imgdata, hit_mask },
	{ kick_imgdata, kick_mask }, { punch1_imgdata, punch1_mask },
	{ punch2_imgdata, punch2_mask }, { punch3_imgdata, punch3_mask },
	{ win3_imgdata, win3_mask }, { win_imgdata, win_mask },
	{ win2_imgdata, win2_mask } };

UWORD *Breaks[] = {
	brk1_imgdata, brk2_imgdata,	brk3_imgdata, brk4_imgdata,
	brk5_imgdata, brk6_imgdata,	brk7_imgdata, brk8_imgdata };

UBYTE WhichFrame[] = {
0, 1, 2, 3, 4, 5, 6, 5, 7, 8, 7, 9, 10, 11, 10, 9, 7, 13, 12, 14, 13, 14 };

UWORD OriginalFrameXOffset[] = {
31, 30, 32, 39, 20, 27, 32, 38, 11, 24, 0, 10, 29, 32, 36 };

UWORD OriginalFrameYOffset[] = {
40, 40, 40, 40, 40, 41, 43, 38, 35, 42, 44, 49, 34, 35, 1 };

UWORD OriginalFrameWidth[] = {
65, 72, 64, 75, 78, 71, 66, 59, 106, 73, 94, 80, 71, 71, 64 };

#define WALK1  0
#define WALK2  1
#define WALK3  2
#define WALK4  3
#define STAND1 4
#define STAND2 5
#define STAND3 6
#define STAND4 7
#define HIT    8
#define KICK   9
#define KICK2  10
#define PUNCH1 11
#define PUNCH2 12
#define PUNCH3 13
#define PUNCH4 14
#define PUNCH5 15
#define PUNCH6 16
#define WIN    17
#define WIN2   18
#define WIN3   19
#define WIN4   20
#define WIN5   21

UBYTE *mem_ptr;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *BitMapBase, *IconBase;
struct DisplayIDInformation *dinfo;
BOOL blanking = TRUE;

extern ULONG RangeSeed;
struct Screen *scr;
struct BitMap *zangiefsbm, *storebm, *shadowbm, *scalebm, *breakbm, *scalebreakbm;
WORD x, y, dirx, diry,
     blitx, blity, sizex, sizey, xoffs, yoffs;
UBYTE scaleX = 0, scaleY = 0;
struct BitMapScaleInfo bsi;
UBYTE depth, frame;
struct RastPort *rp;
PLANEPTR mask;


void MoveZangief( void )
{
x += dirx * 1<<scaleX;
if ( x < -((IMGW<<scaleX)>>1) )
	{
	x = -((IMGW<<scaleX)>>1);
	dirx = 4;
	bsi.bsi_Flags = BSIF_INVERTHOR;
	}
if ( x >= scr->Width - 1 - (IMGW>>1) )
	{
	x = scr->Width - 1 - (IMGW>>1);
	dirx = - 4;
	bsi.bsi_Flags = 0L;
	}

y += diry * 1<<scaleY;
if ( y < -((IMGH<<scaleY)>>1) )
	{
	y = -((IMGH<<scaleY)>>1);
	diry = 4;
	}
if ( y >= scr->Height - 1 - (IMGH>>1) )
	{
	y = scr->Height - 1 - (IMGH>>1);
	diry = - 4;
	}
}



void BreakWall( void )
{
int n = RangeRand( 8 );
WORD hitx = x, hity = y + (IMGH<<scaleY)/3 - 20;

if ( bsi.bsi_Flags & BSIF_INVERTHOR )
	hitx += (IMGW-0x20) << scaleX;

if ( hitx < 0 )
	{ blitx = -hitx; sizex = (0x20<<scaleX) + hitx; }
else if ( hitx >= scr->Width - (0x20<<scaleX) )
	{ blitx = 0; sizex = scr->Width - hitx - 1; }
else
	{ blitx = 0; sizex = 0x20<<scaleX; }
if ( hity < 0 )
	{ blity = -hity; sizey = (0x42<<scaleY) + hity; }
else if ( hity >= scr->Height - (0x42<<scaleY) )
	{ blity = 0; sizey = scr->Height - hity - 1; }
else
	{ blity = 0; sizey = 0x42<<scaleY; }

BltBitMap( storebm, hitx < 0 ? 0 : ( hitx >= scr->Width ? scr->Width - 1 - hitx : hitx ), hity < 0 ? 0 : ( hity >= scr->Height ? scr->Height - 1 - hity : hity ),
	shadowbm, 0, 0,
	0x20 << scaleX, 0x42 << scaleY, 0xC0, 0xFF, NULL );
BltMaskBitMapRastPort( scalebreakbm, ((n * 0x20) << scaleX) + blitx, blity,
	rp, 0, 0,
	0x20 << scaleX, 0x42 << scaleY, (ABC|ABNC|ANBC), scalebreakbm->Planes[0] );
if ( (hitx + (0x20<<scaleX)) >= 0 && hitx < scr->Width &&
     (hity + (0x42<<scaleY)) >= 0 && hity < scr->Height ) 
	{
	BltBitMap( shadowbm, 0, 0,
		storebm, hitx < 0 ? 0 : ( hitx >= scr->Width ? scr->Width - 1 - hitx : hitx ), hity < 0 ? 0 : ( hity >= scr->Height ? scr->Height - 1 - hity : hity ),
		sizex, sizey, 0xC0, 0xFF, NULL );
	}
else
	DisplayBeep( NULL );
}


BOOL CreateFrames( void )
{
int n;
BOOL success = FALSE;

if ( breakbm = AllocVec( sizeof(struct BitMap), MEMF_ANY|MEMF_CLEAR ) )
	{
	InitBitMap( breakbm, depth + 1, 0x20, 0x42 );
	breakbm->Planes[0] = mem_ptr;
	breakbm->Planes[1] = mem_ptr + 528;
	breakbm->Planes[2] = mem_ptr + 1056;
	breakbm->Planes[3] = mem_ptr + 1584;
	breakbm->Planes[depth] = mem_ptr;

	if ( scalebreakbm = CreateBitMap( (0x20 * 10) << scaleX, 0x42 << scaleY, depth + 1 ) )
		{
		if ( zangiefsbm = AllocVec( sizeof(struct BitMap), MEMF_ANY|MEMF_CLEAR ) )
			{
			InitBitMap( zangiefsbm, depth + 1, IMGW, IMGH );
			zangiefsbm->Planes[0] = mem_ptr;
			zangiefsbm->Planes[1] = mem_ptr + BITPLSIZE;
			zangiefsbm->Planes[2] = mem_ptr + 2 * BITPLSIZE;
			zangiefsbm->Planes[3] = mem_ptr + 3 * BITPLSIZE;
			zangiefsbm->Planes[depth] = mem_ptr + 4 * BITPLSIZE;

			if ( shadowbm = CreateBitMap( IMGW << scaleX, IMGH << scaleY, depth + 1 ) )
				{
				if ( scalebm = CreateBitMap( IMGW << scaleX, IMGH << scaleY, depth + 1 ) )
					{
					mask = scalebm->Planes[depth];

					bsi.bsi_SrcLeftEdge = 0;
					bsi.bsi_SrcTopEdge = 0;
					bsi.bsi_DestTopEdge = 0;
					bsi.bsi_HorDen = 1;
					bsi.bsi_VertDen = 1;
					bsi.bsi_TempBitMap = shadowbm;
					bsi.bsi_HorNum = 1 << scaleX;
					bsi.bsi_VertNum = 1 << scaleY;
					bsi.bsi_Flags = NULL;
					bsi.bsi_SrcBitMap = breakbm;
					bsi.bsi_DestBitMap = scalebreakbm;
					bsi.bsi_Width = 0x20;
					bsi.bsi_Height = 0x42;

					for ( n = 0; n < 8 && blanking; n++ )
						{
						if ( STILL_BLANKING )
							{
							Decrunch30( mem_ptr, Breaks[n] );
							bsi.bsi_DestLeftEdge = (n * 0x20) << scaleX;
							bsi.bsi_Flags = NULL;
							ScaleBitMap( &bsi );
							}
						else blanking = FALSE;
						}

					bsi.bsi_DestLeftEdge = 0;
					bsi.bsi_SrcBitMap = zangiefsbm;
					bsi.bsi_DestBitMap = scalebm;
					bsi.bsi_Width = IMGW;
					bsi.bsi_Height = IMGH;

					success = blanking;

					if ( !success ) DisposeBitMap( scalebm );
					}
				if ( !success ) DisposeBitMap( shadowbm );
				}
			if ( !success ) FreeVec( zangiefsbm );
			}
		if ( !success ) DisposeBitMap( scalebreakbm );
		}
	if ( !success ) FreeVec( breakbm );	
	}

return success;
}


void Blank( void )
{
register int n, ticks = 0;
int status = STAND1;
ULONG mode;
Sound *scream, *laugh;
UBYTE volume = GETVOLUME(dinfo);
BOOL success = FALSE;
UBYTE brightness = GETBRIGHTNESS(dinfo);

if ( scr = GetDeeperFrontmostScreen( brightness, 4 ) )
	{
	depth = scr->RastPort.BitMap->Depth;
	if ( depth <= 7 )
		{
		mode = scr->ViewPort.Modes;
		if ( mode & SUPERHIRES )
			{
			if ( mode & LACE )
				{ scaleX = 1; scaleY = 0; }
			else
				{ scaleX = 2; scaleY = 0; }
			}
		else if ( mode & HIRES )
			{
			if ( mode & LACE )
				{ scaleX = 1; scaleY = 1; }
			else
				{ scaleX = 1; scaleY = 0; }
			}
		else if ( mode & LACE )
			{ scaleX = 0; scaleY = 1; }

		if ( storebm = CreateBitMap( scr->Width, scr->Height, depth ) )
			{
			BltBitMap( scr->RastPort.BitMap, 0, 0,
				storebm, 0, 0,
				scr->Width, scr->Height, 0xC0, 0xFF, NULL );

			if ( CreateFrames() )
				{
				if ( rp = AllocVec( sizeof(struct RastPort), MEMF_ANY|MEMF_CLEAR ) )
					{
					success = TRUE;

					scream = Open8SVX( "8SVX/Zangief.scream" );
					laugh = Open8SVX( "8SVX/Zangief.laugh" );

					InitRastPort( rp );
					rp->BitMap = shadowbm;

					SpritesOff();

					for ( n = 1; n < 16; n++ )
						SetRGB32( &scr->ViewPort, n, ((zangief_cmap32[n][0]>>24)*brightness/100)<<24, ((zangief_cmap32[n][1]>>24)*brightness/100)<<24, ((zangief_cmap32[n][2]>>24)*brightness/100)<<24 );

					x = RangeRand( scr->Width - 1 - (IMGW << scaleX) );
					y = RangeRand( scr->Height - 1 - (IMGH << scaleY) );

					while( STILL_BLANKING )
						{
						if ( !(bsi.bsi_Flags + scaleX + scaleY) && ++ticks < 5 )
							WaitTOF();
						else
							{
							ticks = 0;

							if ( status == STAND1 )
								{
								n = RangeRand( 10 );
								if ( !n )
									status = WIN;
								else if ( n == 1 || n == 2 )
									status = HIT;
								else if ( n < 5 )
									{
									status = WALK1;
									while ( ( dirx == 0 ) && ( diry == 0 ) )
										{
										dirx = RangeRand( 3 ) ? 4 : -4;
										diry = RangeRand( 3 ) ? 4 : -4;
										}
									if ( dirx < 0 )
										bsi.bsi_Flags = 0L;
									else
										bsi.bsi_Flags = BSIF_INVERTHOR;
									}
								else status = STAND2;
								}
							else if ( status == STAND2 )
								status = STAND3;
							else if ( status == STAND3 )
								status = STAND4;
							else if ( status == STAND4 )
								status = STAND1;
							else if ( status == WALK1 )
								{ MoveZangief(); status = WALK2; }
							else if ( status == WALK2 )
								{ MoveZangief(); status = WALK3; }
							else if ( status == WALK3 )
								{ MoveZangief(); status = WALK4; }
							else if ( status == WALK4 )
								{ MoveZangief();
								if ( RangeRand( 5 ) ) status = WALK1;
								else status = STAND1; }
							else if ( status == HIT )
								{ if ( RangeRand( 3 ) ) { BreakWall(); PlayAsynch8SVX( scream, volume ); status = KICK; }
								else status = PUNCH1; }
							else if ( status == KICK )
								status = KICK2;
							else if ( status == KICK2 )
								status = STAND1;
							else if ( status == PUNCH1 )
								status = PUNCH2;
							else if ( status == PUNCH2 )
								{ BreakWall(); PlayAsynch8SVX( scream, volume ); status = PUNCH3; }
							else if ( status == PUNCH3 )
								status = PUNCH4;
							else if ( status == PUNCH4 )
								status = PUNCH5;
							else if ( status == PUNCH5 )
								status = PUNCH6;
							else if ( status == PUNCH6 )
								status = STAND1;
							else if ( status == WIN )
								{ if ( RangeRand( 3 ) ) status = WIN2;
								else status = WIN3; }
							else if ( status == WIN2 )
								{ Play8SVX( laugh, volume ); status = STAND1; }
							else if ( status == WIN3 )
								{ PlayAsynch8SVX( scream, volume ); status = WIN4; }
							else if ( status == WIN4 )
								status = WIN5;
							else if ( status == WIN5 )
								status = STAND1;

							if ( x < 0 )
								{ blitx = -x; sizex = (IMGW<<scaleX) + x; }
							else if ( x > scr->Width - 1 - (IMGW<<scaleX) )
								{ blitx = 0; sizex = scr->Width - x; }
							else
								{ blitx = 0; sizex = IMGW<<scaleX; }

							if ( y < 0 )
								{ blity = -y; sizey = (IMGH<<scaleY) + y; }
							else if ( y > scr->Height - 1 - (IMGH<<scaleY) )
								{ blity = 0; sizey = scr->Height - y; }
							else
								{ blity = 0; sizey = IMGH<<scaleY; }

							frame = WhichFrame[status];
							Decrunch30( mem_ptr, FrameAndMask[frame].frame );
							Decrunch30( zangiefsbm->Planes[depth], FrameAndMask[frame].mask );

							xoffs = ( bsi.bsi_Flags & BSIF_INVERTHOR ? 121 - OriginalFrameXOffset[frame] - OriginalFrameWidth[frame] : OriginalFrameXOffset[frame] ) << scaleX;
							bsi.bsi_Width = OriginalFrameWidth[frame];
							bsi.bsi_SrcLeftEdge = OriginalFrameXOffset[frame];
							bsi.bsi_DestLeftEdge = xoffs;

							yoffs = OriginalFrameYOffset[frame] << scaleY;
							bsi.bsi_Height = IMGH - OriginalFrameYOffset[frame] - 4;
							bsi.bsi_SrcTopEdge = OriginalFrameYOffset[frame];
							bsi.bsi_DestTopEdge = yoffs;

							ScaleBitMap( &bsi );

							BltBitMap( storebm, x < 0 ? 0 : ( x >= scr->Width ? scr->Width - 1 - x : x ), y < 0 ? 0 : ( y >= scr->Height ? scr->Height - 1 - y : y ),
								shadowbm, 0, 0,
								IMGW << scaleX ,IMGH << scaleY, 0xC0, 0xFF, NULL );

							BltMaskBitMapRastPort( scalebm, blitx > xoffs ? blitx : xoffs, blity > yoffs ? blity : yoffs, rp,
								blitx ? ( blitx > xoffs ? 0 : xoffs - blitx ) : xoffs, blity ? ( blity > yoffs ? 0 : yoffs - blity ) : yoffs,
								blitx ? ( OriginalFrameWidth[frame] << scaleX ) - ( blitx > xoffs ? blitx - xoffs : 0 ) : OriginalFrameWidth[frame] << scaleX,
								blity ? ( (IMGH - OriginalFrameYOffset[frame] - 4) << scaleY ) - ( blity > yoffs ? blity - yoffs : 0 ) : (IMGH - OriginalFrameYOffset[frame] - 4) << scaleY,
								(ABC|ABNC|ANBC), mask );

							WaitTOF();
							BltBitMap( shadowbm, 0, 0,
								scr->RastPort.BitMap, x < 0 ? 0 : ( x >= scr->Width ? scr->Width - 1 - x : x ), y < 0 ? 0 : ( y >= scr->Height ? scr->Height - 1 - y : y ),
								x < 0 ? IMGW << scaleX : sizex, y < 0 ? IMGH << scaleY : sizey, 0xC0, 0xFF, NULL );
							}
						}
					SpritesOn();

					Close8SVX( scream );
					Close8SVX( laugh );

					FreeVec( rp );
					}
				DisposeBitMap( scalebm );
				DisposeBitMap( shadowbm );
				FreeVec( zangiefsbm );
				DisposeBitMap( scalebreakbm );
				FreeVec( breakbm );
				}
			DisposeBitMap( storebm );
			}
		}
	CloseScreen( scr );
	}

if ( !success )
	SendClientMsg( ACTION_FAILED );
}


void __main( void )
{
if ( IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37L ) )
	{
	if ( GfxBase = (struct GfxBase *)OpenLibrary( "graphics.library", 37L ) )
		{
		if ( BitMapBase = OpenLibrary( "bitmap.library", 0L ) )
			{
			if ( mem_ptr = AllocVec( 5 * BITPLSIZE, MEMF_CHIP | MEMF_CLEAR ) )
				{
				if ( dinfo = OpenCommunication() )
					{
					CurrentTime( &RangeSeed, &RangeSeed );
					Blank();
					CloseCommunication( dinfo );
					}
				FreeVec( mem_ptr );
				}
			CloseLibrary( BitMapBase );
			}
		CloseLibrary( (struct Library *)GfxBase );
		}
	CloseLibrary( (struct Library *)IntuitionBase );
	}
}
