Login

Subversion Repositories NedoOS

Rev

Rev 1913 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

в 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=-