#include #include #include #include #include #include #include #include #include #include #include #include #include #include "engine1.h" #include #include "globals.h" #include "version.h" #include #define ZIVOTY_S 60 #define ZIVOTY_E 62 #define KONDIC_S 64 #define KONDIC_E 66 #define MANA_S 68 #define MANA_E 70 #define BARS_S 13 #define BARS_E 85 #define BARS_YS (BARS_E-BARS_S) #define PIC_X 3 #define PIC_Y 12 #define MANA_COLOR RGB555(15,0,31) #define SEL_COLOR RGB555(31,31,31) #define ZASAHB_X 8 #define ZASAHB_Y 20 #define ZASAHT_X 30 #define ZASAHT_Y 38 #define SHOW {swap_buffs();showview(0,0,0,0);swap_buffs();getche();`} #define HUMAN_ADJUST 97 unsigned int barvy_skupin[POCET_POSTAV+1]= { RGB555(8,8,8)|FONT_TSHADOW, RGB555(31,28,00)|FONT_TSHADOW, RGB555(00,23,06)|FONT_TSHADOW, RGB555(31,11,13)|FONT_TSHADOW, RGB555(22,16,31)|FONT_TSHADOW, RGB555(28,13,31)|FONT_TSHADOW, RGB555(00,29,26)|FONT_TSHADOW }; char reverse_draw=0; int viewsector=1,viewdir=1; char norefresh=0,map_state=0; int cur_sector; //sektor aktualni pozice int back_color; char global_anim_counter=0; char one_buffer=0; char set_halucination=0; int hal_sector; int hal_dir; char see_monster=0; char ghost_walls = 0; char lodka=0; char lodka_battle_draw = 0; //jedncka pokud se zobrazuje programovani (pro lodku) int bgr_distance=0; //vzdalenost pozadi od pohledu int bgr_handle=0; int spell_handle=0,spell_phase,spell_xicht; THE_TIMER *bott_timer=NULL; char *bott_text=NULL; char bott_display; char true_seeing=0; char obl_anim_counter=0; char obl_max_anim=1; char anim_mirror=0; static char showrune=0; static int showruneitem=0; static char lodka_loaded=0; uint8_t dirs[10]; word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; char log_combat=0; SPECTXT_ARR spectxtr; static char spt_ptr=0; void add_spectxtr(word sector,word fhandle,word count,word repeat,integer xpos) { SPECTXTR *sp=spectxtr+spt_ptr; sp->sector=sector; sp->handle=fhandle; sp->count=count; sp->pos=0; sp->repeat=repeat; sp->xpos=xpos; if (count) if ((++spt_ptr)>=MAX_SPECTXTRS) spt_ptr=0; map_coord[sector].flags |= MC_SPECTXTR; } void calc_spectxtrs(void) { int i; for(i=0;ipos>=sp->count) { sp->pos=0;if (sp->repeat>0) sp->repeat--; } } } static void draw_spectxtrs(word sector,int celx,int cely) { int i; char a=1; if (!(map_coord[sector].flags & MC_SPECTXTR)) return; for(i=0;ihandle+sp->pos),celx,cely,sp->xpos); a=0; } if (a) map_coord[sector].flags &= ~MC_SPECTXTR; } void init_spectxtrs(void) { memset(spectxtr,0,sizeof(spectxtr)); } void ukaz_kompas(char mode) { static int phase=0,speed=0; int direct; if (mode==1) { direct=(3-viewdir); direct=phase-direct*10; if (direct<-20) direct+=40; if (direct>=20) direct-=40; speed=((direct>0)-(direct<0)); } if (mode!=255) put_image(ablock(H_KOMPAS),GetScreenAdr()+476,phase*16,102,16); if (mode==1) { phase-=speed;if (phase>39) phase=0; if(phase<0) phase=39; } if (mode==255) showview(476,0,102,15); } void show_money() { char c[20]; set_font(H_FONT7,RGB555(28,28,21)); sprintf(c,"%d",money); set_aligned_position(460,13,2,2,c); outtext(c); } void anim_sipky(int h,int mode) { int32_t scr_linelen2 = GetScreenPitch(); static int phase=0; static char drw=0; static short handle=0; if (mode==1) { handle=h; phase=6; return; } if (phase && mode!=255) { int i; if (phase>4) i=8-phase; else i=phase; i=(i-2)*110; if (i>=0) put_8bit_clipped(ablock(handle),GetScreenAdr()+378*scr_linelen2+498,i,142,102); else put_picture(498,378,ablock(H_SIPKY_END)); drw=1; if (mode!=-1) { phase--; } } if (mode==255 && drw) { showview(498,378,142,102); drw=0; } } void chveni(int i) { static int pos=0; static int count=0; if (!count && !i) return; if (i) count=i; count--; if (!count) pos=0; setvesa_displaystart(8*pos,0); pos=!pos; } void objekty_mimo(THE_TIMER *t) { if (cur_mode == MD_END_GAME) return; schovej_mysku(); ukaz_kompas(1); anim_sipky(0,0); ukaz_mysku(); ukaz_kompas(255); anim_sipky(0,255); chveni(0); } void draw_blood(char mode,int mob_dostal,int mob_dostal_pocet) { static int phase=100; static int block; static int dostal; char s[20]; word *adr; int i; int32_t scr_linelen2 = GetScreenPitch(); mob_dostal_pocet; if (mode) { if (phase<3) dostal+=mob_dostal_pocet;else dostal=mob_dostal_pocet; phase=0; block=mob_dostal; return; } if (phase>7) return; adr=520+378*scr_linelen2+GetScreenAdr(); i=105*phase; phase++; put_8bit_clipped(ablock(H_KREVMIN+block-1),adr,i,120,102); set_font(H_FTINY,RGB555(31,31,31)); int2ascii(dostal,s,10); set_aligned_position(60+520,51+378,1,1,s);outtext(s); } word *bott_clear(void) { word *bott_scr; int32_t scr_linelen2 = GetScreenPitch(); int32_t sz; bott_scr=(word *)getmem(sz = scr_linelen2*104*2); memset(bott_scr,0,sz); return bott_scr; } static void draw_small_icone(int num,int x,int y) { const word *pic; pic=ablock(H_POSTUP); num*=13;x+=num; put_textured_bar(pic,x,y,13,13,num,0); } static const void *bott_fletna_normal(const void *pp, int32_t *s) { word *bott_scr; int i,x; bott_scr=bott_clear(); RedirectScreen(bott_scr); put_picture(0,0,ablock(H_FLETNA_BAR)); set_font(H_FTINY,RGB555(31,31,0)); set_aligned_position(103,52,1,1,texty[174]);outtext(texty[174]); for(i=0,x=156;i<12;i++,x+=22) { set_aligned_position(x,32,1,1,texty[180+i]);outtext(texty[180+i]); } void *out=GetScreenAdr(); *s=GetScreenSizeBytes(); RestoreScreen(); return out; } static const void *bott_draw_normal(const void *pp, int32_t *s) { int i,j;int x,xs=0,y; word *bott_scr; THUMAN *p; int32_t scr_linelen2 = GetScreenPitch(); bott_scr=bott_clear(); RedirectScreen(bott_scr); if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); else put_picture(0,0,ablock(H_DESK)); memcpy(&xs,ablock(H_OKNO),2); x=54; for(j=0;jused) if (cur_mode!=MD_PRESUN || i==moving_player) { char c[]=" ";int z,lv,llv; put_picture(x,0,ablock(H_OKNO));lv=p->lives;llv=p->vlastnosti[VLS_MAXHIT]; if (lv || p->used & 0x80) { z=3-((lv-1)*4/llv);if (lv==llv) z=0; z*=75; if (p->xicht>=0)put_8bit_clipped(ablock(H_XICHTY+i),bott_scr+PIC_X+x+PIC_Y*scr_linelen2,z,54,75); if (p->bonus) draw_small_icone(0,PIC_X+x+1,PIC_Y+1); if (p->spell) draw_small_icone(1,PIC_X+x+1,PIC_Y+1); if (!p->voda) draw_small_icone(2,PIC_X+x+1,PIC_Y+1); if (!p->jidlo) draw_small_icone(3,PIC_X+x+1,PIC_Y+1); } else put_picture(PIC_X+x,PIC_Y,ablock(H_LEBKA)); curcolor=0; y=BARS_YS-p->lives*BARS_YS/p->vlastnosti[VLS_MAXHIT]; if (y) bar32(x+ZIVOTY_S,BARS_S,x+ZIVOTY_E,BARS_S+y); y=BARS_YS-p->kondice*BARS_YS/p->vlastnosti[VLS_KONDIC]; if (y) bar32(x+KONDIC_S,BARS_S,x+KONDIC_E,BARS_S+y); if (p->vlastnosti[VLS_MAXMANA]) y=BARS_YS-p->mana*BARS_YS/p->vlastnosti[VLS_MAXMANA];else y=BARS_YS; if (y<0) y=0; if (y) bar32(x+MANA_S,BARS_S,x+MANA_E,BARS_S+y); if (p->sektor!=viewsector || p->inmaphash != current_map_hash) trans_bar25(x,0,74,102); set_font(H_FLITT,p->groupnum==cur_group && !battle?SEL_COLOR:barvy_skupin[p->groupnum]); set_aligned_position(x+36,92,1,0,p->jmeno);outtext(p->jmeno); c[0]=p->inmaphash !=current_map_hash?'-':p->groupnum+48;set_aligned_position(x+5,86,0,2,c);outtext(c); if (cur_mode==MD_INBATTLE && p->inmaphash == current_map_hash) { char s[20]; signed char dir; set_font(H_FBOLD,RGB555(31,31,0)); sprintf(s,texty[40],p->actions); set_aligned_position(x+56,86,2,2,s);outtext(s); dir=viewdir-p->direction; if (abs(dir)==2) c[0]=2; else if (dir==-1 || dir==3) c[0]=1; else if (dir==-3 || dir==1) c[0]=3; if (dir) { set_font(H_FSYMB,p->groupnum==cur_group && !battle?SEL_COLOR:barvy_skupin[p->groupnum]); c[0]+=4;set_aligned_position(x+10,86,0,2,c);outtext(c); } } if (i==select_player) rectangle(x+3,12,x+3+54,12+75,SEL_COLOR); if (p->dostal) { char s[20]; put_picture(x+ZASAHB_X,ZASAHB_Y,ablock(H_PZASAH)); set_font(H_FBOLD,RGB555(31,31,0)); sprintf(s,"%d",p->dostal); set_aligned_position(x+ZASAHT_X,ZASAHT_Y,1,1,s);outtext(s); } x+=xs; } if (cur_mode==MD_PRESUN || cur_mode==MD_UTEK) { char s[40]; set_font(H_FBOLD,RGB555(31,31,16)); position(150,20);outtext(texty[cur_mode==MD_PRESUN?42:44]); sprintf(s,texty[60+cislovka(postavy[moving_player].actions)],postavy[moving_player].actions); position(150,35);outtext(s); position(150,50);outtext(texty[63]); } /* if (mob_dostal) { word *w; char s[40]; w=ablock(H_MZASAH1+mob_dostal-1); put_picture(580-(w[0]>>1),55-(w[1]>>1),w); itoa(mob_dostal_pocet,s,10); set_font(H_FLITT5,0xffff); set_aligned_position(580,55,1,1,s); outtext(s); } */ void *out = GetScreenAdr(); *s=GetScreenSizeBytes(); RestoreScreen(); return out; } void bott_timer_draw(struct the_timer *q) { q; bott_display=BOTT_NORMAL; zneplatnit_block(H_BOTTBAR); free(bott_text); bott_text=NULL; bott_timer=NULL; } const void *bott_disp_text_proc(const void *pp, int32_t *ss) { char *p,*text; int y=20; int xx,yy; text=alloca(strlen(bott_text)+2); set_font(H_FBOLD,NOSHADOW(0)); zalamovani(bott_text,text,390,&xx,&yy); RedirectScreen(bott_clear()); if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); else put_picture(0,0,ablock(H_DESK)); create_frame(70,20,400,50,1); p=text; do { position(70,y); outtext(p); y+=text_height(p); p=strchr(p,0)+1; } while (p[0]); void *out = GetScreenAdr(); *ss=GetScreenSizeBytes(); RestoreScreen(); return out; } void bott_disp_text(const char *text) { if (text==0) text="Chybi popisek!!"; zneplatnit_block(H_BOTTBAR); if (bott_timer==NULL) bott_timer=add_to_timer(TM_BOTT_MESSAGE,MSG_DELAY,1,bott_timer_draw); else bott_timer->counter=MSG_DELAY; bott_display=BOTT_TEXT; if (bott_text!=NULL) free(bott_text); bott_text=(char *)getmem(strlen(text)+1); strcpy(bott_text,text); } /* static void MaskPutPicture(int x, int y, char mask, word color, char blend, const void *pic) { short *info=(short *)pic; char *data=(char *)(info+3+256); int32_t scr_linelen2 = GetScreenPitch(); word *pos=GetScreenAdr()+x+y*scr_linelen2; if (blend) color=color & 0x7BDE; for (y=0;y>1; } else { pos[x]=color; } } } */ static void *extractByMask(const short *image, const short *mask_data, int mask) { short left = 0x7FFF; short right = 0; short top = 0x7FFF; short bottom =0; short xs = image[0]; short mxs = mask_data[0]; short mys = mask_data[1]; const char *mdata = (const char *)mask_data+sizeof(short)*3+512; for (short y = 0; y < mys; ++y) { for (short x = 0; x < mxs; ++x) { if (mdata[y*mxs+x] == mask) { if (left > x) left = x; if (right < x) right = x; if (bottom < y) bottom = y; if (top > y) top = y; } } } if (left > right || top > bottom) return NULL; short nxs = right-left+1; short nys = bottom-top+1; short *newimg = getmem(nxs*nys*2+3+256); newimg[0] = nxs; newimg[1] = nys; newimg[2] = image[2]; memcpy(newimg+2, image+2, sizeof(short)*266); char *imgdata = (char *)(newimg+3+256); const char *srcimgdata = (char *)(image+3+256); for (short y = top; y <= bottom; ++y) { for (short x = left; x <= right; ++x) { char color = 0; if (mdata[y*mxs+x] == mask) { color = srcimgdata[y*xs+x]; } else { color = 0; } imgdata[(y - top)*nxs+(x - left)] = color; } } return newimg; } const void *bott_draw_rune(const void *pp, int32_t *ss) { int sel_zivel=showrune/10; int sel_rune=showrune%10; // int maskrune=runes[sel_zivel]; // int i; char buff[300]; int spell=(sel_zivel*7+sel_rune)*3; RedirectScreen(bott_clear()); if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); else put_picture(0,0,ablock(H_DESK)); short *rn = extractByMask(ablock(H_RUNEBAR1+sel_zivel), ablock(H_RUNEMASK), sel_rune+6); /* put_picture(520,0,); for (i=0;i<7;i++) if (!(maskrune & (1<counter=MSG_DELAY; } void bott_text_forever() { delete_from_timer(TM_BOTT_MESSAGE); bott_timer=NULL; } const void *bott_draw_proc(const void *p, int32_t *s, int h) { switch (bott_display) { case BOTT_NORMAL:return bott_draw_normal(p,s);break; case BOTT_TEXT:return bott_disp_text_proc(p,s);break; case BOTT_FLETNA:return bott_fletna_normal(p,s);break; case BOTT_RUNA:return bott_draw_rune(p,s);break; default: return p; } } void bott_draw(char priority) { if (priority) { if (bott_display!=BOTT_NORMAL) { delete_from_timer(TM_BOTT_MESSAGE); bott_timer=NULL; bott_display=BOTT_NORMAL; } } if (bott_display==BOTT_NORMAL) zneplatnit_block(H_BOTTBAR); } void bott_draw_fletna() { bott_display=BOTT_FLETNA; zneplatnit_block(H_BOTTBAR); } void draw_spell(int handle,int phase,int xicht) { int x,y,i; const word *w; int32_t scr_linelen2 = GetScreenPitch(); if (bott_display!=BOTT_NORMAL) bott_draw(1); for(i=0;i=10) { spell_handle=0; spell_xicht=0; } } put_picture(0,0,ablock(1)); ukaz_kompas(0); show_money(); anim_sipky(0,-1); draw_fx(); draw_console_window(); int32_t scr_linelen2 = GetScreenPitch(); memset(GetScreenAdr()+(SCREEN_OFFLINE-1)*scr_linelen2,0,1280); memset(GetScreenAdr()+(SCREEN_OFFLINE+360)*scr_linelen2,0,1280); } void display_spell_in_icone(int handle,int xicht) { spell_phase=0; spell_handle=handle; spell_xicht|=xicht; } int fc_num(int anim_counter,int sector,char floor) { int mode; TSECTOR *s; TMAP_EDIT_INFO *m; int basic; s=&map_sectors[sector]; m=&map_coord[cur_sector]; if (floor) { basic=s->floor; mode=s->flags & 0xf; } else { basic=s->ceil; mode=s->flags>>4; } if (mode & 0x8) return basic+(anim_counter % ((mode & 0x7)+1)); switch (mode) { case 0: return basic; case 1: return basic+((m->x+m->y+dirs[1]) & 0x1); case 2: return basic+(dirs[1] & 0x1); case 3: return basic+(dirs[1] & 0x1)*2+((m->x+m->y+(dirs[1]>>1)) & 0x1); case 4: return basic+dirs[1]; case 5: return basic+dirs[1]*2+((m->x+m->y+(dirs[1]>>1)) & 0x1); } return basic; } int enter_tab[VIEW3D_Z+1][VIEW3D_X*2+1]= {{4,3,3,3,3,3,3,3,4}, {4,3,3,2,3,2,3,3,4}, {4,3,3,2,4,2,3,3,4}, {4,3,1,1,4,1,1,3,4}, {4,1,1,1,4,1,1,1,4}}; void crt_minimap_itr(int sector,int smer,int itrx,int itry, int automap) { static int sector_temp; static int32_t sideflags; static short enter=0; short savee; if (itrx==VIEW3D_X && itry==0) enter=0; if (itrx<0 || itrx>VIEW3D_X*2 || itry>VIEW3D_Z) return; if (minimap[itry][itrx]) return; minimap[itry][itrx]=sector; if (!set_halucination) map_coord[sector].flags|=automap & (itrx<=VIEW3D_X+1 && itrx>=VIEW3D_X-1) ; if (itrx<=VIEW3D_X) { sector_temp=map_sectors[sector].step_next[dirs[0]]; sideflags=map_sides[sector*4+dirs[0]].flags; if (sector_temp && sideflags & 0x80 && enter>=0) { savee=enter; enter=-enter_tab[itry][itrx]; crt_minimap_itr(sector_temp,smer,itrx-1,itry,automap &(sideflags & 1)); enter=savee; } } if (itrx>=VIEW3D_X) { sector_temp=map_sectors[sector].step_next[dirs[2]]; sideflags=map_sides[sector*4+dirs[2]].flags; if (sector_temp && sideflags & 0x80 && enter<=0) { savee=enter; enter=enter_tab[itry][itrx]; crt_minimap_itr(sector_temp,smer,itrx+1,itry,automap &(sideflags & 1)); enter=savee; } } sector_temp=map_sectors[sector].step_next[dirs[1]]; sideflags=map_sides[sector*4+dirs[1]].flags; if (sector_temp && sideflags & 0x80) { savee=enter; enter-=(enter>0)-(enter<0); crt_minimap_itr(sector_temp,smer,itrx,itry+1,automap &(sideflags & 1)); enter=savee; } } void create_minimap(int sector, int smer) { memset(minimap,0,sizeof(minimap)); dirs[1]=smer; dirs[0]=(smer-1) & 3; dirs[2]=(smer+1) & 3; crt_minimap_itr(sector,smer,VIEW3D_X,0,1); } static const void *check_autofade(const void *image, char ceil, int dark) { const char *data=image; if (data[5]==0x80) { word *xy=(word *)image; if (mglob.map_autofadefc==1) { word *imgdata=xy+3; int br=back_color>>10; int bg=(back_color>>5) & 0x1F; int bb=back_color & 0x1F; int y; if (dark) br=bg=bb=0; for(y=0;y>10; int g=(*imgdata>>5) & 0x1F; int b=*imgdata & 0x1F; r=(int)(r+factor*(br-r)); g=(int)(g+factor*(bg-g)); b=(int)(b+factor*(bb-b)); *imgdata=(r<<10)|(g<<5)|b; imgdata++; } } } xy[2]=xy[2] & 0xFF; } return image; } #define draw_floor(s,celx,cely,dark) if (s->floor) draw_floor_ceil(celx,cely,0,check_autofade(ablock(num_ofsets[FLOOR_NUM]+fc_num(global_anim_counter,sector,1)),0,dark)); #define draw_ceil(s,celx,cely,dark) if (s->ceil) draw_floor_ceil(celx,cely,1,check_autofade(ablock(num_ofsets[CEIL_NUM]+fc_num(global_anim_counter,sector,0)),1,dark)); #define GET_OBLOUK(p) ((p->oblouk & 0xf)+(p->prim_anim>>4)) static int left_shiftup,right_shiftup; int draw_basic_floor(int celx,int cely,int sector) { TSECTOR *s; int dark; s=&map_sectors[sector]; dark=map_coord[sector].flags & MC_SHADING; draw_floor(s,celx,cely,dark); draw_ceil(s,celx,cely,dark); return 0; } static int calc_item_shiftup(TITEM *it) { const short *s; char *c; int y,x,xs,ys,t; t=0; s=ablock(it->vzhled+face_arr[0]); xs=s[0];ys=s[1];c=((char *)s)+PIC_FADE_PAL_SIZE; c+=xs*ys-1;y=0; while (yitems[i])!=0;i++) { TITEM *it=&glob_items[j-1]; if (it->shiftup==0xff) it->shiftup=calc_item_shiftup(it); draw_item2(celx,cely,v->xpos,v->ypos-it->shiftup,ablock(it->vzhled+face_arr[0]),i); } } static int draw_basic_sector(int celx, int cely, int sector) { TSTENA *w, *q; int obl; int tmask = true_seeing?SD_TRUESEE:0; w = &map_sides[sector * 4]; q = &w[dirs[1]]; obl = GET_OBLOUK(q); if (cely < VIEW3D_Z) { if (q->flags & SD_LEFT_ARC && obl) show_cel2(celx, cely, ablock(num_ofsets[OBL_NUM] + obl), 0, 0, 1, ghost_walls ); if (q->flags & SD_RIGHT_ARC && q->oblouk & 0x0f) show_cel2(celx, cely, ablock(num_ofsets[OBL2_NUM] + obl), 0, 0, 2, ghost_walls); if (q->flags & (SD_PRIM_VIS|tmask) && q->prim) show_cel2(celx, cely, ablock( num_ofsets[MAIN_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, 1 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & (SD_SEC_VIS|tmask) && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (cely != 0) { show_cel2(celx, cely - 1, ablock( num_ofsets[MAIN_NUM] + q->sec + (q->sec_anim >> 4)), 0, 0, 1, ghost_walls | (q->flags & tmask)); } } else { show_cel2(celx, cely, ablock( num_ofsets[MAIN_NUM] + q->sec + (q->sec_anim >> 4)), q->xsec << 1, q->ysec << 1, 0, ghost_walls | (q->flags & tmask)); } } if (q->oblouk & 0x10) draw_vyklenek(celx, cely, sector, dirs[1]); } if (celx <= 0) { q = &w[dirs[0]]; if (left_shiftup) show_cel(celx, cely, ablock(num_ofsets[LEFT_NUM] + left_shiftup), 0, 0, 2, ghost_walls), left_shiftup = 0; if (q->flags & (SD_PRIM_VIS|tmask) && q->prim ) show_cel(-celx, cely, ablock( num_ofsets[LEFT_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, 2 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & (SD_SEC_VIS|tmask) && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (celx != 0) { left_shiftup = q->sec + (q->sec_anim >> 4); } else { left_shiftup = 0; } } else if (q->flags & SD_SPEC) { show_cel(celx, cely, ablock( num_ofsets[LEFT_NUM] + q->sec + (q->sec_anim >> 4)), 0, 0, 2, ghost_walls | (q->flags & tmask)); } else { show_cel(celx, cely, ablock( num_ofsets[LEFT_NUM] + q->sec + (q->sec_anim >> 4)), q->xsec << 1, q->ysec << 1, 0, ghost_walls | (q->flags & tmask)); } } } if (celx >= 0) { q = &w[dirs[2]]; if (right_shiftup) show_cel(celx, cely, ablock(num_ofsets[RIGHT_NUM] + right_shiftup), 0, 0, 3, ghost_walls), right_shiftup = 0; if (q->flags & (SD_PRIM_VIS|tmask) && q->prim ) show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->prim + (q->prim_anim >> 4)), 0, 0, 3 + (q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (q->flags & (SD_SEC_VIS|tmask) && q->sec) { if (q->side_tag & SD_SHIFTUP) { if (celx != 0) right_shiftup = q->sec + (q->sec_anim >> 4); else right_shiftup = 0; } else if (q->flags & SD_SPEC) { show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->sec + (q->sec_anim >> 4)), 0, 0, 3, ghost_walls | (q->flags & tmask)); } else { show_cel(celx, cely, ablock( num_ofsets[RIGHT_NUM] + q->sec + (q->sec_anim >> 4)), 500 - (q->xsec << 1), q->ysec << 1, 1, ghost_walls | (q->flags & tmask)); } } } return 0; } static int draw_lodku(int celx,int cely) { if (cely==0) return 1; show_cel2(celx,cely-1,ablock(H_LODKA0+(global_anim_counter & 7)),250,80,0,0); return 0; } int p_place_table[4][5]= { {0,1,4,2,3}, {1,2,4,3,0}, {2,3,4,0,1}, {3,0,4,1,2} }; int p_positions_x[5]={-32,32,32,-32,0}; int p_positions_y[5]={32,32,-32,-32,0}; void draw_players(int sector,int dir,int celx,int cely) { if (map_coord[sector].flags & MC_DPLAYER) { int i; THUMAN *p; char freep[5]= {0,0,0,0,0}; int j,d,pp=0,f=0; memset(freep,0,sizeof(freep)); for(i=0,pp=0;isektor==sector && p->inmaphash == current_map_hash && ((!p->lives && p->groupnum==0) || p->sektor!=viewsector)) { pp++; d=(p->direction-dir)&0x3; if (p->lives) for(j=0;j<5 && freep[p_place_table[d][j]];j++); else for(j=4;j>=0 && freep[p_place_table[d][j]];j--); if (j==5 || j==-1) break; freep[f=p_place_table[d][j]]=i+1; } } if (pp == 1 && freep[f] & 1) { pp = (f + 1) & 3; freep[pp] = freep[f]; freep[f] = 0; } for (i = 0; i < 5; i++) if ((j = freep[d = p_place_table[0][i]]) != 0) { if (postavy[j - 1].lives) { set_font(H_FLITT5, barvy_skupin[postavy[j - 1].groupnum]); draw_player(ablock(H_POSTAVY + j - 1), celx, cely, p_positions_x[d], p_positions_y[d], HUMAN_ADJUST, postavy[j - 1].jmeno); } else draw_player(ablock(H_KOSTRA), celx, cely, p_positions_x[d], p_positions_y[d] - 32, HUMAN_ADJUST, NULL); } } } int draw_sloup_sector(int celx,int cely,int sector) { TSTENA *w,*q; int obl; int tmask = true_seeing?SD_TRUESEE:0; w=&map_sides[sector*4]; q=&w[dirs[1]]; obl=GET_OBLOUK(q); if (q->flags & SD_LEFT_ARC && q->oblouk) show_cel2(celx,cely,ablock(num_ofsets[OBL_NUM]+obl),0,0,1, ghost_walls); if (q->flags & SD_RIGHT_ARC && q->oblouk) show_cel2(celx,cely,ablock(num_ofsets[OBL2_NUM]+obl),0,0,2, ghost_walls); if (q->flags & (SD_PRIM_VIS|tmask) && q->prim ) show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->prim+(q->prim_anim>>4)),0,0,1+(q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); if (celx<=0) { q=&w[dirs[0]]; if (q->flags & (SD_PRIM_VIS|tmask) && q->prim) show_cel(-celx,cely,ablock(num_ofsets[LEFT_NUM]+q->prim+(q->prim_anim>>4)),0,0,2+(q->oblouk & SD_POSITION), ghost_walls| (q->flags & tmask)); } if (celx>=0) { q=&w[dirs[2]]; if (q->flags & (SD_PRIM_VIS|tmask) && q->prim) show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->prim+(q->prim_anim>>4)),0,0,3+(q->oblouk & SD_POSITION), ghost_walls | (q->flags & tmask)); } q=&w[dirs[1]]; if (q->flags & (SD_SEC_VIS|tmask) && q->sec && cely!=0) { if (q->flags & SD_SPEC) show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),0,0,2, ghost_walls| (q->flags & tmask)); else show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),(q->xsec<<1)+celx*(viewport_geometry[0][0][cely].x-viewport_geometry[0][0][cely-1].x)/2,q->ysec<<1,0, ghost_walls| (q->flags & tmask)); } return 0; } void swap_truesee(int ss) { int i; for(i=0;i<4;i++) { TSTENA *s=map_sides+i+ss; if (s->flags & SD_TRUESEE) s->flags^=SD_PRIM_VIS | SD_SEC_VIS | SD_AUTOMAP; } } void draw_sector(int celx,int cely,int s) { // int ss; //ss=s<<2; // if (true_seeing) swap_truesee(ss); switch (map_sectors[s].sector_type) { case S_SSMRT: case S_SLOUP: case S_TELEPORT: draw_sloup_sector(celx,cely,s); draw_placed_items_normal(celx,cely,s,viewdir); break; case S_LODKA: draw_basic_sector(celx,cely,s); if (cely==0) draw_placed_items_normal(celx,cely,s,viewdir); draw_lodku(celx,cely); break; default: draw_basic_sector(celx,cely,s); draw_placed_items_normal(celx,cely,s,viewdir); break; } // if (true_seeing) swap_truesee(ss); } void back_clear(int celx,int color) { int x1,y1,x2,y2,xc; y1=viewport_geometry[0][0][VIEW3D_Z].y+MIDDLE_Y+SCREEN_OFFLINE; y2=viewport_geometry[0][1][VIEW3D_Z].y+MIDDLE_Y+SCREEN_OFFLINE; x2=viewport_geometry[0][1][VIEW3D_Z].x+MIDDLE_X; x1=-viewport_geometry[0][1][VIEW3D_Z].x+MIDDLE_X; xc=(x2-x1+2)*celx; x1=x1+xc-1; x2=x2+xc; if (x1<0) x1=0; if (x2>640) x2=640; if (x1sektor == viewsector && !(p->vlastnosti[VLS_KOUZLA] & SPL_BLIND)) return 0; } return 1; } extern char folow_mode; static void zobraz_lodku(const word *lodka, word *screen, int size) { int32_t scr_linelen2 = GetScreenPitch(); lodka+=3; int x; while (size) { for (x=0;x<640 && size;x++) { if (*lodka!=0x8000) screen[x]=*lodka; lodka++; size--; } screen+=scr_linelen2; } } /* static __inline void zobraz_lodku(word *data,word *scr,int _size) { __asm { mov ecx,_size mov esi,data mov edi,scr add esi,6 lp1:lodsw or ax,ax jz skp mov [edi],ax skp: add edi,2h dec ecx jnz lp1 } } */ /* static void trace_for_bgr(int dir) { int s,i; static int olddist=0; static int olddir=0; TSTENA *ss; int32_t scr_linelen2 = GetScreenPitch(); bgr_handle=0; bgr_distance=-1; for(i=0,s=0;iflags & SD_PRIM_VIS && !ss->prim) { bgr_distance=i-1; bgr_handle=num_ofsets[BACK_NUM]+dir; break; } } if (olddist!=bgr_distance || olddir!=dir) { if (bgr_distance==-1) { word *w=GetScreenAdr();int i=scr_linelen2*480; do {if (*w>=NOSHADOW(0)) *w=back_color;w++;} while(--i); } zneplatnit_block(H_BGR_BUFF); } olddist=bgr_distance; olddir=dir; } */ void render_scene(int sector, int smer) { int i,j,s; see_monster=0; destroy_fly_map(); build_fly_map(); if (set_blind() && cur_mode!=MD_END_GAME && !folow_mode) { clear_buff(NULL,0,360); return; } if (set_halucination) { sector=hal_sector; smer=hal_dir; } cur_sector=sector; create_minimap(sector,smer); // trace_for_bgr(smer); i=VIEW3D_Z-1; s=minimap[i][VIEW3D_X]; if (s && !map_sectors[s].ceil) clear_buff(ablock_copy(H_BGR_BUFF),back_color,360); else clear_buff(ablock_copy(H_BGR_BUFF),back_color,80); for(i=-VIEW3D_X+1;i=0;i--) { word *p; p=minimap[i]; left_shiftup=0;right_shiftup=0; for(j=VIEW3D_X-1;j>=0;j--) { int s2; if ((s=p[VIEW3D_X+j])!=0) { if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; draw_basic_floor(j,i,s); if (map_sides[(s<<2)+smer].flags & SD_TRANSPARENT) { s2=map_sectors[s].step_next[smer]; draw_mob(s2,smer,j,i,1); } draw_sector(j,i,s); } if (j && (s=p[VIEW3D_X-j])) { if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; draw_basic_floor(-j,i,s); if (map_sides[(s<<2)+smer].flags & SD_TRANSPARENT) { s2=map_sectors[s].step_next[smer]; draw_mob(s2,smer,-j,i,1); } draw_sector(-j,i,s); } } for(j=VIEW3D_X-1;j>=0;j--) { if ((s=p[VIEW3D_X+j])!=0) { if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; draw_players(s,viewdir,j,i); draw_mob(s,viewdir,j,i,0); draw_fly_items(j,i,s,viewdir); draw_spectxtrs(s,j,i); } if (j && (s=p[VIEW3D_X-j])) { if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; draw_players(s,viewdir,-j,i); draw_mob(s,viewdir,-j,i,0); draw_fly_items(-j,i,s,viewdir); draw_spectxtrs(s,-j,i); } } } calc_spectxtrs(); if (lodka) { if (!lodka_battle_draw && !running_anm) { if (!lodka_loaded) { game_display_load_sprite(H_LODKA, (const unsigned short *)ablock(H_LODKA)); lodka_loaded = 1; } game_display_place_sprite(H_LODKA, 0, SCREEN_OFFLINE+301); } else { game_display_hide_sprite(H_LODKA); zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ); lodka_battle_draw = 0; } } } void death_screen() { trans_bar(0, 0, 640, 480, 0); int xs; int ys; int y = 160; const char *t = texty[65]; DECL_VLA(char, buff, strlen(t)+4); set_font(H_FBOLD, RGB555_ALPHA(31,31,31)); zalamovani(t,buff, 440, &xs, &ys); t = buff; while (*t) { set_aligned_position(320, y, 1, 1, t); outtext(t); y+=2*text_height(t); t = t+strlen(t)+1; } } void redraw_scene() { if (norefresh) return; if (one_buffer) RedirectScreenBufferSecond(); render_scene(viewsector,viewdir); if (running_anm) klicovani_anm(GetBuffer2nd()+SCREEN_OFFSET,anim_render_buffer,anim_mirror); update_mysky(); schovej_mysku(); if (one_buffer) RestoreScreen(); OutBuffer2nd(); if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); other_draw(); if (cur_mode == MD_END_GAME) { death_screen(); } ukaz_mysku(); global_anim_counter++; send_message(E_KOUZLO_ANM); } void refresh_scene(THE_TIMER *t) { redraw_scene(); if (!norefresh) { showview(0,0,0,0); calc_game(); if (autoopenaction==1) {go_book(0,0,0,0,0);autoopenaction=0;} } } typedef struct fx_play { int x,y,phase; struct fx_play *next; }FX_PLAY; static FX_PLAY *fx_data=NULL; void draw_fx() { const word *c; FX_PLAY *fx; FX_PLAY **last; int32_t scr_linelen2 = GetScreenPitch(); if (fx_data==NULL) return; fx=fx_data;last=&fx_data; c=ablock(H_FX); while (fx!=NULL) { put_8bit_clipped(c,GetScreenAdr()+fx->x+fx->y*scr_linelen2,fx->phase*16,c[0],16); if (++fx->phase>14) { *last=NULL; free(fx); return; } last=&(fx->next); fx=*last; } } void play_fx(int x,int y) { FX_PLAY *fx; fx=New(FX_PLAY); fx->next=fx_data; fx->x=x; fx->y=y; fx->phase=0; fx_data=fx; } void play_fx_at(int where) { static word polex[]={313,290,362,336,165}; static word poley[]={1,1,1,1,1,1}; play_fx(polex[where],poley[where]); } void display_ver(int x,int y,int ax,int ay) { char *ver="Br�ny Skeldalu version "VERSION" (C)1998"; set_font(H_FTINY,RGB555(31,31,31));set_aligned_position(x,y,ax,ay,ver); outtext(ver);showview(0,0,0,0); } void hide_boat() { game_display_hide_sprite(H_LODKA); }