Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
/*
21
 *
22
 * Special effects, such as rotating fans, electrical walls, and
23
 * other cool animations.
24
 *
25
 */
26
 
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <stdarg.h>
30
#include <string.h>
31
 
32
#include "gr.h"
33
#include "inferno.h"
34
#include "game.h"
35
#include "vclip.h"
36
#include "effects.h"
37
#include "bm.h"
38
#include "u_mem.h"
39
#include "textures.h"
40
#include "physfs-serial.h"
41
#include "cntrlcen.h"
42
#include "segment.h"
43
#include "dxxerror.h"
44
#include "object.h"
45
 
46
#include "compiler-range_for.h"
47
#include "partial_range.h"
48
 
49
unsigned Num_effects;
50
 
51
void init_special_effects()
52
{
53
        auto &Effects = LevelUniqueEffectsClipState.Effects;
54
        range_for (eclip &ec, partial_range(Effects, Num_effects))
55
                ec.time_left = ec.vc.frame_time;
56
}
57
 
58
void reset_special_effects()
59
{
60
        auto &Effects = LevelUniqueEffectsClipState.Effects;
61
        range_for (eclip &ec, partial_range(Effects, Num_effects))
62
        {
63
                ec.segnum = segment_none;                                       //clear any active one-shots
64
                ec.flags &= ~(EF_STOPPED|EF_ONE_SHOT);          //restart any stopped effects
65
 
66
                //reset bitmap, which could have been changed by a crit_clip
67
                if (ec.changing_wall_texture != -1)
68
                        Textures[ec.changing_wall_texture] = ec.vc.frames[ec.frame_count];
69
 
70
                if (ec.changing_object_texture != -1)
71
                        ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[ec.frame_count];
72
 
73
        }
74
}
75
 
76
void do_special_effects()
77
{
78
        auto &LevelUniqueControlCenterState = LevelUniqueObjectState.ControlCenterState;
79
        auto &Effects = LevelUniqueEffectsClipState.Effects;
80
        range_for (eclip &ec, partial_range(Effects, Num_effects))
81
        {
82
                const auto vc_frame_time = ec.vc.frame_time;
83
                if (!vc_frame_time)
84
                        continue;
85
                if ((ec.changing_wall_texture == -1) && (ec.changing_object_texture==-1) )
86
                        continue;
87
 
88
                if (ec.flags & EF_STOPPED)
89
                        continue;
90
 
91
                ec.time_left -= FrameTime;
92
 
93
                while (ec.time_left < 0) {
94
 
95
                        ec.time_left += vc_frame_time;
96
 
97
                        ec.frame_count++;
98
                        if (ec.frame_count >= ec.vc.num_frames) {
99
                                if (ec.flags & EF_ONE_SHOT) {
100
                                        ec.flags &= ~EF_ONE_SHOT;
101
                                        unique_segment &seg = *vmsegptr(ec.segnum);
102
                                        ec.segnum = segment_none;               //done with this
103
                                        assert(ec.sidenum < 6);
104
                                        auto &side = seg.sides[ec.sidenum];
105
                                        assert(ec.dest_bm_num != 0 && side.tmap_num2 != 0);
106
                                        side.tmap_num2 = ec.dest_bm_num | (side.tmap_num2 & 0xc000);            //replace with destoyed
107
                                }
108
 
109
                                ec.frame_count = 0;
110
                        }
111
                }
112
 
113
                if (ec.flags & EF_CRITICAL)
114
                        continue;
115
 
116
                if (ec.crit_clip!=-1 && LevelUniqueControlCenterState.Control_center_destroyed)
117
                {
118
                        int n = ec.crit_clip;
119
 
120
                        if (ec.changing_wall_texture != -1)
121
                                Textures[ec.changing_wall_texture] = Effects[n].vc.frames[Effects[n].frame_count];
122
 
123
                        if (ec.changing_object_texture != -1)
124
                                ObjBitmaps[ec.changing_object_texture] = Effects[n].vc.frames[Effects[n].frame_count];
125
 
126
                }
127
                else    {
128
                        if (ec.changing_wall_texture != -1)
129
                                Textures[ec.changing_wall_texture] = ec.vc.frames[ec.frame_count];
130
 
131
                        if (ec.changing_object_texture != -1)
132
                                ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[ec.frame_count];
133
                }
134
 
135
        }
136
}
137
 
138
void restore_effect_bitmap_icons()
139
{
140
        auto &Effects = LevelUniqueEffectsClipState.Effects;
141
        range_for (auto &ec, partial_const_range(Effects, Num_effects))
142
        {
143
                if (! (ec.flags & EF_CRITICAL)) {
144
                        if (ec.changing_wall_texture != -1)
145
                                Textures[ec.changing_wall_texture] = ec.vc.frames[0];
146
 
147
                        if (ec.changing_object_texture != -1)
148
                                ObjBitmaps[ec.changing_object_texture] = ec.vc.frames[0];
149
                }
150
        }
151
}
152
 
153
//stop an effect from animating.  Show first frame.
154
void stop_effect(int effect_num)
155
{
156
        auto &Effects = LevelUniqueEffectsClipState.Effects;
157
        eclip *ec = &Effects[effect_num];
158
 
159
        //Assert(ec->bm_ptr != -1);
160
 
161
        ec->flags |= EF_STOPPED;
162
 
163
        ec->frame_count = 0;
164
        //*ec->bm_ptr = &GameBitmaps[ec->vc.frames[0].index];
165
 
166
        if (ec->changing_wall_texture != -1)
167
                Textures[ec->changing_wall_texture] = ec->vc.frames[0];
168
 
169
        if (ec->changing_object_texture != -1)
170
                ObjBitmaps[ec->changing_object_texture] = ec->vc.frames[0];
171
 
172
}
173
 
174
//restart a stopped effect
175
void restart_effect(int effect_num)
176
{
177
        auto &Effects = LevelUniqueEffectsClipState.Effects;
178
        Effects[effect_num].flags &= ~EF_STOPPED;
179
 
180
        //Assert(Effects[effect_num].bm_ptr != -1);
181
}
182
 
183
DEFINE_VCLIP_SERIAL_UDT();
184
DEFINE_SERIAL_UDT_TO_MESSAGE(eclip, ec, (ec.vc, ec.time_left, ec.frame_count, ec.changing_wall_texture, ec.changing_object_texture, ec.flags, ec.crit_clip, ec.dest_bm_num, ec.dest_vclip, ec.dest_eclip, ec.dest_size, ec.sound_num, ec.segnum, serial::pad<2>(), ec.sidenum, serial::pad<3>()));
185
ASSERT_SERIAL_UDT_MESSAGE_SIZE(eclip, 130);
186
 
187
/*
188
 * reads n eclip structs from a PHYSFS_File
189
 */
190
void eclip_read(PHYSFS_File *fp, eclip &ec)
191
{
192
        PHYSFSX_serialize_read(fp, ec);
193
}
194
 
195
#if 0
196
void eclip_write(PHYSFS_File *fp, const eclip &ec)
197
{
198
        PHYSFSX_serialize_write(fp, ec);
199
}
200
#endif