PDA

Просмотр полной версии : Игра "Вера". Что еще можно ускорить?



axor
15.07.2005, 09:35
Посмотрите вложение. Что-то еще можно ускорить? Может кто подскажет какой-либо более "удобный" формат для скорости?

rasmer
16.07.2005, 00:14
да фиг его знает... и так вроде намана... ведь это же спек, и предел близок...

newart
16.07.2005, 00:21
Может кто подскажет какой-либо более "удобный" формат для скорости?
ADD HL,HL ;HL=HL*32
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
Этот кусок точно можно ускорить, странно но подобное я видел и в ЧВ.

newart
16.07.2005, 00:24
Может кто подскажет какой-либо более "удобный" формат для скорости?
INC HL
PUSH HL
LD H,(HL)
LD L,A
CALL Anim2 ;Проверка на анимацию и т.п.
CALL BLOCK22 ;Печать блока
POP HL
POP BC
POP DE
INC HL
INC E
DJNZ PRMLP1

Зачем ты выносишь процедуру печати спрайта за цикл?
Лишний Call и Ret отнимает кучу тактов.
Кроме того для счетчиков лучше использовать половинки индексных регистров, это позволит избавиться от нагромаждения POP HL,DE,BC.

newart
16.07.2005, 00:28
PRSHAD1 PUSH BC

.......

POP BC
DJNZ PRSHAD1

И тут тоже можно использовать LX например, вместо того что сувать лишний раз в стек BC.

axor
16.07.2005, 23:29
PRSHAD1 PUSH BC

.......

POP BC
DJNZ PRSHAD1

И тут тоже можно использовать LX например, вместо того что сувать лишний раз в стек BC.

А какова скорость работы с половинками индексных регистров?
На сколько я помню вся работа с полными индексными регистрами выполняется гораздо медленнее чем все остальные команды. Как обстоят дела с половинками не в курсе.

axor
16.07.2005, 23:32
ADD HL,HL ;HL=HL*32
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
Этот кусок точно можно ускорить, странно но подобное я видел и в ЧВ.

А как ускорить?

Подскажи, как можно быстро по коду в HL - 0-511 высчитать адрес спрайта? Спрайты, понятно, выровнены по адресу (#c000), но формат линейный (почти).

Или подскажите кто-нибудь, как можно быстро умножить на 32.

axor
16.07.2005, 23:38
Если бы не формат анимации на карте, то можно было бы карту хранить в более выгодном формате. А именно, уже сразу умножить код спрайта на 32. Все равно в карте он занимает 2 байта. Но, блин, у меня там анимация:( Хотя... Надо подумать :)

axor
17.07.2005, 09:48
Можно не только хранить в карте уже умноженное число на 32, а сразу адрес спрайта. Таким образом у меня на выводе карты будет экономиться порядка 10000 тактов.

Пока правда не придумал как быть с анимацией. Но вроде выход есть. Ведь все адреса спрайтов четные. Поэтому можно задействовать 1-й бит в числе...

Shiru
17.07.2005, 09:52
Вообще, если адреса хранить - они будут не просто чётные, а все младшие 5 бит будут в нуле. Т.е., в принципе, там можно чего-нибудь дополнительное хранить, а на выводе младший байт and %11100000

axor
17.07.2005, 16:31
Вообще, если адреса хранить - они будут не просто чётные, а все младшие 5 бит будут в нуле. Т.е., в принципе, там можно чего-нибудь дополнительное хранить, а на выводе младший байт and %11100000

Я это уже понял. Но все же буду анимацию одним битом отмечать. Т.е. при скопе анимации (чего не будет) в принципе будут небольшие тормоза.

Но все-таки 10000 тактов это не 100000 :( Нужно бы что-то более кардинальное. Но наверное такого не может быть. Или я ошибаюсь?

Надо идти к Димке кланяться :)

newart
17.07.2005, 16:47
Но все-таки 10000 тактов это не 100000 Нужно бы что-то более кардинальное.
100000 тут не откуда взять. Однако я думаю, что остальной код у тебя оптимизорован на том же уровне, что и этот. Соотвественно можно и нужно
его тоже оптимизировать. Например было бы интересно взглянуть на твою процедуру печати юнитов.

axor
18.07.2005, 09:56
100000 тут не откуда взять. Однако я думаю, что остальной код у тебя оптимизорован на том же уровне, что и этот. Соотвественно можно и нужно
его тоже оптимизировать. Например было бы интересно взглянуть на твою процедуру печати юнитов.

Понятно, что 100000 мы нигде не возьмем.

За выходные написал модуль для Maper`а, который конвертит карту в формат высказанный в "Идея". Все получилось.

Но я, кстати, там нашел еще порядка 4000 :) Осталось еще кое-что.

Благодаря этому без турбо обновление экрана теперь успевает за 5 фреймов, ранее было за 6. С турбо все гораздо лучше - 2 фрейма. Но наверно 4 фрейма уже не светит. Вернее можно, но нужно памяти как минимум 9 Кб :( Но если в конце работы будет оставаться, то непременно сделаю это!

А печать юнита тоже тормоз. Там слишком много проверок на выходы за экран и т.п. Выкладываю...

axor
18.07.2005, 17:20
Если кто-то сможет ускорить нижепредложенный кусок, памятник поставлю :)

LD C,(HL) ;Делаем именно так, чтобы прерывание не испортило спрайт поэтому в BC у нас уже есть первые 2 байта спрайта
INC L
LD B,(HL)
INC L
LD SP,HL ;Теперь стек указывает на начало спрайта
EX DE,HL ;hl-экран
LD DE,#FF20

;Непосредственно сам вывод спрайта
LD (HL),C
INC L
LD (HL),B
INC H
POP BC
LD (HL),B
DEC L
LD (HL),C
ADD HL,DE

DUP 6
POP BC
LD (HL),C
INC L
LD (HL),B
INC H
POP BC
LD (HL),B
DEC L
LD (HL),C
ADD HL,DE
EDUP

POP BC
LD (HL),C
INC L
LD (HL),B
INC H
POP BC
LD (HL),B
DEC L
LD (HL),C
BL22SP LD SP,0
RET

Меня здесь смущает присутствие команды ADD HL,DE. Но пока ничего лучшего в голову не пришло :(

Shiru
18.07.2005, 18:17
Для начала надо-бы перенести вывод спрайта в место вызова, тысячу-другую тактов сэкономит.

Насчёт ADD HL,DE - в принципе, можно попытаться выдумать какую-нибудь хитрую перетасовку строк экрана. Пока ничего не надумалось, я вывод раньше также делал (L туда-сюда, потом ADD HL,DE).

newart
18.07.2005, 18:31
Благодаря этому без турбо обновление экрана теперь успевает за 5 фреймов, ранее было за 6. С турбо все гораздо лучше - 2 фрейма.
Ничего не путаешь?
У тебя что спринтер?
Я что-то не помню спеков с турбой более 200%...

newart
18.07.2005, 18:39
А печать юнита тоже тормоз. Там слишком много проверок на выходы за экран и т.п.
У меня в игре для каждого размера спрайта отдельная процедура, и для каждого смещения (по X) тоже. Кроме того используется стек, но прерывания запрещены, просто каждую строчку проверяется сколько прошло тактов и не пора ли сделать прерывания.

axor
18.07.2005, 22:44
Ничего не путаешь?
У тебя что спринтер?
Я что-то не помню спеков с турбой более 200%...

Нет, у меня Кай-256. Турбо есть.

Может я конечно что-то не так считаю, но определял фреймы так:

1. На прерывании висит счетчик. x=x+1

2. Вне прерываний цикл, который проверяет не достиг ли счетчик опред. числа. В начале цикла естественно стоит halt.

3. После этого обнуляю счетчик, вывожу карту на экран, формирую теневой экран, печатаю героя.

4. Снимаю со счетчика число, которое, по-моему, и должно означать за сколько времени я вывел экран и напечатал его в теневом экране, ну и герой там же.

Что-то не так?

axor
18.07.2005, 22:55
Для начала надо-бы перенести вывод спрайта в место вызова, тысячу-другую тактов сэкономит.

Ну это-то сделать не проблема. Нужно что-то еще придумать. Я просто пока не загромождаю процедуру, чтобы отличать что где.


Насчёт ADD HL,DE - в принципе, можно попытаться выдумать какую-нибудь хитрую перетасовку строк экрана. Пока ничего не надумалось, я вывод раньше также делал (L туда-сюда, потом ADD HL,DE).

Вот кто бы выдумал :) Это бы значительно ускорило бы все. Ну хотя бы для не турбированных машин. На турбо меня все устраивает.

Сейчас вот смотрел "ЧВ". Так там все просто летает, по сравнению с моим вариантом. Хотя оценка конечно субъективна. Но на глаз вроде заметна.

А как Медный выводил теневой экран? И спрайтики 2*2 печатал? Кто-то знает?

axor
18.07.2005, 22:58
У меня в игре для каждого размера спрайта отдельная процедура, и для каждого смещения (по X) тоже. Кроме того используется стек, но прерывания запрещены, просто каждую строчку проверяется сколько прошло тактов и не пора ли сделать прерывания.

Может быть. Но у меня всего один герой и поступать так я пока не буду. Тем более, что ускорив вывод героя ничего кардинально не решить. Если бы у меня их 50 штук бегало.

Мне важно ускорить вывод тайлов (2*2), ну может еще вывод теневого экрана.

newart
19.07.2005, 00:09
А как Медный выводил теневой экран? И спрайтики 2*2 печатал? Кто-то знает?
Экран печатается обычнум LDI.
Спрайты тоже стандартно печатаются, через сдтек, скролятся
вроде примерно так: ADD HL,HL: RLCA
У тебя юниты каких размеров бывают?

Shiru
19.07.2005, 00:36
Ну, вообще говоря, для такой игры (где один герой, ходит попиксельно, карта изредка скроллится по знакоместам) можно сделать так: пока экран не скролится - перерисовывается только то, что реально изменяется (анимированные тайлы, герой, фон под ним), когда скроллится - перерисовывается всё (в этот момент анимацию можно отключать). Ощущение будет, что игра идёт быстро.

Кстати, я не понял - почему в ЧВ, и здесь тоже, не используется переключение видеостраниц, а юзается буфер и переброска? Это-же медленно, и расход памяти почти такой-же.

Shiru
19.07.2005, 00:41
Вот, кстати, код вывода карты из ЧВ, может натолкнёт на какие-то идеи.

newart
19.07.2005, 02:07
Ну, вообще говоря, для такой игры (где один герой, ходит попиксельно, карта изредка скроллится по знакоместам) можно сделать так: пока экран не скролится - перерисовывается только то, что реально изменяется (анимированные тайлы, герой, фон под ним), когда скроллится - перерисовывается всё (в этот момент анимацию можно отключать). Ощущение будет, что игра идёт быстро.

Кстати, я не понял - почему в ЧВ, и здесь тоже, не используется переключение видеостраниц, а юзается буфер и переброска? Это-же медленно, и расход памяти почти такой-же.
A как ты себе это представляешь?
Вот у меня используется, но я об этом уже жалею. Ибо тормозно также и геморно.
Как быстро напечатать спрайт лежащий в 6-й странице, в 7-ю страницу?
У меня спрайт сдвигается и копруется в буффер, а из буффера уже с максимальной скоростью на экран. Выйгрыша никакого нету.

Shiru
19.07.2005, 02:13
Как быстро напечатать спрайт лежащий в 6-й странице, в 7-ю страницу?
Ну, я себе это представляю так: нужные на текущем уровне спрайты лежат в нижней памяти и свободной части 7-ой страницы. Разумеется, их количество надо минимизировать. М.б., даже сделать их не 16х16, а 8х8, с возможностью зеркалить по вертикали; вывод для героев тоже с отзеркаливанием. Код вывода графики также в нижней памяти. Код игровой логики и прочие относительно редко используемые вещи - в страничках.

bugsy
19.07.2005, 07:52
Ну, я себе это представляю так: нужные на текущем уровне спрайты лежат в нижней памяти и свободной части 7-ой страницы.
фигасе?!?!?!?
а если у меня "нужных спрайтов" 6-ть страниц??? мне что тоже всё минимизировать и зеркалить?

axor: не слушай их они плохому тебя научат!!! так и быть, я сдам тебе секретную разработку моего брата (firestarter) и авторов игры earth shacker:
вот сейчас ты тайл ландшафта как выводишь?

я думаю так:
---->
---->
---->
---->

а можно так:
---->
<----
---->
<----

а ещё так:
^ | ^ |
| V | V

экономь короче на лишних движениях.

з.ы. лёха прости меня, я не хотел... оно само...

axor
19.07.2005, 09:38
фигасе?!?!?!?
а если у меня "нужных спрайтов" 6-ть страниц??? мне что тоже всё минимизировать и зеркалить?

axor: не слушай их они плохому тебя научат!!! так и быть, я сдам тебе секретную разработку моего брата (firestarter) и авторов игры earth shacker:
вот сейчас ты тайл ландшафта как выводишь?

я думаю так:
---->
---->
---->
---->

а можно так:
---->
<----
---->
<----

а ещё так:
^ | ^ |
| V | V

экономь короче на лишних движениях.

з.ы. лёха прости меня, я не хотел... оно само...

У меня используется второй описанный тобой способ. Он не нов. Ширина спрайта 2 байта и выигрыш в этом варианте практически не получить.

axor
19.07.2005, 09:41
Ну, вообще говоря, для такой игры (где один герой, ходит попиксельно, карта изредка скроллится по знакоместам) можно сделать так: пока экран не скролится - перерисовывается только то, что реально изменяется (анимированные тайлы, герой, фон под ним), когда скроллится - перерисовывается всё (в этот момент анимацию можно отключать). Ощущение будет, что игра идёт быстро.

Кстати, я не понял - почему в ЧВ, и здесь тоже, не используется переключение видеостраниц, а юзается буфер и переброска? Это-же медленно, и расход памяти почти такой-же.

Одно из реальных предложений - не выводить неизмененные участки карты. Правда не знаю как будет себя вести при этом курсор. Но порпробовать наверно стоит.

По поводу двух экранов Слава верно заметил. Спрайты как правило лежат в другой странице нежели 7-й экран. У меня этих спрайтов 512 - они занимают целую страницу...

Firestarter
19.07.2005, 10:20
За советы все Абазацы + нераспростронение [email protected]

bugsy
19.07.2005, 10:56
У меня этих спрайтов 512 - они занимают целую страницу
какую-то страницу?!?!? у меня 6,5 их!!!


За советы все Абазацы
дадада

axor дай в PDF!!!

Shiru
19.07.2005, 12:52
фигасе?!?!?!?
а если у меня "нужных спрайтов" 6-ть страниц??? мне что тоже всё минимизировать и зеркалить?
- Доктор, когда я так делаю - очень больно!
- А вы так не делайте!

Если тебе действительно нужны 6 страниц спрайтов - тогда и разговора нет:)

axor
20.07.2005, 10:04
За советы все Абазацы + нераспростронение [email protected]

Кому?

axor
20.07.2005, 10:04
какую-то страницу?!?!? у меня 6,5 их!!!


дадада

axor дай в PDF!!!

На счет *.pdf все и так знают мое отношение.

Firestarter
20.07.2005, 14:30
Кому?
нам обоим

axor
20.07.2005, 14:31
Пока мы треплемся Дима Быстров работает.

Вот что он ответил на некоторые мои вопросы.

Дима Быстров:
"1. У тебя трассировка происходит перебором на каждом шаге всех клеточек? Это
можно существенно ускорить, если на каждом шаге перебирать только клеточки,
изменённые на предыдущем шаге (кроме карты нужно 2 списка: один обрабатываем,
другой генерируем).

2.
/=== Begin Windows Clipboard ===/
LD (BL22SP+1),SP
LD BC,SPR ;Высчитываем адрес спрайта
ADD HL,HL ;HL=HL*32
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,BC
/=== End Windows Clipboard ===/
20+65

Это можно ускорить:
SP на каждом вызове будет одинаковое, так что сохранять для всех клеток
незачем.
ld a,l
rrca
rrca
rrca
ld h,a
and #e0
ld l,a
xor h
add a,'SPR
ld h,a
46 против 65

А вообще-то ускорять незачем, т.к. клеточек на экране всего 144 - выигрыш 5616
тактов :)"

Поучиться, как всегда, есть чему. Мотаем на ус!
Итого, ко всем моим ускорениям, он ускорил еще на 2880 тактов :) Кто ускорит еще? :)

axor
20.07.2005, 14:36
нам обоим

А за что?

bugsy
20.07.2005, 15:26
А за что?
да ладно...
мы шутим...

Shiru
20.07.2005, 16:52
1. У тебя трассировка происходит перебором на каждом шаге всех клеточек? Это
можно существенно ускорить, если на каждом шаге перебирать только клеточки,
изменённые на предыдущем шаге (кроме карты нужно 2 списка: один обрабатываем,
другой генерируем).
Это и есть поиск по фронту волны, о котором я тебе говорил.

newart
20.07.2005, 17:04
Пока мы треплемся Дима Быстров работает.

Поучиться, как всегда, есть чему. Мотаем на ус!
Итого, ко всем моим ускорениям, он ускорил еще на 2880 тактов :) Кто ускорит еще? :)
Напомни, у тебя поле по знакоместам скролиться или по тайлам?

Raider
21.07.2005, 02:55
А как ускорить?
Подскажи, как можно быстро по коду в HL - 0-511 высчитать адрес спрайта? Спрайты, понятно, выровнены по адресу (#c000), но формат линейный (почти).
Или подскажите кто-нибудь, как можно быстро умножить на 32.

Я так понял, выводишь на экран асинхронно прерываниям.
Вопросец - за один игровой "тик", один оборот игрового цикла, сколько спрайтов выводятся на экран? Сколько раз отработает этот кусочек кода?

axor
21.07.2005, 09:53
Напомни, у тебя поле по знакоместам скролиться или по тайлам?

По тайлам.

axor
21.07.2005, 09:54
Это и есть поиск по фронту волны, о котором я тебе говорил.

Минин Володя (который делал для меня процедуру) сказал, что она так и сделана.

axor
21.07.2005, 09:57
Я так понял, выводишь на экран асинхронно прерываниям.

Теперь вывод экрана привязан к прерываниям. Но может отказаться от этого?

В первой деме вывод экрана не был привязан и выводился асинхронно.


Вопросец - за один игровой "тик", один оборот игрового цикла, сколько спрайтов выводятся на экран? Сколько раз отработает этот кусочек кода?

Если ты имеешь ввиду вывод тайла, то один тайл за цикл (формирование теневого экрана) выведется 144 раза. Это происходит после того, как теневой экран выкидывается на видимый экран.

Raider
22.07.2005, 14:52
Теперь вывод экрана привязан к прерываниям. Но может отказаться от этого?
В первой деме вывод экрана не был привязан и выводился асинхронно.
Если ты имеешь ввиду вывод тайла, то один тайл за цикл (формирование теневого экрана) выведется 144 раза. Это происходит после того, как теневой экран выкидывается на видимый экран.

Ну мож имеет смысл убивать 512 байт памяти и заменять серию ADD..
на такое:

LD H,XX
LD L,YY
LD A,(HL)
INC H
LD H,(HL)
LD L,A
. . .
хотя в гейме я бы не стал. в демке - обязательно.

axor
25.07.2005, 09:46
Ну мож имеет смысл убивать 512 байт памяти и заменять серию ADD..
на такое:

LD H,XX
LD L,YY
LD A,(HL)
INC H
LD H,(HL)
LD L,A
. . .
хотя в гейме я бы не стал. в демке - обязательно.

Согласен. В игре такое уже не нужно.

Полагаю, что практически достигнут логический конец ускорения в разумных пределах конечно. Кардинально уже ничего не ускорить.

Теперь нужна скоростная процедура поиска пути.

Кто знает, как делал Медноногов?

Shiru
25.07.2005, 10:45
Кто знает, как делал Медноногов?
У него там совсем другой случай, и другой принцип поиска - обход по часовой/против часовой стрелки. Юнит трассирует путь по прямой на пару клеток вперёд себя, если там стенка - он делает проверку, в какую сторону нужно пройти меньше клеток для того, чтобы можно было продолжать идти в нужном направлении. Этот способ не даёт 100% нахождения пути, но работает быстрее, и больше подходит для динамических препятствий (специфика RTS).

Он в каком-то журнале описывал используемый в ЧВ алогоритм более подробно и понятно. Не помню, по-моему, ещё в ZX-Format'е каком-то.