/* * atlas_attach — принять .atl, УЖЕ прочитанный в EMM-страницу. * * Вторая половина atlas_load, отделённая ради архивов ресурсов: кто читает * атлас не из отдельного файла, а куском общего архива (PoP: pop_arc.c, * формат PBA1), делает своё чтение сам, а проверку магии, gfx_w0_page_prepare * и разбор заголовка отдаёт сюда — иначе эти двадцать строк пришлось бы * повторять в каждом приложении. * * n — сколько байт реально прочитано (или -1, если чтение не удалось). * При любой ошибке блок ОСВОБОЖДАЕТСЯ: вызывающему остаётся только * вернуть -1, и «полузагруженных» атласов не бывает. * * Ошибки: EREAD — короткое чтение, EINVAL — не .atl. */ #include #include #include #include "../_bgi.h" int atlas_attach(atlas_t *a, uint8_t blk, uint8_t page, int n) { uint8_t ok, count, h[5]; a->blk = blk; a->page = page; if (n < (int)sizeof(h)) { mem_free_block(blk); a->page = 0; if (n >= 0) errno = EREAD; return -1; } bank_read(page, 0, h, sizeof(h)); ok = (n >= (int)_ATL_DATA_OFF && h[0] == 'S' && h[1] == 'P' && h[2] == 'A' && h[3] == '1'); count = 0; if (ok) { count = h[4]; gfx_w0_page_prepare(page); } /* Восстановить W3 ДО записи в *a: если atlas_t лежит в банковской * памяти (её адрес тоже резолвится через W3), запись при ещё * замапленной странице атласа ушла бы не в тот физический банк * (найдено 2026-07-15 — PoP room.c держит tile_atlas[] в --bank 1, * a->count оставался мусором, room_draw читал пиксели не с того * оффсета). a->blk/a->page выше пишутся ДО ремапа — их это не * касалось, только a->count. */ if (!ok) { mem_free_block(blk); a->page = 0; errno = EINVAL; return -1; } a->count = count; return 0; }