Files
Sprinter-SDCC/libc/mem/bank_load_file.c
T
snark13 ba3aca07bf Архивы ресурсов PBA1: звук одним файлом, музыка потоком; ALLOCS 6000
ЗАМЕР, из которого всё выросло (MAME, 2026-08-25): `open` стоит 51,4 мс,
а чтение 16 КБ из уже открытого файла — 32,6 мс.  То есть 61 % времени
загрузки уходит на ОТКРЫТИЕ, а не на данные, и чистая скорость чтения —
491 КБ/с, а не 260.  На диске игры 343 файла; одна только стартовая пачка
(kid+shadow+bg+sound+guard, ~142 файла) — это 7,3 секунды чистого open.

* toolchain/pop_pack_arc.py + pop_arc.c/h (банк 8) — формат PBA1:
  заголовок 512 Б, магия, count, записи по 4 байта (offset в СЕКТОРАХ —
  архив бывает больше 64 КБ; size в байтах — ресурс всегда <= 16 КБ,
  он обязан лезть в EMM-страницу).  Таблицу держит вызывающий на своём
  стеке: в W2 её класть нельзя, а стека в точке загрузки израсходовано
  75 байт из 1279 (замер там же).
* libc: bank_read_page — чтение из УЖЕ ОТКРЫТОГО файла в EMM-страницу.
  bank_load_file переписана через неё, поэтому дублирования работы с W3
  не осталось и резидент почти не вырос.
* Набор эффектов: 10 файлов -> SND\snd.arc, один open вместо десяти.
* Музыка: трек лежит ОДНИМ файлом и читается порциями по странице —
  нарезка на куски больше не нужна.  Этот же путь понадобится финалу
  `won` (1,2 МБ), который в память целиком не влезает.
* Менеджер звука приведён к оригиналу: играющая музыка участвует в
  таблицах приоритета наравне с эффектами (seg000:1672 + data.h:433).
  Почти вся музыка НЕперебиваема, поэтому поверх неё эффект не стартует —
  ровно как в SDLPoP; раньше эффект её перебивал.
* ALLOCS 3000 -> 6000 (решение пользователя): сборка +20 с, резидент
  -161 байт.  Куча 87 -> 248 Б.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 17:13:25 +03:00

30 lines
1.3 KiB
C

/*
* bank_load_file — прочитать файл целиком в физическую EMM-страницу.
*
* Тонкая обёртка над bank_read_page: открыть, перенести, закрыть. Вся
* работа с W3 (ESTEX принимает файловый буфер только в W1..W3) живёт там,
* в одном месте — дублировать её здесь незачем, а резидент W1 у
* приложений тесный.
*
* Кто читает из одного файла НЕСКОЛЬКО кусков (архив ресурсов, поток
* музыки), обязан звать bank_read_page напрямую, держа fd открытым:
* `open` дороже самого чтения — 51,4 мс против 32,6 мс на 16 КБ (замер в
* MAME, PoP, 2026-08-25).
*
* Возврат: фактически прочитанный размер либо -1 + errno.
*/
#include <fcntl.h>
#include <unistd.h>
#include <sprinter_mem.h>
int bank_load_file(uint8_t phys_page, uint16_t off, const char *path,
uint16_t max_size)
{
int fd, n;
fd = open(path, O_RDONLY);
if (fd < 0) return -1;
n = bank_read_page(fd, phys_page, off, max_size);
close(fd);
return n;
}