PoP roomtest (план v2, шаг 2): общая геометрия в pop_geom
Сведены дубли, разъехавшиеся по модулям: - x_bump[20] был в pop_kid (uint8_t!) и в pop_map (int16_t) — теперь одна таблица int16_t; - y_land[5] — две копии; - y_to_row_mod4 — в pop_bg и pop_map; - 32-битный LCG оригинала (prandom) — в pop_bg и pop_trob; функция теперь одна, а СИДЫ остались раздельными (у раскладки кладки и у фаз факелов свои последовательности, смешивать нельзя — иначе поедет рисунок стен). Экономия по коду скромная (_CODE 24462 -> 24421, W3 11643 -> 11632: часть выигрыша съели межмодульные вызовы). Главное здесь другое: pop_geom лежит в W1/W2 и не трогает графику, то есть это тот самый «чистый» слой, который сможет звать __banked-код стражей (docs/layout_plan_v2.md §4, §5.2). Проверено в MAME: комната 1 после пересборки отрисована ПОБАЙТОВО так же, как до правки (0 различающихся пикселей в области комнаты) — значит последовательности PRNG и геометрия не поехали; Kid бегает. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ MEMORY ?= small
|
|||||||
# __banked-модулей (стражи): из банка резидентная страница W3 не видна —
|
# __banked-модулей (стражи): из банка резидентная страница W3 не видна —
|
||||||
# ни напрямую, ни транзитивно. См. docs/layout_plan_v2.md §2 (R2), §4.
|
# ни напрямую, ни транзитивно. См. docs/layout_plan_v2.md §2 (R2), §4.
|
||||||
EXTRA_FLAGS ?= --gfx 256 --w3 pop_bg.c
|
EXTRA_FLAGS ?= --gfx 256 --w3 pop_bg.c
|
||||||
EXTRA_SRCS := pop_kid.c pop_ctrl.c pop_level.c pop_map.c pop_trob.c pop_redraw.c
|
EXTRA_SRCS := pop_kid.c pop_ctrl.c pop_level.c pop_map.c pop_trob.c pop_redraw.c pop_geom.c
|
||||||
|
|
||||||
BG_DIR := $(CURDIR)/../poc/res/bg
|
BG_DIR := $(CURDIR)/../poc/res/bg
|
||||||
KID_DIR := $(CURDIR)/../poc/res/kid
|
KID_DIR := $(CURDIR)/../poc/res/kid
|
||||||
@@ -42,4 +42,4 @@ $(KID_DATA): $(TC)/pop_pack_kid.py $(TC)/pop_pack_bg.py
|
|||||||
kid_data.h $(KID_BIN): $(TC)/pop_extract_kid_data.py
|
kid_data.h $(KID_BIN): $(TC)/pop_extract_kid_data.py
|
||||||
cd $(TC) && python3 pop_extract_kid_data.py
|
cd $(TC) && python3 pop_extract_kid_data.py
|
||||||
|
|
||||||
$(EXAMPLE).exe: pop_bg.c pop_bg.h pop_redraw.c pop_redraw.h pop_kid.c pop_kid.h pop_ctrl.c pop_ctrl.h pop_map.c pop_map.h pop_level.c pop_level.h pop_trob.c pop_trob.h kid_data.h $(BG_DATA) $(KID_DATA) $(KID_BIN) $(LVL_DATA)
|
$(EXAMPLE).exe: pop_bg.c pop_bg.h pop_geom.c pop_geom.h pop_redraw.c pop_redraw.h pop_kid.c pop_kid.h pop_ctrl.c pop_ctrl.h pop_map.c pop_map.h pop_level.c pop_level.h pop_trob.c pop_trob.h kid_data.h $(BG_DATA) $(KID_DATA) $(KID_BIN) $(LVL_DATA)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "pop_bg.h"
|
#include "pop_bg.h"
|
||||||
|
#include "pop_geom.h"
|
||||||
#include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */
|
#include "pop_level.h" /* pop_doorlink2 — состояние нажатия кнопки */
|
||||||
#include "pop_kid.h" /* Kid.curr_col/curr_row — порядок оверлеев (см. ниже) */
|
#include "pop_kid.h" /* Kid.curr_col/curr_row — порядок оверлеев (см. ниже) */
|
||||||
|
|
||||||
@@ -311,11 +312,7 @@ static uint8_t wall_modifier(int row, int col)
|
|||||||
/* ---- PRNG (seg009.c:321, 32-бит LCG) — только на ВХОД в комнату ---- */
|
/* ---- PRNG (seg009.c:321, 32-бит LCG) — только на ВХОД в комнату ---- */
|
||||||
static unsigned long rnd_seed;
|
static unsigned long rnd_seed;
|
||||||
|
|
||||||
static uint16_t prandom(uint16_t maxv)
|
#define prandom(maxv) pop_prandom(&rnd_seed, (maxv))
|
||||||
{
|
|
||||||
rnd_seed = rnd_seed * 214013UL + 2531011UL;
|
|
||||||
return (uint16_t)((uint16_t)(rnd_seed >> 16) % (uint16_t)(maxv + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- Декали-марки стен (seg008.c:2041/2056) ------------------------ */
|
/* ---- Декали-марки стен (seg008.c:2041/2056) ------------------------ */
|
||||||
static void draw_left_mark(uint16_t dv, int arg2, int arg1, int row, int col)
|
static void draw_left_mark(uint16_t dv, int arg2, int arg1, int row, int col)
|
||||||
@@ -1125,10 +1122,7 @@ static int8_t col_from_x(int xpos) /* get_tile_div_mod: колонка (
|
|||||||
return (int8_t)xh;
|
return (int8_t)xh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int8_t y_to_row(int y) /* y_to_row_mod4 (seg006, TILE_SIZEY=63) */
|
#define y_to_row(y) pop_y_to_row((int16_t)(y)) /* общий (pop_geom) */
|
||||||
{
|
|
||||||
return (int8_t)((y + 60) / 63 % 4 - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fore_only_tile(int row, int col)
|
static void fore_only_tile(int row, int col)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* pop_geom.c — общая геометрия + PRNG оригинала. См. pop_geom.h.
|
||||||
|
*/
|
||||||
|
#include "pop_geom.h"
|
||||||
|
|
||||||
|
/* data.h: шаг 14 (ширина тайла в координатах персонажа), [5] = col 0. */
|
||||||
|
const int16_t pop_x_bump[20] = {
|
||||||
|
-12, 2, 16, 30, 44, 58, 72, 86, 100, 114,
|
||||||
|
128, 142, 156, 170, 184, 198, 212, 226, 240, 254
|
||||||
|
};
|
||||||
|
const int16_t pop_y_land[5] = {-8, 55, 118, 181, 244};
|
||||||
|
|
||||||
|
int8_t pop_y_to_row(int16_t y)
|
||||||
|
{
|
||||||
|
return (int8_t)((y + 60) / TILE_SIZEY % 4 - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t pop_prandom(unsigned long *seed, uint16_t maxv)
|
||||||
|
{
|
||||||
|
unsigned long s = *seed * 214013UL + 2531011UL;
|
||||||
|
*seed = s;
|
||||||
|
return (uint16_t)((uint16_t)(s >> 16) % (uint16_t)(maxv + 1));
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* pop_geom.h — общая геометрия PoP и PRNG оригинала.
|
||||||
|
*
|
||||||
|
* Сюда сведено то, что раньше дублировалось по модулям (x_bump/y_land в
|
||||||
|
* pop_kid и pop_map, y_to_row в pop_bg и pop_map, 32-битный LCG в pop_bg и
|
||||||
|
* pop_trob). Кроме экономии это ФУНДАМЕНТ bank-safe API: модуль живёт в
|
||||||
|
* W1/W2 и не трогает графику, поэтому его может звать и главный цикл, и
|
||||||
|
* резидент W3, и будущий __banked-код стражей (docs/layout_plan_v2.md §4).
|
||||||
|
*/
|
||||||
|
#ifndef POP_GEOM_H
|
||||||
|
#define POP_GEOM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FIRST_ONSCREEN_COLUMN 5 /* индекс col 0 комнаты в x_bump */
|
||||||
|
#define TILE_SIZEX 14 /* ширина тайла в координатах персонажа */
|
||||||
|
#define TILE_SIZEY 63 /* высота ряда */
|
||||||
|
|
||||||
|
/* x_bump (data.h): левая граница колонки в координатах персонажа; колонка
|
||||||
|
* комнаты col = x_bump[col + FIRST_ONSCREEN_COLUMN]. y_land: пол ряда
|
||||||
|
* (индекс row+1; [0] — ряд «над комнатой»). */
|
||||||
|
extern const int16_t pop_x_bump[20];
|
||||||
|
extern const int16_t pop_y_land[5];
|
||||||
|
|
||||||
|
/* y_to_row_mod4 (seg006): ряд по координате y с оборотом mod 4 (−1 = полоса
|
||||||
|
* над комнатой, 3 = под комнатой). */
|
||||||
|
int8_t pop_y_to_row(int16_t y);
|
||||||
|
|
||||||
|
/* prandom (seg009:321) — 32-битный LCG оригинала. Сид ВНЕШНИЙ: у стен
|
||||||
|
* (раскладка кладки) и у анимаций тайлов (фаза факелов) свои
|
||||||
|
* последовательности, смешивать их нельзя. */
|
||||||
|
uint16_t pop_prandom(unsigned long *seed, uint16_t maxv);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "pop_kid.h"
|
#include "pop_kid.h"
|
||||||
#include "pop_bg.h" /* POP_YOFF — вертикальное центрирование */
|
#include "pop_bg.h" /* POP_YOFF — вертикальное центрирование */
|
||||||
#include "pop_map.h" /* pop_clip_char_top (clip_char) */
|
#include "pop_map.h" /* pop_clip_char_top (clip_char) */
|
||||||
|
#include "pop_geom.h"
|
||||||
#include "kid_data.h"
|
#include "kid_data.h"
|
||||||
|
|
||||||
kid_t Kid;
|
kid_t Kid;
|
||||||
@@ -20,14 +21,6 @@ kid_t Kid;
|
|||||||
* в play_seq, потребляется pop_check_knock (pop_map) — трясёт loose-полы. */
|
* в play_seq, потребляется pop_check_knock (pop_map) — трясёт loose-полы. */
|
||||||
int8_t knock;
|
int8_t knock;
|
||||||
|
|
||||||
/* Координатные таблицы (data.h). */
|
|
||||||
static const uint8_t x_bump[20] = {
|
|
||||||
(uint8_t)-12, 2, 16, 30, 44, 58, 72, 86, 100, 114,
|
|
||||||
128, 142, 156, 170, 184, 198, 212, 226, 240, 254
|
|
||||||
};
|
|
||||||
static const int16_t y_land[5] = {-8, 55, 118, 181, 244};
|
|
||||||
#define FIRST_ONSCREEN_COLUMN 5
|
|
||||||
#define TILE_SIZEX 14
|
|
||||||
|
|
||||||
/* ---- Атласы Kid (прямая адресация image>>3) ------------------------ */
|
/* ---- Атласы Kid (прямая адресация image>>3) ------------------------ */
|
||||||
#define KID_MAXPAGES 28
|
#define KID_MAXPAGES 28
|
||||||
@@ -258,8 +251,8 @@ void kid_init(uint8_t seq_id, int8_t col, int8_t row, int8_t dir)
|
|||||||
Kid.curr_col = col;
|
Kid.curr_col = col;
|
||||||
Kid.curr_row = row;
|
Kid.curr_row = row;
|
||||||
Kid.direction = dir;
|
Kid.direction = dir;
|
||||||
Kid.x = (uint8_t)(x_bump[col + FIRST_ONSCREEN_COLUMN] + TILE_SIZEX);
|
Kid.x = (uint8_t)(pop_x_bump[col + FIRST_ONSCREEN_COLUMN] + TILE_SIZEX);
|
||||||
Kid.y = (uint8_t)y_land[row + 1];
|
Kid.y = (uint8_t)pop_y_land[row + 1];
|
||||||
Kid.fall_x = Kid.fall_y = 0;
|
Kid.fall_x = Kid.fall_y = 0;
|
||||||
Kid.repeat = 0;
|
Kid.repeat = 0;
|
||||||
Kid.curr_seq = kid_seq_off[seq_id];
|
Kid.curr_seq = kid_seq_off[seq_id];
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* FRAME_NEEDS_FLOOR (0x40), под персонажем не floor -> start_fall();
|
* FRAME_NEEDS_FLOOR (0x40), под персонажем не floor -> start_fall();
|
||||||
* стена -> in_wall();
|
* стена -> in_wall();
|
||||||
* freefall (action 4) -> do_fall(): fall_y-ускорение (в fall_accel/speed),
|
* freefall (action 4) -> do_fall(): fall_y-ускорение (в fall_accel/speed),
|
||||||
* достиг y_land[curr_row+1] -> land()/inc_curr_row.
|
* достиг pop_y_land[curr_row+1] -> land()/inc_curr_row.
|
||||||
*
|
*
|
||||||
* Координатная система PoP: экран.left = 58, тайл = 14 ед. (TILE_SIZEX);
|
* Координатная система PoP: экран.left = 58, тайл = 14 ед. (TILE_SIZEX);
|
||||||
* col = (xpos-58)/14 (округл. вниз), xl = остаток; get_tile_div_mod_m7 =
|
* col = (xpos-58)/14 (округл. вниз), xl = остаток; get_tile_div_mod_m7 =
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "pop_kid.h"
|
#include "pop_kid.h"
|
||||||
#include "pop_map.h"
|
#include "pop_map.h"
|
||||||
#include "pop_ctrl.h" /* pop_ctrl_shift_held() — для check_grab */
|
#include "pop_ctrl.h" /* pop_ctrl_shift_held() — для check_grab */
|
||||||
|
#include "pop_geom.h" /* общая геометрия (x_bump/y_land/y_to_row) */
|
||||||
#include "pop_redraw.h" /* пометки перерисовки (порт set_redraw_*) */
|
#include "pop_redraw.h" /* пометки перерисовки (порт set_redraw_*) */
|
||||||
/* pop_bg нужен ТОЛЬКО падающему куску (mob): spawn/tick/pos — это движущийся
|
/* pop_bg нужен ТОЛЬКО падающему куску (mob): spawn/tick/pos — это движущийся
|
||||||
* ОБЪЕКТ, а не перерисовка тайла (в оригинале он и живёт отдельно: mobs +
|
* ОБЪЕКТ, а не перерисовка тайла (в оригинале он и живёт отдельно: mobs +
|
||||||
@@ -88,23 +89,17 @@
|
|||||||
|
|
||||||
#define FRAME_NEEDS_FLOOR 0x40
|
#define FRAME_NEEDS_FLOOR 0x40
|
||||||
#define FRAME_WEIGHT_X 0x1F
|
#define FRAME_WEIGHT_X 0x1F
|
||||||
#define TILE_SIZEX 14
|
|
||||||
#define TILE_RIGHTX 13
|
#define TILE_RIGHTX 13
|
||||||
#define SCREENSPACE_X 58
|
#define SCREENSPACE_X 58
|
||||||
#define FALL_ACCEL 3
|
#define FALL_ACCEL 3
|
||||||
#define FALL_MAX 33
|
#define FALL_MAX 33
|
||||||
|
|
||||||
#define TILE_MIDX 7
|
#define TILE_MIDX 7
|
||||||
#define FIRST_ONSCREEN_COLUMN 5
|
|
||||||
#define FRAME_THIN 0x20
|
#define FRAME_THIN 0x20
|
||||||
|
|
||||||
static const int16_t y_land[5] = {-8, 55, 118, 181, 244};
|
|
||||||
static const int8_t dir_front[2] = {-1, 1}; /* [dir+1]: dir=-1->-1, 0->+1 */
|
static const int8_t dir_front[2] = {-1, 1}; /* [dir+1]: dir=-1->-1, 0->+1 */
|
||||||
static const int8_t dir_behind[2] = {1, -1}; /* [dir+1]: назад по направлению */
|
static const int8_t dir_behind[2] = {1, -1}; /* [dir+1]: назад по направлению */
|
||||||
static const int16_t x_bump[20] = {
|
|
||||||
-12, 2, 16, 30, 44, 58, 72, 86, 100, 114,
|
|
||||||
128, 142, 156, 170, 184, 198, 212, 226, 240, 254
|
|
||||||
};
|
|
||||||
/* wall_type(tile): gate/doortop=1, mirror=2, chomper=3, wall=4, иначе 0. */
|
/* wall_type(tile): gate/doortop=1, mirror=2, chomper=3, wall=4, иначе 0. */
|
||||||
static const int8_t wall_dl[6] = {0, 10, 0, -1, 0, 0}; /* wall_dist_from_left */
|
static const int8_t wall_dl[6] = {0, 10, 0, -1, 0, 0}; /* wall_dist_from_left */
|
||||||
static const int8_t wall_dr[6] = {0, 0, 10, 13, 0, 0}; /* wall_dist_from_right */
|
static const int8_t wall_dr[6] = {0, 0, 10, 13, 0, 0}; /* wall_dist_from_right */
|
||||||
@@ -372,7 +367,7 @@ static int dist_from_wall_forward(uint8_t tiletype, int8_t tcol)
|
|||||||
uint8_t type = wall_type(tiletype);
|
uint8_t type = wall_type(tiletype);
|
||||||
int coll_left, cx;
|
int coll_left, cx;
|
||||||
if (type == 0) return 127;
|
if (type == 0) return 127;
|
||||||
coll_left = x_bump[tcol + FIRST_ONSCREEN_COLUMN] + TILE_MIDX;
|
coll_left = pop_x_bump[tcol + FIRST_ONSCREEN_COLUMN] + TILE_MIDX;
|
||||||
cx = char_front_coll();
|
cx = char_front_coll();
|
||||||
if (Kid.direction < 0) /* лицом влево */
|
if (Kid.direction < 0) /* лицом влево */
|
||||||
return cx - (coll_left + TILE_RIGHTX - wall_dr[type]);
|
return cx - (coll_left + TILE_RIGHTX - wall_dr[type]);
|
||||||
@@ -428,7 +423,7 @@ static uint8_t fell_on_spikes(void)
|
|||||||
static void land(void)
|
static void land(void)
|
||||||
{
|
{
|
||||||
uint8_t seq;
|
uint8_t seq;
|
||||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1];
|
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1];
|
||||||
if (fell_on_spikes()) return; /* упал на вредные пики — смерть */
|
if (fell_on_spikes()) return; /* упал на вредные пики — смерть */
|
||||||
/* к краю пола — чуть назад (как оригинал) */
|
/* к краю пола — чуть назад (как оригинал) */
|
||||||
if (!tile_is_floor(get_tile_infrontof_char()) && distance_to_edge_weight() < 3)
|
if (!tile_is_floor(get_tile_infrontof_char()) && distance_to_edge_weight() < 3)
|
||||||
@@ -523,7 +518,7 @@ static void check_grab(void)
|
|||||||
uint8_t old_x;
|
uint8_t old_x;
|
||||||
if (!pop_ctrl_shift_held()) return; /* Shift не зажат */
|
if (!pop_ctrl_shift_held()) return; /* Shift не зажат */
|
||||||
if ((uint8_t)Kid.fall_y >= 32) return; /* падает слишком быстро */
|
if ((uint8_t)Kid.fall_y >= 32) return; /* падает слишком быстро */
|
||||||
if ((uint16_t)y_land[Kid.curr_row + 1] > (uint16_t)(Kid.y + 25)) return;
|
if ((uint16_t)pop_y_land[Kid.curr_row + 1] > (uint16_t)(Kid.y + 25)) return;
|
||||||
old_x = Kid.x;
|
old_x = Kid.x;
|
||||||
Kid.x = (uint8_t)char_dx_forward(-8);
|
Kid.x = (uint8_t)char_dx_forward(-8);
|
||||||
determine_col();
|
determine_col();
|
||||||
@@ -532,7 +527,7 @@ static void check_grab(void)
|
|||||||
determine_col();
|
determine_col();
|
||||||
} else {
|
} else {
|
||||||
Kid.x = (uint8_t)char_dx_forward((int8_t)distance_to_edge_weight());
|
Kid.x = (uint8_t)char_dx_forward((int8_t)distance_to_edge_weight());
|
||||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1];
|
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1];
|
||||||
Kid.fall_y = 0;
|
Kid.fall_y = 0;
|
||||||
kid_set_seq(SEQ_15_GRAB_LEDGE_MIDAIR);
|
kid_set_seq(SEQ_15_GRAB_LEDGE_MIDAIR);
|
||||||
play_seq();
|
play_seq();
|
||||||
@@ -544,8 +539,8 @@ static void check_grab(void)
|
|||||||
static void do_fall(void)
|
static void do_fall(void)
|
||||||
{
|
{
|
||||||
uint8_t nrow = (uint8_t)(Kid.curr_row + 1);
|
uint8_t nrow = (uint8_t)(Kid.curr_row + 1);
|
||||||
if (nrow > 4) nrow = 4; /* защита y_land[] от выхода */
|
if (nrow > 4) nrow = 4; /* защита pop_y_land[] от выхода */
|
||||||
if ((uint16_t)y_land[nrow] > (uint16_t)Kid.y) {
|
if ((uint16_t)pop_y_land[nrow] > (uint16_t)Kid.y) {
|
||||||
check_grab(); /* ещё летит — попытка зацепа */
|
check_grab(); /* ещё летит — попытка зацепа */
|
||||||
} else {
|
} else {
|
||||||
if (get_tile_at_char() == TILE_WALL)
|
if (get_tile_at_char() == TILE_WALL)
|
||||||
@@ -905,11 +900,11 @@ static void bumped_floor(void)
|
|||||||
uint8_t frame;
|
uint8_t frame;
|
||||||
/* Оригинал сравнивает БЕЗЗНАКОВО: если персонаж НИЖЕ уровня пола,
|
/* Оригинал сравнивает БЕЗЗНАКОВО: если персонаж НИЖЕ уровня пола,
|
||||||
* разность заворачивается в большое число и тоже даёт «падать». */
|
* разность заворачивается в большое число и тоже даёт «падать». */
|
||||||
if ((uint16_t)(y_land[Kid.curr_row + 1] - (int16_t)Kid.y) >= 15) {
|
if ((uint16_t)(pop_y_land[Kid.curr_row + 1] - (int16_t)Kid.y) >= 15) {
|
||||||
bumped_fall(); /* высоко над полом — в воздухе */
|
bumped_fall(); /* высоко над полом — в воздухе */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1]; /* ПРИЖАТЬ к полу */
|
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1]; /* ПРИЖАТЬ к полу */
|
||||||
if (Kid.fall_y >= 22) { /* влетел быстро — только отжать */
|
if (Kid.fall_y >= 22) { /* влетел быстро — только отжать */
|
||||||
Kid.x = (uint8_t)char_dx_forward(-5);
|
Kid.x = (uint8_t)char_dx_forward(-5);
|
||||||
return;
|
return;
|
||||||
@@ -947,7 +942,7 @@ static void check_bumped(void)
|
|||||||
* hang->hang_fall->seq_11 (правильное приземление). */
|
* hang->hang_fall->seq_11 (правильное приземление). */
|
||||||
if (Kid.frame >= 87 && Kid.frame < 100) return;
|
if (Kid.frame >= 87 && Kid.frame < 100) return;
|
||||||
/* Вне рядов комнаты (падение мимо пола): get_tile даёт WALL, а
|
/* Вне рядов комнаты (падение мимо пола): get_tile даёт WALL, а
|
||||||
* dist_from_wall_forward/x_bump[] — мусор с большим отриц. сдвигом →
|
* dist_from_wall_forward/pop_x_bump[] — мусор с большим отриц. сдвигом →
|
||||||
* underflow X и уход в стену. fell_out ловит do_fall. */
|
* underflow X и уход в стену. fell_out ловит do_fall. */
|
||||||
if (Kid.curr_row < 0 || Kid.curr_row > 2) return;
|
if (Kid.curr_row < 0 || Kid.curr_row > 2) return;
|
||||||
/* seg004 check_collisions: на кадрах разворота коллизии НЕ считаются
|
/* seg004 check_collisions: на кадрах разворота коллизии НЕ считаются
|
||||||
@@ -978,7 +973,7 @@ static void check_bumped(void)
|
|||||||
{
|
{
|
||||||
uint8_t f = 0, prev, need;
|
uint8_t f = 0, prev, need;
|
||||||
if (wt) {
|
if (wt) {
|
||||||
int coll_left = x_bump[tcol + FIRST_ONSCREEN_COLUMN] + TILE_MIDX;
|
int coll_left = pop_x_bump[tcol + FIRST_ONSCREEN_COLUMN] + TILE_MIDX;
|
||||||
int lw = wall_dl[wt] + coll_left; /* get_left_wall_xpos */
|
int lw = wall_dl[wt] + coll_left; /* get_left_wall_xpos */
|
||||||
int rw = coll_left - wall_dr[wt] + TILE_RIGHTX; /* get_right_wall_xpos */
|
int rw = coll_left - wall_dr[wt] + TILE_RIGHTX; /* get_right_wall_xpos */
|
||||||
int e = char_x_forward_edge(), wh = ((int)kid_fp_width() + 1) >> 1;
|
int e = char_x_forward_edge(), wh = ((int)kid_fp_width() + 1) >> 1;
|
||||||
@@ -1157,7 +1152,7 @@ static void fell_on_your_head(void)
|
|||||||
uint8_t frame = Kid.frame, action = Kid.action;
|
uint8_t frame = Kid.frame, action = Kid.action;
|
||||||
if ((frame < 5 || frame >= 15) &&
|
if ((frame < 5 || frame >= 15) &&
|
||||||
(action < ACT_HANGCLIMB || action == ACT_TURN)) {
|
(action < ACT_HANGCLIMB || action == ACT_TURN)) {
|
||||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1];
|
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1];
|
||||||
pop_kid_hurt = 1; /* hitp_delta<0 → draw_hurt_splash */
|
pop_kid_hurt = 1; /* hitp_delta<0 → draw_hurt_splash */
|
||||||
if (take_hp(1)) {
|
if (take_hp(1)) {
|
||||||
kid_set_seq(SEQ_22_CRUSHED);
|
kid_set_seq(SEQ_22_CRUSHED);
|
||||||
@@ -1269,8 +1264,7 @@ void pop_loose_tick(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* y_to_row_mod4 (seg006): ряд по y с оборотом mod4 (TILE_SIZEY=63). */
|
|
||||||
static int8_t y_to_row(int16_t y) { return (int8_t)(((y + 60) / 63) % 4 - 1); }
|
|
||||||
|
|
||||||
/* ---- clip_char (seg006:1749), первый блок: обрезка спрайта СВЕРХУ ----- *
|
/* ---- clip_char (seg006:1749), первый блок: обрезка спрайта СВЕРХУ ----- *
|
||||||
* Оригинал перед add_objtable кладёт в objtable прямоугольник клипа; блиттер
|
* Оригинал перед add_objtable кладёт в objtable прямоугольник клипа; блиттер
|
||||||
@@ -1299,7 +1293,7 @@ int pop_clip_char_top(int obj_x, int obj_y, uint16_t w, uint16_t h)
|
|||||||
xr = xl + wh; /* char_x_right */
|
xr = xl + wh; /* char_x_right */
|
||||||
top_y = obj_y - (int)h + 1; /* char_top_y */
|
top_y = obj_y - (int)h + 1; /* char_top_y */
|
||||||
if (top_y >= 192) top_y = 0; /* весь спрайт ниже комнаты */
|
if (top_y >= 192) top_y = 0; /* весь спрайт ниже комнаты */
|
||||||
trow = y_to_row((int16_t)top_y); /* char_top_row */
|
trow = pop_y_to_row((int16_t)top_y); /* char_top_row */
|
||||||
cL = get_tile_div_mod(xl); if (cL < 0) cL = 0;
|
cL = get_tile_div_mod(xl); if (cL < 0) cL = 0;
|
||||||
cR = get_tile_div_mod(xr); if (cR > 9) cR = 9;
|
cR = get_tile_div_mod(xr); if (cR > 9) cR = 9;
|
||||||
|
|
||||||
@@ -1337,13 +1331,13 @@ static void check_leave_below(void)
|
|||||||
Kid.action != ACT_MIDAIR &&
|
Kid.action != ACT_MIDAIR &&
|
||||||
(int8_t)Kid.y < 10 && (int8_t)Kid.y > -16) {
|
(int8_t)Kid.y < 10 && (int8_t)Kid.y > -16) {
|
||||||
Kid.y = (uint8_t)(Kid.y + 189);
|
Kid.y = (uint8_t)(Kid.y + 189);
|
||||||
Kid.curr_row = y_to_row((int16_t)Kid.y);
|
Kid.curr_row = pop_y_to_row((int16_t)Kid.y);
|
||||||
pop_leave_dir = 3;
|
pop_leave_dir = 3;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Kid.y >= 211) {
|
if (Kid.y >= 211) {
|
||||||
Kid.y = (uint8_t)(Kid.y - 189);
|
Kid.y = (uint8_t)(Kid.y - 189);
|
||||||
Kid.curr_row = y_to_row((int16_t)Kid.y);
|
Kid.curr_row = pop_y_to_row((int16_t)Kid.y);
|
||||||
pop_fell_out = 1;
|
pop_fell_out = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1429,8 +1423,8 @@ static int is_spike_harmful(uint8_t tilepos)
|
|||||||
static void spiked(uint8_t tilepos)
|
static void spiked(uint8_t tilepos)
|
||||||
{
|
{
|
||||||
pop_trob_modif(g_room)[tilepos] = 0xFF;
|
pop_trob_modif(g_room)[tilepos] = 0xFF;
|
||||||
Kid.y = (uint8_t)y_land[Kid.curr_row + 1];
|
Kid.y = (uint8_t)pop_y_land[Kid.curr_row + 1];
|
||||||
Kid.x = (uint8_t)(x_bump[Kid.curr_col + FIRST_ONSCREEN_COLUMN] + 10);
|
Kid.x = (uint8_t)(pop_x_bump[Kid.curr_col + FIRST_ONSCREEN_COLUMN] + 10);
|
||||||
Kid.x = (uint8_t)char_dx_forward(8);
|
Kid.x = (uint8_t)char_dx_forward(8);
|
||||||
Kid.fall_y = 0;
|
Kid.fall_y = 0;
|
||||||
take_hp(100); /* (TODO: sound_48_spiked) */
|
take_hp(100); /* (TODO: sound_48_spiked) */
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "pop_trob.h"
|
#include "pop_trob.h"
|
||||||
#include "pop_level.h"
|
#include "pop_level.h"
|
||||||
|
#include "pop_geom.h"
|
||||||
#include "pop_redraw.h" /* пометки перерисовки тайлов (вместо прямых вызовов) */
|
#include "pop_redraw.h" /* пометки перерисовки тайлов (вместо прямых вызовов) */
|
||||||
/* pop_bg нужен ТОЛЬКО для пламени факела и пузырька зелья: это не тайловая
|
/* pop_bg нужен ТОЛЬКО для пламени факела и пузырька зелья: это не тайловая
|
||||||
* перерисовка, а покадровый оверлей поверх фона (в оригинале — свои
|
* перерисовка, а покадровый оверлей поверх фона (в оригинале — свои
|
||||||
@@ -48,11 +49,7 @@ static uint8_t trob_drawn[POP_ROOMTILES];
|
|||||||
* выбора следующего кадра пламени. */
|
* выбора следующего кадра пламени. */
|
||||||
static unsigned long trob_seed;
|
static unsigned long trob_seed;
|
||||||
|
|
||||||
static uint16_t trob_prandom(uint16_t maxv)
|
#define trob_prandom(maxv) pop_prandom(&trob_seed, (maxv))
|
||||||
{
|
|
||||||
trob_seed = trob_seed * 214013UL + 2531011UL;
|
|
||||||
return (uint16_t)((uint16_t)(trob_seed >> 16) % (uint16_t)(maxv + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pop_trob_reset(void)
|
void pop_trob_reset(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user