support for new SEQ format and idle animations

This commit is contained in:
Ondřej Novák 2025-07-10 15:07:54 +02:00
parent 3463d8e720
commit 2ce5f77825
9 changed files with 284 additions and 93 deletions

View file

@ -76,6 +76,165 @@ typedef struct tmobsavedata
static TMOBSAVEDATA **mobsavedata=0; static TMOBSAVEDATA **mobsavedata=0;
#define MOBFACECOUNT 10
#define MOB_FACE_WALK_FRONT 0
#define MOB_FACE_WALK_LEFT 1
#define MOB_FACE_WALK_BACK 2
#define MOB_FACE_WALK_RIGHT 3
#define MOB_FACE_ATTACK 4
#define MOB_FACE_DAMAGED 5
#define MOB_FACE_IDLE_FRONT 6
#define MOB_FACE_IDLE_LEFT 7
#define MOB_FACE_IDLE_BACK 8
#define MOB_FACE_IDLE_RIGHT 9
struct tmobanimseqitem {
int16_t file;
int16_t offsetx;
int16_t unused;
};
typedef struct tmobanimseq {
uint8_t seq_len[MOBFACECOUNT]; ///<count of frames for each sequence
struct tmobanimseqitem *seq[MOBFACECOUNT];
const char *graphics; ///<pointer to graphics
int32_t graphics_size;
char big; ///<1 if monster is big
uint8_t hitpos; ///hit frame for attack
} TMOBANIMSEQ;
static const void *load_SEQ_file(const void *src, int *sc, int handle) {
const THANDLE_DATA *hdata = get_handle(handle);
const TMOB *mob = (const TMOB *)(hdata->context);
if (strcmp((const char *)src, "<BLOCK>") == 0) {
uint32_t phases_size= 0;
uint32_t graphics_size = 0;
const void *sect = NULL;
uint32_t sect_size = 0;
int type = 0;
//phase 1
TMPFILE_RD *f = temp_storage_from_binary(src, *sc, NULL, NULL);
while ((load_section_mem(f, &sect, &type, &sect_size)) && type) {
switch(type) {
case 1: phases_size = sect_size;break;
case 2: graphics_size = sect_size;break;
default: break;
}
}
temp_storage_close_rd(f);
size_t total_size = sizeof(TMOBANIMSEQ)+graphics_size+phases_size;
//phase 2
TMOBANIMSEQ *newseq = getmem(total_size);
f = temp_storage_from_binary(src, *sc, NULL, NULL);
char *gr = (char *)(newseq+1);
char *iter = gr + graphics_size;
char *iend = iter + phases_size;
while ((load_section_mem(f, &sect, &type, &sect_size)) && type) {
switch(type) {
case 1: memcpy(iter, sect, sect_size);break;
case 2: memcpy(gr, sect, sect_size);break;
case 3: {
const char *c = (const char *)sect;
newseq->big = c[0] != 0;
newseq->hitpos = (uint8_t)(c[1]);
break;
}
default: break;
}
}
temp_storage_close_rd(f);
newseq->graphics = gr;
newseq->graphics_size = graphics_size;
while (iter < iend) {
uint8_t row = iter[0] % MOBFACECOUNT;
uint8_t count = iter[1];
iter+=2;
newseq->seq[row] = (struct tmobanimseqitem *)(iter);
newseq->seq_len[row] = count;
iter+=6*count;
}
*sc = total_size;
CHECK_MEMORY(newseq, total_size);
return newseq;
} else {
char fulname[14];
char znaky[]=MOB_ZNAKY;
int i,j;
const char *seq = (const char *)src;
char allnames[96*13];
char *allnames_iter=allnames;
int findex = 0;
struct tmobanimseqitem seq_items[96];
struct tmobanimseqitem *seq_iter = seq_items;
TMOBANIMSEQ sseq;
strcpy(fulname,mob->mobs_name);
strcat(fulname,"??.PCX");
for(i=0;i<6;i++) {
int k = i;
int l = i == 3?1:i;
if (!mob->_deprecated_anim_counts[i]) k = 0;
sseq.seq[i] = seq_iter;
sseq.seq_len[i] = mob->_deprecated_anim_counts[k];
for(j=0;j<16;j++) {
fulname[6]=znaky[k];
if (j<=mob->_deprecated_anim_counts[k]) {
fulname[7]=*seq++;
strcpy(allnames_iter, fulname);
allnames_iter+=strlen(fulname)+1;
seq_iter->file = findex;
seq_iter->offsetx = mob->_deprecated_adjusting[l * 16 + j];
seq_iter->unused = 0;
++seq_iter;
++findex;
}
if (*seq=='\r') {
char buff[256];
closemode();
sprintf(buff,"Soubor sekvence %s obsahuje chybne udaje nebo je sekvence je moc kratka\n", fulname);
display_error(buff);
exit(0);
}
}
seq=strchr(seq,'\n')+1;
}
sseq.big = (mob->stay_strategy & MOB_BIG) != 0;
sseq.hitpos = mob->_deprecated_hit_pos;
size_t strtable_len = allnames_iter - allnames;
size_t seq_len = seq_iter - seq_items;
size_t total_size = sizeof(sseq) + (seq_len)*sizeof(struct tmobanimseqitem) + (strtable_len)*sizeof(char);
TMOBANIMSEQ *newseq = (TMOBANIMSEQ *)getmem(total_size);
memcpy(newseq, &sseq, sizeof (TMOBANIMSEQ));
char *gr = (char *)(newseq+1);
newseq->graphics = gr;
struct tmobanimseqitem *seq_iter2 = (struct tmobanimseqitem *)(gr+strtable_len);
memcpy(seq_iter2, seq_items, seq_len * sizeof(struct tmobanimseqitem));
memcpy(gr, allnames, strtable_len);
for (int i = 0; i < 6; ++i) {
newseq->seq[i] = sseq.seq[i] + (seq_iter2 - seq_items) + 1;
}
for (int i = 0; i < 4; ++i) {
newseq->seq[i+6] = sseq.seq[i] + (seq_iter2 - seq_items);
newseq->seq_len[i+6] = 1;
}
newseq->graphics_size = strtable_len;
*sc = total_size;
CHECK_MEMORY(newseq, total_size);
return newseq;
}
}
static void register_mob_path(int mob,word *path) //registruje cestu pro potvoru static void register_mob_path(int mob,word *path) //registruje cestu pro potvoru
{ {
mob_paths[mob]=path; mob_paths[mob]=path;
@ -206,7 +365,7 @@ void init_mobs()
send_message(E_DONE,E_KOUZLO_KOLO,mob_reload); send_message(E_DONE,E_KOUZLO_KOLO,mob_reload);
send_message(E_ADD,E_KOUZLO_KOLO,mob_reload); send_message(E_ADD,E_KOUZLO_KOLO,mob_reload);
} }
/*
static void register_mob_graphics(int num,char *name_part,const char *anims,const char *seq) static void register_mob_graphics(int num,char *name_part,const char *anims,const char *seq)
{ {
char fulname[14]; char fulname[14];
@ -253,7 +412,7 @@ static void register_mob_graphics(int num,char *name_part,const char *anims,cons
} }
} }
*/
static void register_mob_sounds(int hlptr,word *sounds) static void register_mob_sounds(int hlptr,word *sounds)
@ -344,12 +503,12 @@ static void mob_sound_event(TMOB *m, int event) {
&& ~m->vlastnosti[VLS_KOUZLA] & SPL_STONED) { && ~m->vlastnosti[VLS_KOUZLA] & SPL_STONED) {
if (event == MBS_WALK) { if (event == MBS_WALK) {
play_sample_at_sector( play_sample_at_sector(
m->cislo_vzoru + 16 * 6 + event + monster_block, viewsector, m->cislo_vzoru + 1 + event + monster_block, viewsector,
m->sector, m - mobs + 256, m->sector, m - mobs + 256,
(m->vlajky & MOB_SAMPLE_LOOP) != 0); (m->vlajky & MOB_SAMPLE_LOOP) != 0);
} else { } else {
play_sample_at_sector( play_sample_at_sector(
m->cislo_vzoru + 16 * 6 + event + monster_block, viewsector, m->cislo_vzoru + 1 + event + monster_block, viewsector,
m->sector, 0, 0); m->sector, 0, 0);
} }
} }
@ -398,17 +557,21 @@ void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int
else else
{ {
char s[20]; char s[20];
int h = *grptr;
*grptr = h + 1;
sprintf(s,"%s.SEQ",mobs[i].mobs_name); sprintf(s,"%s.SEQ",mobs[i].mobs_name);
def_handle(grptr[0]++,s,NULL,SR_ENEMIES); def_handle(h,s,load_SEQ_file,SR_ENEMIES)->context = mobs+i;
mobs[i].cislo_vzoru=*grptr-monster_block;
register_mob_graphics(*grptr,mobs[i].mobs_name,mobs[i].anim_counts,ablock(grptr[0]-1));
grptr[0]+=6*16;
register_mob_sounds(*grptr,mobs[i].sounds); register_mob_sounds(*grptr,mobs[i].sounds);
grptr[0]+=4; grptr[0]+=4;
sprintf(s,"%s.COL",mobs[i].mobs_name); sprintf(s,"%s.COL",mobs[i].mobs_name);
def_handle(grptr[0],s,col_load,SR_ENEMIES); def_handle(grptr[0],s,col_load,SR_ENEMIES);
grptr[0]++; grptr[0]++;
mobs[i].cislo_vzoru=h-monster_block;
const TMOBANIMSEQ *seq = (const TMOBANIMSEQ *)ablock(h);
prepare_graphics(grptr, seq->graphics,seq->graphics_size , pcx_8bit_nopal, SR_ENEMIES);
} }
} }
else else
@ -416,7 +579,7 @@ void load_enemies(const short *data,int size,int *grptr,const TMOB *template,int
mobs[i].cislo_vzoru=-1; mobs[i].cislo_vzoru=-1;
mobs[i].vlajky&=~MOB_LIVE; mobs[i].vlajky&=~MOB_LIVE;
} }
for(j=0;j<6;j++) if (mobs[i].anim_counts[j]==0) mobs[i].anim_counts[j]=mobs[i].anim_counts[0]; // for(j=0;j<6;j++) if (mobs[i].anim_counts[j]==0) mobs[i].anim_counts[j]=mobs[i].anim_counts[0];
data+=2; data+=2;
} }
for(;i<MAX_MOBS;i++) mobs[i].vlajky&=~MOB_LIVE; for(;i<MAX_MOBS;i++) mobs[i].vlajky&=~MOB_LIVE;
@ -890,7 +1053,10 @@ void rozhodni_o_smeru(TMOB *p)
} }
} }
end1: end1:
if (p->headx!=p->locx || p->heady!=p->locy) mob_sound_event(p,MBS_WALK); if (p->headx!=p->locx || p->heady!=p->locy) {
mob_sound_event(p,MBS_WALK);
p->anim_phase = MOB_WALKING;
}
} }
void krok_moba(TMOB *p) void krok_moba(TMOB *p)
@ -904,8 +1070,8 @@ void krok_moba(TMOB *p)
typedef struct enemy_face_tag { typedef struct enemy_face_tag {
int pos; struct tmobanimseqitem face;
int face; int action;
int mirror; int mirror;
} TENEMY_FACE; } TENEMY_FACE;
@ -913,8 +1079,9 @@ typedef struct enemy_face_tag {
TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir) TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir)
{ {
TENEMY_FACE ret; TENEMY_FACE ret;
int view;int pos; const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block);
int pos;
int xs,ys; int xs,ys;
ret.mirror = 0; ret.mirror = 0;
@ -922,9 +1089,9 @@ TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir)
else if (action==MOB_TO_HIT) pos=5; else if (action==MOB_TO_HIT) pos=5;
else if (action==MOB_DEATH) else if (action==MOB_DEATH)
{ {
ret.pos = 0; ret.face.file = 0;
ret.face = 0; ret.face.offsetx = 0;
return ret; return ret;
} }
else else
{ {
@ -937,7 +1104,7 @@ TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir)
if (xs) dirmob=(xs<0)?3:1; if (xs) dirmob=(xs<0)?3:1;
if (ys) dirmob=(ys<0)?0:2; if (ys) dirmob=(ys<0)?0:2;
pos=(2+dirmob-curdir)&0x3; pos=(2+dirmob-curdir)&0x3;
if (game_extras & EX_WALKDIAGONAL && !( p->stay_strategy & MOB_BIG)) if ((game_extras & EX_WALKDIAGONAL) && !( p->stay_strategy & MOB_BIG))
{ {
switch (curdir & 0x3) switch (curdir & 0x3)
{ {
@ -947,12 +1114,14 @@ TENEMY_FACE get_enemy_face(TMOB *p,int dirmob,int action,int curdir)
case 3: if (p->locy>p->heady) pos=3;else if (p->locy<p->heady) pos=1;break; case 3: if (p->locy>p->heady) pos=3;else if (p->locy<p->heady) pos=1;break;
} }
} }
if (pos==3) ret.mirror=1;
if (action == MOB_STANDING) {
pos+=6;
}
} }
if (pos==3) ret.mirror=1;
if (p->anim_counter==-1) view=pos*16; ret.face = seq->seq[pos][p->anim_counter % seq->seq_len[pos]];
else view=pos*16+(p->anim_counter % (MAX(p->anim_counts[pos],1)))+1; ret.action = pos;
ret.face = view;
ret.pos = pos;
return ret; return ret;
} }
@ -977,7 +1146,7 @@ static const void *mob_select_palette(TMOB *p)
{ {
const char *palet; const char *palet;
palet=ablock(p->cislo_vzoru+6*16+4+monster_block); palet=ablock(p->cislo_vzoru+5+monster_block);
return palet+(p->palette)*PIC_FADE_PAL_SIZE; return palet+(p->palette)*PIC_FADE_PAL_SIZE;
} }
@ -1037,18 +1206,12 @@ static void fill_drw_enemy_struct(TMOB *m, DRW_ENEMY *enm, char *buff, int curdi
const char *modes[] = {"NONE","CAST","FLEE","ATTACK"}; const char *modes[] = {"NONE","CAST","FLEE","ATTACK"};
const char *actions[] = { const char *actions[] = {
"STANDFWD","STANDLEFT","STANDBACK","STANDRIGHT","STANDLEFTMIRR", "WALKFWD","WALKLEFT","WALKBACK","WALKRIGHT","ATTACK",
"WALKFWD","WALKLEFT","WALKBACK","WALKRIGHT","WALKLEFTMIRR", "DAMAGED","IDLEFWD","IDLELEFT","IDLEBACK","IDLERIGHT","ERR"};
"ATTACK","ATTACKMIRR","INPAIN","INPAINMIRR","ERR"};
TENEMY_FACE fc = get_enemy_face(m,m->dir,m->anim_phase,curdir); TENEMY_FACE fc = get_enemy_face(m,m->dir,m->anim_phase,curdir);
int action = countof(actions)-1; int ca =countof(actions);
int stand = (fc.face & 0xF) == 0; int action = fc.action>=ca?ca-1:fc.action;
if (fc.pos < 4) {
action = (fc.mirror?4:fc.pos) + (stand?0:5);
} else {
action = ((fc.pos - 4)*2+(fc.mirror?1:0))+10;
}
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
if (m->stay_strategy & (1<<i)) { if (m->stay_strategy & (1<<i)) {
@ -1068,7 +1231,8 @@ static void fill_drw_enemy_struct(TMOB *m, DRW_ENEMY *enm, char *buff, int curdi
"intent: %s\n" "intent: %s\n"
"strategy: %s\n" "strategy: %s\n"
"flags: %s\n" "flags: %s\n"
"has_path: %s", "has_path: %s\n"
"locx,locy: %d,%d",
m->name, m->name,
actions[action], actions[action],
m->walk_data, m->walk_data,
@ -1078,7 +1242,8 @@ static void fill_drw_enemy_struct(TMOB *m, DRW_ENEMY *enm, char *buff, int curdi
modes[(uint8_t)m->mode], modes[(uint8_t)m->mode],
strategy_buff, strategy_buff,
flag_buff, flag_buff,
mob_paths[m - mobs]!=NULL?"YES":"NO" mob_paths[m - mobs]!=NULL?"YES":"NO",
m->locx,m->locy
); );
enm->more_info = buff; enm->more_info = buff;
} }
@ -1101,7 +1266,7 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup)
get_pos(p->locx-128,p->locy-128,&drw1.posx,&drw1.posy,curdir); get_pos(p->locx-128,p->locy-128,&drw1.posx,&drw1.posy,curdir);
view=get_enemy_face(p,p->dir,p->anim_phase,curdir); view=get_enemy_face(p,p->dir,p->anim_phase,curdir);
vw=p->cislo_vzoru+view.face+monster_block; vw=p->cislo_vzoru+view.face.file+monster_block+6;
if ((p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) { if ((p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) {
drw1.txtr = NULL; drw1.txtr = NULL;
vw = 0; vw = 0;
@ -1111,7 +1276,7 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup)
drw1.celx=celx; drw1.celx=celx;
drw1.cely=cely; drw1.cely=cely;
drw1.mirror=view.mirror; drw1.mirror=view.mirror;
drw1.adjust=p->adjusting[view.face]; drw1.adjust=view.face.offsetx;
drw1.shiftup=shiftup; drw1.shiftup=shiftup;
drw1.num=p->lives; drw1.num=p->lives;
drw1.palette=mob_select_palette(p); drw1.palette=mob_select_palette(p);
@ -1124,12 +1289,10 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup)
q=&mobs[p->next-MOB_START]; q=&mobs[p->next-MOB_START];
get_pos(q->locx-128,q->locy-128,&drw2.posx,&drw2.posy,curdir); get_pos(q->locx-128,q->locy-128,&drw2.posx,&drw2.posy,curdir);
view2=get_enemy_face(q,q->dir,q->anim_phase,curdir); view2=get_enemy_face(q,q->dir,q->anim_phase,curdir);
vw2=view2.face+q->cislo_vzoru+monster_block; vw2=q->cislo_vzoru+view2.face.file+monster_block+6;
drw2.shiftup=shiftup; drw2.shiftup=shiftup;
drw2.celx=celx; drw2.celx=celx;
drw2.cely=cely; drw2.cely=cely;
alock(vw);
alock(vw+6*16+5);
if ((q->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) { if ((q->vlastnosti[VLS_KOUZLA] & SPL_INVIS) && !true_seeing) {
drw2.txtr = NULL; drw2.txtr = NULL;
vw2 = 0; vw2 = 0;
@ -1137,9 +1300,7 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup)
drw2.txtr = ablock(vw2); drw2.txtr = ablock(vw2);
} }
drw2.mirror=view2.mirror; drw2.mirror=view2.mirror;
alock(vw2); drw2.adjust=view2.face.offsetx;
alock(vw2+6*16+5);
drw2.adjust=q->adjusting[view2.face];
drw2.num=q->lives; drw2.num=q->lives;
drw2.palette=mob_select_palette(q); drw2.palette=mob_select_palette(q);
drw2.stoned=(q->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0; drw2.stoned=(q->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0;
@ -1161,10 +1322,6 @@ void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup)
draw_enemy(&drw2); draw_enemy(&drw2);
draw_enemy(&drw1); draw_enemy(&drw1);
} }
aunlock(vw);
aunlock(vw2);
aunlock(vw+6*16+5);
aunlock(vw2+6*16+5);
} }
void draw_mob(int num,int curdir,int celx,int cely,char shiftup) void draw_mob(int num,int curdir,int celx,int cely,char shiftup)
@ -1658,10 +1815,9 @@ void mobs_live(int num)
display_error(buff); display_error(buff);
exit(1); exit(1);
} }
if (p->headx==p->locx && p->heady==p->locy && !p->anim_phase) if (p->headx==p->locx && p->heady==p->locy
&& (p->anim_phase == MOB_WALKING || p->anim_phase == MOB_STANDING))
{ {
//zde se bude rozhodovat co dal;
p->anim_counter=-1;
stop_track_free(num+256); stop_track_free(num+256);
if (battle) if (battle)
{ {
@ -1674,7 +1830,11 @@ void mobs_live(int num)
mobs_live(num); mobs_live(num);
return; return;
} }
if (p->mode==MBA_NONE) return; if (p->mode==MBA_NONE) {
p->anim_phase = MOB_STANDING;
p->anim_counter++;
return;
}
rozhodni_o_smeru(p); rozhodni_o_smeru(p);
return; return;
} }
@ -1689,10 +1849,11 @@ void mobs_live(int num)
if (p->walk_data>=224) if (p->walk_data>=224)
if (++p->walk_data<255) if (++p->walk_data<255)
{ {
p->anim_counter=-1; p->anim_phase = MOB_STANDING;
return; return;
} }
p->anim_counter=0; p->anim_counter=0;
p->anim_phase = MOB_WALKING;
rozhodni_o_smeru(p); rozhodni_o_smeru(p);
} }
else else
@ -1703,6 +1864,7 @@ void mobs_live(int num)
} }
else else
{ {
const TMOBANIMSEQ *seq = ablock(p->cislo_vzoru+monster_block);
if (p->anim_phase<MOB_ATTACK) if (p->anim_phase<MOB_ATTACK)
{ {
int spd; int spd;
@ -1726,6 +1888,7 @@ void mobs_live(int num)
else if (ys<-spd) ys=-spd; else if (ys<-spd) ys=-spd;
p->locx+=xs; p->locx+=xs;
p->locy+=ys; p->locy+=ys;
p->anim_phase = MOB_WALKING;
if (xs!=0 || ys!=0) neco_v_pohybu=1; if (xs!=0 || ys!=0) neco_v_pohybu=1;
if (p->locx>192 || p->locx<64 || p->locy>192 || p->locy<64) mob_check(num,p); if (p->locx>192 || p->locx<64 || p->locy>192 || p->locy<64) mob_check(num,p);
} }
@ -1733,20 +1896,19 @@ void mobs_live(int num)
if (p->anim_phase==MOB_ATTACK) if (p->anim_phase==MOB_ATTACK)
{ {
neco_v_pohybu=1; neco_v_pohybu=1;
if (p->anim_counter==p->hit_pos) mobs_hit(p); if (p->anim_counter==seq->hitpos) mobs_hit(p);
if (p->anim_counter>=p->anim_counts[4]) if (p->anim_counter>=seq->seq_len[4])
{ {
if (p->lives<1) p->anim_phase=MOB_TO_HIT;else p->anim_phase=0; if (p->lives<1) p->anim_phase=MOB_TO_HIT;else p->anim_phase=0;
p->anim_counter=-1; p->anim_phase = MOB_STANDING;
p->mode=MBA_NONE; p->mode=MBA_NONE;
} }
} }
else else
if (p->anim_phase==MOB_TO_HIT && p->anim_counter>=p->anim_counts[5]) if (p->anim_phase==MOB_TO_HIT && p->anim_counter>=seq->seq_len[5])
{ {
neco_v_pohybu=1; neco_v_pohybu=1;
p->anim_phase=0; p->anim_phase=MOB_STANDING;
p->anim_counter=-1;
mob_check_death(num,p); mob_check_death(num,p);
} }
else else
@ -1756,8 +1918,7 @@ void mobs_live(int num)
if (p->anim_counter==2) mob_check_death(num,p); if (p->anim_counter==2) mob_check_death(num,p);
else if (p->anim_counter>12) else if (p->anim_counter>12)
{ {
p->anim_phase=0; p->anim_phase=MOB_STANDING;
p->anim_counter=-1;
} }
} }
} }
@ -2370,17 +2531,24 @@ void load_enemy_to_map(int i, int sector, int dir, const TMOB *t) {
int h = find_handle(s, NULL); int h = find_handle(s, NULL);
int *grptr = &h; int *grptr = &h;
if (h == -1) { if (h == -1) {
grptr = &end_ptr; grptr = &end_ptr;
def_handle(grptr[0]++,s,NULL,SR_ENEMIES); h = *grptr;
mobs[i].cislo_vzoru=*grptr-monster_block; *grptr = h +1 ;
register_mob_graphics(*grptr,mobs[i].mobs_name,mobs[i].anim_counts,ablock(grptr[0]-1)); def_handle(h,s,load_SEQ_file,SR_ENEMIES)->context = mobs+i;
grptr[0]+=6*16;
register_mob_sounds(*grptr,mobs[i].sounds); register_mob_sounds(*grptr,mobs[i].sounds);
grptr[0]+=4; grptr[0]+=4;
sprintf(s,"%s.COL",mobs[i].mobs_name); sprintf(s,"%s.COL",mobs[i].mobs_name);
def_handle(grptr[0],s,col_load,SR_ENEMIES); def_handle(grptr[0],s,col_load,SR_ENEMIES);
grptr[0]++; grptr[0]++;
mobs[i].cislo_vzoru=h-monster_block;
const TMOBANIMSEQ *seq = (const TMOBANIMSEQ *)ablock(h);
prepare_graphics(grptr, seq->graphics,seq->graphics_size , pcx_8bit_nopal, SR_ENEMIES);
} else { } else {
mobs[i].cislo_vzoru=(h+1)-monster_block; mobs[i].cislo_vzoru=h-monster_block;
} }
} }

View file

@ -718,9 +718,10 @@ void enemy_draw_transp(const void *src,void *trg,const void *shade,int scale,int
//prepare xtable //prepare xtable
{ {
int *w = xtable; int *w = xtable;
int *we = xtable+sizeof(xtable)/sizeof(xtable[0]);
int ofs = 0; int ofs = 0;
int accu = 0; int accu = 0;
while (ofs < pcx) { while (ofs < pcx && w < we) {
*w++ = ofs; *w++ = ofs;
accu+=320; accu+=320;
while (accu >= scale) { while (accu >= scale) {

View file

@ -453,8 +453,10 @@ int load_map_state_ex(const char *level_fname, int mapsize, char partial)
{ {
for(i=0;i<MAX_MOBS;(mobs[i].vlajky &=~MOB_LIVE),i++); for(i=0;i<MAX_MOBS;(mobs[i].vlajky &=~MOB_LIVE),i++);
while (temp_storage_read(&i,sizeof(i),fsta) && i>=0 && i<=MAX_MOBS) { while (temp_storage_read(&i,sizeof(i),fsta) && i>=0 && i<=MAX_MOBS) {
int h = mobs[i].cislo_vzoru;
if (temp_storage_read(mobs+i,1*sizeof(TMOB),fsta)!=sizeof(TMOB)) goto err; if (temp_storage_read(mobs+i,1*sizeof(TMOB),fsta)!=sizeof(TMOB)) goto err;
mobs[i].vlajky2 = 0; mobs[i].vlajky2 = 0;
mobs[i].cislo_vzoru = h;
} }
} }

View file

@ -1481,13 +1481,14 @@ void unwire_main_functs(void);
//enemy //enemy
#define MOBS_INV 16 #define MOBS_INV 16
#define MOB_POSIT 0 #define MOB_POSIT 0
#define MOB_ATTACK 1 #define MOB_ATTACK 3
#define MOB_TOHIT 2 #define MOB_TOHIT 2
#define MAX_MOBS 255 #define MAX_MOBS 255
#define MOB_ATTACKING 0x2 #define MOB_STANDING 0x0
#define MOB_WALKING 0x1
#define MOB_TO_HIT 0x4 #define MOB_TO_HIT 0x4
#define MOB_DEATH 0x5 #define MOB_DEATH 0x5
#define MOB_START 1 #define MOB_START 1
@ -1517,11 +1518,11 @@ typedef struct tmob
{ {
char name[30]; //jmeno moba char name[30]; //jmeno moba
short casting; short casting;
short adjusting[6*16]; //volba stredu pro animace short _deprecated_adjusting[6*16]; //volba stredu pro animace
unsigned short sector,dir; //pozice unsigned short sector,dir; //pozice
char locx,locy; //presna pozice char locx,locy; //presna pozice
char headx,heady; //pozice kam mob miri char headx,heady; //pozice kam mob miri
short anim_counter; //citac animaci uint16_t anim_counter; //citac animaci
short vlastnosti[24]; //zakladni vlastnosti potvory short vlastnosti[24]; //zakladni vlastnosti potvory
short inv[MOBS_INV]; //batoh potvory short inv[MOBS_INV]; //batoh potvory
short lives; //pocet zivotu potvory short lives; //pocet zivotu potvory
@ -1533,7 +1534,7 @@ typedef struct tmob
char walk_data; //cislo potrebne pro pohyb moba v bludisti char walk_data; //cislo potrebne pro pohyb moba v bludisti
unsigned short bonus; //bonus za zabiti unsigned short bonus; //bonus za zabiti
char flee_num; //pravdepodobnost uteku char flee_num; //pravdepodobnost uteku
char anim_counts[6]; //pocet animacnich policek pro kazdy pohyb char _deprecated_anim_counts[6]; //pocet animacnich policek pro kazdy pohyb
char mobs_name[7]; //zaklad jmena souboru pro moba char mobs_name[7]; //zaklad jmena souboru pro moba
char vlajky2; //vlajky pro summon z konzoli (BIT0 - neukladat) char vlajky2; //vlajky pro summon z konzoli (BIT0 - neukladat)
uint8_t id; //mobile id (template index); uint8_t id; //mobile id (template index);
@ -1544,7 +1545,7 @@ typedef struct tmob
short home_pos; //domaci pozice short home_pos; //domaci pozice
short next; //Cislo dalsiho moba, ktery stoji na jeho pozici short next; //Cislo dalsiho moba, ktery stoji na jeho pozici
char actions; //pocet akci ktere muze potvora provest v kole char actions; //pocet akci ktere muze potvora provest v kole
char hit_pos; //animacni pozice, kdy potvora zasahne char _deprecated_hit_pos; //animacni pozice, kdy potvora zasahne
unsigned short sounds[4]; //zvuky z listu unsigned short sounds[4]; //zvuky z listu
signed char palette; // pocet pouzitelnych palet / cislo palety signed char palette; // pocet pouzitelnych palet / cislo palety
char mode; //akce potvory char mode; //akce potvory

View file

@ -1805,6 +1805,14 @@ void wire_select_power(void)
add_to_timer(TM_DELAIER,12,1,display_power_bar_tm); add_to_timer(TM_DELAIER,12,1,display_power_bar_tm);
} }
void animate_mobs(){
for (int i = 0; i < MAX_MOBS; ++i) {
if (mobs[i].vlajky & MOB_LIVE) {
++mobs[i].anim_counter;
}
}
}
void program_draw() void program_draw()
@ -1882,14 +1890,13 @@ void program_draw()
} }
ukaz_mysku(); ukaz_mysku();
} }
void souboje_redrawing(THE_TIMER *_) void souboje_redrawing(THE_TIMER *_)
{ {
if (neco_v_pohybu) calc_mobs(); if (neco_v_pohybu) calc_mobs(); else mob_animuj();
calc_animations(); calc_animations();
redraw_scene(); redraw_scene();
if (!norefresh) if (!norefresh)
@ -1902,6 +1909,7 @@ void souboje_redrawing(THE_TIMER *_)
} }
void souboje_stisknout(int d) void souboje_stisknout(int d)
{ {
int32_t scr_linelen2 = GetScreenPitch(); int32_t scr_linelen2 = GetScreenPitch();

View file

@ -9,6 +9,7 @@
#include "swaper.c" #include "swaper.c"
#include <fcntl.h> #include <fcntl.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -65,24 +66,26 @@ void (*swap_error)()=standard_swap_error;
void *getmem(int32_t size) void *getmem(int32_t size)
{ {
void *p,*res; void *p;
if (!size) return NULL; #ifndef NDEBUG
do p = malloc(size+4);
{ memset(p, 0xCD, size);
res=malloc(NON_GETMEM_RESERVED); memset((char *)p+size,0xEE,4);
if (res!=NULL)
{
p=(void *)malloc(size);
free(res);
}
else p=NULL;
if (p==NULL) mem_error(size);
}
while (p==NULL);
// SEND_LOG("(ALLOC) **** Alloc: %p size %d",p,*((int32_t *)p-1));
return p; return p;
} #else
return malloc(size);
#endif
}
#ifndef NDEBUG
void CHECK_MEMORY(const void *ptr, size_t sz) {
uint8_t *p = (uint8_t *)ptr + sz;
for (int i = 0; i < 4; i++) {
assert(p[i] == 0xEE);
}
}
#endif
void *load_file(const char *filename, size_t *sz) void *load_file(const char *filename, size_t *sz)

View file

@ -53,6 +53,7 @@ typedef struct thandle_data
unsigned short lockcount; unsigned short lockcount;
uint32_t counter; uint32_t counter;
uint32_t size; uint32_t size;
void *context;
}THANDLE_DATA; }THANDLE_DATA;
#define BK_MAJOR_HANDLES 256 // maximalni pocet skupin rukojeti #define BK_MAJOR_HANDLES 256 // maximalni pocet skupin rukojeti
@ -105,6 +106,13 @@ int32_t get_handle_size(int handle);
//void get_mem_info(MEMORYSTATUS *mem); //void get_mem_info(MEMORYSTATUS *mem);
void ablock_free(const void *ptr); void ablock_free(const void *ptr);
#ifdef NDEBUG
inline void CHECK_MEMORY(const void *x,size_t sz) {}
#else
void CHECK_MEMORY(const void *ptr, size_t sz);
#endif
//access file using memory mapping feature //access file using memory mapping feature
const void *afile_mapped(const char *filename,int group,int32_t *blocksize); const void *afile_mapped(const char *filename,int group,int32_t *blocksize);
//free file memory opened by afile_mapped //free file memory opened by afile_mapped

View file

@ -61,7 +61,7 @@ int main(int argc, char **argv) {
cfg.config_path = config_name.c_str(); cfg.config_path = config_name.c_str();
cfg.lang_path = lang.empty()?NULL:lang.c_str(); cfg.lang_path = lang.empty()?NULL:lang.c_str();
cfg.patch_file = patch.empty()?NULL:patch.c_str(); cfg.patch_file = patch.empty()?NULL:patch.c_str();
cfg.sse_hostport = sse_hostport.c_str(); cfg.sse_hostport = sse_hostport.empty()?NULL:sse_hostport.c_str();
try { try {
if (!gen_stringtable_path.empty()) { if (!gen_stringtable_path.empty()) {

View file

@ -71,7 +71,7 @@ int main(int argc, char **argv) {
cfg.config_path = config_name.c_str(); cfg.config_path = config_name.c_str();
cfg.lang_path = lang.empty()?NULL:lang.c_str(); cfg.lang_path = lang.empty()?NULL:lang.c_str();
cfg.patch_file = patch.empty()?NULL:patch.c_str(); cfg.patch_file = patch.empty()?NULL:patch.c_str();
cfg.sse_hostport = sse_hostport.c_str(); cfg.sse_hostport = sse_hostport.empty()?NULL:sse_hostport.c_str();
{ {
std::string msg = console.str(); std::string msg = console.str();