changeset 50:402aa7dcffe1

core: implement map origin, closes #2462 @1h
author David Demelier <markand@malikania.fr>
date Fri, 17 Jan 2020 12:59:11 +0100
parents a8c7db56ccb0
children 151b0be0d2ac
files Makefile assets/maps/test.map src/map.c src/map.h src/map_state.c tools/molko-map.c
diffstat 6 files changed, 697 insertions(+), 627 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Jan 17 12:09:30 2020 +0100
+++ b/Makefile	Fri Jan 17 12:59:11 2020 +0100
@@ -19,7 +19,7 @@
 .POSIX:
 
 CC=             gcc
-CFLAGS=         -MMD -O3 -DNDEBUG -std=c18 -Wall -Wextra -g
+CFLAGS=         -MMD -O0 -DNDEBUG -std=c18 -Wall -Wextra -g
 PROG=           molko
 LIB=            libmolko.a
 SRCS=           src/animation.c \
--- a/assets/maps/test.map	Fri Jan 17 12:09:30 2020 +0100
+++ b/assets/maps/test.map	Fri Jan 17 12:59:11 2020 +0100
@@ -1,4 +1,5 @@
 title|World
+origin|700|400
 width|100
 height|100
 tilewidth|32
@@ -10717,610 +10718,610 @@
 0
 0
 0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
-0
+407
+408
+409
+410
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+437
+438
+439
+440
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+467
+468
+469
+470
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+497
+498
+499
+500
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+527
+528
+529
+530
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+557
+558
+559
+560
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+587
+588
+589
+590
 0
 0
 0
--- a/src/map.c	Fri Jan 17 12:09:30 2020 +0100
+++ b/src/map.c	Fri Jan 17 12:59:11 2020 +0100
@@ -96,6 +96,8 @@
 		sscanf(line, "tilewidth|%hu", &map->tilewidth);
 	else if (strncmp(line, "tileheight", 10) == 0)
 		sscanf(line, "tileheight|%hu", &map->tileheight);
+	else if (strncmp(line, "origin", 6) == 0)
+		sscanf(line, "origin|%d|%d", &map->origin_x, &map->origin_y);
 	else if (strncmp(line, "tileset", 7) == 0)
 		parse_tileset(map, line);
 	else if (strncmp(line, "layer", 5) == 0)
--- a/src/map.h	Fri Jan 17 12:09:30 2020 +0100
+++ b/src/map.h	Fri Jan 17 12:59:11 2020 +0100
@@ -44,12 +44,17 @@
 
 /**
  * \brief Map object.
+ *
+ * This structure only defines the map characteristics. It does not have any
+ * logic and is left for game state.
  */
 struct map {
 	char title[MAP_TITLE_MAX];      /*!< (RW) The map title */
 	struct texture *tileset;        /*!< (RW) Tileset to use */
 	struct texture *picture;        /*!< (RO) Map drawn into a picture */
 	struct sprite sprite;           /*!< (RO) Sprite to render */
+	int origin_x;                   /*!< (RO) Where the player starts in X */
+	int origin_y;                   /*!< (RO) Where the player starts in Y */
 	unsigned int width;             /*!< (RO) Map width in cells */
 	unsigned int height;            /*!< (RO) Map height in cells */
 	unsigned short tilewidth;       /*!< (RO) Pixels per cell (width) */
--- a/src/map_state.c	Fri Jan 17 12:09:30 2020 +0100
+++ b/src/map_state.c	Fri Jan 17 12:59:11 2020 +0100
@@ -192,7 +192,7 @@
 				data.view_x = map_w - view_w;
 		}
 
-		if (data.player_x > map_w - 48)
+		if (data.player_x > (int)map_w - 48)
 			data.player_x = map_w - 48;
 	} else if (dx < 0) {
 		data.player_x -= delta;
@@ -218,7 +218,7 @@
 				data.view_y = map_h - view_h;
 		}
 
-		if (data.player_y > map_h - 48)
+		if (data.player_y > (int)map_h - 48)
 			data.player_y = map_h - 48;
 	} else if (dy < 0) {
 		data.player_y -= delta;
@@ -269,11 +269,38 @@
 	painter_present();
 }
 
+static void
+center(void)
+{
+	/* This is map size. */
+	const unsigned int win_w = window_width();
+	const unsigned int win_h = window_height();
+	const unsigned int map_w = texture_width(data.map.picture);
+	const unsigned int map_h = texture_height(data.map.picture);
+
+	data.view_x = data.player_x - (win_w / 2);
+	data.view_y = data.player_y - (win_h / 2);
+
+	if (data.view_x < 0)
+		data.view_x = 0;
+	else if (data.view_x > (int)(map_w - win_w))
+		data.view_x = map_w - win_w;
+
+	if (data.view_y < 0)
+		data.view_y = 0;
+	else if (data.view_y > (int)(map_h - win_h))
+		data.view_y = map_h - win_h;
+}
+
 void
 map_state_start(struct map *map, struct sprite *s)
 {
+	/* Copy essential. */
 	data.map = *map;
+	data.player_x = map->origin_x;
+	data.player_y = map->origin_y;
 
+	center();
 	walksprite_init(&data.player_sprite, s, 250);
 	game_switch(&map_state);
 }
--- a/tools/molko-map.c	Fri Jan 17 12:09:30 2020 +0100
+++ b/tools/molko-map.c	Fri Jan 17 12:59:11 2020 +0100
@@ -47,29 +47,64 @@
 	       strcmp(name, "objects") == 0;
 }
 
+const json_t *
+find_property(const json_t *props, const char *which)
+{
+	json_t *value;
+	size_t index;
+
+	json_array_foreach(props, index, value) {
+		if (!json_is_object(value))
+			continue;
+
+		const json_t *key = json_object_get(value, "name");
+
+		if (json_is_string(key) && strcmp(json_string_value(key), which) == 0)
+			return value;
+	}
+
+	return NULL;
+}
+
+static void
+write_title(const json_t *props)
+{
+	const json_t *prop_title = find_property(props, "title");
+
+	if (!prop_title)
+		return;
+
+	const json_t *title = json_object_get(prop_title, "value");
+
+	if (title && json_is_string(title))
+		printf("title|%s\n", json_string_value(title));
+}
+
+static void
+write_origin(const json_t *props)
+{
+	const json_t *prop_origin_x = find_property(props, "origin-x");
+	const json_t *prop_origin_y = find_property(props, "origin-y");
+
+	if (!prop_origin_x || !prop_origin_y)
+		return;
+
+	const json_t *origin_x = json_object_get(prop_origin_x, "value");
+	const json_t *origin_y = json_object_get(prop_origin_y, "value");
+
+	if (!origin_x || !json_is_integer(origin_x) ||
+	    !origin_y || !json_is_integer(origin_y))
+		return;
+
+	printf("origin|%lld|%lld\n", json_integer_value(origin_x),
+	    json_integer_value(origin_y));
+}
+
 static void
 write_properties(const json_t *props)
 {
-	size_t index;
-	json_t *prop, *name, *type, *value;
-
-	if (!json_is_array(props))
-		return;
-
-	json_array_foreach(props, index, prop) {
-		name = json_object_get(prop, "name");
-		type = json_object_get(prop, "type");
-		value = json_object_get(prop, "value");
-
-		if (!json_is_object(prop) ||
-		    !json_is_string(name) ||
-		    !json_is_string(type) ||
-		    !json_is_string(value))
-			die("invalid property\n");
-
-		printf("%s|%s\n", json_string_value(name),
-		    json_string_value(value));
-	}
+	write_title(props);
+	write_origin(props);
 }
 
 static void