diff --git a/common.mk b/common.mk index dc935f0..efa035b 100644 --- a/common.mk +++ b/common.mk @@ -2,17 +2,18 @@ VERSION = 0.1 REVISION = $(shell git rev-list HEAD 2>/dev/null | wc -l) LOCALE_MO = $(patsubst %.po,%.mo,$(wildcard locale/*.po)) -SEARCHPATH += src src/game src/system src/util +SEARCHPATH += src src/game src/system src/util src/world vpath %.c $(SEARCHPATH) vpath %.h $(SEARCHPATH) DEPS += defs.h structs.h +OBJS += camera.o OBJS += draw.o OBJS += game.o OBJS += init.o input.o io.o OBJS += lookup.o -OBJS += main.o maths.o +OBJS += main.o map.o maths.o OBJS += text.o textures.o title.o OBJS += util.o diff --git a/src/defs.h b/src/defs.h index a871cd6..21e5ceb 100644 --- a/src/defs.h +++ b/src/defs.h @@ -58,6 +58,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NUM_TEXTURE_BUCKETS 32 +#define MAP_WIDTH 200 +#define MAP_HEIGHT 200 + +#define MAP_TILE_SIZE 64 +#define MAP_TILE_AIR 0 +#define MAP_TILE_WATER 1 +#define MAP_TILE_SLIME 2 +#define MAP_TILE_LAVA 3 +#define MAP_TILE_SOLID 4 +#define MAP_TILE_NON_SOLID 200 +#define MAP_TILE_ANIMATED_WATER 240 +#define MAP_TILE_ANIMATED_SLIME 245 +#define MAP_TILE_ANIMATED_LAVA 250 +#define MAP_TILE_OUTSIDE 255 +#define MAP_TILE_MAX 256 + enum { CONTROL_LEFT, diff --git a/src/main.h b/src/main.h index b956343..1b2c175 100644 --- a/src/main.h +++ b/src/main.h @@ -30,6 +30,8 @@ extern void presentScene(void); extern void initTitle(void); App app; +Camera camera; Colors colors; Dev dev; Game game; +World world; diff --git a/src/structs.h b/src/structs.h index 11a2b4b..2fe14e9 100644 --- a/src/structs.h +++ b/src/structs.h @@ -74,8 +74,17 @@ typedef struct { struct Entity { float x; float y; + int w; + int h; }; +typedef struct { + SDL_Rect bounds; + float shakeAmount; + int x; + int y; +} Camera; + typedef struct { int x; int y; @@ -112,3 +121,13 @@ typedef struct { typedef struct { long timePlayed; } Game; + +typedef struct { + int data[MAP_WIDTH][MAP_HEIGHT]; + int decal[MAP_WIDTH][MAP_HEIGHT]; + SDL_Rect bounds; +} Map; + +typedef struct { + Map map; +} World; diff --git a/src/util/maths.c b/src/util/maths.c index 6efd80c..7a762bd 100644 --- a/src/util/maths.c +++ b/src/util/maths.c @@ -35,6 +35,21 @@ int getPercent(float current, float total) return (current / total) * 100; } +float limit(float i, float a, float b) +{ + if (i > a) + { + return a; + } + + if (i < b) + { + return b; + } + + return i; +} + int getDistance(int x1, int y1, int x2, int y2) { int x, y; diff --git a/src/world/camera.c b/src/world/camera.c new file mode 100644 index 0000000..21b528b --- /dev/null +++ b/src/world/camera.c @@ -0,0 +1,96 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "camera.h" + +static void clip(void); + +void cameraTrack(Entity *e) +{ + camera.x = (int) e->x + e->w / 2; + camera.y = (int) e->y + e->h / 2; + + camera.x -= (SCREEN_WIDTH / 2); + camera.y -= (SCREEN_HEIGHT / 2); + + clip(); +} + +float cameraChase(Entity *e, int maxSpeed) +{ + float x, y, tx, ty, diffX, diffY, dist; + + x = camera.x; + y = camera.y; + + tx = e->x - (SCREEN_WIDTH / 2); + ty = e->y - (SCREEN_HEIGHT / 2); + + diffX = abs(tx - x); + diffY = abs(ty - y); + + dist = MAX(diffX, diffY); + + diffX /= 20; + diffY /= 20; + + diffX = MAX(0, MIN(maxSpeed, diffX)); + diffY = MAX(0, MIN(maxSpeed, diffY)); + + if (x > tx) + { + x -= diffX; + } + + if (x < tx) + { + x += diffX; + } + + if (y > ty) + { + y -= diffY; + } + + if (y < ty) + { + y += diffY; + } + + camera.x = (int) x; + camera.y = (int) y; + + clip(); + + return dist; +} + +void clip(void) +{ + camera.bounds.x = (int) limit(camera.x, world.map.bounds.x, world.map.bounds.w); + camera.bounds.y = (int) limit(camera.y, world.map.bounds.y, world.map.bounds.h + (MAP_TILE_SIZE * 3)); + camera.bounds.w = SCREEN_WIDTH; + camera.bounds.h = SCREEN_HEIGHT; +} + +int isOnScreen(Entity *e) +{ + return (e->x >= camera.x && e->y >= camera.y && e->x < camera.x + SCREEN_WIDTH && e->y < camera.y + SCREEN_HEIGHT); +} diff --git a/src/world/camera.h b/src/world/camera.h new file mode 100644 index 0000000..4cb59aa --- /dev/null +++ b/src/world/camera.h @@ -0,0 +1,26 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "../common.h" + +extern float limit(float i, float a, float b); + +extern Camera camera; +extern World world; diff --git a/src/world/map.c b/src/world/map.c new file mode 100644 index 0000000..5e4ec53 --- /dev/null +++ b/src/world/map.c @@ -0,0 +1,147 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "map.h" + +static int animTimer; + +void initMap(void) +{ + memset(&world.map, 0, sizeof(Map)); + + world.map.bounds.x = MAP_WIDTH * MAP_TILE_SIZE; + world.map.bounds.y = MAP_HEIGHT * MAP_TILE_SIZE; + world.map.bounds.w = 0; + world.map.bounds.h = 0; + + animTimer = 0; +} + +void animateMap(void) +{ + if (--animTimer < 0) + { + animTimer = 4; + } +} + +int isWithinMap(int x, int y) +{ + return (x >= 0 && y >= 0 && x < MAP_WIDTH && y < MAP_HEIGHT); +} + +int isSolid(int x, int y) +{ + if (!isWithinMap(x, y)) + { + return 1; + } + + if ((world.map.data[x][y] >= MAP_TILE_SOLID) && (world.map.data[x][y] < MAP_TILE_NON_SOLID)) + { + return 1; + } + + return 0; +} + +void addBloodDecal(int x, int y) +{ + if (isSolid(x, y) && world.map.decal[x][y] == 0) + { + world.map.decal[x][y] = (int) rrnd(1, 4); + } +} + +void addScorchDecal(int x, int y) +{ + if (isSolid(x, y) && world.map.decal[x][y] == 0) + { + world.map.decal[x][y] = (int) rrnd(5, 8); + } +} + +int isLiquid(int x, int y) +{ + return isWithinMap(x, y) && world.map.data[x][y] > MAP_TILE_AIR && world.map.data[x][y] < MAP_TILE_SOLID; +} + +int isWalkable(int x, int y) +{ + return isSolid(x, y); +} + +int isBreakable(int x, int y) +{ + return 0; +} + +void calculateMapBounds(void) +{ + int x, y; + + for (y = 0 ; y < MAP_HEIGHT; y++) + { + for (x = 0 ; x < MAP_WIDTH; x++) + { + if (world.map.data[x][y] != 0) + { + if (x < world.map.bounds.x) + { + world.map.bounds.x = x; + } + + if (x > world.map.bounds.w) + { + world.map.bounds.w = x; + } + + if (y < world.map.bounds.y) + { + world.map.bounds.y = y; + } + + if (y > world.map.bounds.h) + { + world.map.bounds.h = y; + } + } + } + } + + if (world.map.bounds.h - RENDER_HEIGHT < world.map.bounds.y) + { + world.map.bounds.y = 0; + } + + world.map.bounds.x = (int) limit(world.map.bounds.x, 0, MAP_WIDTH - RENDER_WIDTH); + world.map.bounds.y = (int) limit(world.map.bounds.y, 0, MAP_HEIGHT - RENDER_HEIGHT); + + world.map.bounds.x *= MAP_TILE_SIZE; + world.map.bounds.y *= MAP_TILE_SIZE; + world.map.bounds.w *= MAP_TILE_SIZE; + world.map.bounds.h *= MAP_TILE_SIZE; + + world.map.bounds.w -= SCREEN_WIDTH; + world.map.bounds.h -= SCREEN_HEIGHT; + + world.map.bounds.w += MAP_TILE_SIZE; + world.map.bounds.h += MAP_TILE_SIZE; +} diff --git a/src/world/map.h b/src/world/map.h new file mode 100644 index 0000000..2360875 --- /dev/null +++ b/src/world/map.h @@ -0,0 +1,29 @@ +/* +Copyright (C) 2018 Parallel Realities + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "../common.h" + +#define RENDER_WIDTH ((SCREEN_WIDTH / MAP_TILE_SIZE) + 1) +#define RENDER_HEIGHT ((SCREEN_HEIGHT / MAP_TILE_SIZE) + 1) + +extern float limit(float i, float a, float b); +extern int rrnd(int low, int high); + +extern World world;