Всем привет. Предлагаю попробовать понять, что делается в этой демке: https://www.pouet.net/prod.php?which=78050 Код (Text): ; ЙННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН» ; є This file is generated by The Interactive Disassembler (IDA) є ; є Copyright (c) 2010 by Hex-Rays SA, <support@hex-rays.com> є ; є Licensed to: Freeware version є ; ИНННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННј ; ; Input MD5 : C2FB6805097A4B2FDE9729F5759AE03B ; File Name : C:\dosbox\Virtual\elite256.com ; Format : MS-DOS COM-file ; Base Address: 0h Range: 100h-1F6h Loaded length: F6h .386 .model tiny ; Segment type: Pure code seg000 segment byte public 'CODE' use16 assume cs:seg000 org 100h assume es:nothing, ss:nothing, ds:seg000, fs:nothing, gs:nothing public start start proc near mov al, 13h int 10h ; - VIDEO - mov word ptr [si], 0FFB0h push 9FBAh pop es assume es:nothing loc_10C: fninit mov ax, [si] cmp ax, si jl short loc_116 mov ax, si loc_116: shl ax, 6 mov [si-50h], ax fild word ptr [si] mov word ptr [bp+si], 1Eh fidiv word ptr [bp+si] fsincos loc_126: mov ax, 0CCCDh mul di sub dh, 68h mov al, 0 mov bp, 4000h pusha mov cl, 80h loc_136: fild word ptr [bx-8] fmul st, st(1) fild word ptr [bx-0Eh] fmul st, st(3) faddp st(1), st fild word ptr [bx-0Eh] fmul st, st(2) fild word ptr [bx-8] fmul st, st(4) fsubp st(1), st fld st fmul st, st(4) fild word ptr [bx-9] fmul st, st(4) faddp st(1), st fxch st(1) fmul st, st(3) fild word ptr [bx-9] fmul st, st(5) fsubp st(1), st fld st fabs fld st(2) fabs faddp st(1), st fld st(3) fabs faddp st(1), st fisub word ptr [si-50h] fistp dword ptr [bp+si] cmp [bp+si+1], bx jg short loc_1B7 mov al, 0Eh fistp word ptr [si-64h] test [si-64h], sp js short loc_189 dec ax loc_189: fistp word ptr [si-60h] test [si-60h], sp js short loc_192 dec ax loc_192: fistp word ptr [bp+si] test [bp+si], sp js short loc_199 dec ax loc_199: add ax, ax cmp word ptr [bp+si], 1000h jl short loc_1D5 cmp word ptr [bp+si], 1800h jg short loc_1D5 cmp byte ptr [si-63h], 8 jl short loc_1D5 cmp byte ptr [si-5Fh], 8 jl short loc_1D5 mov al, 12h jmp short loc_1D5 loc_1B7: fstp st fstp st fstp st sub [bx-0Eh], si dec cx jnz loc_136 mov al, dl add al, [si] imul dh and ax, 55Fh dec ax mov al, 1Fh jz short loc_1D5 mov al, 0 loc_1D5: mov [bx-4], al popa stosb test di, di jnz loc_126 inc word ptr [si] cmp word ptr [si], 200h jg short loc_1F0 in al, 60h ; AT Keyboard controller 8042. cmp al, 1 jnz loc_10C loc_1F0: mov ax, 3 int 10h ; - VIDEO - SET VIDEO MODE ; AL = mode retn start endp seg000 ends end start Работает в досбоксе очень медленно (на видео выглядит веселее). И код выглядит так, будто весь алгоритм процедурный и представлен в виде монолитного куска кода.
Код (Text): // Константы видеорежима 13h const int WIDTH = 320; const int HEIGHT = 200; void draw_frame() { float time = get_frame_counter(); // инкремент [si] float angle_sin = sin(time / 30.0); float angle_cos = cos(time / 30.0); // Внешний цикл по всей видеопамяти (от 0 до 65535) // В асме это: loc_126 -> stosb -> jnz loc_126 for (int i = 0; i < 65536; i++) { // 1. Проецируем индекс пикселя в экранные координаты (x, y) // В асме: mul di / sub dh, 68h float x = (i % WIDTH) - (WIDTH / 2); float y = (i / WIDTH) - (HEIGHT / 2); float z = 0; // Начальная глубина луча int color = 0; // По умолчанию черный (фон) // 2. Внутренний цикл: "шагаем" лучом вглубь (Raymarching) // В асме это: loc_136 -> jnz loc_136 (cx = 128 итераций) for (int step = 0; step < 128; step++) { // Вращаем координаты (x, y, z) с помощью sin/cos // В асме это блок fmul/fadd/fsub после fsincos float rx = x * angle_cos - z * angle_sin; float rz = x * angle_sin + z * angle_cos; float ry = y; // 3. ФОРМУЛА РОМБА (L1-метрика) // В асме: fabs / faddp / fisub // Это условие: |rx| + |ry| + |rz| < RADIUS float distance = abs(rx) + abs(ry) + abs(rz); if (distance < RADIUS) { // Если луч ударился о ромб — вычисляем цвет // В асме: блоки loc_189, loc_192 (проверки знаков через test) color = calculate_shading(rx, ry, rz); break; // Выход из цикла шагов } // Продвигаем луч глубже в сцену z += 1.0; } // 4. Запись в видеопамять video_memory[i] = color; } } - Gemini.