1 #include <assert.h>
2 #include "guru_meditation.h"
3 #include "mood_item.h"
4 #include "globals.h"
5 #include "random_gen.h"
6 #include "datafun.h"
7 #if DEBUG > 0
8 #include <stdio.h>
9 #endif
10 
11 #define MOOD_ITEM_SPEED 0.04
12 #define MOOD_ITEM_TIME_GAP 29179
13 
14 static sdl_surfaces_t* mood_item_surfaces;
15 static SDL_Surface *current_item_surface = NULL; //NULL means none active
16 SDL_Surface *mood_icon_surface = NULL;
17 static float mood_item_x;
18 static float mood_item_y;
19 static Uint32 mood_item_last_ticks = 0;
20 static Uint32 mood_item_time_gap = MOOD_ITEM_TIME_GAP;
21 static float mood_item_speed = MOOD_ITEM_SPEED;
22 
23 /*
24  * Parameters for the mood items are stored in the FORM.ROCK MOOD
25  * chunk. The chunk has the following structure:
26  *
27  * 0000 UWORD	mood item time-gap
28  * 0002 UWORD	mood item speed * 65536 / 4 - 1, default is $028B
29  */
30 
init_mood_item(uiff_ctx_t iff)31 SDL_Surface *init_mood_item(uiff_ctx_t iff) {
32   int32_t chunksize;
33   unsigned int i;
34 
35   chunksize = uiff_find_chunk_wflags(&iff, MakeID('M', 'O', 'O', 'D'), IFF_FIND_REWIND);
36   assert(printf("FORM.ROCK MOOD size = $%08X\n", chunksize));
37   if(chunksize >= 2) {
38     mood_item_time_gap = read16(iff.f);
39     printf("\ttime gap = $%04X\n", (unsigned)mood_item_time_gap);
40   }
41   if(chunksize >= 4) {
42     i = read16(iff.f);
43     mood_item_speed = i + 1;
44     mood_item_speed *= 4.0 / 65536;
45     printf("\titem speed = $%04X %12.6e\n", i, mood_item_speed);
46   } else guru_meditation(GM_FLAGS_GREEN | GM_FLAGS_ABORTIFY, GM_SS_Graphics | GM_GE_BadParm | GURU_SEC_mood_item, &mood_item_speed);
47   if((mood_item_surfaces = load_images_ck("mood_item.%02hx.png", 0, 255, 0)) == NULL) {
48     guru_meditation(GM_FLAGS_DEADEND, GM_SS_Graphics | GM_GE_IOError | GURU_SEC_mood_item, &init_mood_item);
49     return NULL;
50   }
51   if((mood_icon_surface = load_image("icon.mood_item.png", 0, 255, 0)) == NULL) {
52     destroy_mood_item();
53     guru_meditation(GM_FLAGS_DEADEND, GM_SS_Graphics | GM_GE_IOError | GURU_SEC_mood_item, &mood_icon_surface);
54     return NULL;
55   }
56   return mood_icon_surface;
57 }
58 
destroy_mood_item(void)59 void destroy_mood_item(void) {
60   assert(printf("destroy mood item %p %p\n", mood_icon_surface, mood_item_surfaces));
61   if(mood_icon_surface) SDL_FreeSurface(mood_icon_surface);
62   mood_icon_surface = NULL;
63   if(mood_item_surfaces) destroy_sdl_surfaces(mood_item_surfaces);
64   mood_item_surfaces = NULL;
65 }
66 
draw_mood_item(SDL_Surface * target)67 void draw_mood_item(SDL_Surface *target) {
68   SDL_Rect dest;
69 
70   if(!current_item_surface && (rnd() < 1e-3) && (last_ticks - mood_item_last_ticks > mood_item_time_gap)) {
71     current_item_surface = mood_item_surfaces->surfaces[(int)(mood_item_surfaces->num_surfaces * rnd())];
72     mood_item_x = xsize;
73     mood_item_y = rnd() * (ysize - current_item_surface->h);
74   } else if(current_item_surface) { /* We still need to check if an item is active. */
75     dest.x = mood_item_x;
76     dest.y = mood_item_y;
77     dest.w = current_item_surface->w;
78     dest.h = current_item_surface->h;
79     SDL_BlitSurface(current_item_surface, NULL, target, &dest);
80     mood_item_x -= mood_item_speed;
81     if(mood_item_x < -current_item_surface->w) {
82       current_item_surface = NULL;
83       mood_item_last_ticks = last_ticks;
84     }
85   }
86 }
87