76672a4a5c50696a1acc54a03e1bf8422b802a39
[sdk] / samples / guiAndGfx / snow / snow.ec
1 #ifndef __WIN32__
2 void XSync();
3 void * IS_XGetDisplay();
4 #endif
5
6 import "ecere"
7
8 define NUMFLAKES = 60;
9 const char * textString = "Let it snow!";
10 define backgroundColor = Color { 10, 0, 60 };
11
12 class Snowing : Window
13 {
14    text = "Snowing";
15    background = backgroundColor;
16    opacity = 0;
17    drawBehind = false;
18    foreground = red;
19    borderStyle = sizable;
20    hasMaximize = true;
21    hasMinimize = true;
22    hasClose = true;
23    size = { 640, 480 };
24    font = { "Comic Sans MS", 40, true };
25    useSharedMemory = true;
26
27    ColorAlpha * screen, * screenBuffer;
28    uint stride;
29    int w, h;
30    int lastLine;
31    Bitmap buffer { };
32
33    Snowing() { RandomSeed((uint)(GetTime() * 100000)); ((GuiApplication)__thisModule).timerResolution = 60; }
34
35    Timer timer
36    {
37       this, 0.01, true;
38
39       bool DelayExpired()
40       {
41          Update(null);
42          return true;
43       }
44    };
45
46    void OnRedraw(Surface surface)
47    {
48       Bitmap bitmap = ((LFBDisplay)display.driverData).bitmap;
49
50       if(buffer.width != bitmap.width || buffer.height != bitmap.height)
51       {
52          int tw, th;
53          int len = strlen(textString);
54          stride = bitmap.stride;
55          buffer.Allocate(null, bitmap.width, bitmap.height, stride, pixelFormat888, false);
56          surface.TextExtent(textString, strlen(textString), &tw, &th);
57          w = clientSize.w;
58          h = clientSize.h;
59          lastLine = h-1;
60          screen = (ColorAlpha*)bitmap.picture + (surface.offset.y * stride) + surface.offset.x;
61          screenBuffer = (ColorAlpha*)buffer.picture + (surface.offset.y * stride) + surface.offset.x;
62          surface.background = backgroundColor;
63          surface.Area(0,0, w-1, h-1);
64          surface.WriteText((clientSize.w - tw)/2, (clientSize.h - th)/2, textString, len);
65
66          #ifndef __WIN32__
67          XSync(IS_XGetDisplay());   // TODO: Need an API for this...
68          #endif
69
70          memcpy(buffer.picture, bitmap.picture, buffer.sizeBytes);
71       }
72
73       if(screenBuffer)
74       {
75          int x,y;
76          RandLine();
77          for(y = lastLine; y >= 0; y--)
78          {
79             int offset = y * stride;
80             bool isLastLine = true;
81             for(x = 0; x < w; x++, offset++)
82             {
83                if(screen[offset].color == white)
84                   SnowDown(offset);
85                else
86                   isLastLine = false;
87             }
88             if(isLastLine) lastLine = y-1;
89          }
90          memcpy(bitmap.picture, buffer.picture, buffer.sizeBytes);
91       }
92    }
93
94    void RandLine()
95    {
96       int c;
97       for(c = 0; c < NUMFLAKES; c++)
98          screenBuffer[GetRandom(0, w-1)] = white;
99    }
100    bool SnowTo(int offset, int add)
101    {
102       add += offset;
103       if(screen[add].color != backgroundColor)
104          return false;
105       screenBuffer[add] = white;
106       screenBuffer[offset] = backgroundColor;
107       return true;
108    }
109    void SnowDown(int offset)
110    {
111       if(offset < (h-2)*stride + w)
112       {
113          bool atLeft  = (offset % stride) <= 0;
114          bool atRight = (offset % stride) >= w - 1;
115          switch(GetRandom(0, 2))
116          {
117             case 0:
118                if(!SnowTo(offset, stride))
119                {
120                   if(GetRandom(0, 4) == 0)
121                   {
122                      if(GetRandom(0, 1))
123                         (void)((!atLeft && SnowTo(offset, stride-1)) || (!atRight && SnowTo(offset, stride+1)));
124                      else
125                         (void)((!atRight && SnowTo(offset, stride+1)) || (!atLeft && SnowTo(offset, stride-1)));
126                   }
127                }
128                break;
129             case 1: (void)((!atLeft && SnowTo(offset, stride-1)) || (GetRandom(0, 4) == 0 && SnowTo(offset, stride)) || (!atRight && SnowTo(offset, stride+1))); break;
130             case 2: (void)((!atRight && SnowTo(offset, stride+1)) || (GetRandom(0, 4) == 0 && SnowTo(offset, stride)) || (!atLeft && SnowTo(offset, stride-1))); break;
131          }
132       }
133    }
134 }
135
136 Snowing snowing {};