Hi , I came across this video on youtube http://www.youtube.com/watch?v=75AHKaSPUD8
About 17 seconds in there a Falling snow effect....
Does anybody know how that is achieved?
Or has anybody sen this before? it looks so cool
im still learning a lot about assembly and i dont know much! so i dont know if i should be the one to contribute but i'd like to try! :)
the snowflakes just look like static images that are just moving down the screen, the side to side stuff could be done by some kind of periodic function like sine, which in the context we're using it is just a function that would return between -1 and 1 floating point, so you give it an angle increasing linearly and it kinda makes stuff move smoothly back and forth between those two values.
in c you'd do like
counter += (PI / ITERATIONS_PER_WIDTH); //by PI we've moved an entire width, so we divide that by how many times we iterate to move a width
snow_flake.x = sin(counter)*(WIDTH_OF_MOVEMENT)/2 //moves between -1 and 1, so we have to account for that by dividing by 2
in asm you'd have to use the fpu to get something cool like that and i dont know much about that! :)
the absolute value of a signed interpretation of any memory size should give you a periodic function that looks like a triangle if you get the abs
say we have a byte, the values count like this:
unsigned : 1,2,3,...,125,126,127,128,129,130
signed : 1,2,3,....,125,126,127,-128,-127,-126 : i.e. 126,127,128,127,126, periodic and linearly smooth!
dont think that'll help though. i dont know how to get the absolute value in asm and looking at the opcode list in masm32's help files it might be better just using cmp, je, inc, and dec rather than trying to be clever :(
you could use BitBlt to draw the snowflake
BitBlt will transfer a DC to the DC of a window so you could put a snowflake in a DC then tell it to bitblt to the window multiple times, from there it'd just be updating the positions and bitblting all the snowflakes.
theres a recent post that qWord responded to on how to use bitblt and how to create a Memory DC and all kinds of cool graphic jazz:
http://www.masm32.com/board/index.php?topic=17109.0
ill post the crappy code i wrote to play with graphics as well!
in iczelion site , there is a very good similar sample who made a water effect on the screen.
Modify it a little and you will have a snow effect
Thank you all for the responses .... I started this post, after I emailed the author of that video for the falling snow effect and got no response....
It turned out that the author was on a vacation , and got back to me today .....
the author was nice enough to email me this effect here it is (the way I got it, sorry about the "about content") :dazzled:
i noticed he has a blog, too
somewhere in there, you can probably find the "28 ASM Effects" article
http://xylibox.blogspot.com/
might want to be careful with his downloads, though :P
This is way cooler at 335 bytes.
Quote from: dedndave on August 04, 2011, 08:44:40 PM
i noticed he has a blog, too
somewhere in there, you can probably find the "28 ASM Effects" article
http://xylibox.blogspot.com/
might want to be careful with his downloads, though :P
LOL No Thanks .... that will harm my computer most likely .....
the rest of the graphical effects minus one of them are from "THE CYBERDOOM SYSTEMS" :red....I don't want to post the link due to the content but if you Google it .... at least 26 of them
Quote from: Magnum on August 04, 2011, 08:59:19 PM
This is way cooler at 335 bytes.
LOL a com file....
that would be cooler if it was a win32 with source :8)
I looked into it, but it's a very complicated using opengl.
It's a steep learning curve.
yay i think i got some of it right! i see sin and bitblt and a snowdc in here. thank you so much for posting this! :) i always wondered how people did those cool looking window frames. and it has threads in here! i have much to learn :)
(http://smiles.kolobok.us/big_madhouse/mail1.gif) translate most remarks
hi,
in the attachment an example using GDI+.
qWord
EDIT: there was a handle leak ...
god damn qword. thats just beautiful
Quote from: bomz on August 05, 2011, 06:49:38 PM
(http://smiles.kolobok.us/big_madhouse/mail1.gif) translate most remarks
Thank you very much bomz.... :U
Quote from: hfheatherfox07 on August 03, 2011, 11:19:53 PM
Hi , I came across this video on youtube http://www.youtube.com/watch?v=75AHKaSPUD8
About 17 seconds in there a Falling snow effect....
Does anybody know how that is achieved?
Or has anybody sen this before? it looks so cool
Most of those graphic effects are probably not done with OGL / DX, I'm willing to bet it's GDI (not GDI+) or DirectDraw, both can provide fast and easy access to a framebuffer for your drawing. Plus writing your own graphics engine from the ground up like that is a cool throwback to older demoscene stuff so it's popular to find in trainers etc. GDI you can use CreateDibSection() or with DirectDraw you can lock a surface for a pointer to the bits, from there you have direct access to your framebuffer.
Think of each one of your snowflakes as an object (a struct) with an x, y, and whatever else you want to influence it, like speed. Generate random starting points and for each logic tick, move them down vertically, and along a sine wave horizontally. You can skew the sine slightly to make it appear more unpredictable than a perfect wave motion.
I always liked starfields, very cool effect and simple, I've written both 3d and 2d versions of it, can post the source if anyone is interested... just be warned it's in C. The 3d one is interesting because it shows off 3d transformation, can use it as a base to a 3d software renderer.
Quote from: slovach on August 09, 2011, 03:04:22 AM
I always liked starfields, very cool effect and simple, I've written both 3d and 2d versions of it, can post the source if anyone is interested... just be warned it's in C. The 3d one is interesting because it shows off 3d transformation, can use it as a base to a 3d software renderer.
That sounds really cool slovach! I personally would love to see the source to those if you wrote them with gdi :)
Here's a 2d starfield, code isn't structured, just thrown together as an example, have to add the typedefs yourself for the types since I forgot to include it and I'm too lazy to reupload it. If you have any questions as to what exactly is going on anywhere, just ask. It should be fairly simple to follow.
typedefs
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned __int64 u64;
typedef char s8;
typedef short s16;
typedef int s32;
typedef __int64 s64;
typedef float f32;
typedef double f64;
If you're observant you'll notice that the stars don't overlap nicely, there is no proper alpha blending here, I just dim the color instead of blending it. It's easy to fix, but it's most noticeable in the 3d version since you can use alpha blending as a trick to simulate the stars coming out of the darkness.
You get this: http://dl.dropbox.com/u/10565193/sf_2d.rar
3d is a little more involved and I apparently lost my source so I'll just rewrite it, I'll try to explain the 3d transformation while I'm at it.
I still have the exe though somehow, so count it as a preview:
http://dl.dropbox.com/u/10565193/sf3d.rar
Just found some ancient demo routines I did on the Amiga.
Converted them to run on the PC ( PMODE ).
It's not complete but you can have a look at the routines.
It has some nice 3D-star effects.
You can use the star routine for a nice snow effect.....
Siekmanski,
Just to let you know, those programs won't run on Win Vista and Win 7 because they use full screen mode.
Quote from: GregL on August 11, 2011, 01:18:20 AM
Siekmanski,
Just to let you know, those programs won't run on Win Vista and Win 7 because they use full screen mode.
When in doubt, use DOSBOX :)
Quote from: slovach on August 11, 2011, 02:56:28 AM
Quote from: GregL on August 11, 2011, 01:18:20 AM
Siekmanski,
Just to let you know, those programs won't run on Win Vista and Win 7 because they use full screen mode.
When in doubt, use DOSBOX :)
Good idea! here is DOSBOX Portable !
http://sourceforge.net/projects/portableapps/files/DOSBox%20Portable/DOSBox%20Portable%200.74/DOSBoxPortable_0.74.paf.exe/download
This is crude and GDI only, but I think it produces a reasonable effect.
Edit:
Cleaned up the code somewhat. Also increased the update rate and decreased the mean Y increment for smoother motion at the expense of a higher CPU usage.
Edit2:
Updated the code again to add a frame-rate display. If I eliminate the update delay by setting UPDATE_DELAY to zero, with SET_PIXEL = 1 I get a frame rate of ~53, and with SET_PIXEL = 0 I get a frame rate of ~878. So almost all of the update loop time is spent in the calls to SetPixel.
Edit3:
Updated the code again, partly to fix flaws, but mostly to add a faster set pixel procedure.
;==============================================================================
include \masm32\include\masm32rt.inc
.686 ; required for fcomip
;==============================================================================
FLAKE_COUNT equ 2000
UPDATE_DELAY equ 0
USE_FASTSETPIXEL equ 1
;==============================================================================
FPU_RC_NEAREST equ 0
FPU_RC_DOWN equ 400h
FPU_RC_UP equ 800h
FPU_RC_TRUNCATE equ 0c00h
;--------------------------------------------------------------------
; This macro sets the rounding control bits in the FPU Control Word.
;--------------------------------------------------------------------
FPU_SETRC MACRO rc
push eax
fstcw [esp]
pop eax
and eax, NOT 0c00h
or eax, rc
push eax
fldcw [esp]
pop eax
ENDM
;==============================================================================
FLAKE STRUCT
ix DWORD ?
iy DWORD ?
fi REAL4 ?
fy REAL4 ?
FLAKE ENDS
;==============================================================================
.data
hInst dd 0
hDlg dd 0
hdcDDB dd 0
hdcClient dd 0
hDDB dd 0
hPrevBmp dd 0
clientW dd 0
clientH dd 0
pFlakeData dd 0
pBMI dd 0
pDIBits dd 0
frameCount dd 0
ps PAINTSTRUCT <>
rc RECT <>
msg MSG <>
.code
;==============================================================================
;------------------------------------------------------------------------
; This is Abel's version of a Park-Miller-Carta generator, details here:
; http://www.masm32.com/board/index.php?topic=6558.0
; Modified to return a floating-point value in the interval [0,1) at
; the top of the FPU stack in ST(0), as per the normal convention.
;
; The period of the core generator is 2147483646 (tested), and it runs
; in 23 cycles on a P3, including the call overhead and a fstp to store
; the result to memory. Note that in my tests setting frnd_divider to
; the period instead of to a power of 2 caused a ~2x slowdown.
;------------------------------------------------------------------------
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 4
frnd proc
.data
align 8
frnd_divider dq 2147483648
abel_rand_seed dd 1
.code
mov eax, abel_rand_seed
mov ecx, 16807 ; a = 7^5
mul ecx ; edx:eax == a*seed == D:A
mov ecx, 7fffffffh ; ecx = m
add edx, edx ; edx = 2*D
cmp eax, ecx ; eax = A
jna @F
sub eax, ecx ; if A>m, A = A - m
@@:
add eax, edx ; eax = A + 2*D
jns @F
sub eax, ecx ; If (A + 2*D)>m
@@:
mov abel_rand_seed, eax ; save new seed
fild abel_rand_seed
fild frnd_divider
fdiv
ret
frnd endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;==============================================================================
;---------------------------------------------------------
; To keep it simple, this procedure supports 32-bpp only.
;---------------------------------------------------------
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 4
FastSetPixel proc x:DWORD, y:DWORD, color:DWORD
mov ecx, [esp+8]
mov eax, clientW
mul ecx
mov ecx, eax
mov edx, pDIBits
mov eax, [esp+4]
add ecx, eax
mov eax, [esp+12]
mov [edx+ecx*4], eax
ret 12
FastSetPixel endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;==============================================================================
DialogProc proc hwndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
SWITCH uMsg
CASE WM_INITDIALOG
invoke GetClientRect, hwndDlg, addr rc
mov eax, rc.right
inc eax
mov clientW, eax
mov eax, rc.bottom
inc eax
mov clientH, eax
;-------------------------------------------
; Allocate memory for the flake data array.
;-------------------------------------------
mov eax, FLAKE_COUNT
shl eax, 4
mov pFlakeData, alloc(eax)
;-------------------------------------------------------------
; Get a DC for the client area and create a compatible memory
; DC and compatible bitmap (DDB). The compatible bitmap is
; used as a drawing surface for the API SetPixel function and
; to receive the bitmap bits from the device-independent
; bitmap (DIB) that the FastSetPixel procedure draws on.
;-------------------------------------------------------------
invoke GetDC, hwndDlg
mov hdcClient, eax
invoke CreateCompatibleDC, hdcClient
mov hdcDDB, eax
invoke CreateCompatibleBitmap, hdcClient, clientW, clientH
mov hDDB, eax
;----------------------------------------------------
; Select the bitmap into the memory DC and save the
; previously selected object.
;
; The bitmap, by default, will be filled with black.
;----------------------------------------------------
invoke SelectObject, hdcDDB, hDDB
mov hPrevBmp, eax
push ebx
push esi
;-------------------------------------------------------------
; Allocate memory to store the BITMAPINFO structure for our
; DIB and set the biSize member to the size of the structure.
;-------------------------------------------------------------
mov esi, alloc(SIZEOF BITMAPINFO)
mov pBMI, esi
mov [esi].BITMAPINFO.bmiHeader.biSize, SIZEOF BITMAPINFO
;--------------------------------------------------------
; Call the GetDIBits function with the lpvBits parameter
; set to NULL, so the function will pass the dimensions
; and format of the bitmap to the BITMAPINFO structure.
;--------------------------------------------------------
invoke GetDIBits, hdcClient, hDDB, 0, 0, NULL, pBMI, DIB_RGB_COLORS
;------------------------------------
; Ensure that the display bpp is 32.
;------------------------------------
movzx eax, [esi].BITMAPINFO.bmiHeader.biBitCount
cmp eax, 32
je @F
invoke MessageBox, hwndDlg, chr$("Display bpp must be 32 "), 0, 0
call destroy
@@:
;----------------------------------------------------------------
; To keep access to the DIB bits simple, specify an uncompressed
; format and a negative height, so we get a top-down DIB instead
; of the normal bottom-up DIB.
;----------------------------------------------------------------
mov [esi].BITMAPINFO.bmiHeader.biCompression, BI_RGB
neg [esi].BITMAPINFO.bmiHeader.biHeight
;---------------------------------------------------------
; Allocate a buffer to store the bitmap bits for our DIB.
; Note that the alloc macro fills the buffer with zeros,
; effectively providing a black background for the DIB.
; The FastSetPixel procedure draws to this buffer.
;---------------------------------------------------------
mov eax, [esi].BITMAPINFO.bmiHeader.biSizeImage
mov pDIBits, alloc(eax)
pop esi
pop ebx
invoke ReleaseDC, NULL, hdcClient
;-----------------------------------------------------
; Initialize the flake data array with random X and Y
; coordinates, and Y increment values spread over a
; small random range (~0.425 to ~0.575)
;-----------------------------------------------------
push ebx
push edi
xor ebx, ebx
mov edi, pFlakeData
mov ecx, FLAKE_COUNT
.WHILE ecx
push ecx
call frnd
fild clientW
fmul
fistp [edi+ebx].FLAKE.ix
call frnd
fild clientH
fmul
fstp [edi+ebx].FLAKE.fy
call frnd
fld8 0.15
fmul
fld8 0.075
fsub
fld8 0.5
fadd
fstp [edi+ebx].FLAKE.fi
add ebx, SIZEOF FLAKE
pop ecx
dec ecx
.ENDW
pop edi
pop ebx
;-----------------------------------------------------------
; Create a timer to provide a time base for the frame rate.
;-----------------------------------------------------------
invoke SetTimer, hwndDlg, 1, 1000, NULL
CASE WM_PAINT
;------------------------------------------------
; Display the DDB by copying it to the paint DC.
;------------------------------------------------
invoke BeginPaint, hwndDlg, ADDR ps
invoke CreateCompatibleBitmap, ps.hdc, clientW, clientH
push eax
invoke SelectObject, ps.hdc, eax
push eax
invoke BitBlt, ps.hdc, 0, 0, clientW, clientH, hdcDDB, 0, 0, SRCCOPY
pop eax
invoke SelectObject, ps.hdc, eax
pop eax
invoke DeleteObject, eax
invoke EndPaint, hwndDlg, ADDR ps
CASE WM_ERASEBKGND
;----------------------------------------------------------
; This effectively disables the background erase when the
; client area is redrawn, reducing flicker when the window
; is moved.
;----------------------------------------------------------
return 1
CASE WM_TIMER
;------------------------
; Update the frame rate.
;------------------------
invoke SetWindowText, hwndDlg, str$(frameCount)
mov frameCount, 0
CASE WM_COMMAND
SWITCH wParam
CASE IDCANCEL
call destroy
ENDSW
CASE WM_CLOSE
call destroy
CASE WM_DESTROY
invoke PostQuitMessage, NULL
ENDSW
xor eax, eax
ret
destroy:
invoke KillTimer, hwndDlg, 1
invoke SelectObject, hdcDDB, hPrevBmp
invoke ReleaseDC, NULL, hdcDDB
free pFlakeData
free pBMI
free pDIBits
invoke DestroyWindow, hwndDlg
retn
DialogProc endp
;==============================================================================
start:
;==============================================================================
invoke GetModuleHandle, NULL
mov hInst, eax
Dialog 0, \
"MS Sans Serif",10, \
WS_VISIBLE or WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
0, \
0,0,160,160, \
1024
CallModelessDialog hInst, 0, DialogProc, NULL
mov hDlg, eax
;-----------------------------------------------------------
; Set the FPU to round down, to avoid in the flake-position
; update code below, having the default rounding (nearest)
; round the integer y-position up an invalid value.
;-----------------------------------------------------------
FPU_SETRC FPU_RC_DOWN
msgLoop:
invoke PeekMessage, ADDR msg, NULL, 0, 0, PM_REMOVE
.IF eax != 0
.IF msg.message == WM_QUIT
invoke ExitProcess, 0
.ENDIF
invoke IsDialogMessage, hDlg, addr msg
.IF eax == 0
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.ENDIF
.ELSE
;---------------------------------------------------------
; This code runs whenever there is no message to process.
;---------------------------------------------------------
push ebx
push edi
xor ebx, ebx
mov edi, pFlakeData
mov ecx, FLAKE_COUNT
.WHILE ecx
push ecx
;----------------------------------------
; "Erase" the flake at the old position.
;----------------------------------------
IF USE_FASTSETPIXEL EQ 1
invoke FastSetPixel, [edi+ebx].FLAKE.ix,
[edi+ebx].FLAKE.iy, 0
ELSE
invoke SetPixel, hdcDDB, [edi+ebx].FLAKE.ix,
[edi+ebx].FLAKE.iy, 0
ENDIF
;-------------------------------------------------------
; Update the flake position, wrapping to the top of the
; window when the flake reaches the bottom.
;-------------------------------------------------------
fld [edi+ebx].FLAKE.fy ; st(0)=fy
fadd [edi+ebx].FLAKE.fi ; st(0)=updated_fy
fild clientH ; st(0)=clientH,st(1)=updated_fy
fcomip st(0),st(1) ; st(0)=updated_fy
ja @F ; jump if st(0) > st(1)
fstp st(0) ; discard st(0)
fld1 ; st(0)=1
@@:
fst [edi+ebx].FLAKE.fy ; fy=updated_fy,st(0)=updated_fy
fistp [edi+ebx].FLAKE.iy ; iy=st(0),st(0)-st(7) now empty
;-----------------------------------------
; Draw the flake at the updated position.
;-----------------------------------------
IF USE_FASTSETPIXEL EQ 1
invoke FastSetPixel, [edi+ebx].FLAKE.ix,
[edi+ebx].FLAKE.iy, 0ffffffh
ELSE
invoke SetPixel, hdcDDB, [edi+ebx].FLAKE.ix,
[edi+ebx].FLAKE.iy, 0ffffffh
ENDIF
add ebx, SIZEOF FLAKE
pop ecx
dec ecx
.ENDW
pop edi
pop ebx
;-----------------------------------------------
; If using the FastSetPixel procedure, copy the
; bitmap bits from the DIB to the DDB.
;-----------------------------------------------
IF USE_FASTSETPIXEL EQ 1
invoke SetDIBits,0,hDDB,0,clientH,pDIBits,pBMI,DIB_RGB_COLORS
ENDIF
;-------------------------------------
; Force a repaint of the client area.
;-------------------------------------
invoke InvalidateRect, hDlg, 0, 0
;------------------------------------------------------------
; Delay to control the update rate and thus the flake speed.
;------------------------------------------------------------
invoke Sleep, UPDATE_DELAY
inc frameCount
.ENDIF
jmp msgLoop
;==============================================================================
end start
That is so cool , it would be nice if we can get the snow to accumulate on the bottom like the attachment posted by Magnum in the previous page :U
Quote from: MichaelW on August 17, 2011, 06:49:21 PM
This is crude and GDI only, but I think it produces a reasonable effect.
Hi,
It is quite nice on my machine, thanks. Thought there
was some "noise" but that was dust on my monitor!. Pilot
error here. Fixed size and no full screen are the only real
comments for consideration.
Regards,
Steve N.
hfheatherfox07,
Here are some progs that would look good in Win32.
The match and fire are my favorite.
Quote from: FORTRANS on August 18, 2011, 12:30:37 PM
Thought there was some "noise" but that was dust on my monitor! Pilot error here.
(http://l.yimg.com/us.yimg.com/i/mesg/emoticons7/24.gif)
Quote from: Magnum on August 18, 2011, 01:18:32 PM
hfheatherfox07,
Here are some progs that would look good in Win32.
The match and fire are my favorite.
LOL you keep posting stuff with no source.....
anyways I have those.... There are all in TASM which I don't know
Found all the TASM sources...useless to me.... maybe someone wants them..... ::)
Take a chill pill.
I did not post the sources since you don't use Tasm and 16 bit source code would be of no use to someone
making a 32 bit program.
You didn't find the match source code.
Tasm is almost identical to masm.
Well, I am trying to write an application that mimics falling snow like you all are discussing about in this thread. I am writing it to use the SDL library, but I am having a problem. I am having to translate the C header files to an assembler include file. I just don't know what to put for the header. The SDL library is licensed under The GNU Lesser General Public License (Version 2.1), which can be found here for reading: (http://www.gnu.org/licenses/lgpl-2.1.txt; plaintext)
As far as I can see, I just need to go by Section 1. I just need to include the GNU LGPL V2.1 along with the program. Is there anything else I am missing?
; SDL Library binding for assembler
;
; SDL - Simple DirectMedia Layer
; Copyright (C) 1997-2009 Sam Lantinga
;
; This library is free software; you can redistribute it and/or
; modify it under the terms of the GNU Lesser General Public
; License as published by the Free Software Foundation; either
; version 2.1 of the License, or (at your option) any later version.
;
; This library is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; Lesser General Public License for more details.
Quote from: Horton on August 19, 2011, 03:12:21 AM
I am writing a falling snow application in SDL, and I'll release it here.
> I just need to know how I am going to work with the SDL library include files. I will be porting them from C headers to Assembler include files, so how should I deal with the licenses? What do I put for the header of the include file?
I don't know much about SDL but I found this http://www.asmcommunity.net/board/index.php?topic=22122.0
there is http://www.japheth.de/WinInc.html and much more ...I dunno if it is an issue
Yeah, I ended up just putting all the data into one file. All of the external functions, data.
Even though It seems irrelevant, maybe It give some inspiration
It's firework simulation program and funny to play with.
PS: I didn't write it, just found it
Working with SDL is tough. I'm trying to understand it the best I can.