#include <windows.h>
#include "main.h"
#include "game.h"
int spause;
DWORD tpause;
static int X,Y;
bool drag_mode_enabled = TRUE;
bool gpause = FALSE;
void game_loop( void )
{
if ( gpause == FALSE )
{
SPRITE *s = NULL;
populate_level( lvl );
bg_update( lvl ); UpdateSprites(); for ( s = lvl->first_sprite; s; s = s->next )
DodgeAI(s);
}
#ifdef DX
spause = UMAX( 0, --spause ); #endif
game_paint(memDC); HDC hDC = GetDC(game->hWindow);
BitBlt(hDC, 0, 0, game->width, game->height, memDC, 0, 0, SRCCOPY);
ReleaseDC(game->hWindow, hDC);
}
void game_paint(HDC hDC)
{
char buf[MIL];
bg_draw(lvl, hDC);
#if defined(VOLUME) || defined(FPS)
Draw( backbuf, hDC, 0, 0, FALSE, FALSE );
#endif
SetBkMode(hDC, TRANSPARENT);
SetTextColor(hDC, RGB( 0, 0, 0));
#ifdef FPS
char fps[20];
sprintf( fps, "FPS: %d", 1000/game->framedelay);
TextOut(hDC, 5, 2, fps, strlen(fps) );
#endif
#ifdef VOLUME
#ifdef DX
char vol[30];
sprintf( vol, "Volume: %d", (volume+10000));
TextOut(hDC, 5, 20, vol, strlen(vol) );
#else
char vol[30];
sprintf( vol, "Volume: Disabled" );
TextOut(hDC, 5, 20, vol, strlen(vol) );
#endif
#endif
SetTextColor(hDC, RGB( 255, 255, 255));
if ( gpause == FALSE )
DrawSprites( lvl->first_sprite, hDC );
else
TextOut(hDC, (PRG_WIDTH-60)/2, (PRG_HEIGHT+18)/2, "PAUSED", strlen("PAUSED"));
}
void game_start(HWND hWindow)
{
HDC hDC = GetDC( hWindow );
srand(GetTickCount());
#ifdef LOG
#ifdef XLOG
init_log(); #else
if ( exists_file("log") == FALSE )
system( "mkdir log" );
#endif
#endif
start = GetTickCount();
SetTimer( game->hWindow, T_ID, SECOND, NULL );
#ifdef DX
SetTimer( game->hWindow, STREAM_TIMER, SECOND*2.1, NULL ); #endif
memDC = CreateCompatibleDC(GetDC(hWindow));
memBitmap = CreateCompatibleBitmap(GetDC(hWindow), game->width, game->height);
SelectObject(memDC, memBitmap);
lvl = load_level( game->current_level );
populate_level( lvl );
#ifdef LOG
#ifdef LEVEL_LOG
if ( lvl != NULL )
{
#ifdef XLOG
LT( "Game_Start", MESSAGE, "Level %d loaded and populated. Currently had %d sprites and %d proto-sprites!", lvl->num, lvl->num_sprites, lvl->num_proto );
#else
glog( "Game_Start: level %d loaded and populated. Currently had %d sprites and %d proto-sprites!", lvl->num, lvl->num_sprites, lvl->num_proto );
#endif
}
else
{
#ifdef XLOG
LT( "Game_Start", WARNING, "Null level! Expect the worst!", 0 );
#else
glog( "Game_Start: NULL level! Expect crash!" );
#endif
}
#endif
#endif
if ( lvl->bg->type == STARRY )
init_starry( lvl->bg, MAX_STARS, 75 );
#ifdef DX
init_dx(lvl->song);
if ( current_song != MAX_SOUND )
{
set_volume( song, volume );
play_wave( song, TRUE );
}
#endif
#if defined(VOLUME) || defined(FPS)
#ifdef DX
backbuf = bitmap_from_generic(hDC, 110, 40, RGB(255,255,555), "backbuf", FALSE);
#else
backbuf = bitmap_from_generic(hDC, 130, 40, RGB(255,255,55), "backbuf", FALSE);
#endif
#endif
gpause = FALSE;
return;
}
void game_end( void )
{
DeleteObject(memBitmap);
DeleteDC(memDC);
clean_level(lvl, TRUE); #if defined(VOLUME) || defined(FPS) FreeBitmap( backbuf );
#endif
DISPOSE( player->name );
DISPOSE( player );
KillTimer(game->hWindow, T_ID);
#ifdef DX
KillTimer(game->hWindow, STREAM_TIMER);
#endif
DISPOSE( game );
#ifdef DX
close_dx();
#endif
return;
}
void handle_keys( void )
{
#ifdef DX
if ( (GetAsyncKeyState('w') != 0 || GetAsyncKeyState('W') != 0) && spause <= 0) {
play_sound(WHOA_STRANGE);
spause = 50;
}
#endif
if ( GetAsyncKeyState('p') != 0 || GetAsyncKeyState('P') != 0 ) {
if ( gpause == TRUE )
{
gpause = FALSE;
start += (GetTickCount()-tpause);
tpause = GetTickCount();
SetTimer( game->hWindow, T_ID, SECOND, NULL );
}
else
{
gpause = TRUE;
tpause = GetTickCount();
KillTimer(game->hWindow ,T_ID);
}
}
#ifdef DX
if ( GetAsyncKeyState(VK_ADD) < 0 && stopped == FALSE)
{
volume = URANGE(-10000,volume+100,0);
set_volume( song, volume );
}
if ( GetAsyncKeyState(VK_SUBTRACT) < 0 && stopped == FALSE)
{
volume = URANGE(-10000,volume-100,0);
set_volume( song, volume );
}
if ( GetAsyncKeyState('s') < 0 || GetAsyncKeyState('S') < 0 )
{
if ( spause <= 0 )
{
if ( stopped == TRUE )
game_activate();
else
game_deactivate();
spause = 5;
}
}
#endif
}
void mousebuttondown( int x, int y, bool left )
{
if ( (left == TRUE) && (drag == NULL) && (drag_mode_enabled == TRUE))
{
if ( (drag = is_point_in_sprite( x, y ) ) != NULL )
{
SetCapture(game->hWindow);
X = Y = 0;
X = drag->velocity.x;
Y = drag->velocity.y;
drag->velocity.x = 0;
drag->velocity.y = 0;
mousemove(x,y);
}
}
}
void mousebuttonup(int x, int y, bool left)
{
ReleaseCapture();
if ( drag != NULL )
{
drag->velocity.x = X;
drag->velocity.y = Y;
}
X = Y = 0;
drag = NULL;
}
void mousemove(int x, int y)
{
if ( drag != NULL )
{
POINT here;
here.x = x - (drag->width/2);
here.y = y - (drag->height/2);
SetPosition( drag, here );
game_paint( memDC );
}
}
void game_activate( void )
{
}
void game_deactivate( void )
{
}
void DodgeAI( SPRITE *sprite )
{
if ( sprite == NULL )
return;
POINT pos = sprite->position;
int xcol = PRG_WIDTH, ycol = PRG_HEIGHT, xycol = PRG_WIDTH+PRG_HEIGHT;
SPRITE *loop = NULL;
for ( loop = lvl->first_sprite; loop != NULL; loop = loop->next )
{
if ( loop == sprite )
continue;
POINT lpos = loop->position;
int xdist = (pos.x + sprite->bitmap->width / 2) -
(lpos.x + loop->bitmap->width /2);
int ydist = (pos.y + sprite->bitmap->height / 2) -
(lpos.y + loop->bitmap->height /2);
if ( abs(xdist) < abs(xcol) || abs(ydist) < abs(ycol) )
{
if ( abs(xdist) + abs(ydist) < xycol )
{
xycol = abs(xcol) + abs(ycol);
xcol = xdist;
ycol = ydist;
}
}
}
POINT velo = sprite->velocity;
if ( abs(xcol) < 100 )
{
if ( xcol < 0 )
velo.x = UMAX(velo.x - 1, -MAXSPEED );
else
velo.x = UMIN(velo.x + 1, MAXSPEED );
}
if ( abs(ycol) < 100 )
{
if ( ycol < 0 )
velo.y = UMAX(velo.y - 1, -MAXSPEED );
else
velo.y = UMIN(velo.y + 1, MAXSPEED );
}
SetVelocity(sprite, velo.x, velo.y );
}
void game_size( LONG x, LONG y, LEVEL *l )
{
PRG_WIDTH = x;
PRG_HEIGHT = y;
int width = PRG_WIDTH + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
int height = PRG_HEIGHT + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
int xpos = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
int ypos = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
SetWindowPos( game->hWindow, HWND_TOPMOST, xpos, ypos, width, height, SWP_NOZORDER );
game->width = PRG_WIDTH;
game->height = PRG_HEIGHT;
DeleteObject(memBitmap);
DeleteDC(memDC);
memDC = CreateCompatibleDC(GetDC(game->hWindow));
memBitmap = CreateCompatibleBitmap(GetDC(game->hWindow), game->width, game->height);
SelectObject(memDC, memBitmap);
if ( l != NULL )
{
if ( l->bg != NULL )
{
l->bg->width = PRG_WIDTH;
l->bg->height = PRG_HEIGHT;
}
}
}
void NewGame( bool reset_score )
{
gpause = FALSE;
if ( reset_score == TRUE )
player->score = 0;
CleanSprites();
populate_level( lvl );
start = GetTickCount();
SetTimer( game->hWindow, T_ID, SECOND, NULL );
}
int random( int low, int high )
{
int num = rand() % (high+1);
if ( num < low )
num = low;
if ( num > high )
num = high;
return num;
}