// // IRE init systems // #include #include #include #include // MR: added #ifndef _WIN32 #include #endif // defines #define IRE_SYSTEM_MODULE #define ALREADY_KNOW_ITG #define UNDEFINED -1 #define QRAND_MAX 32768 // includes #include "ithelib.h" #include "media.h" #include "console.h" #include "init.h" #include "loadfile.h" #include "gamedata.h" #include "script.hpp" #include "oscli.h" //#include "vrm_in.hpp" // Global variables extern char allegro_error[]; //SQ **SQlist; long SQtot; // Sequences in the SQlist, no. of sequences //CH *CHlist; long CHtot; // Array of characters, no. of characters //SP *SPlist; long SPtot; // Array of sprites, number of sprites PEM *PElist; // PissEasy Script table S_POOL *s_pool; // Pool of sprites loaded into memory SEQ_POOL *seq_pool; // Pool of animation sequences typedef struct search_st { char *name; int num; } search_st; static search_st *sprites; static search_st *sequences; static search_st *scripts; static search_st *characters; static search_st *tables; unsigned char digit[256][8]; char stemp[128]; /* unsigned short font_bground=0,font_fground=0x7fff; char *rootname="main\0"; */ extern char mapname[]; //extern char big_font; // Local variables static int qrt[QRAND_MAX]; // functions short FindProc(char *name); extern void register_exporttable(); extern int sizeof_sprite(BITMAP *bmp); extern BITMAP *load_lightmap(char *filename); static int CMP_sort(const void *a,const void *b); static int CMP_search(const void *a,const void *b); static int CMP_search_DTI(const void *a,const void *b); static int CMP_search_DTS(const void *a,const void *b); static int GetAvg(BITMAP *bmp); static RLE_SPRITE *LoadRLEImage(char *fname, long *avcol); // code /* * LoadImage: high-level image loader */ RLE_SPRITE *LoadRLEImage(char *fname, long *avcol) { char filename[1024]; char cachename[1024]; BITMAP *img; time_t ftime,itime; struct stat sb; int avg; RLE_SPRITE *dest; if(!loadfile(fname,filename)) ithe_panic("Could not load image: (file not found)",fname); img=NULL; ftime=igettime(filename); // Try the image cache strcpy(cachename,imgcachedir); strcat(cachename,filename); itime=0; if(!stat(cachename,&sb)) // Zero is success itime=sb.st_mtime; else ftime=0; if(ftime != 0 && difftime(itime,ftime) >= 0.0) { // ilog_quiet("Try Load cache %s [%s][%s]\n",cachename,imgcachedir,filename); dest = load_rle_sprite(cachename,avcol); } else { // ilog_quiet("Try Load bitmap %s\n",filename); img = iload_bitmap(filename); dest = get_rle_sprite(img); avg=GetAvg(img); // avg=getpixel(img,0,0); // Get a thumbnail colour if(avcol) *avcol=avg; // Write cache entry save_rle_sprite(dest,cachename,avg); } if(img) destroy_bitmap(img); if(!dest) ithe_panic("Could not load image: unsupported format?",filename); return dest; } /* * Init_Sprite() - Load in a single sprite, called by SCRIPT.CPP */ long Init_Sprite(int number) { // Call the generic image loader to get the image SPlist[number].image=LoadRLEImage(SPlist[number].fname, &SPlist[number].thumbcol); // Now store the width and height of the sprite in the pool SPlist[number].w=SPlist[number].image->w; SPlist[number].h=SPlist[number].image->h; // This is the width times the height, for fast access later SPlist[number].wxh=SPlist[number].w*SPlist[number].h; Plot(0); /* Return image size in bytes (this depends on the implementation of the sprite structure, so if it breaks later on if the API changes, just return width*height, or 1..) */ return SPlist[number].image->size; } /* * Init_RoofTile() - Load in a single sprite, called by SCRIPT.CC */ long Init_RoofTile(int number) { // Call the generic image loader to get the image RTlist[number].image=LoadRLEImage(RTlist[number].fname, NULL); // Now store the width and height of the sprite in the pool RTlist[number].w=RTlist[number].image->w; RTlist[number].h=RTlist[number].image->h; // This is the width times the height, for fast access later RTlist[number].wxh=RTlist[number].w*RTlist[number].h; // Write a dot for this image. This Plot was set up in script.cc Plot(0); /* Return image size in bytes (this depends on the implementation of the sprite structure, so if it breaks later on if the API changes, just return width*height, or 1..) */ return RTlist[number].image->size; } /* * Init_LightMap() - Load in a single sprite, called by SCRIPT.CC */ long Init_LightMap(int number) { char filename[1024]; if(!loadfile(LTlist[number].fname,filename)) ithe_panic("Could not load lightmap image: (file not found)",LTlist[number].fname); LTlist[number].image = load_lightmap(filename); if(!LTlist[number].image) ithe_panic("Could not load image: unsupported format?",filename); Plot(0); return 1; } /* * find_spr() - find the address of a sprite by its name */ S_POOL *find_spr(char *name) { int cx; for(cx=0;cxname); // Find the given USE function in the VRM list and put it in the Ucache str = o->funcs->use; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("use: Did not find function '%s'. Ignoring\n",str); o->funcs->ucache = -1; if(rebuild) { o->funcs->ucache = CHlist[objtype].funcs->ucache; strcpy(o->funcs->use,CHlist[objtype].funcs->use); } } else o->funcs->ucache = tmp; } else { o->funcs->ucache = -1; } // Find a STAND function in the VRM list and put it in the Scache // Switch off the trigger bit if none found str = o->funcs->stand; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("stand: Did not find function '%s'. Ignoring\n",str); o->funcs->scache = -1; if(rebuild) { o->funcs->scache = CHlist[objtype].funcs->scache; strcpy(o->funcs->stand,CHlist[objtype].funcs->stand); } else o->flags.trigger = 0; } else o->funcs->scache = tmp; } else o->flags.trigger = 0; // Find the given LOOK function in the VRM list and put it in the Lcache str = o->funcs->look; if(str[0]) { tmp = getnum4PE(str); if(tmp==UNDEFINED) { Bug("look: Did not find function '%s'. Ignoring\n",str); o->funcs->lcache = -1; if(rebuild) { o->funcs->lcache = CHlist[objtype].funcs->lcache; strcpy(o->funcs->look,CHlist[objtype].funcs->look); } } else o->funcs->lcache = tmp; } else o->funcs->lcache = -1; // Find the given KILLED function in the VRM list and put it in the Kcache // If none, the engine will just vanish the dead thing str = o->funcs->kill; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("kill: Did not find function '%s'. Ignoring\n",str); o->funcs->kcache = -1; if(rebuild) { o->funcs->kcache = CHlist[objtype].funcs->kcache; strcpy(o->funcs->kill,CHlist[objtype].funcs->kill); } } else o->funcs->kcache = tmp; } else o->funcs->kcache = -1; // Find the given HURT function in the VRM list and put it in the Hcache str = o->funcs->hurt; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("hurt: Did not find function '%s'. Ignoring\n",str); o->funcs->hcache = -1; if(rebuild) { o->funcs->hcache = CHlist[objtype].funcs->hcache; strcpy(o->funcs->hurt,CHlist[objtype].funcs->hurt); } } else o->funcs->hcache = tmp; } else o->funcs->hcache = -1; // Find the given WIELD function in the VRM list and put it in the Wcache str = o->funcs->wield; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("wield: Did not find function '%s'. Ignoring\n",str); o->funcs->wcache = -1; if(rebuild) { o->funcs->wcache = CHlist[objtype].funcs->wcache; strcpy(o->funcs->wield,CHlist[objtype].funcs->wield); } } else o->funcs->wcache = tmp; } else o->funcs->wcache = -1; // Find the given INIT function in the VRM list and put it in the Icache str = o->funcs->init; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("init: Did not find function '%s'. Ignoring\n",str); o->funcs->icache = -1; if(rebuild) { o->funcs->icache = CHlist[objtype].funcs->icache; strcpy(o->funcs->init,CHlist[objtype].funcs->init); } } else o->funcs->icache = tmp; } else o->funcs->icache = -1; // Find an ATTACK function in the VRM list and put it in the Acache str = o->funcs->attack; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("attack: Did not find function '%s'. Ignoring\n",str); o->funcs->acache = -1; if(rebuild) { o->funcs->acache = CHlist[objtype].funcs->acache; strcpy(o->funcs->attack,CHlist[objtype].funcs->attack); } } else o->funcs->acache = tmp; } else o->funcs->acache = -1; // Find the given HORROR function in the VRM list and put it in the HRcache str = o->funcs->horror; if(str[0]) { tmp = getnum4PE(str); if(tmp == UNDEFINED) { Bug("horror: Did not find function '%s'. Ignoring\n",str); o->funcs->hrcache = -1; if(rebuild) { o->funcs->hrcache = CHlist[objtype].funcs->hrcache; strcpy(o->funcs->horror,CHlist[objtype].funcs->horror); } } else o->funcs->hrcache = tmp; } else o->funcs->hrcache = -1; // Find the given Quantity Change function in the VRM list and put it in the HRcache str = o->funcs->quantity; if(str[0]) { tmp = getnum4PE(str); if(tmp==UNDEFINED) { Bug("look: Did not find function '%s'. Ignoring\n",str); o->funcs->qcache = -1; if(rebuild) { o->funcs->qcache = CHlist[objtype].funcs->qcache; strcpy(o->funcs->quantity,CHlist[objtype].funcs->quantity); } } else o->funcs->qcache = tmp; } else o->funcs->qcache = -1; } /* * calculate the size of a large object based on ideal values */ void Init_Areas(OBJECT *objsel) { objsel->flags.large=0; // Assume it's only 1 square // First the vertical objsel->w = SQlist[objsel->dir[CHAR_D]].seq[0]->w; objsel->h = SQlist[objsel->dir[CHAR_D]].seq[0]->h; // Set up the size in tiles objsel->mw = objsel->w>>5; if(objsel->w & 0x1f || !objsel->mw) objsel->mw++; objsel->mh = objsel->h>>5; if(objsel->h & 0x1f || !objsel->mh) objsel->mh++; if(objsel->mh>1 || objsel->mw>1) // If it's bigger than 1 square.. objsel->flags.large=1; // Set up verticals if(objsel->varea[BLK_W] == 0) { objsel->varea[BLK_W]=objsel->mw; objsel->varea[BLK_X]=0; } if(objsel->varea[BLK_H] == 0) { objsel->varea[BLK_H]=objsel->mh; objsel->varea[BLK_Y]=0; } if(objsel->vblock[BLK_W] == 0) { objsel->vblock[BLK_W]=objsel->mw; objsel->vblock[BLK_X]=0; } if(objsel->vblock[BLK_H] == 0) { objsel->vblock[BLK_H]=objsel->mh; objsel->vblock[BLK_Y]=0; } // Then the horizontal objsel->w = SQlist[objsel->dir[CHAR_R]].seq[0]->w; objsel->h = SQlist[objsel->dir[CHAR_R]].seq[0]->h; // Set up the size in tiles objsel->mw = objsel->w>>5; if(objsel->w & 0x1f || !objsel->mw) objsel->mw++; objsel->mh = objsel->h>>5; if(objsel->h & 0x1f || !objsel->mh) objsel->mh++; // Just to make sure if(objsel->mh>1 || objsel->mw>1) // If it's bigger than 1 square.. objsel->flags.large=1; // Set up horizontals if(objsel->harea[BLK_W] == 0) { objsel->harea[BLK_W]=objsel->mw; objsel->harea[BLK_X]=0; } if(objsel->harea[BLK_H] == 0) { objsel->harea[BLK_H]=objsel->mh; objsel->harea[BLK_Y]=0; } if(objsel->hblock[BLK_W] == 0) { objsel->hblock[BLK_W]=objsel->mw; objsel->hblock[BLK_X]=0; } if(objsel->hblock[BLK_H] == 0) { objsel->hblock[BLK_H]=objsel->mh; objsel->hblock[BLK_Y]=0; } } /* * recalculate current size of a large object from current direction */ void CalcSize(OBJECT *objsel) { if(!objsel->flags.large) // Don't bother for small object return; objsel->w = SQlist[objsel->dir[objsel->curdir]].seq[0]->w; objsel->h = SQlist[objsel->dir[objsel->curdir]].seq[0]->h; // Set up the size in tiles objsel->mw = objsel->w>>5; if(objsel->w & 0x1f || !objsel->mw) objsel->mw++; objsel->mh = objsel->h>>5; if(objsel->h & 0x1f || !objsel->mh) objsel->mh++; } /* * Getnum4char - Find the index of the character in the CHlist array */ int getnum4char_slow(char *name) { int ctr; if(!name) return -1; for(ctr=0;ctrname,((search_st *)b)->name); } static int CMP_search(const void *a,const void *b) { return istricmp((char *)a,((search_st *)b)->name); } static int CMP_search_DTI(const void *a,const void *b) { return (int)((long)a-((DT_ITEM*)b)->ki); } static int CMP_search_DTS(const void *a,const void *b) { return istricmp((char *)a,((DT_ITEM*)b)->ks); } // // Build ordered lists for quick searching // void Init_Lookups() { int ctr; ilog_quiet("Init lookups\n"); if(SPtot < 1) ithe_panic("No sprites","Init_Lookups"); if(SQtot < 1) ithe_panic("No sequences","Init_Lookups"); if(CHtot < 1) ithe_panic("No characters","Init_Lookups"); //if(PEtot < 1) // ithe_panic("No scripts","Init_Lookups"); // Sprites sprites = (search_st *)M_get(SPtot+1,sizeof(search_st)); for(ctr=0;ctr 0) { scripts = (search_st *)M_get(PEtot+1,sizeof(search_st)); for(ctr=0;ctrnum; return -1; } /* * Getnum4tile- Find the index of the tile in the TIlist array */ int getnum4tile(char *name) { int ctr; for(ctr=0;ctrnum].hidden) { Bug("PE script '%s' is local.. can't call it directly\n",name); return -1; } return p->num; } return -1; } /* * Getnum4sprite - Find the index of the sequence in the SPlist array */ int getnum4sprite(char *name) { search_st *p; p = FIND(name,sprites,SPtot); if(p) return p->num; return -1; } /* * Getnum4sequence - Find the index of the sequence in the SQlist array */ int getnum4sequence(char *name) { search_st *p; p = FIND(name,sequences,SQtot); if(p) return p->num; return -1; } /* * Getnum4table - Find the index of the table in the DTlist array */ int getnum4table(char *name) { search_st *p; if(DTtot<1) return -1; p = FIND(name,tables,DTtot); if(p) return p->num; return -1; } /* * Return a pointer to a data item in a table specified by its index * by searching the table for a string */ DT_ITEM *GetTableNum_s(int table,char *name) { if(DTtot<1) return NULL; return bsearch(name,DTlist[table].list,DTlist[table].entries,sizeof(DT_ITEM),CMP_search_DTS); } /* * Return a pointer to a data item in a table specified by its name * by searching the table for a string */ DT_ITEM *GetTableName_s(char *tablename,char *name) { int table; table = getnum4table(tablename); if(table < 0) { Bug("Get_Data: Cannot find table called '%s' in section: tables\n",tablename); return NULL; } return bsearch(name,DTlist[table].list,DTlist[table].entries,sizeof(DT_ITEM),CMP_search_DTS); } /* * Return a pointer to a data item in a table specified by its index * by searching the table for a number */ DT_ITEM *GetTableNum_i(int table,int num) { if(DTtot<1) return NULL; if(table < 0) return NULL; return bsearch((void *)num,DTlist[table].list,DTlist[table].entries,sizeof(DT_ITEM),CMP_search_DTI); } /* * Return a pointer to a data item in a table specified by its name * by searching the table for a string */ DT_ITEM *GetTableName_i(char *tablename, int num) { int table; table = getnum4table(tablename); if(table == -1) return NULL; return bsearch((void *)num,DTlist[table].list,DTlist[table].entries,sizeof(DT_ITEM),CMP_search_DTI); } /* * Return a pointer to a data item in a table specified by its name * by searching the table for a string. This is a case-sensitive search */ DT_ITEM *GetTableCase(char *tablename,char *name) { int table,ctr; table = getnum4table(tablename); if(table < 0) { Bug("Get_Data: Cannot find table called '%s' in section: tables\n",tablename); return NULL; } // Make sure table datatypes are as expected if(DTlist[table].keytype != 's' || DTlist[table].listtype != 's') return NULL; for(ctr=0;ctrQRAND_MAX) qptr=0; return qrt[qptr]; } /* * Initialise quick random number generator */ void qrand_init() { int ctr; for(ctr=0;ctrw/2)+1,(b->h/2)+1); }