mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-15 18:56:41 -04:00
542 lines
12 KiB
C
542 lines
12 KiB
C
#include <skeldal_win.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <memman.h>
|
|
#include <types.h>
|
|
#include <mem.h>
|
|
#include <bgraph.h>
|
|
#include <event.h>
|
|
#include <devices.h>
|
|
#include <bmouse.h>
|
|
#include <gui.h>
|
|
#include <basicobj.h>
|
|
#include <strlists.h>
|
|
#include <strlite.h>
|
|
#include "steny.h"
|
|
#include "globals.h"
|
|
|
|
#define WLISTX 200
|
|
#define WLISTY 200
|
|
|
|
#define DELETED "*(deleted)"
|
|
#define EMPTY "EMPTY.PCX"
|
|
#define ANIM "*frame"
|
|
|
|
TSTR_LIST side_names=NULL;
|
|
TSTR_LIST floors=NULL;
|
|
TSTR_LIST ceils=NULL;
|
|
TSTR_LIST oblouky=NULL;
|
|
TSTR_LIST dlg_names=NULL;
|
|
TSTR_LIST weapons=NULL;
|
|
TSTR_LIST weapons_pos=NULL;
|
|
|
|
int *dlg_pgfs=NULL;
|
|
|
|
void read_side_list(char *filename,TSTR_LIST *outpt,int relative,int structlen)
|
|
{
|
|
char i,j;
|
|
FILE *f;
|
|
char s[200];
|
|
|
|
|
|
if (*outpt!=NULL) release_list(*outpt);
|
|
*outpt=create_list(1);
|
|
str_replace(outpt,0,"<nic>");
|
|
f=fopen(filename,"r");
|
|
if (f==NULL) return;
|
|
i=1;j=0;
|
|
while (relative)
|
|
{
|
|
fscanf(f,"%s",&s);relative--;
|
|
}
|
|
do
|
|
{
|
|
if (fscanf(f,"%s",&s)==1 && (!j)) str_replace(outpt,i++,s);
|
|
j++;
|
|
if (j==structlen) j=0;
|
|
}
|
|
while (!feof(f));
|
|
fclose(f);
|
|
str_delfreelines(outpt);
|
|
j=str_count(*outpt);
|
|
for(i=0;i<j;i++) if ((*outpt)[i]!=NULL && (*outpt)[i][0]=='*') str_replace(outpt,i,NULL);
|
|
}
|
|
|
|
void strlist_init(OBJREC *o,void **strtable)
|
|
{
|
|
o->userptr=(void *)getmem(16);
|
|
memcpy(o->userptr,strtable,4);
|
|
}
|
|
|
|
|
|
void read_dlg_list(char *filename,TSTR_LIST *outpt,int **nums)
|
|
{
|
|
FILE *f;
|
|
char s[200];
|
|
int i,j,k;
|
|
|
|
f=fopen(filename,"r");
|
|
i=0;
|
|
if (*outpt!=NULL) release_list(*outpt);
|
|
*outpt=create_list(1);
|
|
str_replace(outpt,0," <nic>");
|
|
if (f==NULL) return;
|
|
do
|
|
{
|
|
if (fgets(s,199,f)==NULL) break;
|
|
str_replace(outpt,i++,s);
|
|
}
|
|
while (!feof(f));
|
|
fclose(f);
|
|
if (*nums!=NULL) free(*nums);
|
|
k=str_count(*outpt);
|
|
*nums=(int *)getmem(sizeof(int)*k);
|
|
for(j=0;j<i;j++) if ((*outpt)[j]!=NULL)
|
|
sscanf((*outpt)[j],"%d %[^\0]",*nums+j,(*outpt)[j]);
|
|
}
|
|
|
|
int pgf2name(int num)
|
|
{
|
|
int lcount;
|
|
int i;
|
|
|
|
lcount=str_count(dlg_names);
|
|
for(i=0;i<lcount;i++) if (dlg_names[i]!=NULL && dlg_pgfs[i]==num) break;
|
|
if (i==lcount) i=0;
|
|
return i;
|
|
}
|
|
|
|
|
|
void strlist_draw(int x1,int y1,int x2,int y2,OBJREC *o)
|
|
{
|
|
t_side_names *table,**t;
|
|
int *d,i;
|
|
|
|
d=(int *)o->data;
|
|
t=(t_side_names **)o->userptr;
|
|
table=*t;
|
|
bar(x1,y1,x2,y2);
|
|
for (i=0;i<*d;i++)
|
|
if (!strcmp((*table)[i],"\\")) return;
|
|
i=*d;
|
|
while (y1+text_height((*table)[i])<y2 && strcmp((*table)[i],"\\"))
|
|
{
|
|
char s[100];
|
|
strcpy(s,(*table)[i]);
|
|
while (text_width(s)>o->xs)
|
|
{
|
|
char *t;
|
|
|
|
t=strchr(s,'\0');
|
|
*(--t)='\0';
|
|
}
|
|
position(x1,y1);
|
|
outtext(s);
|
|
y1+=text_height(*table);
|
|
i++;
|
|
}
|
|
}
|
|
void strlist_event(EVENT_MSG *msg,OBJREC *o)
|
|
{
|
|
t_side_names *table,**t;
|
|
int *d,i;
|
|
|
|
d=(int *)o->data;
|
|
t=(t_side_names **)o->userptr;
|
|
table=*t;
|
|
if (msg->msg==E_MOUSE)
|
|
{
|
|
MS_EVENT *ms;
|
|
|
|
ms=get_mouse(msg);
|
|
if (ms->event_type & 4)
|
|
{
|
|
int y1=0;
|
|
|
|
i=*d;
|
|
while (y1+text_height((*table)[i])<(ms->y-o->locy))
|
|
{
|
|
if (!strcmp((*table)[i],"\\")) return;
|
|
y1+=text_height(*table);
|
|
i++;
|
|
}
|
|
*d=i;
|
|
terminate_gui();
|
|
}
|
|
}
|
|
if (msg->msg==E_CONTROL)
|
|
{
|
|
memcpy(o->userptr,msg->data,4);
|
|
redraw_object(o);
|
|
}
|
|
}
|
|
|
|
|
|
void strlist(OBJREC *o)
|
|
{
|
|
o->call_init=strlist_init;
|
|
o->call_draw=strlist_draw;
|
|
o->call_event=strlist_event;
|
|
o->datasize=4;
|
|
|
|
}
|
|
|
|
void strlist_scroll()
|
|
{
|
|
c_set_value(0,10,f_get_value(0,20));
|
|
}
|
|
|
|
int strlist_count(char *s)
|
|
{
|
|
int i;
|
|
|
|
i=0;
|
|
while (strcmp(s,"\\")) i++,s+=T_LIST_SIZE;
|
|
return i;
|
|
}
|
|
|
|
TSTR_LIST build_static_list(char *c)
|
|
{
|
|
TSTR_LIST e;
|
|
int i=0;
|
|
|
|
e=create_list(10);
|
|
while (c[0]!='\\')
|
|
{
|
|
str_replace(&e,i,c);
|
|
c=strchr(c,0);
|
|
c++;i++;
|
|
}
|
|
str_delfreelines(&e);
|
|
return e;
|
|
}
|
|
|
|
|
|
int string_list(char *c,int akt)
|
|
{
|
|
int oldid;
|
|
int x1,y1;
|
|
CTL3D *ctl;
|
|
FC_TABLE cl;
|
|
int vysl;
|
|
|
|
cl[0]=0;cl[1]=0x610;
|
|
ctl=def_border(3,WINCOLOR);
|
|
oldid=o_aktual->id;
|
|
x1=o_aktual->locx;
|
|
y1=o_aktual->locy+o_aktual->ys;
|
|
if (y1+WLISTY>desktop_y_size) y1=desktop_y_size-WLISTY;
|
|
if (x1+WLISTX+4>SCR_WIDTH_X) x1=SCR_WIDTH_X-WLISTX-4;
|
|
def_window(WLISTX,WLISTY,"Vyber");
|
|
waktual->x=x1;
|
|
waktual->y=y1;
|
|
on_control_change(terminate_gui);
|
|
set_window_modal();
|
|
define(19,5,20,WLISTX-30,WLISTY-20,0,listbox,c,RGB555(31,31,31),0);c_default(akt);
|
|
on_control_change(terminate_gui);
|
|
define(20,3,42,17,WLISTY-64,1,scroll_bar_v,0,1,18,SCROLLBARCOL);
|
|
property(ctl,NULL,NULL,WINCOLOR);c_default(0);
|
|
define(21,1,20,21,17,1,scroll_button,-1,0,"\x1e");
|
|
property(NULL,icones,&cl,WINCOLOR);on_control_change(scroll_support);
|
|
define(22,1,1,21,17,2,scroll_button,1,1,"\x1f");
|
|
property(NULL,icones,&cl,WINCOLOR);on_control_change(scroll_support);
|
|
redraw_window();
|
|
send_message(E_GUI,19,E_CONTROL,2);
|
|
redraw_window();
|
|
goto_control(19);
|
|
escape();
|
|
if (o_aktual->id==19) vysl=f_get_value(0,19); else vysl=-1;
|
|
close_window(waktual);
|
|
return vysl;
|
|
}
|
|
|
|
char find_nick(FILE *f,char *nick)
|
|
{
|
|
char rn[5];
|
|
int i;
|
|
|
|
do
|
|
{
|
|
i=fscanf(f,"%3s",rn);
|
|
if (i==EOF) return 1;
|
|
while (i!=EOF && i!='{') i=fgetc(f);
|
|
if (!strcmp(rn,nick)) return 0;
|
|
do
|
|
{
|
|
while (i!=EOF && i>=' ') i=fgetc(f);
|
|
while (i!=EOF && i<=' ') i=fgetc(f);
|
|
}
|
|
while (i!=EOF && i!='}');
|
|
}
|
|
while (i!=EOF);
|
|
return 1;
|
|
}
|
|
|
|
void read_side_script_one(char *filename,char *nick,TSTR_LIST *outpt,int relative,int structlen)
|
|
{
|
|
char i,j;
|
|
FILE *f;
|
|
char s[200],end=0;
|
|
|
|
if (*outpt!=NULL) release_list(*outpt);
|
|
*outpt=create_list(1);
|
|
str_replace(outpt,0,"<nic>");
|
|
f=fopen(filename,"r");
|
|
if (f==NULL) return;
|
|
if (find_nick(f,nick))
|
|
{
|
|
fclose(f);
|
|
return;
|
|
}
|
|
i=1;j=0;
|
|
while (relative && !end)
|
|
{
|
|
fscanf(f,"%s",s);relative--;
|
|
if (s[0]=='}') end=1;
|
|
}
|
|
if (!end)
|
|
do
|
|
{
|
|
if (fscanf(f,"%s",s)==1 && (!j) && s[0]!='}') str_replace(outpt,i++,s);
|
|
if (s[0]=='}') end=1;
|
|
j++;
|
|
if (j==structlen) j=0;
|
|
}
|
|
while (!feof(f) && !end);
|
|
fclose(f);
|
|
str_delfreelines(outpt);
|
|
j=str_count(*outpt);
|
|
for(i=0;i<j;i++) if ((*outpt)[i]!=NULL && (*outpt)[i][0]=='*') str_replace(outpt,i,NULL);
|
|
}
|
|
|
|
void read_full_side_script(char *filename)
|
|
{
|
|
read_side_script_one(filename,NSID,&side_names,0,4);
|
|
read_side_script_one(filename,NFLR,&floors,0,2);
|
|
read_side_script_one(filename,NCEI,&ceils,0,2);
|
|
read_side_script_one(filename,NOBL,&oblouky,0,3);
|
|
}
|
|
|
|
void read_spec_procs()
|
|
{
|
|
read_side_script_one("specproc.lst","WAL",&wall_procs,0,1);
|
|
read_side_script_one("specproc.lst","MOB",&mob_procs,0,1);
|
|
}
|
|
|
|
static TSTR_LIST sid[4]={NULL};
|
|
static TSTR_LIST flr[2]={NULL};
|
|
static TSTR_LIST cei[2]={NULL};
|
|
static TSTR_LIST obl[3]={NULL};
|
|
|
|
|
|
static void scan_section_script(FILE *f,int count,TSTR_LIST *ls)
|
|
{
|
|
char s[200];
|
|
int i;
|
|
int j;
|
|
|
|
for(i=0;i<count;i++) ls[i]=create_list(256);
|
|
i=0;j=0;
|
|
do
|
|
{
|
|
fscanf(f,"%s",s);
|
|
if (s[0]=='}') break;
|
|
str_replace(ls+i,j,s);
|
|
i++;if (i>=count) i=0,j++;
|
|
}
|
|
while(1);
|
|
}
|
|
|
|
|
|
void load_side_script(char *filename)
|
|
{
|
|
FILE *f;
|
|
int i;
|
|
|
|
if (sid[0]!=NULL) for(i=0;i<4;i++) release_list(sid[i]);
|
|
if (flr[0]!=NULL) for(i=0;i<2;i++) release_list(flr[i]);
|
|
if (cei[0]!=NULL) for(i=0;i<2;i++) release_list(cei[i]);
|
|
if (obl[0]!=NULL) for(i=0;i<3;i++) release_list(obl[i]);
|
|
f=script_name==NULL?NULL:fopen(filename,"r");
|
|
if (f!=NULL)
|
|
{
|
|
fseek(f,0,SEEK_SET);if (!find_nick(f,NSID)) scan_section_script(f,4,sid);
|
|
fseek(f,0,SEEK_SET);if (!find_nick(f,NFLR)) scan_section_script(f,2,flr);
|
|
fseek(f,0,SEEK_SET);if (!find_nick(f,NCEI)) scan_section_script(f,2,cei);
|
|
fseek(f,0,SEEK_SET);if (!find_nick(f,NOBL)) scan_section_script(f,3,obl);
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
static int add_to_script(TSTR_LIST *ls,char *name,int frames,int count,int max)
|
|
{
|
|
int cnt;
|
|
int i,a,f,j;
|
|
char *c,*d;
|
|
|
|
if (ls[0]==NULL)
|
|
{
|
|
for(i=0;i<count;i++) ls[i]=create_list(256);
|
|
f=0;
|
|
}
|
|
else
|
|
{
|
|
cnt=str_count(ls[0]);
|
|
i=0,a=0;f=-1;
|
|
while (a<frames)
|
|
{
|
|
if (i>=cnt || ls[0][i]==NULL || !strcmp(ls[0][i],DELETED)) a++,f=i;
|
|
else a=0;
|
|
i++;
|
|
}
|
|
}
|
|
if (f+frames>max) return -1;
|
|
c=alloca(strlen(name)+20);
|
|
if (frames>1) sprintf(c,"%s(%d)",name,frames);else strcpy(c,name);
|
|
for (d=c;*d;d++) if (*d<=' ') *d='_';
|
|
str_replace(ls,f,c);for(i=1;i<count;i++) str_replace(ls+i,f,EMPTY);
|
|
for (j=1;j<frames;j++)
|
|
{
|
|
str_replace(ls,f+j,ANIM);for(i=1;i<count;i++) str_replace(ls+i,f+j,EMPTY);
|
|
}
|
|
return f;
|
|
}
|
|
|
|
|
|
int change_side(int script,int side,int pos,int frame,char *new)
|
|
{
|
|
TSTR_LIST ls;
|
|
|
|
side+=frame;
|
|
if (pos==0) return -1;
|
|
switch (script)
|
|
{
|
|
case 0: ls=sid[0];if (ls==NULL) return -2;
|
|
if (pos & 1) str_replace(sid+1,side,new);
|
|
if (pos & 2) str_replace(sid+2,side,new);
|
|
if (pos & 4) str_replace(sid+3,side,new);
|
|
break;
|
|
case 1: ls=flr[0];if (ls==NULL) return -2;
|
|
if (pos!=1) return -1;
|
|
str_replace(flr+1,side,new);
|
|
break;
|
|
case 2: ls=cei[0];if (ls==NULL) return -2;
|
|
if (pos!=1) return -1;
|
|
str_replace(cei+1,side,new);
|
|
break;
|
|
case 3: ls=obl[0];if (ls==NULL) return -2;
|
|
if (pos & 1) return -1;
|
|
if (pos & 2) str_replace(obl+1,side,new);
|
|
if (pos & 4) str_replace(obl+2,side,new);
|
|
break;
|
|
default: return -3;
|
|
}
|
|
side++;
|
|
if (side>=str_count(ls) || ls[side]==NULL || strcmp(ls[side],ANIM)) return 0;
|
|
return 1;
|
|
}
|
|
|
|
static int delete_side_st(TSTR_LIST *ls,int pos,int count)
|
|
{
|
|
int cnt,i;
|
|
|
|
if (ls[0]==NULL) return -1;
|
|
cnt=str_count(ls[0]);
|
|
do
|
|
{
|
|
for(i=0;i<count;i++) str_replace(ls+i,pos,i==0?DELETED:EMPTY);
|
|
pos++;
|
|
}
|
|
while (pos<cnt && ls[0][pos]!=NULL && !strcmp(ls[0][pos],ANIM));
|
|
cnt=str_count(ls[0]);
|
|
while (cnt>0 && (ls[0][cnt-1]==NULL || !strcmp(ls[0][cnt-1],DELETED)))
|
|
{
|
|
cnt--;
|
|
str_replace(ls,cnt,NULL);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int delete_side(int list,int pos)
|
|
{
|
|
switch (list)
|
|
{
|
|
case 0: return delete_side_st(sid,pos,4);break;
|
|
case 1: return delete_side_st(flr,pos,2);break;
|
|
case 2: return delete_side_st(cei,pos,2);break;
|
|
case 3: return delete_side_st(obl,pos,3);break;
|
|
default: return -1;
|
|
}
|
|
}
|
|
|
|
int add_side(int list,char *name,int frames)
|
|
{
|
|
switch (list)
|
|
{
|
|
case 0: return add_to_script(sid,name,frames,4,256);break;
|
|
case 1: return add_to_script(flr,name,frames,2,256);break;
|
|
case 2: return add_to_script(cei,name,frames,2,256);break;
|
|
case 3: return add_to_script(obl,name,frames,3,16);break;
|
|
default: return -1;
|
|
}
|
|
}
|
|
|
|
char *get_side_name(int list,int pos,int field)
|
|
{
|
|
char **res=NULL;
|
|
switch (list)
|
|
{
|
|
case 0: res=sid[field];break;
|
|
case 1: res=flr[field];break;
|
|
case 2: res=cei[field];break;
|
|
case 3: res=obl[field];break;
|
|
default: return NULL;
|
|
}
|
|
if (res==NULL) return NULL;
|
|
return res[pos];
|
|
}
|
|
|
|
|
|
|
|
void save_section_script(FILE *f,TSTR_LIST *ls,int count)
|
|
{
|
|
int i,j,cnt;
|
|
|
|
cnt=str_count(ls[0]);
|
|
for (j=0;j<cnt;j++)
|
|
if (ls[0][j]!=NULL)
|
|
for (i=0;i<count;i++)
|
|
{
|
|
fprintf(f,"%s",ls[i][j]);
|
|
if (i+1==count) fputc('\n',f);else fputc(' ',f);
|
|
}
|
|
}
|
|
|
|
void save_side_script(char *filename)
|
|
{
|
|
FILE *f;
|
|
int i;
|
|
|
|
f=fopen(filename,"w");
|
|
if (sid[0]!=NULL){fputs(NSID"\n{\n",f);save_section_script(f,sid,4);fputs("}\n\n",f);}
|
|
if (flr[0]!=NULL){fputs(NFLR"\n{\n",f);save_section_script(f,flr,2);fputs("}\n\n",f);}
|
|
if (cei[0]!=NULL){fputs(NCEI"\n{\n",f);save_section_script(f,cei,2);fputs("}\n\n",f);}
|
|
if (obl[0]!=NULL){fputs(NOBL"\n{\n",f);save_section_script(f,obl,3);fputs("}\n\n",f);}
|
|
fclose(f);
|
|
read_full_side_script(filename);
|
|
for(i=0;i<4;i++) release_list(sid[i]),sid[i]=NULL;
|
|
for(i=0;i<2;i++) release_list(flr[i]),flr[i]=NULL;
|
|
for(i=0;i<2;i++) release_list(cei[i]),cei[i]=NULL;
|
|
for(i=0;i<3;i++) release_list(obl[i]),obl[i]=NULL;
|
|
}
|
|
|
|
void discharge_side_script()
|
|
{
|
|
int i;
|
|
for(i=0;i<4;i++) release_list(sid[i]),sid[i]=NULL;
|
|
for(i=0;i<2;i++) release_list(flr[i]),flr[i]=NULL;
|
|
for(i=0;i<2;i++) release_list(cei[i]),cei[i]=NULL;
|
|
for(i=0;i<3;i++) release_list(obl[i]),obl[i]=NULL;
|
|
}
|