game folder "just" compiles (not link)

This commit is contained in:
Ondřej Novák 2025-01-25 13:08:41 +01:00
parent 13d3908273
commit 1b0f7fe0c2
135 changed files with 2161 additions and 2336 deletions

5
game/CMakeLists.txt Normal file
View file

@ -0,0 +1,5 @@
SET(files automap.c clk_map.c dialogy.c dump.cpp enemy.c engine2.c globmap.c inv.c kouzla.c menu.c skeldal.c souboje.c
builder.c engine1.c gamesave.c interfac.c kniha.c macros.c realgame.c setup.c sndandmus.c specproc.c)
add_executable(skeldal ${files})

955
game/automap.c Normal file
View file

@ -0,0 +1,955 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#define AUTOMAP_BACK RGB555(8,4,0)
#define AUTOMAP_VODA RGB555(0,15,31)
#define AUTOMAP_LAVA RGB555(31,16,0)
#define AUTOMAP_FORE RGB555(18,17,14)
#define AUTOMAP_LINE1 RGB555(13,11,10)
#define AUTOMAP_LINE2 RGB555(31,22,6)
#define AUTOMAP_MOB RGB555(31,8,8)
#define MEDIUM_MAP 9
#define MEDIUM_MMAP 4
#define MEDIUM_MAP_COLOR RGB555(21,20,19)
#define MEDIUM_MAP_LINE1 RGB555(25,20,17)
#define MEDIUM_MAP_LINE2 RGB555(31,22,6)
word stairs_colors[7]=
{AUTOMAP_LINE1,
RGB555(14,12,11),
RGB555(15,14,12),
RGB555(16,15,12),
RGB555(17,16,13)};
word arrow_colors[7]=
{
AUTOMAP_LINE1,
AUTOMAP_FORE
};
char shift_map(int id,int xa,int ya,int xr,int yr);
char psani_poznamek(int id,int xa,int ya,int xr,int yr);
char map_target_select(int id,int xa,int ya,int xr,int yr);
char map_target_cancel(int id,int xa,int ya,int xr,int yr);
char map_menu(int id,int xa,int ya,int xr,int yr);
char map_menu_glob_map(int id,int xa,int ya,int xr,int yr);
char noarrows=0;
char enable_glmap=0;
static int map_xr,map_yr;
static int cur_depth;
TSTR_LIST texty_v_mape=NULL;
#define BOTT 378
#define LEFT 520
static char cur_disables;
#define CLK_MAP_VIEW 5
T_CLK_MAP clk_map_view[]=
{
{MS_GAME_WIN,0,17,639,377,psani_poznamek,2,H_MS_DEFAULT},
{-1,54,378,497,474,start_invetory,2+8,-1},
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
{-1,LEFT,BOTT,639,479,map_menu,2,H_MS_DEFAULT},
{-1,0,0,639,479,return_game,8,-1},
};
#define CLK_GLOB_MAP 4
T_CLK_MAP clk_glob_map[]=
{
{-1,54,378,497,474,start_invetory,2+8,-1},
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
{-1,LEFT,BOTT,639,479,map_menu,2,H_MS_DEFAULT},
{-1,0,0,639,479,map_menu_glob_map,8,-1},
};
#define CLK_TELEPORT_VIEW 4
T_CLK_MAP clk_teleport_view[]=
{
{MS_GAME_WIN,0,17,639,377,map_target_select,2,H_MS_DEFAULT},
{-1,LEFT,BOTT,639,479,map_target_cancel,2,H_MS_DEFAULT},
{-1,0,0,639,479,map_target_cancel,8,-1},
{-1,0,0,639,479,empty_clk,0xff,-1},
};
char testclip(int x,int y)
{
return (y>=16 && y<360+16 && x>=8 && x<630);
}
/*void shift_map_event(EVENT_MSG *msg,int *data)
{
static int smer;
data;
if (msg->msg==E_INIT) smer=*(int *)msg->data;
else if (msg->msg==E_TIMER)
{
switch (smer)
{
case H_SIPKY_S:send_message(E_KEYBOARD,'H'*256);break;
case H_SIPKY_J:send_message(E_KEYBOARD,'P'*256);break;
case H_SIPKY_V:send_message(E_KEYBOARD,'M'*256);break;
case H_SIPKY_Z:send_message(E_KEYBOARD,'K'*256);break;
case H_SIPKY_SZ:send_message(E_KEYBOARD,'s'*256);msg->msg=-2;break;
case H_SIPKY_SV:send_message(E_KEYBOARD,'t'*256);msg->msg=-2;break;
}
}
else if (msg->msg==E_MOUSE)
{
MS_EVENT *ms;
ms=get_mouse(msg);
if (!ms->tl1 && !ms->tl2)
{
send_message(E_DONE,E_TIMER,shift_map_event);
msg->msg=-2;
schovej_mysku();
other_draw();
ukaz_mysku();
showview(0,0,0,0);
}
}
}
*/
void save_text_to_map(int x,int y,int depth,char *text)
{
char c[512],*d;
if (text[0]==0) return;
memset(c,1,sizeof(c));
strcpy(c+12,text);
if (texty_v_mape==NULL) texty_v_mape=create_list(8);
d=texty_v_mape[str_add(&texty_v_mape,c)];
x=(x-320)+map_xr;
y=(y-197)+map_yr;
memcpy(d,&x,4);memcpy(d+4,&y,4);memcpy(d+8,&depth,4);
}
static char check_for_layer(int layer)
{
int i;
TMAP_EDIT_INFO *m=map_coord;
for(i=0;i<mapsize;i++,m++) if (m->layer==layer && m->flags & MC_MARKED && m->flags & MC_AUTOMAP) return 1;
return 0;
}
void ukaz_vsechny_texty_v_mape()
{
int x,y,d,i,cn;
char *c;
if (texty_v_mape==NULL) return;
set_font(H_FLITT5,NOSHADOW(0));
cn=str_count(texty_v_mape);
for(i=0;i<cn;i++)
{
c=texty_v_mape[i];
if (c!=NULL)
{
memcpy(&x,c,4);memcpy(&y,c+4,4);memcpy(&d,c+8,4);c+=12;
x=x-map_xr;
y=y-map_yr;
x+=320;y+=197;
if (d==cur_depth)
if (testclip(x,y))
{
int h;char *d,e;
d=strchr(c,0);e=0;
while((h=text_width(c)+x)>640)
{
*d=e;
d--;e=*d;*d=0; if (d==c) break;
}
position(x,y);outtext(c);
*d=e;
}
else if(x<8 && x+text_width(c)>10 && y>16 && y<376)
{
char cd[2]=" ";
while (x<10 && *c)
{
cd[0]=*c++;x+=text_width(cd);
}
position(x,y);outtext(c);
}
}
}
}
void psani_poznamek_event(EVENT_MSG *msg,void **data)
{
static int x,y;
static char text[255],index;
static char *save;
static void *save_pic=NULL;
data;
if (msg->msg==E_INIT)
{
int *p;
char *c;
set_font(H_FLITT5,NOSHADOW(0));
p=msg->data;
x=p[0];
y=p[1];
c=*(char **)(p+2);
strcpy(text,c);
save=(char *)getmem(strlen(text)+1);
strcpy(save,text);
index=strchr(text,0)-text;
if (save_pic==NULL)
{
schovej_mysku();
save_pic=getmem(640*20*2+6);
get_picture(0,y,640,20,save_pic);
position(x,y);outtext(text);outtext("_");
showview(0,0,640,480);
}
}
else
if (msg->msg==E_MOUSE)
{
MS_EVENT *ms;
ms=get_mouse(msg);
if (ms->event_type & 0x8) send_message(E_KEYBOARD,27);
msg->msg=-1;
}
else if (msg->msg==E_KEYBOARD)
{
char c;
c=*(char *)msg->data;
set_font(H_FLITT5,NOSHADOW(0));
if (c)
{
switch (c)
{
case 8:if (index) index--; text[index]=0;break;
case 27:strcpy(text,save);
case 13:save_text_to_map(x,y,cur_depth,text);
send_message(E_DONE,E_MOUSE,psani_poznamek_event);msg->msg=-2;return;
default:if (c>=32)
{
text[index]=c;
text[index+1]=0;
if (text_width(text)>(640-x)) text[index]=0; else index++;
}
}
put_picture(0,y,save_pic);
position(x,y);outtext(text);outtext("_");
showview(x,y,640,20);
}
msg->msg=-1;
}
else if (msg->msg==E_DONE)
{
if (save_pic!=NULL)
{
put_picture(0,y,save_pic);
showview(x,y,640,y+20);
free(save_pic);save_pic=NULL;
send_message(E_AUTOMAP_REDRAW);
ukaz_mysku();
}
if (save!=NULL)
{
free(save);save=NULL;
}
}
}
int hledej_poznamku(int x,int y,int depth)
{
int i,count;
x=(x-320)+map_xr;
y=(y-197)+map_yr;
if (texty_v_mape==NULL) return -1;
count=str_count(texty_v_mape);
set_font(H_FLITT5,NOSHADOW(0));
for(i=0;i<count;i++)
if (texty_v_mape[i]!=NULL)
{
int xa,ya,xb,yb,dep;
int xas,yas,xbs,ybs,xs,ys;
xa=*(int *)(texty_v_mape[i]);
ya=*(int *)(texty_v_mape[i]+4);
dep=*(int *)(texty_v_mape[i]+8);
xs=text_width(texty_v_mape[i]+12);
ys=text_height(texty_v_mape[i]+12);
xb=xa+xs;
yb=ya+ys;
if (x>=xa && y>=ya && x<=xb && y<=yb && dep==depth)
{
xas=(xa+320)-map_xr;
yas=(ya+197)-map_yr;
xbs=xas+xs;
ybs=yas+ys;
if (xas>0 && xbs<640 && yas>16 && ybs<360+16) return i;
return -2;
}
}
return -1;
}
char psani_poznamek(int id,int xa,int ya,int xr,int yr)
{
xa;ya;xr;yr;
if (noarrows) return 1;
if ((id=hledej_poznamku(xa,ya,cur_depth))==-1)
{
xa&=~7;xa+=2;
ya&=~7;ya-=4;
send_message(E_ADD,E_KEYBOARD,psani_poznamek_event,xa,ya,"");
send_message(E_ADD,E_MOUSE,psani_poznamek_event,xa,ya,"");
}
else if (id!=-2)
{
char *s;
xa=*(int *)(texty_v_mape[id]);
ya=*(int *)(texty_v_mape[id]+4);
xa=(xa+320)-map_xr;
ya=(ya+197)-map_yr;
s=(char *)getmem(strlen(texty_v_mape[id]+12)+1);
strcpy(s,texty_v_mape[id]+12);
str_remove(&texty_v_mape,id);
str_delfreelines(&texty_v_mape);
send_message(E_AUTOMAP_REDRAW);
for(xr=0;xr<10;xr++) do_events();
send_message(E_ADD,E_KEYBOARD,psani_poznamek_event,xa,ya,s);
send_message(E_ADD,E_MOUSE,psani_poznamek_event,xa,ya,s);
free(s);
}
return 0;
}
char shift_map(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
anim_sipky(id,1);
// send_message(E_ADD,E_TIMER,shift_map_event,id);
// send_message(E_ADD,E_MOUSE,shift_map_event,id);
return 0;
}
static void print_symbol(int x,int y,char znak)
{
char c[2]=" ";
position(x+1,y+1);c[0]=znak;outtext(c);
}
static void draw_amap_sector(int x,int y,int sector,int mode,int turn,int line1,int line2)
{
int j,i,k;
TSTENA *q;
TSECTOR *ss;
q=&map_sides[sector<<2];
ss=&map_sectors[sector];
if (ss->sector_type==S_VODA || ss->sector_type==S_LODKA) curcolor=AUTOMAP_VODA;
else if (ss->sector_type==S_LAVA) curcolor=AUTOMAP_LAVA;
else curcolor=AUTOMAP_FORE;
if (!mode)
{
trans_bar(x,y,8,8,curcolor);
if ((k=map_coord[sector].flags & 0x600)!=0)
{
int i;
i=map_sectors[sector].sector_type;
set_font(H_FSYMB,0);k>>=9;
switch (k)
{
default:
case 3:break;
case 2:set_font(H_FSYMB,0);
font_color(stairs_colors);
print_symbol(x,y,'s');break;
case 1:set_font(H_FSYMB,0);
font_color(arrow_colors);
print_symbol(x,y,4+((i-S_SMER+4-turn) & 0x3));break;
}
}
else
switch(map_sectors[sector].sector_type)
{
int i;
TSTENA *sd;
case S_SCHODY:set_font(H_FSYMB,0x3e0);
memcpy(charcolors,stairs_colors,sizeof(stairs_colors));
print_symbol(x,y,'s');break;
case S_TELEPORT:for(i=0,sd=map_sides+sector*4;i<4 && ~sd->flags & SD_SEC_VIS;i++,sd++);
if (i!=4) {set_font(H_FSYMB,0x3e0);print_symbol(x,y,'T');}break;
case S_DIRA:set_font(H_FSYMB,NOSHADOW(0));print_symbol(x,y,'N');break;
}
}
else
for(j=0;j<4;j++)
{
i=(j+turn)&3;
if (!(q[i].flags & SD_TRANSPARENT)||(q[i].flags & SD_SECRET)) curcolor=line1;
else if (q[i].flags & SD_PLAY_IMPS) curcolor=line2;
else curcolor=AUTOMAP_FORE;
if (q[i].flags & SD_INVIS) curcolor=AUTOMAP_FORE;
if (curcolor!=AUTOMAP_FORE)
{
switch (j)
{
case 0:hor_line(x,y,x+8);break;
case 1:ver_line(x+8,y,y+8);break;
case 2:hor_line(x,y+8,x+8);break;
case 3:ver_line(x,y,y+8);break;
}
}
}
}
void herni_cas(char *s)
{
int mes,den,hod,min;
long cas;
cas=game_time;
mes=cas/(360*24*30);cas%=360*24*30;
den=cas/(360*24);cas%=360*24;
hod=cas/(360);cas%=360;
min=cas/6;
if (mes)
{
sprintf(s,texty[cislovka(mes)+149],mes);
strcat(s," ");
s=strchr(s,0);
}
if (den)
{
sprintf(s,texty[cislovka(den)+146],den);
strcat(s," ");
s=strchr(s,0);
}
sprintf(s,texty[152],hod,min);
}
static void zobraz_herni_cas(void)
{
static char text[100];
static long old_time=-1;
char cas[100];
if (old_time!=game_time)
{
herni_cas(cas);
strcpy(text,texty[145]);
strcat(text," ");
strcat(text,cas);
old_time=game_time;
}
set_font(H_FONT6,NOSHADOW(0));
set_aligned_position(635,372,2,2,text);
outtext(text);
}
extern word color_butt_on[];
extern word color_butt_off[];
static void displ_button(char disable,char **text)
{
int posy[]={0,18,37,55};
int sizy[]={18,20,20,21};
int i;
cur_disables=disable;
set_font(H_FTINY,0);
put_picture(LEFT,BOTT,ablock(H_CHARGEN));
for(i=0;i<4;i++)
{
if (disable & 1)
{
put_8bit_clipped(ablock(H_CHARGENB),(392+posy[i])*scr_linelen2+524+GetScreenAdr(),posy[i],96,sizy[i]);
font_color(color_butt_off);
}
else
{
font_color(color_butt_on);
}
disable>>=1;
set_aligned_position(LEFT+50,BOTT+14+13+i*19,1,2,*text);
outtext(*text);
text++;
}
}
void draw_automap(int xr,int yr)
{
int i,k,x,y,xp,yp;
int depth;
TSTENA *q;
word *s;
update_mysky();
schovej_mysku();
put_textured_bar(ablock(H_BACKMAP),0,17,640,360,-xr*8,-yr*8);
curcolor=AUTOMAP_BACK;
xp=map_coord[viewsector].x*8;
yp=map_coord[viewsector].y*8;
depth=cur_depth;
map_xr=xp-xr*8;
map_yr=yp-yr*8;
for(k=0;k<2;k++)
for(i=1;i<mapsize;i++)
{
int flagmask=MC_AUTOMAP|(k!=0?MC_DISCLOSED:0);
if ((map_coord[i].flags & flagmask) && (map_coord[i].flags & MC_MARKED) && map_coord[i].layer==depth)
{
x=(map_coord[i].x*8+xr*8);
y=(map_coord[i].y*8+yr*8);
q=map_sides+(i*4);
s=map_sectors[i].step_next;
x-=xp;y-=yp;
if (y>=-178 && y<170 && x>=-312 && x<310)
{
x+=320;y+=197;
draw_amap_sector(x,y,i,k,0,AUTOMAP_LINE1,AUTOMAP_LINE2);
if (map_coord[i].flags & MC_PLAYER && !noarrows)
{
int j,l=-1;
for(j=0;j<POCET_POSTAV;j++)
{
if (postavy[j].used)
if (postavy[j].sektor==i)
if (postavy[j].groupnum==cur_group) break;
else l=j;
}
if (j==POCET_POSTAV) j=l;
if (j!=-1)
{
char c[2];
position(x+1,y+1);
set_font(H_FSYMB,postavy[j].groupnum==cur_group?RGB888(255,255,255):barvy_skupin[postavy[j].groupnum]);
c[0]=postavy[j].direction+4;
c[1]=0;
outtext(c);
}
}
}
}
}
ukaz_vsechny_texty_v_mape();
zobraz_herni_cas();
{
char s[50];
sprintf(s,texty[153],mglob.mapname,depth);
set_aligned_position(5,372,0,2,s);
outtext(s);
}
ukaz_mysku();
wait_retrace();
showview(0,16,640,360);
}
void *map_keyboard(EVENT_MSG *msg,void **usr);
void enable_all_map(void)
{
int i;
for(i=1;i<mapsize;i++) map_coord[i].flags|=MC_MARKED;
}
void disable_all_map(void)
{
int i;
for(i=1;i<mapsize;i++) map_coord[i].flags&=~MC_MARKED;
}
void unwire_automap()
{
send_message(E_DONE,E_KEYBOARD,map_keyboard);
send_message(E_DONE,E_AUTOMAP_REDRAW,map_keyboard);
send_message(E_DONE,E_IDLE,map_keyboard);
hold_timer(TM_FAST_TIMER,0);
disable_all_map();
noarrows=0;
set_select_mode(0);
pick_set_cursor();
GlobEvent(MAGLOB_AFTERMAPOPEN,viewsector,viewdir);
}
void *map_keyboard(EVENT_MSG *msg,void **usr)
{
char c;
static int draw=0;
static int xr,yr;
usr;
if (msg->msg==E_INIT) xr=yr=0;
if (msg->msg==E_IDLE && draw==1)
{
draw_automap(xr,yr);
draw=0;
}
else draw--;
if (msg->msg==E_AUTOMAP_REDRAW) draw=4;
if (msg->msg==E_KEYBOARD)
{
c=(*(int *)msg->data)>>8;
switch (c)
{
case 'H':yr++;draw=4;break;
case 'P':yr--;draw=4;break;
case 'M':xr--;draw=4;break;
case 'K':xr++;draw=4;break;
case 'Q':
case 's':if (check_for_layer(cur_depth-1)) cur_depth--;draw=4;break;
case 'I':
case 't':if (check_for_layer(cur_depth+1)) cur_depth++;draw=4;break;
case 15:
case 50:
case 1:
(*(int *)msg->data)=0;
unwire_proc();
wire_proc();
break;
}
}
return &map_keyboard;
}
void show_automap(char full)
{
mute_all_tracks(0);
unwire_proc();
if (full) enable_all_map();
hold_timer(TM_FAST_TIMER,1);
unwire_proc=unwire_automap;
schovej_mysku();
if (cur_mode!=MD_ANOTHER_MAP) bott_draw(1),cur_mode=MD_MAP;
other_draw();
if (!battle && full && enable_glmap) displ_button(cur_mode==MD_ANOTHER_MAP?4:6,texty+210);
else displ_button(7,texty+210);
ukaz_mysku();
showview(0,376,640,480);
cur_depth=map_coord[viewsector].layer;
draw_automap(0,0);
send_message(E_ADD,E_KEYBOARD,map_keyboard);
send_message(E_ADD,E_AUTOMAP_REDRAW,map_keyboard);
send_message(E_ADD,E_IDLE,map_keyboard);
change_click_map(clk_map_view,CLK_MAP_VIEW);
}
static char mob_not_invis(int sector)
{
int m;
m=mob_map[sector];
while (m)
{
m--;if (mobs[m].vlastnosti[VLS_KOUZLA] & SPL_INVIS) return 0;
m=mobs[m].next;
}
return 1;
}
void draw_medium_map()
{
int xr, yr;
int xp, yp;
int xc,yc,x,y;
int j,i,k,layer;
//char c=" ";
xp=MEDIUM_MMAP*8+5;
yp=MEDIUM_MMAP*8+20;
layer=map_coord[viewsector].layer;
xr=map_coord[viewsector].x;
yr=map_coord[viewsector].y;
trans_bar(0,17,MEDIUM_MAP*8+6*2,MEDIUM_MAP*8+4*2,0);
for(j=0;j<2;j++)
for(i=1;i<mapsize;i++)
if (map_coord[i].flags & 1 && map_coord[i].layer==layer)
{
switch (viewdir & 3)
{
case 0:xc=map_coord[i].x-xr;yc=map_coord[i].y-yr;break;
case 1:yc=-map_coord[i].x+xr;xc=map_coord[i].y-yr;break;
case 2:xc=-map_coord[i].x+xr;yc=-map_coord[i].y+yr;break;
case 3:yc=map_coord[i].x-xr;xc=-map_coord[i].y+yr;break;
}
if (xc>=-MEDIUM_MMAP && yc>=-MEDIUM_MMAP && yc<=MEDIUM_MMAP && xc<=MEDIUM_MMAP)
{
draw_amap_sector(x=xc*8+xp,y=yc*8+yp,i,j,viewdir &3,MEDIUM_MAP_LINE1,MEDIUM_MAP_LINE2);
if (j)
if (mob_map[i] && mob_not_invis(i) && battle)
{
position(x+1,y+1);set_font(H_FSYMB,AUTOMAP_MOB);
outtext("N");
}
if (map_coord[i].flags & MC_PLAYER)
{
int u=-1,z=-1;
for(k=0;k<POCET_POSTAV;k++)
if (postavy[k].sektor==i)
if (postavy[k].groupnum==cur_group) z=k;else u=k;
if (z!=-1) u=z;
if (u!=-1)
{
set_font(H_FSYMB,postavy[u].groupnum==cur_group && !battle?RGB888(255,255,255):barvy_skupin[postavy[u].groupnum]);
position(x+1,y+1);
outtext("M");
}
}
}
}
}
char map_menu_glob_map(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
id=set_select_mode(0);
if (id)
{
schovej_mysku();
pick_set_cursor();
displ_button(1,texty+210);
ukaz_mysku();
showview(520,378,120,120);
return 1;
}
return 0;
}
static void wire_glob_map_control()
{
set_select_mode(0);
schovej_mysku();
other_draw();
displ_button(1,texty+210);
wire_global_map();
ukaz_mysku();
update_mysky();
change_click_map(clk_glob_map,CLK_GLOB_MAP);
}
char map_menu(int id,int xa,int ya,int xr,int yr)
{
char *s;
word *c;
ya;xa;id;
id=set_select_mode(0);
s=ablock(H_CHARGENM);
c=ablock(H_CHARGENM);
s+=*c*yr+xr+6;
id=*s;
if (!id) return 1;
if (id>4) return 1;
id--;
if (cur_disables & (1<<id)) return 1;
if (id)
{
pick_set_cursor();
displ_button(1,texty+210);
}
if (cur_mode==MD_ANOTHER_MAP) {unwire_proc();wire_proc();}
switch (id)
{
case 0:wire_glob_map_control();break;
case 1:unwire_proc();show_automap(1);break;
case 2:set_select_mode(1);
schovej_mysku();
displ_button(5,texty+210);
mouse_set_default(H_MS_WHO);
ukaz_mysku();
showview(0,0,0,0);break;
case 3:
unwire_proc();wire_proc();break;
}
return 1;
}
char exit_kniha(int id,int xa,int ya, int xr, int yr)
{
xa;ya;xr;yr;id;
unwire_proc();
wire_proc();
return 1;
}
int selected_page;
char page_change(int id,int xa,int ya,int xr,int yr)
{
int oldp;
xa,ya,xr,yr;
oldp=cur_page;
/*
if (*(char *)0x417 & 0x3)
{
selected_page=cur_page+id;
mouse_set_default(H_MS_LIST);
mouse_set_cursor(H_MS_LIST);
return 1;
}
*/
xa=count_pages();
xa=((xa-1) & ~1)+1;
cur_page+=id;
if (cur_page<1) cur_page=1;
if (cur_page>xa) cur_page=xa;
if (cur_page!=oldp) play_sample_at_channel(H_SND_KNIHA,1,100);
wire_kniha();
return 1;
}
#define CLK_KNIHA 3
T_CLK_MAP clk_kniha[]=
{
{2,320,0,639,479,page_change,2,-1},
{-2,0,0,319,479,page_change,2,-1},
{-1,0,0,639,479,exit_kniha,8,-1},
};
void unwire_kniha()
{
hold_timer(TM_FAST_TIMER,0);
GlobEvent(MAGLOB_AFTERBOOK,viewsector,viewdir);
}
void wire_kniha()
{
int xa;
if (!GlobEvent(MAGLOB_BEFOREBOOK,viewsector,viewdir))
{
return;
}
xa=count_pages();
xa=((xa-1) & ~1)+1;
if (cur_page<1) cur_page=1;
if (cur_page>xa) cur_page=xa;
mute_all_tracks(0);
unwire_proc();
schovej_mysku();
put_picture(0,0,ablock(H_KNIHA));
change_click_map(clk_kniha,CLK_KNIHA);
unwire_proc=unwire_kniha;
set_font(H_FONT6,NOSHADOW(0));
write_book(cur_page);
ukaz_mysku();
showview(0,0,0,0);
hold_timer(TM_FAST_TIMER,1);
}
static int last_selected;
char map_target_cancel(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
return exit_wait=1;
}
void map_teleport_keyboard(EVENT_MSG *msg,void **usr)
{
usr;
if (msg->msg==E_KEYBOARD)
switch (*(short *)msg->data>>8)
{
case 1:
case 15:
case 50: exit_wait=1; msg->msg=-1;break;
}
}
static char path_ok(word sector)
{
map_coord[sector].flags|=MC_MARKED;
return 1;
}
char map_target_select(int id,int xa,int ya,int xr,int yr)
{
int x1,y1,x2,y2;
ya,xa;
for (id=1;id<mapsize;id++)
if (map_coord[id].flags & (MC_AUTOMAP|MC_DISCLOSED))
{
x1=(map_coord[id].x*8-map_xr);
y1=(map_coord[id].y*8-map_yr);
x1+=320;
y1+=197-SCREEN_OFFLINE;
x2=x1+8;
y2=y1+8;
if (xr>=x1 && xr<=x2 && yr>=y1 && yr<=y2)
{
if (!labyrinth_find_path(viewsector,id,SD_PLAY_IMPS,path_ok,NULL)) return 0;
last_selected=id;
exit_wait=1;
return 1;
}
}
return 0;
}
int select_teleport_target()
{
*otevri_zavoru=1;
unwire_proc();
disable_all_map();
labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,path_ok,NULL);
map_coord[viewsector].flags|=MC_MARKED;
schovej_mysku();
send_message(E_ADD,E_KEYBOARD,map_teleport_keyboard);
show_automap(0);
change_click_map(clk_teleport_view,CLK_TELEPORT_VIEW);
last_selected=0;
ukaz_mysku();
escape();
send_message(E_DONE,E_KEYBOARD,map_teleport_keyboard);
disable_all_map();
return last_selected;
}

BIN
game/boldcz.fon Normal file

Binary file not shown.

1315
game/builder.c Normal file

File diff suppressed because it is too large Load diff

908
game/chargen.c Normal file
View file

@ -0,0 +1,908 @@
//CHARACTER GENERATOR
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <gui.h>
#include <basicobj.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include <stddef.h>
//there is defined procedures from source "INV.C"
void display_items_wearing(THUMAN *h);
void inv_display_vlastnosti();;
extern void (*inv_redraw)();
void write_human_big_name(char *c);
#define MSG_COLOR1 RGB555(30,30,23)
#define MAX_XICHTS 8
#define MAX_CHARS 6
#define XICHT_STEP 40
#define INV_DESK 266
#define INV_DESK_Y (SCREEN_OFFLINE)
#define INV_DESC_X 285
#define INV_DESC_Y (SCREEN_OFFLINE+20)
#define HUMAN_X 40
#define HUMAN_Y 328
#define X_SKIP_X 64
#define X_SKIP_Y 85
typedef struct staty
{
int zivl;
int zivh;
int manl;
int manh;
int konl;
int konh;
int akc;
}T_STATY;
static T_STATY cur_stats;
word color_butt_on[]={0,RGB555(31,27,4),RGB555(30,26,4),RGB555(29,25,4)};
word color_butt_off[]={0,RGB555(10,10,10),RGB555(10,10,10),RGB555(10,10,10)};
typedef struct vlasts
{
int sill;
int silh;
int smgl;
int smgh;
int pohl;
int pohh;
int obrl;
int obrh;
int hpreg;
int mpreg;
int vpreg;
}T_VLASTS;
static T_VLASTS cur_vls;
static T_VLASTS rohy[9]=
{
{17,22, 5,10,17,22, 9,14, 3, 2, 3},
{13,18,10,15,20,25, 5,10, 3, 3, 2},
{ 9,14,15,20,17,22, 9,14, 3, 3, 2},
{ 5,10,20,25,13,18,13,18, 2, 4, 2},
{ 9,14,15,20, 9,14,17,22, 2, 3, 2},
{13,18,10,15, 5,10,20,25, 2, 2, 4},
{17,22, 5,10, 9,14,17,22, 3, 1, 2},
{20,25, 0, 5,13,18,13,18, 4, 1, 2},
{12,17,12,17,12,17,12,17, 2, 2, 2},
};
#define CALC_DIFF(x,y,angl) ((x)+(((((y)-(x))<<4)*((angl)<<4)/720+8)>>4))
#define CALC_DIFF2(x,y,pol) ((x)+(((((y)-(x))<<4)*((pol)<<4)/(PERLA_MAXPOLOMER<<4)+8)>>4))
#define DIFF_RAND(x,y) ((x)+rnd((y)-(x)+1))
#define MAX_RACES 5
static char women[MAX_XICHTS]={0,0,0,0,1,1,1,1};
static char poradi[MAX_XICHTS]={0,2,3,4,1,5,6,7};
static char disable[MAX_XICHTS];
static int cur_edited=0;
static int cur_angle=90;
static int cur_polomer=0;
static int cur_xicht=-1;
static char shut_downing_text=0;
static int save_values[POCET_POSTAV][2];
static char del_mode=0;
static char was_enter=0;
#define PERLA_STRED_X (INV_DESK+189)
#define PERLA_STRED_Y (INV_DESK_Y+217)
#define PERLA_POLOMER cur_polomer
#define PERLA_MAXPOLOMER 75
short *pod_perlou=NULL;
short pod_perlou_x=0;
short pod_perlou_y=0;
char *error_text=NULL;
char select_xicht(int id,int xa,int ya,int xr,int yr);
char vol_vlastnosti(int id,int xa,int ya,int xr,int yr);
char go_next_page(int id,int xa,int ya,int xr,int yr);
char vls_click(int id,int xa,int ya,int xr,int yr);
char view_another_click2(int id,int xa,int ya,int xr,int yr);
//char edit_another_click(int id,int xa,int ya,int xr,int yr);
char edit_another_click2(int id,int xa,int ya,int xr,int yr);
char gen_exit_editor(int id,int xa,int ya,int xr,int yr);
void zobraz_staty(T_VLASTS *st);
#define CLK_PAGE1 6
static T_CLK_MAP clk_page1[]=
{
{0,28+INV_DESK,18+INV_DESK_Y,334+INV_DESK,55+INV_DESK_Y,select_xicht,2,-1},
{0,78+INV_DESK,97+INV_DESK_Y,314+INV_DESK,340+INV_DESK_Y,vol_vlastnosti,2+1,-1},
{-1,520,378,639,479,go_next_page,2,-1},
//{-1,54,378,497,479,edit_another_click,2+8,-1},
{2,0,0,639,479,gen_exit_editor,8,-1},
{0,0,0,639,479,empty_clk,0xff,-1},
};
#define CLK_PAGE2 5
static T_CLK_MAP clk_page2[]=
{
{-1,INV_DESK,INV_DESK_Y,639,378,vls_click,2,-1},
{-1,520,378,639,479,go_next_page,2,-1},
{-1,54,378,497,479,view_another_click2,2,-1},
{1,0,0,639,479,gen_exit_editor,8,-1},
{0,0,0,639,479,empty_clk,0xff,-1},
};
#define CLK_PAGE3 4
/*static T_CLK_MAP clk_page3[]=
{
{-1,520,378,639,479,go_next_page,2,-1},
{-1,54,378,497,479,view_another_click2,2+8,-1},
{0,0,0,639,479,edit_another_click2,8,-1},
{0,0,0,639,479,empty_clk,0xff,-1},
};
*/
#define H_GENERACE (H_MENUS_FREE+100)
#define H_GEN_PERLA (H_MENUS_FREE+101)
#define H_GEN_TOPBAR (H_MENUS_FREE+102)
#define H_GEN_OKBUTT (H_MENUS_FREE+103)
#define H_GEN_CHARGEN (H_MENUS_FREE+104)
#define H_GEN_CHARGENB (H_MENUS_FREE+105)
#define H_GEN_CHARGENM (H_MENUS_FREE+106)
#define H_GEN_XICHTY (H_MENUS_FREE+107)
#define H_GEN_POSTAVY (H_GEN_XICHTY+MAX_XICHTS)
TDREGISTERS char_gen_reg[]=
{
{H_GENERACE,"postavy.pcx",pcx_15bit_decomp,SR_BGRAFIKA},
{H_GEN_PERLA,"perla.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_GEN_TOPBAR,"topbar_p.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_GEN_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_GEN_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
{H_GEN_CHARGENM,"chargenm.pcx",pcx_8bit_decomp,SR_BGRAFIKA},
};
#define BOTT 378
#define LEFT 520
char *b_texty[4];
char b_disables;
void displ_button(char disable,char **text)
{
int posy[]={0,18,37,55};
int sizy[]={18,20,20,21};
int i;
set_font(H_FTINY,0);
put_picture(LEFT,BOTT,ablock(H_GEN_CHARGEN));
for(i=0;i<4;i++)
{
if (disable & 1)
{
put_8bit_clipped(ablock(H_GEN_CHARGENB),(392+posy[i])*scr_linelen2+524+GetScreenAdr(),posy[i],96,sizy[i]);
font_color(color_butt_off);
}
else
{
font_color(color_butt_on);
}
disable>>=1;
set_aligned_position(LEFT+50,BOTT+14+13+i*19,1,2,*text);
outtext(*text);
text++;
}
}
static void draw_other_bar()
{
int i;
word *bbar=ablock(H_BOTTBAR);
word *screen=GetScreenAdr()+(480-102)*scr_linelen2;
for (i=0;i<102;i++,screen+=scr_linelen2,bbar+=scr_linelen2) memcpy(screen,bbar,scr_linelen);
//put_8bit_clipped(ablock(H_GEN_OKBUTT),378*640+520+screen,0,120,102);
displ_button(b_disables,b_texty);
put_picture(0,0,ablock(H_GEN_TOPBAR));
zobraz_staty(&cur_vls);
}
static void display_character(THUMAN *p,char i)
{
word *w;
put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK));
if (p->used)
{
w=ablock(H_GEN_POSTAVY+(p->xicht));
put_picture(HUMAN_X+30,HUMAN_Y-w[1],w);
}
if (i) draw_other_bar();
}
static void zobraz_error_text()
{
if (error_text!=NULL)
{
trans_bar(0,362,640,16,0);
set_font(H_FONT6,RGB555(31,31,0));
position(10,364);outtext(error_text);
}
}
static void vypocet_perly(int angle,int xp,int yp,int *x,int *y)
{
float xr,yr;
float rad;
rad=angle*3.14159265f/180;
xr=(float)cos(rad)*PERLA_POLOMER;
yr=(float)sin(rad)*PERLA_POLOMER;
*x=(int)xr+PERLA_STRED_X;
*y=PERLA_STRED_Y-(int)yr;
x[0]-=xp>>1;
y[0]-=yp>>1;
}
static void zobraz_perlu(void)
{
word *perla;
int x,y;
word *scr,*sss;
char *p;
word *b;
int xs,ys,xxs;
alock(H_GEN_PERLA);
perla=ablock(H_GEN_PERLA);
if (pod_perlou==NULL)
{
pod_perlou=getmem(perla[0]*perla[1]*2+6);
}
vypocet_perly(cur_angle,perla[0],perla[1],&x,&y);
xs=perla[0];ys=perla[1];
get_picture(x,y,xs,ys,pod_perlou);
sss=x+scr_linelen2*y+GetScreenAdr();
p=(char *)(perla+256+3);
b=perla+3;
for(;ys>0;ys--)
{
scr=sss;
for(xxs=0;xxs<xs;xxs++)
if (!*p) scr++,p++;else
if (*p<128) *scr++=b[*p++];else
{
*scr=(*scr & RGB555(30,30,30))>>1;
scr++;p++;
}
sss+=scr_linelen2;
}
//put_picture(x,y,perla);
pod_perlou_x=x;
pod_perlou_y=y;
aunlock(H_GEN_PERLA);
}
static void schovej_perlu(void)
{
put_picture(pod_perlou_x,pod_perlou_y,pod_perlou);
}
static void vypocet_vlastnosti(int angle,T_VLASTS *vls)
{
T_VLASTS *low,*hi;
div_t rm;
int p,test;
rm=div(angle,45);
p=rm.quot;
low=rohy+p;p++;if (p>=8) p=0;
hi=rohy+p;
test=CALC_DIFF(8,12,44);
vls->sill=CALC_DIFF(low->sill,hi->sill,rm.rem);
vls->silh=CALC_DIFF(low->silh,hi->silh,rm.rem);
vls->smgl=CALC_DIFF(low->smgl,hi->smgl,rm.rem);
vls->smgh=CALC_DIFF(low->smgh,hi->smgh,rm.rem);
vls->obrl=CALC_DIFF(low->obrl,hi->obrl,rm.rem);
vls->obrh=CALC_DIFF(low->obrh,hi->obrh,rm.rem);
vls->pohl=CALC_DIFF(low->pohl,hi->pohl,rm.rem);
vls->pohh=CALC_DIFF(low->pohh,hi->pohh,rm.rem);
vls->hpreg=CALC_DIFF(low->hpreg,hi->hpreg,rm.rem);
vls->mpreg=CALC_DIFF(low->mpreg,hi->mpreg,rm.rem);
vls->vpreg=CALC_DIFF(low->vpreg,hi->vpreg,rm.rem);
low=&rohy[8];hi=vls;rm.rem=PERLA_POLOMER;
vls->sill=CALC_DIFF2(low->sill,hi->sill,rm.rem);
vls->silh=CALC_DIFF2(low->silh,hi->silh,rm.rem);
vls->smgl=CALC_DIFF2(low->smgl,hi->smgl,rm.rem);
vls->smgh=CALC_DIFF2(low->smgh,hi->smgh,rm.rem);
vls->obrl=CALC_DIFF2(low->obrl,hi->obrl,rm.rem);
vls->obrh=CALC_DIFF2(low->obrh,hi->obrh,rm.rem);
vls->pohl=CALC_DIFF2(low->pohl,hi->pohl,rm.rem);
vls->pohh=CALC_DIFF2(low->pohh,hi->pohh,rm.rem);
vls->hpreg=CALC_DIFF2(low->hpreg,hi->hpreg,rm.rem);
vls->mpreg=CALC_DIFF2(low->mpreg,hi->mpreg,rm.rem);
vls->vpreg=CALC_DIFF2(low->vpreg,hi->vpreg,rm.rem);
}
/*static void vypocet_statu(T_VLASTS *vls,T_STATY *sts)
{
sts->zivl=vls->sill*3/2;
sts->zivh=vls->silh*3/2;
sts->manl=vls->smgl*2;
sts->manh=vls->smgh*2;
sts->konl=vls->obrl*2;
sts->konh=vls->obrh*2;
sts->akc=(((vls->pohl+vls->pohh)/2)+14)/15;
}
*/
static void zobraz_staty(T_VLASTS *st)
{
char s[100];
set_font(H_FTINY,0);font_color(color_topbar);
sprintf(s,texty[2],st->sill,st->silh);
position(230,2);outtext(s);
sprintf(s,texty[3],st->smgl,st->smgh);
position(330,2);outtext(s);
sprintf(s,texty[4],st->pohl,st->pohh);
position(430,2);outtext(s);
sprintf(s,texty[5],st->obrl,st->obrh);
position(530,2);outtext(s);
}
void redraw_generator(char show)
{
T_STATY z;
int i;
memset(&z,20,sizeof(z));
schovej_mysku();
put_picture(INV_DESK,SCREEN_OFFLINE,ablock(H_GENERACE));
if (cur_xicht==-1)
{
put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK));
bott_draw(1);
draw_other_bar();
}
else display_character(postavy+cur_edited,1);
zobraz_error_text();
zobraz_perlu();
for(i=0;i<MAX_XICHTS;i++)
{
if (disable[poradi[i]])
trans_bar(28+INV_DESK+i*XICHT_STEP,18+INV_DESK_Y,26,38,0);
}
ukaz_mysku();
if (show) showview(0,0,0,0);
}
static void set_xicht(int player,int xicht)
{
THUMAN *h=postavy+player;
h->used=1;
h->xicht=xicht;
h->vlastnosti[VLS_MAXHIT]=1;
h->vlastnosti[VLS_KONDIC]=1;
h->lives=1;
h->kondice=0;
h->mana=0;
h->sektor=viewsector;
h->groupnum=1;
h->jidlo=1;
h->voda=1;
h->bonus=0;
h->spell=0;
}
static char select_xicht(int id,int xa,int ya,int xr,int yr)
{
int i,j,k;
char s[20];
i=xr/XICHT_STEP;
j=xr%XICHT_STEP;
if (j>27) return 0;
k=poradi[i];
if (disable[k]) return 1;
memset(disable,0,sizeof(disable));
set_xicht(cur_edited,cur_xicht=k);
postavy[cur_edited].female=women[i];
b_disables=0x6;
if (was_enter) send_message(E_KEYBOARD,13);
else
{
strcpy(postavy[cur_edited].jmeno,texty[160+i]);
send_message(E_KEYBOARD,27);
was_enter=0;
}
sprintf(s,XICHT_NAME,k);
def_handle(H_XICHTY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA);
sprintf(s,CHAR_NAME,k);
def_handle(H_POSTAVY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA);
for(j=0;j<MAX_XICHTS;j++) if (postavy[j].used) disable[postavy[j].xicht]=1;
error_text=NULL;
bott_draw(1);
redraw_generator(1);
displ_button(b_disables,b_texty);
showview(0,0,0,0);
id,xa,ya,xr,yr;
return 1;
}
static char vol_vlastnosti(int id,int xa,int ya,int xr,int yr)
{
int a;
static char cancel=1;
id,xa,ya,xr,yr;
if (!ms_last_event.tl1)
{
cancel=1;
return 0;
}
if (ms_last_event.event_type & 0x2)
if (xa<pod_perlou_x || ya<pod_perlou_y || xa>pod_perlou_x+pod_perlou[0] || ya>pod_perlou_y+pod_perlou[1] )
{
cancel=1;
return 0;
}
else cancel=0;
if (cancel) return 0;
xr=xa-PERLA_STRED_X;
yr=-(ya-PERLA_STRED_Y);
a=(int)(atan2((double)yr,(double)xr)*180/3.14159265);
cur_polomer=(int)sqrt(xr*xr+yr*yr);
if (cur_polomer>PERLA_MAXPOLOMER) cur_polomer=PERLA_MAXPOLOMER;
xa=pod_perlou_x;
ya=pod_perlou_y;
schovej_mysku();
schovej_perlu();
if (a<0) a+=360;
vypocet_vlastnosti(a,&cur_vls);
cur_angle=a;
zobraz_perlu();
ukaz_mysku();
update_mysky();
showview(pod_perlou_x,pod_perlou_y,pod_perlou[0],pod_perlou[1]);
showview(xa,ya,pod_perlou[0],pod_perlou[1]);
put_picture(0,0,ablock(H_GEN_TOPBAR));
zobraz_staty(&cur_vls);
showview(250,0,640,17);
return 1;
}
static int edit_task=-1;
static void edit_name()
{
if (shut_downing_text) return;
curcolor=0;bar(120,2,120+104,16);
edit_task=add_task(16384,type_text_v2,postavy[cur_edited].jmeno,120,2,104,
sizeof(postavy[cur_edited].jmeno)-1,H_FONT6,RGB555(31,31,0),edit_name);
}
static void stop_edit_name()
{
shut_downing_text=1;send_message(E_KEYBOARD,13);
task_sleep(NULL);
if (edit_task>0 && is_running(edit_task))
shut_down_task(edit_task);
shut_downing_text=0;
}
/*static char edit_another_click(int id,int xa,int ya,int xr,int yr)
{
short *w;
id,xa,ya,xr,yr;
w=ablock(H_OKNO);
id=xr/w[0];
if (!postavy[id].used) return 0;
shut_downing_text=1;
send_message(E_KEYBOARD,13);
shut_downing_text=0;
save_values[cur_edited][0]=cur_angle;
save_values[cur_edited][1]=cur_polomer;
select_player=cur_edited=id;
cur_angle=save_values[cur_edited][0];
cur_polomer=save_values[cur_edited][1];
vypocet_vlastnosti(cur_angle,&cur_vls);
cur_xicht=postavy[cur_edited].xicht;
edit_name();
bott_draw(1);
redraw_generator();
return 1;
}
*/
static void def_entries()
{
int i;
int s;
TDREGISTERS *p;
s=sizeof(char_gen_reg)/sizeof(TDREGISTERS);
p=char_gen_reg;
for(i=0;i<s;i++,p++) def_handle(p->h_num,p->name,p->proc,p->path);
for(i=0;i<MAX_XICHTS;i++)
{
char s[15];
sprintf(s,CHAR_NAME,i);
def_handle(H_GEN_POSTAVY+i,s,pcx_8bit_decomp,SR_BGRAFIKA);
apreload(H_GEN_POSTAVY+i);
mix_back_sound(0);
}
for(i=0;i<MAX_XICHTS;i++)
{
char s[15];
sprintf(s,XICHT_NAME,i);
def_handle(H_GEN_XICHTY+i,s,pcx_8bit_decomp,SR_BGRAFIKA);
apreload(H_GEN_XICHTY+i);
mix_back_sound(0);
}
}
static char go_next_page(int id,int xa,int ya,int xr,int yr)
{
word *w;
char *b;
xa,ya;
w=ablock(H_GEN_CHARGENM);
b=(char *)(w+3+256);
b+=*w*yr+xr;
if (!*b) return 1;
id=*b-1;
if (b_disables & (1<<id)) return 1;
send_message(E_CLOSE_GEN,id);
return 1;
}
void generuj_postavu(THUMAN *h)
{
short *v;
h->used=1;
h->groupnum=1;
v=h->stare_vls;
v[VLS_SILA]=DIFF_RAND(cur_vls.sill,cur_vls.silh);
v[VLS_SMAGIE]=DIFF_RAND(cur_vls.smgl,cur_vls.smgh);
v[VLS_POHYB]=DIFF_RAND(cur_vls.pohl,cur_vls.pohh);
v[VLS_OBRAT]=DIFF_RAND(cur_vls.obrl,cur_vls.obrh);
v[VLS_HPREG]=cur_vls.hpreg;
v[VLS_MPREG]=cur_vls.mpreg;
v[VLS_VPREG]=cur_vls.vpreg;
// v[VLS_THIEF]=cur_vls.vpreg;
h->lives=v[VLS_MAXHIT]=(v[VLS_SILA]*3+v[VLS_POHYB])/2;
h->mana=v[VLS_MAXMANA]=v[VLS_SMAGIE]*2;
h->kondice=v[VLS_KONDIC]=v[VLS_OBRAT]*2;
v[VLS_OBRAN_L]=1;
v[VLS_OBRAN_H]=2;
v[VLS_UTOK_L]=1;
v[VLS_UTOK_H]=2;
prepocitat_postavu(h);
h->inv_size=6;
h->level=1;
h->exp=0;
h->bonus=5;
h->jidlo=MAX_HLAD(h);
h->voda=MAX_ZIZEN(h);
h->mana_battery=32767;
//postava je vygenerovana
}
static void redraw_page3()
{
update_mysky();
schovej_mysku();
curcolor=0;
inv_display_vlastnosti();
display_character(postavy+cur_edited,1);
write_human_big_name(postavy[cur_edited].jmeno);
draw_other_bar();
displ_button(b_disables,b_texty);
ukaz_mysku();
showview(0,0,0,0);
inv_redraw=redraw_page3;
}
static void redraw_svitek()
{
if (postavy[cur_edited].bonus==0)
{
char mode;
mode=7;
if (postavy[charmin-1].used) mode&=~2;
if (!postavy[charmax-1].used) mode&=~1;
if (!del_mode) mode&=~4;
b_disables=mode;
redraw_page3();
return;
}
update_mysky();
schovej_mysku();
curcolor=0;
bar(0,16,30,16+360);
bar(620,16,640,16+360);
inv_display_vlastnosti();
display_character(postavy+cur_edited,0);
// display_items_wearing(human_selected);
// write_pocet_sipu();
// display_rings();
zobraz_error_text();
displ_button(b_disables,b_texty);
ukaz_mysku();
showview(0,0,0,0);
inv_redraw=redraw_svitek;
}
static char validate_character(THUMAN *h)
{
if (h->jmeno[0]==0) error_text=texty[111];
else error_text=NULL;
return error_text==NULL;
}
/*static char edit_another_click2(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
cur_edited=select_player;
schovej_mysku();
edit_name();
draw_other_bar();
send_message(E_CLOSE_GEN,0);
ukaz_mysku();
update_mysky();
return 1;
}
*/
static void empty_proc()
{
}
char potvrzeno(char *text,void (*redraw)())
{
int i;
unwire_proc=empty_proc;
stop_edit_name();
i=message(2,0,1,texty[118],text,texty[114],texty[115])==0;
redraw();
edit_name();
return i;
}
static char view_another_click2(int id,int xa,int ya,int xr,int yr)
{
short *w;
id,xa,ya,xr,yr;
w=ablock(H_OKNO);
id=xr/w[0];
if (!(~b_disables & 0x3)) return 1;
if (!postavy[id].used) return 0;
shut_downing_text=1;send_message(E_KEYBOARD,13);
shut_downing_text=0;
select_player=id;
bott_draw(1);
human_selected=postavy+id;
cur_edited=id;
edit_name();
redraw_page3();
if (del_mode)
if (potvrzeno(texty[117],redraw_page3))
{
del_mode=0;
postavy[cur_edited].used=0;
disable[postavy[cur_edited].xicht]=0;
send_message(E_CLOSE_GEN,0);
}
return 0;
}
void effect_show(va_list args)
{
int i;
schovej_mysku();
for(i=0;i<12;i++)
{
showview(0,240-i*20-20,640,20);
showview(0,240+(i*20),640,20);
task_wait_event(E_TIMER);
}
ukaz_mysku();
}
static void enter_reaction(EVENT_MSG *msg,void **unused)
{
unused;
if (msg->msg==E_KEYBOARD)
{
if (*(char *)msg->data==13 && !shut_downing_text)
{
send_message(E_KEYBOARD,13);
bott_draw(1);
redraw_generator(1);
msg->msg=-1;
}
was_enter=1;
}
}
static void enter_reaction2(EVENT_MSG *msg,void **unused)
{
unused;
if (msg->msg==E_KEYBOARD && *(char *)msg->data==13 && !shut_downing_text && ~b_disables & 0x3)
{
send_message(E_KEYBOARD,13);
bott_draw(1);
redraw_page3();
msg->msg=-1;
}
}
char gen_exit_editor(int id,int xa,int ya,int xr,int yr)
{
xa,ya,xr,yr,id;
if (del_mode==1)
{
del_mode=0;
mouse_set_default(H_MS_DEFAULT);
b_disables&=~0x4;
redraw_svitek();
return 1;
}
unwire_proc=empty_proc;
shut_downing_text=1;send_message(E_KEYBOARD,13);shut_downing_text=0;
if (message(2,0,1,texty[118],texty[113],texty[114],texty[115])==0)
{
send_message(E_CLOSE_GEN,255);
}
else
{
if (id==2)redraw_generator(1);
else redraw_svitek();
edit_name();
}
return 1;
}
char enter_generator()
{
int i;
char rep=0;
znova:
del_mode=0;
stop_edit_name();
b_texty[0]=texty[170];
b_texty[1]=texty[171];
b_texty[2]=texty[172];
b_texty[3]=texty[173];
def_entries();
curcolor=0;bar(0,0,639,479);
cur_angle=315;
cur_edited=0;
memset(postavy,0,sizeof(postavy));
memset(disable,0,sizeof(disable));
memset(save_values,0,sizeof(save_values));
do
{
mouse_set_default(H_MS_DEFAULT);
cur_angle=save_values[cur_edited][0];
cur_polomer=save_values[cur_edited][1];
set_xicht(cur_edited,cur_xicht=-1);
select_player=-1;
memset(&cur_stats,0,sizeof(cur_stats));
vypocet_vlastnosti(cur_angle,&cur_vls);
b_disables=0x7;
redraw_generator(rep);if (!rep)effect_show(NULL);rep=1;
edit_name();
change_click_map(clk_page1,CLK_PAGE1);
was_enter=0;
do
{
send_message(E_ADD,E_KEYBOARD,enter_reaction);
i=*(char *)task_wait_event(E_CLOSE_GEN);
send_message(E_DONE,E_KEYBOARD,enter_reaction);
if (i==3 && potvrzeno(texty[116],redraw_generator)) goto znova;
if (i==255) return 1;
}
while (cur_xicht==-1 || i==3);
send_message(E_KEYBOARD,13);
save_values[cur_edited][0]=cur_angle;
save_values[cur_edited][1]=cur_polomer;
cur_xicht=0;
error_text=NULL;
generuj_postavu(postavy+cur_edited);
human_selected=postavy+cur_edited;
b_disables=0x7;
do
{
redraw_svitek();
change_click_map(clk_page2,CLK_PAGE2);
do
{
send_message(E_ADD,E_KEYBOARD,enter_reaction2);
i=*(char *)task_wait_event(E_CLOSE_GEN);
send_message(E_DONE,E_KEYBOARD,enter_reaction2);
if (i==3 && potvrzeno(texty[116],redraw_svitek)) goto znova;
if (i==2)
{
del_mode=1;
mouse_set_default(H_MS_WHO);
b_disables|=0x4;
redraw_svitek();
i=3;
}
}
while (i==3);
mouse_set_default(H_MS_DEFAULT);
del_mode=0;
send_message(E_KEYBOARD,13);
if (i==255) return 1;
if (validate_character(postavy+cur_edited))
for(cur_edited=0;postavy[cur_edited].used;cur_edited++);
}
while (error_text!=NULL);
stop_edit_name();
}
while (i!=1);
disable_click_map();
schovej_mysku();
curcolor=0;
bar(0,0,639,479);
showview(0,0,0,0);
ukaz_mysku();
for(i=0;i<3;i++)
{
if (postavy[i].vlastnosti[VLS_SILA]>20) postavy[i].stare_vls[VLS_UTOK_H]++;
if (postavy[i].vlastnosti[VLS_OBRAT]>20) postavy[i].stare_vls[VLS_OBRAN_H]++;
}
return 0;
}

344
game/chargen2.c Normal file
View file

@ -0,0 +1,344 @@
//CHARACTER GENERATOR
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <gui.h>
#include <basicobj.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include <stddef.h>
//there is defined procedures from source "INV.C"
void display_items_wearing(THUMAN *h);
#define MAX_XICHTS 8
#define MAX_CHARS 3
#define INV_DESK 266
#define INV_DESC_X 285
#define INV_DESC_Y (SCREEN_OFFLINE+20)
#define HUMAN_X 40
#define HUMAN_Y 328
#define X_SKIP_X 64
#define X_SKIP_Y 85
typedef struct staty
{
char zivl;
char zivh;
char manl;
char manh;
char konl;
char konh;
char akc;
}T_STATY;
#define MAX_RACES 5
static char women[MAX_XICHTS]={0,1,0,0,0,1,0,0};//,0,0};
static int cur_edited=0;
static int cur_xicht=-1;
int cur_page=1;
static int loc_select=-1;
#define CLK_PAGE1 3
static T_CLK_MAP clk_page1[]=
{
};
static void display_character(THUMAN *p)
{
word *w;
put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK));
if (p->used)
{
w=ablock(hl_ptr+MAX_XICHTS+(p->xicht));
put_picture(HUMAN_X+30,HUMAN_Y-w[1],w);
}
}
/*
static void display_all_xichts()
{
int i,a,x,y;
a=0;
x=INV_DESC_X;y=INV_DESC_Y;
for(i=0;i<MAX_XICHTS;i++)
{
put_image(ablock(hl_ptr+i),x+640*y+screen,0,54,75);
if (i==cur_xicht) rectangle(x,y,x+53,y+74,0x7fff);
x+=X_SKIP_X;
a++;if (a>4)
{
a=0;
x=INV_DESC_X;
y+=X_SKIP_Y;
}
}
}
*/
/*
static void display_race_line(int line,char pushed)
{
int x,y;
char *c;
set_font(H_FBOLD,pushed?0x3e0:0x7fff);
x=INV_DESK+137;y=INV_DESC_Y+170+22*line;
put_textured_bar(ablock(H_BUTBIG),x,y,100,20,0,20*pushed);
x+=49+pushed;y+=9+pushed;
if (cur_xicht==-1 || !women[cur_xicht]) c=texty[line+110];else c=texty[line+115];
set_aligned_position(x,y,1,1,c);outtext(c);
}
*/
static void tlac2(int x,int y,char *text,int pushed)
{
set_font(H_FBOLD,pushed?0x3e0:0x7fff);
put_textured_bar(ablock(H_BUTSMALL),x,y,56,20,0,20*pushed);
x+=27+pushed;y+=9+pushed;
set_aligned_position(x,y,1,1,text);outtext(text);
}
static void tlac2_press(int x,int y,char *text)
{
schovej_mysku();
tlac2(x,y,text,1);
ukaz_mysku();
showview(x,y,56,20);
}
/*
static void display_page2()
{
int i,x,y;
char s[10];
set_font(H_FBOLD,0x7fff);
position(INV_DESC_X,INV_DESC_Y);outtext(texty[122]);
x=INV_DESC_X+10;y=INV_DESC_Y+100;
for(i=0;i<4;i++)
{
position(x,y);outtext(texty[i+10]);
sprintf(s,"%d",postavy[cur_edited].stare_vls[i+VLS_SILA]);
set_aligned_position(x+140,y,2,0,s);outtext(s);
tlac2(x+150,y-5,"-",0);
tlac2(x+210,y-5,"+",0);
y+=30;
}
position(x,y);outtext(texty[19]);
sprintf(s,"%d",postavy[cur_edited].bonus);
set_aligned_position(x+140,y,2,0,s);outtext(s);
}
*/
static void zobraz_staty(T_STATY *st)
{
char s[100];
set_font(H_FONT6,(28*1024+16*32+2));
sprintf(s,texty[2],st->zivl,st->zivh);
position(250,3);outtext(s);
sprintf(s,texty[3],st->manl,st->manh);
position(350,3);outtext(s);
sprintf(s,texty[4],st->konl,st->konh);
position(450,3);outtext(s);
sprintf(s,texty[5],st->akc);
position(550,3);outtext(s);
}
void redraw_generator()
{
T_STATY z;
memset(&z,20,sizeof(z));
schovej_mysku();
put_picture(INV_DESK,SCREEN_OFFLINE,ablock(H_GENERACE));
put_picture(0,SCREEN_OFFLINE,ablock(H_IOBLOUK));
bott_draw(1);
memcpy(screen+(480-102)*640,ablock(H_BOTTBAR),640*102*2);
put_picture(0,0,ablock(H_GEN_TOPBAR));
zobraz_staty(&z);
ukaz_mysku();
showview(0,0,0,0);
}
static char page1_xicht(int id,int xa,int ya,int xr,int yr)
{
THUMAN *p;
char s[15];
xa,ya,id;
if (xr%X_SKIP_X>54 || yr%X_SKIP_Y>75) return 0;
xr/=X_SKIP_X;
yr/=X_SKIP_Y;
cur_xicht=yr*5+xr;
sprintf(s,CHAR_NAME,cur_xicht);
def_handle(H_CHARS+cur_edited,s,pcx_fade_decomp,SR_BGRAFIKA);
sprintf(s,XICHT_NAME,cur_xicht);
def_handle(H_XICHTY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA);
p=postavy+cur_edited;
p->used=1;
p->lives=1;
p->xicht=cur_xicht;
p->sektor=viewsector;
prepocitat_postavu(p);
redraw_generator();
return 1;
}
static char page1_tlac1(int id,int xa,int ya,int xr,int yr)
{
yr/=22;yr,xa,ya,id,xr;
if (yr<MAX_RACES)loc_select=yr;
redraw_generator();
return 1;
}
static void timered_redraw_call(THE_TIMER *t)
{
t;
redraw_generator();
}
static void timered_redraw()
{
add_to_timer(-1,5,1,timered_redraw_call);
}
static void generate_vlastnosti(THUMAN *p, int povolani)
{
short *w=&p->vlastnosti;
//common definiton
p->used=1;
p->groupnum=1;
p->sipy=0;
p->inv_size=6;
p->level=1;
p->exp=rnd(200);
p->female=women[p->xicht];
switch(povolani)
{
case 0:w[VLS_SILA]=5+rnd(5);
w[VLS_SMAGIE]=0;
w[VLS_POHYB]=rnd(7)+2;
w[VLS_OBRAT]=rnd(5)+1;
w[VLS_MAXHIT]=10+rnd(10);
w[VLS_MAXMANA]=0;
w[VLS_KONDIC]=rnd(10)+10;
w[VLS_HPREG]=2;
w[VLS_MPREG]=1;
w[VLS_VPREG]=1;
p->bonus_zbrani[TPW_MEC]=1;
p->bonus_zbrani[TPW_SEKERA]=1;
break;
case 1:w[VLS_SILA]=rnd(5)+3;
w[VLS_SMAGIE]=rnd(5);
w[VLS_POHYB]=rnd(7)+2;
w[VLS_OBRAT]=rnd(7)+1;
w[VLS_MAXHIT]=10+rnd(10);
w[VLS_MAXMANA]=rnd(10);
w[VLS_KONDIC]=rnd(10)+10;
w[VLS_HPREG]=1;
w[VLS_MPREG]=1;
w[VLS_VPREG]=2;
p->bonus_zbrani[TPW_MEC]=1;
p->bonus_zbrani[TPW_DYKA]=1;
break;
case 2:w[VLS_SILA]=rnd(4)+1;
w[VLS_SMAGIE]=rnd(5)+5;
w[VLS_POHYB]=rnd(4)+1;
w[VLS_OBRAT]=rnd(4)+1;
w[VLS_MAXHIT]=5+rnd(5);
w[VLS_MAXMANA]=5+rnd(10);
w[VLS_KONDIC]=rnd(5)+10;
w[VLS_HPREG]=1;
w[VLS_MPREG]=2;
w[VLS_VPREG]=1;
p->bonus_zbrani[TPW_HUL]=1;
p->bonus_zbrani[TPW_DYKA]=1;
break;
case 3:w[VLS_SILA]=rnd(4)+1;
w[VLS_SMAGIE]=0;
w[VLS_POHYB]=rnd(5)+4;
w[VLS_OBRAT]=rnd(5)+5;
w[VLS_MAXHIT]=10+rnd(5);
w[VLS_MAXMANA]=0;
w[VLS_KONDIC]=rnd(5)+10;
w[VLS_HPREG]=1;
w[VLS_MPREG]=1;
w[VLS_VPREG]=1;
p->bonus_zbrani[TPW_STRELNA]=3;
break;
case 4:w[VLS_SILA]=rnd(4)+1;
w[VLS_SMAGIE]=0;
w[VLS_POHYB]=rnd(7)+2;
w[VLS_OBRAT]=rnd(4)+6;
w[VLS_MAXHIT]=5+rnd(5);
w[VLS_MAXMANA]=5+rnd(10);
w[VLS_KONDIC]=rnd(5)+10;
w[VLS_HPREG]=1;
w[VLS_MPREG]=1;
w[VLS_VPREG]=1;
p->bonus_zbrani[TPW_DYKA]=3;
break;
}
p->lives=w[VLS_MAXHIT];
p->mana=w[VLS_MAXMANA];
p->kondice=w[VLS_KONDIC];
p->jidlo=MAX_HLAD(p);
p->voda=MAX_ZIZEN(p);
memcpy(p->stare_vls,p->vlastnosti,sizeof(p->vlastnosti));
}
static char page1_tlac2(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
tlac2_press(INV_DESK+290,340,texty[120]);
timered_redraw();
if (cur_xicht==-1 || loc_select==-1) return 1;
cur_page=2;
generate_vlastnosti(postavy+cur_edited,loc_select);
return 1;
}
char enter_generator()
{
int i;
curcolor=0;bar(0,0,639,479);
for(i=0;i<MAX_XICHTS;i++)
{
char s[15];
sprintf(s,CHAR_NAME,i);
def_handle(hl_ptr+i+MAX_XICHTS,s,pcx_8bit_decomp,SR_BGRAFIKA);
}
for(i=0;i<MAX_XICHTS;i++)
{
char s[15];
sprintf(s,XICHT_NAME,i);
def_handle(hl_ptr+2*MAX_XICHTS+i,s,pcx_8bit_decomp,SR_BGRAFIKA);
}
memset(postavy,0,sizeof(postavy));
redraw_generator();
change_click_map(clk_page1,CLK_PAGE1);
}

571
game/clk_map.c Normal file
View file

@ -0,0 +1,571 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <types.h>
#include <event.h>
#include <devices.h>
#include <bgraph.h>
#include <bmouse.h>
#include <memman.h>
#include "globals.h"
#include "engine1.h"
#define get_shift_state() ((GetKeyState(VK_SHIFT) & 0x80)!=0)
int default_ms_cursor=0;
char spell_cast=0;
char clk_step(int id,int xa,int ya,int xr,int yr)
{
xa;ya;xr;yr;
spell_cast=0;
pick_set_cursor();
switch (id)
{
case H_SIPKY_S:step_zoom(0);break;
case H_SIPKY_J:step_zoom(2);break;
case H_SIPKY_SV:turn_zoom(1);break;
case H_SIPKY_SZ:turn_zoom(-1);break;
case H_SIPKY_Z:step_zoom(3);break;
case H_SIPKY_V:step_zoom(1);break;
default:return 0;
}
return 1;
}
char clk_touch_vyk(int sector,int side,int xr,int yr)
{
int i;
TVYKLENEK *v;
int x1,y1,x2,y2;
if (picked_item!=NULL && picked_item[1]!=0) return 0;
for(i=0;v=map_vyk+i,i<vyk_max;i++) if (v->sector==sector && v->dir==side) break;
if (i==vyk_max) return 0;
x1=v->xpos-v->xs/2;
x2=v->xpos+v->xs/2;
y1=320-(v->ypos+v->ys);
y2=320-(v->ypos);
x1+=MIDDLE_X-points[0][1][1].x;
x2+=MIDDLE_X-points[0][1][1].x;
y1+=MIDDLE_Y+points[0][1][1].y;
y2+=MIDDLE_Y+points[0][1][1].y;
if (x1<=xr && xr<=x2 && y1<=yr && yr<=y2)
{
if (picked_item==NULL)
{
for(i=0;v->items[i];i++);if (!i) return 0;
i--;
picked_item=NewArr(short,2);
picked_item[0]=v->items[i];picked_item[1]=0;
v->items[i]=0;
do_items_specs();
pick_set_cursor();
call_macro(viewsector*4+viewdir,MC_VYKEVENT);
return 1;
}
else
{
int fc;
word *w;
for(i=0;v->items[i];i++);if (i==8)
{
bott_disp_text(texty[36]);
return 1;
}
fc=picked_item[0];fc=glob_items[fc-1].vzhled+face_arr[0];
w=ablock(fc);
if (v->xs<w[0] || v->ys<w[0])
{
bott_disp_text(texty[35]);
return 1;
}
v->items[i]=picked_item[0];
v->items[i+1]=0;
call_macro(viewsector*4+viewdir,MC_VYKEVENT);
free(picked_item);picked_item=NULL;
pick_set_cursor();
return 1;
}
}
return 0;
}
char clk_touch(int id,int xa,int ya,int xr,int yr)
{
int x1,y1,x2,y2;
word *p;
int ext=0;
xa;ya;id;
spell_cast=0;
pick_set_cursor();
id=viewsector*4+viewdir;
if (map_sides[id].oblouk & 0x10) if (clk_touch_vyk(viewsector,viewdir,xr,yr))return 1;
if (map_sides[id].flags & SD_SEC_VIS && map_sides[id].sec!=0)
{
xa=map_sides[id].xsec<<1;
ya=320-(map_sides[id].ysec<<1);
p=(word *)ablock(map_sides[id].sec+num_ofsets[MAIN_NUM]);
x1=*p++;y1=*p++;
x2=xa+x1/2;y2=ya+y1/2;y1=y2-y1;x1=x2-x1;
x1+=MIDDLE_X-points[0][1][1].x;
x2+=MIDDLE_X-points[0][1][1].x;
y1+=MIDDLE_Y+points[0][1][1].y;
y2+=MIDDLE_Y+points[0][1][1].y;
ext=1;
}
else if (map_sides[id].sec==0)
{
x1=MIDDLE_X-points[0][0][1].x;
y1=MIDDLE_Y+points[0][1][1].y;
x2=640-x1;
y2=MIDDLE_Y+points[0][0][1].y;
ext=((map_sides[id].flags & SD_THING_IMPS) && !(map_sides[id].oblouk & SD_ITPUSH));
}
if (x1<=xr && xr<=x2 && y1<=yr && yr<=y2)
{
a_touch(viewsector,viewdir);
return ext;
}
return 0;
}
char clk_fly_cursor(int id,int xa,int ya,int xr,int yr)
{
id;
if (spell_cast)
{
spell_cast=0;
pick_set_cursor();
return 1;
}
if (yr>180)
if(xr>480) clk_step(H_SIPKY_V,xa,ya,xr,yr);
else if(xr<160) clk_step(H_SIPKY_Z,xa,ya,xr,yr);
else clk_step(H_SIPKY_J,xa,ya,xr,yr);
else
if(xr>480) clk_step(H_SIPKY_SV,xa,ya,xr,yr);
else if(xr<160) clk_step(H_SIPKY_SZ,xa,ya,xr,yr);
else clk_step(H_SIPKY_S,xa,ya,xr,yr);
return 1;
}
char clk_throw(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya;
if (picked_item!=NULL)
{
throw_fly(xr,yr,0);
return 1;
}
return 0;
}
char go_map(int id,int xa,int ya,int xr,int yr)
{
int i=15*256;
id;xa;ya;xr;yr;
if (cur_mode==MD_ANOTHER_MAP)
{unwire_proc();wire_proc();return 1;}
spell_cast=0;
pick_set_cursor();
send_message(E_KEYBOARD,i);
return 1;
}
char go_book(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
spell_cast=0;
pick_set_cursor();
wire_kniha();
return 1;
}
char konec(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
unwire_proc();
if (!message(2,0,1,texty[118],texty[76],texty[77],texty[78]))
{
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
send_message(E_CLOSE_MAP);
}
else wire_proc();
return 1;
}
char spell_casting(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
if (picked_item!=NULL) return 1;
spell_cast=1;
mouse_set_default(H_MS_WHO);
return 1;
}
char clk_sleep(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
if (mglob.map_effector==ME_MESTO)
{
bott_disp_text(texty[120]);
return 1;
}
if (!battle) add_task(8100,sleep_players);
return 1;
}
char start_invetory(int id,int xa,int ya,int xr,int yr)
{
THUMAN *p;
int i;
word *xs;
id;xa;ya;yr;
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
if (bott_display!=BOTT_NORMAL)
{
schovej_mysku();
bott_draw(1);
other_draw();
ukaz_mysku();
showview(0,376,640,104);
return 1;
}
xs=ablock(H_OKNO);
i=xr/xs[0];
if (i<POCET_POSTAV)
{
i=group_sort[i];
p=&postavy[i];
if (p->used)
{
if (ms_last_event.event_type & 0x2)
{
if (get_control_key_state())
{
if (p->sektor==viewsector)
{
add_to_group(i);
zmen_skupinu(p);
return 1;
}
return 1;
}
if (select_player!=i && select_player!=-1 && picked_item==NULL && !(cur_mode==MD_INV && battle_mode==MD_PREZBROJIT))
{
select_player=i;
zmen_skupinu(p);
bott_draw(1);
if (cur_mode==MD_INBATTLE) return 1;
}
if (p->groupnum!=cur_group || spell_cast)
{
if (picked_item!=NULL && p->sektor!=viewsector) return 0;
if (spell_cast && p->sektor==viewsector)
{
wire_fly_casting(i);
spell_cast=0;
mouse_set_default(H_MS_DEFAULT);
return 1;
}
zmen_skupinu(p);
if (cur_mode==MD_GAME && p->groupnum) return 1;
}
if (!p->groupnum && p->sektor!=viewsector) return 1;
unwire_proc();
wire_inv_mode(p);
return 0;
}
else
{
if (picked_item==NULL) return 0;
if (p->sektor==viewsector)
if (put_item_to_inv(p,picked_item))
{
free(picked_item);
picked_item=NULL;
}
pick_set_cursor();
if (cur_mode==MD_INV)
{
unwire_proc();
wire_inv_mode(human_selected);
}
return 1;
}
}
}
return 0;
}
char clk_group_all(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
unwire_proc();
wire_proc();
group_all();
return 1;
}
char clk_saveload(int id,int xa,int ya,int xr,int yr)
{
xa;ya;xr;yr;
if (id && battle)
{
bott_disp_text(texty[81]);other_draw();showview(0,0,0,0);
return 1;
}
if (id && !GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir))
return 1;
if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc();
unwire_proc();
cancel_render=1;
wire_save_load(id);
return 1;
}
char return_game(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
if (ms_last_event.event_type & 0x8)
{
unwire_proc();
wire_proc();
}
return 0;
}
char clk_mob_alter(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
xa=viewsector;
id=mob_map[xa];
while (id==0 || mobs[id-1].dialog==-1)
{
if (id) id=mobs[id-1].next;
if (id==0 && xa==viewsector)
if (~map_sides[(xa<<2)+viewdir].flags & SD_PLAY_IMPS)
{
xa=map_sectors[xa].step_next[viewdir];
id=mob_map[xa];
}
else return 0;
else return 0;
}
id--;
start_dialog(mobs[id].dialog,id);
return 1;
}
char empty_clk(int id,int xa,int ya,int xr,int yr) //tato udalost slouzi ke zruseni nekterych mist v globalni mape
{
id,xa,ya,xr,yr;
return 1;
}
static char sing_song_clk(int id,int xa,int ya,int xr,int yr)
{
char *xadr;
word *xs;
static char playing=0;
char standardflute=map_sectors[viewsector].sector_type>=S_FLT_SMER &&
map_sectors[viewsector].sector_type<S_FLT_SMER+4;
id,xa,ya,xr,yr;
if (bott_display!=BOTT_FLETNA) return 0;
xadr=ablock(H_FLETNA_MASK);
xs=(word *)xadr;
xadr+=6;
xadr+=*xs*yr+xr;
id=*xadr;
id--;
if (id<0 || id>12 || (ms_last_event.event_type & 0x4))
{
if (playing)
{
THE_TIMER *t;
stop_play_flute();
playing=0;
if (standardflute)
{
if (fletna_get_buffer_pos())
{
THE_TIMER *t;
if (standardflute)
{
t=add_to_timer(TM_FLETNA,100,1,check_fletna);
t->userdata[0]=viewsector;
t->userdata[1]=viewdir;
}
}
}
else
{
t=add_to_timer(TM_FLETNA,100,1,check_global_fletna);
t->userdata[0]=viewsector;
t->userdata[1]=viewdir;
}
}
return id<12;
}
if (~ms_last_event.event_type & 0x2) return 1;
start_play_flute(id);
playing=1;
if (standardflute)
{
fletna_pridej_notu(id);
delete_from_timer(TM_FLETNA);
}
else
{
fletna_glob_add_note(id);
delete_from_timer(TM_FLETNA);
}
return 1;
}
T_CLK_MAP clk_main_view[]=
{
{H_SIPKY_S,561,378,598,407,clk_step,2,H_MS_DEFAULT},
{H_SIPKY_SZ,530,387,560,418,clk_step,2,H_MS_DEFAULT},
{H_SIPKY_Z,529,419,555,453,clk_step,2,H_MS_DEFAULT},
{H_SIPKY_J,560,446,598,474,clk_step,2,H_MS_DEFAULT},
{H_SIPKY_SV,599,387,628,418,clk_step,2,H_MS_DEFAULT},
{H_SIPKY_V,605,420,632,454,clk_step,2,H_MS_DEFAULT},
{MS_GAME_WIN,0,17,639,377,clk_fly_cursor,8,-1},
{1,320,303,639,376,pick_item_,2,-1},//344
{0,0,303,320,376,pick_item_,2,-1},//344
{3,0,200,320,340,pick_item_,2,-1},//303
{2,320,200,639,340,pick_item_,2,-1},//303
{MS_GAME_WIN,0,17,639,377,clk_touch,2,-1},
{MS_GAME_WIN,0,17,639,377,clk_throw,2,-1},
{MS_GAME_WIN,0,17,639,250,clk_mob_alter,2,-1},
{-1,0,378,639,479,sing_song_clk,0xff,-1},
{-1,54,378,497,479,start_invetory,2+8,-1},
{-1,315,0,335,14,spell_casting,2,-1},
};
#define GAME_CLK_MAP 8
T_CLK_MAP game_clk_map[]=
{
{-1,499,379,518,390,clk_group_all,2,-1},
{-1,337,0,357,14,go_map,2,H_MS_DEFAULT},
{-1,291,0,313,14,go_book,2,H_MS_DEFAULT},
{-1,87,0,142,14,game_setup,2,H_MS_DEFAULT},
{-1,30,0,85,14,konec,2,H_MS_DEFAULT},
{1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT},
{0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT},
{-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT},
};
T_CLK_MAP *click_map=NULL;
int click_map_size=0;
T_CLK_MAP *global_click_map=NULL;
int global_click_map_size=0;
int find_in_click_map(MS_EVENT *ms,T_CLK_MAP *pt,int pocet,int *evtype)
{
int mscur=-1;
while (pocet--)
{
if (ms->x>=pt->xlu && ms->x<=pt->xrb && ms->y>=pt->ylu && ms->y<=pt->yrb)
{
if (mscur==-1) mscur=pt->cursor;
if ((*evtype) & pt->mask)
if (pt->proc!=NULL)
if (pt->proc(pt->id,ms->x,ms->y,ms->x-pt->xlu,ms->y-pt->ylu))
{
evtype[0]&=~pt->mask;
if (!evtype[0]) break;
}
}
pt++;
}
return mscur;
}
void ms_clicker(EVENT_MSG *msg,void **usr)
{
MS_EVENT *ms;
usr;
if (pass_zavora) return;
switch (msg->msg)
{
case E_INIT:return;
case E_DONE:return;
case E_MOUSE:
{
int mscur;
int msc=-1;
int evtype;
ms=get_mouse(msg);
mscur=-1;
evtype=ms->event_type;
mscur=find_in_click_map(ms,click_map,click_map_size,&evtype);
if (evtype) msc=find_in_click_map(ms,global_click_map,global_click_map_size,&evtype);
if (mscur==-1) mscur=msc;
if (mscur!=-1) mouse_set_cursor(mscur);
else mouse_set_cursor(default_ms_cursor);
}
break;
}
return;
}
void change_click_map(T_CLK_MAP *map,int mapsize)
{
click_map=map;
click_map_size=mapsize;
}
void save_click_map(void **map,int *mapsize)
{
*map=click_map;
*mapsize=click_map_size;
}
void restore_click_map(void *map,int mapsize)
{
click_map=(T_CLK_MAP *)map;
click_map_size=mapsize;
}
void change_global_click_map(T_CLK_MAP *map,int mapsize)
{
global_click_map=map;
global_click_map_size=mapsize;
}
void set_game_click_map(void)
{
change_global_click_map(game_clk_map,GAME_CLK_MAP);
}
T_CLK_MAP map_disabled=
{-1,0,0,639,479,empty_clk,0xff,-1};
void disable_click_map(void)
{
change_click_map(&map_disabled,1);
}

31
game/crc.c Normal file
View file

@ -0,0 +1,31 @@
#include <stdio.h>
#include <mem.h>
unsigned long l;
#define ZAKLAD_CRC 0xC005
char data[100000];
long delka;
FILE *f;
main()
{
int i;
f=fopen("CRC.C","rb");
memset(data,0,sizeof(data));
delka=fread(data,1,sizeof(data),f);
fclose(f);
memcpy(&l,data,2);i=0;
l%=ZAKLAD_CRC;
while(i<delka)
{
i+=2;
l<<=16;
memcpy(&l,data+i,2);
l%=ZAKLAD_CRC;
}
printf("CRC: %x\n",l);
}
z

1420
game/dialogy.c Normal file

File diff suppressed because it is too large Load diff

270
game/dlglib.c Normal file
View file

@ -0,0 +1,270 @@
/*
definice formatu-
:num - odstavec
#text
# asterix = muze obsahovat tyto znaky
. = normal text (vypisuje se)
_ = popis (zapisuje se do LOGu)
" = dialog (vypisuje se do LOGu a tiskne se)
? = vyber.. Nasleduje . nebo _ nebo '
* = prikaz
; = komentar
*/
#include <types.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <strlite.h>
#include <memman.h>
#include <bgraph.h>
FILE *dlg;
long *odstavce=NULL;
int pocet;
int selptr=0;
char get_article()
{
int c;
while ((c=fgetc(dlg))==32);
return (char)c;
}
#define new_line() while (fgetc(dlg)!='\n');
int count_pargh()
{
char c;
int i=0;
fseek(dlg,0,SEEK_SET);
c=get_article();
while (c!=0xff)
{
if (c==':') i++;
if (c!='\n') new_line();
c=get_article();
}
return i;
}
void read_pargh()
{
int s,i;
long *d;
char c;
if (odstavce!=NULL) free(odstavce);
odstavce=NULL;
s=(pocet=i=count_pargh())*sizeof(long)*2;
if (s==0) return;
odstavce=getmem(s);
d=odstavce;
fseek(dlg,0,SEEK_SET);
c=get_article();
while (c!=0xff && i)
{
if (c==':')
{
fscanf(dlg,"%d",&s);
*d++=s;
*d++=ftell(dlg);
i--;
}
if (c!='\n') new_line();
c=get_article();
}
}
void dlg_error(char *chyba)
{
closemode();
printf("Error in dialoge: %s\n",chyba);
exit(1);
}
long *najdi_odstavec(int odstavec)
{
long *d;
int i;
d=odstavce;
for(i=0;i<pocet && *d!=odstavec;i++) d+=2;
if (i==pocet)
{
char s[50];
sprintf(s,"Can't find paragraph num %d",odstavec);
dlg_error(s);
}
return d;
}
char jdi_na_odstavec(int odstavec)
{
long *l,m;
char c;
l=najdi_odstavec(odstavec);
m=l[1] & 0xffffff;
c=l[1]>>24;
fseek(dlg,m,SEEK_SET);
return c;
}
void set_flags(int n,long maskand,long maskor)
{
long *l;
l=najdi_odstavec(n);
l[1]&=(maskand<<24)+0xffffff;
l[1]|=maskor<<24;
}
int param(char *c)
{
int i;
sscanf(c,"%d",&i);
return i;
}
int nparam(int n,char *c)
{
char *d;
if (n)
{
d=c;
while (n--) d=(char *)strchr(d+1,',');
}
else d=c-1;
if (d==NULL) return -1;else return param(d+1);
}
void proved_goto(int num)
{
char c;
long l;
l=ftell(dlg);
c=jdi_na_odstavec(num);
while (c & 1)
{
int i,j;
j=fscanf(dlg,"%d",&i);
if (j) c=jdi_na_odstavec(i); else
{
c=0;
fseek(dlg,l,SEEK_SET);
}
}
}
void proved_d(char *code,char *text)
{
static int mode=0;
static char *save_text;
do
{
if (mode==0)
{
*code=get_article();
switch (*code)
{
case ';':
case ':':*code=0xff;new_line();break;
case '.':*code=1;break;
case '_':*code=2;break;
case '"':*code=3;break;
case '?':*code=4;selptr++;break;
case '*':*code=0;break;
default :*code=0xff;break;
}
if (*code!=0xff)fscanf(dlg,"%[^\n]",text);
if (*code==0)
{
strupr(text);
if (!strncmp(text,"GOTO",4))
{
int n;
sscanf(text+4,"%d",&n);
proved_goto(n);
}
if (!strncmp(text,"JUMP",4))
{
int n;
sscanf(text+4,"%d",&n);
jdi_na_odstavec(n);
}
else if (!strncmp(text,"DISABLE",7)) set_flags(param(text+7),0xff,1);
else if (!strncmp(text,"ENABLE",6)) set_flags(param(text+7),0xfe,0);
else if (!strncmp(text,"CHOICE",6))
{
*text=selptr;
selptr=0;
*code=5;
mode=1;
save_text=getmem(strlen(text)-6+1);
strcpy(save_text,text+6);
}
else if (!strncmp(text,"STOP",4)) *code=7;
else if (!strncmp(text,"MENU",4)) selptr=param(text+4);
}
else if (*code==4)
{
long *l=najdi_odstavec(param(text));
char c,*d;
c=l[1]>>24;
if (c & 1) *code=6;
d=text;while (*d>='0' && *d<='9') d++;
strcpy(text,d);
}
}
else if (mode==1)
{
int i=text[1],j;
*code=5;
j=nparam(i,save_text);
if (j==-1) return;
free(save_text);
proved_goto(j);
set_flags(j,0xff,0x1);
mode=0;
*code=0;
}
}
while (*code==0);
}
main()
{
char code,text[300];
dlg=fopen("test.txt","r");
read_pargh();
proved_goto(1);
proved_d(&code,text);
while (code!=7)
{
switch (code)
{
case 1:printf("%s\n",text);break;
case 2:
case 3:printf("%s\n",text);break;
case 4:printf(" %c.%s\n",selptr+64,text);break;
case 5:text[1]=toupper(getche())-65;putchar('\n');break;
}
proved_d(&code,text);
}
}

91
game/dump.cpp Normal file
View file

@ -0,0 +1,91 @@
#include <iostream>
#include <filesystem>
#include <regex>
#include <string>
#include <optional>
#include <memman.h>
int findMaxDumpNumber(const std::string &directoryPath) {
namespace fs = std::filesystem;
std::regex pattern(R"(dump(\d{4})\.bmp)");
int maxNumber = -1;
for (const auto &entry : fs::directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
std::smatch match;
std::string fileName = entry.path().filename().string();
if (std::regex_match(fileName, match, pattern)) {
int number = std::stoi(match[1]); // Extrahujeme číslo NNNN
if (number > maxNumber) {
maxNumber = number; // Aktualizujeme maximální číslo
}
}
}
}
return maxNumber;
}
extern "C" {
void save_dump(const uint16_t *screen_addr,
unsigned int width,
unsigned int height,
unsigned int linelen);
}
void save_dump(const uint16_t *screen_addr,
unsigned int width,
unsigned int height,
unsigned int linelen) {
static int dump_counter = -1;
FILE *f;
int i, r, g, b, x, y;
const uint16_t *a;
char c[20];
if (dump_counter == -1) {
dump_counter = findMaxDumpNumber(".");
SEND_LOG("(DUMP) Dump counter sets to %d", dump_counter, 0);
}
sprintf(c, "dump%04d.bmp", ++dump_counter);
SEND_LOG("(DUMP) Saving screen shot named '%s'", c, 0);
f = fopen(c, "wb");
fputc('B', f);
fputc('M', f);
i = width * height * 3 + 0x36;
fwrite(&i, 1, 4, f);
i = 0;
fwrite(&i, 1, 4, f);
i = 0x36;
fwrite(&i, 1, 4, f);
i = 0x28;
fwrite(&i, 1, 4, f);
i = width;
fwrite(&i, 1, 4, f);
i = height;
fwrite(&i, 1, 4, f);
i = 1;
fwrite(&i, 1, 2, f);
i = 24;
fwrite(&i, 1, 2, f);
i = 0;
fwrite(&i, 1, 4, f);
i = width * height * 3;
fwrite(&i, 1, 4, f);
for (i = 4, r = 0; i > 0; i--)
fwrite(&r, 1, 4, f);
for (y = height; y > 0; y--) {
const uint16_t *scr = screen_addr;
a = scr + (y - 1) * linelen;
for (x = 0; x < width; x++) {
i = a[x];
b = (i & 0x1f) << 3;
g = (i & 0x7ff) >> 3;
r = i >> 8;
i = ((r * 256) + g) * 256 + b;
fwrite(&i, 1, 3, f);
}
}
fclose(f);
}

66
game/encrypt.c Normal file
View file

@ -0,0 +1,66 @@
#include <stdio.h>
#include <malloc.h>
#include <mem.h>
#include <stdlib.h>
#include <string.h>
FILE *source,*target;
void encrypt_file(FILE *sr,FILE *tg)
{
int i,j,last=0;
i=getc(sr);
while (i!=EOF)
{
j=i-last;
last=i;
putc(j,tg);
i=getc(sr);
}
}
void open_files(char *src,char *tgr)
{
if (tgr==NULL)
{
char *c,*d;
tgr=alloca(strlen(src)+5);
strcpy(tgr,src);
c=strrchr(tgr,'\\');
d=strrchr(tgr,'.');
if (c>d) d=strchr(tgr,0);
strcpy(d,".ENC");
}
source=fopen(src,"rb");
target=fopen(tgr,"wb");
}
void close_files()
{
fclose(source);
fclose(target);
}
char main(int argc,char **argv)
{
if (argc<2)
{
puts("Pouziti: ENCRYPT zdroj.ext [cil.ext] \n"
"\n"
"Pokud nezadas cil, doplni se zdroj s koncovkou .enc\n"
"Nikdy nezadavej pouze cestu jako cil. Vzdycky uved jmeno!");
return 0;
}
if (argc==2) open_files(argv[1],NULL);
else open_files(argv[1],argv[2]);
if (source==NULL)
{puts("Nemuzu najit zdrojovy soubor\n");return 1;};
if (target==NULL)
{puts("Nemuzu otevrit cil pro zapis\n");return 1;};
encrypt_file(source,target);
close_files();
puts("Ok.");
return 0;
}

2140
game/enemy.c Normal file

File diff suppressed because it is too large Load diff

1405
game/engine1.c Normal file

File diff suppressed because it is too large Load diff

162
game/engine1.h Normal file
View file

@ -0,0 +1,162 @@
#ifndef __ENGINE1_H
#define __ENGINE1_H
#define VIEW_SIZE_X 640
#define VIEW_SIZE_Y 360
#define TAB_SIZE_X 640
#define TAB_SIZE_Y 600
#define MIDDLE_X 320
#define MIDDLE_Y 112
#define TXT_SIZE_Y 320
#define TXT_SIZE_X_3D 74
#define TXT_SIZE_X 500
#define VIEW3D_X 4
#define VIEW3D_Z 5
#define START_X1 357
#define START_Y1 305
#define START_X2 357
#define START_Y2 -150
#define FACTOR_3D 3.33
#define ZOOM_PHASES 9
#define SCREEN_OFFLINE (17)
#define SCREEN_OFFSET (scr_linelen2*SCREEN_OFFLINE)
#define C_YMAP_SIZE 90
#define F_YMAP_SIZE 199
#define CF_XMAP_SIZE 7
#define SHADE_STEPS 5
#define SHADE_PAL (SHADE_STEPS*512*2)
void general_engine_init(void);
void draw_floor_ceil(int celx,int cely,char f_c,void *txtr);
void show_cel2(int celx,int cely,void *stena,int xofs,int yofs,char rev);
//zobrazi primou stenu ktera lezi pred nebo napravo od pozorovatele
void show_cel(int celx,int cely,void *stena,int xofs,int yofs,char rev);
void turn_left();
void turn_right();
void zooming_backward(word *background);
void zooming_forward(word *background);
void OutBuffer2nd(void);
void CopyBuffer2nd(void);
void report_mode(int);
void draw_item(int celx,int cely,int posx,int posy,short *pic,int index);
void draw_item2(int celx,int cely,int xpos,int ypos,void *texture,int index);
//void textmode_effekt();
//#pragma aux textmode_effekt modify[eax ebx ecx edx edi];
void clear_buff(word *background,word backcolor,int lines);
typedef struct zoominfo
{
void *startptr, *texture;
long texture_line,line_len;
long *xtable;
short *ytable;
word *palette;
word ycount;
word xmax;
}ZOOMINFO;
typedef struct t_info_y
{
long drawline; //ukazatel na radku na ktere bude stena zacinat
word vert_size; //konecna velikost steny, pokud ma pocatecni velikost TXT_SIZE_Y
word vert_total; //maximalni velikost textury aby jeste nepresahla obrazovku
short zoom_table[TAB_SIZE_Y]; //tabulka pro zoomovaci rutiny
}T_INFO_Y;
typedef struct t_info_x_3d
{
char used; // 1 pokud je tato strana videt
integer xpos; //bod od leveho okraje
word txtoffset; //posunuti x vuci texture
word point_total; //rozdil mezi levym prednim a levym zadnim okrajem postranni steny (v adresach)
long zoom_table[VIEW_SIZE_X]; //zoomovaci tabulka pro osu x pro postranni steny
}T_INFO_X_3D;
typedef struct t_info_x
{
char used; // 1 pokud je tato strana videt
integer xpos; //bod od leveho okraje
integer xpos2; //totez ale pro pravou stranu
word txtoffset; //posunuti x vuci texture
word max_x; //pocet viditelnych bodu z textury
word point_total; //celkovy pocet adres mezi levym a pravym okrajem
long zoom_table[VIEW_SIZE_X]; //zoomovaci tabulka pro osu x pro kolme steny
}T_INFO_X;
typedef struct t_floor_map
{
long lineofs,linesize,counter,txtrofs;
}T_FLOOR_MAP;
typedef struct all_view
{
T_INFO_Y y_table[VIEW3D_Z+1];
T_INFO_X_3D z_table[VIEW3D_X][VIEW3D_Z];
T_INFO_X x_table[VIEW3D_X][VIEW3D_Z+1];
T_FLOOR_MAP f_table[CF_XMAP_SIZE][F_YMAP_SIZE];
T_FLOOR_MAP c_table[CF_XMAP_SIZE][C_YMAP_SIZE];
}ALL_VIEW;
typedef struct t_point
{
int x,y;
}T_POINT;
typedef T_POINT t_points[VIEW3D_X+1][2][VIEW3D_Z+1];
extern word *background;
extern t_points points;
extern int zooming_step;
extern int rot_phases;
extern int rot_step;
extern word *buffer_2nd;
extern char show_names;
extern char show_lives;
extern char secnd_shade;
typedef short palette_t[256];
typedef struct drw_enemy_struct
{
void *txtr;
int celx,cely,posx,posy,adjust,shiftup,num;
char mirror;
char stoned;
palette_t *palette;
}DRW_ENEMY;
void enemy_draw(void *src,void *trg,int shade,int scale,int maxspace,int clip);
//#pragma aux enemy_draw parm[ESI][EDI][EBX][EDX][EAX][ECX]
void enemy_draw_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip);
//#pragma aux enemy_draw_transp parm[ESI][EDI][EBX][EDX][EAX][ECX]
void enemy_draw_mirror_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip);
//#pragma aux enemy_draw_mirror_transp parm[ESI][EDI][EBX][EDX][EAX][ECX]
void enemy_draw_mirror(void *src,void *trg,int shade,int scale,int maxspace,int clip);
//#pragma aux enemy_draw_mirror parm[ESI][EDI][EBX][EDX][EAX][ECX]
//clip je v poradi vpravo - vlevo (HiLo)
void draw_enemy(DRW_ENEMY *drw);
void draw_player(short *txtr,int celx,int cely,int posx,int posy,int adjust,char *name);
void set_lclip_rclip(int celx,int cely,int lc,int rc);
void draw_spectxtr(short *txtr,int celx,int cely,int xpos);
int turn_speed(int turnspeed); //oba je nutne volat na zacatku
int zoom_speed(int zoomspeed);
void scroll_and_copy(void *pic,void *slide, void *scr, int size,int shift, void *lineinfo);
//#pragma aux scroll_and_copy parm[esi][ebx][edi][ecx][edx][eax]
void set_backgrnd_mode(int mode);
int get_item_top(int celx,int cely,int posx,int posy,word *txtr,int index);
//vraci nejnizsi souradnici y predmetu leziciho na zemi v celx, cely na pozici posx,posy;
#endif

2188
game/engine2.asm Normal file

File diff suppressed because it is too large Load diff

1316
game/engine2.c Normal file

File diff suppressed because it is too large Load diff

16
game/extras.h Normal file
View file

@ -0,0 +1,16 @@
#define EX_RANDOM_BACKFIRES 1 //hotovo
#define EX_RESPAWN_MONSTERS 2 //hotovo
#define EX_ALTERNATEFIGHT 4 //hotovo
#define EX_RECOVER_DESTROYED_ITEMS 8 //hotovo
#define EX_MULTIPLE_ITEMS_IN_CURSOR 16 //zruseno
#define EX_BAG_EXTENDED 32 //hotovo
#define EX_SHIELD_BLOCKING 64 //hotovo
#define EX_FAST_TRADE 128 //hotovo
#define EX_ALWAYS_MINIMAP 256 //hotovo
#define EX_GROUP_FLEE 512
#define EX_NOHUNGRY 1024
#define EX_AUTOOPENBOOK 2048
#define EX_AUTOSHOWRUNE 4096
#define EX_WALKDIAGONAL 8192
extern int game_extras;

1518
game/gamesave.c Normal file

File diff suppressed because it is too large Load diff

1741
game/globals.h Normal file

File diff suppressed because it is too large Load diff

660
game/globmap.c Normal file
View file

@ -0,0 +1,660 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <ctype.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include <unistd.h>
#define GLOBMAP "GLOBMAP.DAT"
#define ODDELOVACE ";:=,\n{}"
#define OD_COMMAND oddelovace[0]
#define OD_CRIT oddelovace[1]
#define OD_SET oddelovace[2]
#define OD_COMMA oddelovace[3]
#define OD_NEWLINE oddelovace[4]
#define OD_IN oddelovace[5]
#define OD_OUT oddelovace[6]
#define OD_COMMENT '`'
#define INDEXU 256
typedef struct index_def
{
char mapname[13];
char *text;
char defined;
}INDEX_DEF;
static INDEX_DEF *index_tab=NULL;
static char last_index=1;
static int usemap;
static FILE *glbm;
static char oddelovace[]=ODDELOVACE;
static int last_oddelovac;
static int linecounter=0;
static int enter_sector=0;
static char *symbolmap[]=
{
"A !",
"B &&",
"D BREAK",
"O CURMAP", // krit
"E DRAW",
"F ESCAPE",
"G FLG", // krit
"P IFDEF", // krit
"I INDX",
"I INDEX",
"K MAP",
"Q SEKTOR", // krit
"Q SECTOR", // krit
"L TEXT",
"M UNDEF",
"N USEMAP",
"C ||",
};
#define OP_NOT 'A'
#define OP_AND 'B'
#define OP_OR 'C'
#define OP_INDX 'I'
#define OP_DRAW 'E'
#define OP_TEXT 'L'
#define OP_MAP 'K'
#define OP_UNDEF 'M'
#define OP_FLG 'G'
#define OP_USEMAP 'N'
#define OP_BREAK 'D'
#define OP_ESCAPE 'F'
#define OP_CURMAP 'O'
#define OP_ISDEF 'P'
#define OP_SEKTOR 'Q'
#define ODD last_oddelovac
static char cti_int_num(int *readed)
{
return !fscanf(glbm,"%d",readed);
}
static int find_symbol(char **symbolmap,int list_len,int offset,char *symbol)
{
int start_pos;
char chr=0;
start_pos=0;
while (start_pos<list_len && *symbol)
{
char *ss=symbolmap[start_pos];
if (ss[offset]==*symbol)
{
chr=*symbol;
symbol++;offset++;continue;
}
if (ss[offset]>*symbol) return -1;
if (chr && ss[offset-1]!=chr) return -1;
start_pos++;
}
if (*symbol) return -1;
return start_pos;
}
static char get_symbol(char *symb)
{
int i;
i=find_symbol(symbolmap,sizeof(symbolmap)/sizeof(char *),2,symb);
if (i==-1) return 0;else return symbolmap[i][0];
}
static int cti_oddelovac(void)//cte prvni oddelovac - preskakuje mezery
{
int c;
do
{
c=getc(glbm);
if (c==OD_COMMENT) while((c=getc(glbm))!='\n');
if (c=='\n') linecounter++;
if (strchr(oddelovace,c)!=NULL || c==EOF) return c;
}
while (c==' ' || c=='\x9');
ungetc(c,glbm);
return 0;
}
static int cti_retezec(int znaku,char *text,char mezera,char upcase)
{
int c;
znaku--;
if (mezera)
{
while((c=getc(glbm))==32 || c==9);
}
else c=getc(glbm);
while (strchr(oddelovace,c)==NULL && ((c!=32 && c!=9) || !mezera) && c!=EOF)
{
if (upcase) c=toupper(c);
if (znaku)
{
*text++=c;
znaku--;
}
c=getc(glbm);
}
if (c!=32 && c!=9) ungetc(c,glbm);
*text=0;
return 0;
}
static void error(char *text)
{
char popis[300];
sprintf(popis,"Chyba v souboru "GLOBMAP" na radce %d.\r\n%s",linecounter,text);
SEND_LOG("(ERROR) %s : %s",popis,text);
closemode();
display_error(popis);
exit(0);
}
static void ex_error(char znak)
{
char ex_text[100];
sprintf(ex_text,"Ocekava se znak '%c'",znak);
error(ex_text);
}
static void ready_index_tab(void)
{
index_tab=NewArr(INDEX_DEF,INDEXU);
memset(index_tab,0,INDEXU*sizeof(INDEX_DEF));
}
static void purge_index_tab(void)
{
if (index_tab)
{
int i;
for(i=0;i<255;i++) if (index_tab[i].text!=NULL) free(index_tab[i].text);
free(index_tab);
index_tab=NULL;
}
}
static char test_kriterii(void)
{
char last_op=0;
char not_op=0;
char text[128];
char hodn;
char vysl=0;
char symb,*c;
while (ODD==0 || ODD==OD_NEWLINE)
{
cti_retezec(100,text,1,1);
c=text;if (*c=='!') not_op=1,c++;
symb=get_symbol(c);
switch (symb)
{
case OP_AND:last_op=1;break;
case OP_NOT:not_op=!not_op;break;
case OP_OR:last_op=0;break;
case OP_SEKTOR:
{
int c;
if (cti_int_num(&c)) error("O<EFBFBD>ek<EFBFBD>v<EFBFBD> se <20><>slo");
hodn=c==enter_sector;
}
break;
case OP_CURMAP:cti_retezec(100,text,1,1);
hodn=!strcmp(level_fname,text);
break;
case OP_ISDEF:{
int c;
if (cti_int_num(&c)) error("O<EFBFBD>ek<EFBFBD>v<EFBFBD> se <20><>slo");
hodn=index_tab[c].defined;
}
break;
case OP_FLG:
{
int flag_num;
if (cti_int_num(&flag_num)) error("Za FLG mus<75> b<>t <20><>slo!");
if (flag_num>255) error("<EFBFBD><EFBFBD>slo vlajky (FLG) mus<75> b<>t v rozsahu 0-255!");
hodn=(test_flag(flag_num)!=0);
}
break;
default:
{
char c[200];
sprintf(c,"%s%s.TMP",pathtable[SR_TEMP],text);
hodn=!access(c,0);
}
break;
}
hodn^=not_op;not_op=0;
if (last_op) vysl&=hodn;else vysl|=hodn;
ODD=cti_oddelovac();
}
return vysl;
}
static char proved_prikaz()
{
char prikaz[20];
char text[128];
int c;
char op;
ODD=cti_oddelovac();
while (ODD==OD_NEWLINE) ODD=cti_oddelovac(); //preskoc prazdne radky
if (ODD==OD_IN) return 0; //cti znak {
do
{
while (ODD==OD_NEWLINE || ODD==OD_COMMAND) ODD=cti_oddelovac();
if (ODD!=0) error("O<EFBFBD>ek<EFBFBD>v<EFBFBD> se jm<6A>no definice (p<><70>klad: INDX=)");
cti_retezec(20,prikaz,1,1);
op=get_symbol(prikaz);
if (op==OP_BREAK) return 1;
ODD=cti_oddelovac();
if (ODD!=OD_SET) ex_error(OD_SET);
switch(op)
{
case OP_INDX:
if (cti_int_num(&c)) error("INDX=?");
if (c<0 || c>255) error("INDX=<0,255>");
index_tab[last_index=c].defined=1;
break;
case OP_TEXT:
cti_retezec(128,text,0,0);
index_tab[last_index].text=NewArr(char,strlen(text)+1);
strcpy(index_tab[last_index].text,text);
break;
case OP_MAP:
cti_retezec(13,index_tab[last_index].mapname,1,1);
break;
case OP_DRAW:
{
char file[20];
int xp,yp;
int h;
cti_retezec(20,file,1,1);
ODD=cti_oddelovac();if (ODD!=OD_COMMA)ex_error(OD_COMMA);
if (cti_int_num(&xp)) error("O<EFBFBD>ek<EFBFBD>v<EFBFBD> se <20><>slo xp");
ODD=cti_oddelovac();if (ODD!=OD_COMMA)ex_error(OD_COMMA);
if (cti_int_num(&yp)) error("O<EFBFBD>ek<EFBFBD>v<EFBFBD> se <20><>slo yp");
h=find_handle(file,pcx_8bit_decomp);
if (h==-1) def_handle(h=end_ptr++,file,pcx_8bit_decomp,SR_DIALOGS);
put_picture(xp,yp+SCREEN_OFFLINE,ablock(h));
}
break;
case OP_UNDEF:
if (cti_int_num(&c)) error("UNDEF=?");
if (c<0 || c>255) error("UNDEF=<0,255>");
index_tab[c].defined=0;
break;
case OP_USEMAP:
{
char file[20];
cti_retezec(20,file,1,1);
usemap=find_handle(file,pcx_8bit_nopal);
if (usemap==-1) def_handle(usemap=end_ptr++,file,pcx_8bit_nopal,SR_DIALOGS);
}
break;
case OP_ESCAPE:
{
char *s;
cti_retezec(20,prikaz,1,1);
fclose(glbm);
s=find_map_path(prikaz);
if ((glbm=fopen(s,"r"))==NULL) error(s);
free(s);
return 0;
}
default:error(prikaz);
}
ODD=cti_oddelovac();
if (ODD!=OD_COMMAND && ODD!=OD_NEWLINE && ODD!=EOF) ex_error(OD_COMMAND);
}
while (ODD!=OD_NEWLINE && ODD!=EOF);
return 0;
}
static void preskoc_prikaz(void)
{
char ending=0;
int uroven=0;
char last;
char text;
do
{
last=ODD;
ODD=cti_oddelovac();
switch (ODD)
{
case 0:cti_retezec(1,&text,0,0);ending=1;break;
case '\n':if (ending && uroven==0) return;break;
case EOF: if (uroven!=0)ex_error(OD_OUT);return;break;
case '{': if (last==OD_CRIT || last==OD_NEWLINE) uroven++;break;
case '}': if (last==OD_NEWLINE) uroven--; if (uroven<0) ex_error(OD_IN);
else if (uroven==0)return;break;
}
if (ODD!=0) ending=0;
}
while(1);
}
static void do_script(void)
{
char *s;
char vysledek;
s=find_map_path(GLOBMAP);
linecounter=0;
glbm=fopen(s,"r");
free(s);
if (glbm==NULL) error("Chyb<EFBFBD> uveden<65> soubor...");
ODD=cti_oddelovac();
do
{
if (ODD==0) //existuji kriteria
{
vysledek=test_kriterii();
}
else vysledek=1;
if (ODD==OD_CRIT) //oddelovac kriterii
{
char c=0;
if (vysledek)c=proved_prikaz();else preskoc_prikaz();
if (c) break;
}
ODD=cti_oddelovac();
}
while(ODD!=EOF);
fclose(glbm);
}
static int found_place=0;
static char flp_validate2(word sector)
{
TMOB *m;
char c;
if (mob_map[sector])
{
m=mobs+mob_map[sector]-1;
if (m->vlajky & ~MOB_PASSABLE) return 0;
if (!m->next)
if (mobs[m->next-1].vlajky & ~MOB_PASSABLE) return 0;
}
c=map_sectors[sector].sector_type;
if (c==S_DIRA || ISTELEPORT(c) || c==S_LAVA || c==S_VODA ) return 0;
return 1;
}
static char flp_validate(word sector)
{
TMOB *m;
char c;
if (found_place) return 0;
if (mob_map[sector])
{
m=mobs+mob_map[sector]-1;
if (m->vlajky & ~MOB_PASSABLE) return 0;
if (!m->next)
if (mobs[m->next-1].vlajky & ~MOB_PASSABLE) return 0;
}
c=map_sectors[sector].sector_type;
if (~map_coord[sector].flags & 1) return 0;
if (c==S_DIRA || ISTELEPORT(c) || c==S_LAVA || c==S_VODA ) return 0;
if (c==S_LEAVE && !found_place) found_place=sector;
return 1;
}
static int find_leave_place(int sector)
{
found_place=0;
if (map_sectors[sector].sector_type==S_LEAVE) return sector;
labyrinth_find_path(sector,65535,(SD_PLAY_IMPS | SD_SECRET),flp_validate,NULL);
return found_place;
}
int macro_load_another_map();
static int select_mode = 0;
static char load_index_map(int index)
{
TMA_LOADLEV x;
int lv,i;
THUMAN *h;
if (select_mode)
{
char *a;
a=alloca(strlen(index_tab[index].mapname)+1);strcpy(a,index_tab[index].mapname);
wire_automap_file(a);
return 1;
}
if (!strcmp(index_tab[last_index].mapname,level_fname)) return 0;
lv=find_leave_place(viewsector);
if (lv<1)
{
bott_disp_text(texty[121]);
return 0;
}
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && h->lives)
if (h->sektor!=lv && !labyrinth_find_path(h->sektor,lv,(SD_PLAY_IMPS | SD_SECRET),flp_validate2,NULL))
{
char c[20];
bott_disp_text(itoa(i,c,10));
return 0;
}
if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return 0;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && h->lives) h->sektor=lv;
viewsector=lv;
strncpy(x.name,index_tab[index].mapname,12);
x.start_pos=0;
x.dir=0;
macro_load_another_map(&x);
return 0;
}
static char *fly_text;
static int fly_x,fly_y,fly_xs,fly_ys;
static void *fly_background;
EVENT_PROC(global_map_point)
{
MS_EVENT *ms;
user_ptr;
WHEN_MSG(E_INIT)
{
fly_background=NULL;last_index=0;fly_text=NULL;
fly_x=0;fly_y=0;fly_xs=4;fly_ys=4;
}
WHEN_MSG(E_MOUSE)
{
int x,y,i,xs,ys;
char *ptr;
ms=get_mouse(msg);
if (ms->event_type & 0x1)
{
x=ms->x;y=ms->y-SCREEN_OFFLINE;
if (y<0 || y>359) return;
else
{
alock(usemap);
ptr=ablock(usemap);
ptr+=640*y+x+6;
i=*ptr;
}
y+=60;
schovej_mysku();
if (fly_background!=NULL)put_picture(fly_x,fly_y,fly_background);
set_font(H_FTINY,RGB555(31,31,0));
xs=fly_xs;ys=fly_ys;
if (i!=last_index)
{
free(fly_background);
last_index=i;
if (index_tab[i].defined)
{
fly_text=index_tab[i].text;
mouse_set_default(H_MS_ZARE);
set_ms_finger(5,5);
}
else
{
fly_text=NULL;
mouse_set_default(H_MS_DEFAULT);
}
if (fly_text!=NULL)
{
xs=text_width(fly_text)+4;
ys=text_height(fly_text)+4;
fly_background=NewArr(word,xs*ys*2+6);
}
else
{
fly_text=NULL;xs=4;ys=4;
fly_background=NULL;
}
}
if (fly_text!=NULL)
{
if ((x+xs)>639) x=639-xs;
get_picture(x,y,xs,ys,fly_background);
trans_bar(x,y,xs,ys,0);
position(x+2,y+2);outtext(fly_text);
}
send_message(E_MOUSE,msg);
ukaz_mysku();
showview(fly_x,fly_y,fly_xs+1,fly_ys);
showview(fly_x=x,fly_y=y,(fly_xs=xs)+1,fly_ys=ys);
aunlock(usemap);
}
if (ms->event_type & 0x2 && ms->y>SCREEN_OFFLINE && ms->y<378)
{
if (last_index && index_tab[last_index].defined) if (load_index_map(last_index)) return;
else;else return;
unwire_proc();
wire_proc();
msg->msg=-1;
}
if (ms->event_type & 0x8)
{
unwire_proc();
wire_proc();
msg->msg=-1;
}
}
WHEN_MSG(E_DONE)
{
free(fly_background);
}
}
void unwire_global_map()
{
purge_index_tab();
send_message(E_DONE,E_MOUSE,global_map_point);
set_select_mode(0);
pick_set_cursor();
}
void wire_global_map()
{
unwire_proc();
schovej_mysku();
ready_index_tab();
do_script();
ukaz_mysku();
showview(0,0,0,0);
send_message(E_ADD,E_MOUSE,global_map_point);
unwire_proc=unwire_global_map;
change_click_map(NULL,0);
}
static void *old_wire_save;
static int old_viewsector;
static void empty_unwire()
{
}
static void unwire_automap_file()
{
load_map_automap(level_fname);
wire_proc=old_wire_save;
viewsector=old_viewsector;
build_player_map();
bott_draw(0);
wire_proc();
}
void wire_automap_file(char *mapfile)
{
int c;
if ((c=get_leaving_place(mapfile))==0) return;
old_wire_save=wire_proc;
old_viewsector=viewsector;
viewsector=c;
unwire_proc();
unwire_proc=empty_unwire;
wire_proc=unwire_automap_file;
save_map_state();
load_map_automap(mapfile);
noarrows=1;
cur_mode=MD_ANOTHER_MAP;
show_automap(1);
cancel_render=1;
}
char set_select_mode(char mode)
{
char last=select_mode;
select_mode=mode;
return last;
}
void cestovat()
{
}

1623
game/interfac.c Normal file

File diff suppressed because it is too large Load diff

3012
game/inv.c Normal file

File diff suppressed because it is too large Load diff

715
game/kniha.c Normal file
View file

@ -0,0 +1,715 @@
#include <skeldal_win.h>
/*
Popis jazyka pro psani textu do knihy
[cislo]
.... text
....
[/cislo]
Tagy
<P> paragraph
<BR> break line
<IMG SRC="filename" ALIGN=/left,right,center/>
<HR> horizontal rule
<EP> page end
-----------------------------
Vnitrni zapis
Escape sekvence
ESC s <vynechat> - mezera n bodu
ESC p <filename> <x> <y> obrazek na souradnicich x a y
ESC e - konec stranky (jako prvni v textu)
ESC h - horizontalni rule (jako prvni v textu)
ESC l <skip> - konec radky (skip je pocet vynechanych bodu)
Zapis cisla - to je hexa cislo od 1-255 pokud se nevejde do rozsahu je po 256
pridana dalsi hodnota, tj 255 se zapise jako 255,1,
350 se zapise jako 255,96,
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <strlite.h>
#include <bgraph.h>
#include <memman.h>
#include <event.h>
#include "globals.h"
#define XMAX 254
#define YMAX 390
#define XLEFT 34
#define YLEFT 50
#define XRIGHT 354
#define PARAGRAPH "P"
#define BREAKLINE "BR"
#define IMAGE "IMG"
#define HOR_RULE "HR"
#define CENTER1 "CENTER"
#define CENTER2 "/CENTER"
#define DISTEND1 "DISTEND"
#define DISTEND2 "/DISTEND"
#define ALIGN "ALIGN"
#define PIC_LINE "LINE"
#define PIC_LSIZ "LSIZE"
#define SRC "SRC"
#define ALEFT "LEFT"
#define ARIGHT "RIGHT"
#define ACENTER "CENTER"
#define ANUM_LEFT 1
#define ANUM_RIGHT 2
#define ANUM_CENTER 0
#define END_PAGE 'e'
#define SPACE 's'
#define PICTURE 'p'
#define HRUL 'h'
#define END_LINE 'l'
#define BOOK_FILE "_BOOK.TMP"
static int center=0;
static int distend=0;
static TSTR_LIST all_text=NULL;
static char read_buff[256];
static char write_buff[256];
static int buff_pos=0;
static int buff_end=0;
static int total_width=XMAX;
static int left_skip=0;
static int linepos=0,last_skip=1;
static int picture_len=0;
static char winconv=0;
static int relpos=0;
//static char xlat_table[128]="<22>__<5F><5F>_____<5F>_____<5F>__<5F><5F>__________________________________<5F>___<5F>__<5F><5F>__<5F><5F>_<EFBFBD>__<5F><5F>____<5F><5F><EFBFBD>__<5F>___<5F>___<5F>__<5F><5F>__<5F><5F>_<EFBFBD>__<5F><5F>____<5F><5F><EFBFBD>__<5F>";
static char xlat_table[128] = {
0x9b, 0x5f, 0x5f, 0x86, 0x92, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0xad, 0x5f,
0x5f, 0x5f, 0x5f, 0x5f, 0xa8, 0x5f, 0x5f, 0x9f, 0x91, 0x5f, 0x5f, 0x5f,
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x8f, 0x5f, 0x5f, 0x5f, 0x8a,
0x5f, 0x5f, 0x80, 0x90, 0x5f, 0x5f, 0x89, 0x8b, 0x5f, 0x85, 0x5f, 0x5f,
0xa5, 0x95, 0x5f, 0x5f, 0x5f, 0x5f, 0x9e, 0xa6, 0x97, 0x5f, 0x5f, 0x9d,
0x5f, 0x5f, 0x5f, 0xa0, 0x5f, 0x5f, 0x5f, 0x8d, 0x5f, 0x5f, 0x87, 0x82,
0x5f, 0x5f, 0x88, 0xa1, 0x5f, 0x83, 0x5f, 0x5f, 0xa4, 0xa2, 0x5f, 0x5f,
0x5f, 0x5f, 0xa9, 0x96, 0xa3, 0x5f, 0x5f, 0x98, 0x0a
};
static int insert_num(char *text,int pos,int num)
{
char c=0x80;
do
{
c=num & 0x3f;num>>=6;
if (num) c|=0x80;
c|=0x40;
text[pos++]=c;
}
while (num);
return pos;
}
static int read_num(char *text,int *pos)
{
int num=0,shift=0;
char c;
do
{
c=text[pos[0]++];
num|=(c & 0x3f)<<shift;
shift+=6;
}
while (c & 0x80);
return num;
}
static void next_line(int step)
{
linepos+=step;
if (linepos>YMAX)
{
char s[3];
s[0]=27;
s[1]=END_PAGE;
s[2]=0;
str_add(&all_text,s);
linepos=0;
picture_len=-1;
}
last_skip=step;
}
static int insert_end_line_and_save(int p,int ys)
{
int size;
while (read_buff[buff_pos]==' ' && buff_pos<buff_end) buff_pos++;
size=buff_end-buff_pos;
if (size)memcpy(read_buff,read_buff+buff_pos,size);
write_buff[p++]=27;
write_buff[p++]=END_LINE;
p=insert_num(write_buff,p,ys);
write_buff[p++]=0;
str_add(&all_text,write_buff);
buff_pos=size;
buff_end=buff_pos;
if (picture_len>0) picture_len-=ys;
if (picture_len<=0 && total_width!=XMAX)
{
picture_len=0;
total_width=XMAX;
left_skip=0;
}
return p;
}
static int insert_left_skip(int p,int skip)
{
skip+=left_skip;
if (skip)
{
write_buff[p++]=27;
write_buff[p++]=SPACE;
p=insert_num(write_buff,p,skip);
}
return p;
}
static void save_line_oboustrane()
{
char space[]=" ";
int xs,ys,ss,mez,mm=0,mc=0;
int i,p;
for(i=0,xs=0,mez=0,ys=0;i<buff_pos;i++)
{
space[0]=read_buff[i];
if (space[0]==32) mez++;else
{
xs+=text_width(space);
p=text_height(space);
if (p>ys) ys=p;
}
}
ss=total_width-xs;
p=0;
if (!ys) ys=last_skip;
next_line(ys);
p=insert_left_skip(p,0);
for(i=0,mc=0;i<buff_pos;i++)
{
if (read_buff[i]==32)
{
int sp;
write_buff[p++]=27;
write_buff[p++]=SPACE;
mc++;
sp=ss*(mc)/mez;
p=insert_num(write_buff,p,sp-mm);
mm=sp;
}
else write_buff[p++]=read_buff[i];
}
insert_end_line_and_save(p,ys);
}
static void save_line_center()
{
char space[]=" ";
int xs,ys,ss;
int i,p;
for(i=0,xs=0,ys=0;i<buff_pos;i++)
{
space[0]=read_buff[i];
xs+=text_width(space);
p=text_height(space);
if (p>ys) ys=p;
}
p=0;
if (!ys) ys=last_skip;
next_line(ys);
ss=total_width-xs;
p=insert_left_skip(p,ss/2);
memcpy(write_buff+p,read_buff,buff_pos);
p+=buff_pos;
write_buff[p]=0;
insert_end_line_and_save(p,ys);
}
static void save_line_left()
{
int p,z;
int ys;
p=0;
p=insert_left_skip(p,0);z=p;
if (buff_pos) memcpy(write_buff+p,read_buff,buff_pos);
p+=buff_pos;
write_buff[p]=0;
ys=text_height(write_buff+z);
if (!ys) ys=last_skip;
next_line(ys);
insert_end_line_and_save(p,ys);
}
static void save_buffer()
{
while (buff_end>buff_pos && read_buff[buff_end]==32) buff_end--;
if (center) save_line_center();
else if (buff_pos==buff_end || !distend) save_line_left(); else save_line_oboustrane();
}
static void break_line()
{
buff_pos=buff_end;
save_buffer();
}
static char read_set(FILE *txt,char *var,char *set)
{
int c;
char *cc;
char d;
fscanf(txt,"%[^=]%c",var,&d);
do
c=fgetc(txt);
while (c<33);
if (c=='"') fscanf(txt,"%[^\"]%c%c",set,&d,&d);
else if (c=='\'') fscanf(txt,"%[^']%c%c",set,&d,&d);
else
{
ungetc(c,txt);
fscanf(txt,"%[^> ]%c",set,&d);
}
while(c<33 && c!=EOF) c=fgetc(txt);
if (c!='>') ungetc(c,txt);
cc=strchr(var,0);
while (cc!=var)
{
cc--;
if (*cc>32)
{
cc++;
break;
}
}
*cc=0;
strupr(set);
strupr(var);
return c;
}
static int get_data_handle(char *filename,void *dec)
{
int i;
i=find_handle(filename,dec);
if (i==-1)
{
i=end_ptr++;
def_handle(i,filename,dec,SR_DIALOGS);
}
return i;
}
static void insert_picture(char *filename,int align,int line,int lsize)
{
int x, y;
short *psiz;
char *c=write_buff;
psiz=ablock(get_data_handle(filename,pcx_8bit_decomp));
switch (align)
{
case ANUM_CENTER:
x=(XMAX-psiz[0])/2;
y=linepos;
linepos+=psiz[1];
*c++=27;
*c++=END_LINE;
c+=insert_num(c,0,psiz[1]+last_skip);
break;
case ANUM_LEFT: x=0;
y=linepos;
left_skip=psiz[0]+5;
total_width=XMAX-left_skip;
break;
case ANUM_RIGHT: total_width=(x=XMAX-psiz[0])-5;
left_skip=0;
y=linepos;
break;
}
if (!lsize) lsize=psiz[1]-line;
picture_len=lsize;
*c++=27;
*c++=PICTURE;
while (*filename) *c++=*filename++;
*c++=':';
c+=insert_num(c,0,x);
c+=insert_num(c,0,y);
c+=insert_num(c,0,line);
c+=insert_num(c,0,lsize);
*c++=0;
str_add(&all_text,write_buff);
}
static char read_tag(FILE *txt)
{
char c,var[256],set[256];
int i;
i=fscanf(txt,"%[^> ] %c",var,&c);
while(c<33 && i!=EOF) c=i=fgetc(txt);
if (c!='>') ungetc(c,txt);
strupr(var);
if (!strcmp(var,PARAGRAPH))
{
break_line();
break_line();
return 1;
}
if (!strcmp(var,BREAKLINE))
{
break_line();
return 1;
}
if (!strcmp(var,IMAGE))
{
char pic_name[50]=" ";
char alig=0;
int line=0,lsize=0;
while (c!='>')
{
c=read_set(txt,var,set);
if (!strcmp(var,SRC)) strncpy(pic_name,set,49);
else if (!strcmp(var,ALIGN))
{
if (!strcmp(set,ALEFT)) alig=1;
else if (!strcmp(set,ARIGHT)) alig=2;
else if (!strcmp(set,ACENTER)) alig=0;
}
else if (!strcmp(var,PIC_LINE)) sscanf(set,"%d",&line);
else if (!strcmp(var,PIC_LSIZ)) sscanf(set,"%d",&lsize);
}
if (pic_name[0]!=0)
insert_picture(pic_name,alig,line,lsize);
return 0;
}
if (!strcmp(var,CENTER1)) center++;
else if (!strcmp(var,CENTER2))
{
if (center>0) center--;
}
else if (!strcmp(var,DISTEND1)) distend++;
else if (!strcmp(var,DISTEND2))
{
if (distend>0) distend--;
}
return 0;
}
static char skip_section(FILE *txt)
{
int c;
char end=1;
c=fgetc(txt);
while (c!=']' && c!=EOF)
{
c=fgetc(txt);
end=0;
}
if (c==EOF) end=1;
return end;
}
void prekodovat(char *c)
{
while (*c)
{
if (*c>137) *c=xlat_table[*c-138];
c++;
}
}
static void read_text(FILE *txt)
{
int i;
int xs;
char ss[2]=" ";
char wsp=1;
buff_pos=0;
buff_end=0;
xs=0;
do
{
i=fgetc(txt);
if (i==EOF) break;
if (i<32) i=32;
if (i=='<')
{
if (read_tag(txt))
{
xs=0;
wsp=1;
}
continue;
}
if (i=='[')
{
if (skip_section(txt)) break;
continue;
}
if (i==32)
{
if (wsp) continue;
buff_pos=buff_end;
wsp=1;
}
else wsp=0;
if (i=='&') i=fgetc(txt);
if (winconv && i>137) i=xlat_table[i-138];
ss[0]=i;
xs+=text_width(ss);
read_buff[buff_end++]=i;
if (xs>total_width && !wsp)
{
save_buffer();
read_buff[buff_end]=0;
xs=text_width(read_buff);
}
}
while (1);
}
void seek_section(FILE *txt,int sect_number)
{
int c=0,i;
winconv=0;
do
{
while (c!='[' && c!=EOF) c=fgetc(txt);
if (c=='[')
{
i=-2;
fscanf(txt,"%d",&i);
if (i==sect_number)
{
c=fgetc(txt);
while(c!=']')
{
if (c=='W' || c=='w') winconv=1;
if (c=='K' || c=='k') winconv=0;
c=fgetc(txt);
}
return;
}
}
c=0;
}
while (i!=EOF);
closemode();
{
char buff[256];
sprintf(buff,"Nemohu najit odstavec s cislem %d.",sect_number);
display_error(buff);
}
exit(1);
}
void add_text_to_book(char *filename,int odst)
{
FILE *txt;
ENCFILE fl;
set_font(H_FKNIHA,NOSHADOW(0));
if (all_text==NULL) all_text=create_list(256);
txt=enc_open(filename,&fl);
if (txt==NULL) return;
seek_section(txt,odst);
read_text(txt);
next_line(1000);
enc_close(&fl);
}
static char *displ_picture(char *c)
{
char *d;
int x,y,hn,z,ln,sl;
short *sh;
d=write_buff;
while (*c!=':') *d++=*c++;
*d++=0;c++;
hn=get_data_handle(write_buff,pcx_8bit_decomp);
x=read_num(c,(z=0,&z));c+=z;
y=read_num(c,(z=0,&z));c+=z;
ln=read_num(c,(z=0,&z));c+=z;
sl=read_num(c,(z=0,&z));c+=z;
sh=ablock(hn);
if (sh[1]+y>YMAX) return c;
y+=YLEFT;
x+=relpos;
put_8bit_clipped(sh,GetScreenAdr()+x+scr_linelen2*y,ln,sh[0],sl);
return c;
}
void write_book(int page)
{
int i=0,y=0,z,zz,ps,pg;
char *c;
char space[]=" ";
pg=page;
if (all_text==NULL) return;
set_font(H_FKNIHA,NOSHADOW(0));
relpos=XLEFT;
zz=str_count(all_text);
if (--page)
for(i=0;i<zz && page;i++)
{
c=all_text[i];
if (c!=NULL && c[0]==27 && c[1]==END_PAGE) page--;
}
if (page) return;
for(ps=0;ps<2;ps++)
{
position(relpos,YLEFT+y);
do
{
if (i>zz) break;
c=all_text[i];
if (c==NULL) break;
if (c[0]==27 && c[1]==END_PAGE) break;
while (*c)
{
z=0;
if (*c==27)
{
c++;
switch (*c++)
{
case SPACE:
rel_position_x(read_num(c,&z));
c+=z;
break;
case END_LINE:
y+=read_num(c,&z);
position(relpos,YLEFT+y);
c+=z;
break;
case PICTURE:
c=displ_picture(c);
break;
}
}
else
{
space[0]=*c++;
outtext(space);
}
}
i++;
}
while (1);
i++;y=0;
relpos=XRIGHT;
if (ps==0)
{
char s[20];
sprintf(s,texty[135],pg);
set_aligned_position(XLEFT,YLEFT+YMAX,0,0,s);
outtext(s);
}
if (ps==1)
{
char s[20];
sprintf(s,texty[136],pg+1);
set_aligned_position(XRIGHT+XMAX,YLEFT+YMAX,2,0,s);
outtext(s);
}
}
}
int count_pages()
{
int i,cn,z;
char *c;
if (all_text==NULL) return 0;
z=str_count(all_text);
for(i=0,cn=0;i<z;i++)
{
c=all_text[i];
if (c!=NULL && c[0]==27 && c[1]==END_PAGE) cn++;
}
return cn;
}
void save_book()
{
char *c;
FILE *f;
int i,ss;
char *tx;
if (all_text==NULL) return;
concat(c,pathtable[SR_TEMP],BOOK_FILE);
f=fopen(c,"w");if (f==NULL) return;
i=0;
ss=str_count(all_text);
while (i<ss && (tx=all_text[i++])!=NULL)
{
fputs(tx,f);
fputc('\n',f);
}
fclose(f);
}
void load_book()
{
char *c;
FILE *f;
char tx[512];
if (all_text!=NULL) release_list(all_text);
all_text=NULL;
concat(c,pathtable[SR_TEMP],BOOK_FILE);
f=fopen(c,"r");if (f==NULL) return;
all_text=create_list(256);
while (fgets(tx,510,f)!=NULL)
{
char *c;
c=strchr(tx,0);c--;*c=0;
str_add(&all_text,tx);
}
fclose(f);
}

1970
game/kouzla.c Normal file

File diff suppressed because it is too large Load diff

760
game/macros.c Normal file
View file

@ -0,0 +1,760 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include "specproc.h"
#include "temp_storage.h"
int **macros=NULL;
void *macro_block;
int macro_block_size;
long sound_side_flags=0; //kopie flagu steny pro zvuk
static char codelock_memory[16][8];
static short rand_value;
static int program_counter=0;
static char trig_group;
SGlobalEventDef GlobEventList[MAGLOB_NEXTID];
void propadnout(int sector);
#define TRIG_GROUP 1
#define TRIG_SECTOR 2
char get_player_triggered(int p)
{
return (trig_group & (1<<p))!=0;
}
char save_load_trigger(short load)
{
if (load>=0) trig_group=(char)load;
return trig_group;
}
void load_macros(int size,void *data)
{
int *r;
if (macros!=NULL) free(macros);
macros=(int **)getmem(mapsize*sizeof(int *)*4);
memset(macros,0,mapsize*sizeof(char *)*4);
memset(codelock_memory,0,sizeof(codelock_memory));
r=data;
while (*r)
{
macros[*r]=r+1;
r++;
while(*r) r=(int *)((char *)r+*r+4);
r++;
}
macro_block=data;
macro_block_size=size;
}
void macro_disp_text(int text,char glob)
{
if (glob) bott_disp_text(texty[text]);
else bott_disp_text(level_texts[text]);
}
void macro_fireball(TMA_FIREBALL *z,int sector,int dir)
{
LETICI_VEC *fly;
TITEM *it;
fly=create_fly();
it=glob_items+z->item-1;
fly->items=NULL;
fly->item=z->item;
fly->xpos=z->xpos;
fly->ypos=z->ypos*128/500-64;
fly->zpos=z->zpos*128/320;
fly->speed=z->speed;
fly->velocity=0;
fly->flags=FLY_IN_FLY | (!it->hmotnost?FLY_NEHMOTNA:0) | (it->flags & ITF_DESTROY?FLY_DESTROY:0)|FLY_NEDULEZITA;
fly->sector=sector;
fly->smer=(dir+2)&3;
fly->owner=0;
fly->hit_bonus=0;
fly->damage=0;
fly->counter=0;
if (fly->flags & FLY_DESTROY)fly->lives=it->user_value;
add_fly(fly);
}
void macro_sound(TMA_SOUND *p,int psect,int pdir,int sect,int dir)
{
char up=4;
if (sound_side_flags & SD_PRIM_FORV) up=2;
if (~(p->bit16) & up)
if (psect)
play_effekt(map_coord[sect].x,map_coord[sect].y,map_coord[psect].x,map_coord[psect].y,dir,pdir,p);
else
play_effekt(0,0,0,0,-1,-1,p);
}
void macro_send_act(TMA_SEND_ACTION *p)
{
delay_action(p->s_action,p->sector,p->side,p->change_bits<<24,0,p->delay);
}
void macro_load_another_map(TMA_LOADLEV *z)
{
int i,j=0;
if (battle) return;
group_all();
for(i=0;i<POCET_POSTAV;i++)
if (postavy[i].sektor!=viewsector && postavy[i].used && postavy[i].lives)
{
bott_disp_text(texty[66]);
return;
}
if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return;
for(i=0;i<POCET_POSTAV;i++)
if (postavy[i].groupnum)
if (i!=j)memcpy(&postavy[j++],&postavy[i],sizeof(postavy[i]));else j++;
if (j<POCET_POSTAV) memset(&postavy[j],0,sizeof(THUMAN)*(POCET_POSTAV-j));
loadlevel=*z;
send_message(E_CLOSE_MAP);
save_map=1;
reg_grafiku_postav();
reroll_all_shops();
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].used) postavy[i].sektor=z->start_pos;
}
void macro_drop_item(int sector,int smer,short item)
{
short itms[2];
itms[0]=item+1;
itms[1]=0;
push_item(sector,(smer+rnd(2))&0x3,itms);
}
static void macro_create_item(short item)
{
if (picked_item!=NULL) poloz_vsechny_predmety();
picked_item=NewArr(short,2);
picked_item[0]=item+1;
picked_item[1]=0;
pick_set_cursor();
}
static char decode_lock(char znak,char *string,char codenum)
{
char *memory;
char *endm;
char *ends;
int i;
memory=codelock_memory[codenum];
memmove(memory,memory+1,7);
endm=memory+7;
*endm=znak;
if (!*string) return 1;
ends=string;
for(i=0;i<8;i++,ends++) if (!*ends) break;
ends--;
while (ends>=string)
{
if (*ends!=*endm) break;
ends--;endm--;
}
if (ends<string) return 0;else return 1;
}
void cancel_action(int sector,int dir)
{
D_ACTION *d,*p;
p=NULL;d=d_action;
while (d!=NULL)
{
if (d->sector==sector && d->side==dir)
{
if (p==NULL) d_action=d->next;else p->next=d->next;
free(d);
return;
}
p=d;
d=d->next;
}
}
char if_lock(int side,int key_id,int level,TMA_LOCK *lk)
{
int c;
level;
if (picked_item==NULL)
{
call_macro(side,MC_LOCKINFO);
return 1;
}
c=picked_item[0]-1;
c=glob_items[c].keynum;
if (c==-1 && level!=-1)
{
int i,j=0,min=-1;
THUMAN *h=postavy;
int thlev;
char s[100];
for(i=0;i<POCET_POSTAV;h++,i++) if (h->used && h->groupnum==cur_group && h->vlastnosti[VLS_OBRAT]>min)
{min=h->vlastnosti[VLS_OBRAT];j=i;};
h=postavy+j;
if (level==0) level=100;
if (level>=min)
if (rnd(100)<=level-min)
{
sprintf(s,texty[158+h->female],h->jmeno);
bott_disp_text(s);
destroy_items(picked_item);
free(picked_item);
picked_item=NULL;pick_set_cursor();
return 1;
}
thlev=rnd(min);
if (thlev>level)
{
sprintf(s,texty[154+h->female],h->jmeno);
bott_disp_text(s);
//if (abs(level-thlev)<10 && h->vlastnosti[VLS_THIEF]<100)
// {
//h->vlastnosti[VLS_THIEF]++;
//h->stare_vls[VLS_THIEF]++;
//}
lk->thieflevel=1;
return 0;
}
sprintf(s,texty[156+h->female],h->jmeno);
bott_disp_text(s);
return 1;
}
if (c!=key_id || !c)
{
call_macro(side,MC_TOUCHFAIL);
return 1;
}
return 0;
}
void xchg_block(void *b1, void *b2, int leng) {
uint8_t *p1 = (uint8_t *)b1;
uint8_t *p2 = (uint8_t *)b2;
for (int i = 0; i < leng; i++) {
uint8_t temp = p1[i];
p1[i] = p2[i];
p2[i] = temp;
}
}
void propadnout(int sector)
{
short *i,c,m1,m2;
for(c=0;c<4;c++)
{
pop_item(sector,c,0,&i);
while(i!=NULL)
{
push_item(sector,c,i);
pop_item(sector,c,0,&i);
}
}
if (mob_map[sector])
{
m1=mob_map[sector]-1;
m2=mobs[m1].next-1;
mob_map[sector]=0;
if (map_sectors[sector].sector_type==S_DIRA)
{
mobs[m1].sector=map_sectors[sector].sector_tag;
if (m2>=0) mobs[m2].sector=mobs[m1].sector;
}
mob_map[mobs[m1].sector]=m1+1;
}
postavy_propadnout(sector);
}
static void swap_sectors(TMA_SWAPS *sws)
{
TSECTOR *ss1=&map_sectors[sws->sector1],*ss2=&map_sectors[sws->sector2];
TSTENA *sd1=&map_sides[sws->sector1<<2],*sd2=&map_sides[sws->sector2<<2];
char c=4;
char st1=ss2->sector_type,st2=ss1->sector_type;
for(c=0;c<4;c++) xchg_block(sd1+c,sd2+c,sizeof(TSTENA));
xchg_block(ss1,ss2,sizeof(TSECTOR));
if (st1==S_DIRA || st1==S_VODA) propadnout(sws->sector1);
if (st2==S_DIRA || st2==S_VODA) propadnout(sws->sector2);
recheck_button(sws->sector1,0);
recheck_button(sws->sector2,0);
}
static void hit_1_player(int postava,TMA_WOUND *w,int chaos)
{
int mode=w->pflags>>1;
int zivel=mode-2;
int dostal;
THUMAN *h=postavy+postava;
if (mode==0)
{
dostal=w->minor+rnd(w->major-w->minor+1);
}
else if (mode==1)
{
short vls[24];
memset(vls,0,sizeof(vls));
vls[VLS_UTOK_L]=w->minor;
vls[VLS_UTOK_H]=w->major;
dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0);
}
else
{
short vls[24];
memset(vls,0,sizeof(vls));
vls[VLS_MGSIL_L]=w->minor;
vls[VLS_MGSIL_H]=w->major;
vls[VLS_MGZIVEL]=zivel;
dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0);
}
player_hit(h,dostal,0);
}
static void hit_player(TMA_WOUND *w,int sector)
{
int i,pocet,r;
for(i=0,pocet=0;i<POCET_POSTAV;i++) if (get_player_triggered(i)) pocet++;
if (!pocet) return;
if (~w->pflags & 1)
{
r=rnd(pocet)+1;
for(i=0;i<POCET_POSTAV && r>0;i++) if (get_player_triggered(i)) r--;
i--;
hit_1_player(i,w,pocet);
}
else
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].sektor==sector) hit_1_player(i,w,pocet);
bott_draw(1);
}
static TMULTI_ACTION *go_macro(int side,int abs_pos)
{
int *r;
int mcsiz;
program_counter=abs_pos;
r=macros[side];
if (r==NULL) return NULL;
mcsiz=*r++;
while (abs_pos--)
{
r=(int *)((char *)r+mcsiz);
mcsiz=*r++;
if (!mcsiz) return NULL;
}
return (TMULTI_ACTION *)r;
}
static char monster_in_game(void)
{
int i;
for(i=0;i<MAX_MOBS;i++) if (mobs[i].vlajky & MOB_LIVE && ~mobs[i].vlajky & MOB_MOBILE) return 1;
return 0;
}
static char monster_test;
static char is_monster(word sector)
{
int m1,m2;
m1=mob_map[sector]-1;
if (m1>=0)
{
m2=mobs[m1].next-1;
if (~mobs[m1].vlajky & MOB_MOBILE && (m2<0 || ~mobs[m2].vlajky & MOB_MOBILE)) monster_test=1;
}
return !monster_test;
}
static char monster_in_room(int sector)
{
monster_test=0;
is_monster(sector);
if (!monster_test) labyrinth_find_path(sector,65535,SD_MONST_IMPS,is_monster,NULL);
return monster_test;
}
static int if_jump(TMA_TWOP *i,int side,int abs_pos)
{
TSTENA *sd=map_sides+side;
int go,test,flag;
char ok=0;
test=abs(i->parm1)-1;
go=i->parm2;
flag=sd->flags;
if (test<32) ok=(flag & (1<<test))!=0;
else
switch(test)
{
case 32:ok=monster_in_game();break;
case 33:ok=monster_in_room(side>>2);break;
}
if (i->parm1<0) ok=!ok;
if (ok) return go+abs_pos;else return -1;
}
static int if_have_item(TMA_TWOP *i,int abs_pos)
{
int go,test,ip;
char ok=0;
test=abs(i->parm1);
go=i->parm2;
for(ip=0;ip<POCET_POSTAV && !ok;ip++) if (get_player_triggered(ip)) ok=(q_item_one(ip,test)!=NULL);
if (i->parm1<0) ok=!ok;
if (ok) return go+abs_pos;else return -1;
}
static int ma_randjmp(TMA_TWOP *i,int abs_pos)
{
int go,test;
char ok=0;
test=i->parm1;
go=i->parm2;
if (rand_value==-1) rand_value=rnd(100);
ok=rand_value<test;
if (ok) return go+abs_pos;else return -1;
}
static int ma_test_action(TMA_TWOP *i,int act,int abs_pos)
{
int go,test;
char ok=0;
test=abs(i->parm1)-1;
go=i->parm2;
ok=(test==act);
if (i->parm1<0) ok=!ok;
if (ok) return go+abs_pos;else return -1;
}
static int ma_if_flag(TMA_TWOP *i,int abs_pos)
{
int go,test;
char ok=0;
test=abs(i->parm1)-1;
go=i->parm2;
ok=test_flag(test);
if (i->parm1<0) ok=!ok;
if (ok) return go+abs_pos;else return -1;
}
static int ma_picki(TMA_TWOP *i,int abs_pos)
{
int go,test;
char ok=0;
test=abs(i->parm1);
go=i->parm2;
if (picked_item!=NULL) ok=picked_item[0]==test;else ok=0;
if (i->parm1<0) ok=!ok;
if (ok) return go+abs_pos;else return -1;
}
static void ma_wbook(TMA_LOADLEV *l)
{
char *s;
s=find_map_path(l->name);
add_text_to_book(s,l->start_pos);
play_fx_at(FX_BOOK);
free(s);
}
static void ma_send_experience(long what)
{
int maxl,i;
THUMAN *h;
for(i=0,maxl=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && maxl<h->level) maxl=h->level;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && h->lives)
{
h->exp+=what*h->level/maxl;
check_player_new_level(h);
}
bott_draw(0);
}
static void ma_move_group(int where,int turn,char effect)
{
if (!save_load_trigger(-1)) return;
if (!effect)
{
int i;
THUMAN *h=postavy;
for(i=0;i<POCET_POSTAV;i++,h++)
if (get_player_triggered(i)) h->sektor=where,h->direction=turn;
viewsector=where;
viewdir=turn;
}
else
{
THUMAN *h=postavy;
int i;
int sctr;
char kdo=0;
for(i=0;i<POCET_POSTAV;i++,h++)
if (get_player_triggered(i)) kdo|=1<<i,sctr=postavy[i].sektor;
postavy_teleport_effect(where,turn,kdo,viewsector==sctr);
}
}
static void build_trig_group(char mode,int side)
{
int i;
THUMAN *h;
trig_group=0;
switch (mode)
{
case TRIG_GROUP:if (battle && select_player>=0) trig_group|=1<<select_player;
else for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && h->groupnum==cur_group) trig_group|=1<<i;
break;
case TRIG_SECTOR:side>>=2;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->used && h->sektor==side) trig_group|=1<<i;
break;
}
}
static int ma_play_anim(char *filename,char cls)
{
char *a;
unwire_main_functs();
concat(a,pathtable[SR_VIDEO],filename);
curcolor=0;
if (cls)
{
bar(0,0,639,479);
showview(0,0,0,0);
}
mute_all_tracks(1);
cancel_render=0;
cancel_pass=0;
play_movie_seq(a,cls?60:SCREEN_OFFLINE);
wire_main_functs();
}
static char ma_control_mob_control(word sector)
{
sector;
return 1;
}
static void ma_control_mob(int from,int to)
{
word *path;
int m;
if (mob_map[from]==0) return;
if (labyrinth_find_path(from,to,SD_MONST_IMPS,ma_control_mob_control,&path)==0) return;
m=mob_map[from]-1;
send_mob_to(m,path);
}
static void ma_drop_money(int sect,int side,TMULTI_ACTION *q)
{
int x;
x=rnd(q->twop.parm2-q->twop.parm1+1);
x+=q->twop.parm1;
x=create_item_money(x)-1;
if (x) macro_drop_item(sect,side,x);
}
void macro_change_music(int textindex)
{
char *trackdef=level_texts[textindex];
char *nextTrack;
create_playlist(trackdef);
play_next_music(&nextTrack);
change_music(nextTrack);
}
void macro_register_global_event(TMULTI_ACTION *q)
{
GlobEventList[q->globe.event].cancel=q->globe.cancel;
GlobEventList[q->globe.event].sector=q->globe.sector;
GlobEventList[q->globe.event].side=q->globe.side;
GlobEventList[q->globe.event].param=q->globe.param;
if (q->globe.event>=MAGLOB_ONTIMER1 && q->globe.event<=MAGLOB_ONTIMER4)
{
if (GlobEventList[q->globe.event].param>0)
GlobEventList[q->globe.event].param+=game_time;
else
{
long den=24*60*6;
long cas=((-GlobEventList[q->globe.event].param/100)*60+(-GlobEventList[q->globe.event].param%100))*6;
long curtm=game_time % den;
if (cas<=curtm) cas+=den;
GlobEventList[q->globe.event].param=game_time-curtm+cas;
}
}
}
void call_macro_ex(int side,int flags, int runatside);
void call_macro(int side,int flags)
{
call_macro_ex(side,flags,side);
}
void call_macro_ex(int side,int flags, int runatside)
{
TMULTI_ACTION *z,*p;
int *r;
int mcsiz;
int c;
short saved_trigger;
short ls=last_send_action;
short save_rand;
if (side>=mapsize*4) return;
if (runatside>=mapsize*4) return;
save_rand=rand_value;rand_value=-1;
r=macros[runatside];
program_counter=0;
if (r==NULL) return;
SEND_LOG("(MULTIACTIONS) Start: Side %.1f Call %X",(float)(runatside/4)+((float)(runatside & 3)/10),flags);
saved_trigger=save_load_trigger(-1);
if (flags & (MC_PASSSUC | MC_PASSFAIL | MC_EXIT)) build_trig_group(TRIG_GROUP,0);else build_trig_group(TRIG_SECTOR,side);
while ((mcsiz=*r)!=0)
{
r++;
zde:
z=(TMULTI_ACTION *)r;
if (z->general.flags & flags)
{
c=-1;
switch (z->general.action)
{
case MA_GEN:break;
case MA_SOUND:macro_sound(&z->sound,side>>2,side & 3,viewsector,viewdir);break;
case MA_TEXTG:macro_disp_text(z->text.textindex,1);break;
case MA_TEXTL:macro_disp_text(z->text.textindex,0);break;
case MA_SENDA:macro_send_act(&z->send_a);break;
case MA_FIREB:macro_fireball(&z->fireball,side>>2,side & 3);break;
case MA_DESTI:if (picked_item!=NULL)
{
destroy_items(picked_item);
free(picked_item);
picked_item=NULL;
pick_set_cursor();
}
break;
case MA_LOADL:macro_load_another_map(&z->loadlev);break;
case MA_DROPI:macro_drop_item(side>>2,side & 0x3,z->dropi.item);break;
case MA_CREAT:macro_create_item(z->dropi.item);break;
case MA_DIALG:start_dialog(z->text.textindex,-1);break;
case MA_SSHOP:enter_shop(z->text.textindex);break;
case MA_CLOCK:z->general.cancel=decode_lock(z->clock.znak,z->clock.string,z->clock.codenum);break;
case MA_CACTN:cancel_action(z->cactn.sector,z->cactn.dir);break;
case MA_LOCK :z->general.cancel=if_lock(side,z->lock.key_id,z->lock.thieflevel,&z->lock);break;
case MA_SWAPS:swap_sectors(&z->swaps);break;
case MA_WOUND:hit_player(&z->wound,side>>2);break;
case MA_IFJMP:c=if_jump(&z->twop,side,program_counter);break;
case MA_STORY:write_story_text(level_texts[z->text.textindex]);break;
case MA_HAVIT:c=if_have_item(&z->twop,program_counter);break;
case MA_SNDEX:ma_send_experience(z->twop.parm1);break;
case MA_IFACT:c=ma_test_action(&z->twop,ls,program_counter);break;
case MA_CALLS:if (call_map_event(z->twop.parm1,side>>2,side & 3,z->twop.parm2,flags)) call_macro(side,MC_SPEC_SUCC);break;
case MA_MOVEG:ma_move_group(z->twop.parm1,z->twop.parm2 & 3,z->twop.parm2>>7);break;
case MA_PLAYA:ma_play_anim(z->loadlev.name,z->loadlev.dir);break;
case MA_ISFLG:c=ma_if_flag(&z->twop,program_counter);break;
case MA_CHFLG:change_flag(z->twop.parm1,(char)z->twop.parm2);break;
case MA_CUNIQ:macro_drop_item(side>>2,side & 0x3,create_unique_item(&z->uniq.item)-1);break;
case MA_MONEY:ma_drop_money(side>>2,side & 0x3,z);break;
case MA_GUNIQ:macro_create_item(create_unique_item(&z->uniq.item)-1);break;
case MA_PICKI:c=ma_picki(&z->twop,program_counter);break;
case MA_WBOOK:ma_wbook(&z->loadlev);break;
case MA_RANDJ:c=ma_randjmp(&z->twop,program_counter);break;
case MA_ENDGM:unwire_proc();send_message(E_CLOSE_MAP,(void *)255);break;
case MA_GOMOB:ma_control_mob(z->twop.parm1,z->twop.parm2);break;
case MA_SHRMA:call_macro_ex(side,flags,z->twop.parm1*4+z->twop.parm2);break;
case MA_MUSIC:macro_change_music(z->text.textindex);break;
case MA_GLOBE:macro_register_global_event(z);break;
}
if (c!=-1) p=go_macro(runatside,c);else p=NULL;
if (p!=NULL) {r=(int *)p;program_counter=c;mcsiz=r[-1];goto zde;}
if (z->general.once)
{
z->general.action=0;
z->general.once=0;
if (z->general.cancel)
{
z->general.cancel=0;
goto end;
}
}
if (z->general.cancel) return;
}
r=(int *)((char *)r+mcsiz);
program_counter++;
}
end:
rand_value=save_rand;
save_load_trigger(saved_trigger);
SEND_LOG("(MULTIACTIONS) End: Side %.1f Call %X",(float)(runatside/4)+((float)(runatside & 3)/10),flags);
}
static char lock_saved=255;
static char lock_empty=254;
char save_codelocks(TMPFILE_WR *fsta)
{
temp_storage_write(codelock_memory,sizeof(codelock_memory)*1,fsta);
}
char load_codelocks(TMPFILE_RD *fsta)
{
return !temp_storage_read(codelock_memory,sizeof(codelock_memory)*1,fsta);
}

622
game/menu.c Normal file
View file

@ -0,0 +1,622 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include <stdarg.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#define MUSIC "TRACK06.MUS"
#define H_ANIM_ORIGN (H_MENUS_FREE+0)
#define H_ANIM (H_MENUS_FREE+1)
#define H_MENU_BAR (H_MENUS_FREE+31)
#define H_MENU_MASK (H_MENUS_FREE+32)
#define H_MENU_ANIM (H_MENUS_FREE+33)
#define H_PICTURE (H_MENUS_FREE+39)
#define SELECT 1
#define UNSELECT -1
#define SPEED 3
int speedscroll=3;
char low_mem=0;
static volatile char load_ok=0;
static int cur_pos[]={0,0,0,0,0};
static int cur_dir[]={UNSELECT,UNSELECT,UNSELECT,UNSELECT,UNSELECT};
static int titlefont=H_FBIG;
#define TITLE_HEAD 1
#define TITLE_NAME 2
#define TITLE_TEXT 3
#define TITLE_CENTER 0
#define TITLE_KONEC 4
static int title_mode=0;
static int title_line=0;
#define CLK_MAIN_MENU 4
static char vymacknout(int id,int xa,int ya,int xr,int yr)
{
for(id=0;id<5;id++) cur_dir[id]=UNSELECT;
xa,ya,xr,yr;
return 1;
}
static char promacknuti(int id,int xa,int ya,int xr,int yr)
{
char *z;
word *w;
z=ablock(H_MENU_MASK);w=(word *)z;
z+=6+512;
z+=xr+yr*w[0];
vymacknout(id,xa,ya,xr,yr);
if (*z!=0) cur_dir[*z-1]=SELECT;
return 1;
}
static char click(int id,int xa,int ya,int xr,int yr)
{
int i;
id,xa,ya,xr,yr;
for(i=0;i<5;i++) if (cur_dir[i]==SELECT) break;
if (i!=5) send_message(E_MENU_SELECT,i);
return 1;
}
T_CLK_MAP clk_main_menu[]=
{
{-1,220,300,220+206,300+178,promacknuti,1,-1},
{-1,220,300,220+206,300+178,click,2,-1},
{-1,0,0,639,479,vymacknout,1,-1},
{-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT},
};
void rozdily(uint8_t *orign, uint8_t *obr, uint16_t *hicolor, uint16_t *xtab, size_t pocet) {
for (size_t i = 0; i < pocet; i++) {
uint8_t al = obr[i];
al ^= orign[i];
uint16_t result = xtab[al];
hicolor[i] = result;
}
}
/*void rozdily(void *orign,void *obr,void *hicolor,void *xtab,int pocet)
//#pragma aux rozdily parm[EDX][ESI][EDI][EBX][ECX]=
{
__asm
{
mov edx,orign
mov esi,obr
mov edi,hicolor
mov ebx,xtab
mov ecx,pocet
jp1:lodsb
xor al,[edx]
movzx eax,al
inc edx
movzx eax,short ptr[ebx+eax*2]
stosw
dec ecx
jnz jp1
}
}*/
static void nahraj_rozdilovy_pcx(void **pp,long *s)
{
char *org,*pos;
char *vysl;
word *size,*paltab;
word *hicolor,*p;
void *origin;
int siz;
load_pcx((char *)*pp,*s,A_8BIT,&vysl);
size=(word *)vysl;
free(*pp);
siz=size[0]*size[1];
p=hicolor=getmem(siz*2+12);
*p++=size[0];
*p++=size[1];
*p++=16;
origin=ablock(H_ANIM_ORIGN);
org=(char *)origin+6+512;
pos=(char *)vysl+6+512;
paltab=(word *)vysl+3;
rozdily(org,pos,hicolor+3,paltab,siz);
free(vysl);
*pp=hicolor;
*s=siz*2+12;
}
static void init_menu_entries(void)
{
int i;
char *a;
def_handle(H_ANIM_ORIGN,"LOGO00.PCX",pcx_8bit_decomp,SR_BGRAFIKA);
def_handle(H_ANIM,"LOGO00.PCX",pcx_15bit_decomp,SR_BGRAFIKA);
a=alloca(15);
for(i=1;i<30;i++)
{
sprintf(a,"LOGO%02d.PCX",i);
def_handle(H_ANIM+i,a,nahraj_rozdilovy_pcx,SR_BGRAFIKA);
}
def_handle(H_MENU_BAR,"MAINMENU.PCX",pcx_8bit_decomp,SR_BGRAFIKA);
def_handle(H_MENU_MASK,"MENUVOL5.PCX",pcx_8bit_decomp,SR_BGRAFIKA);
for(i=0;i<5;i++)
{
sprintf(a,"MENUVOL%d.PCX",i);
def_handle(H_MENU_ANIM+i,a,pcx_15bit_decomp,SR_BGRAFIKA);
}
}
/*
void zobraz_podle_masky_asm(char barva,void *scr,void *data, void *maska,int xs,int ys)
//#pragma aux zobraz_podle_masky_asm parm[al][edi][esi][ebx][edx][ecx]=
{
__asm
{
mov al,barva
mov edi,scr
mov esi,data
mov ebx,maska
mov edx,xs
mov ecx,ys
push ebp
mov ebp,edx
jp3: cmp al,[ebx]
jnz jp1
movsw
jmp jp2
jp1: add edi,2
add esi,2
jp2: inc ebx
dec edx
jnz jp3
mov edx,ebp
add edi,scr_linelen
sub edi,edx
sub edi,edx
dec ecx
jnz jp3
pop ebp
}
}
*/
static void zobraz_podle_masky_asm(char barva, uint16_t *scr, uint16_t *data, uint8_t *maska, int xs, int ys, int scr_linelen) {
int width = xs;
for (int y = 0; y < ys; y++) {
for (int x = 0; x < width; x++) {
if (barva == maska[x]) {
scr[x] = data[x];
}
}
scr += scr_linelen; // Přeskoč na další řádek obrazovky
maska += width; // Přeskoč masku
data += width; // Přeskoč zdrojová data
}
}
static void zobraz_podle_masky(char barva,char anim)
{
char *maska;
word *data;
word *obr=GetScreenAdr()+300*scr_linelen2+220;
word xs,ys;
alock(H_MENU_MASK);
maska=ablock(H_MENU_MASK);
data=ablock(H_MENU_ANIM+anim);
xs=data[0];
ys=data[1];
zobraz_podle_masky_asm(barva,obr,data+3,maska+6+512,xs,ys,scr_linelen2);
aunlock(H_MENU_MASK);
}
static void prehraj_animaci_v_menu(EVENT_MSG *msg,char **unused)
{
static int counter=0;
unused;
if (msg->msg==E_TIMER)
{
if (counter % SPEED==0)
{
int i=counter/SPEED;char show=0;
schovej_mysku();
if (!low_mem || ~i & 1)put_picture(0,56,ablock(H_ANIM+i));
do_events();
for(i=0;i<5;i++)
{
cur_pos[i]+=cur_dir[i];
if (cur_pos[i]<0) cur_pos[i]=0;
else if (cur_pos[i]>4) cur_pos[i]=4;
else
{
zobraz_podle_masky(i+1,cur_pos[i]);
do_events();
show=1;
}
}
ukaz_mysku();
update_mysky();
showview(0,56,640,250);
if (show) showview(220,300,206,178);
}
counter++;
if (counter>=(SPEED*30)) counter=0;
}
}
static void preload_anim(va_list args)
{
int i;
low_mem=0;
ablock(H_ANIM+29);
for(i=0;i<30;i+=2)
{
apreload(H_ANIM+i);
task_sleep(NULL);
}
for(i=1;i<30;i+=2)
{
THANDLE_DATA *h;
h=get_handle(H_ANIM+29);
if (h->status!=BK_PRESENT)
{
low_mem=1;
break;
}
apreload(H_ANIM+i);
task_sleep(NULL);
}
for(i=0;i<5;i++)
{
apreload(H_MENU_ANIM+i);
task_sleep(NULL);
}
apreload(H_MENU_MASK);
task_wait_event(E_TIMER);
load_ok=1;
}
static void klavesnice(EVENT_MSG *msg,void **unused)
{
short cursor,i;
unused;
if (msg->msg==E_KEYBOARD)
{
for(cursor=0;cursor<5;cursor++) if (cur_dir[cursor]==SELECT) break;
if (cursor==5) cursor=-1;
switch(*((char *)msg->data+1))
{
case 'H':cursor--;if (cursor<0) cursor=0;break;
case 'P':cursor++;if (cursor>4) cursor=4;break;
case 28:
case 57:click(0,0,0,0,0);return;
}
for(i=0;i<5;i++) if (i==cursor) cur_dir[i]=SELECT;else cur_dir[i]=UNSELECT;
}
}
int enter_menu(char open)
{
char c;
char *d;
init_menu_entries();
add_task(2048,preload_anim);
load_ok=0;
while(!load_ok) task_sleep(NULL);
if (!open)
{
play_next_music(&d);
change_music(d);
}
update_mysky();
schovej_mysku();
curcolor=0;bar(0,0,639,479);
put_picture(0,0,ablock(H_MENU_BAR));
put_picture(0,56,ablock(H_ANIM));
ukaz_mysku();
if (open) effect_show(NULL);else showview(0,0,0,0);
change_click_map(clk_main_menu,CLK_MAIN_MENU);
send_message(E_ADD,E_TIMER,prehraj_animaci_v_menu);
send_message(E_ADD,E_KEYBOARD,klavesnice);
ms_last_event.event_type=0x1;
send_message(E_MOUSE,&ms_last_event);
d=task_wait_event(E_MENU_SELECT);
c=*d;
disable_click_map();
send_message(E_DONE,E_KEYBOARD,klavesnice);
cur_dir[c]=UNSELECT;
while (cur_pos[c]) task_wait_event(E_TIMER);
task_wait_event(E_TIMER);
send_message(E_DONE,E_TIMER,prehraj_animaci_v_menu);
return c;
}
char *get_next_title(signed char control,char *filename)
{
static FILE *titles=NULL;
static ENCFILE fl;
static char buffer[81];
char *path,*c;
switch(control)
{
case 1:concat(path,pathtable[SR_MAP],filename);
titles=enc_open(path,&fl);
if (titles==NULL)
{
concat(path,pathtable[SR_DATA],filename);
titles=enc_open(path,&fl);
if (titles==NULL)
{
char popis[300];
closemode();
sprintf(popis,"Soubor nenalezen: %s%s nebo %s%s\n",pathtable[SR_MAP],filename,pathtable[SR_DATA],filename);
display_error(popis);
exit(1);
}
}
return (char *)titles;
case 0:if (titles!=NULL)fgets(buffer,80,titles);
c=strchr(buffer,'\n');if (c!=NULL) *c=0;
return buffer;
case -1:if (titles!=NULL)enc_close(&fl);
break;
}
return NULL;
}
static int title_lines[640][2];
static int insert_next_line(int ztrata)
{
char *c;
int ll=-1;
RedirectScreenBufferSecond();
do
{
if (title_mode!=TITLE_KONEC) c=get_next_title(0,NULL);else c[0]=0;
if (c[0]=='*')
{
strupr(c);
if (!strcmp(c+1,"HEAD"))
{
title_mode=TITLE_HEAD;
set_font(titlefont,RGB(146,187,142));
}
else if (!strcmp(c+1,"NAME"))
{
title_mode=TITLE_NAME;
set_font(titlefont,RGB(186,227,182));
}
else if (!strcmp(c+1,"CENTER"))
{
title_mode=TITLE_CENTER;
set_font(titlefont,RGB(255,248,240));
}
else if (!strcmp(c+1,"TEXT"))
{
title_mode=TITLE_TEXT;
set_font(titlefont,RGB(255,248,240));
}
else if (!strcmp(c+1,"KONEC"))
{
title_mode=TITLE_KONEC;
}
else if (!strncmp(c+1,"LINE",4))
{
sscanf(c+5,"%d",&title_line);
}
else if (!strncmp(c+1,"SMALL",5)) titlefont=H_FBOLD;
else if (!strncmp(c+1,"BIG",3)) titlefont=H_FBIG;
else if (!strncmp(c+1,"SPEED",5)) sscanf(c+6,"%d",&speedscroll);
}
else
{
ll=text_height(c);
if (ll==0) ll=text_height("W");
if (ll<title_line) ll=title_line;
curcolor=BGSWITCHBIT;
charcolors[0]=RGB555(0,0,1);
bar(0,360+ztrata,639,360+ztrata+ll);
switch(title_mode)
{
case TITLE_TEXT:
case TITLE_HEAD:position(50,360+ztrata);break;
case TITLE_NAME:set_aligned_position(100,360+ztrata,0,0,c);break;
case TITLE_CENTER:set_aligned_position(320,360+ztrata,1,0,c);break;
}
outtext(c);
}
}
while (c[0]=='*');
RestoreScreen();
if (title_mode==TITLE_KONEC) ll=-1;
return ll;
}
static void scan_lines(word *buffer,int start,int poc)
{
int first, last,i,pocet=poc;
word *buf;
while (pocet--)
{
buf=buffer+start*scr_linelen2;
first=0;
last=0;
for(i=0;i<640;i++) if (!(buf[i] & BGSWITCHBIT)) break;
if (i!=640)
{
first=i;
last=i;
for(;i<640;i++) if (!(buf[i] & BGSWITCHBIT)) last=i;
}
first&=~1;if (last)last+=2;last&=~1;
title_lines[start][0]=first;
title_lines[start][1]=last;
start++;
}
}
static void get_max_extend(int *l,int *r)
{
int left=640;
int right=0;
int i;
for(i=0;i<360;i++)
{
left=MIN(title_lines[i][0],left);
right=MAX(title_lines[i][1],right);
}
*l=left;
*r=right;
}
void titles(va_list args)
//#pragma aux titles parm[]
{
char send_back=va_arg(args,int);
char *textname=va_arg(args,char *);
void *picture;
word *scr,*buff;
int counter,newc;
int lcounter=1;
char end=0;
int l,r;
title_mode=TITLE_CENTER;
if (get_next_title(1,textname)==NULL) return;
schovej_mysku();
speedscroll=4;
curcolor=BGSWITCHBIT ; bar(0,0,639,479);
RedirectScreenBufferSecond();bar(0,0,639,479);RestoreScreen();
memset(title_lines,0,sizeof(title_lines));
def_handle(H_PICTURE,"titulky.pcx",pcx_15bit_decomp,SR_BGRAFIKA);
alock(H_PICTURE);
picture=ablock(H_PICTURE);
put_picture(0,0,picture);
effect_show(NULL);
titlefont=H_FBIG;
set_font(titlefont,RGB(158,210,25));charcolors[1]=0;
counter=get_timer_value();newc=counter;
do
{
int skip;
scr=scr_linelen2*60+GetScreenAdr();
buff=GetBuffer2nd();
counter=get_timer_value();
skip=(counter-newc)/speedscroll;
if (skip>0)
{
if (skip>10) skip=10;
newc+=skip*speedscroll;
scan_lines(buff,360,skip);
scroll_and_copy((word *)picture+640*60+3,buff,scr,360,skip,title_lines);
//memcpy(GetScreenAdr(),buff,480*scr_linelen);
get_max_extend(&l,&r);
memmove(title_lines,&title_lines[skip],sizeof(title_lines)-skip*sizeof(int)*2);
//showview(l,60,r-l+1,360);
showview(0,60,639,360);
buff+=scr_linelen2*359;
memcpy(buff,buff+scr_linelen2*skip,40*scr_linelen);
showview(0,0,640,40);
task_wait_event(E_TIMER);
counter+=skip;
lcounter-=skip;
}
else
if (skip<0) counter=skip;
while (lcounter<=0 && !end)
{
int c;
c=insert_next_line(lcounter);
scan_lines(GetBuffer2nd(),360+lcounter,-lcounter);
if (c==-1)
{
end=1;
lcounter=360;
}
else
lcounter+=c;
}
}
while (!(task_quitmsg() || (end && lcounter<=0)));
ukaz_mysku();
get_next_title(-1,NULL);
aunlock(H_PICTURE);
if (send_back)send_message(E_KEYBOARD,27);
}
void run_titles(va_list args)
{
int task_id;
task_id=add_task(8196,titles,1,"titulky.TXT");
task_wait_event(E_KEYBOARD);
term_task(task_id);
}
void konec_hry()
{
int task_id;
int timer;
char *d;
schovej_mysku();
curcolor=0;
bar(0,0,639,479);
effect_show(NULL);
create_playlist(texty[205]);
play_next_music(&d);
change_music(d);
timer=get_timer_value();
while (get_timer_value()-timer<150) task_sleep(NULL);
task_id=add_task(8196,titles,1,"ENDTEXT.TXT");
task_wait_event(E_KEYBOARD);
if (is_running(task_id)) term_task(task_id);
task_wait_event(E_TIMER);
task_wait_event(E_TIMER);
task_id=add_task(8196,titles,0,"TITULKY.TXT");
task_wait_event(E_KEYBOARD);
if (is_running(task_id)) term_task(task_id);
change_music("?");
curcolor=0;
bar(0,0,639,479);
ukaz_mysku();
effect_show(NULL);
timer=get_timer_value();
while (get_timer_value()-timer<150) task_sleep(NULL);
}

2007
game/realgame.c Normal file

File diff suppressed because it is too large Load diff

16
game/serial.c Normal file
View file

@ -0,0 +1,16 @@
#include <stdio.h>
#define DELITEL 0xC005
unsigned long vysledek;
main()
{
int i;
for(i=0;i<65535;i++)
{
vysledek=DELITEL*i;
printf("%08X ",vysledek);
}
}

265
game/setup.c Normal file
View file

@ -0,0 +1,265 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <bios.h>
#include <mem.h>
#include <types.h>
#include <event.h>
#include <memman.h>
#include <devices.h>
#include <bmouse.h>
#include <bgraph.h>
#include <zvuk.h>
#include <strlite.h>
#include "engine1.h"
#include <pcx.h>
#include "globals.h"
#include <gui.h>
#include <basicobj.h>
extern char enable_sort;
extern char autoattack;
char q_runsetup(char *parm)
{
char c[6];
strncpy(c,parm,6);
strupr(c);
return !strncmp(c,"/SETUP",6);
}
static void show_setup_desktop(WINDOW *w)
{
put_picture(w->x,w->y,ablock(H_SETUPBAR));
}
static void checkbox_animator(THE_TIMER *t)
{
t;
animate_checkbox(10,130,10);
}
static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS,SND_XBASS};
static void do_setup_change()
{
char c;
c=f_get_value(0,o_aktual->id);
switch (o_aktual->id)
{
case 10:set_snd_effect(SND_SWAP,c & 1);break;
case 20:set_snd_effect(SND_OUTFILTER,c & 1);break;
default:set_snd_effect(effects[o_aktual->id/10-20],c);break;
}
}
static void change_zoom()
{
int id=o_aktual->id;
int i;
for(i=30;i<60;i+=10) c_set_value(0,i,f_get_value(0,i) & ~1 | (i==id));
zoom_speed((id-30)/10);
}
static void change_turn()
{
int id=o_aktual->id;
int i;
for(i=60;i<90;i+=10) c_set_value(0,i,f_get_value(0,i) & ~1 | (i==id));
turn_speed((id-60)/10);
}
static void unwire_setup();
static EVENT_PROC(setup_keyboard)
{
user_ptr;
WHEN_MSG(E_KEYBOARD)
{
if (GET_DATA(char)==27)
{
unwire_proc();
}
}
}
static void wire_setup()
{
unwire_proc();
unwire_proc=unwire_setup;
mute_all_tracks(0);
cur_mode=MD_SETUP;
send_message(E_ADD,E_KEYBOARD,setup_keyboard);
SEND_LOG("(GAME) Starting setup",0,0);
}
static void unwire_setup()
{
show_names=f_get_value(0,90) & 1;
enable_sort=f_get_value(0,100) & 1;
autoattack=f_get_value(0,110) & 1;
autosave_enabled=f_get_value(0,120) & 1;
level_preload=f_get_value(0,130) & 1;
delete_from_timer(TM_CHECKBOX);
mix_back_sound(32768);
close_current();
send_message(E_DONE,E_KEYBOARD,setup_keyboard);
wire_proc();
cancel_render=1;
SEND_LOG("(GAME) Setup closed",0,0);
}
char exit_setup(int id,int xa,int ya,int xr,int yr)
{
id,xa,ya,xr,yr;
unwire_setup();
return 0;
}
T_CLK_MAP setup[]=
{
{-1,0,0,639,14,exit_setup,2,H_MS_DEFAULT},
{-1,0,15,639,479,exit_setup,0x8,H_MS_DEFAULT},
};
void skeldal_checkbox(OBJREC *);
void setup_ok_button(OBJREC *);
void skeldal_soupak(OBJREC *);
void new_setup()
{
WINDOW *w;
CTL3D ctl;
int i;
static int textxp[]={ 75, 75,435,435,434,535,535,535,434,434,434,434,434, 35,410,510};
static int textyp[]={275,305, 65, 95,125, 65, 95,125,185,215,245,275,305,235, 40, 40};
static int textc[]={ 53, 54, 56, 57, 58, 56, 57, 58,140,141,142,143,144 ,51, 55, 59};
mix_back_sound(256000-16384);
memset(&ctl,0,sizeof(ctl));
change_click_map(setup,4);
set_font(H_FBOLD,SETUP_COL2);
default_font=curfont;
memcpy(f_default,charcolors,sizeof(f_default));
w=create_window(0,SCREEN_OFFLINE,639,359,0,&ctl);
w->draw_event=show_setup_desktop;
desktop_add_window(w);
define(10,50,270,190,20,0,skeldal_checkbox); c_default(get_snd_effect(SND_SWAP)); on_control_change(do_setup_change);
if (check_snd_effect(SND_OUTFILTER))
{
define(20,50,300,190,20,0,skeldal_checkbox);c_default(get_snd_effect(SND_OUTFILTER));
on_control_change(do_setup_change);
}
define(30,410,60,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==0);
on_control_change(change_zoom);
define(40,410,90,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==1);on_control_change(change_zoom);
define(50,410,120,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==2);on_control_change(change_zoom);
define(60,510,60,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==0);on_control_change(change_turn);
define(70,510,90,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==1);on_control_change(change_turn);
define(80,510,120,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==2);on_control_change(change_turn);
for(i=0;i<5;i++)
{
define((i+9)*10,410,180+i*30,190,20,0,skeldal_checkbox);
switch(i)
{
case 0:c_default(show_names);break;
case 1:c_default(enable_sort);break;
case 2:c_default(autoattack);break;
case 3:c_default(autosave_enabled);break;
case 4:c_default(level_preload);break;
}
}
for(i=0;i<sizeof(textc)/sizeof(int);i++)
define(-1,textxp[i],textyp[i]-1,1,1,0,label,texty[textc[i]]);
for(i=0;i<sizeof(effects)/sizeof(int);i++)
if (check_snd_effect(effects[i]))
{
define(200+i*10,50+i*60,30,30,200,0,skeldal_soupak,effects[i]==SND_MUSIC?127:255);c_default(get_snd_effect(effects[i]));
on_control_change(do_setup_change);
}
define(300,559,336,81,21,0,setup_ok_button,texty[174]);on_control_change(unwire_setup);
property(NULL,ablock(H_FTINY),&color_topbar,0);
redraw_window();
add_to_timer(TM_CHECKBOX,4,-1,checkbox_animator);
}
void game_setup_()
{
wire_setup();
new_setup();
}
char game_setup(int id,int xa,int ya,int xr,int yr)
{
id;xa;ya;xr;yr;
run_background(game_setup_);
return 1;
}
void GameResume(EVENT_MSG *msg,void **data)
{
static int volsave;
data;
if (msg->msg==E_INIT)
{
volsave=get_snd_effect(SND_GVOLUME);
set_snd_effect(SND_GVOLUME,volsave>>1);
}
if (msg->msg==E_KEYBOARD)
{
set_snd_effect(SND_GVOLUME,volsave);
wire_main_functs();
msg->msg=-2;
}
}
void GamePause()
{
int i;
unwire_proc();
send_message(E_ADD,E_KEYBOARD,GameResume);
update_mysky();
schovej_mysku();
trans_bar(0,0,640,480,0);
set_font(H_FBOLD,RGB555(0,23,0));
i=text_width(texty[5]);
add_window(320-(i/2)-10,100,i+40,40,H_IDESKA,4,20,20);
redraw_window();
set_aligned_position(320,115,1,1,texty[5]);
outtext(texty[5]);
ukaz_mysku();
showview(0,0,0,0);
cancel_render=1;
}
/*void user_setup()
{
initmode256(cur_xlat);
init_mysky();
hranice_mysky(0,0,639,479);
mouse_set_default(H_MS_DEFAULT);
ukaz_mysku();
setup_dialoge();
escape();
schovej_mysku();
closemode();
}
*/

1715
game/skeldal.c Normal file

File diff suppressed because it is too large Load diff

642
game/sndandmus.c Normal file
View file

@ -0,0 +1,642 @@
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
#include <memman.h>
#include <zvuk.h>
#include <wav_mem.h>
#include <event.h>
#include "globals.h"
#include <math.h>
#include <strlite.h>
#include <unistd.h>
#define PL_RANDOM 1
#define PL_FORWARD 2
#define PL_FIRST 3
#define CHANNELS 20
#define TRACKS 512
#define SND_EFF_MAXVOL 32000
#define SND_EFF_DESCENT 8000
#define have_loop(x) ((x)->start_loop!=(x)->end_loop)
typedef unsigned short SND_FIND_TABLE[2];
typedef struct snd_info
{
TMA_SOUND *data; //4
short xpos,ypos,side; //10
word volume,block; //14
}SND_INFO;
static short chan_state[CHANNELS];
static short track_state[TRACKS];
short sample_volume=255;
//static struct t_wave wav_last_head;
//static int wav_last_size;
static int mute_task=-1;
static char sound_enabled=1;
SND_INFO tracks[TRACKS];
SND_INFO playings[CHANNELS];
static word locks[32];
TSTR_LIST cur_playlist=NULL;
TSTR_LIST sound_table=NULL;
int playlist_size;
int playing_track=0;
int remain_play=0;
int play_list_mode=PL_RANDOM;
void init_tracks()
{
memset(tracks,0,sizeof(tracks));
memset(playings,0,sizeof(playings));
memset(chan_state,0xff,sizeof(chan_state));
memset(track_state,0xff,sizeof(track_state));
memset(locks,0,sizeof(locks));
}
static char last_beep_lev;
/*void pcspeak_uroven(char value,int time);
#pragma aux pcspeak_uroven parm[bh][ecx]=\
"mov ah,last_beep_lev"\
"lp2:add ah,bh"\
"mov al,48h"\
"jc lp1"\
"mov al,4ah"\
"lp1:out 61h,al"\
"loop lp2"\
"mov last_beep_lev,ah"\
modify [eax]
static int get_pc_speed()
{
int ticks=0;
int timer=get_timer_value();
while (get_timer_value()-timer<50) pcspeak_uroven(127,1000),ticks+=1000;
return ticks;
}
void pc_speak_play_sample(char *sample,int size,char step,int freq)
{
static speed=0;
int ticker;
if (!speed) speed=get_pc_speed();
_disable();
ticker=speed/freq;
sample+=step/2;
while (size>0)
{
if (step==2)
pcspeak_uroven(*sample ^ 0x80,ticker);
else
pcspeak_uroven(*sample,ticker);
sample+=step;
size-=step;
}
_enable();
nosound();
}
*/
int find_free_channel(int stamp)
{
int i,j;
int minvol,left,right,mid;
j=0;
if (stamp) for(i=0;i<CHANNELS;i++) if (chan_state[i]==stamp) return i;
minvol=0xffff;
for(i=0;i<CHANNELS;i++)
{
if (!get_channel_state(i)) return i;
get_channel_volume(i,&left,&right);
mid=(left+right)/2;
if (playings[i].side<0) mid*=2;
if (mid<minvol)
{
minvol=mid;j=i;
}
}
return j;
}
void release_channel(int channel)
{
int i;
i=chan_state[channel];
if (i==-1) return;
mute_channel(channel);
{
aunlock(playings[channel].block);
chan_state[channel]=-1;
track_state[i]=-1;
}
}
int calc_volume(int *x,int *y,int side)
{
int ds;
side&=3;*x=-(*x);*y=-(*y);
*x+=(side==1)*(*x>=0)-(side==3)*(*x<=0);
*y+=(side==2)*(*y>=0)-(side==0)*(*y<=0);
ds=abs(*x)+abs(*y);
ds=SND_EFF_MAXVOL-(SND_EFF_DESCENT*8*ds)/(8+ds);
return ds;
}
int calcul_volume(int chan,int x,int y,int side,int volume)
{
int lv,rv;
int ds,bal,i;
if (side==-1) side=viewdir;
side&=3;
ds=calc_volume(&x,&y,side);
if (ds<=0)
{
release_channel(chan);
return -1;
}
for(i=0;i<viewdir;i++)
{
bal=x;
x=y;
y=-bal;
}
y=abs(y);
if (abs(x)>y)
if (x>0) bal=100-y*50/x;else bal=-100-y*50/x;
else bal=50*x/y;
ds=ds*volume/100;
if (bal<0)
{
lv=ds*(100+bal)/100;rv=ds;
}
else
{
rv=ds*(100-bal)/100;lv=ds;
}
lv=(lv*sample_volume)>>8;
rv=(rv*sample_volume)>>8;
set_channel_volume(chan,lv,rv);
return 0;
}
void wav_load(void **p,long *s)
{
char *sr;
long *d;
char *c;
char *tg;
void *tgr;
size_t siz;
struct t_wave x[3];
sr=*p;
sr=find_chunk(sr,WAV_FMT);
read_chunk(sr,&x);
sr=*p;
sr=find_chunk(sr,WAV_DATA);
*s=get_chunk_size(sr);
tgr=tg=getmem(*s+sizeof(struct t_wave)+4);
memcpy(tgr,x,sizeof(struct t_wave));
tg+=sizeof(struct t_wave);
*(int *)tg=*s;
tg+=4;
read_chunk(sr,tg);
free(*p);
*p=tgr;
siz=*s;
*s+=sizeof(struct t_wave)+4;
/* if (x[0].freq!=x[0].bps)
{
char s;
siz>>=1;
s=siz & 1;
siz>>=1;
d=tg;
for(;siz--;d++) *d^=0x80008000;
if (s) {c=(char *)d;c[1]^=0x80;}
}
else
{
char s;
s=siz & 3;
siz>>=2;
d=(long *)tg;
for(;siz--;d++) *d^=0x80808080;
c=(char *)d;
for(;s--;c++) *c^=0x80;
}*/
}
void play_effekt(int x,int y,int xd,int yd,int side,int sided,TMA_SOUND *p)
{
int chan;
int blockid;
SND_INFO *track;
THANDLE_DATA *z;
char *s;
if (!sound_enabled) return;
side;
chan=find_free_channel(p->soundid);
release_channel(chan);
track=&tracks[p->soundid];
track->data=p;
track->xpos=xd;
track->ypos=yd;
track->side=sided;
track_state[p->soundid]=-1;
if (p->bit16 & 0x8)
{
int vol=SND_EFF_MAXVOL*p->volume/100;
if (rnd(100)>50) set_channel_volume(chan,rnd(vol),vol);
else set_channel_volume(chan,vol,rnd(vol));
}
else
if (calcul_volume(chan,x-xd,y-yd,/*side-*/sided,p->volume)) return;
if (p->filename[0]==1) memcpy(&blockid,&p->filename[1],4);
else
{
blockid=find_handle(p->filename,wav_load);
if (blockid==-1)
{
z=def_handle(end_ptr,p->filename,wav_load,SR_ZVUKY);
blockid=end_ptr++;
if (level_preload) apreload(blockid);
}
memcpy(&p->filename[1],&blockid,4);
p->filename[0]=1;
}
alock(blockid);
s=ablock(blockid);
s+=p->offset+sizeof(struct t_wave)+4;
play_sample(chan,s,p->end_loop-p->offset,p->start_loop-p->offset,p->freq,1+(p->bit16 & 1));
playings[chan].data=p;
playings[chan].xpos=xd;
playings[chan].ypos=yd;
playings[chan].side=sided;
playings[chan].volume=p->volume;
playings[chan].block=blockid;
chan_state[chan]=p->soundid;
track_state[p->soundid]=chan;
}
void restore_sound_name(TMA_SOUND *p)
{
int blockid;
THANDLE_DATA *h;
if (p->filename[0]==1)
{
memcpy(&blockid,&p->filename[1],4);
do
{
h=get_handle(blockid);
if (h->status==BK_SAME_AS) blockid=h->seekpos;else blockid=-1;
}
while (blockid!=-1);
strncpy(p->filename,h->src_file,12);
}
}
void restore_sound_names()
{
int i;
for(i=0;i<mapsize*4;i++)
if (macros[i]!=NULL)
{
int *r,mcsiz;
TMULTI_ACTION *z;
r=macros[i];
while ((mcsiz=*r)!=0)
{
r++;
z=(TMULTI_ACTION *)r;
if (z->general.action==MA_SOUND) restore_sound_name(&z->sound);
r=(int *)((char *)r+mcsiz);
}
}
}
void recalc_volumes(int sector,int side)
{
int i;
int newx,newy,layer;
if (sector>=mapsize) return;
side;
SEND_LOG("(SOUND) %s","Recalculating volumes",0);
newx=map_coord[sector].x;
newy=map_coord[sector].y;
layer=map_coord[sector].layer;
for(i=0;i<CHANNELS;i++)
if (chan_state[i]>=0 && playings[i].side>=0)
{
calcul_volume(i,newx-playings[i].xpos,newy-playings[i].ypos,/*side-*/playings[i].side,playings[i].volume);
if (!get_channel_state(i)) release_channel(i);
}
else calcul_volume(i,0,0,-1,playings[i].volume);
for(i=1;i<TRACKS;i++) if (track_state[i]<0 && tracks[i].data!=NULL)
{
if (tracks[i].side<0)
{
if (have_loop(tracks[i].data))
play_effekt(0,0,0,0,-1,-1,tracks[i].data);
}
else
{
int x=newx-tracks[i].xpos, y=newy-tracks[i].ypos;
if (calc_volume(&x,&y,tracks[i].side)>0)
if (have_loop(tracks[i].data))play_effekt(newx,newy,tracks[i].xpos,tracks[i].ypos,side,tracks[i].side,tracks[i].data);
}
}
mute_task=-1;
}
void create_playlist(char *playlist)
{
char *c;
char mode[20];
char shift;
int i=1,j;
if (cur_playlist!=NULL) release_list(cur_playlist);
cur_playlist=NULL;
if (playlist==NULL) return;
if (playlist=="") return;
c=playlist;
while (*c && *c==32) c++;
sscanf(c,"%s",mode);
strupr(mode);
shift=1;
if (!strcmp(mode,"RANDOM")) play_list_mode=PL_RANDOM;
else if (!strcmp(mode,"FORWARD")) play_list_mode=PL_FORWARD;
else if (!strcmp(mode,"FIRST")) play_list_mode=PL_FIRST;
else shift=0;
if (shift) c+=strlen(mode);else play_list_mode=PL_RANDOM;
while (*c && *c==32) c++;
playlist=c;
if (playlist=="") return;
for (c=playlist;c!=NULL;c=strchr(c+1,' ')) i++;
playlist_size=i-1;
cur_playlist=create_list(i);
j=0;
for (c=playlist;c!=NULL;c=strchr(c+1,' '))
{
char *e;
char d[MAX_FILESYSTEM_PATH+2]="!";
strncat(d,c+j,MAX_FILESYSTEM_PATH);d[MAX_FILESYSTEM_PATH+1]=0;j=1;
if ((e=strchr(d,32))!=NULL) *e=0;
str_add(&cur_playlist,d);
}
if (play_list_mode==PL_FIRST)
{
cur_playlist[0][0]=32;
remain_play=1;
play_list_mode=PL_RANDOM;
}
else
{
remain_play=0;
}
playing_track=-1;
}
void play_next_music(char **c)
{
int i,step;
static char d[MAX_FILESYSTEM_PATH];
*c=NULL;
if (cur_playlist==NULL) return;
if (!remain_play)
for(i=0;cur_playlist[i]!=NULL;remain_play++,i++) cur_playlist[i][0]=32;
if (play_list_mode==PL_RANDOM)
step=rand()*(playlist_size-1)/32768+1;
else
step=1;
i=playing_track;
do
{
i++;
if (cur_playlist[i]==NULL) i=0;
if (cur_playlist[i][0]==32) step--;
}
while (step);
playing_track=i;
snprintf(d,sizeof(d),"%s%s",pathtable[SR_MUSIC],cur_playlist[i]+1);
if (access(d,0) == -1)
snprintf(d,sizeof(d),"%s%s",pathtable[SR_ORGMUSIC],cur_playlist[i]+1);
cur_playlist[i][0]=33;
remain_play--;
*c=d;
}
void purge_playlist()
{
if (cur_playlist!=NULL)release_list(cur_playlist);
cur_playlist=NULL;
}
void play_sample_at_sector(int sample,int sector1,int sector2,int track, char loop)
{
int x,y,xd,yd,chan;
char *s;
struct t_wave *p;
int siz;
int oldtrack;
if (!sound_enabled) return;
if (map_coord[sector1].layer!=map_coord[sector2].layer) return;
x=map_coord[sector1].x;
y=map_coord[sector1].y;
xd=map_coord[sector2].x;
yd=map_coord[sector2].y;
chan=find_free_channel(track);
oldtrack=track_state[track];
if (!track || oldtrack==-1) release_channel(chan);
if (calcul_volume(chan,x-xd,y-yd,viewdir,100)) return;
if (!track || oldtrack==-1)
{
alock(sample);
s=ablock(sample);
p=(struct t_wave *)s;
s+=sizeof(struct t_wave);
siz=*(int *)s;s+=4;
play_sample(chan,s,siz,loop?0:siz,p->freq,(p->freq!=p->bps?2:1));
playings[chan].data=NULL;
}
playings[chan].xpos=xd;
playings[chan].ypos=yd;
playings[chan].side=viewdir;
playings[chan].volume=100;
playings[chan].block=sample;
chan_state[chan]=track;
track_state[track]=chan;
}
void play_sample_at_channel(int sample,int channel,int vol)
{
char *s;
struct t_wave *p;
int siz;
if (!sound_enabled) return;
channel+=CHANNELS;
vol*=SND_EFF_MAXVOL/100;
set_channel_volume(channel,vol,vol);
if (locks[channel]) aunlock(locks[channel]);
alock(sample);
locks[channel]=sample;
s=ablock(sample);
p=(struct t_wave *)s;
s+=sizeof(struct t_wave);
siz=*(int *)s;s+=4;
play_sample(channel,s,siz,siz,p->freq,(p->freq!=p->bps?2:1));
}
void create_sound_table(char *template,long size)
{
char *c,*s;
int i=0;
if (sound_table==NULL) sound_table=create_list(2);
s=c=template;
while (c-s<size)
{
if (c[0]!=0) str_replace(&sound_table,i,c);
c=strchr(c,0)+1;
i++;
}
}
void create_sound_table_old()
{
char *c,*s;
long pocet;
int i=0;
if (sound_table==NULL) sound_table=create_list(2);
s=c=ablock(H_SOUND_DAT);
memcpy(&pocet,s,sizeof(long));c+=4;
while (pocet--)
{
if (c[0]!=0) str_replace(&sound_table,i,c);
c=strchr(c,0)+1;
i++;
}
}
void stop_track(int track)
{
int chan;
chan=track_state[track];
if (chan==-1) return;
chan_break_loop(chan);
}
void stop_track_free(int track)
{
int chan;
chan=track_state[track];
if (chan==-1) return;
chan_break_loop(chan);
track_state[track]=-1;
chan_state[chan]=0;
}
void mute_all_tracks(char all)
{
int i;
for(i=0;i<CHANNELS;i++)
if (playings[i].side!=-1 || all) release_channel(i);
mute_task=-1;
SEND_LOG("(SOUND) %s (%d)","MUTE Tracks",all);
}
void kill_all_sounds()
{
int i;
SEND_LOG("(SOUND) Killing sound tracks...",0,0);
for (i=0;i<CHANNELS;i++) release_channel(i);
for (i=0;i<32;i++) if (locks[i]!=0) aunlock(locks[i]);
}
char test_playing(int track)
{
return track_state[track]!=-1;
}
static int flute_canal=30;
void start_play_flute(char note)
{
void *q;
char *w;
float realfrq;
int vol=50;
realfrq=16000*pow(2,note/12.0);
if (check_snd_effect(SND_GFX))
{
q=ablock(H_FLETNA);
w=q;w+=sizeof(struct t_wave)+4;
vol*=SND_EFF_MAXVOL/100;
set_channel_volume(flute_canal,vol,vol);
play_sample(flute_canal,w,0x1665,0xADE,(int)(realfrq+0.5),1);
}
else
{
//sound((unsigned short)(realfrq/30.53));
}
}
void stop_play_flute()
{
void *q;
char *w;
if (check_snd_effect(SND_GFX))
{
q=ablock(H_FLETNA);
w=q;w+=sizeof(struct t_wave);
chan_break_ext(flute_canal,w+4,*(int *)w);
flute_canal^=1;
}
else
{
//nosound();
}
}
char enable_sound(char enbl)
{
register char save;
save=sound_enabled;
sound_enabled=enbl;
SEND_LOG("(SOUND) Sound status (en/dis) changed: new %d, old %d",enbl,save);
return save;
}

2441
game/souboje.c Normal file

File diff suppressed because it is too large Load diff

707
game/specproc.c Normal file
View file

@ -0,0 +1,707 @@
//Toto je hlavni soubor specialnich procedur pro hru BRANY SKELDALU
#include <skeldal_win.h>
#include <stdio.h>
#include <stdlib.h>
#include <event.h>
#include <strlite.h>
#include "bgraph.h"
#include "globals.h"
#include "specproc.h"
#include "bmouse.h"
#include <math.h>
//#include "i86.h"
#define MOB_GO(m) if (m->dir & 1)m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir]
int cur_event_number;
static void event_error(char *text,int number)
{
char buff[256];
closemode();
sprintf(buff,"%s\n Specproc num: %d\n",text,number);
display_error(buff);
exit(1);
}
//Item procs---------------------------------------
ITEM_PROC(item_test)
{
putchar('\x7');event,ptr,p;
putchar('\n');
return 1;
}
//Map procs---------------------------------------
MAP_PROC(map_test)
{
putchar('\x7');sector,side,event,value;
putchar('\n');
return 1;
}
void spell_teleport();
MAP_PROC(map_teleport)
{
side=0;event;
teleport_target=value;
if (mob_map[sector]!=0)
{
int i;
spell_teleport(-mob_map[sector],-1);
if ((i=mobs[mob_map[sector]-1].next)!=0)
spell_teleport(-i,-1);
side=1;
}
if (map_coord[sector].flags & MC_DPLAYER)
{
int i,j=-1;THUMAN *h;
int bit=0;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++) if (h->used && h->sektor==sector && h->sektor==viewsector)
{
j=i;break;
}
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++) if (h->used && h->sektor==sector) bit|=1<<i;
postavy_teleport_effect(teleport_target,h->direction,bit,j!=-1);
side=1;
auto_group();
}
return side;
}
/*
static void otoc_obraz1(word *source,word *target)
{
word *p,*q;
word *sp,*sq;
int x,y;
sp=source+320-180;
sq=target+scr_linelen2*359+320-180;
y=360;
while (y--)
{
p=sp;
q=sq;
x=360;
while (x--)
{
*q=*p;
q-=scr_linelen2;
p++;
}
sp+=scr_linelen2;
sq++;
}
}
void swap_screen(word *_p,word *_q)
{
__asm
{
mov esi,_p
mov edi,_q
std
mov ecx,115200
lp1:
mov ax,[edi]
xchg ax,[esi]
stosw
add esi,2
dec ecx
jnz lp1
cld
}
}
// #pragma aux swap_screen parm [esi][edi]=\ modify [ecx eax]
static void otoc_obraz2(word *source)
{
swap_screen(source,source+scr_linelen2*360-2);
}
static void otoc_obraz3(word *source,word *target,short smer)
{
word *tt,*ss;
int x,y,xs,ys;
int xp,yp;
tt=target;
if (smer>0)x=320+126-224;else x=320+126+224;
if (smer>0)y=180-126-224;else y=180+126-224;
yp=360;
ys=0;
while (yp--)
{
xs=0;
ss=source+scr_linelen2*y+x;
xp=640;
while (xp--)
{
if (ss>=source && ss<source+scr_linelen2*360) *tt++=*ss; else *tt++=0;
xs+=7;
if (xs>10)
{
xs-=10;
ss+=scr_linelen2+smer;
}
}
ys+=7;
if (ys>10)
if (smer>0)
{
ys-=10;
x--;
y++;
}
else
{
ys-=10;
x--;
y--;
}
}
}
static void show_liane(THE_TIMER *t)
{
word *bt,*bs;
static int counter=0;
schovej_mysku();
if (counter<5 && counter)
{
bt=GetScreenAdr()+SCREEN_OFFSET;
bs=GetBuffer2nd()+SCREEN_OFFSET;
}
else
{
redraw_scene();
bs=GetScreenAdr()+SCREEN_OFFSET;
}
switch(counter)
{
case 0:break;
case 1:otoc_obraz3(bs,bt,1);break;
case 2:curcolor=0;
bar(0,SCREEN_OFFLINE,139,SCREEN_OFFLINE+359);
bar(640-140,SCREEN_OFFLINE,639,SCREEN_OFFLINE+359);
otoc_obraz1(bs,bt);break;
case 3:otoc_obraz3(bs,bt,-1);break;
default:otoc_obraz2(bs);if (counter==4)OutBuffer2nd();break;
}
ukaz_mysku();
showview(0,0,0,0);
if (!counter)
{
schovej_mysku();
OutBuffer2nd();
ukaz_mysku();
}
if (t->calls==1)
{
THUMAN *h;
int i;
save_load_trigger((word)(t->userdata[0]));
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++) if (get_player_triggered(i))
{
player_hit(h,h->lives,0);
h->sektor=0;
}
wire_proc();
counter=-1;
}
counter++;
}
*/
static const float Inv2=0.5;
static const float Snapper=3<<22;
static __inline int toInt(float fval)
{
fval += Snapper;
return ( (*(int *)&fval)&0x007fffff ) - 0x00400000;
}
static void OtocObrazPodleMatice(float mx[3][2], word *picture)
{
word *trg=GetScreenAdr()+17*scr_linelen2;
int x,y;
picture+=6;
for (y=0;y<360;y++,trg+=scr_linelen2)
for (x=0;x<640;x++)
{
int oldx=x-320;
int oldy=y-180;
int newx=toInt(oldx*mx[0][0]+oldy*mx[1][0]+320);
int newy=toInt(oldx*mx[0][1]+oldy*mx[1][1]+180);
if (newx>=0 && newx<640 && newy>=0 && newy<360)
trg[x]=picture[newx+640*newy];
else
trg[x]=0;
}
}
static void OtaceniObrazu()
{
word *picture=(word *)malloc(640*360*2+16);
float mx[3][2];
int maxtime=500;
int lasttime=get_game_tick_count();
int curtime;
get_picture(0,17,640,360,picture);
do
{
float phase;
float uhel;
float cosuhel;
float sinuhel;
curtime=get_game_tick_count()-lasttime;
phase=curtime/(float)maxtime;
if (phase>1.0f) phase=1.0f;
uhel=phase*3.14159265;
cosuhel=cos(uhel);
sinuhel=sin(uhel);
mx[0][0]=cosuhel;
mx[0][1]=sinuhel;
mx[1][0]=-sinuhel;
mx[1][1]=cosuhel;
OtocObrazPodleMatice(mx,picture);
showview(0,0,0,0);
do_events();
}
while (curtime<maxtime);
sleep_ms(1000);
free(picture);
}
MAP_PROC(map_liana)
{
int i;
THUMAN *h;
value;
sector,side,event;
bott_draw(1);
other_draw();
unwire_proc();
// add_to_timer(TM_SCENE,gamespeed,15,show_liane)->userdata[0]=save_load_trigger(-1);
schovej_mysku();
OtaceniObrazu();
ukaz_mysku();
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++) if (get_player_triggered(i))
{
player_hit(h,h->lives,0);
h->sektor=0;
}
redraw_scene();
cancel_pass=1;
cancel_render=1;
showview(0,0,0,0);
wire_proc();
return 1;
}
#define ID_XS 400
#define ID_YS 380
MAP_PROC(map_identify)
{
int x,y,yp,xp,ys,yss;
int i,cnt;char s[100];
TITEM *it;
TSTR_LIST ls;
sector;side;event;value;
if (picked_item==NULL) return 0;
it=glob_items+*picked_item-1;
ls=create_list(256);
unwire_proc();
sprintf(s,texty[210],it->jmeno);str_add(&ls,s);
sprintf(s,texty[211],it->hmotnost*2,it->hmotnost>0 && it->hmotnost<3?texty[236]:texty[237]);str_add(&ls,s);
if (it->nosnost)
{
sprintf(s,texty[212],it->nosnost);str_add(&ls,s);
}
for(i=0;i<21;i++)
if (it->zmeny[i] && texty[213+i]!=NULL)
{
if (i==VLS_HPREG || i==VLS_MPREG || i==VLS_VPREG)
sprintf(s,texty[213+i],it->zmeny[i]>0?texty[234]:texty[235]);
else
sprintf(s,texty[213+i],it->zmeny[i],it->zmeny[i+1]);
str_add(&ls,s);
}
if (it->zmeny[VLS_MGSIL_H])
{
sprintf(s,texty[233],texty[22+it->zmeny[VLS_MGZIVEL]]);str_add(&ls,s);
}
for(i=0;i<16;i++)
if (it->zmeny[VLS_KOUZLA] & (1<<i) && texty[i+240]!=NULL) str_add(&ls,texty[i+240]);
for(i=str_count(ls);i>0;i--) if (ls[i-1]!=NULL) break;
cnt=i;i=0;
ys=cnt*10+10;
do
{
x=320-ID_XS/2;
y=y=240-ys/2;
create_frame(x,y,ID_XS,ys,1);
xp=x+5;yp=y+5;ys=ID_YS-10;
set_font(H_FBOLD,NOSHADOW(0));
yss=ys;
while(i<cnt)
{
position(xp,yp);outtext(ls[i]);
yp+=10;yss-=10;
i++;
}
showview(0,0,0,0);
getchar();
wire_proc();
}
while (i<cnt);
return 1;
}
//Mob Procs ---------------------------------------
static int get_dangerous_place(int sector)
{
int i;
for(i=0;i<4;i++)
{
int s=map_sectors[sector].step_next[i];
if (s && map_coord[s].flags & MC_PLAYER) return 1;
}
return 0;
}
MOB_PROC(mob_open_door)
{
if (event==SMPR_WALK)
if (m->user_data<128 || m->user_data>192)
{
int sector=m->sector;
int i;
TSTENA *side;
for(i=0,side=map_sides+(sector<<2);i<4;side++,i++)
if (side->flags & SD_MONST_IMPS && side->sector_tag!=0 && (~side->flags & (SD_PASS_ACTION | SD_SECRET))==(SD_PASS_ACTION|SD_SECRET))
break;
if (i!=4)
{
m->dir=i;stop_mob(m);
if (flag_map[(sector<<2)+i] & SD_MONST_IMPS) a_touch(sector,m->dir);
m->user_data=128;
return 1;
}
side=map_sides+(sector<<2)+((m->dir+2)&3);
if (~side->flags & SD_MONST_IMPS && side->sector_tag!=0 && (~side->flags & (SD_PASS_ACTION | SD_SECRET))==(SD_PASS_ACTION|SD_SECRET))
{
int ss=map_sectors[sector].step_next[(m->dir+2)&3];
int j=mob_map[ss];
while (j) if (mobs[j-1].dir==m->dir) return 0;
else j=mobs[j-1].next;
a_touch(sector,(m->dir+2)&3);
return 0;
}
}
else
{
if (m->user_data>=128 && m->user_data<192) m->user_data++;
if (~map_sides[(m->sector<<2)+m->dir].flags & SD_MONST_IMPS)
{
if (m->dir & 1) m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir];
m->user_data=map_coord[map_sectors[m->sector].step_next[m->dir]].flags & MC_PLAYER?255:127;
}
return m->user_data<144;
}
return 0;
}
MOB_PROC(mob_open_door_battle)
{
if (event==SMPR_ATTACK)
{
m->specproc=5;
}
return 0;
}
static char spec_proc_test_mob(int event_type,TMOB *m)
{
m,event_type;
putchar('\x7');
putchar('\n');
return 0;
}
static char mob_dokola(int event_type,TMOB *m)
{
if (event_type==SMPR_WALK)
{
m->dir++;
m->dir &=3;
MOB_GO(m);
return 1;
}
return 0;
}
static char mob_carodej(int event_type,TMOB *m)
{
static char kouzla[5]={3,8,13,18,80};
if (event_type==SMPR_ATTACK)
{
m->casting=kouzla[rnd(5)];
}
return 0;
}
static char mob_strelec(int event_type,TMOB *m)
{
if (event_type==SMPR_ATTACK)
{
int i,l;
if (m->dostal==0 && ~m->user_data & 128) return 0;
for (i=0;i<4;i++)
{
l=map_sectors[m->sector].step_next[i];
if (l!=0 && map_coord[l].flags & MC_PLAYER) break;
}
if (i==4)
{
if (m->user_data & 128)
{
int s=m->sector;
m->user_data&=~128;
i=m->dir+2&3;
while (s && !(map_coord[s].flags & MC_PLAYER)) if (map_sides[(s<<2)+i].flags & SD_MONST_IMPS) s=0;else s=map_sectors[s].step_next[i];
if (s) m->dir=i;else return 1;
}
return 0; //strilej
}
i=i+2&3;
if (mob_check_next_sector(m->sector,i,m->stay_strategy & MOB_BIG,0))
{
int l=4,z,max=RAND_MAX;
for(i=0;i<4;i++)
if (!mob_check_next_sector(m->sector,i,m->stay_strategy & MOB_BIG,0))
{
int s=map_sectors[m->sector].step_next[i];
if (!get_dangerous_place(s) && (z=rand())<max) max=z,l=i;
}
if (l==4) return 0;
i=l;
}
m->dir=i;
MOB_GO(m);
m->user_data|=128;
return 1;
}
else
{
/*
int i,l;
i=m->dir;
l=m->sector;
if (map_sides[(l<<2)+i].flags & SD_MONST_IMPS) return 0;
l=map_sectors[l].step_next[i];
for(i=0;i<4;i++)
{
int s=map_sectors[l].step_next[i];
if (isplayer(s,NULL,0)!=NULL)
{
m->dir=i+2&3;
m->headx=mob_go_x[i];
m->heady=mob_go_y[i];
return 1;
}
}
*/
if (m->user_data & 128)
{
THUMAN *h;
int i;
for(i=0,h=postavy;i<POCET_POSTAV;i++,h++)
if (h->lives && h->used &&
abs(map_coord[h->sektor].x-map_coord[m->sector].x)<2 &&
abs(map_coord[h->sektor].y-map_coord[m->sector].y)<2)
{
stop_mob(m);
return 1;
}
}
return 0; //delej si co chces
}
}
MOB_PROC(mob_krikloun)
{
if (event==SMPR_ATTACK)
{
sirit_zvuk(m->sector);
}
return 0;
}
static char mob_taktik_recurse(int recall,int sector,int *min_obr,int big,int *csect,int *cdir)
{
int i;
char nasel=0;
//nejprve zjistime kdo je okolo nas
for(i=0;i<4;i++)
{
int s=map_sectors[sector].step_next[i];
THUMAN *h=NULL;
if (!s) continue; //pokud tam je stena tak pokracuj jinym smerem
if (mob_check_next_sector(sector,i,big,0)==1) continue;
if ((h=isplayer(s,h,0))!=NULL) //nekdo tam je - zjisti kdo
while(h!=NULL)
{
if (h->vlastnosti[VLS_OBRAN_H]<*min_obr) // pokud ma nizsi obranu
{
*csect=sector;
*cdir=i;
*min_obr=h->vlastnosti[VLS_OBRAN_H];
nasel=1;
}
h=isplayer(s,h,0);
}
else if (recall) //pokud tam nikdo neni koukni se vedle
{
if (mob_taktik_recurse(0,s,min_obr,big,csect,cdir)) *cdir=i;
}
}
return nasel;
}
MOB_PROC(mob_taktik)
{
int min_obr=1000;
int csect=m->sector;
int cdir=-1;
if (event==SMPR_ATTACK)
{
mob_taktik_recurse(1,m->sector,&min_obr,m->stay_strategy & MOB_BIG,&csect,&cdir);
if (cdir==-1) return 0;
m->dir=cdir;
if (m->sector!=csect)
{
MOB_GO(m);
return 1;
}
}
return 0;
}
MOB_PROC(mob_stoji)
{
if (event==SMPR_ATTACK)
{
int i;
int s;
for(i=0;i<4;i++)
{
s=map_sectors[m->sector].step_next[i];
if (s && map_coord[s].flags & MC_PLAYER) return 0;
}
m->headx=m->locx;
m->heady=m->locy;
m->stay_strategy&=~(MOB_WALK | MOB_LISTEN);
m->vlajky&=~MOB_IN_BATTLE;
return 1;
}
else if (event==SMPR_WALK)
{
m->headx=m->locx;
m->heady=m->locy;
}
else if (event==SMPR_KNOCK) return 1;
return 0;
}
static t_mob_proc sp_mob_table[]=
{
NULL, //0
spec_proc_test_mob, //1
mob_dokola, //2
mob_carodej, //3
mob_strelec, //4
mob_open_door, //5
mob_open_door_battle, //6
mob_krikloun, //7
mob_taktik, //8
mob_stoji, //9
};
#define SP_MOB_TAB_SIZE (sizeof(sp_mob_table)/sizeof(t_mob_proc))
static t_item_proc sp_item_table[]=
{
NULL, //0
item_test, //1
};
#define SP_ITEM_TAB_SIZE (sizeof(sp_item_table)/sizeof(t_item_proc))
static t_map_proc sp_map_table[]=
{
NULL, //0
map_test, //1
map_teleport, //2
map_liana, //3
map_identify, //4
};
#define SP_MAP_TAB_SIZE (sizeof(sp_map_table)/sizeof(t_map_proc))
char call_mob_event(int event_number,int event_type,TMOB *m)
{
if (!event_number) return 0;
if (event_number>=SP_MOB_TAB_SIZE)
event_error("Nestv<EFBFBD>ra pou<6F><75>va neplatnou specproc.",event_number);
cur_event_number=event_number;
return sp_mob_table[event_number](event_type,m);
}
char call_item_event(int event_number,int event_type,short *ptr,THUMAN *p)
{
if (!event_number) return 0;
if (event_number>=SP_ITEM_TAB_SIZE)
event_error("<EFBFBD><EFBFBD>slo ud<75>losti u v<>ci je neplatn<74>. Specproc nen<65> definov<6F>na.",event_number);
cur_event_number=event_number;
return sp_item_table[event_number](event_type,ptr,p);
}
char call_map_event(int event_number,int sector,int side,int value,int event)
{
if (!event_number) return 0;
if (event_number>=SP_MAP_TAB_SIZE)
event_error("Neplatn<EFBFBD> <20><>slo ud<75>losti na st<73>n<EFBFBD>. Specproc s t<>mto <20><>slem nen<65> definov<6F>na.",event_number);
cur_event_number=event_number;
return sp_map_table[event_number](sector,side,value,event);
}

39
game/specproc.h Normal file
View file

@ -0,0 +1,39 @@
#define SMPR_WALK 1
#define SMPR_ATTACK 2
#define SMPR_KNOCK 3 //povoleni, nebo zakazani KNOCK (zakazani = return 1)
#define SIPR_USAGE 1
#define SIPR_PICK 2
#define SIPR_DROP 3
typedef char (*t_mob_proc)(int event_type,TMOB *);
typedef char (*t_item_proc)(int event_type,short *ptr,THUMAN *p);
typedef char (*t_map_proc)(int sector,int side,int value,int event);
#define MOB_PROC(name) static char name(int event,TMOB *m)
#define ITEM_PROC(name) static char name(int event,short *ptr,THUMAN *p)
#define MAP_PROC(name) static char name(int sector,int side,int value,int event)
//specproc pro nestvury vraci char informaci
// 1 - nestvura ma jiz zadanou akci a program se zaridi podle pozadavku specproc
// 0 - specproc ignorovala udalost a nestvura se ma chovat stejne jako bez specproc
//specproc do mapy
// 1 - specproc uspesna
// 0 - specproc neuspesna
// value - je cislo predavane specproc
char call_map_event(int event_number,int sector,int side,int value,int event);
char call_item_event(int event_number,int event_type,short *ptr,THUMAN *p);
char call_mob_event(int event_number,int event_type,TMOB *m);
//funkce z enemy.c
char mob_check_next_sector(int sect,int dir,char alone,char passable);
//alone = MOB_BIG, passable= 1 je-li pruchozi
extern char mob_go_x[];
extern char mob_go_y[];

26
game/temp_storage.h Normal file
View file

@ -0,0 +1,26 @@
///store to temp storage
void temp_storage_store(const char *name, const void *data, long size);
///find in temp storage - returns -1 = not found, otherwise size of data
long temp_storage_find(const char *name);
///retrieve from temp storage (returns same as find)
long temp_storage_retrieve(const char *name, void *data, long size);
void temp_storage_list(void (*callback)(const char *, void *), void *context);
void temp_storage_clear();
typedef struct _temp_storage_file_rd TMPFILE_RD;
typedef struct _temp_storage_file_wr TMPFILE_WR;
TMPFILE_RD *temp_storage_open(const char *name);
TMPFILE_WR *temp_storage_create(const char *name);
TMPFILE_WR *temp_storage_append(const char *name);
void temp_storage_close_rd(TMPFILE_RD *f);
void temp_storage_close_wr(TMPFILE_WR *f);
void temp_storage_write(const void *data, unsigned long size, TMPFILE_WR *f);
unsigned long temp_storage_read(void *data, unsigned long size, TMPFILE_RD *f);
void temp_storage_skip(TMPFILE_RD *f, int bytes);

681
game/transav.c Normal file
View file

@ -0,0 +1,681 @@
#include <stdio.h>
#include <malloc.h>
#include <graph.h>
#include <mem.h>
#include <conio.h>
#include <bios.h>
#define EVENT_MSG long
#include "globals.h"
#include <memman.c>
#include <strlite.c>
#include <inicfg.c>
TSTR_LIST skini;
#define PLAYERS 3
void *datablast;
long datablastsize;
char *lasterror=NULL;
char relarr[6];
char szBuff[65536];
char sekceid[]="<BLOCK>";
typedef struct s_save
{
int viewsector;
int viewdir;
int gold;
short cur_group;
char autosave;
char enable_sort;
char shownames;
char showlives;
char zoom_speed;
char turn_speed;
char autoattack;
char music_vol;
char sample_vol;
char xbass;
char bass;
char treble;
char stereing;
char swapchans;
char out_filter;
long glob_flags;
long game_time;
char runes[5];
char level_name[12];
short picks; //pocet_sebranych predmetu v mysi
short items_added; //pocet_pridanych predmetu
int sleep_long;
int game_flags;
}S_SAVE;
typedef struct tkouzlo
{
word num,um,mge;
word pc;
short owner,accnum; //accnum = akumulacni cislo, owner = kdo kouzlo seslal
int start;
short cil; //kladna cisla jsou postavy zaporna potvory (0 je bez urceni postavy)
char povaha;
word backfire; //backfire / 1 = demon , 0 = bez demona
word wait; //wait - cekani pocet animaci
word delay; //delay - cekani pocet kol
char traceon; //jinak noanim - neprehravaji se animace a zvuky
char spellname[30];
}TKOUZLO;
typedef struct _tkzlall
{
TKOUZLO kouzlo;
short vlstab[24];
long flagmap;
}TKZLALL;
THUMAN postavy[6],postavy2[6];
S_SAVE s;
char mapname[13];
int startsect;
int startsid;
char cz_table_1[]=" 1!3457<35>908+,-./<2F>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\"<EFBFBD>?=:_2ABCDEFGHIJKLMNOPQRSTUVWXYZ<59>\\)6=;abcdefghijklmnopqrstuvwxyz/|(; ";
char cz_table_2[]=" !\"#$%&'()*+,-./0123456789:;<=>?@<40>BCD<43>FGH<47>JK<4A>MN<4D>PQ<50>ST<53>VWX<57>Z[\\]^_`<60>bcd<63>fgh<67>jk<6A>mn<6D>pq<70>st<73>vwx<77>z{|}~ ";
char cz_table_3[]=" !\"#$%&'()*+,-./0123456789:;<=>?@AB<41><42><EFBFBD>FGHIJK<4A>M<EFBFBD><4D>PQ<50><51><EFBFBD><EFBFBD>VWXY<58>[\\]^_`ab<61><62><EFBFBD>fghijk<6A>m<EFBFBD><6D>pq<70><71><EFBFBD><EFBFBD>vwxy<78>{|}~ ";
char *cz_key_tabs[]={cz_table_1,cz_table_2,cz_table_3};
word keyconv(word key)
{
int i;
static char cz_mode=0;
char c,d;
i=key;
d=i>>8;
c=i & 0xff;
if (c=='+' && d<55 && !cz_mode) cz_mode=2;
else if (c=='=' && d<55 && !cz_mode) cz_mode=1;
else if (c>32 && c<127 && d<=53)
{
c=cz_key_tabs[cz_mode][c-32];
i=d;
i=(i<<8)+c;
cz_mode=0;
return i;
}
else
return i;
return 0;
}
#define ZAKLAD_CRC 0xC005
static word vypocet_crc(char *data,long delka)
{
unsigned long l=0;
do
{
l=(l<<8)|(delka>0?*data++:0);delka--;
l=(l<<8)|(delka>0?*data++:0);delka--;
l%=ZAKLAD_CRC;
}
while(delka>-1);
return l & 0xffff;
}
static simple_cz_input(char *buff,int maxchars)
{
int cnt=strlen(buff);
int w;
char *a;
a=alloca(cnt+1);
strcpy(a,buff);
maxchars--;
cputs(buff);
do
{
w=_bios_keybrd(_KEYBRD_READ);
w=keyconv(w);
if (w==0) continue;
switch (w & 0xff)
{
case 13: return;
case 0x8: if (cnt>0)
{
cnt--;buff[cnt]=0;cputs("\x8 \x8");
}
break;
case 0:break;
case 27:strcpy(buff,a);
return;
default: if (cnt<maxchars) putch(buff[cnt++]=w & 0xff);
}
}
while(1);
}
void *addmem(void *to,void *from,int size)
{
memcpy(to,from,size);
return (void *)((char *)to+size);
}
void *loadmem(void *to,void *from,int size)
{
memcpy(to,from,size);
return (void *)((char *)from+size);
}
long load_section(FILE *f,void **section, int *sct_type,long *sect_size)
//
{
long s;
char c[20];
*section=NULL;
fread(c,1,sizeof(sekceid),f);
if (strcmp(c,sekceid)) return -1;
fread(sct_type,1,sizeof(*sct_type),f);
fread(sect_size,1,sizeof(*sect_size),f);
fread(&s,1,sizeof(s),f);
*section=malloc(*sect_size);
s=fread(*section,1,*sect_size,f);
return s;
}
static void load_specific_file(char *slotname,char *filename,void **out,long *size)
{
FILE *slot;
char *c,*d;
long siz;
char fname[12];
char succes=0;
slot=fopen(slotname,"rb");
if (slot==NULL)
{
*out=NULL;
return;
}
fseek(slot,SAVE_NAME_SIZE,SEEK_CUR);
fread(fname,1,12,slot);
while(fname[0] && !succes)
{
fread(&siz,1,4,slot);
if (!strncmp(fname,filename,12)) succes=1; else
{
fseek(slot,siz,SEEK_CUR);
fread(fname,1,12,slot);
}
}
if (succes)
{
*out=malloc(siz);
fread(*out,1,siz,slot);
*size=siz;
}
else *out=NULL;
fclose(slot);
}
void return_spells(int poc,TKZLALL *kzl)
{
int i;
for(i=0;i<poc;i++,kzl++)
{
int j;
THUMAN *h=postavy+kzl->kouzlo.cil-1;
if (kzl->kouzlo.cil>0)
{
for (j=0;j<22;j++) h->stare_vls[j]+=kzl->vlstab[j];
h->stare_vls[VLS_KOUZLA]&=~(kzl->flagmap & 0xffff);
}
}
}
void zero_inv(THUMAN *h)
{
h->inv_size=6;
memset(h->inv,0,sizeof(h->inv));
memset(h->wearing,0,sizeof(h->wearing));
memset(h->prsteny,0,sizeof(h->prsteny));
memcpy(h->vlastnosti,h->stare_vls,sizeof(h->vlastnosti));
h->demon_save=NULL;
h->sektor=startsect;
h->direction=startsid;
h->groupnum=1;
}
void zero_all_inv()
{
THUMAN *h=postavy;int i;
for (i=0;i<6;i++,h++) if (h->used) zero_inv(h);
}
void unpack_save(void *in)
{
int kouzel;
TKZLALL *kzl;
int i;
in=loadmem(&s,in,sizeof(s)); //load basic info
in=(void *)((char *)in+s.picks*2+s.items_added*sizeof(TITEM)); //skip items;
in=loadmem(&kouzel,in,sizeof(kouzel)); //load spell table
kzl=in; //signup spell table for future use
in=(void *)((char *)in+sizeof(TKZLALL)*kouzel);
in=loadmem(postavy,in,sizeof(postavy)); //load character table
for (i=0;i<6;i++)
if (postavy[i].demon_save!=NULL) //correct demons;
in=loadmem(postavy+i,in,sizeof(THUMAN));
//skip dialog info.
//load done;
return_spells(kouzel,kzl);
zero_all_inv();
s.viewsector=startsect;
s.viewdir=startsid;
s.picks=0;
s.items_added=0;
s.glob_flags=0;
s.game_time=0;
strncpy(s.level_name,mapname,12);
memset(s.runes,0,sizeof(s.runes));
}
void del_character(char c)
{
int i;
for(i=c;i<5;i++) relarr[i]=relarr[i+1];
relarr[i]=0;
}
void add_character(char c)
{
THUMAN *h=postavy+c;
int i;
if (!h->used)
{
lasterror="Musis vybrat postavu!";return;
}
for (i=0;i<6;i++) if (relarr[i]==c+1)
{
del_character(i);return;
}
for (i=0;i<6;i++) if (!relarr[i]) break;
if (i==6)
{
lasterror="Nevim sice jak se ti to povedlo, ale neni uz misto!";return;
}
relarr[i]=c+1;
}
char nvlast[][16]=
{"Sila","Schopnost magie","Pohyblivost","Obratnost","Max zraneni",
"Kondice","Max mana","Obrana(dolni)","Obrana(Horni)","Utok(Dolni)",
"Utok(Horni)","Ohen","Voda","Zeme","Vzduch","Mysl","Zivoty Regen",
"Mana Regen","Kondice Regen","Magicka sila(D)", "Magicka sila(H)","","Ucinnek zasahu","*"};
char *zbrane[]={"Mec","Sekera","Kladivo","Hul","Dyka","Strelne","Specialni"};
char build_players()
{
int i;
char z=0;
memset(postavy2,0,sizeof(postavy2));
for (i=0;i<6;i++)
if (relarr[i])postavy2[i]=postavy[relarr[i]-1],z=1;
return z;
}
void c_info(int b)
{
THUMAN *h=postavy+b;
int i;
do
{
_clearscreen(_GCLEARSCREEN);
for(i=0;i<22;i++)
{
cprintf("%-17s %3d ",nvlast[i],h->stare_vls[i]);
if (i<7)
cprintf("%-12s %3d ",zbrane[i],h->bonus_zbrani[i]);
if (i<7)
switch (i)
{
case 0: cprintf("Jmeno: %s",h->jmeno);break;
case 1: cprintf("Uroven: %d",h->level);break;
case 2: cprintf("Zkusenost: %d",h->exp);break;
case 3: cprintf("Pohlavi: %s",h->female?"Zena":"Muz");break;
case 4: cprintf("Portret: XICHT%02X.PCX",h->xicht);break;
case 5: cprintf("Jidlo: %d",h->jidlo/360);break;
case 6: cprintf("Voda: %d",h->voda/360);break;
}
cprintf("\n\r");
}
cprintf("ENTER - zmena jmena, P - pohlavi, X - vzhledu, ESC - navrat:");
do
{i=toupper(getche());putch(8);}
while (i!=13 && i!='X' && i!=27 && i!='P');
if (i==13)
{
cprintf("\r\n\n Zmen jmeno:");simple_cz_input(h->jmeno,sizeof(h->jmeno));
}
else if (i=='X')
{
cprintf("\r\n\n Jelikoz jednoduchost tohoto programu neumoznuje prohizet si obrazky je nutne\n\r"
"tuto volbu odzkouset metodou pokus omyl. Nikdo totiz nezaruci, zda v novem \n\r"
"dobrodruzstvi se nektere z postav nezmeni pohlavi (na obrazku).\r\n"
"V puvodnim SKELDALU:\n\r"
"--------------------\n\r"
"Muzi: 0, 2, 3, 4, 8(Roland), 12(Gralt), 13(Erik)\n\r"
"Zeny: 1, 5, 6, 7\n\r"
"\nZmenit vzhled <%d>, 'x' storno:",h->xicht);
if (scanf("%hd",&h->xicht)==0) while (getchar()!='\n');
}
else if (i=='P') h->female=!h->female;
}
while (i!=27) ;
}
char assign_players()
{
int i;
char c;
char backrel[6];
do
{
_clearscreen(_GCLEARSCREEN);
if (lasterror!=NULL) cprintf("%s\x7\r\n\n",lasterror);
lasterror=NULL;
memset(backrel,0,sizeof(backrel));
for (i=0;i<6;i++) if (relarr[i]) backrel[relarr[i]-1]=i+1;
cprintf("%-33s%s\n\r====================================================\n\r","Stare dobrodruzstvi","Nove dobrodruzstvi");
for(i=0;i<6;i++)
{
if (postavy[i].used)
cprintf("%c%d.%-30s",backrel[i]?'*':' ',i+1,postavy[i].jmeno);
else
cprintf(" %d.%-30s",i+1,"<prazdny slot>");
if (relarr[i])
cprintf("%c.%-30s",i+'a',postavy[relarr[i]-1].jmeno);
else
cprintf("%c.%-30s",i+'a',"<prazdny slot>");
cputs("\n\r");
}
cputs("\n\r");
cputs("[1]-[6] prenese postavu,\n\r"
"[a]-[f] maze postavu.\n\r"
"[SHIFT]+[1]-[6] info o postave\n\r"
"[S] ulozit\n\r"
"[Q] nebo [ESC] konec bez ulozeni\n\n\r");
cprintf("Doporuceny pocet postav v novem dobrodruzstvi je %d.\n\r",PLAYERS);
putch('>');
i=_bios_keybrd(_KEYBRD_READ);
c=toupper(i & 0xff);i>>=8;
switch (c)
{
case 27:
case 'Q':return 1;
case 'S':return 0;
default:
if (i==0) lasterror="Prepni na anglickou klavesnici!!!";
if (i>=2 && i<=7)
if (*(char *)0x417 & 0x3) c_info(i-2);
else add_character(i-2);
if (c>='A' && c<='F') del_character(c-'A');
break;
}
}
while(1);
}
char *scan_saves(char *text,char *path,char mustexists)
{
int i;
FILE *f;
do
{
_clearscreen(_GCLEARSCREEN);
cprintf("%s\n\r============================\n\r",text);
if (lasterror!=NULL) cprintf("%s\x7\r\n\n",lasterror);
lasterror=NULL;
for(i=0;i<10;i++)
{
sprintf(szBuff,"%sSLOT%02d.SAV",path,i);
cprintf("%d. ",(i+1)%10);
f=fopen(szBuff,"rb");
if (f!=NULL)
{
fread(szBuff,1,34,f);szBuff[34]=0;
fclose(f);
cprintf("%s\r\n",szBuff);
}
else
cputs("<nic>\r\n");
}
cputs("\nVyber [1]-[9] a [0] pozici.\n\r[ESC] zrusit.\n\r");
do
i=_bios_keybrd(_KEYBRD_READ)>>8;
while (i>11);
if (i==1) return NULL;
if (i==0) lasterror="Prepni na anglickou klavesnici!!!";
else
{
i-=2;
sprintf(szBuff,"%sSLOT%02d.SAV",path,i);
if (!mustexists || access(szBuff,F_OK)==0) return szBuff;
}
}
while(1);
}
int tracemap(char *name)
{
FILE *f;
void *section;
int type;
long size,s;
f=fopen(name,"rb");
if (f==NULL) return -1;
do
{
s=load_section(f,&section,&type,&size);
if (s!=size)
{
free(section);
fclose(f);
return -1;
}
if (type==A_MAPGLOB)
{
MAPGLOBAL mglob;
memcpy(&mglob,section,sizeof(mglob));
startsect=mglob.start_sector;
startsid=mglob.direction;
}
free(section);
}
while (type!=A_MAPEND);
fclose(f);
return 0;
}
void *build_gametmp(int *size)
{
int siz=*size;
void *zac,*p;
int i,crc;
siz+=256;
p=zac=malloc(siz);
p=addmem(p,&s,sizeof(s)); //add game info
//skip picks
//skip items added
i=0;//no spells;
p=addmem(p,&i,4);
p=addmem(p,postavy2,sizeof(postavy2));
p=addmem(p,&i,4); //no dialogs...
*size=(char *)p-(char *)zac;
crc=vypocet_crc(zac,*size);
p=addmem(p,&crc,2);
size[0]+=2;
return zac;
}
void save_savegame(char *soubor)
{
FILE *f;
void *p;
int s;
f=fopen(soubor,"wb");
strcpy(szBuff,"TRANSAV");
fwrite(szBuff,SAVE_NAME_SIZE,1,f);
strcpy(szBuff,"_GAME.TMP");
fwrite(szBuff,12,1,f);
s=datablastsize;
p=build_gametmp(&s);
fwrite(&s,4,1,f);
fwrite(p,s,1,f);
free(p);
szBuff[0]=0;
fwrite(szBuff,12,1,f);
fclose(f);
}
void begin_program(char *sourceadv,char *targetadv)
{
TSTR_LIST src,trg;
char *c;
src=read_config(sourceadv);
if (src==NULL)
{
cprintf("Nemohu otevrit zdrojove dobrodruzstvi: %s\n\r",sourceadv);
exit(1);
}
trg=read_config(targetadv);
if (trg==NULL)
{
cprintf("Nemohu otevrit cilove dobrodruzstvi: %s\n\r",targetadv);
exit(1);
}
c=get_text_field(trg,"DEFAULT_MAP");
if (c==NULL)
{
cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku DEFAULT_MAP\n\r", targetadv);
exit(1);
}
strncpy(mapname,c,12);mapname[12]=0;
c=get_text_field(trg,"CESTA_MAPY");
if (c==NULL)
{
cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku CESTA_MAPY\n\r", targetadv);
exit(1);
}
sprintf(szBuff,"%s%s",c,mapname);
if (tracemap(szBuff))
{
cprintf("Nemohu precist mapu %s\n\r",szBuff);
exit(1);
}
c=get_text_field(trg,"CESTA_POZICE");
if (c==NULL)
{
cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku CESTA_POZICE\n\r", targetadv);
exit(1);
}
c=get_text_field(src,"CESTA_POZICE");
if (c==NULL)
{
cprintf("Vstupni dobrodruzstvi %s musi obsahovat polozku CESTA_POZICE\n\r", sourceadv);
exit(1);
}
c=scan_saves("Vyber pozici:",c,1);
if (c==NULL) exit(0);
load_specific_file(c,"_GAME.TMP",&datablast,&datablastsize);
if (datablast==NULL)
{
cprintf("Soubor %s: Pristup odmitnut - pozice je pozkozena!\n\r",c);
exit(1);
}
unpack_save(datablast);
do
{
do
if (assign_players()) exit(1);
while (!build_players());
zpet:
c=get_text_field(trg,"CESTA_POZICE");
c=scan_saves("Ulozit na pozici:",c,0);
}
while (c==NULL);
if (access(c,F_OK)==0)
{
cprintf("Prejes si prepsat existujici pozici? (A/cokoliv):");
if (toupper(getche())!='A') goto zpet;
}
save_savegame(c);
}
static char help1[]=
"Tento program prenasi ulozene pozice mezi jednotlivymi dobrodruzstvimi.\n\r"
"Jelikoz ulozena pozice je znacne zavisla na mapach a definicich, je mozne\n\r"
"timto programem prenaset pouze charakteristiky postav. Navic se mohou \n\r"
"objevit nejake komplikace vznikle s nemoznosti predvidat komplexnost obou\n\r"
"dobrodruzstvi.\n\r\n"
"Program ma dva zapisy parametru:\n\r"
"================================\n\r\n"
"TRANSAV <cil.adv>\n\r\n"
" Prenasi puvodni pozici ze hry Brany Skeldalu do noveho dobrodruzstvi\n\r\n"
"TRANSAV <zdroj.adv> <cil.adv>\n\r\n"
" Prenasi pozici mezi dvema dobrodruzstvi\n\r\n";
static char help2[]=
"Jak uz bylo receno, prenasi se pouze charakteristiky postav. Neprenasi se\n\r"
"predmety a runy. Nova pozice se jmenuje TRANSAV, pak si ji prejmenujte. \n\r"
"Ihned po nahrati prenesene pozice okamzite tuto pozici opet ulozte, aby SKELDAL\n\r"
"doplnil chybejici informace vztahujici se k novemu dobrodruzstvi. \n\r"
"V pokrocilejsich castech hry mohou tyto chybejici informace zpusobovat nejake\n\r"
"komplikace...\n\r\n"
"Prenasec pozic pro Vas napsal Ondrej Novak, programator hry Brany Skeldalu.\n\r\n"
"PS: Deaktivujte ovladace ceske klavesnice!!!\n\r";
void main(int argc,char **argv)
{
char szbuff[20];
if (argc!=2 && argc!=3)
{
cputs(help1);
cputs("--- klavesu ---");getche();putch('\r');
cputs(help2);
return;
}
memset(relarr,0,sizeof(relarr));
if (argc==2)
begin_program("SKELDAL.INI",argv[1]);
else
begin_program(argv[1],argv[2]);
}

13
game/version.h Normal file
View file

@ -0,0 +1,13 @@
#define VERSION_MAJOR 1
#define VERSION_MAJORT "1"
#define VERSION_MINOR 3
#define VERSION_MINORT "3"
#define VERSION_BUILD 17
#define VERSION_BUILDT "17"
#define VERSION VERSION_MAJORT"."VERSION_MINORT" Build "VERSION_BUILDT
#define VERSIONNUM VERSION_MAJOR*1000000+VERSION_MINOR*10000+VERSION_BUILD
#define VERSIONWINSTR VERSION_MAJORT","VERSION_MINORT","0","VERSION_BUILDT
#define VERSIONWINRES(x) x VERSION_MAJOR, VERSION_MINOR, 0, VERSION_BUILD

459
game/wizard.c Normal file
View file

@ -0,0 +1,459 @@
#include <skeldal_win.h>
#include <bios.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <mem.h>
#include <types.h>
#include <bgraph.h>
#include <event.h>
#include <devices.h>
#include <bmouse.h>
#include <memman.h>
#include <zvuk.h>
#include <strlite.h>
#include <gui.h>
#include <basicobj.h>
#include <time.h>
#include <stdarg.h>
#include "globals.h"
void kamenik2windows(const char *src, int size, char *trg);
#define BREAK
static void wzprintf(const char *text,...)
{
va_list lst;
va_start(lst, text);
vprintf(text, lst);
}
static void wzputs(const char *text)
{
wzprintf(text);
wzprintf("\r\n");
}
static void wzcls()
{
}
static int wzscanf(const char *prompt, const char *format,...)
{
va_list lst;
va_start(lst, format);
return vscanf(format, lst);
}
char *side_flags[]=
{
"AUTOMAP",
"!PLR",
"!MONST",
"!THING",
"!SOUND",
"ALARM",
"PASS",
"TRANSPARENT",
"P_ANIM",
"P_VIS",
"P_PING",
"P_FORW",
"S_ANIM",
"S_VIS",
"S_PING",
"S_FORW",
"LEFT_A",
"RIGHT_A",
"ALT_SIDES",
"SPEC",
"COPY",
"SEND",
"APLY2ND",
"AUTOANIM",
"",
"",
"",
"",
"",
"SECRET",
"TRUESEE",
"INVIS"
};
char *obl_flags[]=
{
"RECESS",
"UP_SIDE",
"DOWN_SIDE",
"ITPUSH"
};
char *mc_flags[]=
{
"MAPPED",
"FLY_OBJECT",
"PLAYER",
"DEAD_PLAYER",
"SPECTXTR",
"SAFEPLACE",
"UNUSED",
"MARKED!",
"SHADED",
"STAIRS",
"DOWN",
"!AUTOMAP",
"!SUMMON"
};
void mman_scan(int )
{
}
void show_flags(int number,char **flags,char nums)
{
int i=0;
while (nums--)
{
if (number & 1) wzprintf("%s ",flags[i]);
i++;
number>>=1;
}
}
void spell_group_invis()
{
int i;
char ok=1;
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].sektor==viewsector && !(postavy[i].stare_vls[VLS_KOUZLA] & SPL_INVIS))
{
postavy[i].stare_vls[VLS_KOUZLA]|=SPL_INVIS;
ok=0;
}
if (ok)
for(i=0;i<POCET_POSTAV;i++) if (postavy[i].sektor==viewsector)
{
postavy[i].stare_vls[VLS_KOUZLA]&=~SPL_INVIS;
}
for(i=0;i<POCET_POSTAV;i++) prepocitat_postavu(postavy+i);
build_all_players();
}
static void advence_player(int player,int level,char auto_advance)
{
THUMAN *h;
float mh,mv;
if (level<2) return;
h=postavy+player;
mh=(float)human_selected->jidlo/MAX_HLAD(human_selected);
mv=(float)human_selected->voda/MAX_ZIZEN(human_selected);
human_selected=h;
h->exp=level_map[level-2];
check_player_new_level(h);
if (auto_advance)
{
int vlssuma=h->vlastnosti[VLS_SILA]+
h->vlastnosti[VLS_OBRAT]+
h->vlastnosti[VLS_POHYB]+
h->vlastnosti[VLS_SMAGIE];
int b,i;
for(i=0;i<4;i++)
{
b=h->vlastnosti[i]*h->bonus/vlssuma;
h->bonus-=b;vlssuma-=h->vlastnosti[i];
while (b--) advance_vls(i);
}
prepocitat_postavu(human_selected);
}
human_selected->jidlo=(int)(mh*MAX_HLAD(human_selected));
human_selected->voda=(int)(mv*MAX_ZIZEN(human_selected));
wzprintf("%s ziskal%s uroven cislo %d\r\n",h->jmeno,h->female?"a":"",level);
}
extern char folow_mode;
extern char folow_mob;
void macro_drop_item();
static char take_money()
{
int i;
if (!wzscanf("Kolik: (0 - zrusit):","%d",&i)) return 0;
money+=i;
if (i)
{
SEND_LOG("(WIZARD) Take Money %d, total %d",i,money);
}
return (i!=0);
}
#define ALL "ALL"
static char purge_map()
{
char buffer[200];
char *c;
STOP();
/* struct find_t rc;
int rs;
concat(c,pathtable[SR_TEMP],"*.TMP");
rs=_dos_findfirst(c,_A_NORMAL,&rc);
while (rs==0)
{
if (rc.name[0]!='~') wzputs(rc.name);
rs=_dos_findnext(&rc);
}
_dos_findclose(&rc);*/
wzprintf("\r\n Zadej jmeno tempu (all - vse):");gets(buffer);
if (buffer[0]==0) return 0;
strupr(buffer);
concat(c,pathtable[SR_TEMP],buffer);
if (strcmp(buffer,ALL) && access(c,0))
{
wzputs("Soubor nenalezen!");
return 0;
}
SEND_LOG("(WIZARD) Purge Map: '%s'",buffer,0);
if (!strcmp(buffer,ALL)) purge_temps(0);
else remove(c);
return 1;
}
static char heal_meditate(void)
{
int a,b,i;
THUMAN *p;
if (!wzscanf("Obnovit postavu c: (0 - vsechny, -1 - zrusit):","%d",&b)) return 0;
if (b==-1) return 0;
if (b) a=b-1;else a=0,b=POCET_POSTAV;
p=postavy+a;
for(i=a;i<b;i++,p++) if (p->used && p->lives)
{
p->lives=p->vlastnosti[VLS_MAXHIT];
p->mana=p->vlastnosti[VLS_MAXMANA];
p->kondice=p->vlastnosti[VLS_KONDIC];
p->jidlo=MAX_HLAD(p);
p->voda=MAX_ZIZEN(p);
SEND_LOG("(WIZARD) Restoring character '%s'",p->jmeno,0);
bott_draw(1);
}
return 1;
}
static char raise_death(void)
{
int b;
THUMAN *p;
char *c,*d;
if (!wzscanf("Obzivit postavu c: (0 a -1 - zrusit):","%d",&b)) return 0;
b--;
if (b<0) return 0;
p=postavy+b;
p->lives=p->vlastnosti[VLS_MAXHIT];
p->mana=p->vlastnosti[VLS_MAXMANA];
p->kondice=p->vlastnosti[VLS_KONDIC];
c="(WIZARD) '%s' has been returned to game by gods power!";d=strchr(c,'\'');
wzprintf(d,p->jmeno);putchar('\r\n');
bott_draw(1);
return 0;
}
/*
static char raise_killed_monster(HWND hDlg)
{
HWND listdlg=PrepareListWindow(hDlg);
HWND list=GetDlgItem(listdlg,IDC_LIST);
char buff[256];
int i;
int res;
for (i=0;i<MAX_MOBS;i++) if (~mobs[i].vlajky & MOB_LIVE && mobs[i].cislo_vzoru!=0)
{
int p;
_snprintf(buff,sizeof(buff),"%4d. %s (sector: %d home %d)",i,mobs[i].name,mobs[i].sector,mobs[i].home_pos);
kamenik2windows(buff,strlen(buff),buff);
p=ListBox_AddString(list,buff);
ListBox_SetItemData(list,p,i);
}
res=PumpDialogMessages(listdlg);
while (res==IDOK)
{
int cnt;
for (i=0,cnt=ListBox_GetCount(list);i<cnt;i++) if (ListBox_GetSel(list,i))
{
int idx=ListBox_GetItemData(list,i);
mobs[idx].vlajky|=MOB_LIVE;
mobs[idx].lives=mobs[idx].vlastnosti[VLS_MAXHIT];
wzprintf("%s znovu povstal(a)\r\n",mobs[idx].name);
SEND_LOG("(WIZARD) '%s' has been raised",mobs[idx].name,0);
}
res=PumpDialogMessages(listdlg);
}
CloseListWindow(listdlg);
return 1;
}
*/
void unaffect();
extern char immortality;
extern char nohassle;
static char set_immortality()
{
immortality=!immortality;
SEND_LOG("(WIZARD) Immortality has been turned %s.",immortality?"on":"off",0);
wzprintf("Nesmrtelnost byla %s.\r\n",immortality?"zapnuta":"vypnuta");
return 0;
}
static char set_nohassle()
{
nohassle=!nohassle;
SEND_LOG("(WIZARD) Nohassle has been turned %s.",nohassle?"on":"off",0);
wzprintf("Nevycititelnost byla %s.\r\n",nohassle?"zapnuta":"vypnuta");
return 0;
}
static char advance_weapon()
{
int p,i;
char buff[128];
THUMAN *h;
if (!wzscanf("Cislo postavy: (0 = Zpet)","%d",&p)) return 0;
if (p==0) return 0;
h=postavy+p-1;
do
{
int bonus, value;
for(i=0;i<TPW_MAX;i++) wzprintf("%d. %-15s: %2d Exp %5d\r\n",i+1,texty[91+i],h->bonus_zbrani[i],h->weapon_expy[i]);
if (!wzscanf("<Zbran> <Hodnota>","%[^\n]",buff)) return 0;
if (buff[0]==0) return 0;
if (sscanf(buff,"%d %d",&bonus,&value)!=2) wzputs("Huh?!");
else
{
bonus--;
if (bonus<0 || bonus>=TPW_MAX) wzputs("Spatna zbran");
else
if (value<0 || value>=10) wzputs("Spatna hodnota");
else
h->bonus_zbrani[bonus]=value;
}
}
while(1);
}
static reload_mobs()
{
extern char reset_mobiles;
reset_mobiles=1;
strncpy(loadlevel.name,level_fname,12);
loadlevel.start_pos=viewsector;
loadlevel.name[12]=0;
loadlevel.dir=viewdir;
send_message(E_CLOSE_MAP);
}
static char display_game_status(void)
{
short *v;
THUMAN *p;
TSTENA *s;
TSECTOR *ss;
register i,cn,astr;
wzcls();
SEND_LOG("(WIZARD) Starting wizard window at Sect %d Side %d",viewsector,viewdir);
wzprintf("Sektor: %5d Smer: %d Skupina %d \r\n",viewsector,viewdir,cur_group);
for(i=0,p=postavy;i<POCET_POSTAV;i++,p++)
if (p->used)
wzprintf("%d.%-14s (%d) Sek:%5d Smr:%d HPReg:%d MPReg:%d VPReg:%d %04X%s\r\n",i+1,p->jmeno,p->groupnum,p->sektor,p->direction,p->vlastnosti[VLS_HPREG],
p->vlastnosti[VLS_MPREG], p->vlastnosti[VLS_VPREG], p->vlastnosti[VLS_KOUZLA], p->lives?"":"(smrt)");
else
wzprintf("%d. (nepouzito)\r\n",i);
wzputs("");
wzprintf("Predmet(y) v mysi: ");
v=picked_item;
if (v==NULL) wzprintf("<zadne>");else while(*v) wzprintf("%d ",abs(*v++)-1);
wzputs("\r\n");
for(i=0,cn=0,astr=0;i<MAX_MOBS;i++)
{
if (mobs[i].vlajky & MOB_LIVE) cn++;
if (mobs[i].vlajky & MOB_MOBILE) astr++;
}
wzprintf("Celkem potvor ve hre: %5d (+%d) astral mobiles\r\n"
"Celkem predmetu ve hre:%5d\r\n"
" .. z toho klonu: %5d\r\n",cn-astr,astr,item_count,item_count-it_count_orgn);
wzputs("");
ss=map_sectors+viewsector;
s=map_sides+viewsector*4+viewdir;
wzprintf("Sector: (%d) Podlaha %d Strop %d Cil akce %d Smer akce %d Akce %d\r\n",
ss->sector_type, ss->floor,ss->ceil,ss->sector_tag,ss->side_tag,ss->action);
wzprintf(" Vychody: Sev %d Vych %d Jih %d Z<>p %d\r\n",ss->step_next[0],ss->step_next[1],ss->step_next[2],ss->step_next[3]);
wzprintf(" Vlajky: %02X %02X ",ss->flags,map_coord[viewsector].flags);show_flags(map_coord[viewsector].flags,mc_flags,12);
wzputs("\r\n");
wzprintf("Stena: Prim %d Sec %d Obl %d Anim_prim %d/%d Anim_sec %d/%d\r\n",
s->prim,s->sec,s->oblouk & 0xf,s->prim_anim>>4,s->prim_anim & 0xf,s->sec_anim>>4,s->sec_anim & 0xf);
wzprintf(" Cil akce %d Smer akce %d Akce %d\r\n",s->action,s->sector_tag,s->side_tag & 0x3);
wzprintf(" Multiakce: %s\r\n",macros[viewsector*4+viewdir]==NULL?"<zadna>":"Existuje");
wzprintf(" Vlajky: %04X %02X %02X ",s->flags,s->oblouk>>4,s->side_tag>>2);
wzputs("");
show_flags(s->flags,side_flags,32);
show_flags(s->oblouk>>4,obl_flags,4);
return 0;
}
void wizard_kbd(EVENT_MSG *msg,void **usr)
{
char c;
if (map_with_password && debug_enabled!=266859) return;
usr;
if (msg->msg==E_KEYBOARD)
{
c=(*(int *)msg->data)>>8;
msg->msg=-1;
switch (c)
{
case 'C':
case '<':show_debug=!show_debug;break;
case '=':show_lives=!show_lives;break;
case '>':if (mman_action!=NULL) mman_action=NULL;else mman_action=mman_scan;break;
case '@':set_immortality();set_nohassle();break;
case 'A':bott_draw_fletna();break;
case 'B':wire_global_map();break;
case '?':cur_group=10;break;/*folow_mode=!folow_mode;
if (folow_mode) folow_mob=mob_map[map_sectors[viewsector].step_next[viewdir]]-1;
else for(c=0;c<POCET_POSTAV;c++) if (postavy[c].groupnum==cur_group) viewsector=postavy[c].sektor;
if (folow_mob==255) folow_mode=0;
*/
break;
default:
msg->msg=E_KEYBOARD;break;
}
}
return;
}
void install_wizard()
{
send_message(E_ADD,E_KEYBOARD,wizard_kbd);
}

1
game/wizard.h Normal file
View file

@ -0,0 +1 @@
void install_wizard();