1 /**
2  * Header for code common to FreeDink and FreeDinkedit
3 
4  * Copyright (C) 1997, 1998, 1999, 2002, 2003  Seth A. Robinson
5  * Copyright (C) 2008, 2009  Sylvain Beucler
6 
7  * This file is part of GNU FreeDink
8 
9  * GNU FreeDink is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 3 of the
12  * License, or (at your option) any later version.
13 
14  * GNU FreeDink is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18 
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see
21  * <http://www.gnu.org/licenses/>.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 
29 #include <stdlib.h>  /* srand */
30 #include <time.h>  /* time */
31 #include <string.h>  /* memset */
32 #include "game_engine.h"
33 #include "screen.h" /* hm */
34 #include "dinkvar.h"  /* hmap, pam */
35 #include "input.h"
36 
37 struct sp spr[MAX_SPRITES_AT_ONCE]; //max sprite control systems at once
38 int last_sprite_created;
39 
40 /* Engine variables directly mapped with DinkC variables */
41 int *pvision, *plife, *presult, *pspeed, *ptiming, *plifemax,
42   *pexper, *pmap, *pstrength, *pcur_weapon,*pcur_magic, *pdefense,
43   *pgold, *pmagic, *plevel, *plast_text, *pmagic_level;
44 int *pupdate_status, *pmissile_target, *penemy_sprite,
45   *pmagic_cost, *pmissle_source;
46 
47 
48 int flife, fexp, fstrength, fdefense, fgold, fmagic, fmagic_level, flifemax, fraise, last_magic_draw;
49 
50 int fcur_weapon, fcur_magic;
51 
52 /* Sound - BGM */
53 int sound_on = 1;
54 int cd_inserted;
55 int midi_active = 1;
56 
57 
58 
59 struct map_info map;
60 
61 
62 
63 //JOYINFOEX jinfo; //joystick info
64 SDL_Joystick* jinfo;
65 int joystick = /*true*/1;
66 
67 struct wait_for_button wait4b;
68 
69 
70 
71 int dversion = 108;
72 char* dversion_string;
73 
74 int last_saved_game = 0;
75 char save_game_info[200] = "Level &level";
76 char current_map[50] = "map.dat";
77 char current_dat[50] = "dink.dat";
78 
79 time_t time_start;
80 
81 
82 int smooth_follow = 0;
83 
84 
85 
86 /** Fadedown / fadeup **/
87 /* Tell the engine that we're warping */
88 /* (quick fadedown + black + fadeup) */
89 int process_warp = 0;
90 /* Tell the engine that we're fading down */
91 /* or fading up */
92 int process_downcycle = 0;
93 int process_upcycle = 0;
94 /* When the fadedown must finish: */
95 unsigned long cycle_clock = 0;
96 /* What script to resume after fade: */
97 int cycle_script = 0;
98 
99 /* Base for Dink's push sequences */
100 unsigned int dink_base_push = 310;
101 
102 
103 /* hardness */
104 struct hit_map hm;
105 
106 static int high_speed = 0;
107 
game_init()108 void game_init()
109 {
110   /* Clean the game state structure - done by C++ but not
111      automatically done by C, and this causes errors. TODO: fix the
112      errors properly instead of using this dirty trick. */
113   memset(&play, 0, sizeof(play));
114 
115   /* Precaution */
116   memset(&hmap, 0, sizeof(hmap));
117   memset(&pam, 0, sizeof(pam));
118   memset(&spr, 0, sizeof(spr));
119 
120   memset(&hm, 0, sizeof(hm));
121 
122   if (dversion >= 108)
123     dversion_string = "v1.08 FreeDink";
124   else
125     dversion_string = "v1.07 FreeDink";
126 
127   srand((unsigned)time(NULL));
128 }
129 
game_quit()130 void game_quit()
131 {
132   int i = 0;
133   for (i = 1; i < MAX_SPRITES_AT_ONCE; i++)
134     {
135       if (spr[i].custom != NULL)
136 	dinkc_sp_custom_free(spr[i].custom);
137       spr[i].custom = NULL;
138     }
139 }
140 
141 /**
142  * Fake SDL_GetTicks if the player is in high-speed mode.  Make sure
143  * you call it once per frame.
144  */
game_GetTicks()145 Uint32 game_GetTicks()
146 {
147   static Uint32 last_sdl_ticks = 0;
148   static Uint32 high_ticks = 0;
149 
150   Uint32 cur_sdl_ticks = SDL_GetTicks();
151   /* Work-around incorrect initial value */
152   if (last_sdl_ticks == 0)
153     last_sdl_ticks = cur_sdl_ticks - 1;
154 
155   /* If high speed, then count every tick as triple (so add 2x) */
156   if (high_speed)
157     {
158       high_ticks += 2 * (cur_sdl_ticks - last_sdl_ticks);
159     }
160 
161   last_sdl_ticks = cur_sdl_ticks;
162   return cur_sdl_ticks + high_ticks;
163 }
164 
game_set_high_speed()165 void game_set_high_speed()
166 {
167   if (high_speed == 0)
168     {
169       SDL_setFramerate(&framerate_manager, 3*FPS);
170       high_speed = 1;
171     }
172 }
173 
game_set_normal_speed()174 void game_set_normal_speed()
175 {
176   if (high_speed == 1)
177     {
178       SDL_setFramerate(&framerate_manager, FPS);
179       high_speed = 0;
180     }
181 }
182 
183 
184 /* Sound - SFX */
get_pan(int h)185         int get_pan(int h)
186         {
187 
188                 int pan = 0;
189 
190                 int x1 = 320;
191 
192 
193                 //uncomment to allow math to be done from Dink's current location
194                 //x1 = spr[1].x;
195 
196 
197                 if (spr[h].active)
198                 {
199                         if (spr[h].x > x1) pan += (spr[h].x - x1) * 6;
200                         if (x1 > spr[h].x) pan -= (x1 - spr[h].x) * 6;
201 
202                 }
203 
204 
205                 if (pan > 10000) pan = 10000;
206                 if (pan < -10000) pan = -10000;
207 
208 
209                 return(pan);
210 
211 
212         }
213 
get_vol(int h)214         int get_vol(int h)
215         {
216 
217                 int pan = 0;
218                 int pan2 = 0;
219 
220                 if (spr[h].active)
221                 {
222                         if (spr[h].x > spr[1].x) pan -= (spr[h].x - spr[1].x) * 4;
223 
224 
225                         if (spr[1].x > spr[h].x) pan -= (spr[1].x - spr[h].x) * 4;
226 
227 
228                         if (spr[h].y > spr[1].y) pan2 -= (spr[h].y - spr[1].y) * 4;
229 
230                         if (spr[1].y > spr[h].y) pan2 -= (spr[1].y - spr[h].y) * 4;
231 
232 
233                         //Msg("pan %d, pan2 %d", pan, pan2);
234 
235                         if (pan2 < pan) pan = pan2;
236 
237                 }
238 
239 
240                 if (pan > -100) pan = 0;
241 
242                 if (pan < -10000) pan = -10000;
243 
244 
245                 return(pan);
246 
247 
248         }
249