mirror of
https://github.com/luksamuk/engine-psx.git
synced 2025-04-28 13:28:02 +03:00
Improve player sprite export instructions, add some animations
This commit is contained in:
parent
ded76efbcf
commit
8b03030ba8
19 changed files with 139 additions and 104 deletions
|
@ -10,7 +10,7 @@ File_7=Z:\home\alchemist\git\engine-psx\assets\levels\R2\tiles.TIM
|
||||||
File_8=Z:\home\alchemist\git\engine-psx\assets\levels\R3\BG0.TIM
|
File_8=Z:\home\alchemist\git\engine-psx\assets\levels\R3\BG0.TIM
|
||||||
File_9=Z:\home\alchemist\git\engine-psx\assets\levels\R3\TILES.TIM
|
File_9=Z:\home\alchemist\git\engine-psx\assets\levels\R3\TILES.TIM
|
||||||
File_10=Z:\home\alchemist\git\engine-psx\assets\sprites\BASEFONT.TIM
|
File_10=Z:\home\alchemist\git\engine-psx\assets\sprites\BASEFONT.TIM
|
||||||
File_11=Z:\home\alchemist\git\engine-psx\assets\sprites\SONIC.TIM
|
File_11=Z:\home\alchemist\git\engine-psx\assets\sprites\CHARA\SONIC.TIM
|
||||||
[Graphics Mode]
|
[Graphics Mode]
|
||||||
Width=320
|
Width=320
|
||||||
Height=240
|
Height=240
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 35 KiB |
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
Binary file not shown.
BIN
assets/sprites/CHARA/SONIC.TIM
Normal file
BIN
assets/sprites/CHARA/SONIC.TIM
Normal file
Binary file not shown.
BIN
assets/sprites/CHARA/SONIC.aseprite
Normal file
BIN
assets/sprites/CHARA/SONIC.aseprite
Normal file
Binary file not shown.
1
assets/sprites/CHARA/SONIC.json
Normal file
1
assets/sprites/CHARA/SONIC.json
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/sprites/CHARA/SONIC.png
Normal file
BIN
assets/sprites/CHARA/SONIC.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
assets/sprites/CHARA/sonic-sheet.png
Normal file
BIN
assets/sprites/CHARA/sonic-sheet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 7.2 KiB |
|
@ -44,7 +44,8 @@ typedef enum {
|
||||||
ACTION_JUMPING,
|
ACTION_JUMPING,
|
||||||
ACTION_ROLLING,
|
ACTION_ROLLING,
|
||||||
ACTION_SPINDASH,
|
ACTION_SPINDASH,
|
||||||
ACTION_DROPDASH
|
ACTION_DROPDASH,
|
||||||
|
ACTION_SPRING,
|
||||||
} PlayerAction;
|
} PlayerAction;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -64,6 +65,7 @@ typedef struct {
|
||||||
uint8_t push;
|
uint8_t push;
|
||||||
uint32_t spinrev;
|
uint32_t spinrev;
|
||||||
uint8_t ctrllock;
|
uint8_t ctrllock;
|
||||||
|
uint8_t airdirlock;
|
||||||
uint8_t framecount;
|
uint8_t framecount;
|
||||||
uint8_t holding_jump;
|
uint8_t holding_jump;
|
||||||
|
|
||||||
|
|
4
iso.xml
4
iso.xml
|
@ -17,10 +17,10 @@
|
||||||
<dir name="SPRITES">
|
<dir name="SPRITES">
|
||||||
<file name="SONIC.TIM"
|
<file name="SONIC.TIM"
|
||||||
type="data"
|
type="data"
|
||||||
source="${PROJECT_SOURCE_DIR}/assets/sprites/SONIC.TIM" />
|
source="${PROJECT_SOURCE_DIR}/assets/sprites/CHARA/SONIC.TIM" />
|
||||||
<file name="SONIC.CHARA"
|
<file name="SONIC.CHARA"
|
||||||
type="data"
|
type="data"
|
||||||
source="${PROJECT_SOURCE_DIR}/assets/sprites/SONIC.CHARA" />
|
source="${PROJECT_SOURCE_DIR}/assets/sprites/CHARA/SONIC.CHARA" />
|
||||||
<file name="BASEFONT.TIM"
|
<file name="BASEFONT.TIM"
|
||||||
type="data"
|
type="data"
|
||||||
source="${PROJECT_SOURCE_DIR}/assets/sprites/BASEFONT.TIM" />
|
source="${PROJECT_SOURCE_DIR}/assets/sprites/BASEFONT.TIM" />
|
||||||
|
|
|
@ -143,7 +143,7 @@ chara_render_frame(Chara *chara, int16_t framenum, int16_t vx, int16_t vy, uint8
|
||||||
increment_prim(sizeof(POLY_FT4));
|
increment_prim(sizeof(POLY_FT4));
|
||||||
setPolyFT4(poly);
|
setPolyFT4(poly);
|
||||||
setRGB0(poly, level_fade, level_fade, level_fade);
|
setRGB0(poly, level_fade, level_fade, level_fade);
|
||||||
setTPage(poly, 0, 0, chara->prectx, chara->precty);
|
setTPage(poly, 1, 1, chara->prectx, chara->precty); // 8-bit CLUT
|
||||||
setClut(poly, chara->crectx, chara->crecty);
|
setClut(poly, chara->crectx, chara->crecty);
|
||||||
setXYWH(poly, xy0.vx, xy0.vy, 8, 8);
|
setXYWH(poly, xy0.vx, xy0.vy, 8, 8);
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,6 @@
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "screens/level.h"
|
#include "screens/level.h"
|
||||||
|
|
||||||
// Adler32 sums of player animation names
|
|
||||||
#define ANIM_WALKING 0x0854020e
|
|
||||||
|
|
||||||
// Extern elements
|
// Extern elements
|
||||||
extern Player player;
|
extern Player player;
|
||||||
extern Camera camera;
|
extern Camera camera;
|
||||||
|
@ -277,95 +274,19 @@ _spring_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos, uint8_t is_r
|
||||||
player.pos.vy = (solidity_vy - (player_height >> 1)) << 12;
|
player.pos.vy = (solidity_vy - (player_height >> 1)) << 12;
|
||||||
player.grnd = 0;
|
player.grnd = 0;
|
||||||
player.vel.vy = is_red ? -0x10000 : -0xa000;
|
player.vel.vy = is_red ? -0x10000 : -0xa000;
|
||||||
player.vel.vz = 0;
|
|
||||||
player.angle = 0;
|
player.angle = 0;
|
||||||
player.action = 0;
|
player.action = ACTION_SPRING;
|
||||||
state->anim_state.animation = 1;
|
state->anim_state.animation = 1;
|
||||||
player_set_animation_direct(&player, ANIM_WALKING);
|
|
||||||
sound_play_vag(sfx_sprn, 0);
|
sound_play_vag(sfx_sprn, 0);
|
||||||
} else if(state->flipmask & MASK_FLIP_FLIPY) { // Bottom-pointing spring
|
} else if(state->flipmask & MASK_FLIP_FLIPY) { // Bottom-pointing spring
|
||||||
player.pos.vy = (solidity_vy + solidity_h + (player_height >> 1)) << 12;
|
player.pos.vy = (solidity_vy + solidity_h + (player_height >> 1)) << 12;
|
||||||
player.grnd = 0;
|
player.grnd = 0;
|
||||||
player.vel.vy = is_red ? 0x10000 : 0xa000;
|
player.vel.vy = is_red ? 0x10000 : 0xa000;
|
||||||
player.vel.vz = 0;
|
|
||||||
player.angle = 0;
|
player.angle = 0;
|
||||||
player.action = 0;
|
player.action = ACTION_SPRING;
|
||||||
state->anim_state.animation = 1;
|
state->anim_state.animation = 1;
|
||||||
player_set_animation_direct(&player, ANIM_WALKING);
|
|
||||||
sound_play_vag(sfx_sprn, 0);
|
sound_play_vag(sfx_sprn, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Complex spring collision. Commented out. Doesn't work properly.
|
|
||||||
/* switch(collision_side) { */
|
|
||||||
/* default: return; */
|
|
||||||
/* case OBJ_SIDE_LEFT: */
|
|
||||||
/* if(state->flipmask & MASK_FLIP_ROTCT) { */
|
|
||||||
/* if(player.grnd) player.vel.vz = is_red ? -0x10000 : -0xa000; */
|
|
||||||
/* else player.vel.vx = is_red ? -0x10000 : -0xa000; */
|
|
||||||
/* player.ctrllock = 16; */
|
|
||||||
/* player.anim_dir = -1; */
|
|
||||||
/* state->anim_state.animation = 1; */
|
|
||||||
/* sound_play_vag(sfx_sprn, 0); */
|
|
||||||
/* } else { */
|
|
||||||
/* player.ev_right = (CollisionEvent) { */
|
|
||||||
/* .collided = 1, */
|
|
||||||
/* .coord = solidity_vx + 1, */
|
|
||||||
/* .angle = 0 */
|
|
||||||
/* }; */
|
|
||||||
/* } */
|
|
||||||
/* break; */
|
|
||||||
/* case OBJ_SIDE_RIGHT: */
|
|
||||||
/* if(state->flipmask & MASK_FLIP_ROTCW) { */
|
|
||||||
/* if(player.grnd) player.vel.vz = is_red ? 0x10000 : 0xa000; */
|
|
||||||
/* else player.vel.vx = is_red ? 0x10000 : 0xa000; */
|
|
||||||
/* player.ctrllock = 16; */
|
|
||||||
/* player.anim_dir = 1; */
|
|
||||||
/* state->anim_state.animation = 1; */
|
|
||||||
/* sound_play_vag(sfx_sprn, 0); */
|
|
||||||
/* } else { */
|
|
||||||
/* player.ev_left = (CollisionEvent) { */
|
|
||||||
/* .collided = 1, */
|
|
||||||
/* .coord = (solidity_vx + 15), */
|
|
||||||
/* .angle = 0 */
|
|
||||||
/* }; */
|
|
||||||
/* } */
|
|
||||||
/* break; */
|
|
||||||
/* case OBJ_SIDE_TOP: */
|
|
||||||
/* if(state->flipmask == 0) { */
|
|
||||||
/* player.grnd = 0; */
|
|
||||||
/* player.vel.vy = is_red ? -0x10000 : -0xa000; */
|
|
||||||
/* player.angle = 0; */
|
|
||||||
/* player.action = 0; */
|
|
||||||
/* state->anim_state.animation = 1; */
|
|
||||||
/* player_set_animation_direct(&player, ANIM_WALKING); */
|
|
||||||
/* sound_play_vag(sfx_sprn, 0); */
|
|
||||||
/* } else { */
|
|
||||||
/* player.ev_grnd1 = player.ev_grnd2 = (CollisionEvent) { */
|
|
||||||
/* .collided = 1, */
|
|
||||||
/* .coord = solidity_vy + 8, */
|
|
||||||
/* .angle = 0 */
|
|
||||||
/* }; */
|
|
||||||
/* } */
|
|
||||||
/* break; */
|
|
||||||
/* case OBJ_SIDE_BOTTOM: */
|
|
||||||
/* if(state->flipmask & MASK_FLIP_FLIPY) { */
|
|
||||||
/* player.grnd = 0; */
|
|
||||||
/* player.vel.vy = is_red ? 0x10000 : 0xa000; */
|
|
||||||
/* player.angle = 0; */
|
|
||||||
/* player.action = 0; */
|
|
||||||
/* state->anim_state.animation = 1; */
|
|
||||||
/* player_set_animation_direct(&player, ANIM_WALKING); */
|
|
||||||
/* sound_play_vag(sfx_sprn, 0); */
|
|
||||||
/* } else { */
|
|
||||||
/* player.ev_ceil1 = player.ev_ceil2 = (CollisionEvent) { */
|
|
||||||
/* .collided = 1, */
|
|
||||||
/* .coord = solidity_vy + solidity_h, */
|
|
||||||
/* .angle = 0 */
|
|
||||||
/* }; */
|
|
||||||
/* } */
|
|
||||||
/* break; */
|
|
||||||
/* } */
|
|
||||||
} else if(state->anim_state.animation == OBJ_ANIMATION_NO_ANIMATION) {
|
} else if(state->anim_state.animation == OBJ_ANIMATION_NO_ANIMATION) {
|
||||||
state->anim_state.animation = 0;
|
state->anim_state.animation = 0;
|
||||||
state->anim_state.frame = 0;
|
state->anim_state.frame = 0;
|
||||||
|
@ -440,16 +361,15 @@ _spring_diagonal_update(ObjectState *state, ObjectTableEntry *, VECTOR *pos, uin
|
||||||
player.grnd = 0;
|
player.grnd = 0;
|
||||||
player.vel.vx = is_red ? SPRND_ST_R : SPRND_ST_Y;
|
player.vel.vx = is_red ? SPRND_ST_R : SPRND_ST_Y;
|
||||||
player.vel.vy = is_red ? SPRND_ST_R : SPRND_ST_Y;
|
player.vel.vy = is_red ? SPRND_ST_R : SPRND_ST_Y;
|
||||||
player.vel.vz = 0;
|
|
||||||
if(!(state->flipmask & MASK_FLIP_FLIPY)) player.vel.vy *= -1;
|
if(!(state->flipmask & MASK_FLIP_FLIPY)) player.vel.vy *= -1;
|
||||||
if(state->flipmask & MASK_FLIP_FLIPX) {
|
if(state->flipmask & MASK_FLIP_FLIPX) {
|
||||||
player.vel.vx *= -1;
|
player.vel.vx *= -1;
|
||||||
player.anim_dir = -1; // Flip on X: point player left
|
player.anim_dir = -1; // Flip on X: point player left
|
||||||
} else player.anim_dir = 1; // No flip on X: point player right
|
} else player.anim_dir = 1; // No flip on X: point player right
|
||||||
player.angle = 0;
|
player.angle = 0;
|
||||||
player.action = 0;
|
player.airdirlock = 1;
|
||||||
|
player.action = ACTION_SPRING;
|
||||||
state->anim_state.animation = 1;
|
state->anim_state.animation = 1;
|
||||||
player_set_animation_direct(&player, ANIM_WALKING);
|
|
||||||
sound_play_vag(sfx_sprn, 0);
|
sound_play_vag(sfx_sprn, 0);
|
||||||
|
|
||||||
} else if(state->anim_state.animation == OBJ_ANIMATION_NO_ANIMATION) {
|
} else if(state->anim_state.animation == OBJ_ANIMATION_NO_ANIMATION) {
|
||||||
|
|
52
src/player.c
52
src/player.c
|
@ -14,16 +14,19 @@
|
||||||
#define ANIM_IDLE_TIMER_MAX 180
|
#define ANIM_IDLE_TIMER_MAX 180
|
||||||
|
|
||||||
// Adler32 sums of animation names for ease of use
|
// Adler32 sums of animation names for ease of use
|
||||||
#define ANIM_STOPPED 0x08cd0220
|
#define ANIM_STOPPED 0x08cd0220
|
||||||
#define ANIM_IDLE 0x02d1011f
|
#define ANIM_IDLE 0x02d1011f
|
||||||
#define ANIM_WALKING 0x0854020e
|
#define ANIM_WALKING 0x0854020e
|
||||||
#define ANIM_RUNNING 0x08bf0222
|
#define ANIM_RUNNING 0x08bf0222
|
||||||
#define ANIM_ROLLING 0x08890218
|
#define ANIM_ROLLING 0x08890218
|
||||||
#define ANIM_SKIDDING 0x0a85024e
|
#define ANIM_SKIDDING 0x0a85024e
|
||||||
#define ANIM_PEELOUT 0x0849021f
|
#define ANIM_PEELOUT 0x0849021f
|
||||||
#define ANIM_PUSHING 0x08b2021f
|
#define ANIM_PUSHING 0x08b2021f
|
||||||
#define ANIM_CROUCHDOWN 0x104802fd
|
#define ANIM_CROUCHDOWN 0x104802fd
|
||||||
#define ANIM_LOOKUP 0x067001db
|
#define ANIM_LOOKUP 0x067001db
|
||||||
|
#define ANIM_SPRING 0x068e01d4
|
||||||
|
#define ANIM_HURT 0x031b0144
|
||||||
|
#define ANIM_DEATH 0x04200167
|
||||||
|
|
||||||
extern int debug_mode;
|
extern int debug_mode;
|
||||||
|
|
||||||
|
@ -56,6 +59,7 @@ load_player(Player *player,
|
||||||
player->angle = 0;
|
player->angle = 0;
|
||||||
player->spinrev = 0;
|
player->spinrev = 0;
|
||||||
player->ctrllock = 0;
|
player->ctrllock = 0;
|
||||||
|
player->airdirlock = 0;
|
||||||
player->framecount = 0;
|
player->framecount = 0;
|
||||||
|
|
||||||
player_set_animation_direct(player, ANIM_STOPPED);
|
player_set_animation_direct(player, ANIM_STOPPED);
|
||||||
|
@ -367,8 +371,12 @@ _player_handle_collision(Player *player)
|
||||||
player->pos.vy = ((new_coord - 16) << 12);
|
player->pos.vy = ((new_coord - 16) << 12);
|
||||||
player->grnd = 1;
|
player->grnd = 1;
|
||||||
|
|
||||||
if(player->action == ACTION_JUMPING || player->action == ACTION_ROLLING)
|
if(player->action == ACTION_JUMPING
|
||||||
|
|| player->action == ACTION_ROLLING
|
||||||
|
|| player->action == ACTION_SPRING) {
|
||||||
player->action = ACTION_NONE;
|
player->action = ACTION_NONE;
|
||||||
|
player->airdirlock = 0;
|
||||||
|
}
|
||||||
else if(player->action == ACTION_DROPDASH) {
|
else if(player->action == ACTION_DROPDASH) {
|
||||||
// Perform drop dash
|
// Perform drop dash
|
||||||
player->framecount = 0;
|
player->framecount = 0;
|
||||||
|
@ -555,11 +563,13 @@ player_update(Player *player)
|
||||||
if(pad_pressing(PAD_RIGHT)) {
|
if(pad_pressing(PAD_RIGHT)) {
|
||||||
if(player->vel.vx < X_TOP_SPD)
|
if(player->vel.vx < X_TOP_SPD)
|
||||||
player->vel.vx += X_AIR_ACCEL;
|
player->vel.vx += X_AIR_ACCEL;
|
||||||
player->anim_dir = 1;
|
if(!player->airdirlock)
|
||||||
|
player->anim_dir = 1;
|
||||||
} else if(pad_pressing(PAD_LEFT)) {
|
} else if(pad_pressing(PAD_LEFT)) {
|
||||||
if(player->vel.vx > -X_TOP_SPD)
|
if(player->vel.vx > -X_TOP_SPD)
|
||||||
player->vel.vx -= X_AIR_ACCEL;
|
player->vel.vx -= X_AIR_ACCEL;
|
||||||
player->anim_dir = -1;
|
if(!player->airdirlock)
|
||||||
|
player->anim_dir = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Air drag. Calculated before applying gravity.
|
// Air drag. Calculated before applying gravity.
|
||||||
|
@ -654,7 +664,21 @@ player_update(Player *player)
|
||||||
player_set_animation_direct(player, ANIM_RUNNING);
|
player_set_animation_direct(player, ANIM_RUNNING);
|
||||||
} else player_set_animation_direct(player, ANIM_WALKING);
|
} else player_set_animation_direct(player, ANIM_WALKING);
|
||||||
}
|
}
|
||||||
} else player->idle_timer = ANIM_IDLE_TIMER_MAX;
|
} else {
|
||||||
|
player->idle_timer = ANIM_IDLE_TIMER_MAX;
|
||||||
|
if(player->action == ACTION_SPRING) {
|
||||||
|
if(player->vel.vy < 0) {
|
||||||
|
player_set_animation_direct(player, ANIM_SPRING);
|
||||||
|
} else {
|
||||||
|
player->airdirlock = 0;
|
||||||
|
if(abs(player->vel.vz) >= (10 << 12)) {
|
||||||
|
player_set_animation_direct(player, ANIM_PEELOUT);
|
||||||
|
} else if(abs(player->vel.vz) >= (6 << 12)) {
|
||||||
|
player_set_animation_direct(player, ANIM_RUNNING);
|
||||||
|
} else player_set_animation_direct(player, ANIM_WALKING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Animation speed correction
|
// Animation speed correction
|
||||||
if(player->anim_timer == 0) {
|
if(player->anim_timer == 0) {
|
||||||
|
|
|
@ -28,6 +28,95 @@ python -m venv ./venv
|
||||||
To run any scripts with this venv, run ~./tools/venv/bin/python
|
To run any scripts with this venv, run ~./tools/venv/bin/python
|
||||||
./tools/script.py~.
|
./tools/script.py~.
|
||||||
|
|
||||||
|
* Generating a character sprite 8x8 tileset and mappings
|
||||||
|
|
||||||
|
For characters, we need to use the Aseprite tool for building sprites.
|
||||||
|
|
||||||
|
Import the character's sprites as a sprite sheet and into an .aseprite file (see
|
||||||
|
'assets/sprites/CHARA/SONIC.aseprite').
|
||||||
|
|
||||||
|
The character's sprites must be manipulated into individual frames on a tileset
|
||||||
|
layer, with 8x8 tiles. Plus, you'll have to organize the frames in such a way
|
||||||
|
that frames of the same animation are coupled together.
|
||||||
|
|
||||||
|
Finally, group frames into animations by creating tags with animation names
|
||||||
|
(again, see 'SONIC.aseprite' for valid animation names).
|
||||||
|
|
||||||
|
Finally, export the animation names and mappings using 'export_tilemap_psx.lua',
|
||||||
|
then export the player tileset using 'export_tileset_psx.lua'.
|
||||||
|
|
||||||
|
This will create a 'SONIC.png' file and a 'SONIC.json' file.
|
||||||
|
|
||||||
|
Now, just pack the frame and tile data into a CHARA file, and generate a TIM
|
||||||
|
image with correct CLUT and TPAGE info:
|
||||||
|
|
||||||
|
#+begin_src bash :eval never
|
||||||
|
framepacker.py SONIC.json SONIC.CHARA
|
||||||
|
img2tim -usealpha -org 320 0 -plt 0 480 -bpp 8 -o SONIC.TIM SONIC.png
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Notice that, different than other image tile data, character sprites rely on a
|
||||||
|
PNG's alpha channel to generate transparency bits, instead of using the full
|
||||||
|
black color as mask.
|
||||||
|
|
||||||
|
NOTE: If you need to refer to an animation directly by name, the animations are
|
||||||
|
referred to by the engine by their Adler32 hash, so you might want to add a new
|
||||||
|
definition for that on ~player.c~.
|
||||||
|
|
||||||
|
The names used on tags are always converted to uppercase, with no spaces.
|
||||||
|
|
||||||
|
To calculate the Adler32 hash for a string, one may use Zlib through Python.
|
||||||
|
|
||||||
|
Here's a tool to generate hash definitions for some animations.
|
||||||
|
|
||||||
|
#+begin_src python :results output
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
names = [
|
||||||
|
"STOPPED",
|
||||||
|
"IDLE",
|
||||||
|
"WALKING",
|
||||||
|
"RUNNING",
|
||||||
|
"ROLLING",
|
||||||
|
"SKIDDING",
|
||||||
|
"PEELOUT",
|
||||||
|
"PUSHING",
|
||||||
|
"CROUCHDOWN",
|
||||||
|
"LOOKUP",
|
||||||
|
"SPRING",
|
||||||
|
"HURT",
|
||||||
|
"DEATH",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_hash(name):
|
||||||
|
hash = zlib.adler32(str.encode(name))
|
||||||
|
return f"0x{hash:08x}"
|
||||||
|
|
||||||
|
def print_hashes(names):
|
||||||
|
for name in names:
|
||||||
|
hash = get_hash(name)
|
||||||
|
print(f"#define ANIM_{name:16} {hash}")
|
||||||
|
|
||||||
|
print_hashes(names)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
#+begin_example
|
||||||
|
#define ANIM_STOPPED 0x08cd0220
|
||||||
|
#define ANIM_IDLE 0x02d1011f
|
||||||
|
#define ANIM_WALKING 0x0854020e
|
||||||
|
#define ANIM_RUNNING 0x08bf0222
|
||||||
|
#define ANIM_ROLLING 0x08890218
|
||||||
|
#define ANIM_SKIDDING 0x0a85024e
|
||||||
|
#define ANIM_PEELOUT 0x0849021f
|
||||||
|
#define ANIM_PUSHING 0x08b2021f
|
||||||
|
#define ANIM_CROUCHDOWN 0x104802fd
|
||||||
|
#define ANIM_LOOKUP 0x067001db
|
||||||
|
#define ANIM_SPRING 0x068e01d4
|
||||||
|
#define ANIM_HURT 0x031b0144
|
||||||
|
#define ANIM_DEATH 0x04200167
|
||||||
|
#+end_example
|
||||||
|
|
||||||
* Generating 8x8 tiles and their 16x16 mappings
|
* Generating 8x8 tiles and their 16x16 mappings
|
||||||
|
|
||||||
The following steps will allow you to create intermediate files 'tiles.png',
|
The following steps will allow you to create intermediate files 'tiles.png',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue