l2-unlegits/l2ooghelper/GlobalMapImages.cpp
2012-02-01 05:25:08 +00:00

221 lines
5.9 KiB
C++

#include "stdafx.h"
#include "Resource.h"
#include "logger.h"
#include "GlobalMapImages.h"
#include "PngJpegImage.h"
GlobalMapImages::GlobalMapImages()
{
InitializeCriticalSection( &m_cs );
EnterCriticalSection( &m_cs );
int i, j;
for( i=0; i<GEO_W; i++ )
{
for( j=0; j<GEO_H; j++ )
{
m_geo_hdc[i][j] = NULL;
m_width[i][j] = m_height[i][j] = 0;
}
}
m_nLoadedCount = 0;
m_mapsDir[0] = 0;
LeaveCriticalSection( &m_cs );
}
GlobalMapImages::~GlobalMapImages()
{
unloadAllSquares();
DeleteCriticalSection( &m_cs );
}
void GlobalMapImages::setMapsDir( const char *dir )
{
strcpy( m_mapsDir, dir );
}
bool GlobalMapImages::isValidGeoXY( int geo_x, int geo_y )
{
if( (geo_x>=GEO_X_MIN) && (geo_x<=GEO_X_MAX) &&
(geo_y>=GEO_Y_MIN) && (geo_y<=GEO_Y_MAX) ) return true;
return false;
}
bool GlobalMapImages::preloadSquare( int geo_x, int geo_y )
{
Lock();
if( !isValidGeoXY( geo_x, geo_y ) ) { UnLock(); return false; }
if( isSquareLoaded( geo_x, geo_y ) ) { UnLock(); return false; }
// check maps dir
if( m_mapsDir[0] == 0 )
{
char aCurDir[256] = {0};
GetCurrentDirectoryA( 255, aCurDir );
strcat( aCurDir, "\\maps" );
strcpy( m_mapsDir, aCurDir );
}
// first try to load image
char filename[256];
sprintf( filename, "%s\\%d_%d.jpg", m_mapsDir, geo_x, geo_y );
PngJpegImage *img = new PngJpegImage();
if( !img->readFile_JPEG( filename ) )
{
// try another file name
sprintf( filename, "%s\\%d_%d_1.jpg", m_mapsDir, geo_x, geo_y );
if( !img->readFile_JPEG( filename ) )
{
log_error( LOG_ERROR, "GlobalMapImages::preloadSquare( %d, %d ): could not readFile_JPEG( %s ): %u\n",
geo_x, geo_y, filename, GetLastError() );
UnLock();
return false;
}
// here loaded XX_XX_1.jpg
}
// image size
int w = 0, h = 0;
img->getParams( &w, &h, NULL, NULL );
//
HWND hWnd = GetDesktopWindow();
HDC hWindowDC = GetDC( hWnd );
HDC hdc = CreateCompatibleDC( hWindowDC );
if( !hdc )
{
log_error( LOG_ERROR, "GlobalMapImages::preloadSquare( %d, %d ): could not CreateCompatibleDC(): %u\n",
geo_x, geo_y, GetLastError() );
delete img;
UnLock();
return false;
}
HBITMAP hbm = CreateCompatibleBitmap( hWindowDC, w, h );
ReleaseDC( hWnd, hWindowDC ); // now we don't need desktop window DC
if( hbm == NULL )
{
log_error( LOG_ERROR, "GlobalMapImages::preloadSquare( %d, %d ): could not CreateCompatibleBitmap(): %u\n",
geo_x, geo_y, GetLastError() );
delete img;
DeleteDC( hdc );
UnLock();
return false;
}
SelectObject( hdc, (HGDIOBJ)hbm );
img->displayOn( hdc, 0, 0 ); // print image to HDC
delete img;
SetStretchBltMode( hdc, HALFTONE );
geo_XY_to_array_index( geo_x, geo_y );
m_geo_hdc[ geo_x ][ geo_y ] = hdc; // save loaded HDC in array
m_width[ geo_x ][ geo_y ] = w;
m_height[ geo_x ][ geo_y ] = h;
m_nLoadedCount++; // inc loaded count
UnLock();
//log_error_np( LOG_OK, "[GlobalMap] loaded %d_%d\n", geo_x+GEO_X_MIN, geo_y+GEO_Y_MIN );
return true;
}
bool GlobalMapImages::unloadSquare( int geo_x, int geo_y )
{
Lock();
if( !isSquareLoaded( geo_x, geo_y ) ) { UnLock(); return false; }
geo_XY_to_array_index( geo_x, geo_y );
// first get current DC bitmap
HBITMAP hbm = (HBITMAP)GetCurrentObject( m_geo_hdc[geo_x][geo_y], OBJ_BITMAP );
// then delete DC
DeleteDC( m_geo_hdc[geo_x][geo_y] );
m_geo_hdc[geo_x][geo_y] = NULL; // mark as not loaded
m_width[ geo_x ][ geo_y ] = m_height[ geo_x ][ geo_y ] = 0;
// then delete bitmap
if( hbm ) DeleteObject( (HGDIOBJ)hbm );
m_nLoadedCount--; // dec loaded count
UnLock();
return true;
}
void GlobalMapImages::preloadAllSquares()
{
Lock();
int i, j;
for( i=GEO_X_MIN; i<=GEO_X_MAX; i++ )
{
for( j=GEO_Y_MIN; j<=GEO_Y_MAX; j++ )
{
preloadSquare( i, j );
}
}
UnLock();
}
void GlobalMapImages::unloadAllSquares()
{
Lock();
int i, j;
for( i=GEO_X_MIN; i<=GEO_X_MAX; i++ )
{
for( j=GEO_Y_MIN; j<=GEO_Y_MAX; j++ )
{
unloadSquare( i, j );
}
}
UnLock();
}
bool GlobalMapImages::isSquareLoaded( int geo_x, int geo_y ) const
{
if( !isValidGeoXY( geo_x, geo_y ) ) return false;
geo_XY_to_array_index( geo_x, geo_y );
if( m_geo_hdc[ geo_x ][ geo_y ] != NULL ) return true;
return false;
}
HDC GlobalMapImages::getSquareHDC( int geo_x, int geo_y ) const
{
if( !isValidGeoXY( geo_x, geo_y ) ) return NULL;
geo_XY_to_array_index( geo_x, geo_y );
return m_geo_hdc[ geo_x ][ geo_y ];
}
void GlobalMapImages::getSquareWH( int geo_x, int geo_y, int& w, int &h ) const
{
if( !isValidGeoXY( geo_x, geo_y ) ) return;
geo_XY_to_array_index( geo_x, geo_y );
w = m_width[ geo_x ][ geo_y ];
h = m_height[ geo_x ][ geo_y ];
}
/*
protected:
CRITICAL_SECTION m_cs;
int m_nLoadedCount;
HDC m_geo_hdc[GEO_W][GEO_H];
};
*/
void GlobalMapImages::GetGeoSquareStartL2Coords( int geo_x, int geo_y, int *l2_x, int *l2_y )
{
const int geo_square_x_0 = 20;
const int geo_square_y_0 = 18;
if( (geo_x<16) || (geo_x>26) || (geo_y<10) || (geo_y>25) ) return;
(*l2_x) = (geo_x - geo_square_x_0) * GlobalMapImages::GEO_BOX_L2_SIZE;
(*l2_y) = (geo_y - geo_square_y_0) * GlobalMapImages::GEO_BOX_L2_SIZE;
}
void GlobalMapImages::GetGeoMapSquareXYByL2Coords( int l2_x, int l2_y, int *geo_x, int *geo_y )
{
const int geo_square_x_0 = 20;
const int geo_square_y_0 = 18;
int nSquaresFrom_0_x = l2_x / GlobalMapImages::GEO_BOX_L2_SIZE;
int nSquaresFrom_0_y = l2_y / GlobalMapImages::GEO_BOX_L2_SIZE;
int geo_square_x = geo_square_x_0 + nSquaresFrom_0_x;
int geo_square_y = geo_square_y_0 + nSquaresFrom_0_y;
// fix negative offset coords
if( l2_x < 0 ) geo_square_x--;
if( l2_y < 0 ) geo_square_y--;
//
if( (geo_square_x < 16) || (geo_square_x > 26) || (geo_square_y < 10) || (geo_square_y > 25) )
{
log_error_np( LOG_ERROR, "[GlobalMap]: GetGeoMapSquareXYByL2Coords(): error overflow!\n" );
return;
}
if( geo_x ) (*geo_x) = geo_square_x;
if( geo_y ) (*geo_y) = geo_square_y;
}