~ubuntu-branches/ubuntu/lucid/ming/lucid

« back to all changes in this revision

Viewing changes to src/blocks/action.c

  • Committer: Bazaar Package Importer
  • Author(s): Ilya Barygin
  • Date: 2010-02-11 10:57:41 UTC
  • mfrom: (2.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20100211105741-lzpmxc0703c4bo1w
Tags: 1:0.4.3-1ubuntu1
* Merge from Debian unstable (LP: #192664), remaining changes:
  - Python 2.6 transition:
    - debian/rules:
      + Include /usr/share/python/python.mk.
      + Add py_setup_install_args macro to setup.py install.
      + Installed modules differ between python versions and can't be shared,
        use DH_PYCENTRAL=nomove.
    - Remove unnecessary debian/python-ming.{dirs,files}, Python 2.3 is not
      supported anymore.
* debian/control: separate dependencies by commas.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
*/
19
19
 
20
 
/* $Id: action.c,v 1.10 2004/03/30 15:07:28 strk Exp $ */
 
20
/* $Id: action.c,v 1.24 2008/09/28 16:53:58 krechert Exp $ */
 
21
 
 
22
#ifndef __C2MAN__
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#endif
21
26
 
22
27
#include "action.h"
23
 
#include "outputblock.h"
 
28
#include "output.h"
 
29
#include "block.h"
 
30
#include "input.h"
 
31
#include "method.h"
24
32
#include "libming.h"
25
 
 
26
 
 
27
 
SWFAction newSWFAction()
28
 
{
29
 
        return newSWFOutputBlock(newSWFOutput(), SWF_DOACTION);
30
 
}
31
 
 
32
 
 
 
33
#include "character.h"
 
34
#include "movieclip.h"
 
35
#include "actioncompiler/compile.h"
 
36
#include "actiontypes.h"
 
37
 
 
38
typedef enum {
 
39
        INPUT_EMPTY,
 
40
        INPUT_FILE,
 
41
        INPUT_SCRIPT
 
42
} ActionInputType;
 
43
 
 
44
struct SWFAction_s
 
45
{
 
46
        struct SWFBlock_s block;
 
47
        ActionInputType inputType;
 
48
        SWFOutput out;
 
49
        union
 
50
        {
 
51
                FILE *file;
 
52
                char *script;
 
53
        } input;
 
54
        int debug;      
 
55
};
 
56
 
 
57
struct SWFInitAction_s
 
58
{
 
59
        struct SWFBlock_s block;
 
60
        int spriteId;
 
61
        SWFAction action; 
 
62
        SWFMovieClip clip;
 
63
};
 
64
 
 
65
static char *readActionFile(FILE *file)
 
66
{
 
67
        int len;
 
68
        char *script;
 
69
        SWFInput input = newSWFInput_file(file);
 
70
        len = SWFInput_length(input);
 
71
        script = (char *)malloc(len + 1);
 
72
        if(SWFInput_read(input, (unsigned char *)script, len) != len)
 
73
        {
 
74
                SWF_warn("readActionFile failed\n");
 
75
                free(script);
 
76
                return NULL;
 
77
        }
 
78
        destroySWFInput(input); 
 
79
        script[len] = '\0';
 
80
        return script;
 
81
}
 
82
 
 
83
void SWFOutput_writeAction(SWFOutput out, SWFAction action)
 
84
{
 
85
        int len;
 
86
        byte *data;
 
87
 
 
88
        if(action->out == NULL)
 
89
        {
 
90
                SWF_warn("SWFAction: compile action first\n");
 
91
                return;
 
92
        }       
 
93
        
 
94
        len = SWFOutput_getLength(action->out);
 
95
        data = SWFOutput_getBuffer(action->out);
 
96
        SWFOutput_writeBuffer(out, data, len);
 
97
 
98
 
 
99
/*
 
100
 * Compiles the current script stored in this SWFAction instance.
 
101
 * returns 0 on success, -1 otherwise.
 
102
 * the length of the compiled bytecode is storen in the length pointer (if not NULL).
 
103
 */
 
104
int SWFAction_compile(SWFAction action, 
 
105
                      int swfVersion /* target SWF version */, 
 
106
                      int *length /* output length */)
 
107
{
 
108
        char *script = NULL;
 
109
        Buffer b;
 
110
        int parserError;
 
111
 
 
112
        if(action->out != NULL)
 
113
        {
 
114
                if(length != NULL)
 
115
                        *length = SWFOutput_getLength(action->out);
 
116
                return 0;
 
117
        }
 
118
 
 
119
        switch(action->inputType)
 
120
        {
 
121
                case INPUT_SCRIPT:
 
122
                        script = action->input.script;
 
123
                        break;
 
124
                case INPUT_FILE:
 
125
                        script = readActionFile(action->input.file);
 
126
                        break;
 
127
                default: break;
 
128
        }
 
129
 
 
130
        if(script != NULL && swfVersion == 4)
 
131
        {
 
132
                swf4ParseInit(script, action->debug, swfVersion);
 
133
                parserError = swf4parse((void *)&b);
 
134
        }
 
135
        else if (script != NULL)
 
136
        {
 
137
                swf5ParseInit(script, action->debug, swfVersion);
 
138
                parserError = swf5parse((void *)&b);
 
139
        }
 
140
        else 
 
141
                parserError = 1;
 
142
        
 
143
        // if INPUT_FILE script was allocated by readActionFile()
 
144
        if(action->inputType == INPUT_FILE)
 
145
                free(script);
 
146
                
 
147
        action->out = newSWFOutput();
 
148
 
 
149
        if(!parserError)
 
150
        {
 
151
                SWFOutput_writeBuffer(action->out, b->buffer, bufferLength(b));
 
152
                destroyBuffer(b);
 
153
        }
 
154
        else
 
155
                SWF_warn("Parser error: writing empty block\n");
 
156
 
 
157
        SWFOutput_writeUInt8(action->out, SWFACTION_END);
 
158
        if(length != NULL)
 
159
                *length = SWFOutput_getLength(action->out);
 
160
 
 
161
        if(parserError)
 
162
                return -1;
 
163
                
 
164
        return 0;
 
165
}
 
166
 
 
167
/* 
 
168
 * Returns the compiled bytecode.
 
169
 * If not already compiled the script will compiled for SWF V7.
 
170
 *
 
171
 * Returns NULL in case of an error. Length pointer stores the length of 
 
172
 * the compiled bytecode.
 
173
 */
 
174
byte *SWFAction_getByteCode(SWFAction action, int *length)
 
175
{
 
176
        int ret = 0;
 
177
        if(action == NULL) 
 
178
                return NULL;
 
179
 
 
180
        if(action->out == NULL)
 
181
        {
 
182
                SWF_warn("SWFAction_getByteCode: please use SWFAction_compile first\n");
 
183
                SWF_warn("auto-compiling as SWF 7 code now...\n");
 
184
                ret = SWFAction_compile(action, 7, (int *)length);
 
185
        }
 
186
 
 
187
        if(ret < 0)
 
188
        {       
 
189
                *length = -1;
 
190
                return NULL;
 
191
        }
 
192
        return SWFOutput_getBuffer(action->out);
 
193
}
 
194
 
 
195
static int
 
196
completeSWFAction(SWFBlock block)
 
197
{
 
198
        int length;
 
199
        SWFAction action = (SWFAction)block;
 
200
        SWFAction_compile(action, block->swfVersion, &length);
 
201
        return length;
 
202
}
 
203
 
 
204
static int
 
205
completeSWFInitAction(SWFBlock block)
 
206
{
 
207
        SWFInitAction init = (SWFInitAction)block;
 
208
        int len;
 
209
 
 
210
        SWFAction_compile(init->action, block->swfVersion, &len);
 
211
        return len + 2;
 
212
}
 
213
 
 
214
 
 
215
static void
 
216
writeSWFActionToMethod(SWFBlock block, SWFByteOutputMethod method, void* data)
 
217
{
 
218
        SWFOutput out = ((SWFAction)block)->out;
 
219
        SWFOutput_writeToMethod(out, method, data);
 
220
}
 
221
 
 
222
static void
 
223
writeSWFInitActionToMethod(SWFBlock block, SWFByteOutputMethod method, void* data)
 
224
{
 
225
        SWFInitAction init = (SWFInitAction)block;
 
226
        methodWriteUInt16(init->spriteId, method, data);
 
227
        SWFOutput_writeToMethod(init->action->out, method, data);
 
228
}
 
229
 
 
230
/*
 
231
 * Destroys a SWFAction instance
 
232
 */
33
233
void destroySWFAction(SWFAction action)
34
234
{
35
 
        destroySWFOutputBlock(action);
36
 
}
37
 
 
38
 
 
39
 
SWFAction newSWFAction_fromOutput(SWFOutput out)
40
 
{
41
 
        return newSWFOutputBlock(out, SWF_DOACTION);
42
 
}
43
 
 
 
235
        if(!action)
 
236
                return;
 
237
 
 
238
        switch(action->inputType)
 
239
        {
 
240
                case INPUT_FILE:
 
241
                        fclose(action->input.file);
 
242
                        break;
 
243
                case INPUT_SCRIPT:
 
244
                        free(action->input.script);
 
245
                        break;
 
246
                default:
 
247
                        break;
 
248
        }
 
249
        
 
250
        if(action->out)
 
251
                destroySWFOutput(action->out);
 
252
        
 
253
        free(action);
 
254
}
 
255
 
 
256
void destroySWFInitAction(SWFInitAction init)
 
257
{
 
258
        if(!init)
 
259
                return;
 
260
 
 
261
        if(init->clip)
 
262
                destroySWFMovieClip(init->clip);
 
263
        destroySWFAction(init->action);
 
264
        free(init);
 
265
}
 
266
 
 
267
 
 
268
static SWFAction createEmptyAction()
 
269
{
 
270
        SWFAction action = (SWFAction)malloc(sizeof(struct SWFAction_s));
 
271
 
 
272
        SWFBlockInit(BLOCK(action));
 
273
        BLOCK(action)->type = SWF_DOACTION;
 
274
        BLOCK(action)->writeBlock = writeSWFActionToMethod;
 
275
        BLOCK(action)->complete = completeSWFAction;
 
276
        BLOCK(action)->dtor = (destroySWFBlockMethod) destroySWFAction;
 
277
        action->inputType = INPUT_EMPTY;
 
278
        action->out = NULL;
 
279
        action->debug = 0;
 
280
        return action;
 
281
}
 
282
 
 
283
/**
 
284
 * enable verbose compiler output 
 
285
 *
 
286
 * Set debug value to 1 get very! verbose compile messages.
 
287
 * @return old value
 
288
 */
 
289
int SWFAction_setDebug(SWFAction a, int debug /*debug switch*/)
 
290
{
 
291
        int oldval;
 
292
        if(!a)
 
293
                return -1;
 
294
        oldval = a->debug;
 
295
        a->debug = debug;
 
296
        return oldval;
 
297
}
 
298
 
 
299
/*
 
300
 * Creates a new SWFAction object.
 
301
 * Takes a String containing AS[2] source code.
 
302
 *
 
303
 * returns a SWFAction instance.
 
304
 */
 
305
SWFAction newSWFAction(const char *script)
 
306
{
 
307
        SWFAction action = createEmptyAction();
 
308
        action->inputType = INPUT_SCRIPT;
 
309
        action->input.script = strdup(script);
 
310
 
 
311
        return action;
 
312
}
 
313
 
 
314
/*
 
315
 * Creates a new SWFAction object.
 
316
 * Takes a filename pointing to a file containing AS[2] source code.
 
317
 *
 
318
 * return a SWFAction instance.
 
319
 */
 
320
SWFAction newSWFAction_fromFile(const char *filename)
 
321
{
 
322
        SWFAction action = createEmptyAction();
 
323
        action->inputType = INPUT_FILE;
 
324
        action->input.file = fopen(filename, "r");
 
325
        if(action->input.file == NULL)
 
326
        {
 
327
                destroySWFAction(action);
 
328
                return NULL;
 
329
        }
 
330
        return action;
 
331
}
 
332
 
 
333
SWFMovieClip SWFInitAction_getMovieClip(SWFInitAction action)
 
334
{
 
335
        return action->clip;
 
336
}
 
337
 
 
338
/*
 
339
 * create a InitAction block with a given sprite's character id
 
340
 *
 
341
 * This function creates a InitAction block with a given sprite's character id.
 
342
 * Use with care!
 
343
 */
 
344
SWFInitAction newSWFInitAction_withId(SWFAction action, int id /* mc character id */)
 
345
{
 
346
        SWFInitAction init = (SWFInitAction)malloc(sizeof(struct SWFInitAction_s));
 
347
        SWFBlockInit(BLOCK(init));
 
348
        BLOCK(init)->writeBlock = writeSWFInitActionToMethod;
 
349
        BLOCK(init)->complete = completeSWFInitAction;
 
350
        BLOCK(init)->dtor = (destroySWFBlockMethod) destroySWFInitAction;
 
351
        BLOCK(init)->type = SWF_INITACTION;
 
352
        init->clip = NULL;      // use external clip
 
353
        init->spriteId = id;    
 
354
        init->action = action;
 
355
        return init;
 
356
}
 
357
 
 
358
/*
 
359
 * create a InitAction block
 
360
 *
 
361
 * This function creates a InitAction block and defines an empty sprite/mc
 
362
 * which is not placed. This functions is usefull for defining classes.
 
363
 */
 
364
SWFInitAction newSWFInitAction(SWFAction action)
 
365
{
 
366
        SWFInitAction init = (SWFInitAction)malloc(sizeof(struct SWFInitAction_s));
 
367
        SWFBlockInit(BLOCK(init));
 
368
        BLOCK(init)->writeBlock = writeSWFInitActionToMethod;
 
369
        BLOCK(init)->complete = completeSWFInitAction;
 
370
        BLOCK(init)->dtor = (destroySWFBlockMethod) destroySWFInitAction;
 
371
        BLOCK(init)->type = SWF_INITACTION;
 
372
        init->clip = newSWFMovieClip();
 
373
        init->spriteId = CHARACTERID(init->clip);
 
374
        init->action = action;
 
375
        return init;
 
376
}
 
377
 
 
378
SWFInitAction newSWFInitAction_MovieClip(SWFMovieClip clip, SWFAction action)
 
379
{
 
380
        SWFInitAction init = (SWFInitAction)malloc(sizeof(struct SWFInitAction_s));
 
381
        SWFBlockInit(BLOCK(init));
 
382
        BLOCK(init)->writeBlock = writeSWFInitActionToMethod;
 
383
        BLOCK(init)->complete = completeSWFInitAction;
 
384
        BLOCK(init)->dtor = (destroySWFBlockMethod) destroySWFInitAction;
 
385
        BLOCK(init)->type = SWF_INITACTION;
 
386
        init->spriteId = CHARACTERID(clip);
 
387
        init->clip = NULL; // use external clip
 
388
        init->action = action;
 
389
        return init;
 
390
}
44
391
 
45
392
/*
46
393
 * Local variables: