Rev 1913 | Blame | Compare with Previous | Last modification | View Log | Download
в 48K распределение памяти:
6000: таблицы (сейчас свободно 0xb00 байт)
7C00: distbuf (#300)
7f7f: imer
8000: код (сейчас свободно 0x24e байт)
a000: карта, экранный буфер (scrbuf=#A040)
c000: tscales (L=0..63), адреса столбцов (L=64..127 для текстур H=0xc0..df), текстуры в оставшихся местах (можно переключать наборы текстур на 128K)
todo вернуть OSCALLS для перехвата клавиш, через хук для юзерского обработчика прерываний?
перехват надо уже в юзерспейсе, а в системспейсе надо вызывать заданный обработчик (возможно, другой)
щедулинга при этом нет, но есть выставление палитры
в WREND сейчас страница включается в 8000 (было в 0000), в 4000 экран
в c000 скалер
скалер для стен (64 масштаба в страничке - в The Board II было 14801 b высота 200 без пола):
jr NC,$+4
SET 5,H ;todo LD H,
ADD A,L ;todo skip if L<=-40
LD L,A
jr NC,$+3 ;todo skip if L<=-40
INC H ;todo skip if L<=-40
dup scrhgt ;или меньше для мелких масштабов
[pop de] ;всего 32 шт (выигрыш по сравнению с 64*(ld a,(de):inc e) = 384t)
ld (hl),e/d
add hl,bc
edup
jp (ix)
скалер для спрайтов:
...
ld a,(de)
cp IMPOSSIBLECOLOR ;нельзя or a, т.к. 0 должен быть чёрный, а чёрные пиксели есть в текстурах
jr z,$+4
and b/c ;затенение
ld (hl),a
add hl,sp ;-40 или можно +40, прерывание затрёт SETPG32KHIGH, но должно само восстановить
[inc d(или e)]
;49.5t
сейчас одна процедура:
drawspr00
ld d,h
ld a,(de)
exx
cp e;IMPOSSIBLECOLOR
jr z,$+3
ld (hl),a
add hl,bc
exx
add hl,bc
jp nc,drawspr00 ;флаги P/V и S не генерируются!
;нельзя спрайт высотой больше экрана!
чтобы это ускорить, нужно как-то подружить произвольную процедуру-спрайт с дырами и произвольную таблицу вывода с масштабированием
придётся выводить каждый байт 2 раза и иметь много копий спрайтов под разные масштабы с шагом в 2 раза
;de=адрес начала столбца
увеличение в 1..2 раза:
[ld a/bc,n] ;можно также занять a,b,c выгодными константами для данного столбца данного спрайта
pop hl ;Y*11
[add hl,de
ld (hl),a/b/c]
pop hl ;Y*11, может быть равно предыдущему
[add hl,de
ld (hl),a/b/c]
=20..61 t/b (2..7.5 b/b, прозрачные низ (и верх, если таблица строится от центра поочерёдно вверх и вниз) можно пропускать, *2 на все копии с шагом в 2 раза)
уменьшение в 1..2 раза:
[ld a/bc,n] ;можно также занять a,b,c выгодными константами для данного столбца данного спрайта
pop hl ;Y*11, может быть равно предыдущему
[add hl,de
ld (hl),a/b/c]
=10..33 t/texel (до 66 t/b)
обработчик прерывания должен восстанавливать таблицу по контрольной сумме.
надо одновременно включить 3 страницы: спрайт, часть экрана, таблица масштабирования (все масштабы можно уместить в одну страницу)
клипирование только по этой же самой таблице, поэтому нельзя смещать спрайт по Y (только wolf, а не гонки с горками - или отсекать там спрайты целиком)
как не выводить каждый байт 2 раза? для этого как-то надо быстро переключаться между двумя произвольными процедурами, вместо перебрасывания байта из текстуры входить в процедуру спрайта в нужном месте:
[inc hx/ld hx,n] ;0/8/11
jp (ix) ;8
...
[ld (hl),n]
ret ;1..3 b/b (столбец спрайта = 3 столбца по h)
...
add hl,bc ;11
=29..50 t/b
этот вариант самый эффективный для худшего случая и занимает меньше места.
но в случае увеличения будет лишний вызов одинаковых байтов, даже если они пустые (таких примерно 1/4 для спрайтов полной высоты, иначе 1/2)
пустой верх спрайта (вывод снизу вверх) можно пропускать: jp (iy) вместо ret
для люстр можно вывод сверху вниз (отличие только в bc)
можно выводить верх и низ отдельными фрагментами, с перестановкой hl,bc
так что это может быть в 2 раза быстрее, чем простой цикл
типы монстров на карте:
1. стоит спиной => type 1
2. стоит лицом => type 2
3..6. идёт (4 направления) => type 3
7... предметы => type 4... (ammo (type 4), health (type 5), column (type 6))
номера спрайтов:
0 - спиной
1 - лицом (шаг)
2 - стреляет
3 - ранен
4 - умер
5 - ammo
6 - health
7 - column
;фазы:
;0=move1
;1=move2
;2=wantattack (перейдёт в атаку)
;3=attack (при окончании счётчика должен стрелять, потом двигаться)
;4=ранен
;5=(умирает)
;6=труп
;7=-