Фиксированный логический кадр по лучу + режимы FASTEST/FAST/NORMAL
Период стал max(n, ceil(W)) вместо ceil(W)+2: три gfx_wait_vsync после работы отсчитывались от её КОНЦА, поэтому бюджет кадра был один растр. Теперь ждём от якоря начала кадра, и при n=3 бюджет 1 290 240 тактов. Счёт кадров — программный, по биту 5 порта 0xFE (положение луча), а не по кадровым прерываниям: те теряются в DI-окнах акселератора фазозависимо (замер: 0..2,8 %, на полной перерисовке три подряд). Условие точности одно — зазор между выборками меньше 64 512 тактов; точки выборки расставлены по замеру, а не на глаз. Режимы (pop_pace.h), клавиша P по кругу, дефолт FASTEST. Условие боя взято у оригинала буквально (SDLPoP seg003.c:363): Kid.sword == SWORD_2_DRAWN, а не «идёт бой». Проверено в MAME на 11/15: счётчик без недосчёта на 270 кадров, период ровно 3 растра на 302 логических кадрах (ни длиннее 3,1, ни короче 2,9), NORMAL даёт ровно 4, с вынутым мечом — ровно 5.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "pop_bg.h"
|
||||
#include "pop_pace.h" /* pop_beam_sample — счёт кадров по лучу */
|
||||
#include "_pop_bg.h" /* контракт с холодной половиной (pop_room.c, банк 7) */
|
||||
#include "pop_tile.h"
|
||||
#include "pop_map.h" /* pop_upside — переворот (зелье инверсии) */ /* общие листья слоя фона (резидент): блит, тайлы, таблица */
|
||||
@@ -57,6 +58,7 @@ static void ov_mark(int x, int y, int w, int h)
|
||||
|
||||
void pop_fore_heal(void) __banked
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
uint8_t pg = gfx_get_draw_page() & 1;
|
||||
if (!(ov_pending & (1 << pg))) return;
|
||||
pop_heal_off(ov_x0, ov_y0, ov_x1 - ov_x0, ov_y1 - ov_y0);
|
||||
@@ -197,6 +199,7 @@ static const uint8_t WR_RULE[4][6] = {
|
||||
|
||||
static void wall_rnd(int row, int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
/* Кэшируем только штатную сетку: колонка вне 0..9 дала бы индекс
|
||||
* соседнего РЯДА и чужую раскладку (тихий баг вместо промаха). */
|
||||
int idx = (col >= 0 && col < 10) ? (row + 1) * 10 + col : -1;
|
||||
@@ -282,6 +285,7 @@ static uint8_t wpp_d[5]; /* пять prandom(2), 0..2 */
|
||||
|
||||
static void wall_rnd_palace(int row, int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int idx = (col >= 0 && col < 10) ? (row + 1) * 10 + col : -1;
|
||||
pop_rnd_t saved;
|
||||
uint8_t i;
|
||||
@@ -366,6 +370,7 @@ static void wpp_fill(int x, int ytop, int w, int h, uint8_t colour)
|
||||
|
||||
static void wall_pattern_palace(int row, int col, int which_part)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int xh = POP_COL_XH[col];
|
||||
int dbys = 63 * row + 65; /* база БЕЗ POP_YOFF — для блитов */
|
||||
int dmys = dbys - 3;
|
||||
@@ -411,6 +416,7 @@ static void wall_pattern_palace(int row, int col, int which_part)
|
||||
|
||||
static void wall_pattern(int row, int col, int which_part)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int xh = POP_COL_XH[col];
|
||||
int dby = 63 * row + 65;
|
||||
uint8_t parts;
|
||||
@@ -450,6 +456,7 @@ static void wall_pattern(int row, int col, int which_part)
|
||||
/* Решётка ворот (portcullis) из ЛЕВОЙ комнаты (seg008.c:1110). */
|
||||
static void draw_gate_back(uint8_t modl, int xh, int dby, int dmy)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int x = xh * 8;
|
||||
int gate_top_y = dby - 62;
|
||||
int openness = (((modl > 188) ? 188 : modl) >> 2) + 1;
|
||||
@@ -480,6 +487,7 @@ static void draw_gate_back(uint8_t modl, int xh, int dby, int dmy)
|
||||
* Клип по прямоугольнику персонажа делает pop_t_fclip (см. pop_tile.h). */
|
||||
static void draw_gate_fore(uint8_t modl, int xh, int dby, int dmy)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int x = xh * 8;
|
||||
int gate_top_y = dby - 62;
|
||||
int openness = (((modl > 188) ? 188 : modl) >> 2) + 1;
|
||||
@@ -576,6 +584,7 @@ static const uint8_t FORE_ANY[32] = {
|
||||
/* Контекст ft_* обязан быть проставлен вызывающим. */
|
||||
static void fore_only_tile(int row, int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
/* Нажатая кнопка → пол/stuck (get_tile_to_draw) — это уже учтено в ft_code
|
||||
* (его ставит pop_tile_code_drawn), иначе поверх Kid лезет передняя грань
|
||||
* КНОПКИ. */
|
||||
@@ -622,6 +631,7 @@ static void fore_only_tile(int row, int col)
|
||||
* backtable — под персонажем. */
|
||||
static void ceil_over_kid_tile(int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
uint8_t code = pop_tile_code(-1, col);
|
||||
const piece *t = &pop_tile_table[code];
|
||||
int x = POP_COL_XH[col] * 8;
|
||||
@@ -711,6 +721,7 @@ static void other_overlay_tile(int row, int col); /* fwd (draw_floor_overlay -
|
||||
|
||||
static void climb_overlay_tile(int row, int col, uint8_t fidx)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
/* тип — ПОДСТАВЛЕННЫЙ (нажатая кнопка = пол): иначе кромка, за которую
|
||||
* Kid спускается/подтягивается, закрашивается целым тайлом */
|
||||
uint8_t code;
|
||||
@@ -747,6 +758,7 @@ static void climb_overlay_tile(int row, int col, uint8_t fidx)
|
||||
* draw_tile_base, draw_tile_anim (свои пики) и draw_tile_bottom. */
|
||||
static void overlay_mid_tile(int row, int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
uint8_t code = pop_tile_code_drawn(row, col);
|
||||
uint8_t lcode = pop_tile_code_drawn(row, col - 1);
|
||||
const piece *t;
|
||||
@@ -809,6 +821,7 @@ static void overlay_mid_tile(int row, int col)
|
||||
* сразу), поэтому порядок эмулируется явной проверкой. */
|
||||
static void other_overlay_tile(int row, int col)
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
uint8_t code, left;
|
||||
if (!tile_in_fclip(row, col)) return;
|
||||
code = pop_tile_code(row, col);
|
||||
@@ -853,6 +866,7 @@ static void other_overlay_tile(int row, int col)
|
||||
void pop_mob_overlay_tile(int row, int col, int8_t oref_row, int8_t oref_col,
|
||||
int mx, int my, uint8_t mh) __banked
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int8_t saved_row = pop_bg_obj_row, saved_col = pop_bg_obj_col;
|
||||
pop_bg_obj_row = oref_row;
|
||||
pop_bg_obj_col = oref_col;
|
||||
@@ -952,6 +966,7 @@ static void char_footprint(int obj_x, int obj_y, uint16_t w, uint16_t h,
|
||||
* ничем не режется. */
|
||||
void pop_fore_tile_b(int row, int col) __banked
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
uint8_t saved = pop_t_fclip_on;
|
||||
pop_t_fclip_on = 0;
|
||||
fore_tile(row, col);
|
||||
@@ -974,6 +989,7 @@ void pop_fore_tile_b(int row, int col) __banked
|
||||
* странице её надо будет восстановить (pop_fore_heal). */
|
||||
void pop_ceil_fore_tile_b(int col) __banked
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int x = POP_COL_XH[col] * 8;
|
||||
/* ov_mark ЗДЕСЬ НЕ НУЖЕН, и это важно для бюджета. Передние куски потолка
|
||||
* рисуются от dby = 2, то есть занимают строки 0..2 поля, а пометку ставит
|
||||
@@ -999,6 +1015,7 @@ void pop_fore_pass_end(void) __banked { gfx_set_bank(GFX_BANK_NORMAL); }
|
||||
void pop_fore_over_char(const pop_char_t *ch, int obj_x, int obj_y,
|
||||
uint16_t w, uint16_t h) __banked
|
||||
{
|
||||
pop_beam_sample(); /* ТЕМП КАДРА: выборка луча (pop_pace.h) */
|
||||
int8_t cL, cR, cLraw, rT, rB, rTraw, r, c;
|
||||
uint8_t frame = ch->frame, action = ch->action;
|
||||
pop_t_fclip_on = 1; /* окно = прямоугольник спрайта */
|
||||
|
||||
Reference in New Issue
Block a user