home *** CD-ROM | disk | FTP | other *** search
- /* ScummC
- * Copyright (C) 2004-2006 Alban Bedel
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
- /**
- * @file scc_roobj.c
- * @ingroup scc
- * @brief ScummC object files
- */
-
- #include "config.h"
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <inttypes.h>
- #include <errno.h>
-
- #include "scc_util.h"
- #include "scc_parse.h"
- #include "scc_ns.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include "scc_fd.h"
-
- #include "scc_img.h"
-
- #include "scc_cost.h"
- #include "scc_codec.h"
- #include "scc.h"
- #include "scc_roobj.h"
- #include "scc_code.h"
-
-
- static int scc_roobj_set_image(scc_roobj_t* ro,scc_ns_t* ns,char* val);
- static int scc_roobj_set_boxd(scc_roobj_t* ro,scc_ns_t* ns,char* val);
- static int scc_roobj_set_boxm(scc_roobj_t* ro,scc_ns_t* ns,char* val);
- static int scc_roobj_set_scal(scc_roobj_t* ro,scc_ns_t* ns,char* val);
-
- struct {
- char* name;
- int (*set)(scc_roobj_t* ro,scc_ns_t* ns,char* val);
- } roobj_params[] = {
- { "image", scc_roobj_set_image },
- { "boxd", scc_roobj_set_boxd },
- { "boxm", scc_roobj_set_boxm },
- { "scal", scc_roobj_set_scal },
- { NULL, NULL }
- };
-
- static struct scc_res_types {
- int type;
- uint32_t id;
- uint32_t fixid;
- } scc_res_types[] = {
- { SCC_RES_SOUND, MKID('S','O','U','N'), MKID('s','o','u','n') },
- { SCC_RES_COST, MKID('C','O','S','T'), MKID('c','o','s','t') },
- { SCC_RES_COST, MKID('A','K','O','S'), MKID('a','k','o','s') },
- { SCC_RES_CHSET, MKID('C','H','A','R'), MKID('c','h','a','r') },
- { SCC_RES_VOICE, MKID('v','o','i','c'), MKID('v','o','i','c') },
- { -1, 0, 0 }
- };
-
- scc_roobj_t* scc_roobj_new(scc_target_t* target, scc_symbol_t* sym) {
- scc_roobj_t* ro = calloc(1,sizeof(scc_roobj_t));
-
- ro->target = target;
- ro->sym = sym;
-
- return ro;
- }
-
- static void scc_roobj_res_free(scc_roobj_res_t* r) {
- if(r->data) free(r->data);
- free(r);
- }
-
- void scc_roobj_free(scc_roobj_t* ro) {
- scc_roobj_cycl_t* cycl;
- scc_script_t* scr;
- scc_roobj_obj_t* obj;
- scc_roobj_res_t* res;
- scc_boxd_t* box;
- int i;
-
- SCC_LIST_FREE_CB(ro->scr,scr,scc_script_free);
- SCC_LIST_FREE_CB(ro->lscr,scr,scc_script_free);
-
- SCC_LIST_FREE(ro->cycl,cycl);
- SCC_LIST_FREE_CB(ro->obj,obj,scc_roobj_obj_free);
- SCC_LIST_FREE_CB(ro->res,res,scc_roobj_res_free);
-
- if(ro->image) scc_img_free(ro->image);
- for(i = 0 ; i < SCC_MAX_IM_PLANES ; i++)
- if(ro->zplane[i]) scc_img_free(ro->zplane[i]);
- SCC_LIST_FREE(ro->boxd,box);
- if(ro->boxm) free(ro->boxm);
- if(ro->scal) free(ro->scal);
- free(ro);
- }
-
- scc_script_t* scc_roobj_get_scr(scc_roobj_t* ro, scc_symbol_t* sym) {
- scc_script_t* s;
-
- for(s = (sym->type == SCC_RES_SCR ? ro->scr : ro->lscr) ; s ; s = s->next) {
- if(!strcmp(sym->sym,s->sym->sym)) return s;
- }
-
- return NULL;
- }
-
- int scc_roobj_add_scr(scc_roobj_t* ro,scc_script_t* scr) {
-
- if(scc_roobj_get_scr(ro,scr->sym)) {
- scc_log(LOG_ERR,"Why are we trying to add a script we already have????\n");
- return 0;
- }
-
- if(scr->sym->type == SCC_RES_SCR) {
- scr->next = ro->scr;
- ro->scr = scr;
- } else {
- scr->next = ro->lscr;
- ro->lscr = scr;
- }
- return 1;
- }
-
- scc_roobj_res_t* scc_roobj_get_res(scc_roobj_t* ro,scc_symbol_t* sym) {
- scc_roobj_res_t* r;
-
- for(r = ro->res ; r ; r = r->next) {
- if(sym == r->sym) return r;
- }
-
- return NULL;
- }
-
- scc_roobj_obj_t* scc_roobj_get_obj(scc_roobj_t* ro,scc_symbol_t* sym) {
- scc_roobj_obj_t* obj;
-
- for(obj = ro->obj ; obj ; obj = obj->next) {
- if(obj->sym == sym) return obj;
- }
-
- return NULL;
- }
-
- scc_roobj_cycl_t* scc_roobj_get_cycl(scc_roobj_t* ro,scc_symbol_t* sym) {
- scc_roobj_cycl_t* c;
-
- for(c = ro->cycl ; c ; c = c->next)
- if(c->sym == sym) return c;
- return NULL;
- }
-
- int scc_roobj_add_obj(scc_roobj_t* ro,scc_roobj_obj_t* obj) {
- scc_roobj_obj_t* o = scc_roobj_get_obj(ro,obj->sym);
-
- if(o) {
- scc_log(LOG_ERR,"%s is already defined.\n",obj->sym->sym);
- return 0;
- }
-
- if(obj->trans >= 0) {
- int x,y;
- scc_roobj_state_t* state;
- for(state = obj->states ; state ; state = state->next) {
- uint8_t *optr = state->img->data;
- uint8_t *rptr = ro->image->data+obj->y*ro->image->w+obj->x;
- for(y = 0 ; y < state->img->h ; y++) {
- for(x = 0 ; x < state->img->w ; x++)
- if(optr[x] == obj->trans)
- optr[x] = rptr[x];
- optr += state->img->w;
- rptr += ro->image->w;
- }
- }
- }
-
- SCC_LIST_ADD(ro->obj,ro->last_obj,obj);
-
- return 1;
- }
-
- // add costume, sound, etc
- scc_roobj_res_t* scc_roobj_add_res(scc_roobj_t* ro,scc_symbol_t* sym,
- char* val) {
- scc_roobj_res_t* r = scc_roobj_get_res(ro,sym);
- scc_fd_t* fd;
- int len,flen,rt;
- uint32_t ft;
-
- for(rt = 0 ; scc_res_types[rt].type >= 0 ; rt++) {
- if(scc_res_types[rt].type == sym->type) break;
- }
-
- if(scc_res_types[rt].type < 0) {
- scc_log(LOG_ERR,"Unknown resource type!!!!\n");
- return NULL;
- }
-
- if(r) {
- scc_log(LOG_ERR,"Room symbol %s is already defined.\n",sym->sym);
- return NULL;
- }
-
- fd = new_scc_fd(val,O_RDONLY,0);
- if(!fd) {
- scc_log(LOG_ERR,"Failed to open %s.\n",val);
- return NULL;
- }
- // get file size
- scc_fd_seek(fd,0,SEEK_END);
- flen = scc_fd_pos(fd);
- scc_fd_seek(fd,0,SEEK_SET);
-
- // get the header
- ft = scc_fd_r32(fd);
- while(ft != scc_res_types[rt].id) {
- if(scc_res_types[rt+1].type == sym->type) {
- rt++;
- continue;
- }
- scc_log(LOG_ERR,"The file %s doesn't seem to contain what we want.\n",val);
- scc_fd_close(fd);
- return NULL;
- }
- len = scc_fd_r32be(fd);
- if(len <= 8 || len < flen) {
- scc_log(LOG_ERR,"The file %s seems to be invalid.\n",val);
- scc_fd_close(fd);
- return NULL;
- }
-
- r = calloc(1,sizeof(scc_roobj_res_t));
- r->type = ft;
- r->sym = sym;
- r->data = scc_fd_load(fd,len-8);
- r->data_len = len-8;
-
- r->next = ro->res;
- ro->res = r;
-
- scc_fd_close(fd);
-
- return r;
- }
-
- static int scc_check_voc(char* file,unsigned char* data,unsigned size) {
- int hsize,ver,magic,pos,type,len,pack;
-
- if(strncmp(data,"Creative Voice File",19)) {
- scc_log(LOG_ERR,"%s is not a creative voice file.\n",file);
- return 0;
- }
-
- hsize = SCC_GET_16LE(data,20);
- ver = SCC_GET_16LE(data,22);
- magic = SCC_GET_16LE(data,24);
- if(hsize < 0x1A) {
- scc_log(LOG_ERR,"%s: voc header is too small.\n",file);
- return 0;
- }
-
- if(~ver + 0x1234 != magic) {
- scc_log(LOG_ERR,"%s: Invalid voc header.\n",file);
- return 0;
- }
-
- pos = hsize;
- while(pos < size) {
- type = data[pos]; pos++;
-
- // terminator
- if(type == 0) {
- if(pos != size)
- scc_log(LOG_WARN,"%s: Warning, garbage after terminator???\n",file);
- return 1;
- }
-
- len = data[pos]; pos++;
- len |= data[pos] << 8; pos++;
- len |= data[pos] << 16; pos++;
-
- switch(type) {
- case 1:
- pos++; // srate
- pack = data[pos]; pos++;
- len -= 2;
-
- if(pack != 0) {
- scc_log(LOG_ERR,"%s: Unsupported packing format: %x\n",file,pack);
- return 0;
- }
- case 6:
- case 7:
- break;
- default:
- scc_log(LOG_ERR,"%s: Unsupported block type: %x\n",file,type);
- return 0;
- }
-
- pos += len;
- }
-
- scc_log(LOG_ERR,"%s: Truncated file, or the terminator is missing.\n",file);
- return 0;
- }
-
- int scc_roobj_add_voice(scc_roobj_t* ro, scc_symbol_t* sym, char* file,
- int nsync, int* sync) {
- scc_fd_t* fd = new_scc_fd(file,O_RDONLY,0);
- off_t vsize;
- scc_roobj_res_t* r;
- int i;
-
- if(!fd) {
- scc_log(LOG_ERR,"Failed to open %s.\n",file);
- return 0;
- }
- // get the voc file size
- vsize = scc_fd_seek(fd,0,SEEK_END);
- if(vsize < 0x1A) {
- scc_log(LOG_ERR,"%s is too small to be voc file.\n",file);
- scc_fd_close(fd);
- return 0;
- }
- scc_fd_seek(fd,0,SEEK_SET);
-
- // alloc the res
- r = malloc(sizeof(scc_roobj_res_t));
- r->type = MKID('v','o','i','c');
- r->sym = sym;
- r->data_len = 8 + 2*nsync + vsize;
- r->data = malloc(r->data_len);
-
- // write the sync point table
- SCC_SET_32(r->data,0,MKID('V','C','T','L'));
- SCC_SET_32BE(r->data,4,8 + 2*nsync);
- for(i = 0 ; i < nsync ; i++) {
- SCC_SET_16BE(r->data,8+2*i,sync[i]);
- }
- // load the voc data
- if(scc_fd_read(fd,r->data+8+2*nsync,vsize) != vsize) {
- scc_log(LOG_ERR,"Error while reading voc file.\n");
- free(r->data);
- free(r);
- scc_fd_close(fd);
- return 0;
- }
-
- scc_fd_close(fd);
-
- if(!scc_check_voc(file,r->data+8+2*nsync,vsize)) {
- free(r->data);
- free(r);
- return 0;
- }
-
- // add the res to the list
- r->next = ro->res;
- ro->res = r;
-
- return 1;
- }
-
- int scc_roobj_add_cycl(scc_roobj_t* ro, scc_symbol_t* sym,
- int delay, int flags, int start, int end) {
- scc_roobj_cycl_t* c = scc_roobj_get_cycl(ro,sym);
- int freq;
-
- if(c) {
- scc_log(LOG_ERR,"Cycle %s is already defined.\n",sym->sym);
- return 0;
- }
-
- if(delay < 0) {
- scc_log(LOG_ERR,"Cycl delay must be >= 0.\n");
- return 0;
- }
-
- freq = 16384/delay;
-
- if(freq < 1 || freq > 0xffff) {
- scc_log(LOG_ERR,"Error invalid cycle frequency.\n");
- return 0;
- }
- if(start < 0 || start > 0xFF) {
- scc_log(LOG_ERR,"Error invalid cycle start point.\n");
- return 0;
- }
- if(end < 0 || end > 0xFF) {
- scc_log(LOG_ERR,"Error invalid cycle end point.\n");
- return 0;
- }
- if(start > end) {
- scc_log(LOG_ERR,"Error: cycle start point is after the end point.\n");
- return 0;
- }
-
- c = calloc(1,sizeof(scc_roobj_cycl_t));
- c->sym = sym;
- c->freq = freq;
- c->flags = flags;
- c->start = start;
- c->end = end;
-
- c->next = ro->cycl;
- ro->cycl = c;
-
- return 1;
- }
-
- int scc_roobj_set_param(scc_roobj_t* ro,scc_ns_t* ns,
- char* p,char* val) {
- int i;
-
- for(i = 0 ; roobj_params[i].name ; i++) {
- if(strcmp(roobj_params[i].name,p)) continue;
-
- return roobj_params[i].set(ro,ns,val);
- }
-
- scc_log(LOG_ERR,"Rooms have no parameter named %s.\n",p);
- return 0;
- }
-
-
- static int scc_roobj_set_image(scc_roobj_t* ro,scc_ns_t* ns,char* val) {
-
- if(ro->image) {
- scc_log(LOG_ERR,"Room image has already been set.\n");
- return 0;
- }
-
- ro->image = scc_img_open(val);
- if(!ro->image) {
- scc_log(LOG_ERR,"Failed to parse image %s.\n",val);
- return 0;
- }
-
- if(ro->image->w%8 != 0) {
- scc_log(LOG_ERR,"Images must have w%%8==0 !!!\n");
- scc_img_free(ro->image);
- ro->image = NULL;
- return 0;
- }
-
- return 1;
- }
-
- int scc_roobj_set_zplane(scc_roobj_t* ro, int idx,char* val) {
-
- if(idx < 0) {
- scc_log(LOG_ERR,"Z-planes need a subscript.\n");
- return 0;
- }
- if(idx < 1 || idx >= SCC_MAX_IM_PLANES) {
- scc_log(LOG_ERR,"Z-plane index is out of range.\n");
- return 0;
- }
-
- if(ro->zplane[idx]) {
- scc_log(LOG_ERR,"Z-plane %d has already been set.\n",idx);
- return 0;
- }
-
- ro->zplane[idx] = scc_img_open(val);
- if(!ro->zplane[idx]) {
- scc_log(LOG_ERR,"Failed to open zplane image %s.\n",val);
- return 0;
- }
-
- if(ro->zplane[idx]->w%8 != 0) {
- scc_log(LOG_ERR,"Images must have w%%8==0 !!!\n");
- scc_img_free(ro->zplane[idx]);
- ro->zplane[idx] = NULL;
- return 0;
- }
-
- if(ro->zplane[idx]->ncol != 2)
- scc_log(LOG_WARN,"Warning: zplanes should have only 2 colors.\n");
-
- return 1;
- }
-
-
- static int scc_roobj_set_data_param(scc_data_t** ptr,char* name,char* val) {
-
- if(ptr[0]) {
- scc_log(LOG_ERR,"Room %s has already been set.\n",name);
- return 0;
- }
-
- ptr[0] = scc_data_load(val);
-
- return (ptr[0] ? 1 : 0);
- }
-
- static int scc_roobj_set_boxd(scc_roobj_t* ro,scc_ns_t* ns,char* path) {
- scc_fd_t* fd;
- uint32_t type,len,named=1;
- int pos = 8, boxn = 0,nlen = 0;
- scc_boxd_t* boxes=NULL,*last=NULL,*b;
-
- fd = new_scc_fd(path,O_RDONLY,0);
- if(!fd) {
- scc_log(LOG_ERR,"Failed to open %s.\n",path);
- return 0;
- }
-
- type = scc_fd_r32(fd);
- len = scc_fd_r32be(fd);
-
- if(type == MKID('B','O','X','D')) {
- named = 0;
- scc_fd_r16(fd); pos += 2; // skip num box
- } else if(type != MKID('b','o','x','d')) {
- scc_log(LOG_ERR,"%s is not a boxd file.\n",path);
- scc_fd_close(fd);
- return 0;
- }
-
- while(pos < len) {
- if(named) nlen = scc_fd_r8(fd), pos++;
- if(pos + nlen + 20 > len) {
- scc_log(LOG_ERR,"Invalid box entry.\n");
- break;
- }
- boxn++;
- if(nlen > 0) {
- char name[nlen+1];
- scc_fd_read(fd,name,nlen); pos += nlen;
- name[nlen] = '\0';
- if(!scc_ns_decl(ns,NULL,name,SCC_RES_BOX,0,boxn)) {
- scc_log(LOG_ERR,"Failed to declare room box %s.\n",name);
- break;
- }
- }
- b = malloc(sizeof(scc_boxd_t));
- b->next = NULL;
- b->ulx = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->uly = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->urx = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->ury = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->lrx = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->lry = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->llx = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->lly = (int16_t)scc_fd_r16le(fd); pos += 2;
- b->mask = scc_fd_r8(fd); pos++;
- b->flags = scc_fd_r8(fd); pos++;
- b->scale = scc_fd_r16le(fd); pos += 2;
-
- SCC_LIST_ADD(boxes,last,b);
-
- // we are done
- if(pos == len) {
- // prepend the strange box 0
- if(named) {
- b = malloc(sizeof(scc_boxd_t));
- b->next = boxes;
- b->ulx = -32000;
- b->uly = -32000;
- b->urx = -32000;
- b->ury = -32000;
- b->lrx = -32000;
- b->lry = -32000;
- b->llx = -32000;
- b->lly = -32000;
- b->mask = 0;
- b->flags = 0;
- b->scale = 255;
- ro->boxd = b;
-
- // now the matrix should follow with the scal
-
- type = scc_fd_r32(fd);
- len = scc_fd_r32be(fd);
- if(type != MKID('B','O','X','M') || len <= 8) {
- scc_log(LOG_ERR,"The box file is missing the matrix????\n");
- break;
- }
- ro->boxm = malloc(sizeof(scc_data_t)+len);
- ro->boxm->size = len;
- SCC_SET_32(ro->boxm->data,0,MKID('B','O','X','M'));
- SCC_SET_32BE(ro->boxm->data,4,len);
- if(scc_fd_read(fd,&ro->boxm->data[8],len - 8) != len - 8) {
- scc_log(LOG_ERR,"Error while reading the box matrix.\n");
- break;
- }
-
- type = scc_fd_r32(fd);
- len = scc_fd_r32be(fd);
- if(type != MKID('S','C','A','L') || len != 40) {
- scc_log(LOG_ERR,"The box file is missing the scal block????\n");
- break;
- }
- ro->scal = malloc(sizeof(scc_data_t)+len);
- ro->scal->size = len;
- SCC_SET_32(ro->scal->data,0,MKID('S','C','A','L'));
- SCC_SET_32BE(ro->scal->data,4,len);
- if(scc_fd_read(fd,&ro->scal->data[8],len - 8) != len - 8) {
- scc_log(LOG_ERR,"Error while reading the scal block.\n");
- break;
- }
- } else
- ro->boxd = boxes;
- return 1;
- }
- }
-
- SCC_LIST_FREE(boxes,last);
- scc_fd_close(fd);
- return 0;
- }
-
- static int scc_roobj_set_boxm(scc_roobj_t* ro,scc_ns_t* ns,char* val) {
- return scc_roobj_set_data_param(&ro->boxm,"boxm",val);
- }
-
- static int scc_roobj_set_scal(scc_roobj_t* ro,scc_ns_t* ns,char* val) {
- return scc_roobj_set_data_param(&ro->scal,"scal",val);
- }
-
- ////////////////////////// objects ////////////////////////////
-
-
- scc_roobj_obj_t* scc_roobj_obj_new(scc_symbol_t* sym) {
- scc_roobj_obj_t* obj = calloc(1,sizeof(scc_roobj_obj_t));
- obj->sym = sym;
- obj->trans = -1;
- return obj;
- }
-
- static void scc_roobj_obj_state_free(scc_roobj_state_t* st) {
- int l;
-
- if(st->img) scc_img_free(st->img);
- for(l = 0 ; l < SCC_MAX_IM_PLANES ; l++)
- if(st->zp[l]) scc_img_free(st->zp[l]);
-
- free(st);
- }
-
- void scc_roobj_obj_free(scc_roobj_obj_t* obj) {
- scc_roobj_state_t *st;
- scc_script_t *scr;
-
- if(obj->name) free(obj->name);
- SCC_LIST_FREE_CB(obj->states,st,scc_roobj_obj_state_free);
- SCC_LIST_FREE_CB(obj->verb,scr,scc_script_free);
- //if(obj->im) TODO
- free(obj);
- }
-
- int scc_roobj_obj_add_state(scc_roobj_obj_t* obj,int x, int y,
- char *img_path,char** zp_paths) {
- scc_img_t* img = NULL;
- scc_roobj_state_t* st,*s;
- int i;
-
- if(img_path) {
- img = scc_img_open(img_path);
- if(!img) return 0;
-
- if(img->w%8 || img->h%8) {
- scc_log(LOG_ERR,"Image width and height must be multiples of 8.\n");
- scc_img_free(img);
- return 0;
- }
-
- if(!obj->w) obj->w = img->w;
- if(!obj->h) obj->h = img->h;
- if(obj->w != img->w || obj->h != img->h) {
- scc_log(LOG_ERR,"Image size doesn't match the previously defined size.\n");
- scc_img_free(img);
- return 0;
- }
- }
-
- st = calloc(1,sizeof(scc_roobj_state_t));
- st->hs_x = x;
- st->hs_y = y;
- st->img = img;
-
- if(zp_paths) {
- for(i = 0 ; zp_paths[i] ; i++) {
- if(zp_paths[i][0] == '\0')
- st->zp[i] = scc_img_new(img->w,img->h,2);
- else {
- st->zp[i] = scc_img_open(zp_paths[i]);
- if(!st->zp[i]) {
- scc_roobj_obj_state_free(st);
- return 0;
- }
- if(st->zp[i]->w != img->w ||
- st->zp[i]->h != img->h) {
- scc_log(LOG_ERR,"ZPlane %d has the wrong size.\n",i+1);
- scc_roobj_obj_state_free(st);
- return 0;
- }
- }
- }
- }
-
- if(obj->states) {
- for(s = obj->states ; s->next ; s = s->next);
- s->next = st;
- } else
- obj->states = st;
-
- return 1;
- }
-
-
- int scc_roobj_obj_add_verb(scc_roobj_obj_t* obj,scc_script_t* scr) {
- scc_script_t* s;
-
- for(s = obj->verb ; s ; s = s->next) {
- if(scr->sym == s->sym) {
- scc_log(LOG_ERR,"Why are we trying to add a verb we already have????\n");
- return 0;
- }
- if(!s->next) break;
- }
-
- if(s) s->next = scr;
- else obj->verb = scr;
-
- return 1;
- }
-
- int scc_roobj_obj_set_param(scc_roobj_obj_t* obj,char* sym, char* val) {
- if(!strcmp(sym,"name")) {
- if(obj->name) {
- scc_log(LOG_ERR,"Object name is already defined.\n");
- return 0;
- }
- obj->name = strdup(val);
- return 1;
- }
-
- scc_log(LOG_ERR,"Unknown object parameter: %s\n",sym);
- return 0;
- }
-
- int scc_roobj_obj_set_int_param(scc_roobj_obj_t* obj,char* sym,int val) {
-
- if(!strcmp(sym,"x"))
- obj->x = val;
- else if(!strcmp(sym,"y"))
- obj->y = val;
- else if(!strcmp(sym,"w"))
- obj->w = val;
- else if(!strcmp(sym,"h"))
- obj->h = val;
- else if(!strcmp(sym,"hs_x"))
- obj->hs_x = val;
- else if(!strcmp(sym,"hs_y"))
- obj->hs_y = val;
- else if(!strcmp(sym,"dir"))
- obj->dir = val;
- else if(!strcmp(sym,"trans"))
- obj->trans = val;
- else if(!strcmp(sym,"state")) {
- scc_roobj_state_t* s;
- int i;
- if(val < 0) {
- scc_log(LOG_ERR,"Invalid object state: %d\n",val);
- return 0;
- }
- if(!val) {
- obj->state = 0;
- return 1;
- }
- for(i = 1, s = obj->states ; s && i != val ; i++, s = s->next);
- if(!s) {
- scc_log(LOG_ERR,"Invalid object state: %d\n",val);
- return 0;
- }
- obj->state = val;
- } else if(!strcmp(sym,"parent_state")) {
- if(val < 0) {
- scc_log(LOG_ERR,"Invalid parent state: %d.\n",val);
- return 0;
- }
- obj->parent_state = val;
- } else {
- scc_log(LOG_ERR,"Unknown integer object parameter: %s\n",sym);
- return 0;
- }
-
- return 1;
- }
-
- int scc_roobj_obj_set_class(scc_roobj_obj_t* obj, scc_symbol_t* sym) {
- int i;
-
- // look if that class is alredy set
- for(i = 0 ; i < SCC_MAX_CLASS ; i++) {
- if(!obj->class[i]) continue;
- if(obj->class[i] == sym) return 1;
- }
- // add it
- for(i = 0 ; i < SCC_MAX_CLASS ; i++) {
- if(obj->class[i]) continue;
- obj->class[i] = sym;
- return 1;
- }
- // no space left ???
- return 0;
- }
-
- //////////////////////////// Writing ///////////////////////////////
-
- scc_pal_t* scc_roobj_gen_pals(scc_roobj_t* ro) {
- scc_pal_t* pal;
- int i;
-
- if(!ro->image) {
- scc_log(LOG_V,"Room has no image, using dummy one!!!!\n");
- ro->image = scc_img_new(8,8,256);
- }
-
- pal = calloc(1,sizeof(scc_pal_t));
-
- for(i = 0 ; i < ro->image->ncol ; i++) {
- pal->r[i] = ro->image->pal[3*i];
- pal->g[i] = ro->image->pal[3*i+1];
- pal->b[i] = ro->image->pal[3*i+2];
- }
-
- return pal;
- }
-
- scc_rmim_t* scc_roobj_gen_rmim(scc_roobj_t* ro) {
- scc_rmim_t* rmim;
- int i,j,d,nz = 0;
- uint8_t* zd;
-
- if(!ro->image) {
- scc_log(LOG_V,"Room has no image, using dummy one!!!!\n");
- ro->image = scc_img_new(8,8,256);
- }
-
- for(i = 1 ; i < SCC_MAX_IM_PLANES ; i++) {
- if(ro->zplane[i]) nz++;
- else break;
- }
-
- rmim = calloc(1,sizeof(scc_rmim_t));
- rmim->num_z_buf = nz;
-
- rmim->smap_size = scc_code_image(ro->image->data,ro->image->w,
- ro->image->w,ro->image->h,
- -1,&rmim->smap);
-
- for(i = 1 ; i < nz+1 ; i++) {
- // pack the zplane data
- zd = malloc(ro->zplane[i]->w/8*ro->zplane[i]->h);
- d = 0;
- for(j = 0 ; j < ro->zplane[i]->w*ro->zplane[i]->h ; j++) {
- if(ro->zplane[i]->data[j])
- d |= (1<<(7-(j%8)));
-
- if(j % 8 == 7) {
- zd[j/8] = d;
- d = 0;
- }
- }
- // code it
- rmim->z_buf_size[i] = scc_code_zbuf(zd,ro->zplane[i]->w/8,
- ro->zplane[i]->w,ro->zplane[i]->h,
- &rmim->z_buf[i]);
- free(zd);
- }
-
- return rmim;
-
- }
-
- static scc_imnn_t* scc_roobj_state_gen_imnn(scc_roobj_state_t* st,int idx) {
- scc_imnn_t* imnn;
- scc_img_t* i = st->img;
- scc_img_t** z = st->zp;
- int l;
-
- imnn = calloc(1,sizeof(scc_imnn_t));
- imnn->idx = idx;
- imnn->smap_size = scc_code_image(i->data,i->w,
- i->w,i->h,
- -1,&imnn->smap);
-
- for(l = 0 ; l < SCC_MAX_IM_PLANES && z[l] ; l++) {
- // pack the zplane data
- uint8_t* zd = malloc(z[l]->w/8*z[l]->h);
- int j,d = 0;
- for(j = 0 ; j < z[l]->w*z[l]->h ; j++) {
- if(z[l]->data[j])
- d |= (1<<(7-(j%8)));
-
- if(j % 8 == 7) {
- zd[j/8] = d;
- d = 0;
- }
- }
- // code it
- imnn->z_buf_size[l+1] = scc_code_zbuf(zd,z[l]->w/8,
- z[l]->w,z[l]->h,
- &imnn->z_buf[l+1]);
- free(zd);
- }
-
- return imnn;
- }
-
- static scc_imnn_t* scc_roobj_obj_gen_imnn(scc_roobj_obj_t* obj) {
- scc_imnn_t *imnn = NULL,*last = NULL,*new;
- scc_roobj_state_t* st;
- int idx = 1;
-
- for(st = obj->states ; st ; idx++, st = st->next) {
- new = scc_roobj_state_gen_imnn(st,idx);
- SCC_LIST_ADD(imnn,last,new);
- }
-
- return imnn;
- }
-
- static int scc_roobj_make_obj_parent(scc_roobj_t* ro) {
- scc_roobj_obj_t* obj,*iter;
- int idx;
-
- for(obj = ro->obj ; obj ; obj = obj->next) {
- if(!obj->parent) continue;
- // find the parent
- for(iter = ro->obj, idx = 1 ;
- iter && iter->sym != obj->parent ;
- iter = iter->next, idx++);
- if(!iter) {
- scc_log(LOG_ERR,"Failed to find the parent of object %s\n",
- obj->sym->sym);
- return 0;
- }
- obj->parent_id = idx;
- }
- return 1;
- }
-
- static int scc_scob_size(scc_script_t* scr) {
- int size = 8 + scr->code_len;
- scc_sym_fix_t* f;
-
- if(scr->sym_fix) {
- size += 8;
- for(f = scr->sym_fix ; f ; f = f->next)
- size += 8;
- }
-
- return size;
- }
-
- static int scc_write_scob(scc_fd_t* fd, scc_script_t* scr) {
- int n;
- scc_sym_fix_t* f;
-
- if(scr->sym_fix) {
- for(n = 0, f = scr->sym_fix ; f ; n++, f = f->next);
-
- scc_fd_w32(fd,MKID('S','F','I','X'));
- scc_fd_w32be(fd,8 + n*8);
-
- for(f = scr->sym_fix ; f ; f = f->next) {
- scc_fd_w8(fd,f->sym->type);
- scc_fd_w8(fd,f->sym->subtype);
- scc_fd_w16le(fd,f->sym->rid);
- scc_fd_w32le(fd,f->off);
- }
- }
-
- scc_fd_w32(fd,MKID('s','c','o','b'));
- scc_fd_w32be(fd,8 + scr->code_len);
- if(scr->code_len) scc_fd_write(fd,scr->code,scr->code_len);
-
- return 1;
- }
-
- static int scc_write_sym(scc_fd_t* fd, scc_symbol_t* s, char status) {
- // status: import/export
- scc_fd_w8(fd,status);
- // name
- scc_fd_w8(fd,strlen(s->sym));
- scc_fd_write(fd,s->sym,strlen(s->sym));
- // type
- scc_fd_w8(fd,s->type);
- // subtype
- scc_fd_w8(fd,s->subtype);
- // rid
- scc_fd_w16le(fd,s->rid);
- // addr
- scc_fd_w16le(fd,s->addr);
-
- return 1;
- }
-
- static int scc_sym_block_size(scc_symbol_t* s) {
- int size = 0;
-
- while(s) {
- if(s->rid && s->type != SCC_RES_LSCR)
- size += 1 + 1+strlen(s->sym) + 1 + 1 + 2 + 2;
- s = s->next;
- }
-
- return size;
- }
-
-
- static int scc_write_stab(scc_fd_t* fd, scc_roobj_t* ro, scc_ns_t* ns) {
- scc_symbol_t* s, *c;
- char status;
- int len = scc_sym_block_size(ns->glob_sym);
-
- // no sym at all
- if(!len) return 1;
-
- // first the global ns
- scc_fd_w32(fd,MKID('G','S','Y','M'));
- scc_fd_w32be(fd,8 + len);
-
- for(s = ns->glob_sym ; s ; s = s->next) {
- if(!s->rid) continue;
-
- // everything is imported except ourself
- scc_write_sym(fd,s,(s == ro->sym ? 'E' : 'I'));
- }
-
- // then the
- for(s = ns->glob_sym ; s ; s = s->next) {
- if(!s->rid || s->type != SCC_RES_ROOM) continue;
-
- len = scc_sym_block_size(s->childs);
- if(!len) continue;
-
- // again stuff in our room is exported, the rest is imported
- status = (s == ro->sym ? 'E' : 'I');
-
- scc_fd_w32(fd,MKID('R','S','Y','M'));
- scc_fd_w32be(fd,8 + 2 + len);
-
- // rid
- scc_fd_w16le(fd,s->rid);
-
- for(c = s->childs ; c ; c = c->next) {
- if(!c->rid || c->type == SCC_RES_LSCR) continue;
-
- scc_write_sym(fd,c,status);
- }
-
- }
-
- return 1;
- }
-
- static int scc_stab_size(scc_ns_t* ns) {
- int size = 0;
- scc_symbol_t* s;
- int len = scc_sym_block_size(ns->glob_sym);
-
- if(!len) return 0;
-
- size += 8 + len;
-
- for(s = ns->glob_sym ; s ; s = s->next) {
- if(!s->rid || s->type != SCC_RES_ROOM) continue;
-
- len = scc_sym_block_size(s->childs);
- if(!len) continue;
-
- size += 8 + 2 + len;
- }
-
- return size;
- }
-
- int scc_lscr_block_size(scc_roobj_t* ro) {
- scc_script_t *scr;
- int en = 0,ex = 0;
- int size = 8 + 2; // NLSC
-
- for(scr = ro->lscr ; scr ; scr = scr->next) {
- if(!strcmp(scr->sym->sym,"entry")) en = 1;
- else if(!strcmp(scr->sym->sym,"exit")) ex = 1;
- else size += 2;
- size += 8 + scc_scob_size(scr);
- }
-
- if(!en) size += 8 + 1;
- if(!ex) size += 8 + 1;
-
- return size;
- }
-
- int scc_write_lscr_block(scc_roobj_t* ro, scc_fd_t* fd) {
- scc_script_t *scr,*en = NULL,*ex = NULL;
- int n = 0;
-
- for(scr = ro->lscr ; scr ; scr = scr->next) {
- if(!strcmp(scr->sym->sym,"entry")) en = scr;
- else if(!strcmp(scr->sym->sym,"exit")) ex = scr;
- else {
- n++;
- if(scr->sym->addr < 0)
- scc_log(LOG_WARN,"Warning: a local script is missing its address.\n");
- }
- }
-
- if(ex) {
- scc_fd_w32(fd,MKID('e','x','c','d'));
- scc_fd_w32be(fd,8 + scc_scob_size(ex));
- scc_write_scob(fd,ex);
- } else {
- scc_fd_w32(fd,MKID('E','X','C','D'));
- scc_fd_w32be(fd,8 + 1);
- scc_fd_w8(fd,0x65);
- }
-
- if(en) {
- scc_fd_w32(fd,MKID('e','n','c','d'));
- scc_fd_w32be(fd,8 + scc_scob_size(en));
- scc_write_scob(fd,en);
- } else {
- scc_fd_w32(fd,MKID('E','N','C','D'));
- scc_fd_w32be(fd,8 + 1);
- scc_fd_w8(fd,0x65);
- }
-
- scc_fd_w32(fd,MKID('N','L','S','C'));
- scc_fd_w32be(fd,8 + 2);
- scc_fd_w16le(fd,n);
-
- for(scr = ro->lscr ; scr ; scr = scr->next) {
- if(scr == en || scr == ex) continue;
- scc_fd_w32(fd,MKID('l','s','c','r'));
- scc_fd_w32be(fd,8 + 2 + scc_scob_size(scr));
- scc_fd_w16le(fd,scr->sym->addr);
- scc_write_scob(fd,scr);
- }
-
- return 1;
- }
-
- static int scc_imob_size(int version,scc_roobj_obj_t* obj) {
- scc_imnn_t* i;
- int base_size = version == 7 ? 20 : 16;
- int size = 8 + base_size +2;
- int ni = 0;
-
- for(i = obj->im ; i ; i = i->next) {
- size += 8 + scc_imnn_size(i);
- ni++;
- }
-
- if(!ni) ni++;
- size += 4*ni;
-
- return size;
- }
-
- static int scc_write_imob(int version,scc_roobj_obj_t* obj,scc_fd_t* fd) {
- int j,ni=0,nz=0;
- scc_imnn_t* i;
- scc_roobj_state_t* st;
- int base_size = version == 7 ? 20 : 16;
-
- for(i = obj->im ; i ; i = i->next) {
- int z = 0;
- ni++;
- for(j = 0 ; j < SCC_MAX_IM_PLANES ; j++) {
- if(i->z_buf[j]) z++;
- }
- if(z > nz) nz = z;
- }
-
- scc_fd_w32(fd,MKID('i','m','h','d'));
- scc_fd_w32be(fd,8 + base_size + 2 + (ni ? 4*ni : 4));
-
- if(version == 7) {
- // version
- scc_fd_w32le(fd,730);
- // obj id
- scc_fd_w16le(fd,obj->sym->rid);
- // number of image
- scc_fd_w16le(fd,ni);
- // x,y
- scc_fd_w16le(fd,obj->x);
- scc_fd_w16le(fd,obj->y);
- // w,h
- scc_fd_w16le(fd,obj->w);
- scc_fd_w16le(fd,obj->h);
- // num zpnn
- scc_fd_w16le(fd,nz);
- // unk
- scc_fd_w8(fd,0);
- // direction
- scc_fd_w8(fd,obj->dir);
- } else {
- // obj id
- scc_fd_w16le(fd,obj->sym->rid);
-
- // write number of image and zplanes
- scc_fd_w16le(fd,ni);
- scc_fd_w16le(fd,nz);
- // unk
- scc_fd_w16le(fd,0);
- // x,y
- scc_fd_w16le(fd,obj->x);
- scc_fd_w16le(fd,obj->y);
-
- // w,h
- scc_fd_w16le(fd,obj->w);
- scc_fd_w16le(fd,obj->h);
- }
-
- // num hotspot
- if(ni) {
- scc_fd_w16le(fd,ni);
- for(st = obj->states ; st ; st = st->next) {
- scc_fd_w16le(fd,st->hs_x);
- scc_fd_w16le(fd,st->hs_y);
- }
- } else {
- scc_fd_w16le(fd,1);
- scc_fd_w16le(fd,obj->hs_x);
- scc_fd_w16le(fd,obj->hs_y);
- }
-
- for(i = obj->im ; i ; i = i->next) {
- scc_fd_w32(fd,MKID('I','M','0','0'+i->idx));
- scc_fd_w32be(fd,8 + scc_imnn_size(i));
- scc_write_imnn(fd,i);
- }
-
- return 1;
- }
-
- int scc_verb_block_size(scc_script_t* scr) {
- int size = 0;
-
- while(scr) {
- size += 8 + 2 + scc_scob_size(scr);
- scr = scr->next;
- }
-
- return size;
- }
-
- int scc_write_verb_block(scc_script_t* scr,scc_fd_t* fd) {
-
- while(scr) {
- scc_fd_w32(fd,MKID('v','e','r','b'));
- scc_fd_w32be(fd,8 + 2 +scc_scob_size(scr));
- if(scr->sym) scc_fd_w16le(fd,scr->sym->rid);
- else scc_fd_w16le(fd,0);
- scc_write_scob(fd,scr);
- scr = scr->next;
- }
- return 1;
- }
-
- int scc_obob_size(int version,scc_roobj_obj_t* obj) {
- int body_size = version == 7 ? 4+1+1 : 2+2 +2+2 +1+1 +2*2 +1;
- int size = 8 + 2 +1+2+2*SCC_MAX_CLASS + body_size;
-
- size += scc_verb_block_size(obj->verb);
-
- size += 8 + (obj->name ? strlen(obj->name) : 0) + 1;
-
- return size;
- }
-
-
- int scc_write_obob(int version,scc_roobj_obj_t* obj,scc_fd_t* fd) {
- int body_size = version == 7 ? 4+1+1 : 2+2 +2+2 +1+1 +2*2 +1;
- int i;
-
- scc_fd_w32(fd,MKID('c','d','h','d'));
- scc_fd_w32be(fd,8 + 2 +1+2+2*SCC_MAX_CLASS + body_size);
-
- // rid
- scc_fd_w16le(fd,obj->sym->rid);
-
- // initial state
- scc_fd_w8(fd,obj->state);
- // owner
- if(obj->owner)
- scc_fd_w16le(fd,obj->owner->rid);
- else
- scc_fd_w16le(fd,0);
- // classes
- for(i = 0 ; i < SCC_MAX_CLASS ; i++) {
- if(obj->class[i])
- scc_fd_w16le(fd,obj->class[i]->rid);
- else
- scc_fd_w16le(fd,0);
- }
-
- if(version == 7) {
- // version
- scc_fd_w32le(fd,732);
- // parent
- scc_fd_w8(fd,obj->parent_id);
- // parent state
- scc_fd_w8(fd,obj->parent_state);
- } else {
- scc_fd_w16le(fd,obj->x);
- scc_fd_w16le(fd,obj->y);
-
- scc_fd_w16le(fd,obj->w);
- scc_fd_w16le(fd,obj->h);
-
- // parent state
- scc_fd_w8(fd,obj->parent_state);
- // parent
- scc_fd_w8(fd,obj->parent_id);
- // unk
- scc_fd_w32(fd,0);
- // actor dir
- scc_fd_w8(fd,obj->dir);
- }
-
- // VERBS
- scc_write_verb_block(obj->verb,fd);
-
-
- scc_fd_w32(fd,MKID('O','B','N','A'));
- scc_fd_w32be(fd,8 + (obj->name ? strlen(obj->name) : 0) + 1);
- if(obj->name)
- scc_fd_write(fd,obj->name,strlen(obj->name));
- scc_fd_w8(fd,0);
-
- return 1;
- }
-
- int scc_roobj_write_res(scc_roobj_res_t* res, scc_fd_t* fd) {
- int rt;
-
- for(rt = 0 ; scc_res_types[rt].type >= 0 ; rt++) {
- if(res->type && scc_res_types[rt].id == res->type) break;
- }
-
- if(scc_res_types[rt].type < 0) {
- scc_log(LOG_ERR,"Unknown resource type !!!!\n");
- return 0;
- }
-
- scc_fd_w32(fd,scc_res_types[rt].fixid);
- scc_fd_w32be(fd,8 + 2 + res->data_len);
- scc_fd_w16le(fd,res->sym->rid);
- scc_fd_write(fd,res->data,res->data_len);
-
- return 1;
- }
-
-
- int scc_roobj_cycl_size(scc_roobj_cycl_t* c) {
- int size = 1;
- while(c) {
- size += 9;
- c = c->next;
- }
- return size;
- }
-
-
- int scc_roobj_write_cycl(scc_roobj_cycl_t* c, scc_fd_t* fd) {
-
- while(c) {
- scc_fd_w8(fd,c->sym->addr);
- scc_fd_w16(fd,0);
- scc_fd_w16be(fd,c->freq);
- scc_fd_w16be(fd,c->flags);
- scc_fd_w8(fd,c->start);
- scc_fd_w8(fd,c->end);
- c = c->next;
- }
- scc_fd_w8(fd,0);
- return 1;
- }
-
- int scc_roobj_write(scc_roobj_t* ro, scc_ns_t* ns, scc_fd_t* fd) {
- scc_pal_t* pals;
- scc_rmim_t* rmim;
- scc_script_t* scr;
- scc_roobj_obj_t* obj;
- scc_roobj_res_t* res;
- int i;
- int num_obj = 0;
- int stab_len;
- int rmhd_size = ro->target->version == 7 ? 10 : 6;
- int size = 8 + rmhd_size;
-
- stab_len = scc_stab_size(ns);
- if(stab_len) size += 8 + stab_len;
-
- // CYCL
- size += 8 + scc_roobj_cycl_size(ro->cycl);
- // TRNS
- size += 8 + 2;
- // PALS
- pals = scc_roobj_gen_pals(ro);
- if(!pals) return 0;
- size += 8 + scc_pals_size(pals);
- // RMIM
- rmim = scc_roobj_gen_rmim(ro);
- if(!rmim) return 0;
- size += 8 + scc_rmim_size(rmim);
- // OBIM/OBCD
- if(!scc_roobj_make_obj_parent(ro)) return 0;
- for(obj = ro->obj ; obj ; obj = obj->next) {
- obj->im = scc_roobj_obj_gen_imnn(obj);
- size += 8 + scc_imob_size(ro->target->version,obj);
- size += 8 + scc_obob_size(ro->target->version,obj);
- num_obj++;
- }
- // local scripts
- size += scc_lscr_block_size(ro);
- // BOXD
- if(!ro->boxd)
- size += 8 + 42;
- else
- size += 8 + scc_boxd_size(ro->boxd);
- // BOXM
- if(!ro->boxm)
- size += 8 + 8;
- else
- size += ro->boxm->size;
- // SCAL
- if(!ro->scal)
- size += 8 + 20;
- else
- size += ro->scal->size;
-
- // global scripts
- for(scr = ro->scr ; scr ; scr = scr->next)
- size += 8 + 2 + scc_scob_size(scr);
-
- // ressources
- for(res = ro->res ; res ; res = res->next)
- size += 8 + 2 + res->data_len;
-
- // Now write all that
- // the block header
- scc_fd_w32(fd,MKID('r','o','o','m'));
- scc_fd_w32be(fd,size + 1 + 8);
-
- scc_fd_w8(fd,ro->target->version);
-
- scc_fd_w32(fd,MKID('R','M','H','D'));
- scc_fd_w32be(fd,8 + rmhd_size);
- if(ro->target->version == 7)
- scc_fd_w32le(fd,730); // version
- scc_fd_w16le(fd,ro->image->w);
- scc_fd_w16le(fd,ro->image->h);
- scc_fd_w16le(fd,num_obj);
-
- if(stab_len) {
- scc_fd_w32(fd,MKID('S','T','A','B'));
- scc_fd_w32be(fd,stab_len + 8);
- scc_write_stab(fd,ro,ns);
- }
-
- scc_fd_w32(fd,MKID('C','Y','C','L'));
- scc_fd_w32be(fd,8 + scc_roobj_cycl_size(ro->cycl));
- scc_roobj_write_cycl(ro->cycl,fd);
-
- scc_fd_w32(fd,MKID('T','R','N','S'));
- scc_fd_w32be(fd,8 + 2);
- scc_fd_w16le(fd,ro->trans);
-
- scc_fd_w32(fd,MKID('P','A','L','S'));
- scc_fd_w32be(fd,8 + scc_pals_size(pals));
- scc_write_pals(fd,pals);
-
- scc_fd_w32(fd,MKID('R','M','I','M'));
- scc_fd_w32be(fd,8 + scc_rmim_size(rmim));
- scc_write_rmim(fd,rmim);
-
- // OBIM
- for(obj = ro->obj ; obj ; obj = obj->next) {
- scc_fd_w32(fd,MKID('o','b','i','m'));
- scc_fd_w32be(fd,8 + scc_imob_size(ro->target->version,obj));
- scc_write_imob(ro->target->version,obj,fd);
- }
- // OBCD
- for(obj = ro->obj ; obj ; obj = obj->next) {
- scc_fd_w32(fd,MKID('o','b','c','d'));
- scc_fd_w32be(fd,8 + scc_obob_size(ro->target->version,obj));
- scc_write_obob(ro->target->version,obj,fd);
- }
-
- // All the stuff needed for local scripts
- scc_write_lscr_block(ro,fd);
-
-
-
- // BOXD
- scc_fd_w32(fd,MKID('B','O','X','D'));
- if(ro->boxd) {
- scc_fd_w32be(fd,8 + scc_boxd_size(ro->boxd));
- scc_write_boxd(fd,ro->boxd);
- } else {
- scc_fd_w32be(fd,8 + 42);
- scc_fd_w16le(fd,2); // num box
- // box 0
- for(i = 0 ; i < 8 ; i++) // coords
- scc_fd_w16le(fd,-32000);
- scc_fd_w16(fd,0); // mask, flags
- scc_fd_w16le(fd,255); // scale
- // dummy box
- scc_fd_w16le(fd,2); // ulx
- scc_fd_w16le(fd,2); // uly
- scc_fd_w16le(fd,4); // urx
- scc_fd_w16le(fd,2); // ury
- scc_fd_w16le(fd,4); // lrx
- scc_fd_w16le(fd,4); // lry
- scc_fd_w16le(fd,2); // llx
- scc_fd_w16le(fd,4); // lly
- scc_fd_w16(fd,0); // mask, flags
- scc_fd_w16le(fd,255); // scale
- }
- // BOXM
- if(ro->boxm)
- scc_fd_write(fd,ro->boxm->data,ro->boxm->size);
- else {
- scc_fd_w32(fd,MKID('B','O','X','M'));
- scc_fd_w32be(fd,8 + 8);
- scc_fd_w32be(fd,0x000000FF);
- scc_fd_w32be(fd,0x010101FF);
- }
-
- // SCAL
- if(ro->scal)
- scc_fd_write(fd,ro->scal->data,ro->scal->size);
- else {
- scc_fd_w32(fd,MKID('S','C','A','L'));
- scc_fd_w32be(fd,8 + 20);
- for(i = 0 ; i < 5 ; i++)
- scc_fd_w32(fd,0);
- }
-
- // SCOB
- for(scr = ro->scr ; scr ; scr = scr->next) {
- scc_fd_w32(fd,MKID('s','c','r','p'));
- scc_fd_w32be(fd,8 + 2 + scc_scob_size(scr));
- scc_fd_w16le(fd,scr->sym->rid);
- scc_write_scob(fd,scr);
- }
-
- // write ressources
- for(res = ro->res ; res ; res = res->next)
- scc_roobj_write_res(res,fd);
-
- return 1;
- }
-