Pull to refresh

Comments 109

Когда в первый раз смотрел, испугался, подумал что это у меня глаза стали резко цвета менять)
А так ничего, интересная реализация.
Не, круто конечно. Но вот если бы ты это перебил…
Да давайте сразу вспоминать известные демки типа Heaven7, Chaos Theory и ещё был один примечательный 3д-экшн, забыл название, на 64 или 128кб, не помню точно
UFO just landed and posted this here
Причём тут они, там от 64кб. Тут то тоже 256b.
демки замечательно идут под вайном на линухе. юпии
Самые классные тут в посте есть и в комментариях.
Ну я как бы предупредил, что в ассемблере — новичок)
А я серьёзно написал, что здорово и это. Главное идти дальше :) Может ты весь мир сможешь удивить. Как знать.
О, а еще скринсейвер есть на основе этой демки.
Ссылку не трудно привести здесь?
Под XP не работает, в dosbox работает но не очищает экран при выходе.
UFO just landed and posted this here
Подозреваю, от видюхи зависит.
У меня оно даже под вайном завелось (да, там есть какой-то простой эмуль доса), о чём вы.
Под эмулем доса и у меня завелось. Видимо, в видеокарте дело.
Никоим образом.
Windows XP sp3
Intel celeron E1500 @ 2.20 GHz
2. Если вы страдаете приступами эпилепсии — НЕ ЗАПУСКАЙТЕ.

До запуска был уверен, что со мной всё ОК.
Уже пробовал, не получается :-(
выйти не получается? попробуйте вернуться домой
Ну так, гоняю по уровням, выход ищу :-(
Нестыковочка. Не могу я по _уровням_ гонять, ибо выйти можно в конце уровня. Короче, от этой зелёной красоты совсем моск вскипел :-)
>> «Если вы страдаете приступами эпилепсии — НЕ ЗАПУСКАЙТЕ»

Эту фразу лучше писать ПЕРЕД видео роликом, а не после него :)
Там где-то должно быть написано на ютубе. Выбрал бесплатную музыку через сервис звукозамены ютуба.
Brad Sucks — Borderline в какой-то обработке
Я буду всегда обновлять список комментариев перед отправкой.
Я буду всегда обновлять список комментариев перед отправкой.
Я буду всегда обновлять список комментариев перед отправкой.
Я буду всегда обновлять список комментариев перед отправкой.
Я буду всегда обновлять список комментариев перед отправкой.
Fantastic Vamps — Borderline (Fantastic Vamps: 8-Bit Mix)
Пожалуй добавлю к описанию видео на ютубе.
Ммм… любимый «13-й графический», знакомый ещё с MS-DOS.
Палитра (3c8, 3c9). Видеопамять 0xA0000000.
Автор, Вас ниразу не стошнило при написании? :)
На самом деле можно прикольные глюки словить если долго смотреть))
Новый вид легальных наркотиков — asm. Если будут массово применяться, могут стать вне закона. :-)
Есть еще торчковая hypnoice.com от Арви Хэккера. 128байт тоже. Через пару минут втыкания в нее начинает неслабо глючить. Стены волнами идут и прочие эффекты.
есть еще куда оптимизировать на самом деле.
можно ужать еще как минимум на 2-3 десятка байт
Я ужимал до 205 байт, потом добавил управление ± ZOOM на кнопки UP и DOWN и вес стал 234. Добавил в конце байты подписи до 256 байт. Вот так)
Не завелось…
Microsoft Windows XP [Version 5.1.2600] SP3
---------------------------
16 bit MS-DOS Subsystem
---------------------------
C:\DOCUME~1\SZELEN~1\Desktop\k29.com
The NTVDM CPU has encountered an illegal instruction.
CS:c000 IP:dede OP:ff ff ff ff ff Choose 'Close' to terminate the application.
---------------------------
Close Ignore
---------------------------
Я такое видел пару раз на сборках ZverXP. У вас она стоит?
у меня зверь стоит и все работает
Значит просто не та версия файла NTVDM.exe
Вот значит в чём дело. Может кастрированный NTVDM…
NTVDM.exe — Windows NT Virtual DOS Machine.
По идее у вас какая то версия этого файла не та…
Поищу пока с чем это может быть ещё связано.
Можно ужать на четверть, от 100h байт — включая сигнатуру в конце — до 0C0h байт.
Код длинный, поэтому ссылка: pastebin.com/2CXf8EWJ
Напишите пожалуйста номера строк в которых произвели модификацию.
Изменений много, и некоторые не сводятся к изменениям в отдельных строках. Я, пожалуй, отвечу выводом diff, он всё-таки короче всей программы:

4d3
< ; [106h] == 0
7,8c6
<     mov si, 100
<     mov di, RRR
---
>     mov di, kruch
21,22c19,20
<         mov ax, 0A000h
<         mov es, ax
---
>         push 0A000h
>         pop es
25c23
<         mov ax, si
---
>         mov ax, 100
31,33c29,30
<                 
<                 pusha
<                     mul  ax
---
>                 push ax cx
>                     imul ax
35c32
<                     mul  ax
---
>                     imul ax
37,42c34,36
<                     xor  dx, dx
<                     mov  bx, [kruch] ;mov  bx, 40    ; K1 = 40
<                     div  bx
<                     mov  bx, sp
<                     mov  word [bx+10], ax
<                 popa
---
>                     div  word [di]
>                     push ax
>                 mov si,sp
47,50c41,42
<                 mov   word [si], ax    ; COS
<                 fild  word [si]
<                 mov   word [si], cx    ; SIN
<                 fild  word [si]
---
>                 fild  word [si+4]      ; COS
>                 fild  word [si+2]      ; SIN
52,55c44,49
<                 fimul word [vnum]
<                 fmul  dword [glad]
<                 fist  word [si]
<                 add   dx, [si]
---
>                 fimul word [di+vnum-kruch]
>                 fmul  dword [di+glad-kruch]
>                 fiadd word [si]
>                 fist word [si]
>                 pop  dx
>                 pop cx ax
94d87
<                 add  al, cl ; + ??????
102a96
>                 add  al, cl ; + ??????
108d101
<                     mov bx, di
112c105
<                         and al, [bx]
---
>                         and al, byte [di+RRR-kruch]
114c107
<                         inc bx
---
>                         inc di
121,123c114
<                 sub  al, cl ; - ??????
<             
<                 inc  al
---
>                 inc al
157c148
<             dec  [kruch]
---
>             dec  word [di]
159c150,151
<             inc  [kruch]
---
>             inc_kruch_paint_me:
>             inc  word [di]
165,167c157
<             jne  label_push_R
<             inc  [kruch]
<             jmp  paint
---
>             je   inc_kruch_paint_me
172c162
<             not  byte [di]
---
>             not  byte [di+RRR-kruch]
177c167
<             not  byte [di+1]
---
>             not  byte [di+GGG-kruch]
182c172
<             not  byte [di+2]
---
>             not  byte [di+BBB-kruch]
189c179
<             jmp  paint
---
>             jmp  paint_me
205c195
< sign  db 'Dedicated to my wife 9'
\ No newline at end of file
---
> ;sign  db 'Dedicated to my wife 9'
понял, я почему-то не использовал регистры si и di. Вы их использовали di вместо RRR,GGG,BBB. регистр si вы использовали вместо [106h]. Не понял почему вы заменили 47,50c41,42.
Наоборот, Вы использовали di для адресации RRR,GGG,BBB и si для адреса временной переменной сопроцессора. У меня все обращения к глобальным переменным идут через di, кроме одного mov [...],al, где это не имеет смысла, а сам di указывает на наиболее часто используемую переменную.

47,50c41,42 — это часть изменения: pusha / запись в сохранённую копию на стеке / popa / операция с ax и cx через временную переменную -> push ax cx / операция с сохранённой копией на стеке / pop cx ax.
А если исходный код прогнать под оптимизирующим по размеру компиляторе, к примеру? Не будет ли код еще меньше? Плохо, что исходник на Паскале, был бы на Си, можно было бы попробовать, для сравнения.
Ассемблер транслируется напрямую, я думаю.
Это высокоуровневые конструкции в ЯВУ могут быть оптимизированы.
Очевидно, вы никогда не пробовали на практике сравнивать по размеру ассемблерный и эквивалентный скомпилированный код. Компиляторы по скорости ещё могут сравниться с человеком, а по размеру откровенно сливают — тем более, что сегодня и задачи-то такой не ставится.
Поправка: указанная версия занимала целых 0D0h байт, но тем не менее на четверть ужать можно. Версия на 191 байт, правда, с использованием одной инструкции, появившейся в i386, и в которой спираль по умолчанию вращается: pastebin.com/eJSVzF5L
diff с файлом из поста:

7c7,8
<     mov si, 100
---
>     mov si, 0A000h
>     mov es, si
8a10
>     mov bp, 13 ; kruch
18,25c20
<     push cx
<         
<         ; ??????? ES ????????? ?? ???????????
<         mov ax, 0A000h
<         mov es, ax
<        
<         mov bh, 0FAh ;mov  bx, 320*200
<         mov ax, si
---
>         mov bh, 0FAh
27,43c22,27
<         
<             mov cx, 160
<             lp2:
<                 ; ?????? ? DX ????? ??????? ?? K1
<                 
<                 pusha
<                     mul  ax
<                     xchg ax, cx
<                     mul  ax
<                     add  ax, cx
<                     xor  dx, dx
<                     mov  bx, [kruch] ;mov  bx, 40    ; K1 = 40
<                     div  bx
<                     mov  bx, sp
<                     mov  word [bx+10], ax
<                 popa
<                 
---
>             mov  ax, bx
>             xor  dx, dx
>             div  word [_320+di-RRR]
>             sub  ax, 100
>             sub  dx, 160
> 
49c33
<                 mov   word [si], cx    ; SIN
---
>                 mov   word [si], dx    ; SIN
52,55c36,45
<                 fimul word [vnum]
<                 fmul  dword [glad]
<                 fist  word [si]
<                 add   dx, [si]
---
>                 fimul word [vnum+di-RRR]
>                 fmul  dword [glad+di-RRR]
>                 fistp word [si]
> 
>                 imul  ax, ax
>                 imul  dx, dx
>                 add   ax, dx
>                 xor   dx, dx
>                 div   bp
>                 add   ax, [si]
59,69c49,50
<                 mov  byte [es:bx], dl
< 
<             dec cx
<             cmp cx, -160
<             jg  lp2
<             
<         dec ax
<         cmp al, -100
<         jg  lp1
<             
<     pop cx
---
>                 mov  byte [es:bx], al
>                 jnz  lp1
77c58
<         add  cl, ch ; [DELTA]
---
>         add  ch, cl ; [DELTA]
88,92d68
<                 cmp al, 0 ; was ah!!
<                 jl  no_inv
<                 not ah
<                 no_inv:
<                 
94d69
<                 add  al, cl ; + ??????
102a78
>                 add  al, ch ; + ??????
108,109d83
<                     mov bx, di
<                     mov cx, 3
112c86
<                         and al, [bx]
---
>                         and al, [di+bx]
115c89
<                     loop mmm
---
>                         jnp mmm
118a93,94
>                 xor al, 0xFF
>                 js  setColor
121,122d96
<                 sub  al, cl ; - ??????
<             
124c98
<             jnz  setPalette_loop
---
>             jns  setPalette_loop
138a113,126
>         label_push_down:
>             cmp  al, 80
>             jne  label_push_up
>             dec  bp
>             jnz  paint_me
>             inc_kruch_paint_me:
>             inc  bp
>             paint_me:
>             jmp  paint
> 
>         label_push_up:
>             cmp  al, 72
>             je   inc_kruch_paint_me
>     
142c130
<             mov  ch, 0
---
>             mov  cl, 0
147c135
<             dec  ch
---
>             dec  cx
151,164d138
<             jne  label_push_down
<             inc  ch
<     
<         label_push_down:
<             cmp  al, 80
<             jne  label_push_up
<             dec  [kruch]
<             jnz  paint_me
<             inc  [kruch]
<             paint_me:
<             jmp  paint
< 
<         label_push_up:
<             cmp  al, 72
166,167c140
<             inc  [kruch]
<             jmp  paint
---
>             inc  cx
171,174c144,145
<             jne  label_push_G
<             not  byte [di]
<             
<         label_push_G:
---
>             je   change_color
>             inc  bx
176,179c147,148
<             jne  label_push_B
<             not  byte [di+1]
<             
<         label_push_B:
---
>             je   change_color
>             inc  bx
182c151,152
<             not  byte [di+2]
---
>         change_color:
>             not  byte [di+bx]
184a155
>             xor  bx, bx
189c160
<             jmp  paint
---
>             jmp  paint_me
203c174
< kruch dw 13
---
> _320  dw 320
205c176
< sign  db 'Dedicated to my wife 9'
\ No newline at end of file
---
> ;sign  db 'Dedicated to my wife 9'
\ No newline at end of file


За вычетом сигнатуры получаем экономию в 234 — 191 = 43 байта.
В части изменений вы уже разобрались, дополнительно:
— есть свободный регистр bp, самую частую переменную выгоднее засунуть туда, тем более что команды inc/dec word [di] двухбайтовые, а новые inc/dec bp однобайтовые; после этой правки звание самой частой переменной восстанавливается за RRR, на которую и указывает di;
— двойной цикл по координатам точки (ax,cx) выгоднее заменить одним циклом по bx — тем более что это цикл до нуля, такие проще — а координаты восстанавливать делением;
— cl и ch выгоднее переставить, тогда вместо двухбайтовых inc/dec ch можно использовать однобайтовые inc/dec cx; в качестве побочного эффекта при этом спираль начинает вращаться при запуске;
— цикл длины 3 можно записать не только как убывающий по cx от 3 до 0, но и как возрастающий по bx от 0 до 3; нетипичные команды jp/jnp проверяют флаг чётности числа бит в младшем байте результата PF, который для 1 и 2 имеет одно значение, а для 3 — другое; поскольку bx=0 от цикла по точкам, это экономит на инициализации; popa благополучно восстанавливает bx=0;
— можно убрать отдельные действия для al>=0 и al<0 за счёт «цикла» длины 2 (действия) / xor al, 0xFF / js (начало);
— ветку с безусловным переходом назад jmp paint лучше переместить повыше, чтобы jmp стал коротким;
— три команды not byte [di+xxx] можно объединить в одну not byte [di+bx]; после неё надо не забыть сбросить bx.
Супер!
(поностальгировал по ассемблеру, которым развлекался лет 10-15 назад)
Наконец-то на хабре что-то стоящее про ASM

(старое всё перечитано а новое и простое не так часто, а ух хорошее и вовсе редкость)
На ЭЛТ мониторе у вас наблюдается некоторое мерцание. (Щас поймал себя на том, что совершенно не в курсе, как обстоят дела с этой проблемой у LCD).

Я попробую объяснить, но могу ошибиться, так как давно всё это было :)

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

Т.е. допустим, луч на середине экрана, а вы начинаете рисовать сверху, и то что вы нарисуете, будет видно только после того, когда луч дойдет до низа экрана и снова пойдет отрисовывать сверху. Таким образом, когда я постоянно давлю клавишу, у вас получается на верхней половине экрана один кадр, а на нижней половине уже следующий.

Поэтому писать напрямую в видеопамять не принято, лучше выделить область памяти, рисовать туда, потом ждать сигнала «развертки», и кидать всё в видеопамять одним большим куском.

Примерно так:
;выделяем память
mov ah,4ah
mov bx,1000h
int 21h
mov ah,48h
int 21h
jc exit
mov word ptr vseg,ax
;обнулим её
mov es,ax
xor ax,ax
xor di,di
mov cx,32000
rep stosw ;можно использовать stosd

;ваш код

mov dx,3DAh ;порт
; цикл ожидания синхронизации c лучём элт
sync:
in al,dx
test al,8h
jz sync

pusha
push ds

; во vseg, понятно у нас как раз лежит указатель на наш буфер
mov ax,word ptr vseg
mov ds,ax
mov ax,0A000h
mov es,ax
xor si,si
xor di,di
mov cx,32000
rep movsw ;можно использовать movsd
pop ds
popa
;всё, фрейм отрисован
Пардон, я никоим образом не взаимодействую с лучами кинескопа. Я отрисовываю спираль только 1 раз (ну и при изменении числа рукавов). Для анимации циклически сдвигается палитра. Так что видеопамять тут как бы не причём.
Да, действительно, извиняюсь. Но мерцание, так или иначе, наблюдается, и именно такое, какое бывает при не синхронизированном анимации.

По идеё при смене палитры будет должна быть таже самая проблема, но я проверил, ожидание сигнала развертки перед loop_pal_out эффекта не даёт.

Помню, что решал проблему, сейчас поробую раскопать исходники. Может быть они еще живы.

Если что получится — ждём результатов тут.
Просто мне кажется с этим ничего не поделать…
угу, я не разобрался с вашим управлением. Влево/вправо нормально всё, но попробуйте все же добавить после loop_pal_out:
mov dx,03dah
sync:
in al,dx
test al,8h
jz sync

анимация по left/light будет плавнее.

А то что я имел в виду в начале ветки, это как раз именно то, что я имел в виду :) А именно: я нажимал up/down, а там перерисовка.
но там только синхронизацией не поможешь, скорее всего придется делать буфер.

И да, тригонометрию в реалтайме считать не тру, посмотрите, возможно можно обойтись заранее расчитаными таблицами?

И еще, зачем
mov ax, 0A000h
mov es, ax

стоит после paint:, если es у вас нигде не меняется?
Таблицы -> память -> объём кода.
Вычисления в данном случае приоритетней.
У Вас в коде — непаханное поле для оптимизации
Ну не скажи… Та версия что я щас выложил без подписи в конце занимает 234 байта. Сомневаюсь что его можно ужать байт на 20-30. В 10 байт я ещё поверю.
Кому-то не понравился ваш коммент. Странно выглядит на фоне одних плюсов вокруг.
и даже мой плюс не поправил ситуацию
Ну как вариант могу занятся оптимизацией, посмотрим сколько омжно выкрасть — надо только асм поставить
Ну я думаю выкрасть получится на особенностях асма, которые я увы не знаю. Какие-нибудь инструкции особые и т.д. По алгоритму оптимизировать я старался как мог.
Ну это же не «поле» для оптимизации))
Возможно стоит вытащить
mov ax, 0A000h
mov es, ax

чуть выше.
На самом деле изменение размера я добавил совсем недавно. Уже довёл код до 205 байт и бац! Изменение размера увеличило код до 234 байт.
Зачем выделять память ведь если нужно всего 64к (320х200 байт), в сегмент влезет

код примерный

lea si, buf
; обнулим её
xor ax,ax
xor di,di
mov cx,32000
rep stosw; можно использовать stosd

; ваш код

mov dx,3DAh; порт
; цикл ожидания синхронизации c лучём элт
sync:
in al,dx
test al,8h
jz sync

buf db?
Развил Вашу идею, правда… еще 11 лет назад.
«Overdoze (pseudo x-mode plasma)» — 238 байт (за минусом 7 байт, смотрите первые 7 байт файла)
Работа заняла 5 место на «Chaos Construction 2000» в питере, отправлял удаленно через фидо.

Кому интересно:

Архив работ «256 byte compo» с СС2000 можно скачать здесь
Или здесь (но вроде ссылка на скачивание битая)
Скачал посмотрел. Только оно так быстро скачет. Видно что палитрой играет. Жаль давно уже нет нигде 256b compo.
Ну нифига себе не думал) А 105 байт всего вышло))
Дело в том что моя лень диктует немного другие условия, для меня 105 байт на ASM это не «всего 105 байт» а «нифига себе аж 105 байт», ибо обычно я пишу на других языках, а ASM это теперь только хобби. Причём чаще всего я пишу чаще под Z80 а на х86 только переписываю то что понравилось.
Мне почему-то показалось, что это ракеты)))
Облака по формуле рисовали или битмап?
Если я правильно помню, там генерятся битмапы по несложному алгоритму, а потом они как-то хитро блюряться.
В Win7 и Vista работать не будет
Это потому что не поддерживается полноэкранный режим. Я давно хочу преодолеть это ограничение, уже даже есть наработки. А именно — во всем виноват видеодрайвер.

А пока можно использовать Windows XP mode — это автоматически устанавливаемая Virtual PC для Win7, очень удобно. Только нужно не забыть «Отключить компоненты интеграции» в меню Сервис.

Это потому что не поддерживается полноэкранный режим
А еще, возможно потому, что не поддерживаются COM-файлы
Кстати на 32-х битной версии вроде работать должно
.model tiny
.code
.386
org 100h

start: mov al,13h
int 10h
mov ax,0A000h
mov ds,ax
mov dx,1
M0: mov cl,40h
M1: push cx
xor cx,cx
mov ax,1010h
int 10h
add dh,dl
inc bx
pop cx
loop M1
neg dl
add dh,dl
cmp bl,0
jnz M0
M2: mov si,1
mov ax,108h
mov bx,154h
mov bp,101h
call proc1
neg si
add bp,7Eh
add bx,ax
call proc1
in al,60h
dec al
jnz M2
mov ax,3h
int 10h
ret

proc1 proc near
pusha
xor cx,cx
mov cl,0C8h
M4: push cx
mov cl,40h
M3: push cx
xor dx,dx
mov al,byte ptr [bx-1]
add dx,ax
mov al,byte ptr [bx+1]
add dx,ax
mov al,byte ptr [bx-140h]
add dx,ax
mov al,byte ptr [bx+140h]
add dx,ax
shr dx,2
inc dl
inc dl
mov byte ptr [bx],dl
add bx,si
pop cx
loop M3
add bx,bp
pop cx
loop M4
popa
ret
ret
proc1 endp
end start


Вот еще красивая вещь. 128байт. Конструктивно банальнейший клеточный автомат. Но благодаря хитрой формы палитре получается чертовски красивая вещь.

dl.dropbox.com/u/12226548/XCOM.ZIP
Интересне всего как ты допетрил до такого:
3) Циклический сдвиг палитры на одну позицию. Это и даёт иллюзию вращения спирали.

Или случайно обнаружил эффект?
Для этого спираль и градиентная. Иначе ничего бы не вышло. Без этой идеи не было бы программы))
Я подобных эффектов много обнаружил когда на Win95 сидел (кто знает что такое «logo.sys» тот поймёт) много тогда картинок туда ставил, включая подобные спирали, правда когда появился интернет я прочитал что всё то что я «открыл» уже лет так с 50 как уже открыто =)
Даже просмотрев исходники, не могу себя заставить взглянуть на экран – последствия впечатления просмотра скримеров.
Да, коль таки пошла такая пьянка, вставлю свои пять копеек.

Первая в мире демка в 256 Byte со звуком: www.youtube.com/watch?v=veSkQKzjbws

Я, собственно, звук и вставлял. Слабонервным, как обычно, не смотреть — депрессия гарантирована.
Вот интересно, какую часть объма занимает звук?
Очень небольшую, потому что там не семплирование, а прямая работа с MIDI портом. Заявленное на демопатю звуковое оборудование был Gravis Ultra Sound, у него под DOS в полном комплекте драйверов грузились и MIDI драйвера.

Мне нужно было сделать только переключение инструмента на орган, чтоб мрачнее было, и потом в качестве нот в порт засовывались случайные ноты с разной громкостью и разной длительностью. Вот и все.
Если вы страдаете приступами эпилепсии — НЕ ЗАПУСКАЙТЕ.
Ну да, не хотелось бы чтобы из-за ролика кто-нибудь пострадал :) Даже если вероятность этого 1/1000000 при определенном количестве просмотров ролика — вероятность сыграет против нас…
Sign up to leave a comment.

Articles