Comment *---------------------------+ | | | Plasma Effect | | | +-----------------------------------* .686 .Model Flat, StdCall Option CaseMap: None RepArg Macro Arg Local NewStr Quot SubStr , 1, 1 IfIdn Quot, <"> .Data NewStr db Arg,0 .Code ExitM Else ExitM EndIf EndM @ Macro Function:Req, Args:VarArg Arg equ For Var, Arg CatStr Arg, <, RepArg(Var)> EndM Arg ExitM EndM Public @Main ; Event Constants REDRAW_EVENT = 1 KEY_EVENT = 2 ; Event Mask Constants EM_REDRAW = 1 EM_KEY = 2 ; Window styles WS_FILL_TRANSPARENT = 40000000H TSize Struct SizeY Word ? SizeX Word ? TSize EndS TRGBQuad Struct Blue Byte ? Green Byte ? Red Byte ? reserved Byte ? TRGBQuad EndS SetEventMask Proto EventMask:Dword CheckEvent Proto BeginDraw Proto EndDraw Proto GetScreenSize Proto DrawWindow Proto Left:SDword, Top:SDword, Right:SDword, Bottom:SDword, Caption:Ptr, BackColor:Dword, Style:Dword, CapStyle:Dword DrawImageEx Proto Image:Ptr, X:SDword, Y:SDword, XSize:Dword, YSize:Dword, BPP:Dword, Palette:Ptr, Padding:Dword HeapCreate Proto HeapAllocate Proto Bytes:Dword GetTickCount Proto Sleep Proto Time:Dword ThreadTerminate Proto .Const Float_50 Real4 50.0 ; to keep the FrameRate Float_40 Real4 40.0 ; around 40-50 FPS ; The table below can be calculated approximately as: SinTab[i] = Sin(2 * PI * i / 255) * 128 + 128 SinTab Label Byte Byte 128, 131, 134, 137, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174 Byte 177, 180, 183, 186, 189, 191, 194, 197, 199, 202, 205, 207, 209, 212, 214, 217 Byte 219, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245 Byte 246, 248, 249, 250, 251, 252, 252, 253, 254, 254, 255, 255, 255, 255, 255, 255 Byte 255, 255, 255, 255, 255, 255, 254, 254, 253, 253, 252, 251, 250, 249, 248, 247 Byte 246, 245, 243, 242, 240, 239, 237, 236, 234, 232, 230, 228, 226, 224, 222, 220 Byte 218, 215, 213, 211, 208, 206, 203, 201, 198, 195, 193, 190, 187, 184, 181, 179 Byte 176, 173, 170, 167, 164, 161, 158, 155, 152, 148, 145, 142, 139, 136, 133, 130 Byte 126, 123, 120, 117, 114, 111, 108, 104, 101, 98, 95, 92, 89, 86, 83, 80 Byte 77, 75, 72, 69, 66, 63, 61, 58, 55, 53, 50, 48, 45, 43, 41, 38 Byte 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10 Byte 9, 8, 7, 6, 5, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0 Byte 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 10 Byte 11, 12, 13, 15, 16, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37 Byte 39, 42, 44, 47, 49, 51, 54, 57, 59, 62, 65, 67, 70, 73, 76, 79 Byte 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 119, 122, 125, 128 .Data i1 Dword 50 j1 Dword 90 Freq Dword 100 ; // GetTickCount return count of 1/100s of second Instant Real4 0.0 SleepTime Dword 0 .Data? Screen TSize <> i2 Dword ? j2 Dword ? Palette TRGBQuad 256 Dup (<>) Image Dword ? ImageWidth Dword ? ImageHeight Dword ? FrameStart Dword ? .Code CreatePalette Proc Uses ebx Local i:Dword Local Red:Dword, Green:Dword, Blue:Dword mov i, 0 .Repeat mov eax, i .If eax <= 63 ; do nothing .ElseIf eax <= 127 neg eax add eax, 127 .ElseIf eax <= 189 sub eax, 128 .ElseIf eax <= 255 neg eax add eax, 255 .EndIf mov Red, eax mov Green, eax mov Blue, eax .If i <= 127 shl Green, 1 shl Blue, 2 .ElseIf i <= 255 shl Red, 2 shl Blue, 1 .EndIf mov eax, Red ; cmp eax, 255 ; setna bl ; IF Red > 255 THEN bl = 255 dec bl ; ELSE bl = Red or bl, al ; mov eax, Green ; cmp eax, 255 ; setna cl ; IF Green > 255 THEN cl = 255 dec cl ; ELSE cl = Green or cl, al ; mov eax, Blue ; cmp eax, 255 ; setna dl ; IF Blue > 255 THEN dl = 255 dec dl ; ELSE dl = Blue or dl, al ; mov eax, i mov Palette.Red[eax * SizeOf(Type(Palette))], bl mov Palette.Green[eax * SizeOf(Type(Palette))], cl mov Palette.Blue[eax * SizeOf(Type(Palette))], dl inc i .Until i > 255 ret CreatePalette EndP ;******************************************************************************* Render Proc Local X:Dword, Y:Dword Local Row:Ptr dec i1 add j1, 2 mov Y, 0 Align 4 .Repeat mov eax, Y add eax, i1 and eax, 255 movzx eax, SinTab[eax] mov i2, eax mov eax, j1 and eax, 255 movzx eax, SinTab[eax] mov j2, eax mov eax, Y mul ImageWidth add eax, Image mov Row, eax mov X, 0 Align 4 .Repeat mov eax, X add eax, i2 and eax, 255 movzx ecx, SinTab[eax] mov eax, Y add eax, j2 and eax, 255 movzx eax, SinTab[eax] add ecx, eax mov eax, Row add eax, X mov [eax], cl inc X mov eax, ImageWidth .Until eax == X inc Y mov eax, ImageHeight .Until eax == Y ret Render EndP ;******************************************************************************* QueryPerf Proc Local Diff:Dword Invoke GetTickCount sub eax, FrameStart mov Diff, eax fild Diff fild Freq fdivrp fstp Instant mov FrameStart, @(GetTickCount) ret QueryPerf EndP ;******************************************************************************* Waiting Proc ; Keep the FrameRate around 40-50 FPS fld Float_50 fld Instant fcomip st(0), st(1) fstp st(0) .If !CARRY? && !ZERO? inc SleepTime .Else fld Float_40 fld Instant fcomip st(0), st(1) fstp st(0) .If CARRY? && (SleepTime != 0) dec SleepTime .EndIf .EndIf Invoke Sleep, SleepTime ret Waiting EndP ;******************************************************************************* @Main: Invoke HeapCreate mov Screen, @(GetScreenSize) Invoke CreatePalette movzx eax, Screen.SizeX movzx ecx, Screen.SizeY mov ImageWidth, eax mov ImageHeight, ecx mul ecx mov Image, @(HeapAllocate, eax) mov FrameStart, @(GetTickCount) Invoke SetEventMask, EM_REDRAW + EM_KEY .Repeat Invoke CheckEvent .If eax == REDRAW_EVENT Invoke BeginDraw Invoke DrawWindow, 0, 0, ImageWidth, ImageHeight, 0, 0, WS_FILL_TRANSPARENT, 0 Invoke EndDraw .ElseIf eax == KEY_EVENT Invoke ThreadTerminate .Else Invoke Render Invoke QueryPerf Invoke DrawImageEx, Image, 0, 0, ImageWidth, ImageHeight, 8, Offset Palette, 0 Invoke Waiting .EndIf .Until 0 END