From: Andriy Shinkarchuck Date: Sun, 24 Jul 2011 22:00:16 +0000 (+0300) Subject: Editing source tree for configuring with CMake X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=a2115940e7643dcb1b87286f3d19fe95f7b79bd3;p=flatwaifu.git Editing source tree for configuring with CMake --- diff --git a/music/README_INSTALL b/music/README_INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..eb57650 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required( VERSION 2.6 ) + +set( BIN doom2d ) +project( ${BIN} ) + +set( SOURCE_ROOT ../src ) + +aux_source_directory( ${SOURCE_ROOT} SOURCES ) + +include_directories( "${SOURCE_ROOT}" + "/usr/include" + "/usr/include/SDL" ) + +set( INSTALL_PATH /usr/local/bin/ ) + +set( REQUIRED_LIBRARIES + SDL + SDL_mixer ) + +set( CMAKE_CXX_FLAGS "-O2 -Wall -MMD -MP -MF" ) + +add_executable( ${BIN} ${SOURCES} ) + +target_link_libraries( ${BIN} ${REQUIRED_LIBRARIES} ) + +install( TARGETS ${BIN} DESTINATION ${INSTALL_PATH} ) diff --git a/src/a8.c b/src/a8.c new file mode 100644 index 0000000..7d521d3 --- /dev/null +++ b/src/a8.c @@ -0,0 +1,318 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +//#include +#include +#include +#include +#include "vga.h" +#include "keyb.h" +#include "error.h" +#include "files.h" +#include "sound.h" + + +/* +#define WAIT_SZ 400000 + +extern byte gamcor[5][64]; + +extern char cd_path[]; + +extern int gammaa; +void setgamma(int); + +extern void *cd_scr; + +static byte skipping=0,credits=0; + +#define A8_ID 0xA8 + +enum{ + A8C_ENDFR,A8C_PAL,A8C_CLRSCR,A8C_DRAW, + A8C_FILL,A8C_DRAW2C,A8C_DRAW2 +}; + +typedef struct{ + unsigned char id,ver; + short width,height,frames; + long maxfsize; + long f1size; +}a8_hdr_t; + +typedef unsigned char uchar; + +#define SQ 4 + +static int sqw,sqh; + +static int norm_gamma; + +static unsigned char *frp,sqc[2][50][80]; +static int frame; +static a8_hdr_t ah; +static snd_t *strk; +static int strk_ch; + +static signed char *unpack(char *d,signed char *p,int l) { + for(;l>0;) if(*p>0) { + memcpy(d,p+1,*p);d+=*p;l-=*p;p+=*p+1; + }else if(*p<0) { + memset(d,p[1],-*p);d+=-*p;l-=-*p;p+=2; + }else return p+1; + return p; +} + +static unsigned char *draw(signed char *p) { + int x,y,sy,yc,n; + + for(y=0;y0) { + for(yc=*p++;yc;--yc,++y) for(x=0;x0) { + n=(*p++)*SQ; + for(sy=0;sy0) { + for(yc=*p++;yc;--yc,++y) for(x=0;x0) { + for(n=*p++;n;--n,++p,++x) + V_clr(x*SQ,SQ,y*SQ,SQ,*p); + }else x+=-*p++; + }else y+=-*p++; + return p; +} + +static unsigned char *draw2c(signed char *p) { + int x,y,sx,sy,yc,n; + unsigned short w; + + for(y=0;y0) { + for(yc=*p++;yc;--yc,++y) for(x=0;x0) { + for(n=*p++;n;--n,++x) { + sqc[0][y][x]=*p++; + sqc[1][y][x]=*p++; + w=*(unsigned short*)p;p+=2; + for(sy=0;sy>=1) + scra[(y*SQ+sy)*320+x*SQ+sx]=sqc[w&1][y][x]; + } + }else x+=-*p++; + }else y+=-*p++; + return p; +} + +static unsigned char *draw2(signed char *p) { + int x,y,sx,sy,yc,n; + unsigned short w; + + for(y=0;y0) { + for(yc=*p++;yc;--yc,++y) for(x=0;x0) { + for(n=*p++;n;--n,++x) { + w=*(unsigned short*)p;p+=2; + for(sy=0;sy>=1) + scra[(y*SQ+sy)*320+x*SQ+sx]=sqc[w&1][y][x]; + } + }else x+=-*p++; + }else y+=-*p++; + return p; +} + +//---------------------------------------------------------------// + +static int fsz,fdptr; +static FILE *fh; +static char *fdata; + + +static void f_close(void) { + if(fdata) { + free(fdata);fdata=NULL; + }else if(fh!=NULL) {fclose(fh);fh=NULL;} +} + +static char end_clr=1; +*/ + +void A8_close(void) { +/* + if(strk) if(strk_ch) S_stop(strk_ch); + f_close(); + if(frp) {free(frp);frp=NULL;} + if(strk) {free(strk);strk=NULL;} + if(end_clr) { + VP_fill(0,0,0); + V_clr(0,320,0,200,0);V_copytoscr(0,320,0,200); + setgamma(norm_gamma); + } +*/ +} + +int A8_nextframe(void) { +/* + unsigned char *p; + int i,j,k; + static int len; + + if(credits) if(keys[0x33] && keys[0x34]) skipping=1; + if(frame==-1) if(strk) strk_ch=S_play(strk,-1,1024,255); + if(fdata) { + len=*(int*)(fdata+fdptr);fdptr+=4; + }else {len=0;myfread(&len,1,4,fh);} + len-=4; + if(len<=0) { + A8_close(); + return 0; + } + if(fdata) { + p=fdata+fdptr;fdptr+=len; + }else {myfread(frp,1,len,fh);p=frp;} + for(;*p;) switch(*p++) { + case A8C_PAL: + i=*p++;j=*p++;if(!j) j=256; + for(k=0;krate=11000; + strk->len=sz; + strk->lstart=strk->llen=0; + for(p=(unsigned char *)(strk+1);sz;--sz,++p) *p^=0x80; + } + fclose(h); + } + } + sprintf(s,"%sA8\\%s.A8",cd_path,nm); + if((fh=fopen(s,"rb"))==NULL) { + ERR_fatal("Не могу открыть файл %s",s); + } + myfread(&ah,1,sizeof(ah)-4,fh); + if(ah.id!=A8_ID || ah.ver!=0) ERR_fatal("Испорченный файл A8 %s",s); + fseek(fh,0,SEEK_END); + fsz=ftell(fh)-sizeof(ah)+4; + fseek(fh,sizeof(ah)-4,SEEK_SET); + if((fdata=malloc(fsz))!=NULL) { + wait_scr(fsz); + myfread(fdata,1,fsz,fh); + fdptr=0; + fclose(fh);fh=NULL; + }else if(!(frp=malloc(ah.maxfsize))) { + if(strk) {free(strk);strk=NULL;} + if(!(frp=malloc(ah.maxfsize))) { + fclose(fh);fh=NULL;return 0; + } + } + sqw=ah.width/SQ;sqh=ah.height/SQ; + frame=-1; + norm_gamma=gammaa; + if(wscr) blank_scr(); + + + return 1; +*/ + + return 0; +} + +//----------// +//----------// diff --git a/src/anim.c b/src/anim.c new file mode 100644 index 0000000..39bb63c --- /dev/null +++ b/src/anim.c @@ -0,0 +1,106 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +//#include +#include "error.h" + +enum{AB_END,AB_SCREEN,AB_UPDATE}; + +typedef struct{ + short t,st; + unsigned len; +}anm_blk_t; + +#define SQ 4 + +static byte cnum[256]; + +static void init_cpack(void) { + int i; + + for(i=0;i<256;++i) cnum[i]=i; +} + +static byte cpack(byte n) { + byte c; + + c=cnum[n]; + if(n) memmove(cnum+1,cnum,n); + cnum[0]=c; + return c; +} + +static byte *unpack(byte *d,byte *s,int l) { + for(;l>0;--l,++d,++s) { + if(*s==0) {memset(d,cpack(0),(dword)(*(++s))+1);d+=(dword)*s;l-=(dword)*s;} + else *d=cpack(*s); + } + return s; +} + +static byte *line(int y,byte *u) { + int x,n,sy; + + for(x=0;xt==AB_END) return 0; + switch(anm->t) { + case AB_SCREEN: + unpack(scra,(byte*)(anm+1),64000); + break; + case AB_UPDATE: + for(u=(byte*)(anm+1),y=0;y<200/SQ;) + if(*u&0x80) { + for(x=(*u&0x7F)+1,++u;x;--x,++y) + u=line(y*320*SQ,u); + }else{y+=*u+1;++u;} + break; + default: ERR_fatal("«®å®© ANM-ä ©«"); + } + anm=((anm_blk_t*)((byte*)anm+anm->len))+1; + if(anm->t==AB_END) return 0; + return 1; +} diff --git a/src/bmap.c b/src/bmap.c new file mode 100644 index 0000000..ccb4404 --- /dev/null +++ b/src/bmap.c @@ -0,0 +1,61 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include "view.h" +#include "bmap.h" + +byte fld_need_remap=1; + +byte bmap[FLDH/4][FLDW/4]; + +void BM_mark(obj_t *o,byte f) { + int x,y; + int xs,ys,xe,ye; + + if((xs=(o->x-o->r)>>5)<0) xs=0; + if((xe=(o->x+o->r)>>5)>=FLDW/4) xe=FLDW/4-1; + if((ys=(o->y-o->h)>>5)<0) ys=0; + if((ye=o->y>>5)>=FLDH/4) ye=FLDH/4-1; + for(y=ys;y<=ye;++y) + for(x=xs;x<=xe;++x) + bmap[y][x]|=f; +} + +void BM_clear(byte f) +{ + int x,y; + for(x=0; x 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Block map + +#define BM_WALL 1 +#define BM_PLR1 2 +#define BM_PLR2 4 +#define BM_MONSTER 8 + +void BM_clear(byte f); +void BM_mark(obj_t *o,byte f); +void BM_remapfld(void); + +extern byte bmap[FLDH/4][FLDW/4]; +extern byte fld_need_remap; diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..4989e29 --- /dev/null +++ b/src/config.c @@ -0,0 +1,282 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +//#include +//#include +#include "config.h" +#include "vga.h" +#include "error.h" +#include "sound.h" +#include "keyb.h" +#include "files.h" +#include "memory.h" +#include "view.h" +#include "player.h" + +#include + +extern byte _warp,fastdraw,nomon; +extern int mem_chk_sz; + +enum{NONE,BYTE,WORD,DWORD,STRING,SW_ON,SW_OFF,FILES,KEY}; + +typedef struct{ + char *par,*cfg; + void *p; + byte t,o; +}cfg_t; + + +byte cheat=0; + +byte shot_vga=0; + + +char cd_path[128]=""; + +static cfg_t cfg[]={ + {"file",NULL,NULL,FILES,0}, + {"cheat",NULL,&cheat,SW_ON,0}, + {"vga","screenshot",&shot_vga,SW_ON,0}, + {"sndvol","sound_volume",&snd_vol,WORD,0}, + {"musvol","music_volume",&mus_vol,WORD,0}, + {"fullscr","fullscreen",&fullscreen,SW_ON,0}, + {"window",NULL,&fullscreen,SW_OFF,0}, + {NULL,"sky",&w_horiz,SW_ON,0}, + {"mon",NULL,&nomon,SW_OFF,0}, + {"gamma","gamma",&gammaa,DWORD,0}, + {"warp",NULL,&_warp,BYTE,0}, + {"width","screen_width",&SCRW,DWORD,0}, + {"height","screen_height",&SCRH,DWORD,0}, + {NULL,"music_random",&music_random,SW_ON,0}, + {NULL,"music_time",&music_time,DWORD,0}, + {NULL,"music_fade",&music_fade,DWORD,0}, + {NULL,"pl1_left", &pl1.kl,KEY,0}, + {NULL,"pl1_right",&pl1.kr,KEY,0}, + {NULL,"pl1_up", &pl1.ku,KEY,0}, + {NULL,"pl1_down", &pl1.kd,KEY,0}, + {NULL,"pl1_jump", &pl1.kj,KEY,0}, + {NULL,"pl1_fire", &pl1.kf,KEY,0}, + {NULL,"pl1_next", &pl1.kwr,KEY,0}, + {NULL,"pl1_prev", &pl1.kwl,KEY,0}, + {NULL,"pl1_use", &pl1.kp,KEY,0}, + {NULL,"pl2_left", &pl2.kl,KEY,0}, + {NULL,"pl2_right",&pl2.kr,KEY,0}, + {NULL,"pl2_up", &pl2.ku,KEY,0}, + {NULL,"pl2_down", &pl2.kd,KEY,0}, + {NULL,"pl2_jump", &pl2.kj,KEY,0}, + {NULL,"pl2_fire", &pl2.kf,KEY,0}, + {NULL,"pl2_next", &pl2.kwr,KEY,0}, + {NULL,"pl2_prev", &pl2.kwl,KEY,0}, + {NULL,"pl2_use", &pl2.kp,KEY,0}, + {"config",NULL,cfg_file,STRING,0}, + {NULL,NULL,NONE,0} +}; + + +char cfg_file[128]="DEFAULT.CFG"; + +static char buf[256]; + +void CFG_args(int argc, char *argv[]) { + int j; + dword n; + char *s; + + logo("CFG_args: проверка командной строки\n"); + + int i; + char *pbuf = buf; + for (i=1;i0) if(cfg[j-1].t==SW_OFF && cfg[j-1].p==cfg[j].p) cfg[j-1].o=1; + break; + case SW_OFF: + *((byte *)cfg[j].p)=OFF; + if(cfg[j+1].t==SW_ON && cfg[j+1].p==cfg[j].p) cfg[j+1].o=1; + if(j>0) if(cfg[j-1].t==SW_ON && cfg[j-1].p==cfg[j].p) cfg[j-1].o=1; + break; + case FILES: + for(s=strtok(NULL," \r\n\t");s;s=strtok(NULL," \r\n\t")) { + if(*s=='/' || *s=='-') goto next; +#ifdef DEMO + logo(" %s НЕ подключен!\n",s); +#else + F_addwad(s); +#endif + }break; + default: + ERR_failinit("!!! Неизвестный тип в cfg !!!"); + } + cfg[j].o=1;break; + } + } +} + +int get_key(char *name) +{ + int i; + for(i=1; i 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Configuration + +void CFG_args(int argc, char *argv[]); +void CFG_load(void); +void CFG_save(void); + +extern char cfg_file[]; + diff --git a/src/default.cfg b/src/default.cfg new file mode 100644 index 0000000..29ed218 --- /dev/null +++ b/src/default.cfg @@ -0,0 +1,31 @@ +;” ©« ª®­ä¨£ãà æ¨¨ + +gamma=0 +sound_volume=50 +music_volume=60 +screenshot=on +fullscreen=off +screen_width=800 +screen_height=600 +music_random=on +music_time=4 +music_fade=6 +sky=on +pl1_left=[4] +pl1_right=[6] +pl1_up=[8] +pl1_down=[5] +pl1_jump=page down +pl1_fire=delete +pl1_next=end +pl1_prev=home +pl1_use=[8] +pl2_left=s +pl2_right=f +pl2_up=e +pl2_down=d +pl2_jump=q +pl2_fire=a +pl2_next=1 +pl2_prev=2 +pl2_use=e diff --git a/src/doom2d.wad b/src/doom2d.wad new file mode 100644 index 0000000..0c8eafe Binary files /dev/null and b/src/doom2d.wad differ diff --git a/src/dots.c b/src/dots.c new file mode 100644 index 0000000..ddb39a2 --- /dev/null +++ b/src/dots.c @@ -0,0 +1,223 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +//#include +#include +#include "files.h" +#include "memory.h" +#include "vga.h" +#include "error.h" +#include "keyb.h" +#include "sound.h" +#include "view.h" +#include "dots.h" +#include "misc.h" + +#define MAXINI 50 +#define MAXSR 20 + +#define BL_XV 4 +#define BL_YV 4 +#define BL_MINT 10 +#define BL_MAXT 14 + +#define SP_V 2 +#define SP_MINT 5 +#define SP_MAXT 7 + +extern byte z_dot; + +#pragma pack(1) +typedef struct{ + obj_t o; + byte c,t; +}dot_t; +#pragma pack() + +typedef struct{ + int xv,yv; + byte c,t; +}init_t; + +static dot_t dot[MAXDOT]; +static init_t bl_ini[MAXINI],sp_ini[MAXINI]; +static int bl_r,sp_r,sr_r,sxr[MAXSR],syr[MAXSR]; +static int ldot; + +void DOT_savegame(FILE* h) { + int i,n; + + for(i=n=0;i=MAXDOT) ldot=0; +} + +void DOT_alloc(void) { + int i; + + for(i=0;i2) { + if(!xv) dot[i].o.vx=(rand()&1)?-1:1; + else dot[i].o.vx=Z_sign(dot[i].o.vx); + if(rand()%yv==0) dot[i].o.vx*=2; + dot[i].o.yv=yv-2; + } + } + dot[i].o.xv=0; + if(dot[i].t>4 && dot[i].t!=255) dot[i].t=4; + } + if(s&Z_HITWALL) { + dot[i].o.vx=Z_sign(xv)*2; + dot[i].o.yv=Z_sign(dot[i].o.yv); + if(dot[i].o.yv>=0) if(rand()&3) --dot[i].o.yv; + if(dot[i].o.yv>=0) if(rand()&1) --dot[i].o.yv; + } + if(s&Z_HITCEIL) {dot[i].o.xv=0;dot[i].o.yv=(myrand(100))?-2:0;} + } + z_dot=0; +} + +void DOT_draw(void) { + int i; + + for(i=0;i=MAXINI) bl_r=0; + if(++sr_r>=MAXSR) sr_r=0; + incldot(); + } +} + +void DOT_spark(int x,int y,int xv,int yv,int n) { + int i,k,dx,dy; + + for(k=n;k;--k) { + dx=x+sxr[sr_r];dy=y+syr[sr_r]; + if(!Z_canfit(x,y,0,1)) continue; + i=ldot; + dot[i].o.x=dx;dot[i].o.y=dy; + dot[i].o.xv=sp_ini[sp_r].xv-xv/4; + dot[i].o.yv=sp_ini[sp_r].yv-yv/4; + dot[i].c=sp_ini[sp_r].c; + dot[i].t=sp_ini[sp_r].t; + dot[i].o.vx=dot[i].o.vy=0; + if(++sp_r>=MAXINI) sp_r=0; + if(++sr_r>=MAXSR) sr_r=0; + incldot(); + } +} + +void DOT_water(int x,int y,int xv,int yv,int n,int c) { + int i,k,dx,dy; + static byte ct[3]={0xC0,0x70,0xB0}; + + if(c<0 || c>=3) return; + c=ct[c]; + for(k=n;k;--k) { + dx=x+sxr[sr_r];dy=y+syr[sr_r]; + if(!Z_canfit(x,y,0,1)) continue; + i=ldot; + dot[i].o.x=dx;dot[i].o.y=dy; + dot[i].o.xv=bl_ini[bl_r].xv-Z_dec(xv,3); + dot[i].o.yv=bl_ini[bl_r].yv-abs(yv); + dot[i].c=bl_ini[bl_r].c-0xB0+c; + dot[i].t=254; + dot[i].o.vx=dot[i].o.vy=0; + if(++bl_r>=MAXINI) bl_r=0; + if(++sr_r>=MAXSR) sr_r=0; + incldot(); + } +} diff --git a/src/dots.h b/src/dots.h new file mode 100644 index 0000000..b5ac1d9 --- /dev/null +++ b/src/dots.h @@ -0,0 +1,34 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Dots + +#define MAXDOT 400 + +void DOT_init(void); +void DOT_alloc(void); +void DOT_act(void); +void DOT_draw(void); +void DOT_add(int x,int y,char xv,char yv,byte color,byte time); +void DOT_blood(int,int,int,int,int); +void DOT_spark(int,int,int,int,int); +void DOT_water(int,int,int,int,int,int); diff --git a/src/error.c b/src/error.c new file mode 100644 index 0000000..8c8eee9 --- /dev/null +++ b/src/error.c @@ -0,0 +1,84 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +//#include +#include +#include +#include +#include "keyb.h" +#include "sound.h" +#include "vga.h" +#include "memory.h" +#include "files.h" +#include "error.h" +#include "config.h" + +#include + + +void close_all(void) { + S_done(); + S_donemusic(); + K_done(); + V_done(); + M_shutdown(); +} + +void ERR_failinit(char *s,...) { + va_list ap; + + close_all(); + va_start(ap,s); + vprintf(s,ap); + va_end(ap); + puts(""); + exit(1); +} + +void ERR_fatal(char *s,...) { + va_list ap; + + close_all(); + puts("\nКРИТИЧЕСКАЯ ОШИБКА:"); + va_start(ap,s); + vprintf(s,ap); + va_end(ap); + puts(""); + exit(2); +} + +void ERR_quit(void) { + void *p; + //V_done(); + //if(!(p=malloc(4000))) + puts("Спасибо за то, что вы играли в Операцию \"Смятка\"!"); + //else { +// F_loadres(F_getresid("ENDOOM"),p,0,4000); + // memcpy((void*)0xB8000,p,4000);free(p);gotoxy(1,24); + //} + close_all(); + CFG_save(); + exit(0); +} diff --git a/src/error.h b/src/error.h new file mode 100644 index 0000000..6e4e61d --- /dev/null +++ b/src/error.h @@ -0,0 +1,27 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Error handling + +void ERR_failinit(char *,...); +void ERR_fatal(char *,...); +void ERR_quit(void); diff --git a/src/files.c b/src/files.c new file mode 100644 index 0000000..97e69eb --- /dev/null +++ b/src/files.c @@ -0,0 +1,463 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +//#include +#include +//#include +#include +#include +//#include +#include "vga.h" +#include "error.h" +#include "sound.h" +//#include "snddrv.h" +#include "memory.h" +#include "view.h" +#include "items.h" +#include "switch.h" +#include "files.h" +#include "map.h" + + +char *S_getinfo(void); + +extern void *snd_drv; + +typedef struct{ + byte n,i,v,d; +}dmv; + +byte seq[255],seqn; +dmv *pat=NULL; +unsigned *patp; +void **dmi; + +static int inum=0; + +void G_savegame(FILE*); +void W_savegame(FILE*); +void DOT_savegame(FILE*); +void SMK_savegame(FILE*); +void FX_savegame(FILE*); +void IT_savegame(FILE*); +void MN_savegame(FILE*); +void PL_savegame(FILE*); +void SW_savegame(FILE*); +void WP_savegame(FILE*); + +void G_loadgame(FILE*); +void W_loadgame(FILE*); +void DOT_loadgame(FILE*); +void SMK_loadgame(FILE*); +void FX_loadgame(FILE*); +void IT_loadgame(FILE*); +void MN_loadgame(FILE*); +void PL_loadgame(FILE*); +void SW_loadgame(FILE*); +void WP_loadgame(FILE*); + +byte savname[7][24],savok[7]; + +int d_start,d_end,m_start,m_end,s_start,s_end,wad_num; +mwad_t wad[MAX_WAD]; + +char wads[MAX_WADS][__MAX_PATH]; +static FILE* wadh[MAX_WADS]; + +char f_drive[__MAX_DRIVE],f_dir[__MAX_DIR],f_name[__MAX_FNAME],f_ext[__MAX_EXT], + f_path[__MAX_PATH]; + +void F_startup(void) { + logo("F_startup: настройка файловой системы\n"); + memset(wads,0,sizeof(wads)); +} + +void F_getsavnames(void) { + + int i; FILE *h; + static char n[]="SAVGAME0.DAT"; + short ver; + + for(i=0;i<7;++i) { + n[7]=i+'0';memset(savname[i],0,24);savok[i]=0; + if((h=fopen(n,"rb"))==NULL) continue; //if((h=open(n,O_RDONLY|O_BINARY))==-1) continue; + myfread(savname[i],1,24,h);ver=-1;myfread(&ver,1,2,h); + fclose(h);savname[i][23]=0;savok[i]=(ver==3)?1:0;//savok[i]=(ver==2)?1:0; + } +} + +void F_savegame(int n,char *s) { + + FILE* h; + static char fn[]="SAVGAME0.DAT"; + + fn[7]=n+'0'; + if((h=fopen(fn,"wb"))==NULL) return; + myfwrite(s,1,24,h);myfwrite("\3\0",1,2,h);//myfwrite("\2\0",1,2,h); + G_savegame(h); + W_savegame(h); + DOT_savegame(h); + SMK_savegame(h); + FX_savegame(h); + IT_savegame(h); + MN_savegame(h); + PL_savegame(h); + SW_savegame(h); + WP_savegame(h); + fclose(h); + +} + +void F_loadgame(int n) { + FILE* h; + static char fn[]="SAVGAME0.DAT"; + short ver; + + fn[7]=n+'0'; + if((h=fopen(fn,"rb"))==NULL) return;//if((h=open(fn,O_BINARY|O_RDONLY))==-1) return; + fseek(h,24,SEEK_SET);myfread(&ver,1,2,h);if(ver!=3) return;//if(ver!=2) return; + G_loadgame(h); + W_loadgame(h); + DOT_loadgame(h); + SMK_loadgame(h); + FX_loadgame(h); + IT_loadgame(h); + MN_loadgame(h); + PL_loadgame(h); + SW_loadgame(h); + WP_loadgame(h); + fclose(h); +} + +void F_addwad(char *fn) { + int i; + + for(i=0;i=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а"); + memcpy(wad[p].n,w.n,8); + wad[p].o=w.o;wad[p].l=w.l;wad[p].f=0; + ++p; + } + //fclose(h); + for(i=1;i=MAX_WAD) { + if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а"); + memset(wad[p].n,0,8); + strncpy(wad[p].n,f_name,8); + wad[p].o=0L;wad[p].l=myfilelength(h);wad[p].f=i; + ++p; + } + continue; + } + *s=0;myfread(s,1,4,h); + if(strncmp(s,"IWAD",4)!=0 && strncmp(s,"PWAD",4)!=0) + ERR_failinit("Нет подписи IWAD или PWAD"); + myfread(&n,1,4,h);myfread(&o,1,4,h);fseek(h,o,SEEK_SET); + for(j=0;j=MAX_WAD) { + if(p>=MAX_WAD) ERR_failinit("Слишком много элементов WAD'а"); + memcpy(wad[p].n,w.n,8); + wad[p].o=w.o;wad[p].l=w.l;wad[p].f=i; + ++p; + } + } + } + wad_num=p; + +} + +// allocate resources +// (called from M_startup) +void F_allocres(void) { + d_start=F_getresid("D_START"); + d_end=F_getresid("D_END"); + m_start=F_getresid("M_START"); + m_end=F_getresid("M_END"); + s_start=F_getresid("S_START"); + s_end=F_getresid("S_END"); +} + +// load resource +void F_loadres(int r,void *p,dword o,dword l) { + + int oo; + FILE *fh; + + + oo=ftell(fh=wadh[wad[r].f]); + + if(fseek(fh,wad[r].o+o,SEEK_SET)!=0) + ERR_fatal("Ошибка при чтении файла"); + + if((dword)myfreadc(p,1,l,fh)!=l) + ERR_fatal("Ошибка при загрузке ресурса %.8s",wad[r].n); + + fseek(fh,oo,SEEK_SET); + +} + + +void F_saveres(int r,void *p,dword o,dword l) { + + int oo; + FILE* fh; + oo=ftell(fh=wadh[wad[r].f]); + if(fseek(fh,wad[r].o+o,SEEK_SET)!=0) + ERR_fatal("Ошибка при чтении файла"); + myfwrite(p,l,1,fh); + fseek(fh,oo,SEEK_SET); + +} + +// get resource id +int F_getresid(char *n) { + int i; + + for(i=0;i=m_end) i=m_start; + for(++i;;++i) { + if(i>=m_end) i=m_start+1; + + if (strcasecmp(wad[i].n,"MENU") == 0 || + strcasecmp(wad[i].n,"INTERMUS") == 0 || + strcasecmp(wad[i].n,"\x8a\x8e\x8d\x85\x96\x0") == 0) + continue; + + if(strncasecmp(wad[i].n,"DMI",3)!=0) break; + } + memcpy(s,wad[i].n,8); +} + +void F_randmus(char *s) { + int n = myrand(10); + int i; + for (i=0; i 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// File operations + +///#include +//#include +#include + +#define MAX_WADS 20 +#define MAX_WAD 2000 + +typedef char wadname[8]; + +typedef struct { + int o,l; + char n[8]; +}wad_t; + +typedef struct { + int o,l; + char n[8]; + int f; +}mwad_t; + +void F_startup(void); +void F_addwad(char *); +void F_initwads(void); +void F_allocres(void); +//void F_preload(void); +void F_readstr(FILE*,char *,int); +void F_readstrz(FILE*,char *,int); +void F_loadres(int,void *,dword,dword); +int F_getresid(char *); +void F_getresname(char *,int); +int F_findres(char *); +int F_getsprid(char[4],int,int); +int F_getreslen(int); +void F_loadmap(char[8]); +void F_loadmus(char[8]); +void F_freemus(void); +void F_nextmus(char*); + +void F_getsavnames(void); +void F_loadgame(int); +void F_savegame(int,char*); + +void F_randmus(char*);// + +extern char wads[MAX_WADS][__MAX_PATH]; +extern int wad_num; diff --git a/src/fx.c b/src/fx.c new file mode 100644 index 0000000..a6b3f06 --- /dev/null +++ b/src/fx.c @@ -0,0 +1,217 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +//#include +#include +#include +#include +#include "vga.h" +#include "error.h" +#include "view.h" +#include "fx.h" +#include "misc.h" + +enum{NONE,TFOG,IFOG,BUBL}; + +#pragma pack(1) +typedef struct{ + int x,y,xv,yv; + char t,s; +}fx_t; +#pragma pack() + +static void *spr[15],*bsnd[2]; +static char sprd[15]; +static fx_t fx[MAXFX]; +static char bubsn; +static int last; + +unsigned char fx_scr1[64000],fx_scr2[64000]; + +#define SINP 256 +#define SINPM (SINP-1) +#define W (SINP/100) + +static int stdsin[SINP]={ +#include "fx1sin.dat" +}; +static int sintab[SINP]; + +static unsigned char dmap[32*32]; + +static int isin(int a) { + return sintab[a&SINPM]; +} + +static void setamp(int a) { + int i; + + for(i=0;i=k) { + u=x+((isin(y+t))>>16); + v=y+((isin(u+t))>>16); + if(u<0 || u>=320 || v<0 || v>=200) scra[p]=0; + else scra[p]=fx_scr1[v*320+u]; + }else scra[p]=fx_scr2[p]; + } + +} + +static void init_fx1sin(void) { + int j,r,l,rr; + unsigned i; + + memset(dmap,0,32*32); + for(i=1,rr=32*32;i<64;++i) { + for(l=32*32/64;l;--l,--rr) { + r=rand()%rr; + for(j=0;r;--r,++j) { + for(;dmap[j];++j); + } + for(;dmap[j];++j); + dmap[j]=i; + } + } +} + +void FX_savegame(FILE* h) { + int i,n; + + for(i=n=0;i=20) fx[i].t=0; + break; + case IFOG: + if(++fx[i].s>=10) fx[i].t=0; + break; + case BUBL: + fx[i].yv-=5; + fx[i].xv=Z_dec(fx[i].xv,20); + fx[i].x+=fx[i].xv; + fx[i].y+=fx[i].yv; + if((b=fld[fx[i].y>>11][fx[i].x>>11]) < 5 || b>7) fx[i].t=0; + break; + } +} + +void FX_draw(void) { + int i,s; + + for(i=0;i>8)-w_x+WD/2,(fx[i].y>>8)-w_y+HT/2+1+w_o,0xC0+fx[i].s);//V_dot((fx[i].x>>8)-w_x+100,(fx[i].y>>8)-w_y+50+w_o,0xC0+fx[i].s); + continue; + } + if(s>=0) Z_drawspr(fx[i].x,fx[i].y,spr[s],sprd[s]); + } +} + +static int findfree(void) { + int i; + + for(i=0;i=MAXFX) last=0; + return last; +} + +void FX_tfog(int x,int y) { + int i; + + i=findfree(); + fx[i].t=TFOG;fx[i].s=0; + fx[i].x=x;fx[i].y=y; +} + +void FX_ifog(int x,int y) { + int i; + + i=findfree(); + fx[i].t=IFOG;fx[i].s=0; + fx[i].x=x;fx[i].y=y; +} + +void FX_bubble(int x,int y,int xv,int yv,int n) { + int i; + + if(!bubsn) {Z_sound(bsnd[rand()&1],128);bubsn=1;} + for(;n>0;--n) { + i=findfree(); + fx[i].t=BUBL;fx[i].s=rand()&3; + fx[i].x=(x<<8)+myrand(513)-256;fx[i].y=(y<<8)+myrand(513)-256; + fx[i].xv=xv;fx[i].yv=yv-myrand(256)-768; + } +} + diff --git a/src/fx.h b/src/fx.h new file mode 100644 index 0000000..784844a --- /dev/null +++ b/src/fx.h @@ -0,0 +1,33 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Effects + +#define MAXFX 300 + +void FX_init(void); +void FX_alloc(void); +void FX_act(void); +void FX_draw(void); +void FX_tfog(int,int); +void FX_ifog(int,int); +void FX_bubble(int x,int y,int xv,int yv,int n); diff --git a/src/fx1sin.dat b/src/fx1sin.dat new file mode 100644 index 0000000..8decde5 --- /dev/null +++ b/src/fx1sin.dat @@ -0,0 +1,32 @@ +0,1608,3215,4821,6423,8022,9616,11204, +12785,14359,15923,17479,19024,20557,22078,23586, +25079,26557,28020,29465,30893,32302,33692,35061, +36409,37736,39039,40319,41575,42806,44011,45189, +46340,47464,48558,49624,50660,51665,52639,53581, +54491,55368,56212,57022,57797,58538,59243,59913, +60547,61144,61705,62228,62714,63162,63571,63943, +64276,64571,64826,65043,65220,65358,65457,65516, +65535,65516,65457,65358,65220,65043,64826,64571, +64276,63943,63571,63162,62714,62228,61705,61144, +60547,59913,59243,58538,57797,57022,56212,55368, +54491,53581,52639,51665,50660,49624,48558,47464, +46340,45189,44011,42806,41575,40319,39039,37736, +36409,35061,33692,32302,30893,29465,28020,26557, +25079,23586,22078,20557,19024,17479,15923,14359, +12785,11204,9616,8022,6423,4821,3215,1608, +0,-1608,-3215,-4821,-6423,-8022,-9616,-11204, +-12785,-14359,-15923,-17479,-19024,-20557,-22078,-23586, +-25079,-26557,-28020,-29465,-30893,-32302,-33692,-35061, +-36409,-37736,-39039,-40319,-41575,-42806,-44011,-45189, +-46340,-47464,-48558,-49624,-50660,-51665,-52639,-53581, +-54491,-55368,-56212,-57022,-57797,-58538,-59243,-59913, +-60547,-61144,-61705,-62228,-62714,-63162,-63571,-63943, +-64276,-64571,-64826,-65043,-65220,-65358,-65457,-65516, +-65535,-65516,-65457,-65358,-65220,-65043,-64826,-64571, +-64276,-63943,-63571,-63162,-62714,-62228,-61705,-61144, +-60547,-59913,-59243,-58538,-57797,-57022,-56212,-55368, +-54491,-53581,-52639,-51665,-50660,-49624,-48558,-47464, +-46340,-45189,-44011,-42806,-41575,-40319,-39039,-37736, +-36409,-35061,-33692,-32302,-30893,-29465,-28020,-26557, +-25079,-23586,-22078,-20557,-19024,-17479,-15923,-14359, +-12785,-11204,-9616,-8022,-6423,-4821,-3215,-1608 diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..194365e --- /dev/null +++ b/src/game.c @@ -0,0 +1,547 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +#include "files.h" +#include "memory.h" +#include "vga.h" +#include "error.h" +#include "keyb.h" +#include "sound.h" +#include "view.h" +#include "bmap.h" +#include "fx.h" +#include "switch.h" +#include "weapons.h" +#include "items.h" +#include "dots.h" +#include "smoke.h" +#include "player.h" +#include "monster.h" +#include "menu.h" +#include "misc.h" +#include "map.h" + +#include + +#define LT_DELAY 8 +#define LT_HITTIME 6 + +#define GETIME 1092 + + +int A8_start(char*); +int A8_nextframe(void); +void A8_close(void); + + +void FX_trans1(int t); +extern unsigned char fx_scr1[64000],fx_scr2[64000]; + +extern short lastkey; + + +extern int hit_xv,hit_yv; + +extern vgapal std_pal; +void setgamma(int); + +extern int sw_secrets; + +#define PL_FLASH 90 + +extern int PL_JUMP; + +extern map_block_t blk; + +extern byte clrmap[256*12]; + +extern byte cheat; + +byte _2pl=0,g_dm=0,g_st=GS_TITLE,g_exit=0,g_map=1,_warp=0,g_music[8]="MENU"; +byte _net=0; +int g_sttm=1092; +dword g_time; +int dm_pnum,dm_pl1p,dm_pl2p; +pos_t dm_pos[100]; + +static void *telepsnd; +static void *scrnh[3]; +void *cd_scr; + +extern int sky_type; +void *ltn[2][2]; +int lt_time,lt_type,lt_side,lt_ypos,lt_force; +void *ltnsnd[2]; + +int g_trans=0,g_transt; + +static void set_trans(int st) { + switch(g_st) { + case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN: + case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM: + g_st=st;return; + } + switch(g_st=st) { + case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN: + case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM: + return; + } + g_trans=1;g_transt=0; +} + +void G_savegame(FILE* h) { + myfwrite(&_2pl,1,1,h);myfwrite(&g_dm,1,1,h);myfwrite(&g_exit,1,1,h);myfwrite(&g_map,1,1,h); + myfwrite(&g_time,1,4,h);myfwrite(&dm_pl1p,1,4,h);myfwrite(&dm_pl2p,1,4,h); + myfwrite(&dm_pnum,1,4,h);myfwrite(dm_pos,1,dm_pnum*sizeof(pos_t),h); + myfwrite(&cheat,1,1,h); + myfwrite(g_music,1,8,h); +} + +void G_loadgame(FILE* h) { + myfread(&_2pl,1,1,h);myfread(&g_dm,1,1,h);myfread(&g_exit,1,1,h);myfread(&g_map,1,1,h); + myfread(&g_time,1,4,h);myfread(&dm_pl1p,1,4,h);myfread(&dm_pl2p,1,4,h); + myfread(&dm_pnum,1,4,h);myfread(dm_pos,1,dm_pnum*sizeof(pos_t),h); + myfread(&cheat,1,1,h); + myfread(g_music,1,8,h);F_loadmus(g_music); +} + +int G_load(FILE* h) { + switch(blk.t) { + case MB_MUSIC: + myfread(g_music,1,8,h); + if (music_random) F_randmus(g_music); + F_loadmus(g_music); + return 1; + }return 0; +} + +void load_game(int n) { + F_freemus(); + W_init(); + F_loadgame(n); + set_trans(GS_GAME); + V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200); + V_clr(0,SCRW,0,SCRH,0);//V_clr(0,320,0,200,0); + if(_2pl) {w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();} + else {w_o=0;Z_clrst();}//else {w_o=50;Z_clrst();} + V_setscr(scrbuf); + pl1.drawst=0xFF; + if(_2pl) pl2.drawst=0xFF; + BM_remapfld(); + BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER); + BM_mark(&pl1.o,BM_PLR1); + if(_2pl) BM_mark(&pl2.o,BM_PLR2); + MN_mark(); + S_startmusic(music_time); +} + +void G_start(void) { + char s[8]; + + F_freemus(); + sprintf(s,"MAP%02u",(word)g_map); + F_loadmap(s); + set_trans(GS_GAME); + V_setscr((g_trans)?fx_scr2:scrbuf);V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200); + V_clr(0,SCRW,0,SCRH,0);//V_clr(0,320,0,200,0); + if(_2pl) {w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {w_o=0;Z_clrst();w_o=100;Z_clrst();} + else {w_o=0;Z_clrst();}//else {w_o=50;Z_clrst();} + V_setscr(scrbuf); + pl1.drawst=0xFF; + if(_2pl) pl2.drawst=0xFF; + g_exit=0; + itm_rtime=(g_dm)?1092:0; + p_immortal=0;PL_JUMP=10; + g_time=0; + lt_time=1000; + lt_force=1; + if(!_2pl) pl1.lives=3; + BM_remapfld(); + BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER); + BM_mark(&pl1.o,BM_PLR1); + if(_2pl) BM_mark(&pl2.o,BM_PLR2); + MN_mark(); + S_startmusic(music_time); +} + +#define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10) + +void G_init(void) { + int i,j; + char s[9]; + + logo("G_init: настройка ресурсов игры "); + logo_gas(5,GGAS_TOTAL); + telepsnd=Z_getsnd("TELEPT"); + scrnh[0]=M_lock(F_getresid("TITLEPIC")); + scrnh[1]=M_lock(F_getresid("INTERPIC")); + scrnh[2]=M_lock(F_getresid("ENDPIC")); + cd_scr=M_lock(F_getresid("CD1PIC")); + for(i=0;i<2;++i) { + sprintf(s,"LTN%c",i+'1'); + for(j=0;j<2;++j) + ltn[i][j]=Z_getspr(s,j,0,NULL); + } + ltnsnd[0]=Z_getsnd("THUND1"); + ltnsnd[1]=Z_getsnd("THUND2"); + DOT_alloc(); + SMK_alloc(); + FX_alloc(); + WP_alloc(); + IT_alloc(); + SW_alloc(); + PL_alloc(); + MN_alloc(); + Z_initst(); + logo_gas(GGAS_TOTAL,GGAS_TOTAL); + logo("\n"); + GM_init(); + pl1.color=0x70; + pl2.color=0x60; + g_trans=0; +} + +int G_beg_video(void) { +/* + switch(g_map) { + case 3: return A8_start("FALL"); + case 4: return A8_start("KORIDOR"); + case 5: return A8_start("SKULL"); + case 6: return A8_start("TORCHES"); + case 7: return A8_start("CACO"); + case 8: return A8_start("DARTS"); + case 9: return A8_start("FISH"); + case 10: return A8_start("TRAP"); + case 11: return A8_start("JAIL"); + case 12: return A8_start("MMON1"); + case 13: return A8_start("TOWER"); + case 14: return A8_start("SAPOG"); + case 15: return A8_start("SWITCH"); + case 16: return A8_start("ACCEL"); + case 17: return A8_start("MEAT"); + case 18: return A8_start("LEGION"); + case 19: return A8_start("CLOUDS"); + } +*/ + return 0; +} + + +int G_end_video(void) { +/* + switch(g_map) { + case 1: return A8_start("TRUBA"); + case 10: return A8_start("GOTCHA"); + } +*/ + return 0; +} + + +static byte transdraw=0; + +void G_act(void) { + static byte pcnt=0; +/* + if(g_trans) { + if(g_transt==0) { + V_setscr(NULL);memcpy(fx_scr1,scra,64000); + V_setscr(fx_scr2); + transdraw=1;G_draw();transdraw=0; + V_setscr(scrbuf); + } + FX_trans1(g_transt*2); + V_copytoscr(0,320,0,200); + if(++g_transt>32) { + g_trans=0; + } + return; + g_trans=0; + } +*/ g_trans=0; + + + if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) { + if(!A8_nextframe() || lastkey==SDLK_ESCAPE) { + if(lastkey==SDLK_ESCAPE) lastkey=0; + A8_close(); + if(g_st==GS_BVIDEO) G_start(); + else goto inter; + } + V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200); + return; + }else if(g_st==GS_ENDANIM || g_st==GS_END2ANIM || g_st==GS_END3ANIM) { + if(!A8_nextframe()) { + switch(g_st) { + case GS_ENDANIM: g_st=GS_DARKEN;break; + case GS_END2ANIM: g_st=GS_END3ANIM;A8_start("KONEC");break; + case GS_END3ANIM: g_st=GS_ENDSCR;lastkey=0;break; + }g_sttm=0;return; + } + V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200); + return; + }else if(g_st==GS_DARKEN) { + g_st=GS_END2ANIM;A8_start("CREDITS"); + return; + } + + if(GM_act()) return; + + + + switch(g_st) { + case GS_TITLE: case GS_ENDSCR: + + return; + case GS_INTER: +#ifdef DEMO + if(keys[0x39] || keys[0x1C] || keys[0x9C]) { + set_trans(GS_TITLE); + } +#else + if(keys[SDLK_SPACE] || keys[SDLK_RETURN] || keys[SDLK_KP_ENTER])//if(keys[0x39] || keys[0x1C] || keys[0x9C]) + if(!G_beg_video()) G_start(); else { + g_st=GS_BVIDEO;F_freemus(); + } +#endif + return; + } + + + if(sky_type==2) { + if(lt_time>LT_DELAY || lt_force) { + if(!(rand()&31) || lt_force) { + lt_force=0; + lt_time=-LT_HITTIME; + lt_type=rand()%2; + lt_side=rand()&1; + lt_ypos=rand()&31; + Z_sound(ltnsnd[rand()&1],128); + } + }else ++lt_time; + } + ++g_time; + pl1.hit=0;pl1.hito=-3; + if(_2pl) {pl2.hit=0;pl2.hito=-3;} + G_code(); + + W_act(); + IT_act(); + SW_act(); + if(_2pl) { + if(pcnt) {PL_act(&pl1);PL_act(&pl2);} + else {PL_act(&pl2);PL_act(&pl1);} + pcnt^=1; + }else PL_act(&pl1); + MN_act(); + if(fld_need_remap) BM_remapfld(); + BM_clear(BM_PLR1|BM_PLR2|BM_MONSTER); + BM_mark(&pl1.o,BM_PLR1); + if(_2pl) BM_mark(&pl2.o,BM_PLR2); + MN_mark(); + WP_act(); + DOT_act(); + SMK_act(); + FX_act(); + if(_2pl) { + PL_damage(&pl1);PL_damage(&pl2); + if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1); + if(!(pl2.f&PLF_PNSND) && pl2.pain) PL_cry(&pl2); + if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);} + if((pl2.pain-=5) < 0) {pl2.pain=0;pl2.f&=(0xFFFF-PLF_PNSND);} + }else{ + PL_damage(&pl1); + if(!(pl1.f&PLF_PNSND) && pl1.pain) PL_cry(&pl1); + if((pl1.pain-=5) < 0) {pl1.pain=0;pl1.f&=(0xFFFF-PLF_PNSND);} + } + if(g_exit==1) { + + if(G_end_video()) { + F_freemus(); + g_st=GS_EVIDEO; + return; + } + +inter: + switch(g_map) { + case 19: g_st=GS_ENDANIM;A8_start("FINAL");break; + case 31: case 32: g_map=16;set_trans(GS_INTER);break; + default: ++g_map;set_trans(GS_INTER);break; + } + F_freemus(); + if(g_st==GS_INTER) { + F_loadmus("INTERMUS"); + }else {F_loadmus("\x8a\x8e\x8d\x85\x96\x0");if(mus_vol>0) {S_volumemusic(128);} } + S_startmusic(0); + }else if(g_exit==2) { + switch(g_map) { + case 31: g_map=32;set_trans(GS_INTER);break; + case 32: g_map=16;set_trans(GS_INTER);break; + default: g_map=31;set_trans(GS_INTER);break; + } + F_freemus(); + F_loadmus("INTERMUS"); + S_startmusic(0); + } + +#ifdef DEMO + if(g_dm && g_time>10920) {set_trans(GS_INTER);} +#endif +} + +/* +static void drawview(player_t *p) { + if(p->looky<-50) p->looky=-50; + else if(p->looky>50) p->looky=50; + w_x=p->o.x;w_y=p->o.y-12+p->looky;W_draw();PL_drawst(p); +} +*/ +static void drawview(player_t *p) { + if(p->looky<-SCRH/4) p->looky=-SCRH/4; + else if(p->looky>SCRH/4) p->looky=SCRH/4; + w_x=p->o.x;w_y=p->o.y-12+p->looky; + W_draw(); + PL_drawst(p); +} + +static int get_pu_st(int t) { + if(t>=PL_FLASH) return 1; + if((t/9)&1) return 0; + return 1; +} + +static void pl_info(player_t *p,int y) { + dword t; + + t=p->kills*10920/g_time; + Z_gotoxy(25,y);Z_printbf("KILLS");//Z_gotoxy(25,y);Z_printbf("KILLS"); + Z_gotoxy(25,y+15);Z_printbf("KPM");//Z_gotoxy(25,y+15);Z_printbf("KPM"); + Z_gotoxy(25,y+30);Z_printbf("SECRETS %u / %u",p->secrets,sw_secrets);//Z_gotoxy(25,y+30);Z_printbf("SECRETS %u / %u",p->secrets,sw_secrets); + Z_gotoxy(255,y);Z_printbf("%u",p->kills);//Z_gotoxy(255,y);Z_printbf("%u",p->kills); + Z_gotoxy(255,y+15);Z_printbf("%u.%u",t/10,t%10);//Z_gotoxy(255,y+15);Z_printbf("%u.%u",t/10,t%10); +} + +void G_draw(void) { + int h; + word hr,mn,sc; + + if(g_trans && !transdraw) return; + switch(g_st) { + case GS_ENDANIM: case GS_END2ANIM: case GS_DARKEN: + case GS_BVIDEO: case GS_EVIDEO: case GS_END3ANIM: + return; + case GS_TITLE: + V_center(1);// + V_pic(0,0,scrnh[0]); + V_center(0);// + break; + case GS_ENDSCR: + V_center(1);// + V_clr(0,SCRW,0,SCRH,0);V_pic(0,0,scrnh[2]);//V_clr(0,320,0,200,0);V_pic(0,0,scrnh[2]); + V_center(0);// + break; + case GS_INTER: + V_center(1);// + V_clr(0,SCRW,0,SCRH,0);// + V_pic(0,0,scrnh[1]); + Z_gotoxy(60,20);Z_printbf("LEVEL COMPLETE"); + Z_calc_time(g_time,&hr,&mn,&sc); + Z_gotoxy(115,40);Z_printbf("TIME %u:%02u:%02u",hr,mn,sc); + h=60; + if(_2pl) { + Z_gotoxy(80,h);Z_printbf("PLAYER ONE"); + Z_gotoxy(80,h+70);Z_printbf("PLAYER TWO"); + h+=SCRH/10;//h+=20; + } + pl_info(&pl1,h); + if(_2pl) pl_info(&pl2,h+70); + V_center(0);// + break; + } + V_center(1);// + if(g_st!=GS_GAME) { + if(g_trans) return; + GM_draw(); + V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200); + return; + } + V_center(0);// + + if(_2pl) { + w_o=0;WD=SCRW-120;HT=SCRH/2-2;drawview(&pl1);//w_o=0;drawview(&pl1); + w_o=SCRH/2;WD=SCRW-120;HT=SCRH/2-2;drawview(&pl2);//w_o=100;drawview(&pl2); + }else{ + w_o=0;WD=SCRW-120;HT=SCRH-2;drawview(&pl1);//w_o=50;drawview(&pl1); + } + if(g_trans) return; + V_center(1);// + if(GM_draw()) { + pl1.drawst=pl2.drawst=0xFF;//pl1.drawst=pl2.drawst=0; + V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200); + return; + } + V_center(0);// + if(pl1.invl) h=get_pu_st(pl1.invl)*6; + else if(pl1.pain<15) h=0; + else if(pl1.pain<35) h=1; + else if(pl1.pain<55) h=2; + else if(pl1.pain<75) h=3; + else if(pl1.pain<95) h=4; + else h=5; + if(h) V_maptoscr(0,SCRW-120,1,(_2pl)?(SCRH/2-2):(SCRH-2),clrmap+h*256);//if(h) V_maptoscr(0,200,(_2pl)?1:51,98,clrmap+h*256); + else V_copytoscr(0,SCRW-120,1,(_2pl)?(SCRH/2-2):(SCRH-2)); //else V_copytoscr(0,200,(_2pl)?1:51,98); + if(pl1.drawst) V_copytoscr(SCRW-120,120,0,_2pl?(SCRH/2):SCRH);//if(pl1.drawst) V_copytoscr(200,120,(_2pl)?0:50,100); + pl1.drawst=0xFF;//pl1.drawst=0; + if(_2pl) { + if(pl2.invl) h=get_pu_st(pl2.invl)*6; + else if(pl2.pain<15) h=0; + else if(pl2.pain<35) h=1; + else if(pl2.pain<55) h=2; + else if(pl2.pain<75) h=3; + else if(pl2.pain<95) h=4; + else h=5; + if(h) V_maptoscr(0,SCRW-120,SCRH/2+1,SCRH/2-2,clrmap+h*256);//if(h) V_maptoscr(0,200,101,98,clrmap+h*256); + else V_copytoscr(0,SCRW-120,SCRH/2+1,SCRH/2-2);//else V_copytoscr(0,200,101,98); + if(pl2.drawst) V_copytoscr(SCRW-120,120,SCRH/2,SCRH/2);//if(pl2.drawst) V_copytoscr(200,120,100,100); + pl2.drawst=0xFF;//pl2.drawst=0; + } +} + +void G_respawn_player(player_t *p) { + int i; + + if(dm_pnum==2) { + if(p==&pl1) i=dm_pl1p^=1; + else i=dm_pl2p^=1; + p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d; + FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128); + return; + } + do{i=myrand(dm_pnum);}while(i==dm_pl1p || i==dm_pl2p); + p->o.x=dm_pos[i].x;p->o.y=dm_pos[i].y;p->d=dm_pos[i].d; + if(p==&pl1) dm_pl1p=i; else dm_pl2p=i; + FX_tfog(dm_pos[i].x,dm_pos[i].y);Z_sound(telepsnd,128); +} diff --git a/src/gamma.dat b/src/gamma.dat new file mode 100644 index 0000000..b40d111 --- /dev/null +++ b/src/gamma.dat @@ -0,0 +1,5 @@ +{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9, 9,11,12,13,14,15,16,16,18,18,19,20,22,23,24,25,26,26,28,29,29,31,32,33,33,35,36,37,38,38,39,41,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}, +{ 0, 2, 3, 5, 6, 8, 9,10,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,30,31,31,32,33,34,35,36,37,38,39,40,41,42,42,43,44,45,46,47,48,48,49,50,51,52,53,54,54,55,56,57,58,58,59,60,61,62,63}, +{ 0, 3, 6, 8,10,11,13,14,15,17,18,19,20,21,23,24,25,26,27,28,29,30,31,32,33,34,34,35,36,37,38,39,40,40,41,42,43,44,44,45,46,47,48,48,49,50,51,51,52,53,54,54,55,56,56,57,58,58,59,60,60,61,62,63}, +{ 0, 5, 8,11,13,14,16,17,19,20,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,37,38,39,40,41,42,42,43,44,45,45,46,47,47,48,49,49,50,51,51,52,53,53,54,55,55,56,57,57,58,58,59,60,60,61,61,62,63}, +{ 0, 7,11,13,15,17,19,20,22,23,25,26,27,28,29,30,31,32,33,34,35,36,37,38,38,39,40,41,41,42,43,44,44,45,46,46,47,48,48,49,50,50,51,52,52,53,53,54,54,55,56,56,57,57,58,58,59,59,60,60,61,61,62,63} diff --git a/src/glob.h b/src/glob.h new file mode 100644 index 0000000..771bb41 --- /dev/null +++ b/src/glob.h @@ -0,0 +1,71 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Globals + +#ifndef MYGLOB +#define MYGLOB + +#ifndef NULL +#define NULL 0 +#endif + +#define ON 1 +#define OFF 0 +#define TRUE 1 +#define FALSE 0 + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned int dword; + +void logo(const char *,...); +void logo_gas(int,int); + +extern int gammaa; +extern int snd_card; +extern int _cpu; + + +#define __MAX_PATH 255 +#define __MAX_DRIVE 50 +#define __MAX_DIR 100 +#define __MAX_FNAME 50 +#define __MAX_EXT 50 + + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + +#define myrand(a) (rand()%(a)) + +#include +void myfread(void *ptr, size_t n, size_t size, FILE *f); +size_t myfreadc(void *ptr, size_t n, size_t size, FILE *f); +void myfwrite(void *ptr, size_t n, size_t size, FILE *f); + +extern int SCRW; +extern int SCRH; + +#define DELAY 50 + +#endif diff --git a/src/items.c b/src/items.c new file mode 100644 index 0000000..5910fa5 --- /dev/null +++ b/src/items.c @@ -0,0 +1,270 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +//#include +#include +#include "vga.h" +#include "error.h" +#include "sound.h" +#include "files.h" +#include "view.h" +#include "items.h" +#include "fx.h" +#include "player.h" +#include "monster.h" +#include "things.h" +#include "misc.h" +#include "memory.h" +#include "map.h" + +extern map_block_t blk; + +#pragma pack(1) +typedef struct{ + obj_t o; + int t; + int s; +}item_t; +#pragma pack() + +static void *snd[4],*spr[58]; +static char sprd[58]; +static int tsndtm,rsndtm; +static item_t it[MAXITEM]; + +int itm_rtime=1092; + +void IT_savegame(FILE* h) { + int n; + + for(n=MAXITEM;--n;) if(it[n].t) break; + ++n;myfwrite(&n,1,4,h); + myfwrite(it,1,n*sizeof(it[0]),h); + myfwrite(&itm_rtime,1,4,h); +} + +void IT_loadgame(FILE* h) { + int n; + + myfread(&n,1,4,h); + myfread(it,1,n*sizeof(it[0]),h); + myfread(&itm_rtime,1,4,h); +} + +void IT_alloc(void) { + int i,j,n; + static char nm[][6]={ + "ITEMUP","WPNUP","GETPOW","ITMBK" + },snm[][4]={ + "CLIP","SHEL","ROCK","CELL","AMMO","SBOX","BROK","CELP", + "STIM","MEDI","BPAK", + "CSAW","SHOT","SGN2","MGUN","LAUN","PLAS","BFUG" + },n4[][4]={ + "SOUL","SMRT","SMGT","SMBT" + },n3[][4]={ + "GOR1","FCAN" + }; + +// logo(" items"); + for(i=0;i<18;++i) spr[i]=Z_getspr(snm[i],0,0,sprd+i); + for(;i<20;++i) { + spr[i]=Z_getspr("ARM1",i-18,0,sprd+i); + spr[i+2]=Z_getspr("ARM2",i-18,0,sprd+i); + }i+=2; + for(;i<26;++i) spr[i]=Z_getspr("MEGA",i-22,0,sprd+i); + for(;i<30;++i) spr[i]=Z_getspr("PINV",i-26,0,sprd+i); + spr[30]=Z_getspr("AQUA",0,0,sprd+30); + spr[31]=Z_getspr("KEYR",0,0,sprd+31); + spr[32]=Z_getspr("KEYG",0,0,sprd+32); + spr[33]=Z_getspr("KEYB",0,0,sprd+33); + spr[34]=Z_getspr("SUIT",0,0,sprd+34); + for(n=35,j=0;j<4;++j) + for(i=0;i<4;++i,++n) spr[n]=Z_getspr(n4[j],i,0,sprd+n); + for(j=0;j<2;++j) + for(i=0;i<3;++i,++n) spr[n]=Z_getspr(n3[j],i,0,sprd+n); + spr[57]=Z_getspr("GUN2",0,0,sprd+57); + for(i=0;i<4;++i) snd[i]=Z_getsnd(nm[i]); + for(i=0;i0;++i,blk.sz-=8) { + myfread(&t,1,sizeof(t),h); + it[i].o.x=t.x;it[i].o.y=t.y; + it[i].t=t.t;it[i].s=t.f; + if(!it[i].t) break; + if((it[i].s&THF_DM) && !g_dm) it[i].t=0; + }m=i; + for(i=0,j=-1;i=TH_CLIP && it[i].t=I_KEYR && it[i].t<=I_KEYB) it[i].t|=0x8000; + }else if(it[i].t>=TH_DEMON) { + MN_spawn(it[i].o.x,it[i].o.y,it[i].s&THF_DIR,it[i].t-TH_DEMON+MN_DEMON); + it[i].t=0; + } + return 1; + }return 0; +} + +static void takesnd(int t) { + if(tsndtm) return; + t&=0x7FFF; + if(t<=I_CELP || (t>=I_BPACK && t<=I_BFG) || t==I_GUN2) + {tsndtm=Z_sound(snd[1],128);return;} + if(t==I_MEGA || t==I_INVL || t==I_SUPER) + {tsndtm=Z_sound(snd[2],192);return;} + tsndtm=Z_sound(snd[0],256); +} + +void IT_act(void) { + int i,j; + + if(tsndtm) --tsndtm; + if(rsndtm) --rsndtm; + for(i=0;i=18) it[i].s=0; break; + case I_MEGA: case I_INVL: + case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH: + if(++it[i].s>=8) it[i].s=0; break; + case I_GOR1: case I_FCAN: + if(++it[i].s>=6) it[i].s=0; break; + } + if(it[i].t&0x8000) { + if((j=Z_moveobj(&it[i].o))&Z_FALLOUT) {it[i].t=0;continue;} + else if(j&Z_HITWATER) Z_splash(&it[i].o,it[i].o.r+it[i].o.h); + } + if(Z_overlap(&it[i].o,&pl1.o)) + if(PL_give(&pl1,it[i].t&0x7FFF)) { + takesnd(it[i].t); + if(_2pl) if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue; + if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0; + continue; + } + if(_2pl) if(Z_overlap(&it[i].o,&pl2.o)) + if(PL_give(&pl2,it[i].t&0x7FFF)) { + takesnd(it[i].t); + if((it[i].t&0x7FFF)>=I_KEYR && (it[i].t&0x7FFF)<=I_KEYB) continue; + if(!(it[i].s=-itm_rtime) || (it[i].t&0x8000)) it[i].t=0; + continue; + } + } +} + +void IT_draw(void) { + int i,s; + + for(i=0;i=0) switch(it[i].t&0x7FFF) { + case I_ARM1: + s=it[i].s/9+18;break; + case I_ARM2: + s=it[i].s/9+20;break; + case I_MEGA: + s=it[i].s/2+22;break; + case I_INVL: + s=it[i].s/2+26;break; + case I_SUPER: case I_RTORCH: case I_GTORCH: case I_BTORCH: + s=it[i].s/2+(it[i].t-I_SUPER)*4+35;break; + case I_GOR1: case I_FCAN: + s=it[i].s/2+(it[i].t-I_GOR1)*3+51;break; + case I_AQUA: s=30;break; + case I_SUIT: s=34;break; + case I_KEYR: case I_KEYG: case I_KEYB: + s=(it[i].t&0x7FFF)-I_KEYR+31;break; + case I_GUN2: s=57;break; + default: + s=(it[i].t&0x7FFF)-1; + } + if(s>=0) Z_drawspr(it[i].o.x,it[i].o.y,spr[s],sprd[s]); + } +} + +void IT_spawn(int x,int y,int t) { + int i; + + for(i=0;i=a;n-=a) + IT_spawn(x+myrand(3*2+1)-3,y-myrand(7),t); + if(t>=I_AMMO) {t-=4;goto again;} +} diff --git a/src/items.h b/src/items.h new file mode 100644 index 0000000..1c4d184 --- /dev/null +++ b/src/items.h @@ -0,0 +1,52 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Items + +#include + +#define MAXITEM 300 + +enum{I_NONE,I_CLIP,I_SHEL,I_ROCKET,I_CELL,I_AMMO,I_SBOX,I_RBOX,I_CELP, + I_STIM,I_MEDI,I_BPACK,I_CSAW,I_SGUN,I_SGUN2,I_MGUN,I_LAUN,I_PLAS,I_BFG, + I_ARM1,I_ARM2,I_MEGA,I_INVL,I_AQUA,I_KEYR,I_KEYG,I_KEYB,I_SUIT,I_SUPER, + I_RTORCH,I_GTORCH,I_BTORCH,I_GOR1,I_FCAN,I_GUN2 +}; + +void IT_init(void); +void IT_alloc(void); +int IT_load(FILE*); +void IT_act(void); +void IT_draw(void); +void IT_spawn(int x,int y,int i); +void IT_drop_ammo(int i,int n,int x,int y); + +#pragma pack(1) +typedef struct{ + short x; + short y; + short t; + word f; +}thing_t; +#pragma pack() + +extern int itm_rtime; diff --git a/src/keyb.c b/src/keyb.c new file mode 100644 index 0000000..d287b16 --- /dev/null +++ b/src/keyb.c @@ -0,0 +1,65 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "keyb.h" +#include + +// стандартная функция обработки клавиш +key_f def_key_proc; + +// массив клавиш: 0 - отпущена, иначе - нажата +unsigned char *keys = NULL; + +static key_f *key_proc = NULL; + + +void K_init() +{ + keys = SDL_GetKeyState(NULL); +} + +void K_done() +{ + +} +// установить функцию обработки клавиш + void K_setkeyproc(key_f *k) +{ + key_proc = k; +} + +void updatee_keys() +{ + SDL_Event event; + while (SDL_PollEvent (&event)) { + if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN && event.key.keysym.mod & KMOD_LALT) { + V_toggle(); + } + else if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { + if (event.type == SDL_KEYDOWN && key_proc!=NULL) + key_proc(event.key.keysym.sym, event.type == SDL_KEYDOWN); + } + else if (event.type == SDL_QUIT) { + ERR_quit(); + } + } +} diff --git a/src/keyb.h b/src/keyb.h new file mode 100644 index 0000000..0684fc5 --- /dev/null +++ b/src/keyb.h @@ -0,0 +1,51 @@ +/* + Драйвер клавиатуры V1.1 для DOS4GW (а также DirectX 3) + Copyright (C) Алексей Волынсков, 1996 + + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MYKEYB +#define MYKEYB + +#ifdef __cplusplus +extern "C" { +#endif + +void K_init(); +void K_done(); + +// тип функции обработки клавиш +typedef void key_f(int k,int pressed); + +// установить функцию обработки клавиш +void K_setkeyproc(key_f *); + +// массив клавиш: 0 - отпущена, иначе - нажата +extern unsigned char *keys; + +void updatee_keys(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..54b2af6 --- /dev/null +++ b/src/main.c @@ -0,0 +1,156 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +///#include +#include +///#include +#include +///#include +#include +#include +#include +#include "error.h" +#include "config.h" +#include "memory.h" +#include "keyb.h" +#include "sound.h" +#include "vga.h" +#include "files.h" +#include "view.h" +#include "menu.h" +#include "player.h" +#include "misc.h" + +#include + +int gammaa=0; + +char main_pal[256][3],std_pal[256][3]; +byte mixmap[256][256]; +byte clrmap[256*12]; + +void logo(const char *s,...) { + va_list ap; + int x,y; + + va_start(ap,s); + vprintf(s,ap); + va_end(ap); + fflush(stdout); +} + +void logo_gas(int cur,int all) { +} + +byte gamcor[5][64]={ + #include "gamma.dat" +}; + +void setgamma(int g) { + int t; + + if(g>4) g=4; + if(g<0) g=0; + gammaa=g; + for(t=0;t<256;++t) { + std_pal[t][0]=gamcor[gammaa][main_pal[t][0]]; + std_pal[t][1]=gamcor[gammaa][main_pal[t][1]]; + std_pal[t][2]=gamcor[gammaa][main_pal[t][2]]; + } + VP_setall(std_pal); +} + +void myrandomize(void); + +byte bright[256]; + +int main(int argc, char *argv[]) { + if (SDL_Init(SDL_INIT_VIDEO)<0) ERR_failinit("Unable to init SDL: %s\n", SDL_GetError()); + SDL_WM_SetCaption("Doom 2D v1.351", "Doom 2D"); + int i; + + pl1.ku=SDLK_KP8; + pl1.kd=SDLK_KP5; + pl1.kl=SDLK_KP4; + pl1.kr=SDLK_KP6; + pl1.kf=SDLK_PAGEDOWN; + pl1.kj=SDLK_DELETE; + pl1.kwl=SDLK_HOME; + pl1.kwr=SDLK_END; + pl1.kp=SDLK_KP8; + pl1.id=-1; + pl2.ku=SDLK_e; + pl2.kd=SDLK_d; + pl2.kl=SDLK_s; + pl2.kr=SDLK_f; + pl2.kf=SDLK_a; + pl2.kj=SDLK_q; + pl2.kwl=SDLK_1; + pl2.kwr=SDLK_2; + pl2.kp=SDLK_e; + pl2.id=-2; + myrandomize(); + F_startup(); + F_addwad("doom2d.wad"); + CFG_args(argc, argv); + CFG_load(); + F_initwads(); + M_startup(); + F_allocres(); + F_loadres(F_getresid("PLAYPAL"),main_pal,0,768); + for(i=0;i<256;++i) + bright[i]=((int)main_pal[i][0]+main_pal[i][1]+main_pal[i][2])*8/(63*3); + F_loadres(F_getresid("MIXMAP"),mixmap,0,0x10000); + F_loadres(F_getresid("COLORMAP"),clrmap,0,256*12); + G_init(); + K_init(); + logo("S_init: настройка звука\n"); + S_init(); + S_initmusic(); + logo("V_init: настройка видео\n"); + if(V_init()!=0) ERR_failinit("Не могу установить видеорежим VGA"); + setgamma(gammaa); + V_setscr(scrbuf); + GM_init(); + F_loadmus("MENU");S_startmusic(0); + + Uint32 ticks = 0; + for(;;) { + + updatee_keys(); + + S_updatemusic(); + + G_act(); + + G_draw(); + + Uint32 t; + while ((t = SDL_GetTicks())-ticks < DELAY) { + SDL_Delay(1); + } + ticks = t - t % DELAY; + + } +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..05d1816 --- /dev/null +++ b/src/map.h @@ -0,0 +1,177 @@ +/**************************************************************************\ +* * +* Форматы карт Doom'а 2D Версия 2 * +* * +* Prikol Software 10.VII.1996 * +* * +* Разрешается свободно распространять этот файл, при условии сохранения * +* ссылки на Prikol Software, версии и даты выпуска файла. * +* * +* Этот include-файл расчитан на WATCOM C 10.0 и DOS4GW * +* Вы можете переделать его на любой другой язык/компилятор, но сохраните * +* этот файл (если собираетесь его распространять), а в своем укажите, * +* что он изменен (переделан). * +* * +\**************************************************************************/ + +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma pack(1) + +/* Старый формат - версия 1.04 alpha (и раньше) + + названия текстур (old_wall_t) + кончается пустой строкой (old_wall_t.n[0]==0) + + фон - массив 100x100 байт - номера текстур + + тип стенок - массив 100x100 байт: + 0 - пусто + 1 - стена + 2 - закрытая дверь + 3 - открытая дверь + 4 - ступенька + + передний план - массив 100x100 байт - номера текстур + + вещи, монстры и др. (old_thing_t) + кончается нулевым типом (old_thing_t.t==0) + + переключатели (old_switch_t) + кончается нулевым типом (old_switch_t.t==0) + +*/ + +typedef struct{ + char n[8]; // название текстуры + char t; // тип: 0-сплошная 1-"решётка" +}old_wall_t; + +typedef struct{ + short x,y; // координаты + short t; // тип + unsigned short f; // флаги +}old_thing_t; + +typedef struct{ + unsigned char x,y; // координаты/8 + unsigned char t; // тип + unsigned char tm; // должно быть 0 + unsigned char a,b; // обычно - координаты/8 двери + unsigned short c; // не используется (вроде бы) +}old_switch_t; + +/* Новый формат - начиная с версии 1.05 alpha + + заголовок карты (map_header_t) + + блоки (map_block_t) + кончается блоком MB_END (map_block_t.t==MB_END) + +*/ + +typedef struct{ + char id[8]; // "подпись" - "Doom2D\x1A" + short ver; // версия карты +}map_header_t; + +typedef struct{ + short t; // тип блока + short st; // подтип (метод упаковки, например) + // если не используется, то должен быть 0 + // (для будущей совместимости) + int sz; // размер (сколько байт после этой структуры) +}map_block_t; + +enum{ + MB_COMMENT=-1,MB_END=0, + MB_WALLNAMES,MB_BACK,MB_WTYPE,MB_FRONT,MB_THING,MB_SWITCH, + MB_MUSIC,MB_SKY, + MB_SWITCH2, + MB__UNKNOWN +}; + +/* Версия 0 (Doom2D версии 1.05 alpha) + + MB_COMMENT - комментарий + + MB_WALLNAMES - названия текстур (см. старую версию) + количество - по размеру блока + + MB_BACK,MB_WTYPE,MB_FRONT - фон,тип,передний план (см. старую версию) + подтип 0 - без упаковки (как в старой версии) + + MB_THING - вещи,монстры и др. (см. старую версию) + количество - по размеру блока + + MB_SWITCH - переключатели (см. старую версию) + количество - по размеру блока + +*/ + +/* Версия 1 (Doom2D версии 1.06 alpha) + + MB_WALLNAMES + добавлены псевдо-текстуры _WATER_* + где * это 0=вода,1=кислота,2=кровь + + MB_WTYPE + добавлен новый тип 5 - вода + + MB_MUSIC - новый блок - название музыки (8 байт) + + MB_SKY - новый блок - тип неба (2 байта - short) + 1 = облака + 2 = город + 3 = ад + +*/ + +#define SW_PL_PRESS 1 +#define SW_MN_PRESS 2 +#define SW_PL_NEAR 4 +#define SW_MN_NEAR 8 +#define SW_KEY_R 16 +#define SW_KEY_G 32 +#define SW_KEY_B 64 + +typedef struct{ + unsigned char x,y; // координаты/8 + unsigned char t; // тип + unsigned char tm; // должно быть 0 + unsigned char a,b; // обычно - координаты/8 двери + unsigned short c; // не используется (вроде бы) + unsigned char f; // флаги +}switch2_t; + +/* Версия 2 (Doom2D версии 1.17 alpha) + + блок MB_SWITCH заменен на MB_SWITCH2 (см. switch2_t) + +*/ + +#define LAST_MAP_VER 2 // Самая последняя версия карты + +#pragma pack() + +/* КОНЕЦ */ diff --git a/src/megadm.wad b/src/megadm.wad new file mode 100644 index 0000000..1487699 Binary files /dev/null and b/src/megadm.wad differ diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..23e5cbd --- /dev/null +++ b/src/memory.c @@ -0,0 +1,94 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +#include +#include "error.h" +#include "files.h" +#include "memory.h" + +dword dpmi_memavl(void); + +extern int d_start,d_end; + +extern mwad_t wad[]; + +static byte m_active=FALSE; + +static void *resp[MAX_WAD]; +static short resl[MAX_WAD]; + +void M_startup(void) { + if(m_active) return; + logo("M_startup: настройка памяти\n"); + memset(resp,0,sizeof(resp)); + memset(resl,0,sizeof(resl)); + // logo(" свободно DPMI-памяти: %uK\n",dpmi_memavl()>>10); + m_active=TRUE; +} + +void M_shutdown(void) { + + if(!m_active) return; + m_active=FALSE; +} + +static void allocres(int h) { + int *p,s; + + if(h>d_start && h=MAX_WAD) ERR_fatal("M_lock: странный номер ресурса"); + if(!resl[h]) if(!resp[h]) allocres(h); + ++resl[h]; + return resp[h]; +} + +void M_unlock(void *p) { + int h; + + if(!p) return; + h=((int*)p)[-1]; + if(h>=MAX_WAD) ERR_fatal("M_unlock: странный номер ресурса"); + if(!resl[h]) return; + --resl[h]; +} diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 0000000..121490b --- /dev/null +++ b/src/memory.h @@ -0,0 +1,28 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// High-level memory allocation + +void M_startup(void); +void M_shutdown(void); +void *M_lock(int); +void M_unlock(void *); diff --git a/src/menu.c b/src/menu.c new file mode 100644 index 0000000..baada01 --- /dev/null +++ b/src/menu.c @@ -0,0 +1,632 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +#include "files.h" +#include "memory.h" +#include "vga.h" +#include "error.h" +#include "keyb.h" +#include "sound.h" +#include "view.h" +#include "player.h" +#include "switch.h" +#include "menu.h" +#include "misc.h" + +#include "SDL.h" +extern SDL_Surface *screen; + +#define QSND_NUM 14 + +enum{HIT100,ARMOR,JUMP,WPNS,IMMORTAL,SPEED,OPEN,EXIT}; + +extern int PL_JUMP,PL_RUN; +extern byte _warp,cheat,p_fly; + +extern byte g_music[8]; + +extern byte savname[7][24],savok[7]; +void load_game(int); + +static byte panim[]= + "BBDDAACCDDAABBDDAACCDDAABBDDAACCDDAAEEEEEFEFEFEFEFEFEFEFEFEFEEEEE"; +static byte *panimp=panim; + +#define PCOLORN 10 +byte pcolortab[PCOLORN]={ + 0x18,0x20,0x40,0x58,0x60,0x70,0x80,0xB0,0xC0,0xD0 +}; +int p1color=5,p2color=4; + +static byte ibuf[24],input=0; +static int icur; + +enum{MENU,MSG}; +enum{CANCEL,NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME,QUIT,ENDGAME,ENDGM, + PLR1,PLR2,COOP,DM,VOLUME,GAMMA,LOAD,SAVE,PLCOLOR,PLCEND,MUSIC,INTERP, + SVOLM,SVOLP,MVOLM,MVOLP,GAMMAM,GAMMAP,PL1CM,PL1CP,PL2CM,PL2CP}; + +#ifndef DEMO +static int qsnd[QSND_NUM]; +#endif + +static char *main_txt[]={ + "NEW GAME","LOAD GAME","SAVE GAME","OPTIONS","EXIT" +},*opt_txt[]={ + "RESTART","VOLUME","BRIGHTNESS","MUSIC","FULLSCREEN:" +},*ngplr_txt[]={ + "ONE PLAYER","TWO PLAYERS" +},*ngdm_txt[]={ + "COOPERATIVE","DEATHMATCH" +},*vol_txt[]={ + "SOUND","MUSIC" +},*plcolor_txt[]={ + "FIRST","SECOND" +},*gamma_txt[]={ + "" +}; + +static byte main_typ[]={ + NEWGAME,LOADGAME,SAVEGAME,OPTIONS,QUITGAME +},ngplr_typ[]={ + PLR1,PLR2 +},ngdm_typ[]={ + COOP,DM +},opt_typ[]={ + ENDGAME,VOLUME,GAMMA,MUSIC,INTERP +},quit_typ[]={ + QUIT,CANCEL +},endgm_typ[]={ + ENDGM,CANCEL +},vol_typ[]={ + SVOLM,MVOLM +},plcolor_typ[]={ + PL1CM,PL2CM +},gamma_typ[]={ + GAMMAM +},load_typ[]={ + LOAD,LOAD,LOAD,LOAD,LOAD,LOAD,LOAD +},save_typ[]={ + SAVE,SAVE,SAVE,SAVE,SAVE,SAVE,SAVE +}; + +static menu_t main_mnu={ + MENU,5,0,80,"MENU",main_txt,main_typ +},opt_mnu={ + MENU,5,0,75,"OPTIONS",opt_txt,opt_typ +},ngplr_mnu={ + MENU,2,0,90,"NEW GAME",ngplr_txt,ngplr_typ +},ngdm_mnu={ + MENU,2,0,90,"GAME TYPE",ngdm_txt,ngdm_typ +},vol_mnu={ + MENU,2,0,40,"VOLUME",vol_txt,vol_typ +},plcolor_mnu={ + MENU,2,0,90,"COLOR",plcolor_txt,plcolor_typ +},gamma_mnu={ + MENU,1,0,85,"BRIGHTNESS",gamma_txt,gamma_typ +},load_mnu={ + MENU,7,0,85,"LOAD GAME",NULL,load_typ +},save_mnu={ + MENU,7,0,85,"SAVE GAME",NULL,save_typ +},quit1_msg={ + MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ +},quit2_msg={ + MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ +},quit3_msg={ + MSG,0,0,0,"ARE YOU SURE?",NULL,quit_typ +},endgm_msg={ + MSG,0,0,0,"RESTART LEVEL?",NULL,endgm_typ +}; + +static menu_t *qmsg[3]={&quit1_msg,&quit2_msg,&quit3_msg}; + +static menu_t *mnu=NULL; + +static byte gm_redraw=0; +static int gm_tm=0; +short lastkey=0; +static void *csnd1,*csnd2,*msnd1,*msnd2,*msnd3,*msnd4,*msnd5,*msnd6; +static int movsndt=0; +static vgaimg *msklh[2],*mbarl,*mbarm,*mbarr,*mbaro,*mslotl,*mslotm,*mslotr; +static byte cbuf[32]; + +static snd_t *voc=NULL; +static int voc_ch=0; + +void GMV_stop(void) { + if(voc) { + if(voc_ch) {S_stop(voc_ch);voc_ch=0;} + free(voc);voc=NULL; + } +} + +void GMV_say(char *nm) { + int r,len; + snd_t *p; + byte *d; + + if((r=F_findres(nm))==-1) return; + if(!(p=malloc((len=F_getreslen(r))+16))) return; + p->len=len;p->rate=11000; + p->lstart=p->llen=0; + GMV_stop(); + F_loadres(r,p+1,0,len); + for(d=(byte*)(p+1);len;--len,++d) *d^=128; + voc=p; + voc_ch=S_play(voc,-1,1024,255); +} + +void G_code(void) { + void *s; + s=csnd2; + if(memcmp(cbuf+32-5,"IDDQD",5)==0) { + PL_hit(&pl1,400,0,HIT_SOME); + if(_2pl) PL_hit(&pl2,400,0,HIT_SOME); + s=csnd1; + }else if(memcmp(cbuf+32-4,"TANK",4)==0) { + pl1.life=pl1.armor=200;pl1.drawst|=PL_DRAWARMOR|PL_DRAWLIFE; + if(_2pl) {pl2.life=pl2.armor=200;pl2.drawst|=PL_DRAWARMOR|PL_DRAWLIFE;} + }else if(memcmp(cbuf+32-8,"BULLFROG",8)==0) { + PL_JUMP=(PL_JUMP==10)?20:10; + }else if(memcmp(cbuf+32-8,"FORMULA1",8)==0) { + PL_RUN=(PL_RUN==8)?24:8; + }else if(memcmp(cbuf+32-5,"RAMBO",5)==0) { + pl1.ammo=pl1.shel=pl1.rock=pl1.cell=pl1.fuel=30000; + pl1.wpns=0x7FF;pl1.drawst|=PL_DRAWWPN|PL_DRAWKEYS; + pl1.keys=0x70; + if(_2pl) { + pl2.ammo=pl2.shel=pl2.rock=pl2.cell=pl1.fuel=30000; + pl2.wpns=0x7FF;pl2.drawst|=PL_DRAWWPN|PL_DRAWKEYS; + pl2.keys=0x70; + } + }else if(memcmp(cbuf+32-5,"UJHTW",5)==0) { + p_immortal=!p_immortal; + }else if(memcmp(cbuf+32-9,",TKSQJHTK",9)==0) { + p_fly=!p_fly; + }else if(memcmp(cbuf+32-6,"CBVCBV",6)==0) { + SW_cheat_open(); + }else if(memcmp(cbuf+32-7,"GOODBYE",7)==0) { + g_exit=1; + }else if(memcmp(cbuf+32-9,"GJITKYF",7)==0) { + if(cbuf[30]>='0' && cbuf[30]<='9' && cbuf[31]>='0' && cbuf[31]<='9') { + g_map=(cbuf[30]=='0')?0:(cbuf[30]-'0')*10; + g_map+=(cbuf[31]=='0')?0:(cbuf[31]-'0'); + G_start(); + } + }else return; + memset(cbuf,0,32); + Z_sound(s,128); +} + +void GM_set(menu_t *m) { + mnu=m;gm_redraw=1; + if(g_st==GS_GAME) { + //V_setrect(0,SCRW,0,SCRH);V_clr(0,SCRW,0,SCRH,0);//V_setrect(0,320,0,200);V_clr(0,320,0,200,0); + //if(_2pl) {V_setrect(SCRW-120,120,0,SCRH);w_o=0;Z_clrst();w_o=SCRH/2;Z_clrst();}//if(_2pl) {V_setrect(200,120,0,200);w_o=0;Z_clrst();w_o=100;Z_clrst();} + //else {V_setrect(SCRW-120,120,0,SCRH);w_o=0;Z_clrst();}//else {V_setrect(200,120,50,100);w_o=50;Z_clrst();} + //pl1.drawst=pl2.drawst=0xFF;V_setrect(0,SCRW,0,SCRH);//V_setrect(0,320,0,200); + } +} + +void setgamma(int); + +void GM_command(int c) { + switch(c) { + case CANCEL: + GM_set(NULL);break; + case INTERP: + fullscreen=!fullscreen; + V_toggle(); + GM_set(mnu); + break; + case MUSIC: + F_freemus(); + F_nextmus(g_music); + F_loadmus(g_music); + S_startmusic(music_time*2); + GM_set(mnu); + break; + case NEWGAME: + GMV_say("_NEWGAME"); + GM_set(&ngplr_mnu);break; + case PLR2: + GMV_say("_2PLAYER"); + GM_set(&ngdm_mnu);break; + case PLR1: + GMV_say("_1PLAYER"); + ngdm_mnu.cur=0; + case COOP: case DM: + if(c==COOP) GMV_say("_COOP"); + else if(c==DM) GMV_say("_DM"); + if(c!=PLR1) {GM_set(&plcolor_mnu);break;} + case PLCEND: + _2pl=ngplr_mnu.cur; + g_dm=ngdm_mnu.cur; + g_map=(_warp)?_warp:1; + PL_reset(); + if(_2pl) { + pl1.color=pcolortab[p1color]; + pl2.color=pcolortab[p2color]; + }else pl1.color=0x70; + G_start(); + GM_set(NULL);break; + case OPTIONS: + GMV_say("_RAZNOE"); + GM_set(&opt_mnu);break; + case LOADGAME: + GMV_say("_OLDGAME"); + F_getsavnames();GM_set(&load_mnu);break; + case SAVEGAME: + if(g_st!=GS_GAME) break; + GMV_say("_SAVEGAM"); + F_getsavnames();GM_set(&save_mnu);break; + case SAVE: + input=1;memcpy(ibuf,savname[save_mnu.cur],24);icur=strlen(ibuf); + GM_set(mnu);break; + case LOAD: + if(!savok[load_mnu.cur]) break; + load_game(load_mnu.cur); + GM_set(NULL);break; + case VOLUME: + GMV_say("_VOLUME"); + GM_set(&vol_mnu);break; + case GAMMA: + GMV_say("_GAMMA"); + GM_set(&gamma_mnu);break; + case QUITGAME: + GMV_say((rand()&1)?"_EXIT1":"_EXIT2"); + GM_set(qmsg[myrand(3)]);break; + case ENDGAME: + if(g_st!=GS_GAME) break; + GMV_say("_RESTART"); + GM_set(&endgm_msg);break; + case QUIT: + F_freemus(); + GMV_stop(); +#ifndef DEMO + c=Z_sound(M_lock(qsnd[myrand(QSND_NUM)]),256);//for(c=(Z_sound(M_lock(qsnd[random2(QSND_NUM)]),256)+9)<<16,timer=0;timer=PCOLORN) p1color=0; break; + case PL2CM: + if(--p2color<0) p2color=PCOLORN-1; break; + case PL2CP: + if(++p2color>=PCOLORN) p2color=0; break; + case SVOLM: + S_volume(snd_vol-8);break; + case SVOLP: + S_volume(snd_vol+8);break; + case MVOLM: + S_volumemusic(mus_vol-8);break; + case MVOLP: + S_volumemusic(mus_vol+8);break; + case GAMMAM: setgamma(gammaa-1);break; + case GAMMAP: setgamma(gammaa+1);break; + } +} + +/* +byte keychar[2][128]={{ + 0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0, + 'Q','W','E','R','T','Y','U','I','O','P','[',']','\r',0,'A','S', + 'D','F','G','H','J','K','L',';','\'',0,0,'\\','Z','X','C','V', + 'B','N','M',',','.','/',0,'*',0,' ',0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +},{ + 0,0,'!','\"','#','$','%',':','&','*','(',')','_','+',0,0, + 'x','x','x','x','x','x','x','x','x','x','x','x','\r',0,'x','x', + 'x','x','x','x','x','x','x','x','x',0,0,0,'x','x','x','x', + 'x','x','x','x','x','?',0,'*',0,' ',0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}}; +*/ + +struct { + int keysym; + byte ch; +} keychar[] = { + {SDLK_SPACE, ' '}, + {SDLK_0, '0'}, + {SDLK_1, '1'}, + {SDLK_2, '2'}, + {SDLK_3, '3'}, + {SDLK_4, '4'}, + {SDLK_5, '5'}, + {SDLK_6, '6'}, + {SDLK_7, '7'}, + {SDLK_8, '8'}, + {SDLK_9, '9'}, + {SDLK_UNDERSCORE, '_'}, + {SDLK_a, 'A'}, + {SDLK_b, 'B'}, + {SDLK_c, 'C'}, + {SDLK_d, 'D'}, + {SDLK_e, 'E'}, + {SDLK_f, 'F'}, + {SDLK_g, 'G'}, + {SDLK_h, 'H'}, + {SDLK_i, 'I'}, + {SDLK_j, 'J'}, + {SDLK_k, 'K'}, + {SDLK_l, 'L'}, + {SDLK_m, 'M'}, + {SDLK_n, 'N'}, + {SDLK_o, 'O'}, + {SDLK_p, 'P'}, + {SDLK_q, 'Q'}, + {SDLK_r, 'R'}, + {SDLK_s, 'S'}, + {SDLK_t, 'T'}, + {SDLK_u, 'U'}, + {SDLK_v, 'V'}, + {SDLK_w, 'W'}, + {SDLK_x, 'X'}, + {SDLK_y, 'Y'}, + {SDLK_z, 'Z'}, + {SDLK_COMMA,','}, + {0} +}; + +byte get_keychar(int keysym) +{ + int i = 0; + while (keychar[i].keysym) { + if (keychar[i].keysym == keysym) return keychar[i].ch; + i++; + } + return 0; +} + +extern vgapal main_pal,std_pal; +extern byte shot_vga; + +static void shot(void) { + static int num=1; + char fn[13]; + sprintf(fn,"shot%04d.bmp",num); + SDL_SaveBMP(screen, fn); + ++num; +} + +int GM_act(void) { + byte c; + + if(mnu==&plcolor_mnu) { + if(*(++panimp)==0) panimp=panim; + GM_set(mnu); + } + if(movsndt>0) --movsndt; else movsndt=0; + if(g_st==GS_TITLE) if(!mnu) if(lastkey) { + GM_set(&main_mnu);Z_sound(msnd3,128); + lastkey=0; + return 1; + } + if(input) switch(lastkey) { + case SDLK_RETURN: case SDLK_KP_ENTER://case 0x1C: case 0x9C: + F_savegame(save_mnu.cur,ibuf); + input=0;GM_set(NULL);break; + case 1: input=0;GM_set(mnu);break; + case SDLK_BACKSPACE://case 0x0E: + if(icur) {ibuf[--icur]=0;GM_set(mnu);} break; + default: + if(icur>=23) break; + c=get_keychar(lastkey);//c=keychar[(keys[0x2A] || keys[0x36])?1:0][lastkey]; + if(!c) break; + ibuf[icur]=c;ibuf[++icur]=0;GM_set(mnu); + }else { + switch(lastkey) { + case SDLK_ESCAPE://case 1: + if(!mnu) {GM_set(&main_mnu);Z_sound(msnd3,128);} + else {GM_set(NULL);Z_sound(msnd4,128);} + break; + case SDLK_F5: + if(mnu) break; + Z_sound(msnd3,128); + GMV_say("_GAMMA"); + GM_set(&gamma_mnu);break; + case SDLK_F4://case 0x3E: + if(mnu) break; + Z_sound(msnd3,128); + GMV_say("_VOLUME"); + GM_set(&vol_mnu);break; + case SDLK_F2://case 0x3C: + if(mnu) break; + if(g_st!=GS_GAME) break; + Z_sound(msnd3,128); + F_getsavnames();GM_set(&save_mnu);break; + case SDLK_F3://case 0x3D: + if(mnu) break; + Z_sound(msnd3,128); + F_getsavnames();GM_set(&load_mnu);break; + case SDLK_F10://case 0x44: + if(mnu) break; + Z_sound(msnd3,128); + GM_command(QUITGAME);break; + case SDLK_UP: case SDLK_KP8://case 0x48: case 0xC8: + if(!mnu) break; + if(mnu->type!=MENU) break; + if(--mnu->cur<0) mnu->cur=mnu->n-1; + GM_set(mnu); + Z_sound(msnd1,128);break; + case SDLK_DOWN: case SDLK_KP5: case SDLK_KP2://case 0x50: case 0xD0: case 0x4C: + if(!mnu) break; + if(mnu->type!=MENU) break; + if(++mnu->cur>=mnu->n) mnu->cur=0; + GM_set(mnu); + Z_sound(msnd1,128);break; + case SDLK_LEFT: case SDLK_RIGHT: case SDLK_KP4: case SDLK_KP6://case 0x4B: case 0x4D: case 0xCB: case 0xCD: + if(!mnu) break; + if(mnu->type!=MENU) break; + if(mnu->t[mnu->cur]t[mnu->cur]+((lastkey==SDLK_LEFT || lastkey==SDLK_KP4)?0:1));//GM_command(mnu->t[mnu->cur]+((lastkey==0x4B || lastkey==0xCB)?0:1)); + GM_set(mnu); + if(!movsndt) movsndt=Z_sound((lastkey==SDLK_LEFT || lastkey==SDLK_KP4)?msnd5:msnd6,255);//if(!movsndt) movsndt=Z_sound((lastkey==0x4B || lastkey==0xCB)?msnd5:msnd6,255); + break; + case SDLK_RETURN: case SDLK_SPACE: case SDLK_KP_ENTER://case 0x1C: case 0x39: case 0x9C: + if(!mnu) break; + if(mnu->type!=MENU) break; + if(mnu->t[mnu->cur]>=PL1CM) { + Z_sound(msnd2,128); + GM_command(PLCEND); + break; + } + if(mnu->t[mnu->cur]>=SVOLM) break; + Z_sound(msnd2,128); + GM_command(mnu->t[mnu->cur]); + break; + case SDLK_y://case 0x15: + if(!mnu) break; + if(mnu->type!=MSG) break; + Z_sound(msnd3,128); + GM_command(mnu->t[0]); + break; + case SDLK_n://case 0x31: + if(!mnu) break; + if(mnu->type!=MSG) break; + Z_sound(msnd4,128); + GM_command(mnu->t[1]); + break; + case SDLK_F1://case 0x3B: + if(shot_vga) {shot();Z_sound(msnd4,128);} + break; + } + } + lastkey=0; + return((mnu)?1:0); +} + +void G_keyf(int k, int press) { + int i; + + lastkey=k; + if(!_2pl || cheat) { + for(i=0;i<31;++i) cbuf[i]=cbuf[i+1]; + cbuf[31]=get_keychar(k); + } +} + +void GM_init(void) { +#ifndef DEMO + int i; + static char nm[QSND_NUM][6]={ + "CYBSIT","KNTDTH","MNPAIN","PEPAIN","SLOP","MANSIT","BOSPN","VILACT", + "PLFALL","BGACT","BGDTH2","POPAIN","SGTATK","VILDTH" + }; + char s[8]; + + s[0]='D';s[1]='S'; + for(i=0;itype==MENU) { + y=(200-mnu->n*16-20)/2; + Z_gotoxy(mnu->x,y-10);Z_printbf(mnu->ttl); + for(i=0;in;++i) { + if(mnu->t[i]==LOAD || mnu->t[i]==SAVE) { + V_spr(mnu->x,j=y+i*16+29,mslotl); + for(k=8;k<184;k+=8) + V_spr(mnu->x+k,j,mslotm); + V_spr(mnu->x+184,j,mslotr); + Z_gotoxy(mnu->x+4,j-8); + if(input && i==save_mnu.cur) Z_printsf("%s_",ibuf); + else Z_printsf("%s",savname[i]); + }else{ + Z_gotoxy(mnu->x+((mnu->t[i]>=SVOLM)?((mnu->t[i]>=PL1CM)?50:152):0),y+i*16+20); + Z_printbf(mnu->m[i]); + } + if(mnu->t[i]==MUSIC) { + Z_printbf(" '%.8s'",g_music); + }else if(mnu->t[i]==INTERP) { + Z_printbf("%s",fullscreen?"ON":"OFF"); + }else if(mnu->t[i]>=PL1CM) { + V_manspr(mnu->x+((mnu->t[i]==PL1CM)?15:35),y+i*16+20+14, + PL_getspr(*panimp,0), + pcolortab[(mnu->t[i]==PL1CM)?p1color:p2color] + ); + }else if(mnu->t[i]>=SVOLM) { + V_spr(mnu->x,j=y+i*16+20,mbarl); + for(k=8;k<144;k+=8) + V_spr(mnu->x+k,j,mbarm); + V_spr(mnu->x+144,j,mbarr); + switch(mnu->t[i]) { + case SVOLM: k=snd_vol;break; + case MVOLM: k=mus_vol;break; + case GAMMAM: k=gammaa<<5;break; + } + V_spr(mnu->x+8+k,j,mbaro); + } + } + V_spr(mnu->x-25,y+mnu->cur*16+20-8,msklh[(gm_tm/6)&1]); + }else{ + Z_gotoxy((320-strlen(mnu->ttl)*7)/2,90);Z_printsf(mnu->ttl); + Z_gotoxy(136,100);Z_printsf("(Y/N)"); + } + return 1; +} diff --git a/src/menu.h b/src/menu.h new file mode 100644 index 0000000..c72c6f7 --- /dev/null +++ b/src/menu.h @@ -0,0 +1,40 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Game menus + +typedef struct{ + byte type; + int n,cur,x; + char *ttl; + char **m; + byte *t; +}menu_t; + +void GMV_say(char *); +void GMV_stop(void); + +void GM_init(void); +int GM_act(void); +int GM_draw(void); + +void G_code(void); diff --git a/src/misc.h b/src/misc.h new file mode 100644 index 0000000..6d4ac76 --- /dev/null +++ b/src/misc.h @@ -0,0 +1,84 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Miscellaneous functions + +#define MAXDIST 2000000L + +enum{ + Z_HITWALL=1,Z_HITCEIL=2,Z_HITLAND=4,Z_FALLOUT=8, + Z_INWATER=16,Z_HITWATER=32,Z_HITAIR=64,Z_BLOCK=128 +}; + +void *Z_getspr(char[4],int,int,char *); +void *Z_getsnd(char[6]); +void Z_drawspr(int,int,void *,char); +void Z_drawmanspr(int,int,void *,char,byte); +void Z_drawstair(int); +void Z_drawstprcnt(int,int); +void Z_drawstnum(int); +void Z_drawstwpn(int,int); +void Z_drawstkeys(byte); +void Z_drawstlives(char); +int Z_sound(void *,int); +void Z_initst(void); +void Z_drawfld(byte *, int); +int Z_sign(int); +int Z_dec(int,int); +int Z_canstand(int,int,int); +int Z_canfit(int x,int y,int r,int h); +void Z_teleobj(int o,int x,int y); +int Z_moveobj(obj_t *); +int Z_what_cpu(void); +int Z_gunhit(int,int,int,int,int); +int Z_overlap(obj_t *,obj_t *); +int Z_look(obj_t *,obj_t *,int); +int Z_hit(obj_t *,int,int,int); +int Z_hitobj(int id,int d,int o,int t); +void Z_kickobj(obj_t *,int,int,int); +void Z_explode(int,int,int,int); +void Z_bfg9000(int,int,int); +int Z_cansee(int,int,int,int); +int Z_chktrap(int,int d,int o,int t); +int Z_istrapped(int,int,int,int); +int Z_inwater(int x,int y,int r,int h); +int Z_canbreathe(int x,int y,int r,int h); +int Z_getobjpos(int,obj_t *o); + +void Z_water_trap(obj_t *); +void Z_untrap(byte); + +void Z_splash(obj_t *,int n); + +void Z_set_speed(obj_t *,int); + +void Z_calc_time(dword t,word *h,word *m,word *s); + +void Z_putbfch(int); +void Z_printbf(char *,...); +void Z_putsfch(int); +void Z_printsf(char *,...); +void Z_gotoxy(int,int); + +int Z_getacid(int x,int y,int r,int h); + +void Z_clrst(); diff --git a/src/miscc.c b/src/miscc.c new file mode 100644 index 0000000..13359cd --- /dev/null +++ b/src/miscc.c @@ -0,0 +1,604 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include +#include +#include "files.h" +#include "memory.h" +#include "error.h" +#include "vga.h" +#include "sound.h" +#include "view.h" +#include "bmap.h" +#include "dots.h" +#include "monster.h" +#include "misc.h" + +//#define WD 200 +//#define HT 98 + +#define MAX_YV 30 + +#define MAXAIR 1091 + +extern dword walf[256]; + +byte z_dot=0; + +extern void *walp[256]; + +static void *sth[22],*bfh[160-'!'],*sfh[160-'!'],*bulsnd[2],*stone, *stone2, *keys[3]; +static int prx=0,pry=0; + +int Z_sign(int a) { + if(a>0) return 1; + if(a<0) return -1; + return 0; +} + +int Z_dec(int a,int b) { + if(abs(a)<=b) return 0; + if(a>0) return a-b; + if(a<0) return a+b; + return 0; +} + +void *Z_getspr(char n[4],int s,int d,char *dir) { + int h; + + h=F_getsprid(n,s,d); + if(dir) *dir=(h&0x8000)?1:0; + return M_lock(h); +} + +void *Z_getsnd(char n[6]) { + char s[8]; + + //if(snd_type==-1) return NULL; + strncpy(s+2,n,6);s[0]='D'; + s[1]='S'; + return M_lock(F_getresid(s)); +} + +int Z_sound(void *s,int v) { + //if(snd_type==-1) return 0; + if(!s) return 0; + S_play(s,-1,1024,v); + return F_getreslen(((int*)s)[-1])/605; +} + +#define GAS_START (MN__LAST-MN_DEMON+5) +#define GAS_TOTAL (MN__LAST-MN_DEMON+16+10) + +void Z_initst(void) { + int i; + char s[10]; + static char nm[22][8]={ + "STTNUM0","STTNUM1","STTNUM2","STTNUM3","STTNUM4", + "STTNUM5","STTNUM6","STTNUM7","STTNUM8","STTNUM9", + "STTMINUS","STTPRCNT", + "FISTA0","CSAWA0","PISTA0","SHOTA0","SGN2A0","MGUNA0","LAUNA0", + "PLASA0","BFUGA0","GUN2A0" + }; + + stone=M_lock(F_getresid("STONE")); + stone2=M_lock(F_getresid("STONE2")); + keys[0]=M_lock(F_getresid("KEYRA0")); + keys[1]=M_lock(F_getresid("KEYGA0")); + keys[2]=M_lock(F_getresid("KEYBA0")); + for(i=0;i<22;++i) + sth[i]=M_lock(F_getresid(nm[i])); + strcpy(s,"STBF_*"); + for(i='!';i<160;++i) { + s[5]=i; + bfh[i-'!']=M_lock(F_findres(s)); + if(!(i&15)) logo_gas(GAS_START+((i-'!')>>4),GAS_TOTAL); + } + for(i='!';i<160;++i) { + sprintf(s,"STCFN%03d",i); + sfh[i-'!']=M_lock(F_findres(s)); + if(!(i&15)) logo_gas(GAS_START+8+((i-'!')>>4),GAS_TOTAL); + } + strcpy(s,"WINUM*"); + for(i='0';i<='9';++i) { + s[5]=i; + bfh[i-'!']=M_lock(F_getresid(s)); + } + bfh[':'-'!']=M_lock(F_getresid("WICOLON")); + bulsnd[0]=Z_getsnd("BUL1"); + bulsnd[1]=Z_getsnd("BUL2"); +} + +void Z_putbfch(int c) { + vgaimg *p; + + if(c>32 && c<160) p=bfh[c-'!']; else p=NULL; + if(p) { + V_spr(prx,pry,p); + prx+=p->w-1; + }else prx+=12; +} + +void Z_putsfch(int c) { + vgaimg *p; + + if(c>32 && c<160) p=sfh[c-'!']; else p=NULL; + if(p) { + V_spr(prx,pry,p); + prx+=p->w-1; + }else prx+=7; +} + +void Z_gotoxy(int x,int y) {prx=x;pry=y;} + +void Z_printbf(char *s,...) { + int i; + va_list ap; + char buf[80]; + + va_start(ap,s); + vsprintf(buf,s,ap); + va_end(ap); + for(i=0;buf[i];++i) switch(buf[i]) { + case '\n': + pry+=13; + case '\r': + prx=0;break; + default: + Z_putbfch((byte)buf[i]); + } +} + +void Z_printsf(char *s,...) { + int i; + va_list ap; + char buf[80]; + + va_start(ap,s); + vsprintf(buf,s,ap); + va_end(ap); + for(i=0;buf[i];++i) switch(buf[i]) { + case '\n': + pry+=8; + case '\r': + prx=0;break; + default: + Z_putsfch((byte)buf[i]); + } +} + +void Z_drawspr(int x,int y,void *p,char d) { + if(d) V_spr2(x-w_x+WD/2,y-w_y+HT/2+1+w_o,p);//if(d) V_spr2(x-w_x+100,y-w_y+HT/2+1+w_o,p); + else V_spr(x-w_x+WD/2,y-w_y+HT/2+1+w_o,p);//else V_spr(x-w_x+100,y-w_y+HT/2+1+w_o,p); +} + +void Z_clrst(void) { + V_pic(SCRW-120,w_o,stone);//V_pic(200,w_o,stone); + int y = ((vgaimg*)stone)->h; + while (yh; + } +} + + +void Z_drawstlives(char n) { + V_setrect(SCRW-40,30,w_o,40);Z_clrst();//V_setrect(280,30,w_o,40);Z_clrst(); + V_spr(SCRW-35,w_o+17,sth[n]);//V_spr(285,w_o+17,sth[n]); +} + +void Z_drawstkeys(byte k) { + int x,n; + + V_setrect(SCRW-120,70,w_o+77,23);Z_clrst();//V_setrect(200,70,w_o+77,23);Z_clrst(); + for(k>>=4,n=0,x=SCRW-75;n<3;++n,k>>=1,x+=9)//for(k>>=4,n=0,x=245;n<3;++n,k>>=1,x+=9) + if(k&1) V_spr(x,w_o+91,keys[n]); +} + +void Z_drawstair(int a) { + V_setrect(SCRW-120,120,w_o+49,2);Z_clrst();//V_setrect(200,120,w_o+49,2);Z_clrst(); + if(a<=0) return; + if(a>MAXAIR) a=MAXAIR; + a=a*100/MAXAIR; + if(!a) return; + V_clr(SCRW-110,a,w_o+49,2,0xC8);//V_clr(210,a,w_o+49,2,0xC8); +} + +void Z_drawstprcnt(int y,int n) { + char s[20]; + int l,i,x,c; + + V_setrect(SCRW-120,70,y*19+7+w_o,19);Z_clrst();//V_setrect(200,70,y*19+7+w_o,19);Z_clrst(); + sprintf(s,"%3d%%",n); + l=strlen(s);x=SCRW-110;//l=strlen(s);x=210; + for(i=0;i='0' && s[i]<='9') c=s[i]-'0'; + else if(s[i]=='-') c=10; + else if(s[i]=='%') c=11; + else c=-1; + if(c>=0) + V_spr(x,y*19+7+w_o,sth[c]); + } +} + +void Z_drawstnum(int n) { + char s[20]; + int l,i,x,c; + + V_setrect(SCRW-50,50,w_o+77,23);Z_clrst();//V_setrect(270,50,w_o+77,23);Z_clrst(); + if(!g_dm) return; + sprintf(s,"%d",n); + l=strlen(s);x=(115-l*14)+SCRW-120;//l=strlen(s);x=(115-l*14)+200; + for(i=0;i='0' && s[i]<='9') c=s[i]-'0'; + else if(s[i]=='-') c=10; + else if(s[i]=='%') c=11; + else c=-1; + if(c>=0) + V_spr(x,w_o+77+5,sth[c]); + } +} + +void Z_drawstwpn(int n,int a) { + char s[20]; + int l,i,x,c; + + i=n; + V_setrect(SCRW-120,120,w_o+58,23);Z_clrst();//V_setrect(200,120,w_o+58,23);Z_clrst(); + if(i>=0) V_spr(SCRW-88,w_o+58+19,sth[i+12]);//if(i>=0) V_spr(232,w_o+58+19,sth[i+12]); + if(n>=2) { + sprintf(s,"%d",a); + l=strlen(s);x=SCRW-10-l*14;//l=strlen(s);x=310-l*14; + for(i=0;i='0' && s[i]<='9') c=s[i]-'0'; + else if(s[i]=='-') c=10; + else if(s[i]=='%') c=11; + else c=-1; + if(c>=0) + V_spr(x,w_o+58+2,sth[c]); + } + } +} + + + +void Z_drawmanspr(int x,int y,void *p,char d,byte color) { + if(d) V_manspr2(x-w_x+WD/2,y-w_y+HT/2+1+w_o,p,color);//if(d) V_manspr2(x-w_x+100,y-w_y+HT/2+1+w_o,p,color); + else V_manspr(x-w_x+WD/2,y-w_y+HT/2+1+w_o,p,color);//else V_manspr(x-w_x+100,y-w_y+HT/2+1+w_o,p,color); +} + +int Z_canstand(int x,int y,int r) { + int i; + + i=(x-r)/CELW; + x=(x+r)/CELW; + y=(y+1)/CELH; + if(y>=FLDH || y<0) return 0; + if(i<0) i=0; + if(x>=FLDW) x=FLDW-1; + for(;i<=x;++i) + if(fld[y][i]==1 || fld[y][i]==2 || fld[y][i]==4) + if(!z_dot) return 1; + else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1; + return 0; +} + +int Z_hitceil(int x,int y,int r,int h) { + int i; + + i=(x-r)/CELW; + x=(x+r)/CELW; + y=(y-h+1)/CELH; + if(y>=FLDH || y<0) return 0; + if(i<0) i=0; + if(x>=FLDW) x=FLDW-1; + for(;i<=x;++i) + if(fld[y][i]==1 || fld[y][i]==2) + if(!z_dot) return 1; + else if(!((walf[fldf[y][i]]|walf[fldb[y][i]])&2)) return 1; + return 0; +} + +int Z_canfit(int x,int y,int r,int h) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-0)/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==1 || fld[j][i]==2) + if(!z_dot) return 0; + else if(!((walf[fldf[j][i]]|walf[fldb[j][i]])&2)) return 0; + return 1; +} + +int Z_inlift(int x,int y,int r,int h) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-1)/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==9 || fld[j][i]==10) return fld[j][i]-8; + return 0; +} + +int Z_isblocked(int x,int y,int r,int h,int xv) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-1)/CELH; + if(xv<0) x=sx; + else if(xv>0) sx=x; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==8) return 1; + return 0; +} + +int Z_istrapped(int x,int y,int r,int h) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-1)/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==255) return 1; + return 0; +} + +void Z_set_speed(obj_t *o,int s) { + int m; + + if(!(m=max(abs(o->xv),abs(o->yv)))) m=1; + o->xv=o->xv*s/m;o->yv=o->yv*s/m; +} + +static byte wfront; + +int Z_inwater(int x,int y,int r,int h) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-h/2)/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]>=5 && fld[j][i]<=7) {wfront=fldf[j][i];return 1;} + return 0; +} + +int Z_getacid(int x,int y,int r,int h) { + int i,j,sx,sy,a; + static byte tab[4]={0,5,10,20}; + + a=0; + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=y/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==6) a|=1; + else if(fld[j][i]==7) a|=2; + return tab[a]; +} + +int Z_canbreathe(int x,int y,int r,int h) { + int i,j,sx,sy; + + sx=(x-r)/CELW; + sy=(y-h+1)/CELH; + if(sx<0) sx=0; + if(sy<0) sy=0; + x=(x+r)/CELW; + y=(y-h/2)/CELH; + if(x>=FLDW) x=FLDW-1; + if(y>=FLDH) y=FLDH-1; + if(sx>x || sy>y) return 1; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==0 || fld[j][i]==3 || fld[j][i]==9 || fld[j][i]==10) return 1; + return 0; +} + +int Z_overlap(obj_t *a,obj_t *b) { + if(a->x - a->r > b->x + b->r) return 0; + if(a->x + a->r < b->x - b->r) return 0; + if(a->y <= b->y - b->h) return 0; + if(a->y - a->h >= b->y) return 0; + return 1; +} + +void Z_kickobj(obj_t *o,int x,int y,int pwr) { + int dx,dy,m; + + dx=o->x-x;dy=o->y-o->h/2-y; + if(!(m=max(abs(dx),abs(dy)))) m=1; + o->vx+=(long)dx*pwr/m; + o->vy+=(long)dy*pwr/m; +} + +int Z_cansee(int x,int y,int xd,int yd) { + register dword d,m; + int sx,sy; + dword xe,ye,s,i; + + if((xd-=x)>0) sx=1; + else if(xd<0) sx=-1; + else sx=0; + if((yd-=y)>0) sy=1; + else if(yd<0) sy=-1; + else sy=0; + if(!xd && !yd) return 1; + if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd; + xe=ye=0; + for(i=0;i<=d;) { + if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) return 0; + if((bmap[y>>5][x>>5]&BM_WALL)) { + if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) return 0; + if((xe+=(xd<<3))>=d) { + x+=xe/d*sx;xe=xe%d; + } + if((ye+=(yd<<3))>=d) { + y+=ye/d*sy;ye=ye%d; + } + i+=8; + }else{ + if(sx==0) m=0; + else{m=x&31;if(sx>0) m^=31; ++m;} + if(sy==0) s=0; + else{s=y&31;if(sy>0) s^=31; ++s;} + if((sx-a->x)!=d*2-1) return 0; + return Z_cansee(a->x,a->y-a->h/2,b->x,b->y-b->h/2); +} + +#define wvel(v) if((xv=abs(v)+1)>5) v=Z_dec(v,xv/2-2) + +byte z_mon=0; + +int Z_moveobj(obj_t *p) { + static int x,y,xv,yv,r,h,lx,ly,st; + static byte inw; + + st=0; + switch(Z_inlift(x=p->x,y=p->y,r=p->r,h=p->h)) { + case 0: + if(++p->yv>MAX_YV) --p->yv; + break; + case 1: + if(--p->yv < -5) ++p->yv; + break; + case 2: + if(p->yv > 5) {--p->yv;break;} + ++p->yv;break; + } + if((inw=Z_inwater(x,y,r,h))!=0) { + st|=Z_INWATER; + wvel(p->xv); + wvel(p->yv); + wvel(p->vx); + wvel(p->vy); + } + p->vx=Z_dec(p->vx,1); + p->vy=Z_dec(p->vy,1); + xv=p->xv+p->vx;yv=p->yv+p->vy; + while(xv || yv) { + if(x<-100 || x>=FLDW*8+100 || y<-100 || y>=FLDH*8+100) + {st|=Z_FALLOUT;} + + lx=x; + x+=(abs(xv)<=7)?xv:((xv>0)?7:-7); + if(z_mon) if(Z_isblocked(x,y,r,h,xv)) st|=Z_BLOCK; + if(!Z_canfit(x,y,r,h)) { + if(xv==0) x=lx; + else if(xv<0) x=((lx-r)&0xFFF8)+r; + else x=((lx+r)&0xFFF8)-r+7; + xv=p->xv=p->vx=0;st|=Z_HITWALL; + } + xv-=(abs(xv)<=7)?xv:((xv>0)?7:-7); + + ly=y; + y+=(abs(yv)<=7)?yv:((yv>0)?7:-7); + if(yv>=8) --y; + if(yv<0 && Z_hitceil(x,y,r,h)) { + y=((ly-h+1)&0xFFF8)+h-1; + yv=p->vy=1;p->yv=0;st|=Z_HITCEIL; + } + if(yv>0 && Z_canstand(x,y,r)) { + y=((y+1)&0xFFF8)-1; + yv=p->yv=p->vy=0;st|=Z_HITLAND; + } + yv-=(abs(yv)<=7)?yv:((yv>0)?7:-7); + } + p->x=x;p->y=y; + if(Z_inwater(x,y,r,h)) { + st|=Z_INWATER; + if(!inw) st|=Z_HITWATER; + }else if(inw) st|=Z_HITAIR; + return st; +} + +void Z_splash(obj_t *p,int n) { + Z_sound(bulsnd[0],128); + DOT_water(p->x,p->y-p->h/2,p->xv+p->vx,p->yv+p->vy,n, + (int)walp[wfront]-1); +} + +void Z_calc_time(dword t,word *h,word *m,word *s) +{ + t = t * DELAY; + t = t / 1000; + *s = t % 60; + t = t - *s; + t = t / 60; + *m = t % 60; + t = t - *m; + t = t / 60; + *h = t; +} diff --git a/src/monster.c b/src/monster.c new file mode 100644 index 0000000..ed7604e --- /dev/null +++ b/src/monster.c @@ -0,0 +1,1031 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +//#include +#include +#include +#include "vga.h" +#include "files.h" +#include "error.h" +#include "view.h" +#include "bmap.h" +#include "dots.h" +#include "weapons.h" +#include "player.h" +#include "monster.h" +#include "items.h" +#include "switch.h" +#include "misc.h" +#include "fx.h" +#include "smoke.h" + +#define MANCOLOR 0xD0 + +#define MAX_ATM 90 + +#define MN_TN (MN__LAST-MN_DEMON) + +extern byte z_mon; + +enum{ + SLEEP,GO,RUN,CLIMB,DIE,DEAD,ATTACK,SHOOT,PAIN,WAIT,REVIVE,RUNOUT +}; + +#pragma pack(1) +typedef struct{ + obj_t o; + byte t,d,st,ftime; + int fobj; + int s; + char *ap; + int aim,life,pain,ac,tx,ty,ammo; + short atm; +}mn_t; +#pragma pack(0) + +typedef struct{ + int r,h,l,mp,rv,jv,sp,minp; +}mnsz_t; + +byte nomon=1; + +static char *sleepanim[MN_TN]={ + "AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB", + "A","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB", + "A","A","AAABBB" +}, *goanim[MN_TN]={ + "AABBCCDD","AABBCCDD","AABBDDAACCDD","AABBDDAACCDD","AABBDDCCDDBB", + "AABBDDAACCDD","AABBCCDD","AABBCCDD","A","AABB","AABBCCBB", + "AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF","AABBCCDDEEFF", + "AABB","A","DDEEFFGGHHIIJJKKLLAABBCC","ACDABD" +}, *painanim[MN_TN]={ + "H","H","G","G","G","G","H","H","F","E","G","I","I","J","L","Q","EECCDDCC", + "A","D","G" +}, *waitanim[MN_TN]={ + "A","A","A","A","A","A","A","A","A","AABB","A","A","A","I","K","A","A", + "A","D","E" +}, *attackanim[MN_TN]={ + "EEFFGG","EEFFGG","EEEEEF","EEEEEF","EEEEEF","EF","EEFFGG","EEFFGG", + "BBCCDD","CCDD","DDEEFF","GH","GH","GGGGHH","GGHHII", + "QQGGGHHHIIJJKKLLMMNNOOPP","BBFFAA","A","OOPPQQ","EEEEFF" +}, *dieanim[MN_TN]={ + "IIIJJJKKKLLLMMM","IIIJJJKKKLLL","HHHIIIJJJKKK","HHHIIIJJJKKK", + "HHHIIIJJJKKKLLLMMMNNNOOO","HHHIIIJJJKKKLLLMMM", + "IIIJJJKKKLLLMMMNNN","IIIJJJKKKLLLMMMNNN","GGGHHHIIIJJJKKK", + "FFFGGGHHHIIIJJJKKK","HHHIIIJJJKKKLLLMMM", + "JJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRR","JJJKKKLLLMMMNNNOOO", + "KKKLLLMMMNNNOOOPPPRRRSSS","MMMNNNOOOPPP","RRRSSSTTTUUUVVVWWWXXXYYY", + "DDDD","CCCDDDEEEFFFGGG","D","HHHHIIIIJJJJKKKKLLLLMMMM" +}, *slopanim[MN_TN]={ + "","NNNOOOPPPRRRSSSTTT","MMMNNNOOOPPPRRRSSSTTT","MMMNNNOOOPPPRRRSSSTTT","", + "OOOPPPQQQRRRSSS","","","","","","","","","","","","","","OOPPQQRRSSTTUUVV" +}, *deadanim[MN_TN]={ + "N","M","L","L","P","N","O","O","L","","","S","P","T","Q","Z","C","","D","N" +}, *messanim[MN_TN]={ + "","U","U","U","","T","","","","","","","","","","","","","","W" +}; + +int hit_xv,hit_yv; + +static void *spr[MN_TN][29*2],*fspr[8],*fsnd,*pauksnd,*trupsnd,*sgun[2]; +static char sprd[MN_TN][29*2]; +static void *snd[MN_TN][5],*impsitsnd[2],*impdthsnd[2],*firsnd,*slopsnd,*gsnd[4]; +static void *swgsnd,*pchsnd,*pl_spr[2],*telesnd; +static void *positsnd[3],*podthsnd[3]; +static mn_t mn[MAXMN]; +static int mnum,gsndt; +static mnsz_t mnsz[MN_TN+1]={ +//rad ht life pain rv jv slop min_pn + 0, 0, 0, 0, 0, 0, 0, 0, // none + 15, 28, 60, 20, 7,10, 0, 10, // demon + 10, 28, 25, 15, 3,10, 30, 0, // imp + 10, 28, 15, 10, 3,10, 30, 0, // zomby + 10, 28, 20, 10, 3,10, 30, 0, // sergeant + 20, 55, 500, 70, 5,10, 0, 50, // cyberdemon + 12, 28, 60, 20, 3,10, 30, 10, // chaingunner + 12, 32, 150, 40, 3,10, 0, 30, // baron of hell + 12, 32, 75, 40, 3,10, 0, 30, // hell knight + 15, 28, 100, 10, 4, 4, 0, 0, // cacodemon + 8, 18, 60, 10, 4, 4, 0, 0, // lost soul + 15, 28, 100, 10, 4, 4, 0, 0, // pain elemental + 64, 50, 500, 70, 4,10, 0, 50, // spider mastermind + 25, 27, 150, 20, 4,10, 0, 0, // arachnotron + 18, 30, 200, 40, 3, 7, 0, 20, // mancubus + 17, 36, 200, 40, 6,11, 0, 20, // revenant + 17, 36, 150, 30, 7,12, 0, 10, // archvile + 5, 5, 35, 20,14, 6, 0, 10, // fish + 5, 17, 20, 0, 7, 6, 0, 0, // barrel + 17, 38, 20, 40, 3, 6, 0, 20, // robot + 8, 26, 400, 70, 8,10, 30, 50 // man +}; + +void MN_savegame(FILE* h) { + int n; + + for(n=MAXMN;--n;) if(mn[n].t) break; + ++n;myfwrite(&n,1,4,h); + myfwrite(mn,1,n*sizeof(mn[0]),h); + myfwrite(&mnum,1,4,h);myfwrite(&gsndt,1,4,h); +} + +static void setst(int,int); + +void MN_loadgame(FILE* h) { + int n,c; + + myfread(&n,1,4,h); + myfread(mn,1,n*sizeof(mn[0]),h); + myfread(&mnum,1,4,h);myfread(&gsndt,1,4,h); + for(n=0;n=MN_PL_DEAD) goto ok; + return -1; +ok: + mn[i].o.x=x;mn[i].o.y=y; + mn[i].o.xv=mn[i].o.yv=mn[i].o.vx=mn[i].o.vy=0; + mn[i].d=d;mn[i].t=t; + mn[i].st=SLEEP; + if(tx,o->y,c,t+MN_PL_DEAD))==-1) return -1; + mn[i].o=*o;return i; +} + +static int isfriend(int a,int b) { + if(a==MN_BARREL || b==MN_BARREL) return 1; + if(a==b) switch(a) { + case MN_IMP: case MN_DEMON: + case MN_BARON: case MN_KNIGHT: + case MN_CACO: case MN_SOUL: + case MN_MANCUB: case MN_SKEL: + case MN_FISH: + return 1; + } + if(a==MN_SOUL && b==MN_PAIN) return 1; + if(b==MN_SOUL && a==MN_PAIN) return 1; + return 0; +} + +static int MN_findnewprey(int i) { + int a,b,l; + + a=!PL_isdead(&pl1); + if(_2pl) b=!PL_isdead(&pl2); else b=0; + if(a) { + if(b) mn[i].aim=(abs(mn[i].o.x-pl1.o.x)+abs(mn[i].o.y-pl1.o.y) + <= abs(mn[i].o.x-pl2.o.x)+abs(mn[i].o.y-pl2.o.y))?-1:-2; + else mn[i].aim=-1; + }else{ + if(b) mn[i].aim=-2; + else{ + for(a=0,b=32000,mn[i].aim=-3;a=0 && i=50) mn[i].ammo=(mn[i].t==MN_ROBO)?-200:-50; + break; + case MN_MAN: + break; + case MN_MANCUB: + if(++mn[i].ammo>=5) mn[i].ammo=-50; + break; + case MN_SPIDER: + if(++mn[i].ammo>=100) mn[i].ammo=-50; + break; + case MN_CYBER: + if(rand()&1) return 0; + if(++mn[i].ammo>=10) mn[i].ammo=-50; + break; + case MN_BARON: case MN_KNIGHT: + if(rand()&7) return 0; + break; + case MN_SKEL: + if(rand()&31) return 0; + break; + case MN_VILE: + if(rand()&7) return 0; + break; + case MN_PAIN: + if(rand()&7) return 0; + break; + default: + if(rand()&15) return 0; + } + if(!Z_look(&mn[i].o,o,mn[i].d)) return 0; + mn[i].atm=0; + mn[i].tx=o->x+(o->xv+o->vx)*6;mn[i].ty=o->y-o->h/2+(o->yv+o->vy)*6; + if(abs(mn[i].tx-mn[i].o.x)x;mn[i].ty=o->y; + setst(i,SHOOT);Z_sound(fsnd,128); + Z_sound(snd[MN_VILE-1][2],128);break; + case MN_SOUL: + setst(i,ATTACK);Z_sound(snd[MN_SOUL-1][2],128); + yd=mn[i].ty-mn[i].o.y+mn[i].o.h/2;xd=mn[i].tx-mn[i].o.x; + if(!(m=max(abs(xd),abs(yd)))) m=1; + mn[i].o.xv=xd*16/m;mn[i].o.yv=yd*16/m; + break; + case MN_MANCUB: if(mn[i].ammo==1) Z_sound(snd[MN_MANCUB-1][2],128); + case MN_ZOMBY: case MN_SERG: case MN_BSP: case MN_ROBO: + case MN_CYBER: case MN_CGUN: case MN_SPIDER: + case MN_PAIN: case MN_MAN: + setst(i,SHOOT);break; + default: + return 0; + } + return 1; +} + +static int kick(int i,obj_t *o) { + switch(mn[i].t) { + case MN_FISH: + setst(i,ATTACK);return 1; + case MN_DEMON: + setst(i,ATTACK);Z_sound(snd[0][2],128);return 1; + case MN_IMP: + setst(i,ATTACK);Z_sound(snd[1][2],128);return 1; + case MN_SKEL: + setst(i,ATTACK);Z_sound(swgsnd,128);return 1; + case MN_ROBO: + setst(i,ATTACK);Z_sound(swgsnd,128);return 1; + case MN_BARON: case MN_KNIGHT: case MN_CACO: case MN_MANCUB: + return shoot(i,o,1); + } + return 0; +} + +static int iscorpse(obj_t *o,int n) { + int i; + + if(!n) if(rand()&7) return -3; + for(i=0;i 123) pt_xs=-pt_xs; + if(abs(pt_y+=pt_ys) > 50) pt_ys=-pt_ys; + if(gsndt>0) if(--gsndt==0) { + Z_sound(gsnd[myrand(4)],128); + } + for(i=0;i=mnsz[t].mp) + {mn[i].pain=mnsz[t].mp;Z_sound(snd[t-1][1],128);} + if((mn[i].pain-=5)<=mnsz[t].minp) + {setst(i,GO);mn[i].pain=0;mn[i].ammo=-9;} + break; + case SLEEP: + if(++mn[i].s>=18) mn[i].s=0; else break; + if(Z_look(&mn[i].o,&pl1.o,mn[i].d)) + {setst(i,GO);mn[i].aim=-1;mn[i].atm=0;Z_sound(wakeupsnd(t),128);} + if(_2pl) if(Z_look(&mn[i].o,&pl2.o,mn[i].d)) + {setst(i,GO);mn[i].aim=-2;mn[i].atm=0;Z_sound(wakeupsnd(t),128);} + break; + case WAIT: + if(--mn[i].s<0) setst(i,GO); + break; + case GO: + if(st&Z_BLOCK) {mn[i].d^=1;setst(i,RUNOUT);mn[i].s=40;break;} + if(t==MN_VILE) if(iscorpse(&mn[i].o,0)>=0) { + setst(i,ATTACK);mn[i].o.xv=0;break; + } + if(!Z_getobjpos(mn[i].aim,&o) || mn[i].atm>MAX_ATM) + if(!MN_findnewprey(i)) { + mn[i].aim=-3; + o.x=mn[i].o.x+pt_x;o.y=mn[i].o.y+pt_y; + o.xv=o.vx=o.yv=o.vy=o.r=0;o.h=1; + }else Z_getobjpos(mn[i].aim,&o); + if(Z_overlap(&mn[i].o,&o)) { + mn[i].atm=0; + if(kick(i,&o)) break; + } + sx=o.x-mn[i].o.x; + sy=o.y-o.h/2-mn[i].o.y+mn[i].o.h/2; + if(!(st&Z_BLOCK)) if(abs(sx)<20) + if(t!=MN_FISH) {setst(i,RUN);mn[i].s=15;mn[i].d=rand()&1;break;} + if(st&Z_HITWALL) { + if(SW_press(mn[i].o.x,mn[i].o.y,mn[i].o.r,mn[i].o.h,2,i)) + {setst(i,WAIT);mn[i].s=4;break;} + switch(t) { + case MN_CACO: case MN_SOUL: case MN_PAIN: case MN_FISH: + break; + default: + if(Z_canstand(mn[i].o.x,mn[i].o.y,mn[i].o.r)) + {mn[i].o.yv=-mnsz[t].jv;setst(i,CLIMB);break;} + }break; + } + mn[i].d=(sx>0)?1:0; + if(canshoot(t)) + if(abs(sx)>abs(sy)) if(shoot(i,&o,0)) break; + + switch(t) { + case MN_FISH: + if(!(st&Z_INWATER)) { + if(Z_canstand(mn[i].o.x,mn[i].o.y,mn[i].o.r)) { + mn[i].o.yv=-6; + mn[i].o.vx+=rand()%17-8; + }setst(i,PAIN);mn[i].pain+=50;break; + } + case MN_CACO: case MN_SOUL: case MN_PAIN: + if(abs(sy)>4) mn[i].o.yv=(sy<0)?-4:4; else mn[i].o.yv=0; + if(t==MN_FISH) if(mn[i].o.yv<0) + if(!Z_inwater(mn[i].o.x,mn[i].o.y-8,mn[i].o.r,mn[i].o.h)) + {mn[i].o.yv=0;setst(i,RUN);mn[i].d=rand()&1;mn[i].s=20;} + break; + default: + if(sy<-20) if(Z_canstand(mn[i].o.x,mn[i].o.y,mn[i].o.r)) + if(!(rand()&3)) mn[i].o.yv=-mnsz[t].jv; + } + if(++mn[i].s>=8) { + mn[i].s=0; + if(!(rand()&7)) Z_sound(snd[t-1][0],128); + } + mn[i].o.xv=((mn[i].d)?1:-1)*mnsz[t].rv; + if(st&Z_INWATER) mn[i].o.xv/=2; + else if(t==MN_FISH) mn[i].o.xv=0; + break; + case RUN: + if(st&Z_BLOCK) {setst(i,RUNOUT);mn[i].d^=1;mn[i].s=40;break;} + if(--mn[i].s<=0 || ((st&Z_HITWALL) && mn[i].o.yv+mn[i].o.vy==0)) { + setst(i,GO);mn[i].s=0;if(st&(Z_HITWALL|Z_BLOCK)) mn[i].d^=1; + if(!(rand()&7)) Z_sound(snd[t-1][0],128); + }mn[i].o.xv=((mn[i].d)?1:-1)*mnsz[t].rv; + if(st&Z_INWATER) mn[i].o.xv/=2; + else if(t==MN_FISH) mn[i].o.xv=0; + break; + case RUNOUT: + if(!(st&Z_BLOCK) && mn[i].s>0) mn[i].s=0; + if(--mn[i].s<=-18) { + setst(i,GO);mn[i].s=0;if(st&(Z_HITWALL|Z_BLOCK)) mn[i].d^=1; + if(!(rand()&7)) Z_sound(snd[t-1][0],128); + }mn[i].o.xv=((mn[i].d)?1:-1)*mnsz[t].rv; + if(st&Z_INWATER) mn[i].o.xv/=2; + else if(t==MN_FISH) mn[i].o.xv=0; + break; + case CLIMB: + if(mn[i].o.yv+mn[i].o.vy>=0 || !(st&Z_HITWALL)) { + setst(i,GO);mn[i].s=0; + if(st&(Z_HITWALL|Z_BLOCK)) {mn[i].d^=1;setst(i,RUN);mn[i].s=15;} + }mn[i].o.xv=((mn[i].d)?1:-1)*mnsz[t].rv; + if(st&Z_INWATER) mn[i].o.xv/=2; + else if(t==MN_FISH) mn[i].o.xv=0; + break; + case ATTACK: + case SHOOT: + if(t==MN_SOUL) {if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) setst(i,GO); break;} + if(t!=MN_FISH) mn[i].o.xv=Z_dec(mn[i].o.xv,1); + if(t==MN_VILE && mn[i].st==SHOOT) { + if(!Z_getobjpos(mn[i].aim,&o)) {setst(i,GO);break;} + if(!Z_look(&mn[i].o,&o,mn[i].d)) {setst(i,GO);break;} + if(Z_inwater(o.x,o.y,o.r,o.h)) {setst(i,GO);break;} + mn[i].tx=o.x;mn[i].ty=o.y; + Z_hitobj(mn[i].aim,2,i,HIT_SOME); + }break; + } + if(mn[i].st==REVIVE) { + if(--mn[i].ac==0) setst(i,GO); + }else ++mn[i].ac; + if(!mn[i].ap[mn[i].ac]) switch(mn[i].st) { + case ATTACK: + switch(t) { + case MN_SOUL: mn[i].ac=0; + case MN_IMP: + case MN_DEMON: + if(Z_hit(&mn[i].o,15,i,HIT_SOME)) if(t==MN_SOUL) setst(i,GO); + break; + case MN_FISH: + if(Z_hit(&mn[i].o,10,i,HIT_SOME)) + Z_sound(snd[MN_FISH-1][2],128); + break; + case MN_SKEL: case MN_ROBO: + o=mn[i].o;o.xv=mn[i].d?50:-50; + if(Z_hit(&o,50,i,HIT_SOME)) Z_sound(pchsnd,128); + break; + case MN_VILE: + sx=iscorpse(&mn[i].o,1); + if(sx==-3) break; + if(!mn[sx].t || mn[sx].st!=DEAD) break; + setst(sx,REVIVE);Z_sound(slopsnd,128); + hit_xv=hit_yv=0;MN_hit(i,5,-3,HIT_SOME); + break; + }if(t!=MN_SOUL && mn[i].st!=DIE) setst(i,GO); + break; + case SHOOT: + switch(t) { + case MN_IMP: + WP_ball1(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_ZOMBY: + WP_pistol(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_SERG: + WP_shotgun(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_MAN: + WP_dshotgun(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + mn[i].ammo=-36;break; + case MN_CYBER: + WP_rocket(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_SKEL: + WP_revf(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i,mn[i].aim); + break; + case MN_CGUN: + case MN_SPIDER: + WP_mgun(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_BSP: + WP_aplasma(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_ROBO: + WP_plasma(mn[i].o.x+(mn[i].d*2-1)*15,mn[i].o.y-30,mn[i].tx,mn[i].ty,i); + break; + case MN_MANCUB: + WP_manfire(mn[i].o.x+(mn[i].d*2-1)*mn[i].o.r,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_BARON: case MN_KNIGHT: + WP_ball7(mn[i].o.x,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_CACO: + WP_ball2(mn[i].o.x,mn[i].o.y-mn[i].o.h/2,mn[i].tx,mn[i].ty,i); + break; + case MN_PAIN: + if((sx=MN_spawn(mn[i].o.x,mn[i].o.y,mn[i].d,MN_SOUL))==-1) break; + Z_getobjpos(mn[sx].aim=mn[i].aim,&o);mn[sx].atm=0; + shoot(sx,&o,1); + break; + } + if(t==MN_CGUN || t==MN_SPIDER || t==MN_BSP || t==MN_MANCUB || t==MN_ROBO) + if(!Z_getobjpos(mn[i].aim,&o)) MN_findnewprey(i); + else if(shoot(i,&o,0)) break; + setst(i,GO);break; + case DIE: + setst(i,DEAD); + if(t==MN_PAIN || t==MN_SOUL) mn[i].ftime=0; + if(t==MN_PAIN) { + if((sx=MN_spawn(mn[i].o.x-15,mn[i].o.y,0,MN_SOUL))==-1) break; + setst(sx,GO); + if((sx=MN_spawn(mn[i].o.x+15,mn[i].o.y,1,MN_SOUL))==-1) break; + setst(sx,GO); + if((sx=MN_spawn(mn[i].o.x,mn[i].o.y-10,1,MN_SOUL))==-1) break; + setst(sx,GO); + }break; + default: mn[i].ac=0; + } + switch(mn[i].st) { + case GO: case RUN: case CLIMB: case RUNOUT: + if(t==MN_CYBER || t==MN_SPIDER || t==MN_BSP) { + if(mn[i].ac==0 || mn[i].ac==6) Z_sound(snd[t-1][2],128); + }else if(t==MN_ROBO) + if(mn[i].ac==0 || mn[i].ac==12) Z_sound(snd[t-1][2],128); + } + } +} + +void MN_mark(void) { + int i; + for(i=0;i=MN_PL_DEAD) { + Z_drawmanspr(mn[i].o.x,mn[i].o.y,pl_spr[mn[i].t-MN_PL_DEAD],0,mn[i].d); + continue; + } + if((mn[i].t!=MN_SOUL && mn[i].t!=MN_PAIN) || mn[i].st!=DEAD) { + if(mn[i].t!=MN_MAN) + Z_drawspr(mn[i].o.x,mn[i].o.y, + spr[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d], + sprd[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d]); + else{ + if(mn[i].ap[mn[i].ac]=='E' || mn[i].ap[mn[i].ac]=='F') + Z_drawspr(mn[i].o.x,mn[i].o.y,sgun[mn[i].ap[mn[i].ac]-'E'],mn[i].d); + Z_drawmanspr(mn[i].o.x,mn[i].o.y, + spr[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d], + sprd[mn[i].t-1][(mn[i].ap[mn[i].ac]-'A')*2+mn[i].d],MANCOLOR); + } + } + if(mn[i].t==MN_VILE && mn[i].st==SHOOT) { + Z_drawspr(mn[i].tx,mn[i].ty,fspr[mn[i].ac/3],0); + } + } +} + +int MN_hit(int n,int d,int o,int t) { + int i; + + if(mn[n].st==DEAD || mn[n].st==DIE) return 0; + if(o==n) { + if(t!=HIT_ROCKET && t!=HIT_ELECTRO) return 0; + if(mn[n].t==MN_CYBER || mn[n].t==MN_BARREL) return 1; + } + if(o>=0) { + if(mn[o].t==MN_SOUL && mn[n].t==MN_PAIN) return 0; + if(mn[o].t==mn[n].t) switch(mn[n].t) { + case MN_IMP: case MN_DEMON: + case MN_BARON: case MN_KNIGHT: + case MN_CACO: case MN_SOUL: + case MN_MANCUB: case MN_SKEL: + case MN_FISH: + return 0; + } + } + if(t==HIT_FLAME) if(mn[n].ftime && mn[n].fobj==o) {if(g_time&31) return 1;} + else {mn[n].ftime=255;mn[n].fobj=o;} + if(t==HIT_ELECTRO) if(mn[n].t==MN_FISH) + {setst(n,RUN);mn[n].s=20;mn[n].d=rand()&1;return 1;} + if(t==HIT_TRAP) mn[n].life=-100; + if(mn[n].t==MN_ROBO) d=0; + if((mn[n].life-=d)<=0) --mnum; + if(!mn[n].pain) mn[n].pain=3; + mn[n].pain+=d; + if(mn[n].st!=PAIN) { + if(mn[n].pain>=mnsz[mn[n].t].minp) setst(n,PAIN); + } + if(mn[n].t!=MN_BARREL) + DOT_blood(mn[n].o.x,mn[n].o.y-mn[n].o.h/2,hit_xv,hit_yv,d*2); + mn[n].aim=o;mn[n].atm=0; + if(mn[n].life<=0) { + if(mn[n].t!=MN_BARREL) + if(o==-1) ++pl1.kills; + else if(o==-2) ++pl2.kills; + setst(n,DIE); + switch(mn[n].t) { + case MN_ZOMBY: i=I_CLIP;break; + case MN_SERG: i=I_SGUN;break; + case MN_CGUN: i=I_MGUN;break; + case MN_MAN: i=I_KEYR;break; + default: i=0; + }if(i) IT_spawn(mn[n].o.x,mn[n].o.y,i); + mn[n].o.xv=0;mn[n].o.h=6; + if(mn[n].life<=-mnsz[mn[n].t].sp) + switch(mn[n].t) { + case MN_IMP: case MN_ZOMBY: case MN_SERG: case MN_CGUN: + case MN_MAN: + mn[n].ap=slopanim[mn[n].t-1]; + Z_sound(slopsnd,128); + break; + case MN_BSP: if(g_map==9) break; + default: + Z_sound(dthsnd(mn[n].t),128); + } + else if(mn[n].t!=MN_BSP || g_map!=9) Z_sound(dthsnd(mn[n].t),128); + mn[n].life=0; + }else if(mn[n].st==SLEEP) {setst(n,GO);mn[n].pain=mnsz[mn[n].t].mp;} + return 1; +} + +#define hit(o,x,y) (y<=o.y && y>o.y-o.h && x>=o.x-o.r && x<=o.x+o.r) + +int Z_gunhit(int x,int y,int o,int xv,int yv) { + int i; + + if(o!=-1) if(hit(pl1.o,x,y)) if(PL_hit(&pl1,3,o,HIT_SOME)) + {pl1.o.vx+=xv;pl1.o.vy+=yv;return -1;} + if(_2pl && o!=-2) if(hit(pl2.o,x,y)) if(PL_hit(&pl2,3,o,HIT_SOME)) + {pl2.o.vx+=xv;pl2.o.vy+=yv;return -2;} + + for(i=0;ixv+o->vx; + hit_yv=o->yv+o->vy; + if(Z_overlap(o,&pl1.o)) if(PL_hit(&pl1,d,own,t)) { + pl1.o.vx+=(o->xv+o->vx)*((t==HIT_BFG)?8:1)/4; + pl1.o.vy+=(o->yv+o->vy)*((t==HIT_BFG)?8:1)/4; + if(t==HIT_BFG) goodsnd(); + return -1; + } + if(_2pl) if(Z_overlap(o,&pl2.o)) if(PL_hit(&pl2,d,own,t)) { + pl2.o.vx+=(o->xv+o->vx)*((t==HIT_BFG)?8:1)/4; + pl2.o.vy+=(o->yv+o->vy)*((t==HIT_BFG)?8:1)/4; + if(t==HIT_BFG) goodsnd(); + return -2; + } + + for(i=0;ixv+o->vx)*((t==HIT_BFG)?8:1)/4; + mn[i].o.vy+=(o->yv+o->vy)*((t==HIT_BFG)?8:1)/4; + return 1; + } + return 0; +} + +void MN_killedp(void) { + int i; + + for(i=0;i=MAXMN) return 0; + if(mn[obj].t) return MN_hit(obj,d,own,t); + return 0; +} + +void Z_explode(int x,int y,int rad,int own) { + long r; + int dx,dy,m,i; + + if(x<-100 || x>FLDW*CELW+100) return; + if(y<-100 || y>FLDH*CELH+100) return; + r=(long)rad*rad; + dx=pl1.o.x-x;dy=pl1.o.y-pl1.o.h/2-y; + if((long)dx*dx+(long)dy*dyFLDW*CELW+100) return; + if(y<-100 || y>FLDH*CELH+100) return; + dx=pl1.o.x-x;dy=pl1.o.y-pl1.o.h/2-y; + if(own!=-1) if((long)dx*dx+(long)dy*dy<16000) + if(Z_cansee(x,y,pl1.o.x,pl1.o.y-pl1.o.h/2)) { + if(PL_hit(&pl1,50,own,HIT_SOME)) + WP_bfghit(pl1.o.x,pl1.o.y-pl1.o.h/2,own); + } + if(_2pl) { + dx=pl2.o.x-x;dy=pl2.o.y-pl2.o.h/2-y; + if(own!=-2) if((long)dx*dx+(long)dy*dy<16000) + if(Z_cansee(x,y,pl2.o.x,pl2.o.y-pl2.o.h/2)) { + if(PL_hit(&pl2,50,own,HIT_SOME)) + WP_bfghit(pl2.o.x,pl2.o.y-pl2.o.h/2,own); + } + } + for(i=0;i=0 && ox,p->y);FX_tfog(p->x=x,p->y=y); + Z_sound(telesnd,128); +} + +void MN_warning(int l,int t,int r,int b) { + int i; + + for(i=0;i=l && mn[i].o.x-mn[i].o.r<=r + && mn[i].o.y>=t && mn[i].o.y-mn[i].o.h<=b) + if(Z_canstand(mn[i].o.x,mn[i].o.y,mn[i].o.r)) + mn[i].o.yv=-mnsz[mn[i].t].jv; +} diff --git a/src/monster.h b/src/monster.h new file mode 100644 index 0000000..376b1a2 --- /dev/null +++ b/src/monster.h @@ -0,0 +1,44 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Monsters + +#define MAXMN 200 + +enum{ + MN_NONE,MN_DEMON,MN_IMP,MN_ZOMBY,MN_SERG,MN_CYBER,MN_CGUN, + MN_BARON,MN_KNIGHT,MN_CACO,MN_SOUL,MN_PAIN,MN_SPIDER,MN_BSP, + MN_MANCUB,MN_SKEL,MN_VILE,MN_FISH,MN_BARREL,MN_ROBO,MN_MAN, + MN__LAST, + MN_PL_DEAD=100,MN_PL_MESS +}; + +void MN_init(void); +void MN_alloc(void); +int MN_spawn(int,int,byte,int); +int MN_spawn_deadpl(obj_t *,byte,int); +void MN_act(void); +void MN_mark(void); +void MN_draw(void); +void MN_warning(int l,int t,int r,int b); + +void MN_killedp(void); diff --git a/src/music.c b/src/music.c new file mode 100644 index 0000000..1f08815 --- /dev/null +++ b/src/music.c @@ -0,0 +1,231 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include "sound.h" +#include +#include + +short mus_vol = 50; + +Mix_Music * muslo; + +char music_random = ON; +int music_time = 3; +int music_fade = 5; + +Uint32 muscount; + +int musdisabled = 1; + +void S_initmusic(void) +{ + if (!SDL_WasInit(SDL_INIT_AUDIO)) { + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + fprintf(stderr, "\nUnable to initialize audio: %s\n", SDL_GetError()); + musdisabled=1; + return; + } + + if (Mix_OpenAudio(22050, AUDIO_S16, 1, 1000) < 0) { + fprintf(stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError()); + musdisabled=1; + return; + } + } + + muslo=NULL; + + muscount=0; + + musdisabled = (mus_vol==0); + + S_volumemusic(mus_vol); +} + +void S_donemusic(void) +{ + F_freemus(); + Mix_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); +} + +void S_startmusic(int time) +{ + if (musdisabled) return; + Mix_PlayMusic(muslo, -1); + Mix_VolumeMusic(mus_vol); + muscount=time*60*1000/DELAY; +} + +void S_stopmusic(void) +{ + if (musdisabled) return; + Mix_HaltMusic(); + muscount = 0; +} + +void S_volumemusic(int v) +{ + if (musdisabled) return; + mus_vol = v; + if (mus_vol>128) mus_vol=128; + if (mus_vol<0) mus_vol=0; + if (mus_vol==0 && Mix_PlayingMusic()) { + S_stopmusic(); + } + else if (mus_vol>0 && !Mix_PlayingMusic()) { + S_startmusic(music_time); + } + else { + Mix_VolumeMusic(v); + } +} + +struct { + Uint8 ascii; + Uint8 asciilc; + char *ch; +} atrans[] = { + {0x80, 0xA0, "A"},//А + {0x81, 0xA1, "B"},//Б + {0x82, 0xA2, "V"},//В + {0x83, 0xA3, "G"},//Г + {0x84, 0xA4, "D"},//Д + {0x85, 0xA5, "E"},//Е + {0x86, 0xA6, "ZH"},//Ж + {0x87, 0xA7, "Z"},//З + {0x88, 0xA8, "I"},//И + {0x89, 0xA9, "J"},//Й + {0x8A, 0xAA, "K"},//К + {0x8B, 0xAB, "L"},//Л + {0x8C, 0xAC, "M"},//М + {0x8D, 0xAD, "N"},//Н + {0x8E, 0xAE, "O"},//О + {0x8F, 0xAF, "P"},//П + {0x90, 0xE0, "R"},//Р + {0x91, 0xE1, "S"},//С + {0x92, 0xE2, "T"},//Т + {0x93, 0xE3, "U"},//У + {0x94, 0xE4, "F"},//Ф + {0x95, 0xE5, "H"},//Ð¥ + {0x96, 0xE6, "C"},//Ц + {0x97, 0xE7, "CH"},//Ч + {0x98, 0xE8, "SH"},//Ш + {0x99, 0xE9, "SCH"},//Щ + {0x9A, 0xEA, "X"},//Ъ + {0x9B, 0xEB, "Y"},//Ы + {0x9C, 0xEC, "J"},//Ь + {0x9D, 0xED, "E"},//Э + {0x9E, 0xEE, "JU"},//Ю + {0x9F, 0xEF, "JA"},//Я + {0} +}; + +char *get_trans_char (Uint8 c) +{ + int i = 0; + while (atrans[i].ascii) { + + if (atrans[i].ascii == c || atrans[i].asciilc == c) { + return atrans[i].ch; + } + i++; + } + return NULL; +} + +void trans_ascii_str (char *dest, char *src) +{ + char *p = dest; + int i; + for (i=0; i0) { + if (muscount < music_fade*1100/DELAY) { + Mix_FadeOutMusic(music_fade*1000); + } + muscount--; + if (muscount==0) { + if (music_random) F_randmus(g_music); + else F_nextmus(g_music); + F_freemus(); + F_loadmus(g_music); + S_startmusic(music_time); + } + } +} diff --git a/src/my.c b/src/my.c new file mode 100644 index 0000000..72f444d --- /dev/null +++ b/src/my.c @@ -0,0 +1,97 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include "glob.h" +#include "keyb.h" +#include "error.h" +#include + +void mysplitpath(const char* path, char* drv, char* dir, char* name, char* ext) +{ + const char* end; /* end of processed string */ + const char* p; /* search pointer */ + const char* s; /* copy pointer */ + + /* extract drive name */ + if (path[0] && path[1]==':') { + if (drv) { + *drv++ = *path++; + *drv++ = *path++; + *drv = '\0'; + } + } else if (drv) + *drv = '\0'; + + /* search for end of string or stream separator */ + for(end=path; *end && *end!=':'; ) + end++; + + /* search for begin of file extension */ + for(p=end; p>path && *--p!='\\' && *p!='/'; ) + if (*p == '.') { + end = p; + break; + } + + if (ext) + for(s=end; (*ext=*s++); ) + ext++; + + /* search for end of directory name */ + for(p=end; p>path; ) + if (*--p=='\\' || *p=='/') { + p++; + break; + } + + if (name) { + for(s=p; s 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include "files.h" +#include "memory.h" +#include "vga.h" +#include "error.h" +#include "keyb.h" +#include "view.h" +#include "dots.h" +#include "smoke.h" +#include "weapons.h" +#include "monster.h" +#include "fx.h" +#include "items.h" +#include "switch.h" +#include "player.h" +#include "misc.h" + +extern int hit_xv,hit_yv; + +#define PL_RAD 8 +#define PL_HT 26 + +#define PL_SWUP 4 +#define PL_FLYUP 4 + +#define PL_AIR 360 +#define PL_AQUA_AIR 1091 + +byte p_immortal=0,p_fly=0; + +int PL_JUMP=10,PL_RUN=8; + +int wp_it[11]={0,I_CSAW,0,I_SGUN,I_SGUN2,I_MGUN,I_LAUN,I_PLAS,I_BFG,I_GUN2,0}; + +enum{STAND,GO,DIE,SLOP,DEAD,MESS,OUT,FALL}; + +typedef void fire_f(int,int,int,int,int); + +player_t pl1,pl2; +static int aitime; +static void *aisnd[3]; +static void *pdsnd[5]; + +static void *spr[27*2],*snd[11]; +static char sprd[27*2]; +static void *wpn[11][6]; +static byte goanim[]="BDACDA", + dieanim[]="HHHHIIIIJJJJKKKKLLLLMMMM", + slopanim[]="OOPPQQRRSSTTUUVVWW"; + + +#pragma pack(1) +struct { + int ku,kd,kl,kr,kf,kj,kwl,kwr,kp; +} _keys; +#pragma pack() + +void PL_savegame(FILE* h) { + myfwrite(&pl1,1,sizeof(pl1)-sizeof(_keys),h);//myfwrite(&pl1,1,sizeof(pl1),h); + if(_2pl) myfwrite(&pl2,1,sizeof(pl2)-sizeof(_keys),h);//myfwrite(&pl2,1,sizeof(pl2),h); + myfwrite(&PL_JUMP,1,4,h);myfwrite(&PL_RUN,1,4,h);myfwrite(&p_immortal,1,1,h); +} + +void PL_loadgame(FILE* h) { + myfread(&pl1,1,sizeof(pl1)-sizeof(_keys),h);//myfread(&pl1,1,sizeof(pl1),h); + if(_2pl) myfread(&pl2,1,sizeof(pl2)-sizeof(_keys),h);//myfread(&pl2,1,sizeof(pl2),h); + myfread(&PL_JUMP,1,4,h);myfread(&PL_RUN,1,4,h);myfread(&p_immortal,1,1,h); +} + +static int nonz(int a) {return (a)?a:1;} + +static int firediry(player_t *p) { + if(p->f&PLF_UP) return -42; + if(p->f&PLF_DOWN) return 19; + return 0; +} + +static void fire(player_t *p) { + static fire_f *ff[11]={ + WP_pistol,WP_pistol,WP_pistol,WP_shotgun,WP_dshotgun, + WP_mgun,WP_rocket,WP_plasma,WP_bfgshot,WP_shotgun,WP_pistol}; + static int ft[11]={5,2,6,18,36,2,12,2,0,2,1}; + + if(p->cwpn) return; + if(p->wpn==8) { + if(!p->fire) + if(keys[p->kf] && p->cell>=40) + {Z_sound(snd[5],128);p->fire=21;p->cell-=40;p->drawst|=PL_DRAWWPN;return;} + else return; + if(p->fire==1) p->cwpn=12; + else return; + }else if(p->wpn==1) { + if(!p->csnd) { + if(!keys[p->kf]) {Z_sound(snd[7],128);p->csnd=13;return;} + } + if(keys[p->kf] && !p->fire) { + p->fire=2; + WP_chainsaw(p->o.x+((p->d)?4:-4),p->o.y,(g_dm)?9:3,p->id); + if(!p->csnd) {Z_sound(snd[8],128);p->csnd=29;} + }return; + }else if(p->fire) return; + if(keys[p->kf] || p->wpn==8) { + switch(p->wpn) { + case 2: case 5: + if(!p->ammo) return; + --p->ammo;p->drawst|=PL_DRAWWPN;break; + case 3: case 9: + if(!p->shel) return; + --p->shel;p->drawst|=PL_DRAWWPN;break; + case 4: + if(p->shel<2) return; + p->shel-=2;p->drawst|=PL_DRAWWPN;break; + case 6: + if(!p->rock) return; + --p->rock;p->drawst|=PL_DRAWWPN;break; + case 7: + if(!p->cell) return; + --p->cell;p->drawst|=PL_DRAWWPN;break; + case 10: + if(!p->fuel) return; + --p->fuel;p->drawst|=PL_DRAWWPN;break; + } + if(p->wpn==10) + WP_ognemet(p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30),p->o.y-15+firediry(p), + p->o.xv+p->o.vx,p->o.yv+p->o.vy,p->id); + else if(p->wpn>=1) ff[p->wpn] (p->o.x,p->o.y-15,p->o.x+((p->d)?30:-30), + p->o.y-15+firediry(p),p->id); + else WP_punch(p->o.x+((p->d)?4:-4),p->o.y,3,p->id); + p->fire=ft[p->wpn]; + if(p->wpn>=2) p->f|=PLF_FIRE; + } +} + +static void chgwpn(player_t *p) { + if(p->cwpn) return; + if(p->fire && p->wpn!=1) return; + if(keys[p->kwl]) { + do{ if(--p->wpn<0) p->wpn=10; }while(!(p->wpns&(1<wpn))); + p->cwpn=3; + }else if(keys[p->kwr]) { + do{ if(++p->wpn>10) p->wpn=0; }while(!(p->wpns&(1<wpn))); + p->cwpn=3; + } + if(p->cwpn) { + p->drawst|=PL_DRAWWPN;p->fire=0; + if(p->wpn==1) Z_sound(snd[6],128); + } +} + +static void jump(player_t *p,int st) { + if(Z_canbreathe(p->o.x,p->o.y,p->o.r,p->o.h)) { + if(p->airair=PL_AIR;p->drawst|=PL_DRAWAIR;} + }else { + if(--p->air < -9) { + p->air=0; + PL_hit(p,10,-3,HIT_WATER); + }else if((p->air&31)==0) { + FX_bubble(p->o.x,p->o.y-20,0,0,5); + } + p->drawst|=PL_DRAWAIR; + } + if(keys[p->kj]) { + if(p_fly) { + p->o.yv=-PL_FLYUP; + }else{ + if(Z_canstand(p->o.x,p->o.y,p->o.r)) p->o.yv=-PL_JUMP; + else if(st&Z_INWATER) p->o.yv=-PL_SWUP; + } + } +} + +int PL_isdead(player_t *p) { + switch(p->st) { + case DEAD: case MESS: + case OUT: + return 1; + } + return 0; +} + +void PL_init(void) { + p_immortal=0; + PL_JUMP=10;PL_RUN=8; + aitime=0; +} + +void PL_alloc(void) { + int i,j; + static char nm[][6]={ + "OOF", + "PLPAIN", + "PLDETH", + "SLOP", + "PDIEHI", + "BFG", + "SAWUP", + "SAWIDL", + "SAWFUL", + "SAWHIT", + "PLFALL" + }; + static char s[6]; + + for(i=0;i<27;++i) { + spr[i*2]=Z_getspr("PLAY",i,1,sprd+i*2); + spr[i*2+1]=Z_getspr("PLAY",i,2,sprd+i*2+1); + } + memcpy(s,"PWPx",4); + for(i=1;i<11;++i) { + s[3]=((i<10)?'0':('A'-10))+i; + for(j=0;j<6;++j) wpn[i][j]=Z_getspr(s,j,1,NULL); + } + for(i=0;i<11;++i) snd[i]=Z_getsnd(nm[i]); + memcpy(s,"AIx",4); + for(i=0;i<3;++i) { + s[2]=i+'1'; + aisnd[i]=Z_getsnd(s); + } + memcpy(s,"PLDTHx",6); + for(i=0;i<5;++i) { + s[5]=i+'1'; + pdsnd[i]=Z_getsnd(s); + } +} + +void PL_restore(player_t *p) { + p->o.xv=p->o.yv=p->o.vx=p->o.vy=0; + p->o.r=PL_RAD;p->o.h=PL_HT; + p->pain=0; + p->invl=p->suit=0; + switch(p->st) { + case DEAD: case MESS: case OUT: + case DIE: case SLOP: case FALL: + p->life=100;p->armor=0;p->air=PL_AIR; + p->wpns=5; + p->wpn=2; + p->ammo=50;p->fuel=p->shel=p->rock=p->cell=0; + p->amul=1; + } + p->st=STAND; + p->fire=p->cwpn=p->csnd=0; + p->f=0; + p->drawst=0xFF; + p->looky=0; + p->keys=(g_dm)?0x70:0; +} + +void PL_reset(void) { + pl1.st=pl2.st=DEAD; + pl1.frag=pl2.frag=0; +} + +void PL_spawn(player_t *p,int x,int y,char d) { + PL_restore(p); + p->o.x=x;p->o.y=y;p->d=d; + p->kills=p->secrets=0; +} + +int PL_hit(player_t *p,int d,int o,int t) { + if(!d) return 0; + switch(p->st) { + case DIE: case SLOP: + case DEAD: case MESS: + case OUT: case FALL: + return 0; + } + if(t==HIT_TRAP) {if(!p_immortal) {p->armor=0;p->life=-100;}} + else if(t!=HIT_ROCKET && t!=HIT_ELECTRO) { + if(p->id==-1) {if(o==-1) return 0;} + else if(o==-2) return 0; + } + if(t!=HIT_WATER && t!=HIT_ELECTRO) + DOT_blood(p->o.x,p->o.y-15,hit_xv,hit_yv,d*2); + else if(t==HIT_WATER) FX_bubble(p->o.x,p->o.y-20,0,0,d/2); + if(p_immortal || p->invl) return 1; + p->hit+=d; + p->hito=o; + return 1; +} + +void PL_damage(player_t *p) { + int i; + + if(!p->hit && p->life>0) return; + switch(p->st) { + case DIE: case SLOP: + case DEAD: case MESS: + case OUT: case FALL: + return; + } + i=p->hit*p->life/nonz(p->armor*3/4+p->life); + p->pain+=p->hit; + p->drawst|=PL_DRAWLIFE|PL_DRAWARMOR; + if((p->armor-=p->hit-i)<0) {p->life+=p->armor;p->armor=0;} + if((p->life-=i)<=0) { + if(p->life>-30) {p->st=DIE;p->s=0;Z_sound(pdsnd[rand()%5],128);} + else {p->st=SLOP;p->s=0;Z_sound(snd[3],128);} + if(p->amul>1) IT_spawn(p->o.x,p->o.y,I_BPACK); + if(!g_dm) { + if(p->keys&16) IT_spawn(p->o.x,p->o.y,I_KEYR); + if(p->keys&32) IT_spawn(p->o.x,p->o.y,I_KEYG); + if(p->keys&64) IT_spawn(p->o.x,p->o.y,I_KEYB); + } + for(i=1,p->wpns>>=1;i<11;++i,p->wpns>>=1) + if(i!=2) if(p->wpns&1) IT_spawn(p->o.x,p->o.y,wp_it[i]); + p->wpns=5;p->wpn=2; + p->f|=PLF_PNSND; + p->drawst|=PL_DRAWWPN; + if(g_dm && _2pl) { + if(p->id==-1) { + if(p->hito==-2) {++pl2.kills;++pl2.frag;} + else if(p->hito==-1) --pl1.frag; + }else{ + if(p->hito==-1) {++pl1.kills;++pl1.frag;} + else if(p->hito==-2) --pl2.frag; + } + pl1.drawst|=PL_DRAWFRAG; + if(_2pl) pl2.drawst|=PL_DRAWFRAG; + } + p->life=0;return; + } + return; +} + +void PL_cry(player_t *p) { + Z_sound(snd[(p->pain>20)?1:0],128); + p->f|=PLF_PNSND; +} + +int PL_give(player_t *p,int t) { + int i; + + switch(p->st) { + case DIE: case SLOP: + case DEAD: case MESS: case OUT: + return 0; + } + switch(t) { + case I_STIM: case I_MEDI: + if(p->life>=100) return 0; + if((p->life+=((t==I_MEDI)?25:10))>100) p->life=100; + p->drawst|=PL_DRAWLIFE;return 1; + case I_CLIP: + if(p->ammo>=200*p->amul) return 0; + if((p->ammo+=10)>200*p->amul) p->ammo=200*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_AMMO: + if(p->ammo>=200*p->amul) return 0; + if((p->ammo+=50)>200*p->amul) p->ammo=200*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_SHEL: + if(p->shel>=50*p->amul) return 0; + if((p->shel+=4)>50*p->amul) p->shel=50*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_SBOX: + if(p->shel>=50*p->amul) return 0; + if((p->shel+=25)>50*p->amul) p->shel=50*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_ROCKET: + if(p->rock>=50*p->amul) return 0; + if((++p->rock)>50*p->amul) p->rock=50*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_RBOX: + if(p->rock>=50*p->amul) return 0; + if((p->rock+=5)>50*p->amul) p->rock=50*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_CELL: + if(p->cell>=300*p->amul) return 0; + if((p->cell+=40)>300*p->amul) p->cell=300*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_CELP: + if(p->cell>=300*p->amul) return 0; + if((p->cell+=100)>300*p->amul) p->cell=300*p->amul; + p->drawst|=PL_DRAWWPN;return 1; + case I_BPACK: + if(p->amul==1) {p->amul=2;i=1;} else i=0; + i|=PL_give(p,I_CLIP); + i|=PL_give(p,I_SHEL); + i|=PL_give(p,I_ROCKET); + i|=PL_give(p,I_CELL); + return i; + case I_CSAW: + if(!(p->wpns&2)) {p->wpns|=2;p->drawst|=PL_DRAWWPN;return 1;} + return 0; + case I_GUN2: + i=PL_give(p,I_SHEL); + if(!(p->wpns&512)) {p->wpns|=512;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_SGUN: + i=PL_give(p,I_SHEL); + if(!(p->wpns&8)) {p->wpns|=8;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_SGUN2: + i=PL_give(p,I_SHEL); + if(!(p->wpns&16)) {p->wpns|=16;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_MGUN: + i=PL_give(p,I_AMMO); + if(!(p->wpns&32)) {p->wpns|=32;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_LAUN: + i=PL_give(p,I_ROCKET); + i|=PL_give(p,I_ROCKET); + if(!(p->wpns&64)) {p->wpns|=64;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_PLAS: + i=PL_give(p,I_CELL); + if(!(p->wpns&128)) {p->wpns|=128;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_BFG: + i=PL_give(p,I_CELL); + if(!(p->wpns&256)) {p->wpns|=256;i=1;} + p->drawst|=PL_DRAWWPN;return i; + case I_ARM1: + if(p->armor>=100) return 0; + p->armor=100;p->drawst|=PL_DRAWARMOR;return 1; + case I_ARM2: + if(p->armor>=200) return 0; + p->armor=200;p->drawst|=PL_DRAWARMOR;return 1; + case I_MEGA: + i=0; + if(p->life<200) {p->life=200;p->drawst|=PL_DRAWLIFE;i=1;} + if(p->armor<200) {p->armor=200;p->drawst|=PL_DRAWARMOR;i=1;} + return i; + case I_SUPER: + if(p->life<200) {p->life=min(p->life+100,200);p->drawst|=PL_DRAWLIFE;return 1;} + return 0; + case I_INVL: + p->invl=PL_POWERUP_TIME; + return 1; + case I_SUIT: + p->suit=PL_POWERUP_TIME; + return 1; + case I_AQUA: + if(p->air >= PL_AQUA_AIR) return 0; + p->air=PL_AQUA_AIR;p->drawst|=PL_DRAWAIR; + return 1; + case I_KEYR: + if(p->keys&16) return 0; + p->keys|=16;p->drawst|=PL_DRAWKEYS;return 1; + case I_KEYG: + if(p->keys&32) return 0; + p->keys|=32;p->drawst|=PL_DRAWKEYS;return 1; + case I_KEYB: + if(p->keys&64) return 0; + p->keys|=64;p->drawst|=PL_DRAWKEYS;return 1; + default: + return 0; + } +} + +void PL_act(player_t *p) { + int st; + + if(--aitime<0) aitime=0; + SW_press(p->o.x,p->o.y,p->o.r,p->o.h,4|p->keys,p->id); + if(!p->suit) if((g_time&15)==0) + PL_hit(p,Z_getacid(p->o.x,p->o.y,p->o.r,p->o.h),-3,HIT_SOME); + if(p->st!=FALL && p->st!=OUT) { + if(((st=Z_moveobj(&p->o))&Z_FALLOUT) && p->o.y>=FLDH*CELH+50) { + switch(p->st) { + case DEAD: case MESS: case DIE: case SLOP: + p->s=5;break; + default: + p->s=Z_sound(snd[10],128); + if(g_dm) --p->frag; + }p->st=FALL; + } + }else st=0; + if(st&Z_HITWATER) Z_splash(&p->o,PL_RAD+PL_HT); + if(p->f&PLF_FIRE) if(p->fire!=2) p->f-=PLF_FIRE; + if(keys[p->ku]) {p->f|=PLF_UP;p->looky-=5;} + else{ + p->f&=0xFFFF-PLF_UP; + if(keys[p->kd]) + {p->f|=PLF_DOWN;p->looky+=5;} + else {p->f&=0xFFFF-PLF_DOWN;p->looky=Z_dec(p->looky,5);} + } + if(keys[p->kp]) SW_press(p->o.x,p->o.y,p->o.r,p->o.h,1|p->keys,p->id); + if(p->fire) --p->fire; + if(p->cwpn) --p->cwpn; + if(p->csnd) --p->csnd; + if(p->invl) --p->invl; + if(p->suit) --p->suit; + switch(p->st) { + case DIE: + p->o.h=7; + if(!dieanim[++p->s]) {p->st=DEAD;MN_killedp();} + p->o.xv=Z_dec(p->o.xv,1); + break; + case SLOP: + p->o.h=6; + if(!slopanim[++p->s]) {p->st=MESS;MN_killedp();} + p->o.xv=Z_dec(p->o.xv,1); + break; + case GO: + chgwpn(p);fire(p);jump(p,st); + if(p_fly) + SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128); + if((p->s+=abs(p->o.xv)/2) >= 24) p->s%=24; + if(!keys[p->kl] && !keys[p->kr]) { + if(p->o.xv) p->o.xv=Z_dec(p->o.xv,1); + else p->st=STAND; + break; + } + if(p->o.xvkr]) {p->o.xv+=PL_RUN>>3;p->d=1;} + else if(PL_RUN>8) + SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32); + if(p->o.xv>-PL_RUN && keys[p->kl]) {p->o.xv-=PL_RUN>>3;p->d=0;} + else if(PL_RUN>8) + SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,32); + break; + case STAND: + chgwpn(p);fire(p);jump(p,st); + if(p_fly) + SMK_gas(p->o.x,p->o.y-2,2,3,p->o.xv+p->o.vx,p->o.yv+p->o.vy,128); + if(keys[p->kl]) {p->st=GO;p->s=0;p->d=0;} + else if(keys[p->kr]) {p->st=GO;p->s=0;p->d=1;} + break; + case DEAD: + case MESS: + case OUT: + p->o.xv=Z_dec(p->o.xv,1); + if(keys[p->ku] || keys[p->kd] || keys[p->kl] || keys[p->kr] || + keys[p->kf] || keys[p->kj] || keys[p->kp] || keys[p->kwl] || keys[p->kwr]) { + if(p->st!=OUT) MN_spawn_deadpl(&p->o,p->color,(p->st==MESS)?1:0); + PL_restore(p); + if(g_dm) {G_respawn_player(p);break;} + if(!_2pl) { + if(--p->lives==0) {G_start();break;} + else{p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;} + p->drawst|=PL_DRAWLIVES; + } + if(p->id==-1) + {p->o.x=dm_pos[0].x;p->o.y=dm_pos[0].y;p->d=dm_pos[0].d;} + else {p->o.x=dm_pos[1].x;p->o.y=dm_pos[1].y;p->d=dm_pos[1].d;} + }break; + case FALL: + if(--p->s<=0) p->st=OUT; + break; + } +} + +static int standspr(player_t *p) { + if(p->f&PLF_UP) return 'X'; + if(p->f&PLF_DOWN) return 'Z'; + return 'E'; +} + +static int wpnspr(player_t *p) { + if(p->f&PLF_UP) return 'C'; + if(p->f&PLF_DOWN) return 'E'; + return 'A'; +} + +void PL_draw(player_t *p) { + int s,w,wx,wy; + static int wytab[]={-1,-2,-1,0}; + + s='A';w=0;wx=wy=0; + switch(p->st) { + case STAND: + if(p->f&PLF_FIRE) {s=standspr(p)+1;w=wpnspr(p)+1;} + else if(p->pain) {s='G';w='A';wx=p->d?2:-2;wy=1;} + else {s=standspr(p);w=wpnspr(p);} + break; + case DEAD: + s='N';break; + case MESS: + s='W';break; + case GO: + if(p->pain) {s='G';w='A';wx=p->d?2:-2;wy=1;} + else { + s=goanim[p->s/8];w=(p->f&PLF_FIRE)?'B':'A'; + wx=p->d?2:-2;wy=1+wytab[s-'A']; + } + break; + case DIE: + s=dieanim[p->s];break; + case SLOP: + s=slopanim[p->s];break; + case OUT: + s=0;break; + } + if(p->wpn==0) w=0; + if(w) Z_drawspr(p->o.x+wx,p->o.y+wy,wpn[p->wpn][w-'A'],p->d); + if(s) Z_drawmanspr(p->o.x,p->o.y,spr[(s-'A')*2+p->d],sprd[(s-'A')*2+p->d],p->color); +} + +void *PL_getspr(int s,int d) { + return spr[(s-'A')*2+d]; +} + +static void chk_bfg(player_t *p,int x,int y) { + int dx,dy; + + if(aitime) return; + switch(p->st) { + case DIE: case SLOP: case FALL: + case DEAD: case MESS: case OUT: + return; + } + dx=p->o.x-x;dy=p->o.y-p->o.h/2-y; + if(dx*dx+dy*dy<=1600) { + aitime=Z_sound(aisnd[rand()%3],128)*4; + } +} + +void bfg_fly(int x,int y,int o) { +// if(!g_dm) return; + if(o!=-1) chk_bfg(&pl1,x,y); + if(_2pl) if(o!=-2) chk_bfg(&pl2,x,y); + if(o==-1 || o==-2) MN_warning(x-50,y-50,x+50,y+50); +} + +void PL_drawst(player_t *p) { + V_setrect(WD,120,w_o,HT);Z_clrst(); + int i; + + if(p->drawst&PL_DRAWAIR) + if (p->airair); + if(p->drawst&PL_DRAWLIFE) + Z_drawstprcnt(0,p->life); + if(p->drawst&PL_DRAWARMOR) + Z_drawstprcnt(1,p->armor); + if(p->drawst&PL_DRAWWPN) { + switch(p->wpn) { + case 2: case 5: + i=p->ammo;break; + case 3: case 4: case 9: + i=p->shel;break; + case 6: + i=p->rock;break; + case 10: + i=p->fuel;break; + case 7: case 8: + i=p->cell;break; + } + Z_drawstwpn(p->wpn,i); + } + if(p->drawst&PL_DRAWFRAG) Z_drawstnum(p->frag); + if(p->drawst&PL_DRAWKEYS) Z_drawstkeys(p->keys); + if(!_2pl) if(p->drawst&PL_DRAWLIVES) Z_drawstlives(p->lives); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..e56357c --- /dev/null +++ b/src/player.h @@ -0,0 +1,93 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Player data and functions + +#define PL_DRAWLIFE 1 +#define PL_DRAWARMOR 2 +#define PL_DRAWWPN 4 +#define PL_DRAWFRAG 8 +#define PL_DRAWAIR 16 +#define PL_DRAWKEYS 32 +#define PL_DRAWLIVES 64 + +#define PLK_U 1 +#define PLK_D 2 +#define PLK_L 4 +#define PLK_R 8 +#define PLK_F 16 +#define PLK_J 32 +#define PLK_P 64 +#define PLK_W 128 +#define PLK_WL 1 +#define PLK_WR 2 + +#define PLF_FIRE 1 +#define PLF_PNSND 2 +#define PLF_UP 4 +#define PLF_DOWN 8 + +#define PL_POWERUP_TIME 546 + +#pragma pack(1) +typedef struct{ + obj_t o; + int looky; + int st,s; + int life,armor,hit,hito; + int pain,air; + int invl,suit; + char d; + //byte ku,kd,kl,kr,kf,kj,kwl,kwr,kp; + int frag,ammo,shel,rock,cell,fuel,kills,secrets; + byte fire,cwpn,csnd; + byte amul; + word wpns; + char wpn; + byte f; + byte drawst; + byte color; + int id; + byte keys; + char lives; + int ku,kd,kl,kr,kf,kj,kwl,kwr,kp; +}player_t; +#pragma pack() + +void PL_init(void); +void PL_alloc(void); +void PL_spawn(player_t *,int,int,char); +int PL_hit(player_t *,int,int,int); +int PL_isdead(player_t *); +void PL_act(player_t *); +void PL_draw(player_t *); +void PL_drawst(player_t *); +void PL_cry(player_t *); +void PL_damage(player_t *); +int PL_give(player_t *,int); +void G_respawn_player(player_t *); + +void PL_reset(void); +void *PL_getspr(int c,int d); + +extern byte p_immortal; +extern player_t pl1,pl2; diff --git a/src/redraw.c b/src/redraw.c new file mode 100644 index 0000000..363bec0 --- /dev/null +++ b/src/redraw.c @@ -0,0 +1,117 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +//#include "..\averr.h" +#include "vga.h" +#include "glob.h" +/* +#define MAXRECT 500 + +typedef struct{short x,w,y,h;}rect; + +static rect *rt,*rp; +static redraw_f *fn; +static short sl,st,sr,sb; + + +void *RD_init(short x,short w,short y,short h) { + rect *p; + + if(!(p=malloc((MAXRECT*2+1)*sizeof(rect)))) + {error(0,0,ENOMEM,NULL,NULL);return NULL;}//{error(EZ_VGALIB,ET_STD,ENOMEM,NULL,NULL);return NULL;} + p->x=x;p->w=x+w-1;p->y=y;p->h=y+h-1; + memset(p+1,0,MAXRECT*2*sizeof(rect)); + return p; +} + +void RD_start(void *p,redraw_f *f) { + rt=p;fn=f; + sl=rt->x;sr=rt->w; + st=rt->y;sb=rt->h; + ++rt; + rp=rt; +} + +static void add(short x,short r,short y,short b) { + int i; + short rx,rr,ry,rb; + + for(i=0;i(rr=(rx=rp[i].x)+rp[i].w-1)) continue; + if(r(rb=(ry=rp[i].y)+rp[i].h-1)) continue; + if(brr) add(rr+1,r,y,b); + if(yrb) add(max(rx,x),min(rr,r),rb+1,b); + return; + } + for(i=0;isr) return; + if(x+w<=sl) return; + if(y>sb) return; + if(y+h<=st) return; + w+=x-1;h+=y-1; + if(xsr) w=sr; + if(h>sb) h=sb; + add(x,w,y,h); +} + +void RD_spr(short x,short y,vgaimg *v) { + RD_rect(x-v->sx,v->w,y-v->sy,v->h); +} + +void RD_spr2(short x,short y,vgaimg *v) { + RD_rect(x-v->w+v->sx,v->w,y-v->sy,v->h); +} + +void RD_end(void) { + int i; + + V_setscr(scrbuf); + rp=rt+MAXRECT; + for(i=0;i 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include "files.h" +#include "memory.h" +#include "vga.h" +#include "error.h" +#include "sound.h" +#include "view.h" +#include "smoke.h" +#include "fx.h" +#include "misc.h" + +#define MAXSR 20 + +#define SMSN 10 +#define FLSN 8 + +#pragma pack(1) +typedef struct{ + int x,y,xv,yv; + byte t,s; + short o; +}smoke_t; +#pragma pack() + +static smoke_t sm[MAXSMOK]; +static int sr_r,sxr[MAXSR],syr[MAXSR]; +static int lsm; + +static void *spr[SMSN],*fspr[FLSN]; +static void *burnsnd; +static int burntm=0; + +byte flametab[16]={ +0xBC,0xBA,0xB8,0xB6,0xB4,0xB2,0xB0,0xD5,0xD6,0xD7,0xA1,0xA0,0xE3,0xE2,0xE1,0xE0 +}; + +void SMK_savegame(FILE* h) { + int i,n; + + for(i=n=0;i=MAXSMOK) lsm=0; +} + +void SMK_act(void) { + int i,ox,oy; + static obj_t o; + + if(burntm) --burntm; + for(i=0;i>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + } + ox=sm[i].x;oy=sm[i].y; + sm[i].x+=sm[i].xv/2;sm[i].y+=sm[i].yv/2; + if(!Z_canfit(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + } + if(sm[i].o!=-3) { + o.x=sm[i].x>>8;o.y=sm[i].y>>8; + o.xv=sm[i].xv>>10;o.yv=sm[i].yv>>10; + o.vx=o.vy=0; + if(!(g_time&3)) Z_hit(&o,1,sm[i].o,HIT_FLAME); + } + }else{ + ox=sm[i].x;oy=sm[i].y; + sm[i].xv=Z_dec(sm[i].xv,20); + sm[i].yv=Z_dec(sm[i].yv,20); + sm[i].x+=sm[i].xv;sm[i].y+=sm[i].yv; + if(!Z_canfit(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + }else if(Z_inwater(sm[i].x>>8,(sm[i].y>>8)+3,3,7)) { + sm[i].x=ox;sm[i].y=oy; + } + } + --sm[i].t; + } +} + +void SMK_draw(void) { + int i,s; + + for(i=0;i=(SMSN-1)*3) s=0; else s=SMSN-1-s/3; + V_sprf((sm[i].x>>8)-w_x+WD/2,(sm[i].y>>8)-w_y+HT/2+1+w_o,spr[s],&smoke_sprf);//V_sprf((sm[i].x>>8)-w_x+100,(sm[i].y>>8)-w_y+50+w_o,spr[s],&smoke_sprf); + break; + case 1: + if((s=sm[i].t)>=(FLSN-1)) s=0; else s=FLSN-1-s; + V_sprf((sm[i].x>>8)-w_x+WD/2,(sm[i].y>>8)-w_y+HT/2+1+w_o,fspr[s],&flame_sprf);//V_sprf((sm[i].x>>8)-w_x+100,(sm[i].y>>8)-w_y+50+w_o,fspr[s],&flame_sprf); + break; + } +} + +void SMK_add(int x,int y,int xv,int yv,byte t,byte s,short o) { + int i; + + if(!Z_canfit(x>>8,(y>>8)+3,3,7)) return; + if(Z_inwater(x>>8,(y>>8)+3,3,7)) {FX_bubble(x>>8,y>>8,xv,yv,1);return;} + i=lsm; + sm[i].x=x;sm[i].y=y; + sm[i].xv=xv;sm[i].yv=yv; + sm[i].t=t;sm[i].s=s; + sm[i].o=o; + inclast(); +} + +void SMK_gas(int x0,int y0,int xr,int yr,int xv,int yv,int k) { + int i,x,y; + static int sxv,syv; + + xv=-xv;yv=-yv; + sxv=xv*k;syv=yv*k; + k=max(abs(xv),abs(yv)); + if(!k) return; + for(i=0;i<=k;i+=3) { + x=((xv*i/k+x0)<<8)+sxr[sr_r]*xr; + y=((yv*i/k+y0)<<8)+syr[sr_r]*yr; + if(++sr_r>=MAXSR) sr_r=0; + SMK_add(x,y,sxv,syv,SMSN*3,0,-3); + } +} + +void SMK_flame(int x0,int y0,int ox,int oy,int xr,int yr,int xv,int yv,int k,int o) { + int i,x,y; + static int sxv,syv; + + sxv=xv*k;syv=yv*k; + xv=xv-(ox<<8);yv=yv-(oy<<8); + k=max(abs(xv),abs(yv)); + if(!k) return; + if(!burntm) burntm=Z_sound(burnsnd,128); + for(i=0;i<=k;i+=200) { + x=xv*i/k+(x0<<8)+sxr[sr_r]*xr; + y=yv*i/k+(y0<<8)+syr[sr_r]*yr; + if(++sr_r>=MAXSR) sr_r=0; + SMK_add(x,y,sxv,syv,FLSN,1,o); + } +} diff --git a/src/smoke.h b/src/smoke.h new file mode 100644 index 0000000..e516117 --- /dev/null +++ b/src/smoke.h @@ -0,0 +1,33 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Smoke + +#define MAXSMOK 500 + +void SMK_init(void); +void SMK_alloc(void); +void SMK_act(void); +void SMK_draw(void); +void SMK_add(int x,int y,int xv,int yv,byte t,byte s,short o); +void SMK_gas(int x,int y,int rx,int ry,int xv,int yv,int k); +void SMK_flame(int x,int y,int ox,int oy,int rx,int ry,int xv,int yv,int k,int o); diff --git a/src/sound.c b/src/sound.c new file mode 100644 index 0000000..ab92524 --- /dev/null +++ b/src/sound.c @@ -0,0 +1,156 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include "files.h" +#include "sound.h" +#include +#include + +#define NUM_CHANNELS 16 +#define NUM_CHUNKS 300 + +short snd_vol = 50; + +int snddisabled = 1; + +struct { + snd_t *s; + Mix_Chunk *c; +} chunks[NUM_CHUNKS]; + +void S_init(void) +{ + if (!SDL_WasInit(SDL_INIT_AUDIO)) { + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + fprintf(stderr, "\nUnable to initialize audio: %s\n", SDL_GetError()); + snddisabled=1; + return; + } + + if (Mix_OpenAudio(22050, AUDIO_S16, 1, 1000) < 0) { + fprintf(stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError()); + snddisabled=1; + return; + } + + if (Mix_AllocateChannels(NUM_CHANNELS)!=NUM_CHANNELS) { + fprintf(stderr, "Error allocation channels: %s\n", Mix_GetError()); + snddisabled=1; + return; + } + } + + int i; + for (i=0; ilen; + SDL_AudioCVT cvt; + SDL_BuildAudioCVT(&cvt, AUDIO_S8, 1, s->rate, AUDIO_S16, 1, 22050); + if (!(cvt.buf = malloc(dlen*cvt.len_mult))) ERR_fatal("Out of memory\n");; + memcpy(cvt.buf, data, dlen); + cvt.len = dlen; + SDL_ConvertAudio(&cvt); + + Mix_Chunk *chunk; + if (!(chunk = malloc(sizeof(Mix_Chunk)))) ERR_fatal("Out of memory\n");; + chunk->abuf=cvt.buf; + chunk->alen=cvt.len_cvt; + chunk->allocated=0; + chunk->volume=(float)v/255*SDL_MIX_MAXVOLUME; + + chunks[fi].s = s; + chunks[fi].c = chunk; + + return chunk; +} + +void free_chunks() +{ + if (snddisabled) return; + Mix_HaltChannel(-1); + int i; + for (i=0; iabuf); + free(chunks[i].c); + chunks[i].c = NULL; + chunks[i].s = NULL; + } + } +} + +short S_play(snd_t *s,short c,unsigned r,short v) +{ + if (snddisabled) return 0; + Mix_Chunk *chunk = get_chunk(s,r,v); + if (chunk==NULL) return 0; + return Mix_PlayChannel(c, chunk, 0); +} + +void S_stop(short c) +{ + Mix_HaltChannel(c); +} + +void S_volume(int v) +{ + if (snddisabled) return; + snd_vol=v; + if (snd_vol>128) snd_vol=128; + if (snd_vol<0) snd_vol=0; + Mix_Volume(-1, snd_vol); +} + +void S_wait() +{ + if (snddisabled) return; + while (Mix_Playing(-1)) { + SDL_Delay(10); + } +} diff --git a/src/sound.h b/src/sound.h new file mode 100644 index 0000000..6ce65e3 --- /dev/null +++ b/src/sound.h @@ -0,0 +1,76 @@ +/* + Управление звуком и музыкой для DOS4GW + Версия 1.0 + Copyright (C) Алексей Волынсков, 1996 + + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// заголовок инструмента (DMI) +#pragma pack(1) +typedef struct{ + unsigned int len, // длина в байтах + rate, // частота в Гц. + lstart, // начало повтора в байтах от начала данных + llen; // длина повтора в байтах +}snd_t; +#pragma pack(1) + +void S_init(void); + +void S_done(void); + +// проиграть звук s на канале c (1-8), частоте r и громкости v (0-255) +// возвращает номер канала, на котором играется звук +// если c==0, то звук попадет в любой свободный канал +// r - это относительная частота (обычно 1024) +short S_play(snd_t *s,short c,unsigned r,short v); + +// остановить звук на канале c (1-8) +void S_stop(short c); + +void S_startmusic(int); + +void S_stopmusic(void); + +// громкость звука и музыки (0-128) +extern short snd_vol,mus_vol; + +void S_volumemusic(int v); +void S_volume(int v); +void free_chunks(); +void S_wait(); + +extern char music_random; +extern int music_time; +extern int music_fade; + +void F_freemus(void); +void S_initmusic(void); +void S_donemusic(void); + +#ifdef __cplusplus +} +#endif diff --git a/src/superdm.wad b/src/superdm.wad new file mode 100644 index 0000000..996f046 Binary files /dev/null and b/src/superdm.wad differ diff --git a/src/switch.c b/src/switch.c new file mode 100644 index 0000000..51e6eb0 --- /dev/null +++ b/src/switch.c @@ -0,0 +1,312 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include "files.h" +#include "view.h" +#include "bmap.h" +#include "switch.h" +#include "player.h" +#include "misc.h" +#include "map.h" + +#define MAXSW 100 + +extern map_block_t blk; + +#pragma pack(1) +typedef struct{ + byte x,y; + byte t,tm; + byte a,b,c,d; + byte f; +}sw_t; +#pragma pack() + +static sw_t sw[MAXSW]; + +static void *sndswn,*sndswx,*sndnoway,*sndbdo,*sndbdc,*sndnotele; +static int swsnd; + +int sw_secrets; + +void SW_savegame(FILE* h) { + int n; + + for(n=MAXSW;--n;) if(sw[n].t) break; + ++n;myfwrite(&n,1,4,h);myfwrite(sw,1,n*sizeof(sw[0]),h); + myfwrite(&sw_secrets,1,4,h); +} + +void SW_loadgame(FILE* h) { + int n; + + myfread(&n,1,4,h);myfread(sw,1,n*sizeof(sw[0]),h); + myfread(&sw_secrets,1,4,h); +} + +int SW_load(FILE* h) { + int i; + + switch(blk.t) { + case MB_SWITCH2: + sw_secrets=0; + for(i=0;i0;++i,blk.sz-=sizeof(sw_t)) { + myfread(sw+i,1,sizeof(sw_t),h); + sw[i].tm=0;sw[i].d=0; + sw[i].f|=0x80; + if(sw[i].t==SW_SECRET) ++sw_secrets; + } + return 1; + }return 0; +} + +void SW_alloc(void) { + sndswn=Z_getsnd("SWTCHN"); + sndswx=Z_getsnd("SWTCHX"); + sndnoway=Z_getsnd("NOWAY"); + sndbdo=Z_getsnd("BDOPN"); + sndbdc=Z_getsnd("BDCLS"); + sndnotele=Z_getsnd("NOTELE"); +} + +void SW_init(void) { + int i; + + for(i=0;i=FLDW || y>=FLDH) return; + if(fld[y][x]!=cht) return; + ex=x+1; + for(;x && fld[y][x-1]==cht;--x); + for(;exy)>=FLDH*CELH+o->h) return; + if((x=o->x)<0 || o->x>FLDW*CELW) return; + sx=(x-o->r)/CELW; + sy=(y-o->h+1)/CELH; + x=(x+o->r)/CELW; + y=(y-o->h/2)/CELH; + for(i=sx;i<=x;++i) + for(j=sy;j<=y;++j) + if(fld[j][i]==5) { + cht=5;chto=255;f_ch=0; + door(i,j); + } +} + +void Z_untrap(byte t) { + byte *p; + word n; + + for(p=(byte*)fld,n=FLDW*FLDH;n;--n,++p) + if(*p==255) *p=t; +} + +static void opendoor(int i) { + int j; + + swsnd=Z_sound(sndbdo,128); + j=fldf[sw[i].b][sw[i].a]; + cht=2;chto=3;chf=0;f_ch=1; + door(sw[i].a,sw[i].b); + fldf[sw[i].b][sw[i].a]=j; + fld_need_remap=1; +} + +static int shutdoor(int i) { + int j; + + cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1; + door(sw[i].a,sw[i].b); + cht=255; + if(Z_chktrap(0,0,-3,HIT_SOME)) { + j=fldf[sw[i].b][sw[i].a]; + chto=3;chf=0;f_ch=1; + door(sw[i].a,sw[i].b); + fldf[sw[i].b][sw[i].a]=j; + return 0; + } + chto=2; + door(sw[i].a,sw[i].b); + fld_need_remap=1; + swsnd=Z_sound(sndbdc,128); + return 1; +} + +void SW_act(void) { + int i; + + if(swsnd) --swsnd; + for(i=0;i=sx && sw[i].x<=x && sw[i].y>=sy && sw[i].y<=y && ((sw[i].f&0x8F)&t)) { + if(sw[i].f&0x70) if((sw[i].f&(t&0x70))!=(sw[i].f&0x70)) continue; + switch(sw[i].t) { + case SW_EXIT: + g_exit=1;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break; + case SW_EXITS: + g_exit=2;sw[i].tm=9;swsnd=Z_sound(sndswx,128);break; + case SW_DOOR: case SW_DOOR5: + switch(fld[sw[i].b][sw[i].a]) { + case 2: + opendoor(i);sw[i].tm=9;sw[i].d=doortime(sw[i].t);break; + case 3: + if(shutdoor(i)) {sw[i].tm=9;sw[i].d=0;} + else { + if(!swsnd) swsnd=Z_sound(sndnoway,128); + sw[i].d=2; + }break; + }break; + case SW_PRESS: + sw[i].tm=9; + SW_press((dword)sw[i].a*8+4,(dword)sw[i].b*8+12,8,16,(t&0x70)|0x80,o); + break; + case SW_TELE: + if(o < -2) break; + if(!Z_canfit((dword)sw[i].a*8+4,(dword)sw[i].b*8+7,r,h)) { + if(!swsnd) swsnd=Z_sound(sndnotele,128); + break; + }Z_teleobj(o,(dword)sw[i].a*8+4,(dword)sw[i].b*8+7); + sw[i].tm=1; + break; + case SW_OPENDOOR: + if(fld[sw[i].b][sw[i].a]!=2) break; + opendoor(i); + sw[i].tm=1; + break; + case SW_SHUTDOOR: + if(fld[sw[i].b][sw[i].a]!=3) break; + if(shutdoor(i)) {sw[i].tm=1;sw[i].d=0;} + else { + if(!swsnd) swsnd=Z_sound(sndnoway,128); + sw[i].d=2; + }break; + case SW_SHUTTRAP: case SW_TRAP: + if(fld[sw[i].b][sw[i].a]!=3) break; + cht=3;chto=255;chf=fldf[sw[i].b][sw[i].a];f_ch=1; + door(sw[i].a,sw[i].b); + Z_chktrap(1,100,-3,HIT_TRAP); + cht=255;chto=2; + door(sw[i].a,sw[i].b); + fld_need_remap=1; + swsnd=Z_sound(sndswn,128); + sw[i].tm=1;sw[i].d=20; + break; + case SW_LIFT: + if(fld[sw[i].b][sw[i].a]==10) { + cht=10;chto=9;f_ch=0; + }else if(fld[sw[i].b][sw[i].a]==9) { + cht=9;chto=10;f_ch=0; + }else break; + door(sw[i].a,sw[i].b); + fld_need_remap=1; + swsnd=Z_sound(sndswx,128); + sw[i].tm=9; + break; + case SW_LIFTUP: + if(fld[sw[i].b][sw[i].a]!=10) break; + cht=10;chto=9;f_ch=0; + door(sw[i].a,sw[i].b); + fld_need_remap=1; + swsnd=Z_sound(sndswx,128); + sw[i].tm=1; + break; + case SW_LIFTDOWN: + if(fld[sw[i].b][sw[i].a]!=9) break; + cht=9;chto=10;f_ch=0; + door(sw[i].a,sw[i].b); + fld_need_remap=1; + swsnd=Z_sound(sndswx,128); + sw[i].tm=1; + break; + case SW_SECRET: + if(o!=-1 && o!=-2) break; + if(o==-1) ++pl1.secrets; + else ++pl2.secrets; + sw[i].tm=1;sw[i].t=0;break; + } + if(sw[i].tm) + {fldb[sw[i].y][sw[i].x]=walswp[fldb[sw[i].y][sw[i].x]];p=1;} + if(sw[i].tm==1) sw[i].tm=0; + } + } + return p; +} diff --git a/src/switch.h b/src/switch.h new file mode 100644 index 0000000..eda6686 --- /dev/null +++ b/src/switch.h @@ -0,0 +1,39 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Switches + +#include + +enum{ + SW_NONE,SW_EXIT,SW_EXITS,SW_OPENDOOR,SW_SHUTDOOR,SW_SHUTTRAP, + SW_DOOR,SW_DOOR5,SW_PRESS,SW_TELE,SW_SECRET,SW_LIFTUP,SW_LIFTDOWN,SW_TRAP, + SW_LIFT +}; + +void SW_init(void); +void SW_alloc(void); +int SW_load(FILE*); +void SW_act(void); +int SW_press(int x,int y,int r,int h,byte t,int o); + +void SW_cheat_open(void); diff --git a/src/things.h b/src/things.h new file mode 100644 index 0000000..b93142f --- /dev/null +++ b/src/things.h @@ -0,0 +1,53 @@ +/*************************************************************************\ +* * +* Типы предметов в картах Doom'а 2D версии 1.22 alpha * +* * +* Prikol Software 28.VII.1996 * +* * +* Разрешается свободно распространять этот файл, при условии сохранения * +* ссылки на Prikol Software и даты выпуска файла. * +* * +\*************************************************************************/ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// флаги +#define THF_DIR 1 // направление: 1=вправо 0=влево +#define THF_DM 16 // появляется только в DeathMatch'е + +enum{TH_NONE=0, + TH_PLR1,TH_PLR2,TH_DMSTART, + TH_CLIP=100,TH_SHEL,TH_ROCKET,TH_CELL,TH_AMMO,TH_SBOX,TH_RBOX,TH_CELP, + TH_STIM,TH_MEDI,TH_BPACK, + TH_CSAW,TH_SGUN,TH_SGUN2,TH_MGUN,TH_LAUN,TH_PLAS,TH_BFG, + TH_ARM1,TH_ARM2,TH_MEGA,TH_INVL,TH_AQUA, + TH_RKEY,TH_GKEY,TH_BKEY, + TH_SUIT,TH_SUPER, + TH_RTORCH,TH_GTORCH,TH_BTORCH, + TH_GOR1,TH_FCAN, + TH_GUN2, + TH__LASTI, + TH_DEMON=200,TH_IMP,TH_ZOMBY,TH_SERG,TH_CYBER,TH_CGUN, + TH_BARON,TH_KNIGHT,TH_CACO,TH_SOUL,TH_PAIN,TH_SPIDER,TH_BSP, + TH_MANCUB,TH_SKEL,TH_VILE,TH_FISH,TH_BARREL,TH_ROBO,TH_MAN, + TH__LASTM +}; diff --git a/src/vga.c b/src/vga.c new file mode 100644 index 0000000..e06baf4 --- /dev/null +++ b/src/vga.c @@ -0,0 +1,358 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include "vga.h" +#include +#include "error.h" +#include "view.h" + + +// адрес экранного буфера +unsigned char *scra; + +// виртуальный экран +unsigned char scrbuf[64000]; + + +int SCRW = 800; +int SCRH = 600; + +SDL_Surface* screen = NULL; + +int cx1,cx2,cy1,cy2; + +char fullscreen = OFF; + +#define HQ 2 + +short V_init(void) +{ + Uint32 flags = SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_HWPALETTE; + if (fullscreen) flags = flags | SDL_FULLSCREEN; + screen = SDL_SetVideoMode(SCRW, SCRH, 8, flags); + if (!screen) ERR_failinit("Unable to set video mode: %s\n", SDL_GetError()); + SCRW /= HQ; + SCRH /= HQ; + return 0; +} + +// переключение в текстовый режим +void V_done(void) +{ + SDL_Quit(); +} + +void draw_rect (int x, int y, int w, int h, int c) +{ + SDL_Rect dstrect; + dstrect.x = x*HQ; + dstrect.y = y*HQ; + dstrect.w = w*HQ; + dstrect.h = h*HQ; + SDL_FillRect(screen, &dstrect, c); +} + +// установить область вывода +void V_setrect(short x,short w,short y,short h) +{ + SDL_Rect r; + r.x=x*HQ; + r.y=y*HQ; + r.w=w*HQ; + r.h=h*HQ; + SDL_SetClipRect(screen, &r); + SDL_GetClipRect(screen, &r); + cx1 = x; + cx2 = x+w-1; + cy1 = y; + cy2 = y+h-1; + if (cx1<0) cx1=0; + if (cx2>=SCRW) cx2=SCRW-1; + if (cy1<0) cy1=0; + if (cy2>=SCRH) cy2=SCRH-1; +} + +void putpixel(int x, int y, Uint8 color) +{ + if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { + x*=HQ; + y*=HQ; + Uint8 *p = (Uint8 *)screen->pixels + y*screen->pitch + x; + *p = color; + *(p+1) = color; + p += screen->pitch; + *p = color; + *(p+1) = color; + } +} + +byte getpixel(int x, int y) +{ + if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { + x*=HQ; + y*=HQ; + return *((Uint8 *)screen->pixels + y*screen->pitch + x); + } + return 0; +} + +void mappixel(int x,int y,byte* cmap) +{ + byte c = getpixel(x,y); + putpixel(x,y,cmap[c]); +} + +int offx = 0; +int offy = 0; + +void V_center(int f) +{ + if (f) V_offset(SCRW/2-320/2, SCRH/2-200/2); + else V_offset(0, 0); +} + +void V_offset(int ox, int oy) +{ + offx=ox; + offy=oy; +} + +void draw_spr(short x,short y,vgaimg *i, int d, int c) +{ + if (i==NULL) return; + x += offx; + y += offy; + if (d & 1) x=x-i->w+i->sx; else x-=i->sx; + if (d & 2) y=y-i->h+i->sy; else y-=i->sy; + if(x+i->w>=cx1 && x<=cx2 && y+i->h>=cy1 && y<=cy2) { + int lx, ly; + byte *p = (byte*)i + sizeof(vgaimg); + for (ly=0; lyh; ly++) { + for(lx=0; lxw; lx++) { + int rx,ry; + rx = (d & 1) ? (i->w-lx-1) : (rx=lx); + ry = (d & 2) ? (i->h-ly-1) : (ry=ly); + if (*p) { + byte t = *p; + if (c) if (t>=0x70 && t<=0x7F) t=t-0x70+c; + putpixel(x+rx,y+ry,t); + } + p++; + } + } + } +} + +void V_rotspr (int x, int y, vgaimg* i, int d) +{ + x+=i->w*((d&1)?1:0); + y+=i->h*((d&2)?1:0); + draw_spr(x,y,i,d,0); +} + +void V_pic(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i, 0, 0); +} + +void V_manspr(int x,int y,void *p, unsigned char c) +{ + draw_spr(x,y,p, 0, c); +} + +void V_manspr2(int x,int y,void *p, unsigned char c) +{ + draw_spr(x,y,p, 1, c); +} + +// вывести точку цвета c в координатах (x,y) +void V_dot(short x,short y, unsigned char c) +{ + putpixel(x,y,c); +} + + +extern byte bright[256]; +extern byte flametab[16]; +extern byte mixmap[256][256]; + +void smoke_sprf(int x, int y, byte c) +{ + byte t = getpixel(x,y); + c = c + bright[t]; + c += 0x60; + c ^= 0xF; + putpixel(x,y,mixmap[c][t]); +} + +void flame_sprf(int x, int y, byte c) +{ + byte t = getpixel(x,y); + c = c + bright[t]; + putpixel(x,y,flametab[c]); +} + +void V_sprf(short x,short y,vgaimg *i,spr_f *f) +{ + if (i==NULL) return; + x-=i->sx; + y-=i->sy; + int cx, cy; + byte *p = (byte*)i; + p+=sizeof(vgaimg); + for (cy=y; cyh; cy++) { + for(cx=x; cxw; cx++) { + if (*p) { + (*f)(cx, cy, *p); + } + p++; + } + } +} + +void V_spr(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i,0, 0); +} + +void V_spr2(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i,1,0); +} + +void V_clr(short x,short w,short y,short h,unsigned char c) +{ + draw_rect(x,y,w,h, c); +} + +// установить палитру из массива p +void VP_setall(void *p) +{ + VP_set(p, 0, 256); +} + +// установить n цветов, начиная с f, из массива p +void VP_set(void *p,short f,short n) +{ + byte *ptr = (byte*)p; + SDL_Color colors[256]; + int i; + for(i=f;iformat->palette->ncolors; + SDL_Color colors[256]; + int i; + for (i=0; iformat->palette->colors[i].r; + colors[i].g = screen->format->palette->colors[i].g; + colors[i].b = screen->format->palette->colors[i].b; + } + + Uint32 flags = screen->flags; + + SDL_FreeSurface(screen); + + screen = SDL_SetVideoMode(0, 0, 0, flags ^ SDL_FULLSCREEN); + if(screen == NULL) { + ERR_fatal("Unable to set video mode\n"); + exit(1); + } + + SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, ncolors); + } +} diff --git a/src/vga.h b/src/vga.h new file mode 100644 index 0000000..132af8c --- /dev/null +++ b/src/vga.h @@ -0,0 +1,238 @@ +/* + Управление графикой VGA для DOS4GW + Модуль версии 1.0 + Copyright (C) Алексей Волынсков, 1996 + + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// заголовок изображения +#pragma pack(1) +typedef struct{ + unsigned short w,h; // W-ширина,H-высота + short sx,sy; // сдвиг центра изображения +}vgaimg; + +// R-красный,G-зеленый,B-синий +typedef struct{ + unsigned char r,g,b; +}rgb_t; +#pragma pack() + +// 256-и цветовая палитра VGA +typedef rgb_t vgapal[256]; + +// карта цветов +typedef unsigned char colormap[256]; + +// тип функции перерисовки экрана +typedef void redraw_f(void); + +typedef void spr_f(int, int, unsigned char);//typedef void spr_f(void); + +// переключение в режим VGA 320x200,256 цветов +// возвращает 0, если все о'кей +short V_init(void); + +// переключение в текстовый режим +void V_done(void); + +// ждать обратного хода луча развертки +void V_wait(void); + +// вывести картинку i в координатах (x,y) +void V_pic(short x,short y,vgaimg *i); + +// вывести спрайт i в координатах (x,y) при помощи функции f +// параметры: AL=цвет_точки_спрайта EDI=>экран +// !!! сохраняйте все регистры, кроме EAX +// !!! EDI должен быть переведен на точку вправо (INC EDI или STOSB) +void V_sprf(short x,short y,vgaimg *i,spr_f *f); + +void smoke_sprf(int x, int y, unsigned char c); +void flame_sprf(int x, int y, unsigned char c); + +// вывести спрайт i в координатах (x,y) +void V_spr(short x,short y,vgaimg *i); + +// вывести зеркально перевернутый спрайт i в координатах (x,y) +void V_spr2(short x,short y,vgaimg *i); + +// вывести форму спрайта i в координатах (x,y) одним цветом c +// (подходит для рисования теней) +void V_spr1color(short x,short y,vgaimg *i,unsigned char c); + +// вывести точку цвета c в координатах (x,y) +void V_dot(short x,short y,unsigned char c); + + +void V_manspr(int x,int y,void *p,unsigned char c); + +void V_manspr2(int x,int y,void *p,unsigned char c); + + +// очистить прямоугольник цветом c +// x-левая сторона,w-ширина,y-верх,h-высота +void V_clr(short x,short w,short y,short h,unsigned char c); + +// получить текущую палитру в массив p +void VP_getall(void *p); + +// установить палитру из массива p +void VP_setall(void *p); + +// установить n цветов, начиная с f, из массива p +void VP_set(void *p,short f,short n); + +// заполнить палитру одним цветом (r,g,b) +void VP_fill(char r,char g,char b); + +// приблизить палитру p к цвету (r,g,b) на s/n +// полученная палитра находится в pal_tmp +void VP_tocolor(void *p,char r,char g,char b,char n,char s); + +// приблизить палитру p к палитре p2 на s/n +// полученная палитра находится в pal_tmp +void VP_topal(void *p,void *p2,char n,char s); + +// вывести перемасштабированный к размерам (sx,sy) спрайт i в координатах (x,y) +void VM_spr(short x,short y,short sx,short sy,vgaimg *i); + +// установить область вывода +void V_setrect(short x,short w,short y,short h); + +// установить адрес экранного буфера +// NULL - реальный экран +void V_setscr(void *); + +// скопировать прямоугольник на экран +void V_copytoscr(short x,short w,short y,short h); + +void V_maptoscr(int,int,int,int,void *); + +// вывести символ c +void V_putch(short c); + +// вывести строку s +void V_puts(char *s); + +// вычислить длину строки s (в точках) +short V_strlen(char *s); + +// вычислить ширину символа c (в точках) +short V_chrlen(char c); + +// начать анимацию a +void V_start_anim(void *a); + +// нарисовать кадр анимации +// возвращает номер кадра или 0, если конец +short V_draw_anim(void); + + +// полное описание функций RD_* см. в файле REDRAW.DOC + +// инициализация экрана +void *RD_init(short x,short w,short y,short h); + +// начать перерисовку экрана s при помощи функции f +void RD_start(void *s,redraw_f *f); + +// перерисовать прямоугольник +void RD_rect(short x,short w,short y,short h); + +// перерисовать спрайт +void RD_spr(short x,short y,vgaimg *s); +void RD_spr2(short x,short y,vgaimg *s); + +// окончание перерисовки +void RD_end(void); + + +// возвращает яркость цвета (r,g,b) +short VP_brightness(char r,char g,char b); + +// начать поиск по палитре p, состоящей из n цветов, первый - f +void VP_start_search(rgb_t *p,short n,short f); + +// найти подходящий цвет +short VP_findcolor(short r,short g,short b); + +// переделать изображение i по карте цветов m +void V_remap(vgaimg *i,colormap m); + + +// загружает палитру p из файла f (VGAED 2.0) +// возвращает 0 при ошибке +short load_pal(char *f,void *p); + +// загружает изображение i из файла f (VGAED 2.0) +// возвращает NULL при ошибке +vgaimg *load_vga(char *f,char *i); + +// загружает анимацию из файла f +// возвращает NULL при ошибке +void *load_anim(char *f); + +// область вывода +extern short scrw,scrh,scrx,scry; + +// адрес экранного буфера +extern unsigned char *scra; + +// временная палитра +extern vgapal pal_tmp; + +// ждать ли обратного хода луча при установке палитры +// 0-нет, иначе-да +extern char vp_waitrr; + +// координаты для вывода следующего символа +extern short vf_x,vf_y; + +// расстояние между символами +extern short vf_step; + +// цвет символов +// если 0 - не используется +extern unsigned char vf_color; + +// шрифт +extern void *vf_font; + +// виртуальный экран +extern unsigned char scrbuf[64000]; + + +void V_toggle(); +void V_rotspr (int x, int y, vgaimg* i, int d); +void V_center(int f); +void V_offset(int ox, int oy); +extern char fullscreen; + + +#ifdef __cplusplus +} +#endif diff --git a/src/view.c b/src/view.c new file mode 100644 index 0000000..c1af0cc --- /dev/null +++ b/src/view.c @@ -0,0 +1,289 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +#include +#include "vga.h" +#include "memory.h" +#include "files.h" +#include "error.h" +#include "view.h" +#include "dots.h" +#include "smoke.h" +#include "weapons.h" +#include "items.h" +#include "switch.h" +#include "fx.h" +#include "player.h" +#include "monster.h" +#include "misc.h" +#include "map.h" +#include "sound.h" + +#define ANIT 5 + +/* +#define WD 200 +#define HT 98 + +#define MAXX (FLDW*CELW-WD/2) +#define MAXY (FLDH*CELH-HT/2) +*/ + +int WD; // +int HT; // + +extern map_block_t blk; + +extern byte clrmap[256*12]; +void V_remap_rect(int,int,int,int,byte *); + +byte w_horiz=ON; +void *horiz=NULL;//static void *horiz=NULL; +int w_o,w_x,w_y,sky_type=1; +void *walp[256]; +dword walf[256]; +int walh[256]; +byte walswp[256]; +byte walani[256]; +int anih[ANIT][5]; +byte anic[ANIT]; +byte fldb[FLDH][FLDW]; +byte fldf[FLDH][FLDW]; +byte fld[FLDH][FLDW]; + +extern int lt_time,lt_type,lt_side,lt_ypos; +extern void *ltn[2][2]; + +static void getname(int n,char *s) { + if(walh[n]==-1) {memset(s,0,8);return;} + if(walh[n]==-2) { + memcpy(s,"_WATER_",8);s[7]=(byte)walp[n]-1+'0'; + return; + } + F_getresname(s,walh[n]&0x7FFF); +} + +static short getani(char *n) { + if(strncasecmp(n,"WALL22_1",8)==0) return 1; + if(strncasecmp(n,"WALL58_1",8)==0) return 2; + if(strncasecmp(n,"W73A_1",8)==0) return 3; + if(strncasecmp(n,"RP2_1",8)==0) return 4; + return 0; +} + +void W_savegame(FILE* h) { + char s[8]; + int i; + + myfwrite(&sky_type,1,4,h); + for(i=1;i<256;++i) { + getname(i,s);myfwrite(s,1,8,h); + } + myfwrite(walf,1,sizeof(walf),h); + myfwrite(walswp,1,sizeof(walswp),h); + myfwrite(fldb,1,FLDW*FLDH,h); + myfwrite(fld,1,FLDW*FLDH,h); + myfwrite(fldf,1,FLDW*FLDH,h); +} + +void W_loadgame(FILE* h) { + char s[8]; + int i; + + myfread(&sky_type,1,4,h); + for(i=1;i<256;++i) { + walani[i]=0; + myfread(s,1,8,h);if(!s[0]) {walh[i]=-1;walp[i]=NULL;continue;} + walani[i]=getani(s); + if(strncasecmp(s,"_WATER_",7)==0) { //if(memicmp(s,"_WATER_",7)==0) { + walh[i]=-2;walp[i]=(void*)(s[7]-'0'+1); + }else walp[i]=M_lock(walh[i]=F_getresid(s)); + } + myfread(walf,1,sizeof(walf),h); + for(i=1;i<256;++i) if(walf[i]&1) walh[i]|=0x8000; + myfread(walswp,1,sizeof(walswp),h); + myfread(fldb,1,FLDW*FLDH,h); + myfread(fld,1,FLDW*FLDH,h); + myfread(fldf,1,FLDW*FLDH,h); + strcpy(s,"RSKY1");s[4]=sky_type+'0'; + M_unlock(horiz); + horiz=M_lock(F_getresid(s)); +} + +void W_adjust(void) { + int MAXX =(FLDW*CELW-WD/2);// + int MAXY =(FLDH*CELH-HT/2);// + + if(w_xMAXX) w_x=MAXX; + if(w_y>MAXY) w_y=MAXY; +} + +void W_draw(void) { + W_adjust(); + V_setrect(0,WD,w_o+1,HT); + if(w_horiz) { + + + //V_pic(127-(word)(w_x-WD/2)*56U/(word)(MAXX-WD/2),w_o+123-(word)(w_y-HT/2)*28U/(word)(MAXY-HT/2),horiz); + vgaimg *img = (vgaimg*)horiz; + int x=0; + int d=0; + do { + int y=w_o; + d &= ~2; + do { + V_rotspr(x,y,img,d); + y+=img->h; + d^=2; + } while (yw; + d^=1; + } while (x0;++i,blk.sz-=sizeof(w)) { + myfread(&w,1,sizeof(w),h); + + if(strncasecmp(w.n,"_WATER_",7)==0) //if(memicmp(w.n,"_WATER_",7)==0) + {walp[i]=(void*)(w.n[7]-'0'+1);walh[i]=-2;continue;} + walp[i]=M_lock(walh[i]=F_getresid(w.n)); + if(w.n[0]=='S' && w.n[1]=='W' && w.n[4]=='_') walswp[i]=0; + walf[i]=(w.t)?1:0;if(w.t) walh[i]|=0x8000; + + if(strncasecmp(w.n,"VTRAP01",8)==0) walf[i]|=2; //if(memicmp(w.n,"VTRAP01",8)==0) walf[i]|=2; + walani[i]=getani(w.n); + } + for(j=i,i=1;i<256;++i) if(walswp[i]==0) { + if(j>=256) break; + F_getresname(w.n,walh[i]&0x7FFF); + w.n[5]^=1; + g=F_getresid(w.n)|(walh[i]&0x8000); + for(k=1;k<256;++k) if(walh[k]==g) break; + if(k>=256) { + walh[k=j++]=g;walp[k]=M_lock(g); + walf[k]=(g&0x8000)?1:0; + } + walswp[i]=k;walswp[k]=i; + } + return 1; + case MB_BACK: p=fldb;goto unp; + case MB_WTYPE: p=fld;goto unp; + case MB_FRONT: p=fldf; + unp: switch(blk.st) { + case 0: myfread(p,1,FLDW*FLDH,h);break; + case 1: + if(!(buf=malloc(blk.sz))) + ERR_fatal("Не хватает памяти"); + myfread(buf,1,blk.sz,h); + unpack(buf,blk.sz,p);free(buf);break; + default: return 0; + }return 1; + case MB_SKY: + sky_type=0;myfread(&sky_type,1,2,h); + strcpy(w.n,"RSKY1");w.n[4]=sky_type+'0'; + M_unlock(horiz); + horiz=M_lock(F_getresid(w.n)); + return 1; + }return 0; +} diff --git a/src/view.h b/src/view.h new file mode 100644 index 0000000..477f991 --- /dev/null +++ b/src/view.h @@ -0,0 +1,92 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// View functions + +#include + + +// object data structure +#pragma pack(1) +typedef struct{ + int x,y; // coordinates + int xv,yv; // velocity + int vx,vy; + int r,h; // radius, height +}obj_t; + + +typedef struct{ + int x,y; + byte d; +}pos_t; +#pragma pack() + +enum{HIT_SOME,HIT_ROCKET,HIT_BFG,HIT_TRAP,HIT_WATER,HIT_ELECTRO,HIT_FLAME}; + +enum{ + GS_TITLE,GS_GAME,GS_INTER,GS_DARKEN,GS_ENDANIM,GS_END2ANIM,GS_ENDSCR, + GS_BVIDEO,GS_EVIDEO,GS_END3ANIM +}; + +#define FLDW 100 +#define FLDH 100 +#define CELW 8 +#define CELH 8 +#define MAXTXW 16 +#define MAXTXH 8 + +#pragma pack(1) + +typedef struct{ + char n[8]; + char t; +}wall_t; + +#pragma pack() + +void W_draw(void); +void W_act(void); + +void W_init(void); + +int W_load(FILE*); +int G_load(FILE*); + +void G_init(void); +void G_start(void); +void G_act(void); +void G_draw(void); + +extern byte walswp[256]; +extern byte _2pl,g_dm,g_st,g_exit,w_horiz,g_map; +extern int g_sttm; +extern dword g_time; +extern int w_o,w_x,w_y; +extern byte fldb[FLDH][FLDW]; +extern byte fldf[FLDH][FLDW]; +extern byte fld[FLDH][FLDW]; +extern pos_t dm_pos[]; +extern int dm_pnum,dm_pl1p,dm_pl2p; + +extern int WD; // +extern int HT; // diff --git a/src/weapons.c b/src/weapons.c new file mode 100644 index 0000000..4ccc73b --- /dev/null +++ b/src/weapons.c @@ -0,0 +1,512 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include +//#include +#include "vga.h" +#include "error.h" +#include "sound.h" +#include "view.h" +#include "bmap.h" +#include "dots.h" +#include "smoke.h" +#include "weapons.h" +#include "misc.h" + +extern int hit_xv,hit_yv; + +void bfg_fly(int x,int y,int own); + +enum{NONE=0,ROCKET,PLASMA,APLASMA,BALL1,BALL2,BALL7,BFGBALL,BFGHIT, + MANF,REVF,FIRE}; + +#pragma pack(1) +typedef struct{ + obj_t o; + byte t,s; + int own; + short target; +}weapon_t; +#pragma pack() + +static void *snd[14],*spr[49*2]; +static char sprd[49*2]; +static weapon_t wp[MAXWPN]; + +static void throw(int,int,int,int,int,int,int,int); + +void WP_savegame(FILE* h) { + int n; + + for(n=MAXWPN;--n;) if(wp[n].t) break; + ++n;myfwrite(&n,1,4,h);myfwrite(wp,1,n*sizeof(wp[0]),h); +} + +void WP_loadgame(FILE* h) { + int n; + + myfread(&n,1,4,h);myfread(wp,1,n*sizeof(wp[0]),h); +} + +void WP_alloc(void) { + int i; + static char nm[14][6]={ + "PISTOL", + "SHOTGN", + "DSHTGN", + "RLAUNC", + "RXPLOD", + "PLASMA", + "FIRSHT", + "FIRXPL", + "BAREXP", + "PUNCH", + "SAWHIT", + "MGUN", + "SPARK1", + "SPARK2" + }; + + for(i=0;i<4;++i) { + spr[i*2]=Z_getspr("MISL",i,1,sprd+i*2); + spr[i*2+1]=Z_getspr("MISL",i,2,sprd+i*2+1); + } + for(;i<6;++i) { + spr[i*2]=Z_getspr("PLSS",i-4,1,sprd+i*2); + spr[i*2+1]=Z_getspr("PLSS",i-4,2,sprd+i*2+1); + } + for(;i<11;++i) { + spr[i*2]=Z_getspr("PLSE",i-6,1,sprd+i*2); + spr[i*2+1]=Z_getspr("PLSE",i-6,2,sprd+i*2+1); + } + for(;i<13;++i) { + spr[i*2]=Z_getspr("APLS",i-11,1,sprd+i*2); + spr[i*2+1]=Z_getspr("APLS",i-11,2,sprd+i*2+1); + } + for(;i<18;++i) { + spr[i*2]=Z_getspr("APBX",i-13,1,sprd+i*2); + spr[i*2+1]=Z_getspr("APBX",i-13,2,sprd+i*2+1); + } + for(;i<20;++i) { + spr[i*2]=Z_getspr("BFS1",i-18,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BFS1",i-18,2,sprd+i*2+1); + } + for(;i<26;++i) { + spr[i*2]=Z_getspr("BFE1",i-20,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BFE1",i-20,2,sprd+i*2+1); + } + for(;i<30;++i) { + spr[i*2]=Z_getspr("BFE2",i-26,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BFE2",i-26,2,sprd+i*2+1); + } + for(;i<32;++i) { + spr[i*2]=Z_getspr("MISL",i-30+4,1,sprd+i*2); + spr[i*2+1]=Z_getspr("MISL",i-30+4,2,sprd+i*2+1); + } + for(;i<37;++i) { + spr[i*2]=Z_getspr("BAL1",i-32,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BAL1",i-32,2,sprd+i*2+1); + } + for(;i<42;++i) { + spr[i*2]=Z_getspr("BAL7",i-37,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BAL7",i-37,2,sprd+i*2+1); + } + for(;i<47;++i) { + spr[i*2]=Z_getspr("BAL2",i-42,1,sprd+i*2); + spr[i*2+1]=Z_getspr("BAL2",i-42,2,sprd+i*2+1); + } + for(;i<49;++i) { + spr[i*2]=Z_getspr("MANF",i-47,1,sprd+i*2); + spr[i*2+1]=Z_getspr("MANF",i-47,2,sprd+i*2+1); + } + for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]); +} + +void WP_init(void) { + int i; + + for(i=0;i=2) {if(++wp[i].s>=8) wp[i].t=0; break;} + if(st&Z_HITAIR) Z_set_speed(&wp[i].o,12); + if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) { + wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128); + Z_explode(wp[i].o.x,wp[i].o.y,30,wp[i].own);break;} + else if(Z_hit(&wp[i].o,10,wp[i].own,HIT_SOME)) { + wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[4],128); + Z_explode(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,30,wp[i].own);break;} + bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own); + break; + case PLASMA: + case APLASMA: + if(st&Z_INWATER) { + Z_sound(snd[12],128); + Z_water_trap(&wp[i].o); + Z_chktrap(1,10,wp[i].own,HIT_ELECTRO); + Z_untrap(5); + wp[i].t=0;break; + } + case BALL1: + case BALL7: + case BALL2: + case MANF: + if(wp[i].s>=2) + {if(++wp[i].s>=((wp[i].t==BALL1 || wp[i].t==BALL7 || wp[i].t==BALL2 || wp[i].t==MANF)?8:12)) wp[i].t=0; break;} + if(st&Z_HITAIR) Z_set_speed(&wp[i].o,16); + if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) + {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;} + else if(Z_hit(&wp[i].o,(wp[i].t==BALL7 || wp[i].t==MANF)?40:((wp[i].t==BALL2)?20:5),wp[i].own,HIT_SOME)) + {wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[7],128);break;} + wp[i].s^=1;break; + case BFGBALL: + if(st&Z_INWATER) { + Z_sound(snd[8],40);Z_sound(snd[13],128); + Z_water_trap(&wp[i].o); + Z_chktrap(1,1000,wp[i].own,HIT_ELECTRO); + Z_untrap(5); + wp[i].t=0;break; + } + if(wp[i].s>=2) {if(++wp[i].s>=14) wp[i].t=0; break;} + else if(st&(Z_HITWALL|Z_HITCEIL|Z_HITLAND)) { + Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own); + wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;} + else if(Z_hit(&wp[i].o,100,wp[i].own,HIT_BFG)) { + Z_bfg9000(wp[i].o.x,wp[i].o.y,wp[i].own); + wp[i].s=2;wp[i].o.xv=wp[i].o.yv=0;Z_sound(snd[8],128);break;} + bfg_fly(wp[i].o.x,wp[i].o.y-wp[i].o.h/2,wp[i].own); + wp[i].s^=1;break; + case BFGHIT: + if(++wp[i].s>=8) wp[i].t=0; + break; + default: break; + } + } +} + +void WP_draw(void) { + int i,s,d,x,y; + + for(i=0;i0)?1:0; + x=abs(wp[i].o.xv);y=wp[i].o.yv;s=0; + if(y<0) {if(-y>=x) s=30;} + else if(y>0) if(y>=x/2) s=31; + }else {s=(d-2)/2+1;d=0;} + break; + case MANF: + if((s=wp[i].s)>=2) {s/=2;break;} + case PLASMA: + case APLASMA: + case BALL1: + case BALL7: + case BALL2: + if((s=wp[i].s)>=2) s=s/2+1; + switch(wp[i].t) { + case PLASMA: s+=4;break; + case APLASMA: s+=11;break; + case BALL1: s+=32;break; + case BALL2: s+=42;break; + case BALL7: s+=37;d=(wp[i].o.xv>=0)?1:0;break; + case MANF: s+=47;d=(wp[i].o.xv>=0)?1:0;break; + }break; + case BFGBALL: + if((s=wp[i].s)>=2) s=s/2+1; + s+=18;break; + case BFGHIT: + s=wp[i].s/2+26;break; + } + if(s>=0) Z_drawspr(wp[i].o.x,wp[i].o.y,spr[s*2+d],sprd[s*2+d]); + } +} + +void WP_gun(int x,int y,int xd,int yd,int o,int v) { + register dword d,m; + int sx,sy,lx,ly; + dword xe,ye,s; + byte f; + + f=BM_MONSTER|BM_WALL; + if(o!=-1) f|=BM_PLR1; + if(o!=-2) f|=BM_PLR2; + if((xd-=x)>0) sx=1; + else if(xd<0) sx=-1; + else sx=0; + if((yd-=y)>0) sy=1; + else if(yd<0) sy=-1; + else sy=0; + if(!xd && !yd) return; + if((xd=abs(xd)) > (yd=abs(yd))) d=xd; else d=yd; + hit_xv=xd*10/d*sx; + hit_yv=yd*10/d*sy; + xe=ye=0; + lx=x;ly=y; + for(;;) { + if(x<0 || x>=FLDW*8 || y<0 || y>=FLDH*8) break; + if(((m=bmap[y>>5][x>>5])&f)) { + if(m&BM_WALL) if(fld[y>>3][x>>3]==1 || fld[y>>3][x>>3]==2) { + for(x=lx,y=ly,xe=ye=0;fld[y>>3][x>>3]!=1 && fld[y>>3][x>>3]!=2;) { + lx=x;ly=y; + if((xe+=xd)>=d) {xe-=d;x+=sx;} + if((ye+=yd)>=d) {ye-=d;y+=sy;} + } + DOT_spark(lx,ly,sx*10,sy*10,1); + break; + } + if(m&(BM_MONSTER|BM_PLR1|BM_PLR2)) if(Z_gunhit(x,y,o,sx*v,sy*v)) break; + lx=x;ly=y; + if((xe+=(xd<<3))>=d) { + x+=xe/d*sx;xe=xe%d; + } + if((ye+=(yd<<3))>=d) { + y+=ye/d*sy;ye=ye%d; + } + }else{ + if(sx==0) m=0; + else{m=x&31;if(sx>0) m^=31; ++m;} + if(sy==0) s=0; + else{s=y&31;if(sy>0) s^=31; ++s;} + if((s=x)?1:0; + wp[i].own=o; + throw(i,x,y,xd,yd,2,5,12); + return; + } +} + +void WP_revf(int x,int y,int xd,int yd,int o,int t) { + int i; + + for(i=0;i=x)?1:0; + wp[i].own=o;wp[i].target=t; + throw(i,x,y,xd,yd,2,5,12); + return; + } +} + +void WP_plasma(int x,int y,int xd,int yd,int o) { + int i; + + for(i=0;i=0;--i) { + j=myrand(10*2+1)-10; + WP_gun(x,y+j,xd,yd+j,o,(i%3)?0:1); + } +} + +void WP_ognemet(int x,int y,int xd,int yd,int xv,int yv,int o) { + int m; + + m=abs(xd-x);if(!m) m=abs(yd-y); + SMK_flame(x,y,xv,yv,2,2,(xd-x)*3000/m,(yd-y)*3000/m,1,o); +} diff --git a/src/weapons.h b/src/weapons.h new file mode 100644 index 0000000..538d301 --- /dev/null +++ b/src/weapons.h @@ -0,0 +1,50 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +// Weapons + +#define MAXWPN 300 + +void WP_init(void); +void WP_alloc(void); +void WP_act(void); +void WP_draw(void); +void WP_punch(int,int,int,int); +int WP_chainsaw(int,int,int,int); +void WP_gun(int,int,int,int,int,int); +void WP_pistol(int,int,int,int,int); +void WP_mgun(int,int,int,int,int); +void WP_rocket(int,int,int,int,int); +void WP_revf(int,int,int,int,int,int); +void WP_plasma(int,int,int,int,int); +void WP_ball1(int,int,int,int,int); +void WP_ball2(int,int,int,int,int); +void WP_ball7(int,int,int,int,int); +void WP_aplasma(int,int,int,int,int); +void WP_manfire(int,int,int,int,int); +void WP_bfgshot(int,int,int,int,int); +void WP_bfghit(int,int,int); +void WP_shotgun(int,int,int,int,int); +void WP_dshotgun(int,int,int,int,int); +void WP_ognemet(int x,int y,int xd,int yd,int xv,int yv,int o); + +void WP_grenade(int x, int y, int xd, int yd, int o);