File: powerup.c

package info (click to toggle)
rockdodger 1.0.2-1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 2,352 kB
  • ctags: 852
  • sloc: ansic: 5,790; makefile: 159; sh: 21
file content (137 lines) | stat: -rw-r--r-- 3,756 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <assert.h>
#include "powerup.h"
#include "datafun.h"
#include "guru_meditation.h"
#include "random_gen.h"
#include "globals.h"

static struct PowerupInformationForIni {
  const char *pname;
  const char *pfilename;
  short ckr, ckg, ckb; // colour keys
} powerupiniinfo[] = {
  { "NONE", NULL },
  { "Laserpowerups", "laserpowerup.%02X.png", 0, 0, 255 },
  { "Shieldpowerups", "shieldpowerup.%02X.png", 0, 0, 255 },
  { "Lifepowerups", "lifepowerup.%02X.ilbm", 0, 255, 0 }
};

/*! \brief array with power surfaces
 *
 * Here we store all surfaces for the powerup animations. The order is
 * the same as the powerup numbers.
 */
sdl_surfaces_t *surf_powerups[POWERUP_MAXPOWERUP];

/*! \brief powerup state data
 */
static powerup_t powerup;


powerup_types_t get_current_powerup(void) {
  return powerup.active;
}


powerup_t *init_powerup() {
  int ip;
  struct PowerupInformationForIni *iniptr;

  for(ip = POWERUP_NONE + 1; ip < POWERUP_MAXPOWERUP; ++ip) {
    iniptr = powerupiniinfo + ip;
    printf("%s:\n", iniptr->pname);
    surf_powerups[ip] = load_images_ck(iniptr->pfilename, iniptr->ckr, iniptr->ckg, iniptr->ckb);
    if(surf_powerups[ip] == NULL) {
#ifndef DEBUG
      guru_meditation(GM_FLAGS_DEADEND, GM_SS_Graphics | GM_GE_IOError | GURU_SEC_powerup, iniptr);
#endif
      return NULL;
    }
  }
  deactivate_powerup();
#ifdef DEBUG
  printf("surf_powerups[POWERUP_LASER]=%p surf_powerups[POWERUP_SHIELD]=%p surf_powerups[POWERUP_LIFE]=%p\n", surf_powerups[POWERUP_LASER], surf_powerups[POWERUP_SHIELD], surf_powerups[POWERUP_LIFE]);
#endif
  return &powerup;
}

void shutdown_powerups() {
  int ip;

  deactivate_powerup();
  for(ip = POWERUP_NONE + 1; ip < POWERUP_MAXPOWERUP; ++ip) {
    assert(surf_powerups[ip]);
    destroy_sdl_surfaces(surf_powerups[ip]);
#ifdef DEBUG
    printf("Free '%s' at %p.\n", powerupiniinfo[ip].pname, surf_powerups[ip]);
#endif
  }
}

SDL_Surface *get_powerup_surface() {
  SDL_Surface *source;
  int pownum;
  sdl_surfaces_t *surfaces = NULL;

  pownum = get_current_powerup();
  if(pownum <= POWERUP_NONE || pownum >= POWERUP_MAXPOWERUP) {
    guru_meditation(GM_FLAGS_DEADEND | GM_FLAGS_ABORTIFY, GM_SS_Graphics | GM_GE_BadParm | GURU_SEC_powerup, &get_powerup_surface);
    assert(0);
    return NULL;
  }
  surfaces = surf_powerups[pownum];
  assert(surfaces);
  source = surfaces->surfaces[(unsigned short)powerup.img_ctr % surfaces->num_surfaces];
  assert(source);
  return source;
}

void display_powerup(SDL_Surface * surf_screen) {
  SDL_Rect dest;
  SDL_Surface *source;

  dest.w = 0; //powersurf->w;
  dest.h = 0; //powersurf->h;
  dest.x = powerup.x;
  dest.y = powerup.y;
  source = get_powerup_surface();
  SDL_BlitSurface(source, NULL, surf_screen, &dest);
}

void deactivate_powerup() {
  powerup.active = POWERUP_NONE;
  powerup.countdown = POWERUPDELAY;
  powerup.img_ctr = 0;
}

void update_powerup() {
  if(powerup.active != POWERUP_NONE) {
    SDL_Surface *surf = get_powerup_surface();
    powerup.x += powerup.dx * movementrate;
    powerup.y += powerup.dy * movementrate;
    if(powerup.x < -surf->w
       || powerup.y < -surf->h
       || powerup.x > xsize
       || powerup.y > ysize) {
      deactivate_powerup();
    }
  } else {
    powerup.countdown -= movementrate;
    if(powerup.countdown < 0 && rnd() < .3) {
      powerup.x = xsize;
      powerup.dx = -(3 + rnd() * 5);
      powerup.dy = .5 + rnd() * 3;
      if((powerup.y = rnd() * ysize) >= ysize / 2)
	powerup.dy = -powerup.dy;
      if(rnd() < 0.051807) {
	powerup.active = POWERUP_LIFE;
      } else if(rnd() < .7) {
	powerup.active = POWERUP_LASER;
      } else {
	powerup.active = POWERUP_SHIELD;
      }
      assert(powerup.active != POWERUP_NONE);
    }
  }
  powerup.img_ctr += movementrate;
}