Rev 595 | Blame | Compare with Previous | Last modification | View Log | Download
todo вернуть OSCALLS для перехвата клавиш, для этого в оси сделать хук для юзерского обработчика прерываний?перехват надо уже в юзерспейсе, а в системспейсе надо вызывать заданный обработчик (возможно, другой)щедулинга при этом нет, но есть выставление палитрыbugs:графика портится после raytraceна 8-2 прохождение обламывается при MULTITASKING=1 (даже с MUSICONINT=0)если подбежать к грибу справа, когда он на левом краю экрана, то счёт показывается наполовину справа (так и было? в версии без оптимизированного клипирования так уже было)ни одна дема не проходит 1-2:;фиксы CY не помогли (проверил 0..5);возможные причины:;- субпиксели - не нашёл, есть только friction - как он работает?;- история запуска (вроде всё чистится!);- игрок возник не там (но тогда бы не смог так точно прыгать?);- игрок возник не когда надо;- враг возник не там;- враг возник не когда надо;- неправильный bounding box врага;- неправильный критерий столкновения с врагом (на 1-2 этого врага мы должны перепрыгнуть в последний момент перед ним);- неправильно определяется столкновение с трубой;- неправильно реагирует на столкновение с трубойв 177... убрал после 1-1 3 фрейма - проходит дальше (умирает на третьей трубе), 4 фрейма - не допрыгивает до третьей трубы, 5-20 всё плохосделал NOPIRANHAPLANT=1, убрал 3 фрейма после 1-1, 2 фрейма после 1-2 (с 1 доходит далеко)1-4 (с ошибкой в Z80OPT3hy): 1 убранный фрейм не помогает, 0..14 добавленных фреймов не помогает, 0..14+сразу B не помогает, 15+-сразу B лучше, 16+-сразу B ещё лучше, 17..18 то же, 19 доходит до дракона, 20 его убивает (пробовал только без сразу B - как в оригинале)2-1 (7900): убрать 0..3 плохо, 4 лучше, 5 не так хорошо, 6 застревает, добавить 1..27 ничего не даёт; поэтому сделал изменения в двух местах (замедление в середине и три лишних фрейма бега в конце, 4 тоже можно, 2 мало)2-2 (9710): вставка 7..11 нормально ест 3 первых монетки, дальше плохо, 12..14 вообще тонет в яме, 15..17 плохо, 18 тонет в яме, 19..20 лучше, 21 плохов итоге очень много изменений2-3 (13600): сразу работает2-4 (16300): 0..5 плохо, +6..21 умер сразув итоге много исправлений3-1 (18200): нет хорошей фазы, взял лучшую (вставка 5) и сильно переделал3-2 (20600): поскольку флаг в прошлом уровне снят не сверху, а снизу, то потеряно много времени, сделана большая вставка, а ложные нажатия в начале вырезаныв итоге пришлось всё переписать3-3 (22800): записан с клавиатуры3-4 (26077): записан с клавиатуры4-1 (29750): записан с клавиатуры4-2 (33050): записан с клавиатуры и т.д.4-2 лоза растёт (и звук есть), но при скролле исчезает (реально по ней при этом можно залезть) - это не KillVine, но при этом не вызывается DrawVine, вызывается только VineObjectHandlerвылетает сразу:cpxn ++$05 ;check enemy offset for special use slot ;реально там 4bne ExitVH ;if not in last slot, branch to leaveисчезает на 1 метатайл раньше, чем в оригинале? или в оригинале не видим левый край экрана?fixed:спуск в трубу уже работает, враги в трубах в 1-2 есть, черепахи работают, лифты работают, блоки разбиваются головой большого Мариофейерверки в конце 1-1 работаютпосле спуска флага вверху остаются цифры (так и надо)1-4 вода не шевелится (так и надо)после некоторых смертей не показывал x2 (т.е. число жизней), а только фигуру Марио - выводится всегда на 0 экране тайлов (нет сплитскрина по монетке) - исправлено в mainубийство первого монстра может приводить к зависанию? - вроде исправилось после SCRATCHPAD2в деме была всегда смерть на первом монстре (в оригинале это редко) - исправилосьworld 1-2 неправильно показан вход в трубу - исправлен флагбыли тормоза из-за выключенных прерыванийworld 2-4 используется переворот спрайтов огня по вертикали (мёртвые монстры в 1-1 тоже)перекрасил тайлы фона в соответствии с их палитрами (взять из метатайлов). если на один тайл много палитр, то размножить тайл и поменять номера в исходнике метатайловworld 1-3 в конце флажок поднимается в середине здания (от должен быть позади тайлов - реализовал такое поведение спрайтов, заодно для монетки в спрайте 0)были неправильно окрашены монетки в воде 2-2 и следы от них (красный фон), водоросли (зелёный фон), нижняя часть гориз. трубы в 2-2 (x91,x92)при движении платформ на верёвочках новые верёвочки были зелёныебыли подёргивания экрана из-за рисования на отображаемом экране иногда;[почему-то огненные палки и плевки дракона голубые];[и рамка их центра голубая];[и лава голубая];[фаербол Марио почему-то с чёрной окантовкой (надо оранжевый с красной окантовкой, взрыв внутри белый)];[очки надо белым (сейчас розовым)];[гриб надо c белой ножкой, оранжевый с красными пятнами];[плевок лавы наполовину зелёный почему-то, а наполовину голубой];[ёжик падает зелёный, а приземляется красный - а надо всегда красный с белыми блестючками];[лоза в подземелье ок, но наверху она почему-то чёрная]TODO в будущем использовать только метатайлы 16х16 и не строить карту тайлов 8х8? (кроме верха экрана и сообщений о смерти)для некоторых метатайлов (которые не бывают внизу экрана) можно уже делать 16x8 (вертикально), но без выигрыша в скорости, т.к. во втором ряду надо пропускатьTODO спрайты надо сгенерить со всеми существующими палитрами в отдельные страницы, переворот по вертикали можно программно?TODO ускорить логику, сейчас она 47000 тактов (было 80000)палитры: WaterPaletteData и др. (много), мигание вопросиковвывод тайлов фона:пусть тайл - это процедура>2..3 байта на байтто есть все тайлы одного набора не поместятся в странице?нам нужно только 256-19 тайлов, из которых 4 полностью залитые, а 1 (№255) может не использоватьсяв среднем надо 69 байт на тайл (2,17 байта на байт)можно для цифробукв сделать call:db data,data...если бы не было скроллинга, то прокатило бы так:ld (hl),nset 7,hld (hl),nset 6,hld (hl),nres 7,hld (hl),nadd hl,bc... и наоборотно реально все 4 адреса столбцов независимые! вплоть до невидимыходин столбец тайла = 0..+40*7 = +280-128-88-48-8+32+72+112(+142)ld (ix+-d),n...ld (iy+-d),n ;19t...ld (hl),nadd hl,bc ;21t, т.е. проигрыш (21-19)*8-11 = 5t, реально проигрыша нет...ex de,hlld (hl),nadd hl,bc...потом надо обновить экранные адресамы можем читать из стека экранные адреса, но не все (а то слишком большие таблицы надо разместить в нижней памяти, и стек нельзя ниже 3b00)но если переход на тайлопроцедуру быстрый, то можно выводить экран по 2 слоя (не 4) за раз, заодно нет проблем с ужиманием всех тайлов в страницу, такие страницы:0000 kernel4000 screenaddrstack8000 screenc000 tileprocleft/tileprocrightтогда можно хранить в стеке все экранные адресаминимальный переход на тайлопроцедуру:[а)ld a,(de)inc eld hx,a ;64 tiles!!jp (ix)...jp;37t][б)ex de,hlld d,(hl)inc lex de,hlld a,1srl hrrarr hrrald l,a ;hl=%10tttttt tt000000jp (hl);58t][в)ld a,(de)inc eld l,1srl a ;rra (если гарантированно NC)rr lrrarr l ;NCld h,a ;hl=%10tttttt tt000000jp (hl);54(50)t]г)процедуры расположены лесенкой: 0xc000,0xc101...ld a,(de)inc eld l,aor 0xc0ld h,ajp (hl);30t, 7bвыход из строки по одному из незанятых номеров тайлов (надо патчить тайловую карту перед входом, а потом распатчить обратно)минимальный вывод тайла (pop hl не будет быстрее add hl,bc):pop hl ;пиксели 0..1dup 7ld (hl),nadd hl,bcedupld (hl),npop hl ;пиксели 4..5 в той же странице (другой bit 5 и возможно +1)dup 7ld (hl),nadd hl,bcedupld (hl),n;336t (*2 для второй страницы), 48b;+7b, итого меньше 64b;проблема только с тайлом 0xff, у которого адрес процедуры 0xffff (но, возможно, он не используется);весь экран = 366*2*33*25 = 603900tможно пропускать ld (hl),0, если экран очищенобработчик прерывания надо свой, чтобы восстанавливать данные в стеке, если стек в 0x4000+ - из копии в другой странице?что выгоднее - пустой тайл выводить так же (только через ld (hl),b - 288t) или заранее затереть весь экран через push, а вместо вывода пустого только pop:pop (20t)?5.5*32*200*4 = 35200*4t = 176t/tileесли пустых тайлов 50%, то весь экран будет:при обычной процедуре: (318+366)*33*25 = 564300tчерез push: 140800 + 366*33*25 = 442750tпри push ещё можно немного оптимизировать тайлы с прозрачными пикселями, просто пропускать эти байтыкак лежит стек экранных адресов:в каждой строке 33 пары адресоввсего 25 строк4 фазы скроллаитого 33*2*2*25*4 = 13200, но класть влоб 33 пары неудобноширину строки лучше не сокращатьпоэтому надо таблицу адреса входа в каждую строку для фазы 0, а для остальных фаз прибавлять константыили всегда выводить все строки, тогда достаточно прибавлять константу на каждой строке;для scroll phase 0 стек такой:;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2;(scrR) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2;для scroll phase 1 стек такой:;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1;(scrL) 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 2;для scroll phase 2 стек такой:;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1;(scrR) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1;для scroll phase 3 стек такой:;(scrR) noaddr, noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023;(scrL) noaddr, 0x8004, 0xa004, 0x8005, ... 0xa023, noaddr x 1реально достаточно сгенерировать стек для одной фазы скролла с запасами на пустышки слеваСПРАЙТЫесли все экранные адреса лежат в стеке, то надо несколько страниц стека (постолбцово).кодстекэкранспрайтокод- когда переключать экранные страницы? вывести сначала чётные столбцы спрайта, потом нечётные?у нас активный экран (256+7) * (200+7+7), при спрайтах 8х8тогда стек (точнее, стек для одной страницы экрана) займёт 2 * (64+2) * (200+7+7) = 28248реально надо 3 страницы стека (столбцы левой половины экрана, столбцы правой половины экрана, центр)как переходить между столбцами стека? inc h? в любом случае 3 страницы стекаld sp,hlpop deld a,(de)and...or...ld (de),a...inc h...как выходить из спрайта? jp (ix)?более универсально выводить столбцы подряд, в две страницы экранатогда надо переключать все 4 окнатакой процедуры в недоос нет, надо её генерировать из существующих (а если керналь изменится - придётся переделывать)удобнее всего стек в 0xc000, тогда в 3D можно inc h:jr nzв 3D переключаются не страницы спрайтокода, а страницы с текстурой, их нельзя в 0000 (или уменьшить текстуру)экран тоже нельзя в 0000получается, стек надо в 0x100..0x3fff: dec h:jr nzесли стек горизонтальный и без клипирования по вертикали, то:pop hladd hl,de ;смещение по Y относительно того, что в стеке...[ld a,(hl)][and...][or...]ld (hl),a ;/ld (hl),nadd hl,bc;max 39t, 7b/bтут достаточно стека на 2*160 байт (ширина экрана), его можно в 0x3b00наложение спрайта под фон:надо накладывать только на пустые пикселиld a,(hl):and:or:ld (hl),a не получаетсяможно целыми байтами:pop hladd hl,de ;смещение по Y относительно того, что в стеке...cp (hl) ;a=0jr nz,$+4ld (hl),nadd hl,bc;32.5t, 6b/bнеудобно через deпри 6..7 b/b нужно под 256 спрайтов (32-байтных) 4 страницы - только под один вид поворота-подкладывания!спрайт 0xff - низ монетки, его можно не использоватьесли 2 страницы экрана включено одновременно, то размещать спрайты надо с шагом 256 и пересчётом номера страницыесли включена только 1 страница экрана, то надо с шагом 128 (неудобно) или с переходом по таблице (пересчёт номера страницы тоже нужен, иначе надо включить сразу 2 страницы спрайтов)вызов спрайта:ld a,(ix) ;ysub 8*YSKIPFROMTOPcp 200-8jp nc,prsprites_skip ;большинство спрайтовых записей пустые, можно даже проверять на ==0xf8ld l,a ;y;CY=1ld d,(ix+1) ;tileld a,(ix+2) ;attributes (d7=flip vertically, d6=flip horizontally, d5=behind background, d1..d0=palette)rr drrasrl d ;%01ttttttrrald c,a ;%tTVHB??? ;TODO palette (128 pages???)ld b,tsprpages/256ld a,(bc)SETPG16Kif 1==1ld h,tlineaddr/256ld e,(hl)inc hld d,(hl) ;de=y*40inc h ;ld h,sprscrstack/256elseld h,0ld b,h;0ld c,ladd hl,hladd hl,hladd hl,bc ;*5add hl,hladd hl,hladd hl,hl ;*40ex de,hl ;de=y*40ld h,sprscrstack/256endifld l,(ix+3) ;xres 0,lld sp,hl ;sp=sprscrstack+2*(x/2);de=y*40ld bc,40ld l,bjp (hl)...xor apop hladd hl,de ;смещение по Y относительно того, что в стеке...cp (hl) ;a=0jr nz,$+4ld (hl),nadd hl,bc...jp (iy)можно переворот спрайта сделать выводом снизу вверх: надо по-другому проверить границу, прибавить 40*7, заменить константу 40 на -40сейчас скорость без процедурных спрайтов на сцене 2.5 Goomba + маленький Марио + 2 трубы:173156 cls189924 фон (после ускорения пустых примерно 143700)65667 спрайты (14 шт, 4 персонажа, т.е. 16416/персонаж) - при этом настройка спрайтов персонажей EnemyGfxHandler заняла 3280 на каждый из 4 персонажей (на каждом фрейме, включая 2(?) пропущенных!), то есть 10000 тактов/персонаж, что сравнимо с отрисовкой! <--- сделал EnemyGfxHandler только на последнем фрейме, но с PlayerGfxHandler проблемы(после ускорения пустых спрайтов 50190 спрайты (большой Марио + 2 Goomba) = 16 шт)можно сэкономить 29000 на обновлении верхних 2 строк, если там нет спрайтов и ничего не менялось? TODO найти все места, где меняют строки статуса!