Page 1 of 1

FFire Demo Эффект огня

Posted: Sat Apr 23, 2016 12:40 pm
by Kopa
Не нашёл подходящий раздел для размещения. :)
Запустил один из демо примеров (имитация огня) из проекта ForthEC в Kолибри
Из различий c версией под Windows - пока не стал добавлять ограничение на FPS (загрузку процессора)
Kpack ужал код с 1800 байт -> 762 байта.
В Windows версии исполняемый файл этого примера имеет размер около 5200 байт.

P.S. ForthEC - кросс компилятор упрощённого Форт подобного языка в ассемблер MASM (и другие) (язык реализции Euphoria)
С возможностью втавки ассемблерного MASM кода. Хотелось проверить применимость данного инструментария для Колибри. :)
ffire (762 Bytes)
Downloaded 425 times

Re: FFire Demo Эффект огня

Posted: Sat Apr 23, 2016 5:18 pm
by Wildwest
Закинь сюда еще текст программы.

Re: FFire Demo Эффект огня

Posted: Sat Apr 23, 2016 5:37 pm
by Kopa
Думаю сделать какое то описание этого процесса :)
Код на ForthEC для Колибри
Spoiler:\ Allocate 28 bytes for the msg struct (actually 4+28)
variable rng 19 rng !
variable rngh 1 rngh !
variable video-buffer video-buffer 4 + video-buffer ! 65000 allot
variable screen screen 4 + screen ! 256000 allot
variable msg 28 allot
variable bih 36 allot
variable palette here ( palette 4 + palette ! ) 1030 allot palette !
variable done
variable last-time

: redraw
notouch
call init
call main
ret
redraw:
call draw_window
wait_event:
mov eax, 11
int 40h
dec eax
jz redraw
dec eax
jz key
dec eax
jz close
ret
close:
; button pressed; we have only one button, close
mov eax, -1
int 40h
key:
; key pressed, read it and ignore
mov eax, 2
int 40h
ret
jmp wait_event
touch
;

: draw_window
notouch
draw_window:
mov eax, 12
mov ebx, 1
int 40h ; start redraw
xor eax, eax
mov ebx, 50*65536 + 330 ; 360
mov ecx, 150*65536 + 228 ; 228

mov edx, 33FFFFFFh
mov edi, offset string ;title
int 40h ; define&draw window

; mov eax, 4
; mov ebx, 60*65536 + 10
; mov ecx, 80000000h
; mov edx, offset string
; int 40h ; draw string

; mov ebx, 50000h
; mov eax,dword ptr [var_0000000]
; mov ecx,dword ptr [eax]

; mov eax, 47
; mov edx, 20*65536 + 10
; mov esi, 0h ; color
; int 40h ; draw number

mov eax,dword ptr [var_0000002]
mov ebx, dword ptr [eax]
; mov edx, 2*65536 + 25 ; 150 x,y
; mov ecx, 320*65536 + 228 ; 50 size
mov edx, 0*65536 + 0 ; 150 x,y
mov ecx, 320*65536 + 200 ; 50 size

mov esi, 8
mov eax,dword ptr [var_0000006]
mov edi,dword ptr [eax]
mov ebp,0
mov eax,65
int 40h

mov eax, 12
mov ebx, 2
int 40h ; end redraw
ret
touch
;

\ Random number generator (borrowed from Paul Dixon)
: random ( -- n )
rngh rng notouch
pop esi
pop edi
mov edx,[edi]
shr edx,1
mov eax,[esi]
mov ecx,eax
rcr ecx,1
rcl edx,1
mov [edi],edx
shl eax,12
xor ecx,eax
mov eax,ecx
shr eax,20
xor ecx,eax
mov [esi],ecx
and ecx,191
mov eax,ecx
touch a@ ;


\ This draws the actual fire
: flames
12160 video-buffer @ +
12798 video-buffer @ +

160 0 do
over over
82 0 do
dup dup dup dup
c@ swap 2 + c@ + swap 4 + c@ + swap 644 + c@ + 2 >>
dup 0 <> if 1- then
dup 8 << or
dup 3 pick w!
2 pick 320 + w! swap 640 + swap 640 + loop
over 640 - random 10 + swap c!
drop drop swap 2 + swap 2 + loop drop drop ;

: setup-palette
palette @ 1024 -1 fill
palette @
33 1 do
i 3 << 1- \ pal c
over 0 swap !
over 2 + over swap c!
over 128 + 0 swap c!
over 129 + over swap c!
over 256 + c!
4 + loop drop
;

: draw-fire
flames

;


: win-main \ { hInst -- }

320 done !

\ Keep looping until the window is closed
begin
draw-fire
done @ dup 1- done ! 0= until

;

: main

notouch
main:
touch
setup-palette
\ Allocate room for a 320x200 bitmap, plus a little more

video-buffer 4 + video-buffer !
video-buffer @ 64000 0 fill
notouch
main1:
touch
win-main \ 19 rng !
notouch
call redraw
jmp main1
touch
;
Полученный листинг MASM
Spoiler:; Generated by ForthEC

.686p
.mmx
.model flat,stdcall
option casemap:none

include ani.inc

;##############################################################################

pushdw macro pval
db 68h
dd pval
endm

;##############################################################################

.data
db 'MENUET01'
dd 1
dd offset _start
dd offset bss_start
dd offset bss_end
dd offset stacktop
dd 0, 0
title db 'HelloWorld test',0
string db 'FFire Demo',0
szFormatInt db "%d ",0
szFormatChar db "%hc",0
szBuffer db 256 dup(0)
szCR db 13,0
szLF db 10,0

.data?
bss_start label byte
align 4
db 1000h dup (?)
stacktop = $
stackBase dd ?
dictptr dd ?
dictionary dd 100000 dup(?)
ipstackptr dd ?
ipstack dd 256 dup(?)
fpstackptr dd ?
fpstack dq 128 dup(?)
loopstackptr dd ?
loopstack dd 64 dup(?)
miscstackptr dd ?
miscstack dd 64 dup(?)
hOutput dd ?
hInput dd ?
caseVar dd ?
lpCharsWritten dd ?
scratch1 dd ?
scratch2 dd ?
returnaddress dd ?
var_0000005 dd ?
var_0000007 dd ?
var_0000008 dd ?
var_0000004 dd ?
var_0000006 dd ?
var_0000000 dd ?
var_0000001 dd ?
var_0000003 dd ?
var_0000002 dd ?
bss_end label byte

;##############################################################################

.code
_start:
mov fpstackptr,offset fpstack
mov ipstackptr,offset ipstack
add ipstackptr,1024
mov dictptr,offset dictionary
mov miscstackptr,offset miscstack
mov loopstackptr,offset loopstack

; redraw
@@lbl_726564726177:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
call init
call main
ret
redraw:
call draw_window
wait_event:
mov eax, 11
int 40h
dec eax
jz redraw
dec eax
jz key
dec eax
jz close
ret
close:
; button pressed; we have only one button, close
mov eax, -1
int 40h
key:
; key pressed, read it and ignore
mov eax, 2
int 40h
ret
jmp wait_event
@@lbl_726564726177_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; draw_window
@@lbl_647261775F77696E646F77:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
draw_window:
mov eax, 12
mov ebx, 1
int 40h ; start redraw
xor eax, eax
mov ebx, 50*65536 + 330 ; 360
mov ecx, 150*65536 + 228 ; 228
mov edx, 33FFFFFFh
mov edi, offset string ;title
int 40h ; define&draw window
; mov eax, 4
; mov ebx, 60*65536 + 10
; mov ecx, 80000000h
; mov edx, offset string
; int 40h ; draw string
; mov ebx, 50000h
; mov eax,dword ptr [var_0000000]
; mov ecx,dword ptr [eax]
; mov eax, 47
; mov edx, 20*65536 + 10
; mov esi, 0h ; color
; int 40h ; draw number
mov eax,dword ptr [var_0000002]
mov ebx, dword ptr [eax]
; mov edx, 2*65536 + 25 ; 150 x,y
; mov ecx, 320*65536 + 228 ; 50 size
mov edx, 0*65536 + 0 ; 150 x,y
mov ecx, 320*65536 + 200 ; 50 size
mov esi, 8
mov eax,dword ptr [var_0000006]
mov edi,dword ptr [eax]
mov ebp,0
mov eax,65
int 40h
mov eax, 12
mov ebx, 2
int 40h ; end redraw
ret
@@lbl_647261775F77696E646F77_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; random
@@lbl_72616E646F6D:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
push dword ptr [var_0000001]
mov esi,dword ptr [var_0000000]
pop edi
mov edx,[edi]
shr edx,1
mov eax,[esi]
mov ecx,eax
rcr ecx,1
rcl edx,1
mov [edi],edx
shl eax,12
xor ecx,eax
mov eax,ecx
shr eax,20
xor ecx,eax
mov [esi],ecx
and ecx,191
mov eax,ecx
push eax
@@lbl_72616E646F6D_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; flames
@@lbl_666C616D6573:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
add miscstackptr,4
mov eax,miscstackptr
mov [eax-4],ebp
mov ebp,loopstackptr
pushdw 12160
mov eax,dword ptr [var_0000002]
mov ebx,[eax]
add [esp],ebx
pushdw 12798
mov eax,dword ptr [var_0000002]
mov ebx,[eax]
add [esp],ebx
mov dword ptr [esp-4],160
mov dword ptr [esp-8],0
sub esp,8
mov eax,ebp
pop ecx
pop edx
add ebp,8
mov [eax],edx
mov [eax+4],ecx
@@loop_0000:
push dword ptr [esp+4]
push dword ptr [esp+4]
pushdw 82
mov esi,0
add ebp,8
pop edi
@@loop_0001:
push dword ptr [esp]
push dword ptr [esp]
push dword ptr [esp]
mov eax,[esp]
movzx ebx,byte ptr [eax]
mov eax,ebx
pop ecx
push eax
lea eax,[ecx+2]
movzx ebx,byte ptr [eax]
add [esp],ebx
pop eax
pop ecx
push eax
lea eax,[ecx+4]
movzx ebx,byte ptr [eax]
add [esp],ebx
pop eax
pop ecx
push eax
lea eax,[ecx+644]
movzx ebx,byte ptr [eax]
add [esp],ebx
mov ecx,2
shr dword ptr [esp],cl
cmp dword ptr [esp],0
jz @@if_000000_false
dec dword ptr [esp]
@@if_000000_false:
@@if_000000_true:
mov eax,dword ptr [esp]
shl eax,8
or [esp],eax
mov eax,dword ptr [esp+8]
mov ecx,dword ptr [esp]
mov [eax],cx
mov ecx,dword ptr [esp+8]
add ecx,320
pop eax
mov [ecx],ax
pop eax
pop ecx
push eax
lea eax,[ecx+640]
pop ecx
push eax
push ecx
add dword ptr [esp],640
inc esi
cmp esi,edi
jne @@loop_0001
@@loop_0001_end:
sub ebp,8
push dword ptr [esp+4]
mov eax,640
sub [esp],eax
call @@lbl_72616E646F6D
add dword ptr [esp],10
pop ecx
pop eax
mov [eax],cl
lea esp,[esp+8]
pop eax
pop ecx
push eax
lea eax,[ecx+2]
pop ecx
push eax
push ecx
add dword ptr [esp],2
lea eax,[ebp-8]
inc dword ptr [eax+4]
mov ecx,[eax]
cmp [eax+4],ecx
jne @@loop_0000
@@loop_0000_end:
sub ebp,8
lea esp,[esp+8]
@@lbl_666C616D6573_return:
sub miscstackptr,4
mov loopstackptr,ebp
mov esi,miscstackptr
mov ebp,[esi]
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; setup-palette
@@lbl_73657475702D70616C65747465:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
add miscstackptr,4
mov eax,miscstackptr
mov [eax-4],ebp
mov ebp,loopstackptr
mov eax,dword ptr [var_0000006]
push dword ptr [eax]
pushdw 1024
mov eax,-1
pop ecx
pop edi
rep stosb
mov eax,dword ptr [var_0000006]
push dword ptr [eax]
pushdw 33
mov esi,1
add ebp,8
pop edi
@@loop_0002:
push esi
shl dword ptr [esp],3
dec dword ptr [esp]
push dword ptr [esp+4]
mov eax,0
pop ecx
xchg eax,ecx
mov [eax],ecx
push dword ptr [esp+4]
add dword ptr [esp],2
mov ecx,dword ptr [esp+4]
pop eax
mov [eax],cl
push dword ptr [esp+4]
add dword ptr [esp],128
mov eax,0
pop ecx
xchg eax,ecx
mov [eax],cl
push dword ptr [esp+4]
add dword ptr [esp],129
mov ecx,dword ptr [esp+4]
pop eax
mov [eax],cl
push dword ptr [esp+4]
add dword ptr [esp],256
mov eax,[esp]
mov ecx,[esp+4]
mov [eax],cl
add esp,8
add dword ptr [esp],4
inc esi
cmp esi,edi
jne @@loop_0002
@@loop_0002_end:
sub ebp,8
lea esp,[esp+4]
@@lbl_73657475702D70616C65747465_return:
sub miscstackptr,4
mov loopstackptr,ebp
mov esi,miscstackptr
mov ebp,[esi]
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; draw-fire
@@lbl_647261772D66697265:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
call @@lbl_666C616D6573
@@lbl_647261772D66697265_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; win-main
@@lbl_77696E2D6D61696E:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
mov eax,dword ptr [var_0000007]
mov dword ptr [eax],320
@@loop_0003:
call @@lbl_647261772D66697265
mov eax,dword ptr [var_0000007]
push dword ptr [eax]
push dword ptr [esp]
dec dword ptr [esp]
mov eax,dword ptr [var_0000007]
pop ecx
mov [eax],ecx
pop eax
xor ecx,ecx
sub esp,4
cmp eax,0
pop eax
jnz @@loop_0003
@@loop_0003_end:
@@lbl_77696E2D6D61696E_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]
; main
@@lbl_6D61696E:
sub ipstackptr,4
mov eax,ipstackptr
pop dword ptr [eax]
main:
call @@lbl_73657475702D70616C65747465
push dword ptr [var_0000002]
add dword ptr [esp],4
mov eax,dword ptr [var_0000002]
pop ecx
mov [eax],ecx
mov eax,dword ptr [var_0000002]
push dword ptr [eax]
pushdw 64000
mov eax,0
pop ecx
pop edi
rep stosb
main1:
call @@lbl_77696E2D6D61696E
call redraw
jmp main1
@@lbl_6D61696E_return:
mov eax,ipstackptr
add ipstackptr,4
jmp dword ptr [eax]

;##############################################################################

init:
mov fpstackptr,offset fpstack
mov ipstackptr,offset ipstack
add ipstackptr,1024
mov dictptr,offset dictionary
mov miscstackptr,offset miscstack
mov loopstackptr,offset loopstack

mov eax,dictptr
mov var_0000000,eax
add dictptr,4
mov eax,dword ptr [var_0000000]
mov dword ptr [eax],19
mov eax,dictptr
mov var_0000001,eax
add dictptr,4
mov eax,dword ptr [var_0000001]
mov dword ptr [eax],1
mov eax,dictptr
mov var_0000002,eax
add dictptr,4
push dword ptr [var_0000002]
add dword ptr [esp],4
mov eax,dword ptr [var_0000002]
pop ecx
mov [eax],ecx
mov eax,65000
add dictptr,eax
mov eax,dictptr
mov var_0000003,eax
add dictptr,4
push dword ptr [var_0000003]
add dword ptr [esp],4
mov eax,dword ptr [var_0000003]
pop ecx
mov [eax],ecx
mov eax,256000
add dictptr,eax
mov eax,dictptr
mov var_0000004,eax
add dictptr,4
mov eax,28
add dictptr,eax
mov eax,dictptr
mov var_0000005,eax
add dictptr,4
mov eax,36
add dictptr,eax
mov eax,dictptr
mov var_0000006,eax
add dictptr,4
push dword ptr [dictptr]
mov eax,1030
add dictptr,eax
mov eax,dword ptr [var_0000006]
pop ecx
mov [eax],ecx
mov eax,dictptr
mov var_0000007,eax
add dictptr,4
mov eax,dictptr
mov var_0000008,eax
add dictptr,4

ret
END _start
Полученный листинг "ассемблируется" (превращается в obj), линкуется, транслируется (через использование скрипта doexe с помощью FASM) по методике описанной в Wiki

P.S. Для понимания действий по формированию Flames для себя расписал действия с ячейками памяти по данному коду на листочке.
(возможно имеет смысл отобразить дополнительно) и можно его, наверное если есть смысл, записать его более прозрачно средствами ForthEC или представить в виде мнемо-рисунка. Алгоритм формирования палитры более простой по действиям :) (их можно переписать и на ассемблере)
ForthEC тоже подвергся некоторым доработкам по способу запуска кода. Можно убрать ещё некоторую избыточность кода программы
и поработать над компилятором ForthEC c опробованием разных опций оптимизации.
Выполнение кода начинается с кода первого слова redraw (название в этом месте чисто номинальное и более подходит, что то сообразное Entry)
А далее вызывается Init где производится инициализация стеков и main цикл по рисованию и опросу событий (в листинге ассемблера)
notouch ... touch прямая вставка MASM кода без изменений для компилятора (переменные в ассемблере из Форт идентифицируются по номеру)
Цикл по отрисовке заданного количество Flames в win-main избыточен (остался по недосмотру при "экспериментах" с кодом) наверное можно убрать. Работа примера не "оптимизировалась" для эмулятора (чем код необходимо дополнить)

P.P.S. Тему можно как то переобозначить если дополнить другими "элементами" и их описанием этого решения (кому будет интересно)
Есть интерес к рассмотрению "потенциала" и подводных камней данного подхода и варианты доработки "напильником" (головой и руками)

Архив с примером и ForthEC вариантом для Kolibri OS (в файле readme указана последовательность запуска bat файлов)
В системе должны присутствовать MASM32 и Euphoria (чувствительность к конкретной версии не проверялась 3-й или 4-ой)
kol_forthec.zip (37.11 KiB)
Downloaded 431 times
Проект оригинального ForthEC находится здесь
Последняя версия ForthEC от автора на github

Re: FFire Demo Эффект огня

Posted: Sun Apr 24, 2016 11:04 am
by Kopa
Добавил файлы проекта для самостоятельной сборки примера.
Некоторые обсуждения ForthEC можно найти на Форт форуме fforum.winglion.ru (от пользователя с ником Kamikaze)

Re: FFire Demo Эффект огня

Posted: Wed May 16, 2018 1:36 am
by 0CodErr
Закомментировал в сгенерированном http://board.kolibrios.org/viewtopic.ph ... 268#p65268 MASM-листинге:

Code: Select all

include ani.inc
оно для KolibriOS не нужно просто.

Перенёс из секции .data в начало секции .code:

Code: Select all

db 'MENUET01'
dd 1
dd offset _start
dd offset bss_start
dd offset bss_end
dd offset stacktop
dd 0, 0
и собрал с помощью UASM http://www.terraspace.co.uk/uasm.html[code]uasm32 -bin -Fo fire_forthec.kex fire_forthec.asm[/code]Кстати, для сравнения: размер файла из архива http://board.kolibrios.org/viewtopic.php?p=65268#p65268 — 1804 байт, а размер полученного — 1767 байт.
Если поправить ForthEC, чтобы он вставлял AppHeader сразу в секцию .code, то извращения с fasm и doexe будут не нужны.

В самой демке при перерисовке заметно мерцание, думаю, поможет использование флага для процедуры DrawWindow

Code: Select all

WS_FILL_TRANSPARENT  = $40000000;

Re: FFire Demo Эффект огня

Posted: Sat May 19, 2018 7:16 pm
by 0CodErr
Я кое-что подправил, в том числе make.bat.
У меня интерпретатор называется не euiw.exe, а exwc.exe.

Code: Select all

Euphoria Interpreter 3.1.1 for 32-bit Windows.
Copyright (c) Rapid Deployment Software 2007
See http://www.RapidEuphoria.com/License.txt
Перенёс в исходнике ForthEC вот это

Code: Select all

        puts(outfile,"\tdb 'MENUET01'"&NL)
        puts(outfile,"\tdd 1"&NL)
        puts(outfile,"\tdd offset _start"&NL)
        puts(outfile,"\tdd offset bss_start"&NL)
        puts(outfile,"\tdd offset bss_end"&NL)
        puts(outfile,"\tdd offset stacktop"&NL)
        puts(outfile,"\tdd 0, 0"&NL) 
 
в то место, где генерируется секция .Code.
Зачем-то было захардкожено

Code: Select all

        puts(outfile," title db 'HelloWorld test',0"&NL)
        puts(outfile," string db 'FFire Demo',0"&NL)
то есть, заголовок задаётся в исходнике компилятора :shock: а не в исходнике forth-программы. Я оставил это как есть, но это нужно убрать из компилятора.
Думаю, можно добавить target kos в ForthEC и использовать его вместо win32.

Для сборки требуется:
ffire_ForthEC.7z (25.55 KiB)
Downloaded 330 times