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 = &current_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(&current_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(&current_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(&current_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, &current_anim.cnv);
119     gr_push_canvas(&current_anim.cnv);
120     gr_clear(0);
121     gr_pop_canvas();
122 
123 	return &current_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(&current_anim, ANCODE_KILL, &data);
139 
140 	free(current_anim.cnv.bm.bits);
141 }
142