Collab_RPG/src/map.c

239 lines
8.4 KiB
C

#include "map.h"
#include "config.h"
#include "game.h"
#include <gint/display.h>
extern Map *worldRPG[];
//extern ExtraData *extraRPG[];
void render_map(Game *game) {
Map *map_level = game->map_level;
Player *player = &game->player;
/* for all Layer (2 in the current configuration: Background is layer 0 and
* foreground is layer 1 ) */
/* x and y will contain the position in the loop. */
unsigned char x, y;
/* The positions where we start drawing the tiles will be in tx and
* ty. */
unsigned short int tx, ty;
/* mx and my will contain how many pixels will be hidden on x and on
* y. */
unsigned char mx, my;
/* dw and dh contain the amount of tiles that will be drawn on x and on
* y. */
unsigned char dw = DWIDTH/T_WIDTH+2, dh = DHEIGHT/T_HEIGHT+1;
/* mw and mh will contain the height and the width of the map. */
unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT;
/* tile contains the tile to draw. */
short int tile;
/* The position where I start drawing */
unsigned short int sx, sy;
/* The position of the tile in the tileset. */
unsigned short int xtile, ytile;
/* The layer we're drawing */
unsigned char l;
/* The index of the current tile we're drawing in the layer. */
int current_index;
/* Fix sx. */
if(player->x<DWIDTH/2){
/* If I can't center the player because I'm near the left border of
* the map. */
player->px = player->x;
sx = 0;
}else if(player->x+DWIDTH/2>mw){
/* If I can't center the player because I'm near the right border of
* the map. */
sx = mw-DWIDTH;
player->px = player->x-sx;
}else{
/* I can center the player. */
player->px = DWIDTH/2;
sx = player->x-player->px;
}
/* Fix sy. */
if(player->y<DHEIGHT/2){
/* If I can't center the player because I'm near the top border of
* the map. */
player->py = player->y;
sy = 0;
}else if(player->y+DHEIGHT/2>mh){
/* If I can't center the player because I'm near the bottom border
* of the map. */
sy = mh-DHEIGHT;
player->py = player->y-sy;
}else{
/* I can center the player. */
player->py = DHEIGHT/2;
sy = player->y-player->py;
}
tx = sx/T_WIDTH;
ty = sy/T_HEIGHT;
mx = sx-tx*T_WIDTH;
my = sy-ty*T_HEIGHT;
for (l = 0; l < map_level->nblayers-1; l++){
/* Draw a layer of the map on screen. */
for(y=0;y<dh;y++){
for(x=0;x<dw;x++){
/* I get the tile number if his position is inside the map. Then
* I draw it. */
if(tx+x>=0 && tx+x < map_level->w &&
ty+y>=0 && ty+y < map_level->h){
/* index of the current tile */
current_index = (y+ty) * map_level->w + tx+x;
/* we get the ID of the tile in the current drawable layers
*/
tile = map_level->layers[l][current_index];
/* tile == -1 means nothing to be drawn */
if(tile >= 0){
/* get x and y position in the tileset image */
xtile = (tile % map_level->tileset_size) * T_WIDTH;
ytile = (tile / map_level->tileset_size) * T_HEIGHT;
/* render */
dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my,
map_level->tileset, xtile, ytile, T_WIDTH,
T_HEIGHT, DIMAGE_NONE);
}
}
}
}
}
}
void render_map_by_layer(Game *game, int layer) {
Map *map_level = game->map_level;
Player *player = &game->player;
/* for all Layer (2 in the current configuration: Background is layer 0 and
* foreground is layer 1 ) */
/* x and y will contain the position in the loop. */
unsigned char x, y;
/* The positions where we start drawing the tiles will be in tx and
* ty. */
unsigned short int tx, ty;
/* mx and my will contain how many pixels will be hidden on x and on
* y. */
unsigned char mx, my;
/* dw and dh contain the amount of tiles that will be drawn on x and on
* y. */
unsigned char dw = DWIDTH/T_WIDTH+2, dh = DHEIGHT/T_HEIGHT+1;
/* mw and mh will contain the height and the width of the map. */
unsigned short int mw = map_level->w*T_WIDTH, mh = map_level->h*T_HEIGHT;
/* tile contains the tile to draw. */
short int tile;
/* The position where I start drawing */
unsigned short int sx, sy;
/* The position of the tile in the tileset. */
unsigned short int xtile, ytile;
/* Fix sx. */
if(player->x<DWIDTH/2){
/* If I can't center the player because I'm near the left border of
* the map. */
player->px = player->x;
sx = 0;
}else if(player->x+DWIDTH/2>mw){
/* If I can't center the player because I'm near the right border of
* the map. */
sx = mw-DWIDTH;
player->px = player->x-sx;
}else{
/* I can center the player. */
player->px = DWIDTH/2;
sx = player->x-player->px;
}
/* Fix sy. */
if(player->y<DHEIGHT/2){
/* If I can't center the player because I'm near the top border of
* the map. */
player->py = player->y;
sy = 0;
}else if(player->y+DHEIGHT/2>mh){
/* If I can't center the player because I'm near the bottom border
* of the map. */
sy = mh-DHEIGHT;
player->py = player->y-sy;
}else{
/* I can center the player. */
player->py = DHEIGHT/2;
sy = player->y-player->py;
}
tx = sx/T_WIDTH;
ty = sy/T_HEIGHT;
mx = sx-tx*T_WIDTH;
my = sy-ty*T_HEIGHT;
/* Draw a layer of the map on screen. */
for(y=0;y<dh;y++){
for(x=0;x<dw;x++){
/* I get the tile number if his position is inside the map. Then
* I draw it. */
if(tx+x>=0 && tx+x < map_level->w &&
ty+y>=0 && ty+y < map_level->h){
/* index of the current tile */
int currentIndex = (y+ty) * map_level->w + tx+x;
/* we get the ID of the tile in the current drawable layers
*/
tile = map_level->layers[layer][currentIndex];
/* tile == -1 means nothing to be drawn */
if(tile >= 0){
/* get x and y position in the tileset image */
xtile = (tile % map_level->tileset_size) * T_WIDTH;
ytile = (tile / map_level->tileset_size) * T_HEIGHT;
/* render */
dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my,
map_level->tileset, xtile, ytile, T_WIDTH,
T_HEIGHT, DIMAGE_NONE);
}
}
}
}
}
short int get_tile(Game *game, int x, int y, int l) {
Map *map_level = game->map_level;
/* Get the tile at (x, y) on layer l. Returns the tile ID or MAP_OUTSIDE if
* she's not found. */
return (x>=0 && x < map_level->w && y>=0 && y < map_level->h) ?
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE;
}
short int get_walkable(Game *game, int x, int y) {
Map *map_level = game->map_level;
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
* found. */
return (x>=0 && x < map_level->w && y>=0 && y < map_level->h) ?
map_level->walkable[y * map_level->w + x] : MAP_OUTSIDE;
}
/* return the pointer to the map containing the given position */
Map *get_map_for_coordinates( Game *game, int x, int y )
{
/* check if the current map contains the point */
if (x>=game->map_level->xmin && x<game->map_level->xmax &&
y>=game->map_level->ymin && y<game->map_level->ymax)
return game->map_level;
/* else we check in worldRPG if there is a mal containing that point */
int i = 0;
Map *current = worldRPG[i];
do
{
if (x>=current->xmin && x<current->xmax &&
y>=current->ymin && y<current->ymax)
return current;
i++;
current = worldRPG[i];
}
while (current!=NULL);
/* else we return NULL cause the point is a not within a map */
return NULL;
}