489 lines
16 KiB
C++
489 lines
16 KiB
C++
|
|
#include "parameters.h"
|
|
|
|
#include "level.h"
|
|
#include "player.h"
|
|
#include <azur/azur.h>
|
|
#include <azur/gint/render.h>
|
|
|
|
#include <num/num.h>
|
|
|
|
#include "utilities.h"
|
|
|
|
#include <cstdint>
|
|
#include <stdlib.h>
|
|
|
|
#define TILESIZE 16
|
|
|
|
extern struct Map map_level0;
|
|
extern struct Map map_level1;
|
|
extern struct Map map_level2;
|
|
extern struct Map map_level3;
|
|
extern struct Map map_level4;
|
|
extern struct Map map_level5;
|
|
|
|
extern bool drawbackground;
|
|
extern bool drawforeground;
|
|
extern bool drawnormals;
|
|
extern bool drawborders;
|
|
extern bool textbacktile;
|
|
extern bool textforetile;
|
|
|
|
|
|
extern uint16_t tilecolor;
|
|
|
|
extern std::vector<Border*> MyLevelBorders;
|
|
|
|
|
|
struct Map *map_level;
|
|
|
|
|
|
int tileXmin, tileXmax;
|
|
int tileYmin, tileYmax;
|
|
int XinTile, YinTile;
|
|
|
|
extern bopti_image_t img_selected;
|
|
|
|
|
|
Level::Level( )
|
|
{
|
|
map_level = &map_level0;
|
|
this->UpdateBorders();
|
|
}
|
|
|
|
Level::~Level( )
|
|
{
|
|
|
|
}
|
|
|
|
void Level::ChangeMap( int level, Player *MyPlayer )
|
|
{
|
|
if(level==0) map_level = &map_level0;
|
|
else if(level==1) map_level = &map_level1;
|
|
else if(level==2) map_level = &map_level2;
|
|
else if(level==3) map_level = &map_level3;
|
|
else if(level==4) map_level = &map_level4;
|
|
else if(level==5) map_level = &map_level5;
|
|
else map_level = &map_level0;
|
|
|
|
this->UpdateDataMap( MyPlayer );
|
|
this->UpdateBorders( );
|
|
}
|
|
|
|
void Level::UpdateDataMap( Player *MyPlayer )
|
|
{
|
|
for(int i=0; i<map_level->w; i++)
|
|
{
|
|
for(int j=0; j<map_level->h; j++)
|
|
{
|
|
uint16_t index = j * map_level->w + i;
|
|
uint16_t currentTile = map_level->layers[1][ index ];
|
|
if (currentTile==31)
|
|
{
|
|
MyPlayer->currx = (float) (i) + 0.5f;
|
|
MyPlayer->curry = (float) (j) + 0.5f;
|
|
|
|
MyPlayer->vx = 0.0f;
|
|
MyPlayer->vy = 0.0f;
|
|
|
|
MyPlayer->Update( 0.0f );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Level::Render( void )
|
|
{
|
|
for(int u=!drawbackground; u<map_level->nblayers-!drawforeground;u++)
|
|
{
|
|
for(int i=0; i<map_level->w; i++)
|
|
{
|
|
for(int j=0; j<map_level->h; j++)
|
|
{
|
|
uint16_t index = j * map_level->w + i;
|
|
int16_t currentTile = map_level->layers[u][ index ];
|
|
if (currentTile!=-1)
|
|
{
|
|
uint16_t xtile = (currentTile % map_level->tileset_size) * 16;
|
|
uint16_t ytile = (currentTile / map_level->tileset_size) * 16;
|
|
if (u==0) azrp_subimage_rgb16_dye( i*16, j*16, map_level->tileset, xtile, ytile, 16, 16, IMAGE_DYE | IMAGE_NOCLIP_INPUT, tilecolor );
|
|
else azrp_subimage_rgb16( i*16, j*16, map_level->tileset, xtile, ytile, 16, 16, DIMAGE_NONE | IMAGE_NOCLIP_INPUT );
|
|
|
|
#if(DEBUG_MODE)
|
|
if (textbacktile) Azur_draw_text( i*16, j*16, "%d", GetTileBackgroundINT( i, j ) );
|
|
if (textforetile) Azur_draw_text( i*16+8, j*16+8, "%d", GetTileForegroundINT( i, j ) );
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if(DEBUG_MODE)
|
|
if (drawborders)
|
|
for( int i=0; i<MyLevelBorders.size(); i++)
|
|
azrp_line( (int) MyLevelBorders[i]->A.x, (int) MyLevelBorders[i]->A.y,
|
|
(int) MyLevelBorders[i]->B.x, (int) MyLevelBorders[i]->B.y,
|
|
C_GREEN );
|
|
|
|
if (drawnormals)
|
|
for( int i=0; i<MyLevelBorders.size(); i++)
|
|
azrp_line( ((int) MyLevelBorders[i]->A.x+(int) MyLevelBorders[i]->B.x)/2, ((int) MyLevelBorders[i]->A.y+(int) MyLevelBorders[i]->B.y)/2,
|
|
((int) MyLevelBorders[i]->A.x+(int) MyLevelBorders[i]->B.x)/2 + (int) MyLevelBorders[i]->N.x/2, ((int) MyLevelBorders[i]->A.y+(int) MyLevelBorders[i]->B.y)/2 + (int) MyLevelBorders[i]->N.y/2,
|
|
C_BLUE );
|
|
#endif
|
|
|
|
}
|
|
|
|
void Level::RenderSelected( uint8_t i, uint8_t j )
|
|
{
|
|
//azrp_image_p8( i*16, j*16, &img_selected, DIMAGE_NONE );
|
|
//Azur_draw_text( i*16+1, j*16+1, "B=%d", GetTileBackgroundINT( i, j ) );
|
|
//Azur_draw_text( i*16+1, j*16+1, "F=%d", GetTileForegroundINT( i, j ) );
|
|
}
|
|
|
|
|
|
void Level::Update( float dt )
|
|
{
|
|
|
|
}
|
|
|
|
/*RETURN the type of tile located in the background for the point x, y using player coordinates (x=[0..25], y=[0..14]) */
|
|
/*the x and y correspond to hte integer part of MyPlayer.x and MyPlayer.y*/
|
|
int Level::GetTileBackgroundINT( uint8_t x, uint8_t y )
|
|
{
|
|
uint16_t index = y * map_level->w + x;
|
|
uint16_t currentTile = map_level->layers[0][ index ];
|
|
return currentTile;
|
|
}
|
|
|
|
/*RETURN the type of tile located in the foreground for the point x, y using player coordinates (x=[0..25], y=[0..14]) */
|
|
/*the x and y correspond to hte integer part of MyPlayer.x and MyPlayer.y*/
|
|
int Level::GetTileForegroundINT( uint8_t x, uint8_t y )
|
|
{
|
|
uint16_t index = y * map_level->w + x;
|
|
uint16_t currentTile = map_level->layers[1][ index ];
|
|
return currentTile;
|
|
}
|
|
|
|
|
|
/*RETURN the type of tile located in the background for the point x, y using screen coordinates (x=[0..396], y=[0..223]) */
|
|
int Level::GetTileBackground( uint16_t x, uint16_t y )
|
|
{
|
|
uint8_t tileX = x >> 4;
|
|
uint8_t tileY = y >> 4;
|
|
uint16_t index = tileY * map_level->w + tileX;
|
|
uint16_t currentTile = map_level->layers[0][ index ];
|
|
|
|
return currentTile;
|
|
}
|
|
|
|
/*RETURN the type of tile located in the foreground for the point x, y using screen coordinates (x=[0..396], y=[0..223]) */
|
|
int Level::GetTileForeground( uint16_t x, uint16_t y )
|
|
{
|
|
uint8_t tileX = x >> 4;
|
|
uint8_t tileY = y >> 4 ;
|
|
uint16_t index = tileY * map_level->w + tileX;
|
|
uint16_t currentTile = map_level->layers[1][ index ];
|
|
return currentTile;
|
|
}
|
|
|
|
/*RETURN true if the player can go in the target position*/
|
|
bool Level::CanGo( Player *MyPlayer )
|
|
{
|
|
uint16_t targetTile = this->GetTileBackgroundINT( (int) MyPlayer->nextx, (int) MyPlayer->nexty );
|
|
|
|
if (targetTile!=0) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*RETURN true if the player is above a solid tile*/
|
|
/*TO DO : TO BE IMPROVED, THIS IS REALLY DIRTY !!!!*/
|
|
bool Level::IsOnGround( Player *MyPlayer )
|
|
{
|
|
if (this->GetTileBackgroundINT( (uint8_t) MyPlayer->currx, (uint8_t) MyPlayer->curry +1 ) !=0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Border* Level::MakeBorder( libnum::num DX, libnum::num DY, float x1, float y1, float x2, float y2 )
|
|
{
|
|
Border *Bord = new Border();
|
|
|
|
Bord->A.x = DX + libnum::num(x1*15.0);
|
|
Bord->A.y = DY + libnum::num(y1*15.0);
|
|
|
|
Bord->B.x = DX + libnum::num(x2*15.0);
|
|
Bord->B.y = DY + libnum::num(y2*15.0);
|
|
|
|
Bord->N.x = Bord->A.y - Bord->B.y;
|
|
Bord->N.y = Bord->B.x - Bord->A.x;
|
|
|
|
return Bord;
|
|
}
|
|
|
|
void Level::UpdateBorders( void )
|
|
{
|
|
MyLevelBorders.clear();
|
|
|
|
Border *B1;
|
|
|
|
for(int i=0; i<map_level->w; i++)
|
|
{
|
|
for(int j=0; j<map_level->h; j++)
|
|
{
|
|
uint16_t index = j * map_level->w + i;
|
|
int16_t currentTile = map_level->layers[0][ index ];
|
|
|
|
libnum::num DeltaX = libnum::num( i*16 );
|
|
libnum::num Deltay = libnum::num( j*16 );
|
|
|
|
|
|
switch(currentTile)
|
|
{
|
|
case -1: break; // Empty background
|
|
case 0: break; // No borders (filling tile)
|
|
|
|
case 1:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
//45° diagonals
|
|
|
|
case 2:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 3:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 12:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 13:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
|
|
//22.5° diagonals
|
|
|
|
case 4:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,0.5 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 5:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.5, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 6:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 1.0,0.5 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 7:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.5, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
|
|
case 14:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.5, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 15:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 0.0,0.5 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 16:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.5, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 17:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.5 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
|
|
|
|
// 67.5° Diagonals
|
|
|
|
|
|
case 24:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.5,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 34:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 0.5,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 25:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.5,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 35:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.5,0.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
|
|
case 26:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.5,1.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 36:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 0.5,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 27:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.5,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 37:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.5,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
|
|
// Blocks with 3 sides
|
|
|
|
case 8:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 9:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 18:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 19:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
// Blocks with 2 sides
|
|
|
|
case 28:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 29:
|
|
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 38:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 39:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 48:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 49:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
// Blocks with one single side
|
|
|
|
case 10:
|
|
case 44:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,0.0, 0.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 11:
|
|
case 46:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,1.0, 1.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 20:
|
|
case 47:
|
|
B1 = MakeBorder( DeltaX, Deltay, 0.0,0.0, 0.0,1.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
case 21:
|
|
case 45:
|
|
B1 = MakeBorder( DeltaX, Deltay, 1.0,1.0, 1.0,0.0 );
|
|
MyLevelBorders.push_back(B1);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
} |