main: add warp events
You can now walk from pallet town to the mount moon exit.
This commit is contained in:
parent
e6cae1c242
commit
e1a430abec
2
Makefile
2
Makefile
@ -9,6 +9,8 @@ GEN_SRC =
|
||||
GEN_SRC += gen/maps.cpp
|
||||
GEN_SRC += gen/map_objects.cpp
|
||||
GEN_SRC += gen/sprites.cpp
|
||||
GEN_SRC += gen/tilesets.cpp
|
||||
GEN_SRC += gen/collision_tile_ids.cpp
|
||||
|
||||
SRC =
|
||||
SRC += $(GEN_SRC)
|
||||
|
54
actor.hpp
54
actor.hpp
@ -14,21 +14,27 @@ struct actor_t
|
||||
world_t world;
|
||||
enum direction facing;
|
||||
bool moving;
|
||||
bool collision;
|
||||
uint8_t frame;
|
||||
uint8_t cycle;
|
||||
|
||||
constexpr inline offset_t offset()
|
||||
{
|
||||
switch (facing) {
|
||||
case left:
|
||||
return {-frame, 0};
|
||||
case right:
|
||||
return {frame, 0};
|
||||
case up:
|
||||
return {0, -frame};
|
||||
case down:
|
||||
return {0, frame};
|
||||
default:
|
||||
if (collision) {
|
||||
return {0, 0};
|
||||
} else {
|
||||
switch (facing) {
|
||||
case left:
|
||||
return {-frame, 0};
|
||||
case right:
|
||||
return {frame, 0};
|
||||
case up:
|
||||
return {0, -frame};
|
||||
case down:
|
||||
return {0, frame};
|
||||
default:
|
||||
return {0, 0};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,19 +43,24 @@ struct actor_t
|
||||
{
|
||||
if (!moving) return;
|
||||
|
||||
if (++frame == 16) {
|
||||
moving = false;
|
||||
frame = frame + 1;
|
||||
if (frame == 16) {
|
||||
cycle += 1;
|
||||
frame = 0;
|
||||
switch (facing) {
|
||||
case left: world.x--; break;
|
||||
case right: world.x++; break;
|
||||
case up: world.y--; break;
|
||||
case down: world.y++; break;
|
||||
if (!collision) {
|
||||
switch (facing) {
|
||||
case left: world.x--; break;
|
||||
case right: world.x++; break;
|
||||
case up: world.y--; break;
|
||||
case down: world.y++; break;
|
||||
}
|
||||
}
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline void move(enum direction dir)
|
||||
constexpr inline void move(enum direction dir,
|
||||
bool collision)
|
||||
{
|
||||
/*
|
||||
m 1 . 2 . 3 . 4 .
|
||||
@ -57,10 +68,11 @@ struct actor_t
|
||||
|
||||
*/
|
||||
|
||||
if (moving) return;
|
||||
|
||||
frame = 0;
|
||||
if (!(this->collision) && moving) return;
|
||||
if (!collision)
|
||||
frame = 0;
|
||||
facing = dir;
|
||||
moving = true;
|
||||
this->collision = collision;
|
||||
}
|
||||
};
|
||||
|
@ -14,13 +14,13 @@ struct offset_t { // in pixels
|
||||
int32_t y;
|
||||
};
|
||||
|
||||
struct world_t;
|
||||
|
||||
struct block_t {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
};
|
||||
|
||||
struct world_t;
|
||||
|
||||
struct screen_t {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
|
210
main.cpp
210
main.cpp
@ -88,11 +88,12 @@ struct draw_t {
|
||||
|
||||
struct state_t {
|
||||
enum map_t::map map;
|
||||
enum map_t::map last_map;
|
||||
draw_t draw;
|
||||
actor_t player;
|
||||
};
|
||||
} __attribute__ ((aligned (4)));
|
||||
|
||||
static state_t state = { map_t::pallet_town, 0 };
|
||||
static state_t state = { map_t::pallet_town, map_t::last_map, 0 };
|
||||
|
||||
uint32_t load_tileset(uint32_t top, enum tileset_t::tileset tileset)
|
||||
{
|
||||
@ -132,12 +133,41 @@ void load_vram()
|
||||
vdp1_top = load_sprite(vdp1_top, static_cast<enum spritesheet_t::spritesheet>(i));
|
||||
}
|
||||
|
||||
void render_sprite(const uint32_t ix, const uint32_t sprite_id, const screen_t& screen, const offset_t& offset)
|
||||
static inline uint32_t facing_offset(const actor_t::direction facing)
|
||||
{
|
||||
switch (facing) {
|
||||
default: [[fallthrough]];
|
||||
case actor_t::down: return 0;
|
||||
case actor_t::up: return 1;
|
||||
case actor_t::left: return 2;
|
||||
case actor_t::right: return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t facing_inverted(const actor_t::direction facing, const uint32_t animation_cycle)
|
||||
{
|
||||
switch (facing) {
|
||||
default: [[fallthrough]];
|
||||
case actor_t::down: [[fallthrough]];
|
||||
case actor_t::up:
|
||||
return (animation_cycle & 1) ? CTRL__DIR__INVERTED_HORIZONTALLY : CTRL__DIR__NOT_INVERTED;
|
||||
case actor_t::left:
|
||||
return CTRL__DIR__NOT_INVERTED;
|
||||
case actor_t::right:
|
||||
return CTRL__DIR__INVERTED_HORIZONTALLY;
|
||||
}
|
||||
}
|
||||
|
||||
void render_sprite(const uint32_t ix, const uint32_t sprite_id,
|
||||
const enum actor_t::direction facing, const uint32_t animation_frame, const uint32_t animation_cycle,
|
||||
const screen_t& screen, const offset_t& offset)
|
||||
{
|
||||
constexpr uint32_t color_address = 0;
|
||||
const uint32_t character_address = (state.draw.base_pattern.spritesheets[sprite_id] * 128) / 8;
|
||||
const uint32_t sprite_offset = facing_offset(facing) + animation_frame;
|
||||
const uint32_t base_pattern = state.draw.base_pattern.spritesheets[sprite_id];
|
||||
const uint32_t character_address = ((base_pattern + sprite_offset) * 128) / 8;
|
||||
|
||||
vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__NORMAL_SPRITE;
|
||||
vdp1.vram.cmd[ix].CTRL = CTRL__JP__JUMP_NEXT | CTRL__COMM__NORMAL_SPRITE | facing_inverted(facing, animation_cycle);
|
||||
vdp1.vram.cmd[ix].LINK = 0;
|
||||
// The "end code" is 0xf, which is being used in the mai sprite palette. If
|
||||
// both transparency and end codes are enabled, it seems there are only 14
|
||||
@ -157,7 +187,12 @@ void render_sprites(const offset_t& offset)
|
||||
{
|
||||
uint32_t ix = 2;
|
||||
|
||||
render_sprite(ix, spritesheet_t::red, {4, 4}, {0, 0});
|
||||
const uint32_t animation_frame = ((state.player.frame & 0b1000) != 0) * 3;
|
||||
render_sprite(ix,
|
||||
spritesheet_t::red,
|
||||
state.player.facing, animation_frame, state.player.cycle,
|
||||
{4, 4},
|
||||
{0, 0});
|
||||
ix++;
|
||||
|
||||
const object_t& obj = map_objects[state.map];
|
||||
@ -166,6 +201,7 @@ void render_sprites(const offset_t& offset)
|
||||
const world_t world = { event.position.x, event.position.y };
|
||||
render_sprite(ix,
|
||||
event.sprite_id,
|
||||
actor_t::down, 0, 0,
|
||||
world.to_screen(state.player.world),
|
||||
offset);
|
||||
ix++;
|
||||
@ -220,22 +256,153 @@ void render_map()
|
||||
vdp2.reg.BGON = BGON__N0ON | BGON__N0TPON;
|
||||
}
|
||||
|
||||
constexpr inline world_t direction_offset(const world_t& world, const enum actor_t::direction dir)
|
||||
{
|
||||
switch (dir) {
|
||||
default: [[fallthrough]];
|
||||
case actor_t::up: return {world.x , world.y - 1};
|
||||
case actor_t::down: return {world.x , world.y + 1};
|
||||
case actor_t::left: return {world.x - 1, world.y };
|
||||
case actor_t::right: return {world.x + 1, world.y };
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline bool collision(const map_t& map,
|
||||
const world_t& world,
|
||||
enum actor_t::direction dir)
|
||||
{
|
||||
const world_t coord = direction_offset(world, dir);
|
||||
// keep this synchronized with render_screen()
|
||||
const uint8_t block_ix = get_block(map, coord.to_block());
|
||||
const tileset_t& tileset = tilesets[map.tileset];
|
||||
const uint8_t * block_start = &(tileset.blockset.start)[block_ix * 4 * 4];
|
||||
const int32_t quadrant_x = 2 * (coord.x & 1);
|
||||
const int32_t quadrant_y = 2 * (coord.y & 1);
|
||||
|
||||
const int32_t block_row = 4 * (quadrant_y + 1);
|
||||
const uint8_t tile_ix = block_start[block_row + quadrant_x];
|
||||
|
||||
for (uint32_t i = 0; i < tileset.collision.size; i++) {
|
||||
if (tileset.collision.start[i] == tile_ix)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void change_maps()
|
||||
{
|
||||
const map_t& map = maps[state.map];
|
||||
|
||||
#define _has(_dir_) (map.connections[map_t::connection_t::_dir_].map != map_t::unconnected)
|
||||
#define _get(_dir_) (maps[map.connections[map_t::connection_t::_dir_].map])
|
||||
#define _offset(_dir_) (map.connections[map_t::connection_t::_dir_].offset)
|
||||
|
||||
const block_t block = state.player.world.to_block();
|
||||
if (block.y < 0) {
|
||||
// north
|
||||
if (_has(north)) {
|
||||
const map_t& north_map = _get(north);
|
||||
state.player.world.y = ((north_map.height + block.y) << 1) | (state.player.world.y & 1);
|
||||
state.player.world.x = ((block.x - _offset(north)) << 1) | (state.player.world.x & 1);
|
||||
state.map = map.connections[map_t::connection_t::north].map;
|
||||
}
|
||||
} else if (block.y >= static_cast<int32_t>(map.height)) {
|
||||
// south
|
||||
if (_has(south)) {
|
||||
state.player.world.y = ((block.y - map.height) << 1) | (state.player.world.y & 1);
|
||||
state.player.world.x = ((block.x - _offset(south)) << 1) | (state.player.world.x & 1);
|
||||
state.map = map.connections[map_t::connection_t::south].map;
|
||||
}
|
||||
} else if (block.x < 0) {
|
||||
// west
|
||||
if (_has(west)) {
|
||||
const map_t& west_map = _get(west);
|
||||
state.player.world.x = ((west_map.width + block.x) << 1) | (state.player.world.x & 1);
|
||||
state.player.world.y = ((block.y - _offset(west)) << 1) | (state.player.world.y & 1);
|
||||
state.map = map.connections[map_t::connection_t::west].map;
|
||||
}
|
||||
} else if (block.x >= static_cast<int32_t>(map.width)) {
|
||||
// east
|
||||
if (_has(east)) {
|
||||
state.player.world.x = ((block.x - map.width) << 1) | (state.player.world.x & 1);
|
||||
state.player.world.y = ((block.y - _offset(east)) << 1) | (state.player.world.y & 1);
|
||||
state.map = map.connections[map_t::connection_t::east].map;
|
||||
}
|
||||
}
|
||||
|
||||
#undef _offset
|
||||
#undef _get
|
||||
#undef _has
|
||||
}
|
||||
|
||||
constexpr bool is_outside(const enum map_t::map& map_id)
|
||||
{
|
||||
const map_t& map = maps[map_id];
|
||||
switch (map.tileset) {
|
||||
case tileset_t::overworld: [[fallthrough]];
|
||||
case tileset_t::plateau:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void update_warp()
|
||||
{
|
||||
if (state.player.moving) return;
|
||||
world_t& coord = state.player.world;
|
||||
|
||||
for (uint32_t j = 0; j < map_objects[state.map].warp_length; j++) {
|
||||
const warp_event_t& warp = map_objects[state.map].warp_events[j];
|
||||
if (coord.x == warp.position.x && coord.y == warp.position.y) {
|
||||
if (warp.destination.map == map_t::last_map) {
|
||||
if (state.last_map == map_t::last_map) {
|
||||
// use last_map as a sentinel value for "the player hasn't
|
||||
// warped yet". This should never happen in normal gameplay.
|
||||
continue;
|
||||
}
|
||||
|
||||
state.map = state.last_map;
|
||||
} else {
|
||||
// Only change last_map if the current map is an "outside"
|
||||
// map. Warps that use last_map are designed to be used this
|
||||
// way.
|
||||
if (is_outside(state.map)) state.last_map = state.map;
|
||||
|
||||
state.map = warp.destination.map;
|
||||
}
|
||||
// warp_index starts at 1
|
||||
const warp_event_t& dest = map_objects[state.map].warp_events[warp.destination.warp_index - 1];
|
||||
coord.x = dest.position.x;
|
||||
coord.y = dest.position.y;
|
||||
|
||||
state.player.move(state.player.facing, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
state.player.tick();
|
||||
change_maps();
|
||||
update_warp();
|
||||
|
||||
const map_t& map = maps[state.map];
|
||||
|
||||
if (event::cursor_left()) {
|
||||
state.player.move(actor_t::left);
|
||||
//state.player.world.x--;
|
||||
const bool c = collision(map, state.player.world, actor_t::left);
|
||||
state.player.move(actor_t::left, c);
|
||||
} else if (event::cursor_right()) {
|
||||
state.player.move(actor_t::right);
|
||||
//state.player.world.x++;
|
||||
const bool c = collision(map, state.player.world, actor_t::right);
|
||||
state.player.move(actor_t::right, c);
|
||||
} else if (event::cursor_up()) {
|
||||
state.player.move(actor_t::up);
|
||||
//state.player.world.y--;
|
||||
const bool c = collision(map, state.player.world, actor_t::up);
|
||||
state.player.move(actor_t::up, c);
|
||||
} else if (event::cursor_down()) {
|
||||
state.player.move(actor_t::down);
|
||||
//state.player.world.y++;
|
||||
const bool c = collision(map, state.player.world, actor_t::down);
|
||||
state.player.move(actor_t::down, c);
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,6 +567,10 @@ void init_vdp2()
|
||||
void main()
|
||||
{
|
||||
state.map = map_t::pallet_town;
|
||||
//state.map = map_t::viridian_forest;
|
||||
//state.map = map_t::route_2;
|
||||
state.player.world.x = 6;
|
||||
state.player.world.y = 6;
|
||||
|
||||
load_vram();
|
||||
|
||||
@ -408,6 +579,17 @@ void main()
|
||||
init_vdp1();
|
||||
init_vdp2();
|
||||
|
||||
constexpr uint16_t top_x = 80 - 1;
|
||||
constexpr uint16_t top_y = 48 - 1;
|
||||
constexpr uint16_t bot_x = 239 + 1;
|
||||
constexpr uint16_t bot_y = 191 + 1;
|
||||
|
||||
vdp2.reg.WCTLA = WCTLA__N0W0E | WCTLA__N0W0A__OUTSIDE;
|
||||
vdp2.reg.WPSX0 = top_x << 1;
|
||||
vdp2.reg.WPSY0 = top_y;
|
||||
vdp2.reg.WPEX0 = bot_x << 1;
|
||||
vdp2.reg.WPEY0 = bot_y;
|
||||
|
||||
// free-running timer
|
||||
sh2.reg.TCR = TCR__CKS__INTERNAL_DIV128;
|
||||
sh2.reg.FTCSR = 0;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "map_objects.hpp"
|
||||
#include "vdp2.h"
|
||||
|
||||
static inline uint8_t get_block(const map_t& map, block_t block)
|
||||
constexpr inline uint8_t get_block(const map_t& map, block_t block)
|
||||
{
|
||||
const uint8_t border_block = map_objects[map.id].border_block;
|
||||
|
||||
@ -15,10 +15,10 @@ static inline uint8_t get_block(const map_t& map, block_t block)
|
||||
const bool y_gt = block.y >= 0;
|
||||
|
||||
const bool inside_map = x_lt && y_lt && x_gt && y_gt;
|
||||
const bool north = x_lt && x_gt && !(y_gt);
|
||||
const bool south = x_lt && x_gt && !(y_lt);
|
||||
const bool west = y_lt && y_gt && !(x_gt);
|
||||
const bool east = y_lt && y_gt && !(x_lt);
|
||||
const bool north = x_lt && x_gt && !y_gt;
|
||||
const bool south = x_lt && x_gt && !y_lt;
|
||||
const bool west = y_lt && y_gt && !x_gt;
|
||||
const bool east = y_lt && y_gt && !x_lt;
|
||||
|
||||
#define _has(_dir_) (map.connections[map_t::connection_t::_dir_].map != map_t::unconnected)
|
||||
#define _get(_dir_) (maps[map.connections[map_t::connection_t::_dir_].map])
|
||||
@ -27,11 +27,29 @@ static inline uint8_t get_block(const map_t& map, block_t block)
|
||||
if (inside_map) {
|
||||
return map.blocks.start[map.width * block.y + block.x];
|
||||
} else if (north && _has(north)) {
|
||||
map_t north_map = _get(north);
|
||||
const map_t& north_map = _get(north);
|
||||
return get_block(north_map, {
|
||||
.x = block.x - _offset(north),
|
||||
.y = static_cast<int32_t>(north_map.height + block.y),
|
||||
});
|
||||
} else if (south && _has(south)) {
|
||||
const map_t& south_map = _get(south);
|
||||
return get_block(south_map, {
|
||||
.x = block.x - _offset(south),
|
||||
.y = static_cast<int32_t>(block.y - map.height),
|
||||
});
|
||||
} else if (west && _has(west)) {
|
||||
const map_t& west_map = _get(west);
|
||||
return get_block(west_map, {
|
||||
.x = static_cast<int32_t>(west_map.width + block.x),
|
||||
.y = block.y - _offset(west),
|
||||
});
|
||||
} else if (east && _has(east)) {
|
||||
const map_t& east_map = _get(east);
|
||||
return get_block(east_map, {
|
||||
.x = static_cast<int32_t>(block.x - map.width),
|
||||
.y = block.y - _offset(east),
|
||||
});
|
||||
} else {
|
||||
return border_block;
|
||||
}
|
||||
@ -53,11 +71,10 @@ static inline void render_screen(const uint32_t base_pattern,
|
||||
const screen_t& screen)
|
||||
{
|
||||
const world_t world = screen.to_world(origin);
|
||||
const block_t block = world.to_block();
|
||||
|
||||
const uint8_t block_ix = get_block(map, block);
|
||||
const uint8_t * block_start = &(tilesets[map.tileset].blockset.start)[block_ix * 4 * 4];
|
||||
|
||||
// keep this synchronized with collision()
|
||||
const uint8_t block_ix = get_block(map, world.to_block());
|
||||
const tileset_t& tileset = tilesets[map.tileset];
|
||||
const uint8_t * block_start = &(tileset.blockset.start)[block_ix * 4 * 4];
|
||||
const int32_t quadrant_x = 2 * (world.x & 1);
|
||||
const int32_t quadrant_y = 2 * (world.y & 1);
|
||||
|
||||
|
48
tools/generate/collision_tile_ids.py
Normal file
48
tools/generate/collision_tile_ids.py
Normal file
@ -0,0 +1,48 @@
|
||||
from parse import parse
|
||||
|
||||
from generate.generate import renderer
|
||||
from generate.tilesets import sorted_tilesets_constants_list
|
||||
|
||||
def includes_header():
|
||||
yield '#include <cstdint>'
|
||||
yield ''
|
||||
|
||||
def extern_collision_tile_ids():
|
||||
for name, index in sorted_tilesets_constants_list():
|
||||
tileset_header = parse.tileset_headers_list[index]
|
||||
coll_path = tileset_header.coll()
|
||||
tile_ids = parse.collision_tile_ids_list[coll_path]
|
||||
yield f"extern uint8_t {coll_path}[{len(tile_ids)}];"
|
||||
|
||||
def generate_header():
|
||||
render, out = renderer()
|
||||
render(includes_header())
|
||||
render(extern_collision_tile_ids())
|
||||
return out
|
||||
|
||||
def collision_array(name, index):
|
||||
tileset_header = parse.tileset_headers_list[index]
|
||||
coll_path = tileset_header.coll()
|
||||
tile_ids = parse.collision_tile_ids_list[coll_path]
|
||||
yield f"uint8_t {coll_path}[] = {{"
|
||||
yield " ".join(
|
||||
f"{tile_ix},"
|
||||
for tile_ix in sorted(tile_ids)
|
||||
)
|
||||
yield "};"
|
||||
|
||||
def collision_tile_ids():
|
||||
for name, index in sorted_tilesets_constants_list():
|
||||
yield from collision_array(name, index)
|
||||
|
||||
def includes_source():
|
||||
yield '#include <cstdint>'
|
||||
yield ''
|
||||
yield '#include "collision_tile_ids.hpp"'
|
||||
yield ''
|
||||
|
||||
def generate_source():
|
||||
render, out = renderer()
|
||||
render(includes_source())
|
||||
render(collision_tile_ids());
|
||||
return out
|
@ -1,11 +1,18 @@
|
||||
from generate import maps
|
||||
from generate import map_objects
|
||||
from generate import sprites
|
||||
from generate import tilesets
|
||||
from generate import collision_tile_ids
|
||||
|
||||
files = [
|
||||
(maps.generate_maps_header, "maps.hpp"),
|
||||
(maps.generate_maps_source, "maps.cpp"),
|
||||
(map_objects.generate_map_objects_source, "map_objects.cpp"),
|
||||
(sprites.generate_sprites_header, "sprites.hpp"),
|
||||
(sprites.generate_sprites_source, "sprites.cpp"),
|
||||
(maps.generate_header, "maps.hpp"),
|
||||
(maps.generate_source, "maps.cpp"),
|
||||
(tilesets.generate_header, "tilesets.hpp"),
|
||||
(tilesets.generate_source, "tilesets.cpp"),
|
||||
# map_objects.hpp is not generated
|
||||
(map_objects.generate_source, "map_objects.cpp"),
|
||||
(sprites.generate_header, "sprites.hpp"),
|
||||
(sprites.generate_source, "sprites.cpp"),
|
||||
(collision_tile_ids.generate_header, "collision_tile_ids.hpp"),
|
||||
(collision_tile_ids.generate_source, "collision_tile_ids.cpp"),
|
||||
]
|
||||
|
@ -99,7 +99,7 @@ def map_objects():
|
||||
yield from object(map_name, map_objects)
|
||||
yield "};"
|
||||
|
||||
def generate_map_objects_source():
|
||||
def generate_source():
|
||||
render, out = renderer()
|
||||
render(includes_source())
|
||||
render(map_objects())
|
||||
|
@ -38,47 +38,17 @@ def sorted_map_headers():
|
||||
# e.g CERULEAN_TRASHED_HOUSE_COPY has no map header
|
||||
)
|
||||
|
||||
def sorted_tilesets_constants_list():
|
||||
return sorted(parse.tileset_constants_list.items(), key=default_sort)
|
||||
|
||||
def includes_header():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield '#include "../start_size.hpp"'
|
||||
yield '#include "tilesets.hpp"'
|
||||
yield ""
|
||||
for map_header in sorted_map_headers():
|
||||
block_path = parse.maps_blocks_list[map_header.blocks()]
|
||||
yield f'#include "../res/{block_path}.h"'
|
||||
for tileset_name, _ in sorted_tilesets_constants_list():
|
||||
tileset_index = parse.tileset_constants_list[tileset_name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
yield f'#include "../res/{blockset_path}.h"'
|
||||
yield f'#include "../res/{gfx_path}.h"'
|
||||
yield ""
|
||||
|
||||
def struct_tileset_t():
|
||||
_sorted_tilesets_constants_list = list(sorted_tilesets_constants_list())
|
||||
tileset_names = (
|
||||
f"{name.lower()},"
|
||||
for name, _ in _sorted_tilesets_constants_list
|
||||
)
|
||||
return [
|
||||
"struct tileset_t {",
|
||||
"start_size_t blockset;",
|
||||
"start_size_t tileset;",
|
||||
"",
|
||||
"enum tileset {",
|
||||
*tileset_names,
|
||||
"};",
|
||||
"",
|
||||
f"static constexpr int32_t count = {len(_sorted_tilesets_constants_list)};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def struct_map_t():
|
||||
_sorted_map_headers = list(sorted_map_headers())
|
||||
map_names = (
|
||||
@ -119,33 +89,6 @@ def struct_connection_t():
|
||||
"};",
|
||||
]
|
||||
|
||||
def blockset_tileset(name: str):
|
||||
tileset_index = parse.tileset_constants_list[name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
return [
|
||||
f"[tileset_t::{name.lower()}] = {{",
|
||||
".blockset = {",
|
||||
*start_size_value(blockset_path),
|
||||
"},",
|
||||
".tileset = {",
|
||||
*start_size_value(gfx_path),
|
||||
"}",
|
||||
"},"
|
||||
]
|
||||
|
||||
def tilesets_header():
|
||||
yield "extern const tileset_t tilesets[];"
|
||||
|
||||
def tilesets():
|
||||
yield "const tileset_t tilesets[] = {"
|
||||
for name, _ in sorted_tilesets_constants_list():
|
||||
yield from blockset_tileset(name)
|
||||
yield "};"
|
||||
|
||||
def connections(map_header):
|
||||
cs = dict((c.name, c) for c in map_header.connections)
|
||||
assert len(cs) == len(map_header.connections), map_header.connections
|
||||
@ -183,7 +126,7 @@ def map(map_header):
|
||||
"},",
|
||||
]
|
||||
|
||||
def maps_header():
|
||||
def extern_maps():
|
||||
yield "extern const map_t maps[];"
|
||||
|
||||
def maps():
|
||||
@ -192,13 +135,11 @@ def maps():
|
||||
yield from map(map_header)
|
||||
yield "};"
|
||||
|
||||
def generate_maps_header():
|
||||
def generate_header():
|
||||
render, out = renderer()
|
||||
render(includes_header())
|
||||
render(struct_tileset_t())
|
||||
render(struct_map_t())
|
||||
render(tilesets_header());
|
||||
render(maps_header());
|
||||
render(extern_maps());
|
||||
return out
|
||||
|
||||
def includes_source():
|
||||
@ -207,9 +148,8 @@ def includes_source():
|
||||
yield '#include "maps.hpp"'
|
||||
yield ''
|
||||
|
||||
def generate_maps_source():
|
||||
def generate_source():
|
||||
render, out = renderer()
|
||||
render(includes_source())
|
||||
render(tilesets())
|
||||
render(maps())
|
||||
return out
|
||||
|
@ -61,7 +61,7 @@ def struct_spritesheet_t():
|
||||
def sprites_header():
|
||||
yield "extern const spritesheet_t spritesheets[];"
|
||||
|
||||
def generate_sprites_header():
|
||||
def generate_header():
|
||||
render, out = renderer()
|
||||
render(includes_header())
|
||||
render(struct_spritesheet_t())
|
||||
@ -94,7 +94,7 @@ def sprites():
|
||||
yield from sprite(name, index)
|
||||
yield "};"
|
||||
|
||||
def generate_sprites_source():
|
||||
def generate_source():
|
||||
render, out = renderer()
|
||||
render(includes_source());
|
||||
render(sprites())
|
||||
|
94
tools/generate/tilesets.py
Normal file
94
tools/generate/tilesets.py
Normal file
@ -0,0 +1,94 @@
|
||||
from parse import parse
|
||||
|
||||
from generate.sort import default_sort
|
||||
from generate.generate import renderer
|
||||
from generate.binary import start_size_value
|
||||
|
||||
def sorted_tilesets_constants_list():
|
||||
return sorted(parse.tileset_constants_list.items(), key=default_sort)
|
||||
|
||||
def includes_header():
|
||||
yield "#pragma once"
|
||||
yield ""
|
||||
yield '#include "../start_size.hpp"'
|
||||
yield ""
|
||||
for tileset_name, _ in sorted_tilesets_constants_list():
|
||||
tileset_index = parse.tileset_constants_list[tileset_name]
|
||||
tileset_header = parse.tileset_headers_list[tileset_index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
|
||||
yield f'#include "../res/{blockset_path}.h"'
|
||||
yield f'#include "../res/{gfx_path}.h"'
|
||||
|
||||
def struct_tileset_t():
|
||||
_sorted_tilesets_constants_list = list(sorted_tilesets_constants_list())
|
||||
tileset_names = (
|
||||
f"{name.lower()},"
|
||||
for name, _ in _sorted_tilesets_constants_list
|
||||
)
|
||||
return [
|
||||
"struct tileset_t {",
|
||||
"start_size_t blockset;",
|
||||
"start_size_t tileset;",
|
||||
"start_size_t collision;",
|
||||
"",
|
||||
"enum tileset {",
|
||||
*tileset_names,
|
||||
"};",
|
||||
"",
|
||||
f"static constexpr int32_t count = {len(_sorted_tilesets_constants_list)};",
|
||||
"};",
|
||||
]
|
||||
|
||||
def extern_tilesets():
|
||||
yield "extern const tileset_t tilesets[];"
|
||||
|
||||
def generate_header():
|
||||
render, out = renderer()
|
||||
render(includes_header())
|
||||
render(struct_tileset_t())
|
||||
render(extern_tilesets())
|
||||
return out
|
||||
|
||||
def blockset_tileset(name, index):
|
||||
tileset_header = parse.tileset_headers_list[index]
|
||||
|
||||
blockset_path = parse.gfx_tilesets_list[tileset_header.blockset()]
|
||||
gfx_path = parse.gfx_tilesets_list[tileset_header.gfx()]
|
||||
coll_path = tileset_header.coll()
|
||||
|
||||
return [
|
||||
f"[tileset_t::{name.lower()}] = {{",
|
||||
".blockset = {",
|
||||
*start_size_value(blockset_path),
|
||||
"},",
|
||||
".tileset = {",
|
||||
*start_size_value(gfx_path),
|
||||
"},",
|
||||
".collision = {",
|
||||
f".start = &{coll_path}[0],",
|
||||
f".size = (sizeof ({coll_path})),",
|
||||
"}",
|
||||
"},"
|
||||
]
|
||||
|
||||
def tilesets():
|
||||
yield "const tileset_t tilesets[] = {"
|
||||
for name, index in sorted_tilesets_constants_list():
|
||||
yield from blockset_tileset(name, index)
|
||||
yield "};"
|
||||
|
||||
def includes_source():
|
||||
yield '#include <cstdint>'
|
||||
yield ''
|
||||
yield '#include "tilesets.hpp"'
|
||||
yield '#include "collision_tile_ids.hpp"'
|
||||
yield ''
|
||||
|
||||
def generate_source():
|
||||
render, out = renderer()
|
||||
render(includes_source())
|
||||
render(tilesets())
|
||||
return out
|
@ -1,5 +1,5 @@
|
||||
from pprint import pprint
|
||||
from parse import parse
|
||||
|
||||
for i in parse.map_objects_list.items():
|
||||
for i in parse.collision_tile_ids_list.items():
|
||||
pprint(i)
|
||||
|
Loading…
x
Reference in New Issue
Block a user