1 /*
2 
3 This is not the AGS SnowRain plugin by Scorpiorus (http://www.bigbluecup.com/yabb/index.php?topic=25665.0),
4 but a workalike plugin created by JJS for the AGS engine PSP port.
5 
6 */
7 
8 #ifdef WIN32
9 #define WINDOWS_VERSION
10 #define WIN32_LEAN_AND_MEAN
11 #include <windows.h>
12 #pragma warning(disable : 4244)
13 #endif
14 
15 #if !defined(BUILTIN_PLUGINS)
16 #define THIS_IS_THE_PLUGIN
17 #endif
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <math.h>
23 
24 #ifdef PSP_VERSION
25 #include <pspsdk.h>
26 #include <pspmath.h>
27 #define sin(x) vfpu_sinf(x)
28 #endif
29 
30 #include "plugin/agsplugin.h"
31 
32 #if defined(BUILTIN_PLUGINS)
33 namespace ags_snowrain {
34 #endif
35 
36 //#define DEBUG
37 //#define AGS_SNOWRAIN_DLL_SAVEGAME_COMPATIBILITY
38 
39 #define signum(x) ((x > 0) ? 1 : -1)
40 
41 const unsigned int Magic = 0xCAFE0000;
42 const unsigned int Version = 2;
43 const unsigned int SaveMagic = Magic + Version;
44 const float PI = 3.14159265f;
45 
46 int screen_width = 320;
47 int screen_height = 200;
48 int screen_color_depth = 32;
49 
50 IAGSEngine* engine;
51 
52 
53 typedef struct
54 {
55   int view;
56   int loop;
57   bool is_default;
58   BITMAP* bitmap;
59 } view_t;
60 
61 
62 typedef struct
63 {
64   float x;
65   float y;
66   int alpha;
67   float speed;
68   int max_y;
69   int kind_id;
70   int drift;
71   float drift_speed;
72   float drift_offset;
73 } drop_t;
74 
75 
76 class Weather
77 {
78   public:
79     Weather();
80     Weather(bool IsSnow);
81     ~Weather();
82 
83     void Initialize();
84     void InitializeParticles();
85 
86     void RestoreGame(long file);
87     void SaveGame(long file);
88     bool ReinitializeViews();
89 
90     bool IsActive();
91     void Update();
92     void UpdateWithDrift();
93     void EnterRoom();
94 
95     void SetDriftRange(int min_value, int max_value);
96     void SetDriftSpeed(int min_value, int max_value);
97     void ChangeAmount(int amount);
98     void SetView(int kind_id, int event, int view, int loop);
99     void SetDefaultView(int view, int loop);
100     void SetTransparency(int min_value, int max_value);
101     void SetWindSpeed(int value);
102     void SetBaseline(int top, int bottom);
103     void SetAmount(int amount);
104     void SetFallSpeed(int min_value, int max_value);
105 
106   private:
107     void ClipToRange(int &variable, int min, int max);
108 
109     bool mIsSnow;
110 
111     int mMinDrift;
112     int mMaxDrift;
113     int mDeltaDrift;
114 
115     int mMinDriftSpeed;
116     int mMaxDriftSpeed;
117     int mDeltaDriftSpeed;
118 
119     int mAmount;
120     int mTargetAmount;
121 
122     int mMinAlpha;
123     int mMaxAlpha;
124     int mDeltaAlpha;
125 
126     float mWindSpeed;
127 
128     int mTopBaseline;
129     int mBottomBaseline;
130     int mDeltaBaseline;
131 
132     int mMinFallSpeed;
133     int mMaxFallSpeed;
134     int mDeltaFallSpeed;
135 
136     drop_t mParticles[2000];
137     view_t mViews[5];
138 
139     bool mViewsInitialized;
140 };
141 
142 
Weather()143 Weather::Weather()
144 {
145   mIsSnow = false;
146   Initialize();
147 }
148 
149 
Weather(bool IsSnow)150 Weather::Weather(bool IsSnow)
151 {
152   mIsSnow = IsSnow;
153   Initialize();
154 }
155 
156 
~Weather()157 Weather::~Weather()
158 {
159 }
160 
161 
Update()162 void Weather::Update()
163 {
164   if (mTargetAmount > mAmount)
165     mAmount++;
166   else if (mTargetAmount < mAmount)
167     mAmount--;
168 
169   if (!ReinitializeViews())
170     return;
171 
172   int i;
173   for (i = 0; i < mAmount * 2; i++)
174   {
175     mParticles[i].y += mParticles[i].speed;
176     mParticles[i].x += mWindSpeed;
177 
178     if (mParticles[i].x < 0)
179       mParticles[i].x += screen_width;
180 
181     if (mParticles[i].x > screen_width - 1)
182       mParticles[i].x -= screen_width;
183 
184     if (mParticles[i].y > mParticles[i].max_y)
185     {
186       mParticles[i].y = -1 * (rand() % screen_height);
187       mParticles[i].x = rand() % screen_width;
188       mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha;
189       mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f;
190       mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline;
191     }
192     else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0))
193       engine->BlitSpriteTranslucent(mParticles[i].x, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha);
194   }
195 
196   engine->MarkRegionDirty(0, 0, screen_width, screen_height);
197 }
198 
199 
UpdateWithDrift()200 void Weather::UpdateWithDrift()
201 {
202   if (mTargetAmount > mAmount)
203     mAmount++;
204   else if (mTargetAmount < mAmount)
205     mAmount--;
206 
207   if (!ReinitializeViews())
208     return;
209 
210   int i, drift;
211   for (i = 0; i < mAmount * 2; i++)
212   {
213     mParticles[i].y += mParticles[i].speed;
214     drift = mParticles[i].drift * sin((float)(mParticles[i].y + mParticles[i].drift_offset) * mParticles[i].drift_speed * 2.0f * PI / 360.0f);
215 
216     if (signum(mWindSpeed) == signum(drift))
217       mParticles[i].x += mWindSpeed;
218     else
219       mParticles[i].x += mWindSpeed / 4;
220 
221     if (mParticles[i].x < 0)
222       mParticles[i].x += screen_width;
223 
224     if (mParticles[i].x > screen_width - 1)
225       mParticles[i].x -= screen_width;
226 
227     if (mParticles[i].y > mParticles[i].max_y)
228     {
229       mParticles[i].y = -1 * (rand() % screen_height);
230       mParticles[i].x = rand() % screen_width;
231       mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha;
232       mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f;
233       mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline;
234       mParticles[i].drift = rand() % mDeltaDrift + mMinDrift;
235       mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f;
236     }
237     else if ((mParticles[i].y > 0) && (mParticles[i].alpha > 0))
238       engine->BlitSpriteTranslucent(mParticles[i].x + drift, mParticles[i].y, mViews[mParticles[i].kind_id].bitmap, mParticles[i].alpha);
239   }
240 
241   engine->MarkRegionDirty(0, 0, screen_width, screen_height);
242 }
243 
engineFileRead(void * ptr,size_t size,size_t count,long fileHandle)244 static size_t engineFileRead(void * ptr, size_t size, size_t count, long fileHandle) {
245   int totalBytes = engine->FRead(ptr, size*count, fileHandle);
246   return totalBytes/size;
247 }
248 
engineFileWrite(const void * ptr,size_t size,size_t count,long fileHandle)249 static size_t engineFileWrite(const void *ptr, size_t size, size_t count, long fileHandle) {
250   int totalBytes = engine->FWrite(const_cast<void *>(ptr), size*count, fileHandle);
251   return totalBytes/size;
252 }
253 
RestoreGame(long file)254 void Weather::RestoreGame(long file)
255 {
256   unsigned int SaveVersion = 0;
257   engineFileRead(&SaveVersion, sizeof(SaveVersion), 1, file);
258 
259   if (SaveVersion != SaveMagic) {
260     engine->AbortGame("ags_snowrain: bad save.");
261   }
262 
263   // Current version
264   engineFileRead(&mIsSnow, 4, 1, file);
265   engineFileRead(&mMinDrift, 4, 1, file);
266   engineFileRead(&mMaxDrift, 4, 1, file);
267   engineFileRead(&mDeltaDrift, 4, 1, file);
268   engineFileRead(&mMinDriftSpeed, 4, 1, file);
269   engineFileRead(&mMaxDriftSpeed, 4, 1, file);
270   engineFileRead(&mDeltaDriftSpeed, 4, 1, file);
271   engineFileRead(&mAmount, 4, 1, file);
272   engineFileRead(&mTargetAmount, 4, 1, file);
273   engineFileRead(&mMinAlpha, 4, 1, file);
274   engineFileRead(&mMaxAlpha, 4, 1, file);
275   engineFileRead(&mDeltaAlpha, 4, 1, file);
276   engineFileRead(&mWindSpeed, 4, 1, file);
277   engineFileRead(&mTopBaseline, 4, 1, file);
278   engineFileRead(&mBottomBaseline, 4, 1, file);
279   engineFileRead(&mDeltaBaseline, 4, 1, file);
280   engineFileRead(&mMinFallSpeed, 4, 1, file);
281   engineFileRead(&mMaxFallSpeed, 4, 1, file);
282   engineFileRead(&mDeltaFallSpeed, 4, 1, file);
283   engineFileRead(mViews, sizeof(view_t) * 5, 1, file);
284 
285   InitializeParticles();
286 }
287 
288 
SaveGame(long file)289 void Weather::SaveGame(long file)
290 {
291   engineFileWrite(&SaveMagic, sizeof(SaveMagic), 1, file);
292 
293   engineFileWrite(&mIsSnow, 4, 1, file);
294   engineFileWrite(&mMinDrift, 4, 1, file);
295   engineFileWrite(&mMaxDrift, 4, 1, file);
296   engineFileWrite(&mDeltaDrift, 4, 1, file);
297   engineFileWrite(&mMinDriftSpeed, 4, 1, file);
298   engineFileWrite(&mMaxDriftSpeed, 4, 1, file);
299   engineFileWrite(&mDeltaDriftSpeed, 4, 1, file);
300   engineFileWrite(&mAmount, 4, 1, file);
301   engineFileWrite(&mTargetAmount, 4, 1, file);
302   engineFileWrite(&mMinAlpha, 4, 1, file);
303   engineFileWrite(&mMaxAlpha, 4, 1, file);
304   engineFileWrite(&mDeltaAlpha, 4, 1, file);
305   engineFileWrite(&mWindSpeed, 4, 1, file);
306   engineFileWrite(&mTopBaseline, 4, 1, file);
307   engineFileWrite(&mBottomBaseline, 4, 1, file);
308   engineFileWrite(&mDeltaBaseline, 4, 1, file);
309   engineFileWrite(&mMinFallSpeed, 4, 1, file);
310   engineFileWrite(&mMaxFallSpeed, 4, 1, file);
311   engineFileWrite(&mDeltaFallSpeed, 4, 1, file);
312   engineFileWrite(mViews, sizeof(view_t) * 5, 1, file);
313 }
314 
315 
ReinitializeViews()316 bool Weather::ReinitializeViews()
317 {
318   if ((mViews[4].view == -1) || (mViews[4].loop == -1))
319     return false;
320 
321   AGSViewFrame* view_frame = engine->GetViewFrame(mViews[4].view, mViews[4].loop, 0);
322   BITMAP* default_bitmap = engine->GetSpriteGraphic(view_frame->pic);
323 
324   int i;
325   for (i = 0; i < 5; i++)
326   {
327     if (mViews[i].bitmap != NULL)
328     {
329       if (mViews[i].is_default)
330         mViews[i].bitmap = default_bitmap;
331       else
332       {
333         view_frame = engine->GetViewFrame(mViews[i].view, mViews[i].loop, 0);
334         mViews[i].bitmap = engine->GetSpriteGraphic(view_frame->pic);
335       }
336     }
337   }
338 
339   return true;
340 }
341 
342 
IsActive()343 bool Weather::IsActive()
344 {
345   return (mAmount > 0) || (mTargetAmount != mAmount);
346 }
347 
348 
EnterRoom()349 void Weather::EnterRoom()
350 {
351   mAmount = mTargetAmount;
352 }
353 
354 
ClipToRange(int & variable,int min,int max)355 void Weather::ClipToRange(int &variable, int min, int max)
356 {
357   if (variable < min)
358     variable = min;
359 
360   if (variable > max)
361     variable = max;
362 }
363 
364 
Initialize()365 void Weather::Initialize()
366 {
367   SetDriftRange(10, 100);
368   SetDriftSpeed(10, 120);
369 
370   SetTransparency(0, 0);
371   SetWindSpeed(0);
372   SetBaseline(0, 200);
373 
374   if (mIsSnow)
375     SetFallSpeed(10, 70);
376   else
377     SetFallSpeed(100, 300);
378 
379   mViewsInitialized = false;
380 
381   int i;
382   for (i = 0; i < 5; i++)
383   {
384     mViews[i].is_default = true;
385     mViews[i].view = -1;
386     mViews[i].loop = -1;
387     mViews[i].bitmap = NULL;
388   }
389 
390   SetAmount(0);
391 }
392 
393 
InitializeParticles()394 void Weather::InitializeParticles()
395 {
396   memset(mParticles, 0, sizeof(drop_t) * 2000);
397   int i;
398   for (i = 0; i < 2000; i++)
399   {
400     mParticles[i].kind_id = rand() % 5;
401     mParticles[i].y = rand() % (screen_height * 2) - screen_height;
402     mParticles[i].x = rand() % screen_width;
403     mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha;
404     mParticles[i].speed = (float)(rand() % mDeltaFallSpeed + mMinFallSpeed) / 50.0f;
405     mParticles[i].max_y = rand() % mDeltaBaseline + mTopBaseline;
406     mParticles[i].drift = rand() % mDeltaDrift + mMinDrift;
407     mParticles[i].drift_speed = (rand() % mDeltaDriftSpeed + mMinDriftSpeed) / 50.0f;
408     mParticles[i].drift_offset = rand() % 100;
409   }
410 }
411 
412 
SetDriftRange(int min_value,int max_value)413 void Weather::SetDriftRange(int min_value, int max_value)
414 {
415 #ifdef DEBUG
416   char buffer[200];
417   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftRange", min_value, max_value);
418   engine->PrintDebugConsole(buffer);
419 #endif
420 
421   ClipToRange(min_value, 0, 100);
422   ClipToRange(max_value, 0, 100);
423 
424   if (min_value > max_value)
425     min_value = max_value;
426 
427   mMinDrift = min_value / 2;
428   mMaxDrift = max_value / 2;
429   mDeltaDrift = mMaxDrift - mMinDrift;
430 
431   if (mDeltaDrift == 0)
432     mDeltaDrift = 1;
433 }
434 
435 
SetDriftSpeed(int min_value,int max_value)436 void Weather::SetDriftSpeed(int min_value, int max_value)
437 {
438 #ifdef DEBUG
439   char buffer[200];
440   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDriftSpeed", min_value, max_value);
441   engine->PrintDebugConsole(buffer);
442 #endif
443 
444   ClipToRange(min_value, 0, 200);
445   ClipToRange(max_value, 0, 200);
446 
447   if (min_value > max_value)
448     min_value = max_value;
449 
450   mMinDriftSpeed = min_value;
451   mMaxDriftSpeed = max_value;
452   mDeltaDriftSpeed = mMaxDriftSpeed - mMinDriftSpeed;
453 
454   if (mDeltaDriftSpeed == 0)
455     mDeltaDriftSpeed = 1;
456 }
457 
458 
ChangeAmount(int amount)459 void Weather::ChangeAmount(int amount)
460 {
461 #ifdef DEBUG
462   char buffer[200];
463   sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "ChangeAmount", amount);
464   engine->PrintDebugConsole(buffer);
465 #endif
466 
467   ClipToRange(amount, 0, 1000);
468 
469   mTargetAmount = amount;
470 }
471 
472 
SetView(int kind_id,int event,int view,int loop)473 void Weather::SetView(int kind_id, int event, int view, int loop)
474 {
475 #ifdef DEBUG
476   char buffer[200];
477   sprintf(buffer, "%d %s %d %d %d %d\n", (int)mIsSnow, "SetView", kind_id, event, view, loop);
478   engine->PrintDebugConsole(buffer);
479 #endif
480 
481   AGSViewFrame* view_frame = engine->GetViewFrame(view, loop, 0);
482   mViews[kind_id].bitmap = engine->GetSpriteGraphic(view_frame->pic);
483   mViews[kind_id].is_default = false;
484   mViews[kind_id].view = view;
485   mViews[kind_id].loop = loop;
486 
487   if (!mViewsInitialized)
488     SetDefaultView(view, loop);
489 }
490 
491 
SetDefaultView(int view,int loop)492 void Weather::SetDefaultView(int view, int loop)
493 {
494 #ifdef DEBUG
495   char buffer[200];
496   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetDefaultView", view, loop);
497   engine->PrintDebugConsole(buffer);
498 #endif
499 
500   AGSViewFrame* view_frame = engine->GetViewFrame(view, loop, 0);
501   BITMAP* bitmap = engine->GetSpriteGraphic(view_frame->pic);
502 
503   mViewsInitialized = true;
504 
505   int i;
506   for (i = 0; i < 5; i++)
507   {
508     if (mViews[i].is_default)
509     {
510       mViews[i].view = view;
511       mViews[i].loop = loop;
512       mViews[i].bitmap = bitmap;
513     }
514   }
515 }
516 
517 
SetTransparency(int min_value,int max_value)518 void Weather::SetTransparency(int min_value, int max_value)
519 {
520 #ifdef DEBUG
521   char buffer[200];
522   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetTransparency", min_value, max_value);
523   engine->PrintDebugConsole(buffer);
524 #endif
525 
526   ClipToRange(min_value, 0, 100);
527   ClipToRange(max_value, 0, 100);
528 
529   if (min_value > max_value)
530     min_value = max_value;
531 
532   mMinAlpha = 255 - floor((float)max_value * 2.55f + 0.5f);
533   mMaxAlpha = 255 - floor((float)min_value * 2.55f + 0.5f);
534   mDeltaAlpha = mMaxAlpha - mMinAlpha;
535 
536   if (mDeltaAlpha == 0)
537     mDeltaAlpha = 1;
538 
539   int i;
540   for (i = 0; i < 2000; i++)
541     mParticles[i].alpha = rand() % mDeltaAlpha + mMinAlpha;
542 }
543 
544 
SetWindSpeed(int value)545 void Weather::SetWindSpeed(int value)
546 {
547 #ifdef DEBUG
548   char buffer[200];
549   sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetWindSpeed", value);
550   engine->PrintDebugConsole(buffer);
551 #endif
552 
553   ClipToRange(value, -200, 200);
554 
555   mWindSpeed = (float)value / 20.0f;
556 }
557 
558 
SetBaseline(int top,int bottom)559 void Weather::SetBaseline(int top, int bottom)
560 {
561 #ifdef DEBUG
562   char buffer[200];
563   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetBaseline", top, bottom);
564   engine->PrintDebugConsole(buffer);
565 #endif
566 
567   if (screen_height > 0)
568   {
569     ClipToRange(top, 0, screen_height);
570     ClipToRange(bottom, 0, screen_height);
571   }
572 
573   if (top > bottom)
574     top = bottom;
575 
576   mTopBaseline = top;
577   mBottomBaseline = bottom;
578   mDeltaBaseline = mBottomBaseline - mTopBaseline;
579 
580   if (mDeltaBaseline == 0)
581     mDeltaBaseline = 1;
582 }
583 
584 
SetAmount(int amount)585 void Weather::SetAmount(int amount)
586 {
587 #ifdef DEBUG
588   char buffer[200];
589   sprintf(buffer, "%d %s %d\n", (int)mIsSnow, "SetAmount", amount);
590   engine->PrintDebugConsole(buffer);
591 #endif
592 
593   ClipToRange(amount, 0, 1000);
594 
595   mAmount = mTargetAmount = amount;
596 
597   InitializeParticles();
598 }
599 
600 
SetFallSpeed(int min_value,int max_value)601 void Weather::SetFallSpeed(int min_value, int max_value)
602 {
603 #ifdef DEBUG
604   char buffer[200];
605   sprintf(buffer, "%d %s %d %d\n", (int)mIsSnow, "SetFallSpeed", min_value, max_value);
606   engine->PrintDebugConsole(buffer);
607 #endif
608 
609   ClipToRange(min_value, 0, 1000);
610   ClipToRange(max_value, 0, 1000);
611 
612   if (min_value > max_value)
613     min_value = max_value;
614 
615   mMinFallSpeed = min_value;
616   mMaxFallSpeed = max_value;
617   mDeltaFallSpeed = mMaxFallSpeed - mMinFallSpeed;
618 
619   if (mDeltaFallSpeed == 0)
620     mDeltaFallSpeed = 1;
621 }
622 
623 
624 
625 Weather* rain;
626 Weather* snow;
627 
628 
629 
630 
631 // ********************************************
632 // ************  AGS Interface  ***************
633 // ********************************************
634 
srSetWindSpeed(int value)635 void srSetWindSpeed(int value)
636 {
637   snow->SetWindSpeed(value);
638   rain->SetWindSpeed(value);
639 }
640 
srSetBaseline(int top,int bottom)641 void srSetBaseline(int top, int bottom)
642 {
643   snow->SetBaseline(top, bottom);
644   rain->SetBaseline(top, bottom);
645 }
646 
srSetSnowDriftRange(int min_value,int max_value)647 void srSetSnowDriftRange(int min_value, int max_value)
648 {
649   snow->SetDriftRange(min_value, max_value);
650 }
651 
srSetSnowDriftSpeed(int min_value,int max_value)652 void srSetSnowDriftSpeed(int min_value, int max_value)
653 {
654   snow->SetDriftSpeed(min_value, max_value);
655 }
656 
srChangeSnowAmount(int amount)657 void srChangeSnowAmount(int amount)
658 {
659   snow->ChangeAmount(amount);
660 }
661 
srSetSnowView(int kind_id,int event,int view,int loop)662 void srSetSnowView(int kind_id, int event, int view, int loop)
663 {
664   snow->SetView(kind_id, event, view, loop);
665 }
666 
srSetSnowDefaultView(int view,int loop)667 void srSetSnowDefaultView(int view, int loop)
668 {
669   snow->SetDefaultView(view, loop);
670 }
671 
srSetSnowTransparency(int min_value,int max_value)672 void srSetSnowTransparency(int min_value, int max_value)
673 {
674   snow->SetTransparency(min_value, max_value);
675 }
676 
srSetSnowWindSpeed(int value)677 void srSetSnowWindSpeed(int value)
678 {
679   snow->SetWindSpeed(value);
680 }
681 
srSetSnowBaseline(int top,int bottom)682 void srSetSnowBaseline(int top, int bottom)
683 {
684   snow->SetBaseline(top, bottom);
685 }
686 
srSetSnowAmount(int amount)687 void srSetSnowAmount(int amount)
688 {
689   snow->SetAmount(amount);
690 }
691 
srSetSnowFallSpeed(int min_value,int max_value)692 void srSetSnowFallSpeed(int min_value, int max_value)
693 {
694   snow->SetFallSpeed(min_value, max_value);
695 }
696 
srSetRainDriftRange(int min_value,int max_value)697 void srSetRainDriftRange(int min_value, int max_value)
698 {
699   rain->SetDriftRange(min_value, max_value);
700 }
701 
srSetRainDriftSpeed(int min_value,int max_value)702 void srSetRainDriftSpeed(int min_value, int max_value)
703 {
704   rain->SetDriftSpeed(min_value, max_value);
705 }
706 
srChangeRainAmount(int amount)707 void srChangeRainAmount(int amount)
708 {
709   rain->ChangeAmount(amount);
710 }
711 
srSetRainView(int kind_id,int event,int view,int loop)712 void srSetRainView(int kind_id, int event, int view, int loop)
713 {
714   rain->SetView(kind_id, event, view, loop);
715 }
716 
srSetRainDefaultView(int view,int loop)717 void srSetRainDefaultView(int view, int loop)
718 {
719   rain->SetDefaultView(view, loop);
720 }
721 
srSetRainTransparency(int min_value,int max_value)722 void srSetRainTransparency(int min_value, int max_value)
723 {
724   rain->SetTransparency(min_value, max_value);
725 }
726 
srSetRainWindSpeed(int value)727 void srSetRainWindSpeed(int value)
728 {
729   rain->SetWindSpeed(value);
730 }
731 
srSetRainBaseline(int top,int bottom)732 void srSetRainBaseline(int top, int bottom)
733 {
734   rain->SetBaseline(top, bottom);
735 }
736 
srSetRainAmount(int amount)737 void srSetRainAmount(int amount)
738 {
739   rain->SetAmount(amount);
740 }
741 
srSetRainFallSpeed(int min_value,int max_value)742 void srSetRainFallSpeed(int min_value, int max_value)
743 {
744   rain->SetFallSpeed(min_value, max_value);
745 }
746 
AGS_EngineStartup(IAGSEngine * lpEngine)747 void AGS_EngineStartup(IAGSEngine *lpEngine)
748 {
749   engine = lpEngine;
750 
751   if (engine->version < 13)
752     engine->AbortGame("Engine interface is too old, need newer version of AGS.");
753 
754   engine->RegisterScriptFunction("srSetSnowDriftRange", (void*)&srSetSnowDriftRange);
755   engine->RegisterScriptFunction("srSetSnowDriftSpeed", (void*)&srSetSnowDriftSpeed);
756   engine->RegisterScriptFunction("srSetSnowFallSpeed", (void*)&srSetSnowFallSpeed);
757   engine->RegisterScriptFunction("srChangeSnowAmount", (void*)&srChangeSnowAmount);
758   engine->RegisterScriptFunction("srSetSnowBaseline", (void*)&srSetSnowBaseline);
759   engine->RegisterScriptFunction("srSetSnowTransparency", (void*)&srSetSnowTransparency);
760   engine->RegisterScriptFunction("srSetSnowDefaultView", (void*)&srSetSnowDefaultView);
761   engine->RegisterScriptFunction("srSetSnowWindSpeed", (void*)&srSetSnowWindSpeed);
762   engine->RegisterScriptFunction("srSetSnowAmount", (void*)&srSetSnowAmount);
763   engine->RegisterScriptFunction("srSetSnowView", (void*)&srSetSnowView);
764 
765   engine->RegisterScriptFunction("srSetRainDriftRange", (void*)&srSetRainDriftRange);
766   engine->RegisterScriptFunction("srSetRainDriftSpeed", (void*)&srSetRainDriftSpeed);
767   engine->RegisterScriptFunction("srSetRainFallSpeed", (void*)&srSetRainFallSpeed);
768   engine->RegisterScriptFunction("srChangeRainAmount", (void*)&srChangeRainAmount);
769   engine->RegisterScriptFunction("srSetRainBaseline", (void*)&srSetRainBaseline);
770   engine->RegisterScriptFunction("srSetRainTransparency", (void*)&srSetRainTransparency);
771   engine->RegisterScriptFunction("srSetRainDefaultView", (void*)&srSetRainDefaultView);
772   engine->RegisterScriptFunction("srSetRainWindSpeed", (void*)&srSetRainWindSpeed);
773   engine->RegisterScriptFunction("srSetRainAmount", (void*)&srSetRainAmount);
774   engine->RegisterScriptFunction("srSetRainView", (void*)&srSetRainView);
775 
776   engine->RegisterScriptFunction("srSetWindSpeed", (void*)&srSetWindSpeed);
777   engine->RegisterScriptFunction("srSetBaseline", (void*)&srSetBaseline);
778 
779   engine->RequestEventHook(AGSE_PREGUIDRAW);
780   engine->RequestEventHook(AGSE_PRESCREENDRAW);
781   engine->RequestEventHook(AGSE_ENTERROOM);
782   engine->RequestEventHook(AGSE_SAVEGAME);
783   engine->RequestEventHook(AGSE_RESTOREGAME);
784 
785   rain = new Weather;
786   snow = new Weather(true);
787 }
788 
AGS_EngineShutdown()789 void AGS_EngineShutdown()
790 {
791   delete rain;
792   delete snow;
793 }
794 
AGS_EngineOnEvent(int event,int data)795 int AGS_EngineOnEvent(int event, int data)
796 {
797   if (event == AGSE_PREGUIDRAW)
798   {
799     if (rain->IsActive())
800       rain->Update();
801 
802     if (snow->IsActive())
803       snow->UpdateWithDrift();
804   }
805   else if (event == AGSE_ENTERROOM)
806   {
807     rain->EnterRoom();
808     snow->EnterRoom();
809   }
810   else if (event == AGSE_RESTOREGAME)
811   {
812     rain->RestoreGame(data);
813     snow->RestoreGame(data);
814   }
815   else if (event == AGSE_SAVEGAME)
816   {
817     rain->SaveGame(data);
818     snow->SaveGame(data);
819   }
820   else if (event == AGSE_PRESCREENDRAW)
821   {
822     // Get screen size once here
823     engine->GetScreenDimensions(&screen_width, &screen_height, &screen_color_depth);
824     engine->UnrequestEventHook(AGSE_PRESCREENDRAW);
825   }
826 
827   return 0;
828 }
829 
AGS_EngineDebugHook(const char * scriptName,int lineNum,int reserved)830 int AGS_EngineDebugHook(const char *scriptName, int lineNum, int reserved)
831 {
832   return 0;
833 }
834 
AGS_EngineInitGfx(const char * driverID,void * data)835 void AGS_EngineInitGfx(const char *driverID, void *data)
836 {
837 }
838 
839 
840 
841 #if defined(WINDOWS_VERSION) && !defined(BUILTIN_PLUGINS)
842 
843 // ********************************************
844 // ***********  Editor Interface  *************
845 // ********************************************
846 
847 const char* scriptHeader =
848   "import void srSetSnowDriftSpeed(int, int);\r\n"
849   "import void srSetSnowDriftRange(int, int);\r\n"
850   "import void srSetSnowFallSpeed(int, int);\r\n"
851   "import void srChangeSnowAmount(int);\r\n"
852   "import void srSetSnowBaseline(int, int);\r\n"
853   "import void srChangeRainAmount(int);\r\n"
854   "import void srSetRainView(int, int, int, int);\r\n"
855   "import void srSetRainTransparency(int, int);\r\n"
856   "import void srSetSnowTransparency(int, int);\r\n"
857   "import void srSetSnowDefaultView(int, int);\r\n"
858   "import void srSetRainDefaultView(int, int);\r\n"
859   "import void srSetRainWindSpeed(int);\r\n"
860   "import void srSetSnowWindSpeed(int);\r\n"
861   "import void srSetWindSpeed(int);\r\n"
862   "import void srSetRainBaseline(int, int);\r\n"
863   "import void srSetBaseline(int, int);\r\n"
864   "import void srSetSnowAmount(int);\r\n"
865   "import void srSetRainAmount(int);\r\n"
866   "import void srSetRainFallSpeed(int, int);\r\n"
867   "import void srSetSnowView(int, int, int, int);\r\n";
868 
869 
870 IAGSEditor* editor;
871 
872 
AGS_GetPluginName(void)873 LPCSTR AGS_GetPluginName(void)
874 {
875   // Return the plugin description
876   return "Snow/Rain plugin recreation";
877 }
878 
AGS_EditorStartup(IAGSEditor * lpEditor)879 int  AGS_EditorStartup(IAGSEditor* lpEditor)
880 {
881   // User has checked the plugin to use it in their game
882 
883   // If it's an earlier version than what we need, abort.
884   if (lpEditor->version < 1)
885     return -1;
886 
887   editor = lpEditor;
888   editor->RegisterScriptHeader(scriptHeader);
889 
890   // Return 0 to indicate success
891   return 0;
892 }
893 
AGS_EditorShutdown()894 void AGS_EditorShutdown()
895 {
896   // User has un-checked the plugin from their game
897   editor->UnregisterScriptHeader(scriptHeader);
898 }
899 
AGS_EditorProperties(HWND parent)900 void AGS_EditorProperties(HWND parent)
901 {
902   // User has chosen to view the Properties of the plugin
903   // We could load up an options dialog or something here instead
904   MessageBoxA(parent, "Snow/Rain plugin recreation by JJS", "About", MB_OK | MB_ICONINFORMATION);
905 }
906 
AGS_EditorSaveGame(char * buffer,int bufsize)907 int AGS_EditorSaveGame(char* buffer, int bufsize)
908 {
909   // We don't want to save any persistent data
910   return 0;
911 }
912 
AGS_EditorLoadGame(char * buffer,int bufsize)913 void AGS_EditorLoadGame(char* buffer, int bufsize)
914 {
915   // Nothing to load for this plugin
916 }
917 
918 #endif
919 
920 
921 #if defined(BUILTIN_PLUGINS)
922 } // namespace ags_snowrain
923 #endif
924