Compare commits
3 Commits
1f80d22e72
...
a443d09b3d
Author | SHA1 | Date | |
---|---|---|---|
a443d09b3d | |||
d12e49aa16 | |||
fde161dabf |
4
Makefile
4
Makefile
@ -54,11 +54,11 @@ gen/%.cpp: gen/%.hpp $(GEN_PYTHON_SOURCE)
|
|||||||
|
|
||||||
res/%.2bpp: pokered/%.png
|
res/%.2bpp: pokered/%.png
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
python tools/png_to_nbpp.py $< 2 $@
|
python tools/png_to_nbpp.py 2 $@ $<
|
||||||
|
|
||||||
res/gfx/sprites/%.2bpp: pokered/gfx/sprites/%.png
|
res/gfx/sprites/%.2bpp: pokered/gfx/sprites/%.png
|
||||||
@mkdir -p $(dir $@)
|
@mkdir -p $(dir $@)
|
||||||
python tools/png_to_nbpp_sprite.py $< 2 $@
|
python tools/png_to_nbpp_sprite.py 2 $@ $<
|
||||||
|
|
||||||
%.2bpp.h:
|
%.2bpp.h:
|
||||||
$(BUILD_BINARY_H)
|
$(BUILD_BINARY_H)
|
||||||
|
85
actor.hpp
85
actor.hpp
@ -11,56 +11,101 @@ struct actor_t
|
|||||||
right,
|
right,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum collision {
|
||||||
|
impassable,
|
||||||
|
jump,
|
||||||
|
passable,
|
||||||
|
};
|
||||||
|
|
||||||
world_t world;
|
world_t world;
|
||||||
enum direction facing;
|
enum direction facing;
|
||||||
bool moving;
|
bool moving;
|
||||||
bool collision;
|
enum collision collision;
|
||||||
uint8_t frame;
|
uint8_t frame;
|
||||||
uint8_t cycle;
|
uint8_t cycle;
|
||||||
|
|
||||||
|
constexpr inline int32_t frame_pixels()
|
||||||
|
{
|
||||||
|
switch (collision) {
|
||||||
|
case jump: return frame;
|
||||||
|
default: return frame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constexpr inline offset_t offset()
|
constexpr inline offset_t offset()
|
||||||
{
|
{
|
||||||
if (collision) {
|
const int32_t pixels = frame_pixels();
|
||||||
|
|
||||||
|
switch (collision) {
|
||||||
|
default:
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
} else {
|
case jump: [[fallthrough]];
|
||||||
|
case passable:
|
||||||
switch (facing) {
|
switch (facing) {
|
||||||
case left:
|
case left:
|
||||||
return {-frame, 0};
|
return {-pixels, 0};
|
||||||
case right:
|
case right:
|
||||||
return {frame, 0};
|
return {pixels, 0};
|
||||||
case up:
|
case up:
|
||||||
return {0, -frame};
|
return {0, -pixels};
|
||||||
case down:
|
case down:
|
||||||
return {0, frame};
|
return {0, pixels};
|
||||||
default:
|
default:
|
||||||
return {0, 0};
|
return {0, 0};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// engine/overworld/player_animations.asm
|
||||||
|
// $38, $36, $34, $32, $31, $30, $30, $30, $31, $32, $33, $34, $36, $38, $3C, $3C
|
||||||
|
// ^ these are in absolute position, subtract 60 from each to get the offset:
|
||||||
|
// an offset of -4 is the same as not jumping
|
||||||
|
static constexpr int8_t jump_screen_offset[16] = {-4, -8, -10, -12, -14, -15, -16, -16, -16, -15, -14, -13, -12, -10, -8, -4};
|
||||||
|
|
||||||
|
// in pixels
|
||||||
|
constexpr inline int32_t y_offset()
|
||||||
|
{
|
||||||
|
if (collision == jump)
|
||||||
|
return jump_screen_offset[frame >> 1 & 15];
|
||||||
|
else
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline int32_t world_increment()
|
||||||
|
{
|
||||||
|
switch (collision) {
|
||||||
|
case jump: return 2;
|
||||||
|
default: return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// call tick() before move()
|
// call tick() before move()
|
||||||
constexpr inline void tick()
|
constexpr inline void tick()
|
||||||
{
|
{
|
||||||
if (!moving) return;
|
if (!moving) return;
|
||||||
|
|
||||||
frame = frame + 1;
|
frame = frame + 1;
|
||||||
if (frame == 16) {
|
if (frame == (16 * world_increment())) {
|
||||||
cycle += 1;
|
cycle += 1;
|
||||||
frame = 0;
|
frame = 0;
|
||||||
if (!collision) {
|
int32_t inc = world_increment();
|
||||||
|
switch (collision) {
|
||||||
|
default: break;
|
||||||
|
case jump: [[fallthrough]];
|
||||||
|
case passable:
|
||||||
switch (facing) {
|
switch (facing) {
|
||||||
case left: world.x--; break;
|
case left: world.x -= inc; break;
|
||||||
case right: world.x++; break;
|
case right: world.x += inc; break;
|
||||||
case up: world.y--; break;
|
case up: world.y -= inc; break;
|
||||||
case down: world.y++; break;
|
case down: world.y += inc; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
moving = false;
|
moving = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline void move(enum direction dir,
|
constexpr inline void move(enum collision collision,
|
||||||
bool collision)
|
enum direction dir)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
m 1 . 2 . 3 . 4 .
|
m 1 . 2 . 3 . 4 .
|
||||||
@ -68,9 +113,13 @@ struct actor_t
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!(this->collision) && moving) return;
|
// don't change directions in the middle of a movement animation
|
||||||
if (!collision)
|
if (this->collision != impassable && moving) return;
|
||||||
frame = 0;
|
|
||||||
|
// reset animation frame if there is no collision
|
||||||
|
// if there is a collision, keep animating
|
||||||
|
if (collision != impassable) frame = 0;
|
||||||
|
|
||||||
facing = dir;
|
facing = dir;
|
||||||
moving = true;
|
moving = true;
|
||||||
this->collision = collision;
|
this->collision = collision;
|
||||||
|
35
ledge_tiles.hpp
Normal file
35
ledge_tiles.hpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
data/tilesets/ledge_tiles.asm
|
||||||
|
; player direction, tile player standing on, ledge tile, input required
|
||||||
|
db SPRITE_FACING_DOWN, $2C, $37, D_DOWN
|
||||||
|
db SPRITE_FACING_DOWN, $39, $36, D_DOWN
|
||||||
|
db SPRITE_FACING_DOWN, $39, $37, D_DOWN
|
||||||
|
db SPRITE_FACING_LEFT, $2C, $27, D_LEFT
|
||||||
|
db SPRITE_FACING_LEFT, $39, $27, D_LEFT
|
||||||
|
db SPRITE_FACING_RIGHT, $2C, $0D, D_RIGHT
|
||||||
|
db SPRITE_FACING_RIGHT, $2C, $1D, D_RIGHT
|
||||||
|
db SPRITE_FACING_RIGHT, $39, $0D, D_RIGHT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "actor.hpp"
|
||||||
|
|
||||||
|
struct ledge_tile_t {
|
||||||
|
enum actor_t::direction direction;
|
||||||
|
uint8_t actor;
|
||||||
|
uint8_t collision;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ledge_tile_t ledge_tiles[] = {
|
||||||
|
{actor_t::down, 0x2c, 0x37},
|
||||||
|
{actor_t::down, 0x39, 0x36},
|
||||||
|
{actor_t::down, 0x39, 0x37},
|
||||||
|
{actor_t::left, 0x2c, 0x27},
|
||||||
|
{actor_t::left, 0x39, 0x27},
|
||||||
|
{actor_t::right, 0x2c, 0x0d},
|
||||||
|
{actor_t::right, 0x2c, 0x1d},
|
||||||
|
{actor_t::right, 0x39, 0x0d},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr uint8_t ledge_tiles_length = (sizeof (ledge_tiles)) / (sizeof (ledge_tile_t));
|
107
main.cpp
107
main.cpp
@ -19,6 +19,7 @@
|
|||||||
#include "coordinates.hpp"
|
#include "coordinates.hpp"
|
||||||
#include "render_map.hpp"
|
#include "render_map.hpp"
|
||||||
#include "actor.hpp"
|
#include "actor.hpp"
|
||||||
|
#include "ledge_tiles.hpp"
|
||||||
|
|
||||||
constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b)
|
constexpr inline uint16_t rgb15(int32_t r, int32_t g, int32_t b)
|
||||||
{
|
{
|
||||||
@ -160,7 +161,8 @@ static inline uint32_t facing_inverted(const actor_t::direction facing, const ui
|
|||||||
|
|
||||||
void render_sprite(const uint32_t ix, const uint32_t sprite_id,
|
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 enum actor_t::direction facing, const uint32_t animation_frame, const uint32_t animation_cycle,
|
||||||
const screen_t& screen, const offset_t& offset)
|
const screen_t& screen, const offset_t& offset,
|
||||||
|
int32_t y_offset)
|
||||||
{
|
{
|
||||||
constexpr uint32_t color_address = 0;
|
constexpr uint32_t color_address = 0;
|
||||||
const uint32_t sprite_offset = facing_offset(facing) + animation_frame;
|
const uint32_t sprite_offset = facing_offset(facing) + animation_frame;
|
||||||
@ -180,7 +182,7 @@ void render_sprite(const uint32_t ix, const uint32_t sprite_id,
|
|||||||
vdp1.vram.cmd[ix].SRCA = character_address;
|
vdp1.vram.cmd[ix].SRCA = character_address;
|
||||||
vdp1.vram.cmd[ix].SIZE = SIZE__X(16) | SIZE__Y(16);
|
vdp1.vram.cmd[ix].SIZE = SIZE__X(16) | SIZE__Y(16);
|
||||||
vdp1.vram.cmd[ix].XA = (cell_offset::x * 8) + screen.x * 16 - offset.x;
|
vdp1.vram.cmd[ix].XA = (cell_offset::x * 8) + screen.x * 16 - offset.x;
|
||||||
vdp1.vram.cmd[ix].YA = (cell_offset::y * 8) + screen.y * 16 - 4 - offset.y;
|
vdp1.vram.cmd[ix].YA = (cell_offset::y * 8) + screen.y * 16 + y_offset - offset.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_sprites(const offset_t& offset)
|
void render_sprites(const offset_t& offset)
|
||||||
@ -192,7 +194,8 @@ void render_sprites(const offset_t& offset)
|
|||||||
spritesheet_t::red,
|
spritesheet_t::red,
|
||||||
state.player.facing, animation_frame, state.player.cycle,
|
state.player.facing, animation_frame, state.player.cycle,
|
||||||
{4, 4},
|
{4, 4},
|
||||||
{0, 0});
|
{0, 0},
|
||||||
|
state.player.y_offset());
|
||||||
ix++;
|
ix++;
|
||||||
|
|
||||||
const object_t& obj = map_objects[state.map];
|
const object_t& obj = map_objects[state.map];
|
||||||
@ -203,7 +206,8 @@ void render_sprites(const offset_t& offset)
|
|||||||
event.sprite_id,
|
event.sprite_id,
|
||||||
actor_t::down, 0, 0,
|
actor_t::down, 0, 0,
|
||||||
world.to_screen(state.player.world),
|
world.to_screen(state.player.world),
|
||||||
offset);
|
offset,
|
||||||
|
-4);
|
||||||
ix++;
|
ix++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,12 +271,10 @@ constexpr inline world_t direction_offset(const world_t& world, const enum actor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool collision(const map_t& map,
|
constexpr inline uint8_t get_tile_ix(const map_t& map, const world_t& coord)
|
||||||
const world_t& world,
|
|
||||||
enum actor_t::direction dir)
|
|
||||||
{
|
{
|
||||||
const world_t coord = direction_offset(world, dir);
|
|
||||||
// keep this synchronized with render_screen()
|
// keep this synchronized with render_screen()
|
||||||
|
|
||||||
const uint8_t block_ix = get_block(map, coord.to_block());
|
const uint8_t block_ix = get_block(map, coord.to_block());
|
||||||
const tileset_t& tileset = tilesets[map.tileset];
|
const tileset_t& tileset = tilesets[map.tileset];
|
||||||
const uint8_t * block_start = &(tileset.blockset.start)[block_ix * 4 * 4];
|
const uint8_t * block_start = &(tileset.blockset.start)[block_ix * 4 * 4];
|
||||||
@ -282,12 +284,42 @@ constexpr inline bool collision(const map_t& map,
|
|||||||
const int32_t block_row = 4 * (quadrant_y + 1);
|
const int32_t block_row = 4 * (quadrant_y + 1);
|
||||||
const uint8_t tile_ix = block_start[block_row + quadrant_x];
|
const uint8_t tile_ix = block_start[block_row + quadrant_x];
|
||||||
|
|
||||||
|
return tile_ix;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline enum actor_t::collision collision(const map_t& map,
|
||||||
|
const world_t& world,
|
||||||
|
enum actor_t::direction direction)
|
||||||
|
{
|
||||||
|
const world_t coord = direction_offset(world, direction);
|
||||||
|
uint8_t collision_tile_ix = get_tile_ix(map, coord);
|
||||||
|
|
||||||
|
const tileset_t& tileset = tilesets[map.tileset];
|
||||||
for (uint32_t i = 0; i < tileset.collision.size; i++) {
|
for (uint32_t i = 0; i < tileset.collision.size; i++) {
|
||||||
if (tileset.collision.start[i] == tile_ix)
|
if (tileset.collision.start[i] == collision_tile_ix)
|
||||||
return false;
|
return actor_t::passable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// check ledge_tile pairs
|
||||||
|
|
||||||
|
uint8_t actor_tile_ix = get_tile_ix(map, world);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < ledge_tiles_length; i++) {
|
||||||
|
const ledge_tile_t& lt = ledge_tiles[i];
|
||||||
|
if (direction == lt.direction
|
||||||
|
&& actor_tile_ix == lt.actor
|
||||||
|
&& collision_tile_ix == lt.collision) {
|
||||||
|
return actor_t::jump;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actor_t::impassable;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr inline void collision_move(const map_t& map, actor_t::direction dir)
|
||||||
|
{
|
||||||
|
const enum actor_t::collision c = collision(map, state.player.world, dir);
|
||||||
|
state.player.move(c, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_maps()
|
void change_maps()
|
||||||
@ -336,7 +368,7 @@ void change_maps()
|
|||||||
#undef _has
|
#undef _has
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool is_outside(const enum map_t::map& map_id)
|
constexpr inline bool is_outside(const enum map_t::map& map_id)
|
||||||
{
|
{
|
||||||
const map_t& map = maps[map_id];
|
const map_t& map = maps[map_id];
|
||||||
switch (map.tileset) {
|
switch (map.tileset) {
|
||||||
@ -348,6 +380,30 @@ constexpr bool is_outside(const enum map_t::map& map_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct collision_direction_t {
|
||||||
|
enum actor_t::collision collision;
|
||||||
|
enum actor_t::direction direction;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr inline collision_direction_t find_direction(const map_t& map, const world_t& world, const enum actor_t::direction facing)
|
||||||
|
{
|
||||||
|
// first, try `facing`, as this is typically correct in non- edge-cases
|
||||||
|
const enum actor_t::collision c_facing = collision(map, world, facing);
|
||||||
|
if (c_facing != actor_t::impassable)
|
||||||
|
return {c_facing, facing};
|
||||||
|
|
||||||
|
// otherwise try all other directions
|
||||||
|
// (this checks facing a second time for no reason)
|
||||||
|
constexpr enum actor_t::direction dirs[] = {actor_t::up, actor_t::down, actor_t::left, actor_t::right};
|
||||||
|
for (const enum actor_t::direction& dir : dirs) {
|
||||||
|
const enum actor_t::collision c = collision(map, world, dir);
|
||||||
|
if (c != actor_t::impassable)
|
||||||
|
return {c, dir};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {actor_t::impassable, facing};
|
||||||
|
}
|
||||||
|
|
||||||
void update_warp()
|
void update_warp()
|
||||||
{
|
{
|
||||||
if (state.player.moving) return;
|
if (state.player.moving) return;
|
||||||
@ -377,7 +433,13 @@ void update_warp()
|
|||||||
coord.x = dest.position.x;
|
coord.x = dest.position.x;
|
||||||
coord.y = dest.position.y;
|
coord.y = dest.position.y;
|
||||||
|
|
||||||
state.player.move(state.player.facing, false);
|
// force the player to move off of the warp
|
||||||
|
|
||||||
|
const collision_direction_t c_d = find_direction(maps[state.map], state.player.world, state.player.facing);
|
||||||
|
state.player.move(c_d.collision, c_d.direction);
|
||||||
|
|
||||||
|
// must return: because map state.map changed, the rest of this
|
||||||
|
// loop is invalid
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,21 +451,10 @@ void update()
|
|||||||
change_maps();
|
change_maps();
|
||||||
update_warp();
|
update_warp();
|
||||||
|
|
||||||
const map_t& map = maps[state.map];
|
if (event::cursor_left() ) collision_move(maps[state.map], actor_t::left);
|
||||||
|
else if (event::cursor_right()) collision_move(maps[state.map], actor_t::right);
|
||||||
if (event::cursor_left()) {
|
else if (event::cursor_up() ) collision_move(maps[state.map], actor_t::up);
|
||||||
const bool c = collision(map, state.player.world, actor_t::left);
|
else if (event::cursor_down() ) collision_move(maps[state.map], actor_t::down);
|
||||||
state.player.move(actor_t::left, c);
|
|
||||||
} else if (event::cursor_right()) {
|
|
||||||
const bool c = collision(map, state.player.world, actor_t::right);
|
|
||||||
state.player.move(actor_t::right, c);
|
|
||||||
} else if (event::cursor_up()) {
|
|
||||||
const bool c = collision(map, state.player.world, actor_t::up);
|
|
||||||
state.player.move(actor_t::up, c);
|
|
||||||
} else if (event::cursor_down()) {
|
|
||||||
const bool c = collision(map, state.player.world, actor_t::down);
|
|
||||||
state.player.move(actor_t::down, c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
|
@ -6,13 +6,13 @@ from PIL import Image
|
|||||||
from palette import intensity_to_index
|
from palette import intensity_to_index
|
||||||
|
|
||||||
def convert(image, bpp):
|
def convert(image, bpp):
|
||||||
assert bpp in {8, 4, 2}, bpp
|
assert bpp in {8, 4, 2, 1}, bpp
|
||||||
px_per_byte = 8 // bpp
|
px_per_byte = 8 // bpp
|
||||||
px_per_row = 8
|
px_per_row = 8
|
||||||
bits_per_byte = 8
|
bits_per_byte = 8
|
||||||
bytes_per_row = (px_per_row // (bits_per_byte // bpp))
|
bytes_per_row = (px_per_row // (bits_per_byte // bpp))
|
||||||
|
|
||||||
assert image.mode == 'L', image.mode
|
assert image.mode in {'L', '1'}, image.mode
|
||||||
width, height = image.size
|
width, height = image.size
|
||||||
|
|
||||||
buf = bytearray(width * height // px_per_byte)
|
buf = bytearray(width * height // px_per_byte)
|
||||||
@ -21,14 +21,17 @@ def convert(image, bpp):
|
|||||||
for cell_x in range(width//8):
|
for cell_x in range(width//8):
|
||||||
for y in range(8):
|
for y in range(8):
|
||||||
for x in range(8):
|
for x in range(8):
|
||||||
px = im.getpixel((cell_x * 8 + x, cell_y * 8 + y))
|
px = image.getpixel((cell_x * 8 + x, cell_y * 8 + y))
|
||||||
|
if image.mode == 'L':
|
||||||
index = intensity_to_index(px)
|
index = intensity_to_index(px)
|
||||||
|
elif image.mode == '1':
|
||||||
|
index = int(px != 0)
|
||||||
buf_ix = x//px_per_byte + (bytes_per_row * (cell_x * 8 + (cell_y * width) + y))
|
buf_ix = x//px_per_byte + (bytes_per_row * (cell_x * 8 + (cell_y * width) + y))
|
||||||
buf[buf_ix] |= (index << bpp * ((px_per_byte - 1) - (x % px_per_byte)))
|
buf[buf_ix] |= (index << bpp * ((px_per_byte - 1) - (x % px_per_byte)))
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def debug(buf, bpp):
|
def debug(buf, bpp):
|
||||||
assert bpp in {8, 4, 2}, bpp
|
assert bpp in {8, 4, 2, 1}, bpp
|
||||||
px_per_byte = 8 // bpp
|
px_per_byte = 8 // bpp
|
||||||
px_per_row = 8
|
px_per_row = 8
|
||||||
bits_per_byte = 8
|
bits_per_byte = 8
|
||||||
@ -44,13 +47,14 @@ def debug(buf, bpp):
|
|||||||
if (row % 8 == 7):
|
if (row % 8 == 7):
|
||||||
print()
|
print()
|
||||||
|
|
||||||
in_path = sys.argv[1]
|
bpp = int(sys.argv[1])
|
||||||
bpp = int(sys.argv[2])
|
out_path = sys.argv[2]
|
||||||
out_path = sys.argv[3]
|
assert len(sys.argv) >= 4, sys.argv
|
||||||
|
|
||||||
im = Image.open(in_path)
|
|
||||||
buf = convert(im, bpp)
|
|
||||||
if 'NBPP_DEBUG' in os.environ:
|
|
||||||
debug(buf, bpp)
|
|
||||||
with open(out_path, 'wb') as f:
|
with open(out_path, 'wb') as f:
|
||||||
|
for in_path in sys.argv[3:]:
|
||||||
|
im = Image.open(in_path)
|
||||||
|
buf = convert(im, bpp)
|
||||||
|
if 'NBPP_DEBUG' in os.environ:
|
||||||
|
debug(buf, bpp)
|
||||||
f.write(buf)
|
f.write(buf)
|
||||||
|
@ -56,13 +56,14 @@ def debug(buf, bpp):
|
|||||||
if (row % cell_height == (cell_height - 1)):
|
if (row % cell_height == (cell_height - 1)):
|
||||||
print()
|
print()
|
||||||
|
|
||||||
in_path = sys.argv[1]
|
bpp = int(sys.argv[1])
|
||||||
bpp = int(sys.argv[2])
|
out_path = sys.argv[2]
|
||||||
out_path = sys.argv[3]
|
assert len(sys.argv) >= 4, sys.argv
|
||||||
|
|
||||||
im = Image.open(in_path)
|
|
||||||
buf = convert(im, bpp)
|
|
||||||
if 'NBPP_DEBUG' in os.environ:
|
|
||||||
debug(buf, bpp)
|
|
||||||
with open(out_path, 'wb') as f:
|
with open(out_path, 'wb') as f:
|
||||||
|
for in_path in sys.argv[3:]:
|
||||||
|
im = Image.open(in_path)
|
||||||
|
buf = convert(im, bpp)
|
||||||
|
if 'NBPP_DEBUG' in os.environ:
|
||||||
|
debug(buf, bpp)
|
||||||
f.write(buf)
|
f.write(buf)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user