426 lines
17 KiB
C++
426 lines
17 KiB
C++
#include "room.h"
|
|
#include "jdraw.h"
|
|
#include "jfile.h"
|
|
#include "jutil.h"
|
|
#include "actor.h"
|
|
|
|
namespace room
|
|
{
|
|
static int current_room = 0;
|
|
|
|
static int inner_w = 2;
|
|
static int inner_h = 2;
|
|
|
|
static vec3_t size = {8,8,8}; // Tamany de l'habitació en tiles
|
|
static vec3_t tmin = {0,0,0}; // primer tile en cada coordenada
|
|
static vec3_t tmax = {7,7,7}; // ultim tile en cada coordenada
|
|
static vec3_t min = {0,0,0}; // primer "pixel isometric" en cada coordenada
|
|
static vec3_t max = {56,56,56}; // ultim "pixel isometric" en cada coordenada
|
|
|
|
static int doors = NO_DOOR; // Portes obertes
|
|
static int door_height[4]; // Altura de cada porta
|
|
static int exits[6]; // Habitació destí a la que du cada porta (piso i sostre inclosos)
|
|
static int color = 5; // Color de l'habitació
|
|
|
|
static int floor_type = 0; // Tile per al piso
|
|
static int walls_type = 0; // Tile per a les pareds
|
|
static int doors_type = 0; // Textura per a les portes
|
|
static int walldoors_type = 0; // Textura per a baix de les portes
|
|
|
|
static bool modified = false;
|
|
|
|
// Surface on se guarden els gràfics de cada cosa
|
|
static draw::surface *floor_surf = nullptr;
|
|
static draw::surface *walls_surf = nullptr;
|
|
static draw::surface *doors_surf = nullptr;
|
|
static draw::surface *aux_surf = nullptr;
|
|
|
|
void init()
|
|
{
|
|
actor::clear();
|
|
|
|
// [TODO][2024-06-05] Açò es una xorrada. Si al final sempre son els mateixos arxius,
|
|
// carregar açò al principi del joc i au
|
|
if (floor_surf) draw::freeSurface(floor_surf);
|
|
if (walls_surf) draw::freeSurface(walls_surf);
|
|
if (doors_surf) draw::freeSurface(doors_surf);
|
|
if (aux_surf) draw::freeSurface(aux_surf);
|
|
|
|
floor_surf = draw::loadSurface("floor.gif");
|
|
walls_surf = draw::loadSurface("walls.gif");
|
|
doors_surf = draw::loadSurface("doors.gif");
|
|
aux_surf = draw::loadSurface("roomaux.gif");
|
|
|
|
editor::updateRoomList();
|
|
}
|
|
|
|
void refresh()
|
|
{
|
|
size = {(inner_w+1)*2,(inner_h+1)*2,3};
|
|
tmin = {3-inner_w,3-inner_h,0};
|
|
tmax = {4+inner_w,4+inner_h,3};
|
|
min = {tmin.x*8,tmin.y*8,0};
|
|
max = {tmax.x*8,tmax.y*8,24};
|
|
doors = (door_height[XP]>=0?DOOR_XP:0) | (door_height[XN]>=0?DOOR_XN:0) | (door_height[YP]>=0?DOOR_YP:0) | (door_height[YN]>=0?DOOR_YN:0);
|
|
//door_height[0] = inner_xp; //XP
|
|
//door_height[1] = inner_xn; //XN
|
|
//door_height[2] = inner_yp; //YP
|
|
//door_height[3] = inner_yn; //YN
|
|
|
|
if (doors & DOOR_YP)
|
|
{
|
|
uint8_t actual_floor = door_height[2]>0?0:floor_type*32;
|
|
actor::actor_t *act = actor::create("DOOR_YP1", {24,(tmax.y+1)*8,0}, {8,8,(door_height[2])*4}, "floor.gif", {actual_floor,1,32,15}, {0,15+door_height[2]*8});
|
|
act->flags = FLAG_NOEDITOR;
|
|
actor::setDirty(act, true);
|
|
act = actor::create("DOOR_YP2", {32,(tmax.y+1)*8,0}, {8,8,(door_height[2])*4}, "floor.gif", {actual_floor,1,32,15}, {0,15+door_height[2]*8});
|
|
act->flags = FLAG_NOEDITOR;
|
|
actor::setDirty(act, true);
|
|
}
|
|
|
|
if (doors & DOOR_XP)
|
|
{
|
|
uint8_t actual_floor = door_height[0]>0?0:floor_type*32;
|
|
actor::actor_t *act = actor::create("DOOR_XP1", {(tmax.x+1)*8,24,0}, {8,8,(door_height[0])*4}, "floor.gif", {actual_floor,1,32,15}, {0,15+door_height[0]*8});
|
|
act->flags = FLAG_NOEDITOR;
|
|
actor::setDirty(act, true);
|
|
act = actor::create("DOOR_XP2", {(tmax.x+1)*8,32,0}, {8,8,(door_height[0])*4}, "floor.gif", {actual_floor,1,32,15}, {0,15+door_height[0]*8});
|
|
act->flags = FLAG_NOEDITOR;
|
|
actor::setDirty(act, true);
|
|
}
|
|
|
|
actor::reorder();
|
|
}
|
|
|
|
//void load(int x, int y, int8_t xp, int8_t xn, int8_t yp, int8_t yn, uint8_t col, uint8_t floor, uint8_t walls, uint8_t door, uint8_t walldoor)
|
|
void load(const int room)
|
|
{
|
|
if (modified) editor::save();
|
|
|
|
if (room > 64) { perror("ERROR: Nombre d'habitació massa gran! Eixint..."); exit(1); }
|
|
init();
|
|
|
|
// Primer carreguem els valors per defecte
|
|
inner_w = inner_h = 2;
|
|
for (int i=0;i<4;++i) door_height[i] = -1;
|
|
color = 9;
|
|
floor_type = walls_type = doors_type = walldoors_type = 0;
|
|
for (int i=0;i<6;++i) exits[i] = -1;
|
|
|
|
// Després intentem carregar els valors segons el arxiu que toca, si existeix
|
|
char filename[] = "rooms/00.txt";
|
|
filename[6] = int(room/10)+48;
|
|
filename[7] = (room%10)+48;
|
|
int filesize=0;
|
|
char *buffer = file::getFileBuffer(filename, filesize, true);
|
|
char *original_buffer = buffer;
|
|
|
|
if (buffer)
|
|
{
|
|
while (*buffer != 0)
|
|
{
|
|
const char* key = file::readString(&buffer);
|
|
|
|
if (util::strcomp(key, "width:")) {
|
|
const int val = file::readInt(&buffer);
|
|
inner_w = SDL_clamp(val, 0, 3);
|
|
} else if (util::strcomp(key, "height:")) {
|
|
const int val = file::readInt(&buffer);
|
|
inner_h = SDL_clamp(val, 0, 3);
|
|
|
|
} else if (util::strcomp(key, "door-height-xp:")) {
|
|
const int val = file::readInt(&buffer);
|
|
door_height[XP] = SDL_clamp(val, -1, 5);
|
|
} else if (util::strcomp(key, "door-height-xn:")) {
|
|
const int val = file::readInt(&buffer);
|
|
door_height[XN] = SDL_clamp(val, -1, 5);
|
|
} else if (util::strcomp(key, "door-height-yp:")) {
|
|
const int val = file::readInt(&buffer);
|
|
door_height[YP] = SDL_clamp(val, -1, 5);
|
|
} else if (util::strcomp(key, "door-height-yn:")) {
|
|
const int val = file::readInt(&buffer);
|
|
door_height[YN] = SDL_clamp(val, -1, 5);
|
|
|
|
} else if (util::strcomp(key, "color:")) {
|
|
color = util::stringToInt(file::readString(&buffer), {"blue", "red", "purple", "green", "cyan", "yellow", "white"}, {5, 6, 7, 8, 9, 10, 11});
|
|
|
|
} else if (util::strcomp(key, "floor-texture:")) {
|
|
floor_type = file::readInt(&buffer);
|
|
} else if (util::strcomp(key, "wall-texture:")) {
|
|
walls_type = file::readInt(&buffer);
|
|
} else if (util::strcomp(key, "door-texture:")) {
|
|
doors_type = file::readInt(&buffer);
|
|
} else if (util::strcomp(key, "under-door-texture:")) {
|
|
walldoors_type = file::readInt(&buffer);
|
|
|
|
} else if (util::strcomp(key, "exit-xp:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[0] = SDL_clamp(val, 0, 64);
|
|
} else if (util::strcomp(key, "exit-xn:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[1] = SDL_clamp(val, 0, 64);
|
|
} else if (util::strcomp(key, "exit-yp:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[2] = SDL_clamp(val, 0, 64);
|
|
} else if (util::strcomp(key, "exit-yn:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[3] = SDL_clamp(val, 0, 64);
|
|
} else if (util::strcomp(key, "exit-zp:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[4] = SDL_clamp(val, 0, 64);
|
|
} else if (util::strcomp(key, "exit-zn:")) {
|
|
const int val = file::readInt(&buffer);
|
|
exits[5] = SDL_clamp(val, 0, 64);
|
|
|
|
} else if (util::strcomp(key, "actor{")) {
|
|
actor::actor_t *act = actor::createFromFile(&buffer);
|
|
actor::setDirty(act, true);
|
|
}
|
|
}
|
|
free(original_buffer);
|
|
}
|
|
current_room = room;
|
|
refresh();
|
|
}
|
|
|
|
void update()
|
|
{
|
|
actor::remove(actor::find("DOOR_XP1"));
|
|
actor::remove(actor::find("DOOR_XP2"));
|
|
actor::remove(actor::find("DOOR_YP1"));
|
|
actor::remove(actor::find("DOOR_YP2"));
|
|
|
|
refresh();
|
|
}
|
|
|
|
void draw()
|
|
{
|
|
draw::pushSource();
|
|
draw::swapcol(1, color);
|
|
|
|
// RUTINES DE PINTAT DE LA PORTA DE DALT A LA DRETA
|
|
if (doors & DOOR_YN)
|
|
{
|
|
// Si la porta està elevada, pintar la part frontal de baix de la porta
|
|
if (door_height[3] > 0) {
|
|
draw::setSource(walls_surf);
|
|
draw::draw( 164+3*16-tmin.y*16, (36+3*8+tmin.y*8) + (5-door_height[3])*8, 16, 48-(5-door_height[3])*8, walldoors_type*16, (5-door_height[3])*8);
|
|
draw::draw( 164+4*16-tmin.y*16, (36+4*8+tmin.y*8) + (5-door_height[3])*8, 16, 48-(5-door_height[3])*8, walldoors_type*16, (5-door_height[3])*8);
|
|
}
|
|
|
|
// Pintem els dos tiles baix de la porta
|
|
draw::setSource(walls_surf);
|
|
draw::draw(164+4*16-(tmin.y-1)*16, -door_height[3]*8+84+4*8+(tmin.y-1)*8, 16, 15, walls_type*16, 33, DRAW_FLIP_HORIZONTAL); // Vora
|
|
draw::setSource(floor_surf);
|
|
draw::draw(148+3*16-(tmin.y-1)*16, -door_height[3]*8+76+3*8+(tmin.y-1)*8, 32, 15, floor_type*32, 1); // Tile de Piso
|
|
draw::draw(148+4*16-(tmin.y-1)*16, -door_height[3]*8+76+4*8+(tmin.y-1)*8, 32, 15, floor_type*32, 1); // Tile de Piso
|
|
|
|
// Pintem la porta
|
|
draw::setSource(doors_surf);
|
|
draw::draw(164+3*16-tmin.y*16, -door_height[3]*8+32+3*8+tmin.y*8,40,59,doors_type*40,0);
|
|
}
|
|
|
|
// RUTINES DE PINTAT DE LA PORTA DE DALT A LA ESQUERRA
|
|
if (doors & DOOR_XN)
|
|
{
|
|
// Si la porta està elevada, pintar la part frontal de baix de la porta
|
|
if (door_height[1] > 0) {
|
|
draw::setSource(walls_surf);
|
|
draw::draw(148+tmin.x*16-3*16, (36+tmin.x*8+3*8)+(5-door_height[1])*8, 16, 48-(5-door_height[1])*8, walldoors_type*16, (5-door_height[1])*8, DRAW_FLIP_HORIZONTAL);
|
|
draw::draw(148+tmin.x*16-4*16, (36+tmin.x*8+4*8)+(5-door_height[1])*8, 16, 48-(5-door_height[1])*8, walldoors_type*16, (5-door_height[1])*8, DRAW_FLIP_HORIZONTAL);
|
|
}
|
|
|
|
// Pintem els dos tiles baix de la porta
|
|
draw::setSource(walls_surf);
|
|
draw::draw(164+(tmin.x-1)*16-5*16, -door_height[1]*8+84+(tmin.x-1)*8+4*8, 16, 15, walls_type*16, 33); // Vora
|
|
draw::setSource(floor_surf);
|
|
draw::draw(148+(tmin.x-1)*16-3*16, -door_height[1]*8+76+(tmin.x-1)*8+3*8,32,15,floor_type*32,1);
|
|
draw::draw(148+(tmin.x-1)*16-4*16, -door_height[1]*8+76+(tmin.x-1)*8+4*8,32,15,floor_type*32,1);
|
|
|
|
// Pintem la porta
|
|
draw::setSource(doors_surf);
|
|
draw::draw(164+(tmin.x-1)*16-4*16-8, -door_height[1]*8+32+3*8+9+(tmin.x-1)*8, 40,59, doors_type*40,0, DRAW_FLIP_HORIZONTAL);
|
|
}
|
|
|
|
draw::setSource(walls_surf);
|
|
for (int x=tmin.x;x<=tmax.x;++x)
|
|
{
|
|
// Si hi ha porta en YP i està a altura 0, no pintem la vorera en eixos dos tiles
|
|
if ( !(doors & DOOR_YP) || (door_height[2] != 0) || (x!=3 && x!=4) ) draw::draw(148+x*16-tmax.y*16,84+x*8+tmax.y*8,16,15,walls_type*16, 33);
|
|
|
|
// Si hi ha porta en YN, no pintem la pared en eixos dos tiles
|
|
if ( !(doors & DOOR_YN) || (x!=3 && x!=4) ) draw::draw(164+x*16-tmin.y*16,36+x*8+tmin.y*8,16,48,walls_type*16, 0);
|
|
}
|
|
|
|
for (int y=tmin.y;y<=tmax.y;++y)
|
|
{
|
|
draw::setSource(walls_surf);
|
|
// Si hi ha porta en XP i està a altura 0, no pintem la vorera en eixos dos tiles
|
|
if ( !(doors & DOOR_XP) || (door_height[0] != 0) || (y!=3 && y!=4) ) draw::draw(164+tmax.x*16-y*16,84+tmax.x*8+y*8,16,15,walls_type*16, 33, DRAW_FLIP_HORIZONTAL);
|
|
|
|
// Si hi ha porta en XN, no pintem la pared en eixos dos tiles
|
|
if ( !(doors & DOOR_XN) || (y!=3 && y!=4) ) draw::draw(148+tmin.x*16-y*16,36+tmin.x*8+y*8,16,48,walls_type*16,0, DRAW_FLIP_HORIZONTAL);
|
|
|
|
// Pintem tots els tiles del piso
|
|
draw::setSource(floor_surf);
|
|
for (int x=tmin.x;x<=tmax.x;++x)
|
|
{
|
|
draw::draw(148+x*16-y*16,76+x*8+y*8,32,15,floor_type*32,1);
|
|
}
|
|
}
|
|
draw::popSource();
|
|
}
|
|
|
|
void draw2()
|
|
{
|
|
draw::pushSource();
|
|
draw::swapcol(1, color);
|
|
|
|
if (doors & DOOR_YP)
|
|
{
|
|
// Pintem les voreres dels dos tiles extra per a la porta YP
|
|
draw::setSource(walls_surf);
|
|
draw::draw(164+4*16-(tmax.y+1)*16, -door_height[2]*8+84+4*8+(tmax.y+1)*8, 16, 15+door_height[2]*8, walldoors_type*16, 1, DRAW_FLIP_HORIZONTAL);
|
|
draw::draw(148+3*16-(tmax.y+1)*16, -door_height[2]*8+84+3*8+(tmax.y+1)*8, 16, 15+door_height[2]*8, walldoors_type*16, 1);
|
|
draw::draw(148+4*16-(tmax.y+1)*16, -door_height[2]*8+84+4*8+(tmax.y+1)*8, 16, 15+door_height[2]*8, walldoors_type*16, 1);
|
|
|
|
draw::setSource(aux_surf);
|
|
draw::draw(164+4*16-(tmax.y+1)*16, 91+4*8+(tmax.y+1)*8, 16, 8, 16, 0);
|
|
draw::draw(148+3*16-(tmax.y+1)*16, 91+3*8+(tmax.y+1)*8, 16, 8, 0, 0);
|
|
draw::draw(148+4*16-(tmax.y+1)*16, 91+4*8+(tmax.y+1)*8, 16, 8, 0, 0);
|
|
|
|
// Pintem la porta YP
|
|
draw::setSource(doors_surf);
|
|
draw::draw(164+3*16-8-(tmax.y+1)*16, -door_height[2]*8+32+3*8+4+(tmax.y+1)*8,40,59,doors_type*40,0);
|
|
}
|
|
if (doors & DOOR_XP)
|
|
{
|
|
// Pintem les voreres dels dos tiles extra per a la porta XP
|
|
draw::setSource(walls_surf);
|
|
draw::draw(148+(tmax.x+1)*16-4*16, -door_height[0]*8+84+(tmax.x+1)*8+4*8,16,15+door_height[0]*8,walldoors_type*16, 1);
|
|
draw::draw(164+(tmax.x+1)*16-3*16, -door_height[0]*8+84+(tmax.x+1)*8+3*8,16,15+door_height[0]*8,walldoors_type*16, 1, DRAW_FLIP_HORIZONTAL);
|
|
draw::draw(164+(tmax.x+1)*16-4*16, -door_height[0]*8+84+(tmax.x+1)*8+4*8,16,15+door_height[0]*8,walldoors_type*16, 1, DRAW_FLIP_HORIZONTAL);
|
|
|
|
draw::setSource(aux_surf);
|
|
draw::draw(148+(tmax.x+1)*16-4*16, 91+(tmax.x+1)*8+4*8,16,8,0,0);
|
|
draw::draw(164+(tmax.x+1)*16-3*16, 91+(tmax.x+1)*8+3*8,16,8,16,0);
|
|
draw::draw(164+(tmax.x+1)*16-4*16, 91+(tmax.x+1)*8+4*8,16,8,16,0);
|
|
|
|
// Pintem la porta XP
|
|
draw::setSource(doors_surf);
|
|
draw::draw( 164+(tmax.x+1)*16-4*16-16, -door_height[0]*8+32+3*8+4+(tmax.x+1)*8, 40,59, doors_type*40,0, DRAW_FLIP_HORIZONTAL);
|
|
}
|
|
draw::popSource();
|
|
}
|
|
|
|
vec3_t getSize()
|
|
{
|
|
return size;
|
|
}
|
|
|
|
vec3_t getMin()
|
|
{
|
|
return min;
|
|
}
|
|
|
|
vec3_t getMax()
|
|
{
|
|
return max;
|
|
}
|
|
|
|
uint8_t getDoors()
|
|
{
|
|
return doors;
|
|
}
|
|
|
|
uint8_t getDoor(const int d)
|
|
{
|
|
return door_height[d];
|
|
}
|
|
|
|
uint8_t getColor()
|
|
{
|
|
return color;
|
|
}
|
|
|
|
namespace editor
|
|
{
|
|
static bool room_exists[256];
|
|
|
|
int &refWidth() { return inner_w; }
|
|
int &refHeight() { return inner_h; }
|
|
|
|
int &refDoor(const int which) { return door_height[which]; }
|
|
|
|
int &refColor() { return color; }
|
|
int &refFloorTex() { return floor_type; }
|
|
int &refWallTex() { return walls_type; }
|
|
int &refDoorTex() { return doors_type; }
|
|
int &refWallDoorTex() { return walldoors_type; }
|
|
|
|
int &refExit(const int which) { return exits[which]; }
|
|
|
|
bool roomExists(const int which) { return room_exists[which]; }
|
|
|
|
void updateRoomList()
|
|
{
|
|
for (int room=0; room<64; ++room)
|
|
{
|
|
char filename[] = "rooms/00.txt";
|
|
filename[6] = int(room/10)+48;
|
|
filename[7] = (room%10)+48;
|
|
room_exists[room] = (file::fileExists(filename));
|
|
};
|
|
}
|
|
|
|
int getCurrentRoom() { return current_room; }
|
|
|
|
const char *numToColor(uint8_t value)
|
|
{
|
|
const char* colors[7] = {"blue", "red", "purple", "green", "cyan", "yellow", "white"};
|
|
return colors[value-5];
|
|
}
|
|
|
|
void modify() { modified = true; }
|
|
|
|
void save()
|
|
{
|
|
char filename[] = "data/rooms/00.txt";
|
|
filename[6] = int(current_room/10)+48;
|
|
filename[7] = (current_room%10)+48;
|
|
FILE *f = fopen(filename, "w");
|
|
|
|
fprintf(f, "width: %i\n", inner_w);
|
|
fprintf(f, "height: %i\n", inner_h);
|
|
fprintf(f, "door-height-xp: %i\n", door_height[XP]);
|
|
fprintf(f, "door-height-xn: %i\n", door_height[XN]);
|
|
fprintf(f, "door-height-yp: %i\n", door_height[YP]);
|
|
fprintf(f, "door-height-yn: %i\n", door_height[YN]);
|
|
|
|
fprintf(f, "color: %s\n", numToColor(color));
|
|
fprintf(f, "floor-texture: %i\n", floor_type);
|
|
fprintf(f, "wall-texture: %i\n", walls_type);
|
|
fprintf(f, "door-texture: %i\n", doors_type);
|
|
fprintf(f, "under-door-texture: %i\n", walldoors_type);
|
|
|
|
fprintf(f, "exit-xp: %i\n", exits[XP]);
|
|
fprintf(f, "exit-xn: %i\n", exits[XN]);
|
|
fprintf(f, "exit-yp: %i\n", exits[YP]);
|
|
fprintf(f, "exit-yn: %i\n", exits[YN]);
|
|
fprintf(f, "exit-zp: %i\n", exits[ZP]);
|
|
fprintf(f, "exit-zn: %i\n", exits[ZN]);
|
|
|
|
actor::actor_t *act = actor::getFirst();
|
|
while (act)
|
|
{
|
|
actor::saveToFile(f, act);
|
|
act = act->next;
|
|
}
|
|
|
|
fclose(f);
|
|
modified = false;
|
|
}
|
|
}
|
|
|
|
}
|