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