gates_of_skeldal/MAPS/CDIALOGY.C
2025-01-24 18:27:22 +01:00

585 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ctype.h>
#include <windows.h>
#define P_STRING 1
#define P_SHORT 2
#define P_VAR 3
#define TEMP_NAME1 "cdialogy.$$$"
#define SCRIPT "dialogy.scr"
typedef struct t_paragraph
{
unsigned num:15;
unsigned alt:15;
unsigned visited:1;
unsigned first:1;
long position;
}T_PARAGRAPH;
char *pgf_name=NULL;
T_PARAGRAPH *pgf_list=NULL;
int pgf_count=0;
char *program;
int prog_size=0;
int prog_pos=0;
int last_pgf;
int sentencs=0;
int libs=0;
FILE *f;
FILE *mlist;
#define newline(f) {int c;while ((c=fgetc(f))!='\n' && c!=EOF);}
#define get_cislo(f,cislo) fscanf(f,"%d",cislo);newline(f)
#define get_command(f,cislo) fscanf(f,"%c%d",cislo,cislo);newline(f)
static int basic_num;
static int abs_num;
static int last_dialoge;
static int standard_jump;
static char sentence;
static char sub_mode,b_closed=1;
static int open_level=0;
static int iff_mode=0;
static char was_sub=0;
#define IF_JUMP 1
#define IF_NOT_JUMP 2
#define IF_ELSE 3
typedef struct if_record
{
int level;
int pointer;
}IF_RECORD;
int if_ptr=0;
#define IF_LEN 32
static IF_RECORD if_data[IF_LEN];
int init(char *c)
{
prog_size=163840;
prog_pos=0;
program=malloc(prog_size);
f=fopen(c,"rt");
if (f==NULL) return 1;
return 0;
}
void error(char *c)
{
printf("%s v odstavci %d (Dialog %d Sentence %d).",c,last_pgf,basic_num/128,last_pgf);
exit(1);
}
void resize(void **p,int newsize)
{
void *q;
if (*p==NULL) q=malloc(newsize);else
{
q=malloc(newsize);
if (q!=NULL)
{
memcpy(q,*p,_msize(*p));
free(*p);
}
}
if (q==NULL)
{
puts("Nedostatek pamØti");
exit(1);
}
*p=q;
}
void check_prog_space(int num)
{
if (prog_pos+num>prog_size-16)
{
prog_size+=163840;
resize(&program,prog_size);
}
}
void add_byte(char byte)
{
check_prog_space(1);
program[prog_pos++]=byte;
}
void add_short(short i)
{
add_byte(P_SHORT);
check_prog_space(2);
*(short*)(program+prog_pos++)=i;
prog_pos++;
}
void add_var(short i)
{
add_byte(P_VAR);
check_prog_space(2);
*(short*)(program+prog_pos++)=i;
prog_pos++;
}
void copy_short(FILE *f)
{
int c;
int i;
c=fgetc(f);
if (c=='&')
{
get_cislo(f,&i);
add_var(i);
}
else
{
if (isdigit(c)) ungetc(c,f);
get_cislo(f,&i);
add_short(i);
}
}
void add_string(char *c)
{
add_byte(P_STRING);
check_prog_space(strlen(c)+1);
while (*c && *c!='\n') program[prog_pos++]=*c++;
program[prog_pos++]=0;
}
void add_pgf(T_PARAGRAPH *p)
{
resize(&pgf_list,sizeof(*p)*(pgf_count+1));
memcpy(pgf_list+pgf_count,p,sizeof(*p));
pgf_list[pgf_count].position=prog_pos;
pgf_list[pgf_count].visited=0;
pgf_list[pgf_count].first=0;
if (pgf_name!=NULL)
{
fprintf(mlist,"%6d %s\n",pgf_list[pgf_count].num,pgf_name);
free(pgf_name);
pgf_name=NULL;
}
pgf_count++;
}
void decode_pgf1(char *c) //c je text bez vykricniku
{
int pn,an,i;
T_PARAGRAPH p;
char relative=0;
if (*c=='!')
{
relative=1;
c++;
}
i=sscanf(c,"%d",&pn);
if (relative) pn+=abs_num;else abs_num=pn;
if (i!=1) error("Chybn pou§it¡ znaku \"!\"");
last_pgf=pn;
c=strchr(c,',');
if (c==NULL) an=pn;
else
{
c++;
i=sscanf(c,"%d",&an);
if (i!=1) error("OŸek v  se Ÿ¡slo alternativn¡ho odstavce");
}
p.num=pn;
p.alt=an;
add_pgf(&p);
}
void js_dialoge(FILE *f)
{
int parm1;
T_PARAGRAPH pgf;
if (!b_closed) error("Ocekava se '}' (close_block)");
get_cislo(f,&parm1);
abs_num=basic_num=parm1*128;
pgf.num=basic_num;
pgf.alt=basic_num;
last_dialoge=pgf_count;
last_pgf=0;
add_pgf(&pgf);
get_command(f,&parm1);
if (parm1!=-2) error ("Ocekava se '{' (open_block)");
sentence=0;
b_closed=0;
add_short(167);
add_short(basic_num);
}
void js_first(FILE *f)
{
int parm1;
add_short(166);
add_short(last_pgf);
add_short(140);
get_cislo(f,&parm1);
add_short(parm1);
}
void js_standard(FILE *f)
{
int parm1;
get_cislo(f,&parm1);
if (parm1>0) standard_jump=parm1;else standard_jump=32767+parm1-basic_num;
}
void js_close_block()
{
if (open_level)
{
if (was_sub)
if (sub_mode)
add_short(165);
else
{
add_short(139);
add_short(standard_jump);
}
sub_mode=0;
open_level--;
return;
}
if (b_closed) error("Neocekavany znak '}' (close_block)");
if (sentence && sub_mode) add_short(165);else
{
add_short(139);
add_short(standard_jump);
}
b_closed=1;
}
void js_sentence(FILE *f)
{
int par1,par2;
T_PARAGRAPH pgf;
if (!b_closed || open_level) error("Ocekava se '}' (close_block)");
b_closed=0;
get_cislo(f,&par1);
get_cislo(f,&par2);
sub_mode=par2;
pgf.num=par1+basic_num;
pgf.alt=par1+basic_num;
add_pgf(&pgf);
sentence=1;
last_pgf=par1;
get_command(f,&par1);
if (par1!=-2) error ("Ocekava se '{' (open_block)");
sentencs++;
was_sub=0;
}
void js_sub(FILE *f)
{
int par1;
char *c;
int d;
c=malloc(65536);
d=getc(f);while (d!=EOF && d!='$') d=getc(f);
fgets(c,65536,f);
if (sub_mode)
{
add_short(142);
get_cislo(f,&par1);
if (par1>0) add_short(par1);else add_short(32767+par1-basic_num);
add_string(c);
}
else
{
add_short(148);
add_string(c);
get_cislo(f,&par1);
if (par1>0) standard_jump=par1;else standard_jump=32767+par1-basic_num;
}
free(c);
}
void js_close_sub()
{
was_sub=1;
if (sub_mode)add_short(164); else add_short(144);
}
void save_pgf_name(FILE *f)
{
long l;
int i,s;
l=ftell(f);
for(s=0;(i=fgetc(f))!=EOF && i!='\n';s++);
if (pgf_name!=NULL) free(pgf_name);
pgf_name=(char *)malloc(s+2);
fseek(f,l,SEEK_SET);
fgets(pgf_name,s+1,f);
fgetc(f);
}
void push_level(int level,int pos)
{
if (if_ptr==IF_LEN) error("Priliz dlouha struktura if & else");
if_data[if_ptr].level=level;
if_data[if_ptr].pointer=pos;
if_ptr++;
}
void pop_and_fill(int pos,int level)
{
int i;
int prog_sav;
prog_sav=prog_pos;
while (if_ptr && if_data[if_ptr-1].level==level)
{
if_ptr--;
prog_pos=if_data[if_ptr].pointer;
i=pos-if_data[if_ptr].pointer-3;
if (i>32767 || i<-32767) error("Blok if/else je priliz dlouhy (delsi nez 32767 bytu)");
add_short(i);
}
prog_pos=prog_sav;
}
int get_last_level()
{
if (if_ptr) return if_data[if_ptr-1].level;
else return -1;
}
void add_if_jump()
{
char c=1;
switch(iff_mode)
{
case IF_NOT_JUMP:add_short(169);break;
case IF_JUMP:add_short(170);break;
case IF_ELSE:c=0;break;
}
if (c)
{
push_level(open_level,prog_pos);
add_short(0);
}
iff_mode=0;
was_sub=0;
}
void add_else()
{
int psave,c;
get_command(f,&c);
if (c!=-2) error("Chybn  syntaxe pý¡kazu else. OŸek v  se '{'");
was_sub=0;
if (get_last_level()!=open_level) error("Else bez if");
add_short(171);
psave=prog_pos;
add_short(0);
pop_and_fill(prog_pos,open_level);
push_level(open_level,psave);
open_level++;
}
void set_alternative(FILE *f)
{
int cislo;
get_cislo(f,&cislo);
pgf_list[pgf_count-1].alt=cislo+basic_num;
}
void decode_program(FILE *f)
{
int c;
char next_sub=0;
char *d;
d=(char *)calloc(sizeof(char),16384);
open_level=0;
c=fgetc(f);
while (c!=EOF)
{
if (c=='!')
{
char d[256];
fgets(&d,256,f);
decode_pgf1(d);
}
else if (isdigit(c) || c=='-')
{
int cislo;
ungetc(c,f);
get_cislo(f,&cislo);
add_short(cislo);
}
else if (c=='*')
{
int cislo;
get_cislo(f,&cislo);
if (cislo!=517 && next_sub)
{
js_close_sub();
next_sub=0;
}
if (cislo!=171 && !iff_mode) pop_and_fill(prog_pos,open_level);
switch (cislo)
{
case 512:js_dialoge(f);break; //Sekce DIALOG
case 513:js_first(f);break; //Prikaz FIRST
case 514:add_short(152); //Prikaz WHEN_ITEM
copy_short(f);
add_short(140);
get_cislo(f,&cislo);
if (cislo>0)add_short(cislo);else add_short(cislo+32767-basic_num);
break;
case 515:add_short(163); //prikaz WHEN_FLAG
copy_short(f);
add_short(140);
get_cislo(f,&cislo);
if (cislo>0)add_short(cislo);else add_short(cislo+32767-basic_num);
break;
case 516:js_standard(f);break; //prikaz STANDARD
case 517:js_sub(f);next_sub=1;break; //prikaz SUB
case 520:js_sentence(f);break; //Sekce SENTENCE
case -1:js_close_block();break; //znak }//
case -2: if (iff_mode) add_if_jump();else error("Neocekavany znak '{' (open_block)");
open_level++;
break; //znak {//
case 999:save_pgf_name(f);break;
case 169:if (iff_mode) add_if_jump(); //prikaz if
iff_mode=IF_NOT_JUMP;break;
case 170:if (iff_mode!=IF_NOT_JUMP) error("NOT bez IF"); //modifikator not
iff_mode=IF_JUMP;break;
case 171:if (iff_mode) error("Chybn pou§it¡ pý¡kazu ELSE"); //prikaz else
add_else();break;
case 173:set_alternative(f);break;
default: add_short(cislo);break;
}
}
else if (c=='$')
{
fgets(d,16384,f);
add_string(d);
}
else if (c=='&')
{
int cislo;
get_cislo(f,&cislo);
add_var(cislo);
}
c=fgetc(f);
}
free(d);
}
void save_program()
{
FILE *tg;
int pgstart;
tg=fopen("dialogy.dat","wb");
pgstart=pgf_count*sizeof(*pgf_list);
fwrite(&pgf_count,1,sizeof(pgf_count),tg);
fwrite(&prog_pos,1,sizeof(prog_pos),tg);
fwrite(pgf_list,1,pgstart,tg);
fwrite(program,1,prog_pos,tg);
fclose(tg);
}
void create_include_list(char *filename)
{
FILE *f,*g;
int i;
char s[15];
f=fopen(filename,"r");
if (f==NULL)
{
printf("Soubor nenalezen: %s\n",filename);
exit(0);
}
g=fopen(TEMP_NAME1,"w");
fputs("#include dialogy.def\n",g);
fputs("#command pgf_name *999 1\n",g);
do
{
i=fscanf(f,"%14s",s);
if (i==1)
{
fprintf(g,"pgf_name '");
while((i=fgetc(f))!='\n' && i!=EOF) fputc(i,g);fputs("'\n",g);
fprintf(g,"#include %s\n",s);
libs++;
i=1;
}
}
while(i==1);
fclose(f);
fclose(g);
}
const char *GetLexLibPath()
{
static char c[MAX_PATH];
char *z;
GetModuleFileName(0,c,MAX_PATH);
z=strrchr(c,'\\')+1;
strcpy(z,"lex_lib.exe");
return c;
}
main(int argc,char *argv[])
{
if (argc<2)
{
puts("Tento program vyzaduje jmeno souboru, ve kterem se naleza\n"
"script pro popis dialogu pro hru BRANY SKELDALU v 1.0");
exit(0);
}
puts("");
puts("Prob¡h  kompilace:");
puts(" Spouçt¡m program LEX_LIB.EXE\n");
putenv("DOS4G=QUIET");
create_include_list(argv[1]);
if (spawnlp(P_WAIT,GetLexLibPath(),"lex_lib.exe",TEMP_NAME1,"temp.$$$",NULL))
exit(1);
if (errno || init("temp.$$$"))
{
puts("Nemohu spustit program lex_lib.exe");
exit(1);
}
mlist=fopen(SCRIPT,"w");
if (mlist==NULL)
{
printf("Nemohu otevrit soubor %s pro zapis.\n",SCRIPT);
exit(0);
}
decode_program(f);
fclose(f);
remove("temp.$$$");
remove(TEMP_NAME1);
puts("Kompilace £spØçn ...");
printf("Vytvoreno odstavcu: %d\nCelkem knihoven: %d\nCelkem Sentenci: %d\nDlka k¢du: %d\n",pgf_count,libs,sentencs,prog_pos);
save_program();
fclose(mlist);
}