1 #include "anim.h"
2 #include "tools.h"
3 #include "faketime.h"
4 #include "gr2ss.h"
5 #include <SDL.h>
6
7 ActAnim current_anim;
8
9 extern void SDLDraw(void);
10 extern void pump_events(void);
11
12 bool done_playing_anim = false;
13
14 // play
AnimRecur()15 void AnimRecur() {
16 int x, y = 0;
17
18 if(done_playing_anim)
19 return;
20
21 AnimCodeData *data = ¤t_anim.pah->data[current_anim.curSeq];
22 grs_bitmap unpackBM;
23
24 // stop drawing the mouse for now, switch to video canvas
25 uiHideMouse(NULL);
26 gr_push_canvas(¤t_anim.cnv);
27
28 // might need to draw a background before the first frame
29 if(current_anim.frameNum == 0) {
30 if(current_anim.composeFunc != NULL)
31 current_anim.composeFunc(current_anim.reg->r, 0x04);
32 }
33
34 short a, b, c, d;
35 STORE_CLIP(a, b, c, d);
36
37 // grab this frame
38 FrameDesc *f = RefLock(current_anim.currFrameRef);
39
40 if (f != NULL) {
41 f->bm.bits = (uchar *)(f + 1);
42 f->bm.flags = BMF_TRANS;
43
44 gr_set_cliprect(f->updateArea.ul.x, f->updateArea.ul.y, f->updateArea.lr.x, f->updateArea.lr.y);
45 gr_rsd8_bitmap((grs_bitmap *)f, 0, 0);
46 }
47 else {
48 TRACE("Done playing anim!");
49 done_playing_anim = true;
50 }
51
52 RefUnlock(current_anim.currFrameRef);
53
54 RESTORE_CLIP(a, b, c, d);
55 gr_pop_canvas();
56
57 // Draw the scaled up movie
58 x = current_anim.loc.x;
59 y = current_anim.loc.y;
60 ss_bitmap(¤t_anim.cnv.bm, x, y);
61
62 long time = SDL_GetTicks();
63 if(time >= current_anim.timeContinue) {
64 current_anim.currFrameRef++;
65 current_anim.frameNum++;
66 current_anim.timeContinue = time + 100;
67
68 if(current_anim.frameNum > data->frameRunEnd + 1) {
69 current_anim.curSeq++;
70 }
71 }
72
73 // safe to draw the mouse again
74 uiShowMouse(NULL);
75
76 if(done_playing_anim) {
77 AnimKill(¤t_anim);
78 }
79
80 // Make SDL happy
81 pump_events();
82 SDLDraw();
83 }
84
AnimSetAnimPall(Ref animRef)85 void AnimSetAnimPall(Ref animRef) {
86
87 }
88
AnimPreloadFrames(ActAnim * paa,Ref animRef)89 bool AnimPreloadFrames(ActAnim *paa, Ref animRef) {
90 return 1;
91 }
92
AnimPlayRegion(Ref animRef,LGRegion * region,LGPoint loc,char unknown,void (* composeFunc)(LGRect * area,ubyte flags))93 ActAnim *AnimPlayRegion(Ref animRef, LGRegion *region, LGPoint loc, char unknown,
94 void (*composeFunc)(LGRect *area, ubyte flags)) {
95 // start playing
96 DEBUG("Playing animation: %x", animRef);
97
98 AnimHead *head = (AnimHead *)RefGet(animRef);
99 if(head != NULL) {
100 TRACE("Animation frames at %x", head->frameSetId);
101 }
102
103 done_playing_anim = false;
104 current_anim.reg = region;
105 current_anim.pah = head;
106 current_anim.currFrameRef = MKREF(head->frameSetId, 0);
107 current_anim.curSeq = 0;
108 current_anim.frameNum = 0;
109 current_anim.composeFunc = composeFunc;
110 current_anim.timeContinue = SDL_GetTicks() + 100;
111 current_anim.loc = loc;
112
113 // Initialize canvas for this animation
114 grs_bitmap bm;
115 uchar *bptr = (uchar *)malloc(head->size.x * head->size.y * 2);
116
117 gr_init_bm(&bm, bptr, BMT_FLAT8, BMF_TRANS, head->size.x, head->size.y);
118 gr_make_canvas(&bm, ¤t_anim.cnv);
119 gr_push_canvas(¤t_anim.cnv);
120 gr_clear(0);
121 gr_pop_canvas();
122
123 return ¤t_anim;
124 }
125
AnimSetNotify(ActAnim * paa,void * powner,AnimCode mask,void (* func)(ActAnim *,AnimCode ancode,AnimCodeData * animData))126 void AnimSetNotify(ActAnim *paa, void *powner, AnimCode mask,
127 void (*func) (ActAnim *, AnimCode ancode, AnimCodeData *animData)) {
128
129 // user callback function
130 paa->notifyFunc = func;
131 }
132
AnimKill(ActAnim * paa)133 void AnimKill(ActAnim *paa) {
134 // Stop animation
135 AnimCodeData data;
136
137 if(current_anim.notifyFunc != NULL)
138 current_anim.notifyFunc(¤t_anim, ANCODE_KILL, &data);
139
140 free(current_anim.cnv.bm.bits);
141 }
142