From fdb3057d3afd5ac13dba3ffd0d1d59a7fae15329 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 14 Mar 2020 19:33:22 +0300 Subject: [PATCH 01/16] fix palette --- src/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render.c b/src/render.c index 5f16f7e..55ec317 100644 --- a/src/render.c +++ b/src/render.c @@ -1373,7 +1373,7 @@ void R_init () { if (V_init() != 0) { ERR_failinit("Не могу установить видеорежим VGA"); } - //R_setgamma(gammaa); + R_setgamma(gammaa); V_setrect(0, SCRW, 0, SCRH); V_setscr(scrbuf); V_clr(0, SCRW, 0, SCRH, 0); -- 2.29.2 From 3d2215798aaab87db7ae5265d21e359864e1f1c2 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 14 Mar 2020 21:43:05 +0300 Subject: [PATCH 02/16] fix texture drawing --- src/miscc.c | 2 +- src/render.c | 19 ++++++++++--------- src/view.c | 5 ++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/miscc.c b/src/miscc.c index 2ece443..90cfecb 100644 --- a/src/miscc.c +++ b/src/miscc.c @@ -392,7 +392,7 @@ int Z_moveobj(obj_t *p) { 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, R_get_special_id(wfront)); + DOT_water(p->x, p->y-p->h / 2, p->xv + p->vx, p->yv + p->vy, n, R_get_special_id(wfront) - 1); } void Z_calc_time(dword t,word *h,word *m,word *s) diff --git a/src/render.c b/src/render.c index 55ec317..254b87e 100644 --- a/src/render.c +++ b/src/render.c @@ -304,9 +304,10 @@ static void Z_drawfld (byte *fld, int bg) { int sx = x * CELW - w_x + WD / 2; int sy = y * CELH - w_y + HT / 2 + 1 + w_o; int id = *p; - if (id != 0) { + if (id) { + //intptr_t spc = (intptr_t) walp[id]; int spc = R_get_special_id(id); - if (spc <= 3) { + if (spc >= 0 && spc <= 3) { if (!bg) { byte *cmap = clrmap + (spc + 7) * 256; V_remap_rect(sx, sy, CELW, CELH, cmap); @@ -1263,23 +1264,23 @@ static short getani (char n[8]) { int R_get_special_id (int n) { assert(n >= 0 && n < 256); - intptr_t x = (intptr_t)walp[n] - 1; - return x > 0 && x <= 3 ? x : 0; + intptr_t x = (intptr_t)walp[n]; + return x >= 0 && x <= 3 ? x : -1; } void R_begin_load (void) { int i; - for (i = 0; i < max_textures; i++) { -// if (walp[i] != NULL && walh[i] >= 0) { -// M_unlock(walp[i]); -// } + for (i = 0; i < 256; i++) { + if (walp[i] != NULL && walh[i] >= 0) { + M_unlock(walp[i]); + } walh[i] = -1; walp[i] = NULL; walswp[i] = i; walani[i] = 0; } memset(anic, 0, sizeof(anic)); - max_textures = 0; + max_textures = 1; } void R_load (char s[8], int f) { diff --git a/src/view.c b/src/view.c index 73953d7..4e1fce7 100644 --- a/src/view.c +++ b/src/view.c @@ -86,14 +86,14 @@ void W_loadgame (FILE* h) { myfread(s[i], 8, 1, h); } R_begin_load(); - R_load("", 0); // empty i = myfread32(h); // ignore for (i = 1; i < 256; i++) { walf[i] = myfread32(h); R_load(s[i], walf[i] & 1); } for (i = 0; i < 256; i++) { - walswp[i] = myfread8(h); + //walswp[i] = myfread8(h); + (void)myfread8(h); // useless in new code } myfread(fldb, FLDW*FLDH, 1, h); myfread(fld, FLDW*FLDH, 1, h); @@ -140,7 +140,6 @@ int W_load (FILE *h) { switch (blk.t) { case MB_WALLNAMES: R_begin_load(); - R_load("", 0); // empty for (i = 1; i < 256 && blk.sz > 0; i++, blk.sz -= 9) { myfread(s, 8, 1, h); t = myfread8(h); -- 2.29.2 From 2bb81ea2565c3627c954b5c37326db89b0048472 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 15 Mar 2020 12:20:39 +0300 Subject: [PATCH 03/16] headers describes that c-files implements --- src/a8.c | 1 + src/a8.h | 8 ++ src/anim.c | 3 +- src/anim.h | 7 ++ src/bmap.c | 1 + src/bmap.h | 18 +++-- src/config.c | 32 +++----- src/config.h | 17 +++-- src/dots.c | 3 +- src/dots.h | 31 +++++--- src/error.c | 14 ++++ src/error.h | 13 +++- src/files.c | 167 +++++++++++++++++++---------------------- src/files.h | 67 ++++++++--------- src/fx.c | 21 +++--- src/fx.h | 29 ++++--- src/game.c | 96 ++++++++++-------------- src/game.h | 38 ++++++++++ src/glob.h | 24 ++---- src/items.c | 32 ++++---- src/items.h | 45 ++++++----- src/keyb.c | 23 ++---- src/keyb.h | 29 ++----- src/main.c | 17 +---- src/map.h | 5 +- src/memory.c | 20 ++--- src/memory.h | 17 +++-- src/menu.c | 94 ++++++++--------------- src/menu.h | 25 ++++--- src/misc.h | 76 +++++++++---------- src/miscc.c | 25 +++---- src/monster.c | 153 ++++++++++++++++++------------------- src/monster.h | 54 ++++++++----- src/music.c | 46 +++++------- src/music.h | 18 +++++ src/my.c | 11 +-- src/my.h | 20 +++-- src/player.c | 50 +++++++------ src/player.h | 68 ++++++++++------- src/render.c | 21 ++---- src/render.h | 7 ++ src/smoke.c | 14 ++-- src/smoke.h | 29 ++++--- src/sound.c | 29 +++---- src/sound.h | 55 +++++--------- src/switch.c | 84 ++++++++++----------- src/switch.h | 33 ++++---- src/vga.c | 121 +++++++++++------------------- src/vga.h | 204 ++++++++++---------------------------------------- src/view.c | 15 +--- src/view.h | 80 ++++++++------------ src/weapons.c | 52 ++++++------- src/weapons.h | 59 ++++++++------- 53 files changed, 1018 insertions(+), 1203 deletions(-) create mode 100644 src/a8.h create mode 100644 src/anim.h create mode 100644 src/game.h create mode 100644 src/music.h diff --git a/src/a8.c b/src/a8.c index 2203b52..855ec1e 100644 --- a/src/a8.c +++ b/src/a8.c @@ -31,6 +31,7 @@ #include "error.h" #include "files.h" #include "sound.h" +#include "a8.h" */ /* diff --git a/src/a8.h b/src/a8.h new file mode 100644 index 0000000..b5be13c --- /dev/null +++ b/src/a8.h @@ -0,0 +1,8 @@ +#ifndef A8_H_INCLUDED +#define A8_H_INCLUDED + +int A8_start(char *nm); +int A8_nextframe (void); +void A8_close (void); + +#endif /* A8_H_INCLUDED */ diff --git a/src/anim.c b/src/anim.c index 71c4421..f68f0a2 100644 --- a/src/anim.c +++ b/src/anim.c @@ -26,6 +26,7 @@ #include //#include #include "error.h" +#include "anim.h" enum{AB_END,AB_SCREEN,AB_UPDATE}; @@ -104,4 +105,4 @@ int ANM_play(void) { if(anm->t==AB_END) return 0; return 1; } -*/ \ No newline at end of file +*/ diff --git a/src/anim.h b/src/anim.h new file mode 100644 index 0000000..110c871 --- /dev/null +++ b/src/anim.h @@ -0,0 +1,7 @@ +#ifndef ANIM_H_INCLUDED +#define ANIM_H_INCLUDED + +// void ANM_start (void *p); +// int ANM_play (void); + +#endif /* ANIM_H_INCLUDED */ diff --git a/src/bmap.c b/src/bmap.c index ccb4404..aa63cdb 100644 --- a/src/bmap.c +++ b/src/bmap.c @@ -20,6 +20,7 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "glob.h" #include "view.h" #include "bmap.h" diff --git a/src/bmap.h b/src/bmap.h index 218c0c7..ff53c7a 100644 --- a/src/bmap.h +++ b/src/bmap.h @@ -19,16 +19,22 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Block map +#ifndef BMAP_H_INCLUDED +#define BMAP_H_INCLUDED + +#include "glob.h" +#include "view.h" // obj_t #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; +extern byte bmap[FLDH/4][FLDW/4]; + +void BM_clear (byte f); +void BM_mark (obj_t *o, byte f); +void BM_remapfld (void); + +#endif /* BMAP_H_INCLUDED */ diff --git a/src/config.c b/src/config.c index 9ad78cb..0c5bc21 100644 --- a/src/config.c +++ b/src/config.c @@ -24,20 +24,19 @@ #include #include #include -#include "config.h" -//#include "vga.h" -#include "error.h" +#include +#include "map.h" #include "sound.h" -#include "files.h" +#include "music.h" #include "view.h" +#include "monster.h" #include "player.h" +#include "menu.h" +#include "files.h" +#include "render.h" +#include "error.h" #include "my.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{ @@ -46,13 +45,12 @@ typedef struct{ byte t,o; }cfg_t; - byte cheat=0; - byte shot_vga=0; - - char cd_path[128]=""; +char cfg_file[128]="default.cfg"; + +static char buf[256]; static cfg_t cfg[]={ {"file",NULL,NULL,FILES,0}, @@ -93,11 +91,6 @@ static cfg_t cfg[]={ {NULL,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; @@ -161,8 +154,7 @@ next: } } -int get_key(char *name) -{ +static int get_key (char *name) { int i; for(i=1; i #include #include "view.h" #include "dots.h" @@ -39,8 +40,6 @@ #define SP_MINT 5 #define SP_MAXT 7 -extern byte z_dot; - typedef struct{ int xv,yv; byte c,t; diff --git a/src/dots.h b/src/dots.h index 7229fff..5a8b752 100644 --- a/src/dots.h +++ b/src/dots.h @@ -19,23 +19,32 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Dots +#ifndef DOTS_H_INCLUDED +#define DOTS_H_INCLUDED + +#include "glob.h" +#include "view.h" // obj_t +#include // FILE #define MAXDOT 400 #pragma pack(1) -typedef struct{ +typedef struct { obj_t o; - byte c,t; -}dot_t; + byte c, t; +} dot_t; #pragma pack() extern dot_t dot[MAXDOT]; -void DOT_init(void); -void DOT_alloc(void); -void DOT_act(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); +void DOT_savegame (FILE *h); +void DOT_loadgame (FILE *h); +void DOT_init (void); +void DOT_alloc (void); +void DOT_act (void); +void DOT_add (int x, int y, char xv, char yv, byte c, byte t); +void DOT_blood (int x, int y, int xv, int yv, int n); +void DOT_spark (int x, int y, int xv, int yv, int n); +void DOT_water (int x, int y, int xv, int yv, int n, int c); + +#endif /* DOTS_H_INCLUDED */ diff --git a/src/error.c b/src/error.c index ef9c388..46e5c43 100644 --- a/src/error.c +++ b/src/error.c @@ -31,6 +31,20 @@ #include "memory.h" #include "error.h" #include "config.h" +#include "music.h" + +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) { + // stub +} static void close_all (void) { S_done(); diff --git a/src/error.h b/src/error.h index ecb2cc2..45b2975 100644 --- a/src/error.h +++ b/src/error.h @@ -19,8 +19,13 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Error handling +#ifndef ERROR_H_INCLUDED +#define ERROR_H_INCLUDED -void ERR_failinit(char *,...); -void ERR_fatal(char *,...); -void ERR_quit(void); +void logo (const char *s, ...); +void logo_gas (int cur, int all); +void ERR_failinit (char *s, ...); +void ERR_fatal (char *s, ...); +void ERR_quit (void); + +#endif /* ERROR_H_INCLUDED */ diff --git a/src/files.c b/src/files.c index f6ef6b5..597d149 100644 --- a/src/files.c +++ b/src/files.c @@ -25,69 +25,56 @@ #include #include #include -#include "error.h" -#include "view.h" -#include "items.h" -#include "switch.h" #include "files.h" #include "map.h" #include "my.h" +#include "game.h" +#include "view.h" +#include "dots.h" +#include "smoke.h" +#include "fx.h" +#include "items.h" +#include "monster.h" +#include "player.h" +#include "switch.h" +#include "weapons.h" +#include "error.h" -char *S_getinfo(void); - -extern void *snd_drv; - -typedef struct{ - byte n,i,v,d; -}dmv; +typedef struct { + byte n, i, v, d; +} dmv; -byte seq[255],seqn; -dmv *pat=NULL; -unsigned *patp; -void **dmi; +int d_start, d_end; +byte savname[7][24]; +byte savok[7]; +mwad_t wad[MAX_WAD]; +map_block_t blk; +static byte seq[255]; +static byte seqn; static int inum=0; +static dmv *pat=NULL; +static unsigned *patp; +static void **dmi; -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]; +static int m_start, m_end; +static int s_start, s_end; +static int wad_num; -char wads[MAX_WADS][__MAX_PATH]; +static 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]; +static char f_drive[__MAX_DRIVE]; +static char f_dir[__MAX_DIR]; +static char f_name[__MAX_FNAME]; +static char f_ext[__MAX_EXT]; -void F_startup(void) { +void F_startup (void) { logo("F_startup: настройка файловой системы\n"); memset(wads,0,sizeof(wads)); } -char *getsavfpname(int n, int ro) -{ +static char *getsavfpname (int n, int ro) { static char fn[]="savgame0.dat"; fn[7]=n+'0'; #ifndef WIN32 @@ -168,7 +155,7 @@ void F_loadgame (int n) { } } -void F_addwad(char *fn) { +void F_addwad (char *fn) { int i; for(i=0;i=m_end) i=m_start; @@ -403,16 +389,16 @@ void F_nextmus(char *s) { memcpy(s,wad[i].n,8); } -void F_randmus(char *s) { - int n = myrand(10); - int i; - for (i=0; i -//#include -#include +#include "glob.h" +#include // FILE +#include "map.h" // map_block_t #define MAX_WADS 20 #define MAX_WAD 2000 @@ -31,42 +32,38 @@ typedef char wadname[8]; typedef struct { - int o,l; + int o, l; char n[8]; -}wad_t; +} wad_t; typedef struct { - int o,l; + int o, l; char n[8]; int f; -}mwad_t; +} 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*); +extern int d_start, d_end; +extern byte savname[7][24]; +extern byte savok[7]; +extern mwad_t wad[MAX_WAD]; +extern map_block_t blk; -void F_getsavnames(void); -void F_loadgame(int); -void F_savegame(int,char*); +void F_startup (void); +void F_getsavnames (void); +void F_savegame (int n, char *s); +void F_loadgame (int n); +void F_addwad (char *fn); +void F_initwads (void); +void F_allocres (void); +void F_loadres (int r, void *p, dword o, dword l); +int F_findres (char *n); +int F_getresid (char *n); +void F_getresname (char *n, int r); +int F_getsprid (char n[4], int s, int d); +int F_getreslen (int r); +void F_nextmus (char *s); +void F_randmus (char *s); +void F_readstr (FILE* h, char *s, int m); +void F_loadmap (char n[8]); -void F_randmus(char*);// - -extern char wads[MAX_WADS][__MAX_PATH]; -extern int wad_num; - -int F_getsprid(char n[4],int s,int d); -int F_getresid(char *n); +#endif /* FILES_H_INCLUDED */ diff --git a/src/fx.c b/src/fx.c index 35777ac..cea21f8 100644 --- a/src/fx.c +++ b/src/fx.c @@ -36,7 +36,7 @@ static void *bsnd[2]; static char bubsn; static int last; -unsigned char fx_scr1[64000],fx_scr2[64000]; +//unsigned char fx_scr1[64000],fx_scr2[64000]; #define SINP 256 #define SINPM (SINP-1) @@ -59,8 +59,8 @@ static void setamp(int a) { for(i=0;i // FILE #define MAXFX 300 #pragma pack(1) -typedef struct{ - int x,y,xv,yv; - char t,s; -}fx_t; +typedef struct { + int x, y, xv, yv; + char t, s; +} fx_t; #pragma pack() extern fx_t fx[MAXFX]; -void FX_init(void); -void FX_alloc(void); -void FX_act(void); -void FX_tfog(int,int); -void FX_ifog(int,int); -void FX_bubble(int x,int y,int xv,int yv,int n); +void FX_savegame (FILE *h); +void FX_loadgame (FILE *h); +void FX_alloc (void); +void FX_init (void); +void FX_act (void); +void FX_tfog (int x, int y); +void FX_ifog (int x, int y); +void FX_bubble (int x, int y, int xv, int yv, int n); + +#endif /* FX_H_INLUDED */ diff --git a/src/game.c b/src/game.c index 4ae9e11..8d14674 100644 --- a/src/game.c +++ b/src/game.c @@ -42,6 +42,11 @@ #include "misc.h" #include "map.h" #include "my.h" +#include "game.h" +#include "config.h" +#include "music.h" +#include "a8.h" +#include "error.h" #include @@ -50,49 +55,30 @@ #define GETIME 1092 - -int A8_start(char*); -int A8_nextframe(void); -void A8_close(void); - - -byte transdraw=0; - - -void FX_trans1(int t); -extern unsigned char fx_scr1[64000],fx_scr2[64000]; - -extern short lastkey; - - -extern int hit_xv,hit_yv; - -//void setgamma(int); - -extern int PL_JUMP; - -extern map_block_t blk; - -extern byte cheat; - -byte _2pl=0,g_dm=0,g_st=GS_TITLE,g_exit=0,g_map=1,_warp=0; -char g_music[8]="MENU"; -byte _net=0; -int g_sttm=1092; +byte transdraw; +byte _2pl; +byte g_dm; +byte g_st = GS_TITLE; +byte g_exit; +byte g_map = 1; +char g_music[8] = "MENU"; dword g_time; -int dm_pnum,dm_pl1p,dm_pl2p; +int dm_pnum; +int dm_pl1p; +int dm_pl2p; pos_t dm_pos[100]; static void *telepsnd; -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 lt_time; +int lt_type; +int lt_side; +int lt_ypos; +static int lt_force; +static void *ltnsnd[2]; -int g_trans=0,g_transt; +int g_trans; +static int g_transt; static void set_trans(int st) { switch(g_st) { @@ -108,7 +94,7 @@ static void set_trans(int st) { g_trans=1;g_transt=0; } -void G_savegame(FILE* h) { +void G_savegame (FILE* h) { myfwrite8(_2pl, h); myfwrite8(g_dm, h); myfwrite8(g_exit, h); @@ -128,7 +114,7 @@ void G_savegame(FILE* h) { myfwrite(g_music, 8, 1, h); } -void G_loadgame(FILE* h) { +void G_loadgame (FILE* h) { _2pl = myfread8(h); g_dm = myfread8(h); g_exit = myfread8(h); @@ -151,18 +137,18 @@ void G_loadgame(FILE* h) { int G_load (FILE *h) { switch (blk.t) { - case MB_MUSIC: - myfread(g_music, 8, 1, h); - if (music_random) { - F_randmus(g_music); - } - F_loadmus(g_music); - return 1; + case MB_MUSIC: + myfread(g_music, 8, 1, h); + if (music_random) { + F_randmus(g_music); + } + F_loadmus(g_music); + return 1; } return 0; } -void load_game(int n) { +void load_game (int n) { F_freemus(); W_init(); F_loadgame(n); @@ -177,7 +163,7 @@ void load_game(int n) { S_startmusic(music_time); } -void G_start(void) { +void G_start (void) { char s[8]; F_freemus(); @@ -203,7 +189,7 @@ void G_start(void) { #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10) -void G_init(void) { +void G_init (void) { int i,j; char s[9]; @@ -229,7 +215,7 @@ void G_init(void) { g_trans=0; } -int G_beg_video(void) { +static int G_beg_video (void) { /* switch(g_map) { case 3: return A8_start("FALL"); @@ -255,7 +241,7 @@ int G_beg_video(void) { } -int G_end_video(void) { +static int G_end_video (void) { /* switch(g_map) { case 1: return A8_start("TRUBA"); @@ -265,8 +251,7 @@ int G_end_video(void) { return 0; } - -void G_act(void) { +void G_act (void) { static byte pcnt=0; /* if(g_trans) { @@ -302,7 +287,8 @@ void G_act(void) { 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; + } + return; } // V_copytoscr(0,SCRW,0,SCRH);//V_copytoscr(0,320,0,200); return; @@ -414,7 +400,7 @@ inter: #endif } -void G_respawn_player(player_t *p) { +void G_respawn_player (player_t *p) { int i; if(dm_pnum==2) { diff --git a/src/game.h b/src/game.h new file mode 100644 index 0000000..48b7898 --- /dev/null +++ b/src/game.h @@ -0,0 +1,38 @@ +#ifndef GAME_H_INLUDED +#define GAME_H_INLUDED + +#include "glob.h" +#include "view.h" // pos_t +#include "player.h" // player_t +#include // FILE + +extern byte transdraw; +extern byte _2pl; +extern byte g_dm; +extern byte g_st; +extern byte g_exit; +extern byte g_map; +extern char g_music[8]; +extern dword g_time; +extern int dm_pnum; +extern int dm_pl1p; +extern int dm_pl2p; +extern pos_t dm_pos[100]; + +extern int lt_time; +extern int lt_type; +extern int lt_side; +extern int lt_ypos; + +extern int g_trans; + +void G_savegame (FILE* h); +void G_loadgame (FILE* h); +int G_load (FILE *h); +void load_game (int n); +void G_start (void); +void G_init (void); +void G_act (void); +void G_respawn_player (player_t *p); + +#endif /* GAME_H_INLUDED */ diff --git a/src/glob.h b/src/glob.h index b68f4b6..67391c8 100644 --- a/src/glob.h +++ b/src/glob.h @@ -22,8 +22,10 @@ // Globals -#ifndef MYGLOB -#define MYGLOB +#include + +#ifndef GLOB_H_INCLUDED +#define GLOB_H_INCLUDED #ifndef NULL #define NULL 0 @@ -38,33 +40,17 @@ typedef unsigned char byte; typedef unsigned short word; typedef unsigned int dword; -void logo(const char *,...); -void logo_gas(int,int); - -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 +#endif /* GLOB_H_INCLUDED */ diff --git a/src/items.c b/src/items.c index 8918203..49f954b 100644 --- a/src/items.c +++ b/src/items.c @@ -32,15 +32,14 @@ #include "misc.h" #include "map.h" #include "my.h" - -extern map_block_t blk; - +#include "files.h" +#include "game.h" item_t it[MAXITEM]; static void *snd[4]; -static int tsndtm,rsndtm; +static int tsndtm, rsndtm; -int itm_rtime=1092; +int itm_rtime = 1092; void IT_savegame (FILE *h) { int i, n; @@ -96,14 +95,17 @@ void IT_alloc (void) { } } -void IT_init(void) { +void IT_init (void) { int i; - - for(i=0;i=I_BPACK && t<=I_BFG) || t==I_GUN2) @@ -209,7 +211,7 @@ static void takesnd(int t) { tsndtm=Z_sound(snd[0],256); } -void IT_act(void) { +void IT_act (void) { int i,j; if(tsndtm) --tsndtm; @@ -251,7 +253,7 @@ void IT_act(void) { } } -void IT_spawn(int x,int y,int t) { +void IT_spawn (int x,int y,int t) { int i; for(i=0;i +#include "view.h" // obj_t +#include // FILE #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 +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 }; #pragma pack(1) -typedef struct{ +typedef struct { obj_t o; int t; int s; -}item_t; +} item_t; #pragma pack() extern item_t it[MAXITEM]; +extern int itm_rtime; -void IT_init(void); -void IT_alloc(void); -int IT_load(FILE*); -void IT_act(void); -void IT_spawn(int x,int y,int i); -void IT_drop_ammo(int i,int n,int x,int y); +void IT_savegame (FILE *h); +void IT_loadgame (FILE *h); +void IT_alloc (void); +void IT_init (void); +int IT_load (FILE *h); +void IT_act (void); +void IT_spawn (int x, int y, int t); +void IT_drop_ammo (int t, 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; +#endif /* ITEMS_H_INCLUDED */ diff --git a/src/keyb.c b/src/keyb.c index 4123c07..7110996 100644 --- a/src/keyb.c +++ b/src/keyb.c @@ -24,32 +24,25 @@ #include "error.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_init (void) { + keys = SDL_GetKeyState(NULL); } -void K_done() -{ - +void K_done (void) { + // not needed for sdl } + // установить функцию обработки клавиш - void K_setkeyproc(key_f *k) -{ - key_proc = k; +void K_setkeyproc (key_f *k) { + key_proc = k; } -void updatee_keys() -{ +void updatee_keys (void) { SDL_Event event; while (SDL_PollEvent (&event)) { /* diff --git a/src/keyb.h b/src/keyb.h index 0684fc5..d52559a 100644 --- a/src/keyb.h +++ b/src/keyb.h @@ -23,29 +23,16 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MYKEYB -#define MYKEYB +#ifndef KEYB_H_INCLUDED +#define KEYB_H_INCLUDED -#ifdef __cplusplus -extern "C" { -#endif +typedef void key_f (int k, int pressed); -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 +void K_init (void); +void K_done (void); +void K_setkeyproc (key_f *k); +void updatee_keys (void); -#endif +#endif /* KEYB_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 81c257c..4b6a958 100644 --- a/src/main.c +++ b/src/main.c @@ -36,24 +36,11 @@ #include "player.h" #include "my.h" #include "render.h" +#include "game.h" +#include "music.h" #include -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) { -} - -void myrandomize(void); - 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"); diff --git a/src/map.h b/src/map.h index 5e574a6..e0afb71 100644 --- a/src/map.h +++ b/src/map.h @@ -35,6 +35,9 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef MAP_H_INCLUDED +#define MAP_H_INCLUDED + #pragma pack(1) /* Старый формат - версия 1.04 alpha (и раньше) @@ -173,4 +176,4 @@ typedef struct{ #pragma pack() -/* КОНЕЦ */ +#endif /* MAP_H_INCLUDED */ diff --git a/src/memory.c b/src/memory.c index d3c5e8c..5be719f 100644 --- a/src/memory.c +++ b/src/memory.c @@ -27,18 +27,11 @@ #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 byte m_active; static void *resp[MAX_WAD]; static short resl[MAX_WAD]; -void M_startup(void) { +void M_startup (void) { if(m_active) return; logo("M_startup: настройка памяти\n"); memset(resp,0,sizeof(resp)); @@ -47,13 +40,12 @@ void M_startup(void) { m_active=TRUE; } -void M_shutdown(void) { - +void M_shutdown (void) { if(!m_active) return; m_active=FALSE; } -static void allocres(int h) { +static void allocres (int h) { int *p,s; if(h>d_start && h=MAX_WAD) ERR_fatal("M_lock: странный номер ресурса"); @@ -81,7 +73,7 @@ void *M_lock(int h) { return resp[h]; } -void M_unlock(void *p) { +void M_unlock (void *p) { int h; if(!p) return; diff --git a/src/memory.h b/src/memory.h index 84ca70f..191b8b7 100644 --- a/src/memory.h +++ b/src/memory.h @@ -19,11 +19,14 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// High-level memory allocation +#ifndef MEMORY_H_INCLULDED +#define MEMORY_H_INCLULDED -void M_startup(void); -void M_shutdown(void); -void *M_lock(int); -void M_unlock(void *); -int M_locked(int); -int M_was_locked(int); +void M_startup (void); +void M_shutdown (void); +void *M_lock (int h); +void M_unlock (void *p); +int M_locked (int h); +int M_was_locked (int h); + +#endif /* MEMORY_H_INCLULDED */ diff --git a/src/menu.c b/src/menu.c index 7d5f374..bd225a4 100644 --- a/src/menu.c +++ b/src/menu.c @@ -35,31 +35,28 @@ #include "menu.h" #include "misc.h" #include "render.h" +#include "config.h" +#include "game.h" +#include "player.h" +#include "sound.h" +#include "music.h" #include #include -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 char g_music[8]; - -extern byte savname[7][24],savok[7]; -void load_game(int); +static byte panim[] = "BBDDAACCDDAABBDDAACCDDAABBDDAACCDDAAEEEEEFEFEFEFEFEFEFEFEFEFEEEEE"; +byte *panimp = panim; +byte _warp; -static byte panim[]= - "BBDDAACCDDAABBDDAACCDDAABBDDAACCDDAAEEEEEFEFEFEFEFEFEFEFEFEFEEEEE"; -byte *panimp=panim; - -byte pcolortab[PCOLORN]={ - 0x18,0x20,0x40,0x58,0x60,0x70,0x80,0xB0,0xC0,0xD0 +byte pcolortab[PCOLORN] = { + 0x18, 0x20, 0x40, 0x58, 0x60, 0x70, 0x80, 0xB0, 0xC0, 0xD0 }; -int p1color=5,p2color=4; +int p1color = 5; +int p2color = 4; char ibuf[24]; byte input=0; @@ -155,16 +152,14 @@ static byte cbuf[32]; static snd_t *voc=NULL; static int voc_ch=0; -extern byte shot_vga; // config.c - -void GMV_stop(void) { +static 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) { +void GMV_say (char *nm) { int r,len; snd_t *p; byte *d; @@ -180,7 +175,17 @@ void GMV_say(char *nm) { voc_ch=S_play(voc,-1,1024,255); } -void G_code(void) { +static 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 G_code (void) { void *s; s=csnd2; if(memcmp(cbuf+32-5,"IDDQD",5)==0) { @@ -222,19 +227,7 @@ void G_code(void) { 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) { +static void GM_command (int c) { switch(c) { case CANCEL: GM_set(NULL);break; @@ -339,28 +332,6 @@ void GM_command(int c) { } } -/* -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; @@ -407,8 +378,7 @@ struct { {0} }; -byte get_keychar(int keysym) -{ +static byte get_keychar (int keysym) { int i = 0; while (keychar[i].keysym) { if (keychar[i].keysym == keysym) return keychar[i].ch; @@ -417,7 +387,8 @@ byte get_keychar(int keysym) return 0; } -static void shot(void) { +static void shot (void) { +/* static int num=1; char fn[100];//... #ifndef WIN32 @@ -431,9 +402,10 @@ static void shot(void) { #endif SDL_SaveBMP(screen, fn); ++num; +*/ } -int GM_act(void) { +int GM_act (void) { byte c; if(mnu==&plcolor_mnu) { @@ -540,7 +512,7 @@ int GM_act(void) { return((mnu)?1:0); } -void G_keyf(int k, int press) { +static void G_keyf (int k, int press) { int i; lastkey=k; @@ -550,7 +522,7 @@ void G_keyf(int k, int press) { } } -void GM_init(void) { +void GM_init (void) { #ifndef DEMO int i; static char nm[QSND_NUM][6]={ diff --git a/src/menu.h b/src/menu.h index ed4a5e9..3e6c65e 100644 --- a/src/menu.h +++ b/src/menu.h @@ -19,19 +19,22 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Game menus +#ifndef MENU_H_INCLUDED +#define MENU_H_INCLUDED -typedef struct{ +#include "glob.h" + +typedef struct { byte type; - int n,cur,x; + int n, cur, x; char *ttl; char **m; byte *t; -}menu_t; +} menu_t; extern menu_t save_mnu; - extern byte *panimp; +extern byte _warp; #define PCOLORN 10 extern byte pcolortab[PCOLORN]; @@ -43,11 +46,11 @@ extern byte input; extern menu_t *mnu; extern byte gm_redraw; +extern short lastkey; -void GMV_say(char *); -void GMV_stop(void); - -void GM_init(void); -int GM_act(void); +void GMV_say (char *nm); +void G_code (void); +int GM_act (void); +void GM_init (void); -void G_code(void); +#endif /* MENU_H_INCLUDED */ diff --git a/src/misc.h b/src/misc.h index 9d81cfa..b48cc3a 100644 --- a/src/misc.h +++ b/src/misc.h @@ -20,53 +20,49 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Miscellaneous functions +#ifndef MISC_H_INCLUDED +#define MISC_H_INCLUDED -#include -#include "view.h" +#include "glob.h" +#include "view.h" // obj_t +#include // int16_t int32_t #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 +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_getsnd(char[6]); -int Z_sound(void *,int); -void Z_initst(void); -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); +extern byte z_dot; +extern byte z_mon; -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); - -int Z_getacid(int x,int y,int r,int h); +int Z_sign (int a); +int Z_dec (int a, int b); +void *Z_getsnd (char n[6]); +int Z_sound (void *s, int v); +void Z_initst (void); +int Z_canstand (int x, int y, int r); +int Z_canfit (int x, int y, int r, int h); +int Z_istrapped (int x, int y, int r, int h); +void Z_set_speed (obj_t *o, int s); +int Z_inwater (int x, int y, int r, int h); +int Z_getacid (int x, int y, int r, int h); +int Z_canbreathe (int x, int y, int r, int h); +int Z_overlap (obj_t *a, obj_t *b); +int Z_cansee (int x, int y, int xd, int yd); +int Z_look (obj_t *a, obj_t *b, int d); +int Z_moveobj (obj_t *p); +void Z_splash (obj_t *p, int n); +void Z_calc_time(dword t, word *h, word *m, word *s); int16_t short2host (int16_t x); int32_t int2host (int32_t x); + +#endif /* MISC_H_INCLUDED */ diff --git a/src/miscc.c b/src/miscc.c index 90cfecb..1cea2b5 100644 --- a/src/miscc.c +++ b/src/miscc.c @@ -40,13 +40,10 @@ #define MAX_YV 30 -extern dword walf[256]; - -byte z_dot=0; - -extern void *walp[256]; - +byte z_dot; +byte z_mon; static void *bulsnd[2]; +static byte wfront; int Z_sign(int a) { if(a>0) return 1; @@ -111,7 +108,7 @@ int Z_canstand(int x,int y,int r) { return 0; } -int Z_hitceil(int x,int y,int r,int h) { +static int Z_hitceil(int x,int y,int r,int h) { int i; i=(x-r)/CELW; @@ -146,7 +143,7 @@ int Z_canfit(int x,int y,int r,int h) { return 1; } -int Z_inlift(int x,int y,int r,int h) { +static int Z_inlift(int x,int y,int r,int h) { int i,j,sx,sy; sx=(x-r)/CELW; @@ -163,7 +160,7 @@ int Z_inlift(int x,int y,int r,int h) { return 0; } -int Z_isblocked(int x,int y,int r,int h,int xv) { +static int Z_isblocked(int x,int y,int r,int h,int xv) { int i,j,sx,sy; sx=(x-r)/CELW; @@ -206,8 +203,6 @@ void Z_set_speed(obj_t *o,int s) { 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; @@ -271,7 +266,7 @@ int Z_overlap(obj_t *a,obj_t *b) { return 1; } -void Z_kickobj(obj_t *o,int x,int y,int pwr) { +static 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; @@ -326,8 +321,6 @@ int Z_look(obj_t *a,obj_t *b,int d) { #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; @@ -410,7 +403,7 @@ void Z_calc_time(dword t,word *h,word *m,word *s) #define SWAP_VAR(a, b) do { unsigned char t = a; a = b; b = t; } while(0) -int16_t short2swap (int16_t x) { +static int16_t short2swap (int16_t x) { union { uint8_t a[2]; int16_t x; @@ -420,7 +413,7 @@ int16_t short2swap (int16_t x) { return y.x; } -int32_t int2swap (int32_t x) { +static int32_t int2swap (int32_t x) { union { uint8_t a[4]; int32_t x; diff --git a/src/monster.c b/src/monster.c index 1357446..e895a38 100644 --- a/src/monster.c +++ b/src/monster.c @@ -36,20 +36,21 @@ #include "fx.h" #include "smoke.h" #include "my.h" +#include "player.h" +#include "error.h" +#include "game.h" #define MAX_ATM 90 -extern byte z_mon; - enum{ SLEEP,GO,RUN,CLIMB,DIE,DEAD,ATTACK,SHOOT,PAIN,WAIT,REVIVE,RUNOUT }; -typedef struct{ - int r,h,l,mp,rv,jv,sp,minp; -}mnsz_t; +typedef struct { + int r, h, l, mp, rv, jv, sp, minp; +} mnsz_t; -byte nomon=1; +byte nomon = 1; static char *sleepanim[MN_TN]={ "AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB","AAABBB", @@ -87,7 +88,7 @@ static char *sleepanim[MN_TN]={ "","U","U","U","","T","","","","","","","","","","","","","","W" }; -int hit_xv,hit_yv; +int hit_xv, hit_yv; mn_t mn[MAXMN]; static void *fsnd,*pauksnd,*trupsnd; @@ -120,6 +121,48 @@ static mnsz_t mnsz[MN_TN+1]={ 8, 26, 400, 70, 8,10, 30, 50 // man }; +static void setst(int i,int st) { + char *a; + int t; + + switch(mn[i].st) { + case DIE: case DEAD: + if(st!=DEAD && st!=REVIVE) return; + } + mn[i].ac=0; + t=mn[i].t-1; + switch(mn[i].st=st) { + case SLEEP: a=sleepanim[t];break; + case PAIN: a=painanim[t];break; + case WAIT: a=waitanim[t];break; + case CLIMB: + case RUN: case RUNOUT: + case GO: a=goanim[t];break; + case SHOOT: + if(t==MN_SKEL-1) {a="KKKKJJ";break;} + if(t==MN_ROBO-1) {a="MN";break;} + case ATTACK: a=attackanim[t]; + if(st==ATTACK && t==MN_VILE-1) a="[[\\\\]]"; + break; + case DIE: + if(g_map==9 && t==MN_BSP-1) Z_sound(pauksnd,128); + a=dieanim[t];break; + case DEAD: + a=deadanim[t]; + if(mn[i].ap==slopanim[t]) a=messanim[t]; + if(t==MN_BARREL-1) {mn[i].t=0;} + break; + case REVIVE: + a=(mn[i].ap==messanim[t])?slopanim[t]:dieanim[t]; + mn[i].ac=strlen(a)-1; + mn[i].o.r=mnsz[t+1].r;mn[i].o.h=mnsz[t+1].h; + mn[i].life=mnsz[t+1].l;mn[i].ammo=mn[i].pain=0; + ++mnum; + break; + } + mn[i].ap=a; +} + void MN_savegame (FILE *h) { int i, n; for (n = MAXMN - 1; n >= 0 && mn[n].t == 0; n--) { @@ -156,10 +199,6 @@ void MN_savegame (FILE *h) { myfwrite32(gsndt, h); } -static void setst(int,int); - -static int MN_hit(int n,int d,int o,int t); - void MN_loadgame (FILE *h) { int i, n, c; n = myfread32(h); @@ -201,7 +240,7 @@ void MN_loadgame (FILE *h) { #define GGAS_TOTAL (MN__LAST-MN_DEMON+16+10) -void MN_alloc(void) { +void MN_alloc (void) { int i,j; static char sn[MN_TN][5][6]={ {"DMACT","DMPAIN","SGTATK","SGTSIT","SGTDTH"}, @@ -255,56 +294,13 @@ void MN_alloc(void) { for(i=0;i<4;++i) {gsn[4]=i+'1';gsnd[i]=Z_getsnd(gsn);} } -void MN_init(void) { +void MN_init (void) { int i; - for(i=0;ix,o->y,c,t+MN_PL_DEAD))==-1) return -1; @@ -373,7 +369,7 @@ static int MN_findnewprey(int i) { return 1; } -int Z_getobjpos(int i,obj_t *o) { +int Z_getobjpos (int i, obj_t *o) { if(i==-1) {*o=pl1.o;return !PL_isdead(&pl1);} if(_2pl) if(i==-2) {*o=pl2.o;return !PL_isdead(&pl2);} if(i>=0 && i=MAXMN) return 0; + if(mn[obj].t) return MN_hit(obj,d,own,t); + return 0; +} + +void MN_act (void) { int i,st,sx,sy,t; static obj_t o; static int pt_x=0,pt_xs=1,pt_y=0,pt_ys=1; @@ -784,7 +789,7 @@ void MN_act(void) { } } -void MN_mark(void) { +void MN_mark (void) { int i; for(i=0;io.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 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)) @@ -874,7 +879,7 @@ static void goodsnd(void) { gsndt=18; } -int Z_hit(obj_t *o,int d,int own,int t) { +int Z_hit (obj_t *o, int d, int own, int t) { int i; hit_xv=o->xv+o->vx; @@ -901,24 +906,14 @@ int Z_hit(obj_t *o,int d,int own,int t) { return 0; } -void MN_killedp(void) { +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) { +void Z_explode (int x,int y,int rad,int own) { long r; int dx,dy,m,i; @@ -952,7 +947,7 @@ void Z_explode(int x,int y,int rad,int own) { } } -void Z_bfg9000(int x,int y,int own) { +void Z_bfg9000 (int x,int y,int own) { int dx,dy,i; hit_xv=hit_yv=0; @@ -982,7 +977,7 @@ void Z_bfg9000(int x,int y,int own) { } } -int Z_chktrap(int t,int d,int o,int ht) { +int Z_chktrap (int t, int d, int o, int ht) { int i,s; hit_xv=hit_yv=0; @@ -1003,7 +998,7 @@ int Z_chktrap(int t,int d,int o,int ht) { return s; } -void Z_teleobj(int o,int x,int y) { +void Z_teleobj (int o, int x, int y) { obj_t *p; if(o==-1) p=&pl1.o; @@ -1014,7 +1009,7 @@ void Z_teleobj(int o,int x,int y) { Z_sound(telesnd,128); } -void MN_warning(int l,int t,int r,int b) { +void MN_warning (int l,int t,int r,int b) { int i; for(i=0;i #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; +static Uint32 muscount; +static Mix_Music * muslo; +static int musdisabled = 1; +static int volsetcount = 0; -void S_initmusic(void) -{ +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()); @@ -63,8 +62,7 @@ void S_initmusic(void) S_volumemusic(mus_vol); } -void S_donemusic(void) -{ +void S_donemusic (void) { if (SDL_WasInit(SDL_INIT_AUDIO)) { F_freemus(); Mix_CloseAudio(); @@ -72,23 +70,20 @@ void S_donemusic(void) } } -void S_startmusic(int time) -{ +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) -{ +void S_stopmusic (void) { if (musdisabled) return; Mix_HaltMusic(); muscount = 0; } -void S_volumemusic(int v) -{ +void S_volumemusic (int v) { if (musdisabled) return; mus_vol = v; if (mus_vol>128) mus_vol=128; @@ -104,7 +99,7 @@ void S_volumemusic(int v) } } -struct { +static struct { Uint8 ascii; Uint8 asciilc; char *ch; @@ -144,7 +139,7 @@ struct { {0} }; -char *get_trans_char (Uint8 c) +static char *get_trans_char (Uint8 c) { int i = 0; while (atrans[i].ascii) { @@ -157,7 +152,7 @@ char *get_trans_char (Uint8 c) return NULL; } -void trans_ascii_str (char *dest, char *src) +static void trans_ascii_str (char *dest, char *src) { char *p = dest; int i; @@ -175,7 +170,7 @@ void trans_ascii_str (char *dest, char *src) *p='\0'; } -void F_loadmus(char n[8]) { +void F_loadmus (char n[8]) { if (musdisabled) return; char f[50]; char name[50]; @@ -204,7 +199,7 @@ void F_loadmus(char n[8]) { } -void F_freemus(void) { +void F_freemus (void) { if (musdisabled) return; if (muslo) { Mix_HaltMusic(); @@ -213,12 +208,7 @@ void F_freemus(void) { muslo = NULL; } -extern char g_music[8]; - -static int volsetcount = 0; - -void S_updatemusic() -{ +void S_updatemusic (void) { if (musdisabled) return; //періодично встановлюю гучність музикі, так як вона сама підвищується до максимуму через певний час diff --git a/src/music.h b/src/music.h new file mode 100644 index 0000000..ab1d3e7 --- /dev/null +++ b/src/music.h @@ -0,0 +1,18 @@ +#ifndef MUSIC_H_INCLUDED +#define MUSIC_H_INCLUDED + +extern short mus_vol; +extern char music_random; +extern int music_time; +extern int music_fade; + +void S_initmusic (void); +void S_donemusic (void); +void S_startmusic (int time); +void S_stopmusic (void); +void S_volumemusic (int v); +void F_loadmus (char n[8]); +void F_freemus (void); +void S_updatemusic (void); + +#endif /* MUSIC_H_INCLUDED */ diff --git a/src/my.c b/src/my.c index bfae25f..a966eb8 100644 --- a/src/my.c +++ b/src/my.c @@ -28,8 +28,7 @@ #include #include -void mysplitpath(const char* path, char* drv, char* dir, char* name, char* ext) -{ +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 */ @@ -127,13 +126,11 @@ void myfwrite32 (int32_t x, FILE *f) { myfwrite(&x, 4, 1, f); } -void myrandomize(void) -{ +void myrandomize (void) { srand(SDL_GetTicks()); } -int fexists(char * filename) -{ +int fexists (char *filename) { FILE *f; if ((f = fopen(filename, "r"))) { @@ -141,4 +138,4 @@ int fexists(char * filename) return 1; } return 0; -} \ No newline at end of file +} diff --git a/src/my.h b/src/my.h index f52be8b..15792f1 100644 --- a/src/my.h +++ b/src/my.h @@ -19,30 +19,28 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef __cplusplus -extern "C" { -#endif +#ifndef MY_H_INCLUDED +#define MY_H_INCLUDED -#include -#include +#include // int16_t int32_t +#include // FILE -void mysplitpath (const char *path, char *drv, char *dir, char *name, char *ext); +void mysplitpath(const char* path, char* drv, char* dir, char* name, char* ext); -size_t myfreadc(void *ptr, size_t size, size_t n, FILE *f); +size_t myfreadc (void *ptr, size_t size, size_t n, FILE *f); void myfread (void *ptr, size_t size, size_t n, FILE *f); int8_t myfread8 (FILE *f); int16_t myfread16 (FILE *f); int32_t myfread32 (FILE *f); -void myfwrite(void *ptr, size_t size, size_t n, FILE *f); +void myfwrite (void *ptr, size_t size, size_t n, FILE *f); void myfwrite8 (int8_t x, FILE *f); void myfwrite16 (int16_t x, FILE *f); void myfwrite32 (int32_t x, FILE *f); void myrandomize (void); + int fexists (char *filename); -#ifdef __cplusplus -} -#endif +#endif /* MY_H_INCLUDED */ diff --git a/src/player.c b/src/player.c index 7a693ac..f593f30 100644 --- a/src/player.c +++ b/src/player.c @@ -35,8 +35,7 @@ #include "player.h" #include "misc.h" #include "my.h" - -extern int hit_xv,hit_yv; +#include "game.h" #define PL_RAD 8 #define PL_HT 26 @@ -46,25 +45,28 @@ extern int hit_xv,hit_yv; #define PL_AQUA_AIR 1091 -byte p_immortal=0,p_fly=0; +byte p_immortal; +byte p_fly; -int PL_JUMP=10,PL_RUN=8; +int PL_JUMP=10; +int 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}; +static 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; +player_t pl1; +player_t pl2; static int aitime; static void *aisnd[3]; static void *pdsnd[5]; static void *snd[11]; -byte plr_goanim[]="BDACDA", - plr_dieanim[]="HHHHIIIIJJJJKKKKLLLLMMMM", - plr_slopanim[]="OOPPQQRRSSTTUUVVWW"; +byte plr_goanim[]="BDACDA"; +byte plr_dieanim[]="HHHHIIIIJJJJKKKKLLLLMMMM"; +byte plr_slopanim[]="OOPPQQRRSSTTUUVVWW"; #pragma pack(1) @@ -73,7 +75,7 @@ struct { } _keys; #pragma pack() -void PL_save_player (player_t *p, FILE *h) { +static void PL_save_player (player_t *p, FILE *h) { myfwrite32(p->o.x, h); myfwrite32(p->o.y, h); myfwrite32(p->o.xv, h); @@ -127,7 +129,7 @@ void PL_savegame (FILE *h) { myfwrite8(p_immortal, h); } -void PL_load_player (player_t *p, FILE *h) { +static void PL_load_player (player_t *p, FILE *h) { p->o.x = myfread32(h); p->o.y = myfread32(h); p->o.xv = myfread32(h); @@ -181,7 +183,9 @@ void PL_loadgame (FILE *h) { p_immortal = myfread8(h); } -static int nonz(int a) {return (a)?a:1;} +static int nonz (int a) { + return a ? a : 1; +} static int firediry(player_t *p) { if(p->f&PLF_UP) return -42; @@ -283,7 +287,7 @@ static void jump(player_t *p,int st) { } } -int PL_isdead(player_t *p) { +int PL_isdead (player_t *p) { switch(p->st) { case DEAD: case MESS: case OUT: @@ -292,7 +296,7 @@ int PL_isdead(player_t *p) { return 0; } -void PL_init(void) { +void PL_init (void) { p_immortal=0; PL_JUMP=10;PL_RUN=8; aitime=0; @@ -327,7 +331,7 @@ void PL_alloc(void) { } } -void PL_restore(player_t *p) { +static 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; @@ -349,18 +353,18 @@ void PL_restore(player_t *p) { p->keys=(g_dm)?0x70:0; } -void PL_reset(void) { +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) { +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) { +int PL_hit (player_t *p,int d,int o,int t) { if(!d) return 0; switch(p->st) { case DIE: case SLOP: @@ -382,7 +386,7 @@ int PL_hit(player_t *p,int d,int o,int t) { return 1; } -void PL_damage(player_t *p) { +void PL_damage (player_t *p) { int i; if(!p->hit && p->life>0) return; @@ -426,12 +430,12 @@ void PL_damage(player_t *p) { return; } -void PL_cry(player_t *p) { +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 PL_give (player_t *p, int t) { int i; switch(p->st) { @@ -553,7 +557,7 @@ int PL_give(player_t *p,int t) { } } -void PL_act(player_t *p) { +void PL_act (player_t *p) { int st; if(--aitime<0) aitime=0; @@ -660,7 +664,7 @@ static void chk_bfg(player_t *p,int x,int y) { } } -void bfg_fly(int x,int y,int o) { +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); diff --git a/src/player.h b/src/player.h index 2ddb96f..db4f992 100644 --- a/src/player.h +++ b/src/player.h @@ -20,7 +20,12 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Player data and functions +#ifndef PLAYER_H_INCLUDED +#define PLAYER_H_INCLUDED + +#include "glob.h" +#include "view.h" // obj_t +#include // FILE #define PL_DRAWLIFE 1 #define PL_DRAWARMOR 2 @@ -50,17 +55,16 @@ #define PL_POWERUP_TIME 546 #pragma pack(1) -typedef struct{ +typedef struct { obj_t o; int looky; - int st,s; - int life,armor,hit,hito; - int pain,air; - int invl,suit; + 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; + int frag, ammo, shel, rock, cell, fuel, kills, secrets; + byte fire, cwpn, csnd; byte amul; word wpns; char wpn; @@ -70,24 +74,34 @@ typedef struct{ int id; byte keys; char lives; - int ku,kd,kl,kr,kf,kj,kwl,kwr,kp; -}player_t; + int ku, kd, kl, kr, kf, kj, kwl, kwr, kp; +} player_t; #pragma pack() -extern byte plr_goanim[], plr_dieanim[], plr_slopanim[]; - extern byte p_immortal; -extern player_t pl1, pl2; - -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_cry(player_t *); -void PL_damage(player_t *); -int PL_give(player_t *,int); -void G_respawn_player(player_t *); - -void PL_reset(void); +extern byte p_fly; +extern int PL_JUMP; +extern int PL_RUN; + +extern player_t pl1; +extern player_t pl2; + +extern byte plr_goanim[]; +extern byte plr_dieanim[]; +extern byte plr_slopanim[]; + +void PL_savegame (FILE *h); +void PL_loadgame (FILE *h); +int PL_isdead (player_t *p); +void PL_init (void); +void PL_alloc (void); +void PL_reset (void); +void PL_spawn (player_t *p, int x, int y, char d); +int PL_hit (player_t *p, int d, int o, int t); +void PL_damage (player_t *p); +void PL_cry (player_t *p); +int PL_give (player_t *p, int t); +void PL_act (player_t *p); +void bfg_fly (int x, int y, int o); + +#endif /* PLAYER_H_INCLUDED */ diff --git a/src/render.c b/src/render.c index 254b87e..b0f2485 100644 --- a/src/render.c +++ b/src/render.c @@ -19,6 +19,9 @@ #include "memory.h" #include "files.h" #include "error.h" +#include "game.h" +#include "sound.h" +#include "music.h" // game static vgaimg *scrnh[3]; // TITLEPIC INTERPIC ENDPIC @@ -61,6 +64,8 @@ static byte gamcor[5][64]={ }; // walls #define ANIT 5 +static int WD, HT; +static int w_o, w_x, w_y; static vgaimg *walp[256]; static int walh[256]; static byte walani[256]; @@ -69,20 +74,6 @@ static byte anic[ANIT]; static int max_textures; static vgaimg *horiz; -extern byte bright[256]; // vga.c -extern byte mixmap[256][256]; // vga.c -extern byte clrmap[256*12]; // vga.c - -extern int g_trans; // game.c -extern byte transdraw; // game.c -extern int sky_type; // view.c -extern int lt_time, lt_type, lt_side, lt_ypos, lt_force; // game.c - -extern byte savname[7][24]; // files.c -extern char g_music[8]; // game.c -extern short snd_vol; // sound.c -extern short mus_vol; // music.c - /* --- misc --- */ static void *Z_getspr (char n[4], int s, int d, char *dir) { @@ -1376,7 +1367,7 @@ void R_init () { } R_setgamma(gammaa); V_setrect(0, SCRW, 0, SCRH); - V_setscr(scrbuf); +// V_setscr(scrbuf); V_clr(0, SCRW, 0, SCRH, 0); R_alloc(); } diff --git a/src/render.h b/src/render.h index 9226e99..71d4365 100644 --- a/src/render.h +++ b/src/render.h @@ -1,3 +1,8 @@ +#ifndef RENDER_H_INCLUDED +#define RENDER_H_INCLUDED + +extern int SCRW, SCRH; // from vga.c + void R_draw (void); void R_alloc (void); void R_init (void); @@ -13,3 +18,5 @@ void R_begin_load (void); void R_load (char s[8], int f); void R_end_load (void); void R_loadsky (int sky); + +#endif /* RENDER_H_INCLUDED */ diff --git a/src/smoke.c b/src/smoke.c index 6ccb15a..19bf714 100644 --- a/src/smoke.c +++ b/src/smoke.c @@ -24,9 +24,11 @@ #include #include "view.h" #include "smoke.h" +#include "game.h" #include "fx.h" #include "misc.h" #include "my.h" +#include "monster.h" #define MAXSR 20 @@ -73,7 +75,7 @@ void SMK_loadgame (FILE *h) { } } -void SMK_init(void) { +void SMK_init (void) { int i; for(i=0;i=MAXSMOK) lsm=0; } -void SMK_act(void) { +void SMK_act (void) { int i,ox,oy; static obj_t o; @@ -139,7 +141,7 @@ void SMK_act(void) { } } -void SMK_add(int x,int y,int xv,int yv,byte t,byte s,short o) { +static 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; @@ -152,7 +154,7 @@ void SMK_add(int x,int y,int xv,int yv,byte t,byte s,short o) { inclast(); } -void SMK_gas(int x0,int y0,int xr,int yr,int xv,int yv,int k) { +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; @@ -168,7 +170,7 @@ void SMK_gas(int x0,int y0,int xr,int yr,int xv,int yv,int k) { } } -void SMK_flame(int x0,int y0,int ox,int oy,int xr,int yr,int xv,int yv,int k,int o) { +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; diff --git a/src/smoke.h b/src/smoke.h index 1f33f1d..8ba0a0f 100644 --- a/src/smoke.h +++ b/src/smoke.h @@ -19,7 +19,11 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// Smoke +#ifndef SMOKE_H_INLUDED +#define SMOKE_H_INLUDED + +#include "glob.h" +#include // FILE #define MAXSMOK 500 @@ -27,18 +31,21 @@ #define FLSN 8 #pragma pack(1) -typedef struct{ - int x,y,xv,yv; - byte t,s; +typedef struct { + int x, y, xv, yv; + byte t, s; short o; -}smoke_t; +} smoke_t; #pragma pack() extern smoke_t sm[MAXSMOK]; -void SMK_init(void); -void SMK_alloc(void); -void SMK_act(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); +void SMK_savegame (FILE *h); +void SMK_loadgame (FILE *h); +void SMK_init (void); +void SMK_alloc (void); +void SMK_act (void); +void SMK_gas (int x0, int y0, int xr, int yr, int xv, int yv, int k); +void SMK_flame (int x0, int y0, int ox, int oy, int xr, int yr, int xv, int yv, int k, int o); + +#endif /* SMOKE_H_INLUDED */ diff --git a/src/sound.c b/src/sound.c index de33434..2fe510b 100644 --- a/src/sound.c +++ b/src/sound.c @@ -31,15 +31,13 @@ short snd_vol = 50; -int snddisabled = 1; - -struct { +static int snddisabled = 1; +static struct { snd_t *s; Mix_Chunk *c; } chunks[NUM_CHUNKS]; -void S_init(void) -{ +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()); @@ -71,8 +69,7 @@ void S_init(void) S_volume(snd_vol); } -void S_done(void) -{ +void S_done (void) { free_chunks(); if (SDL_WasInit(SDL_INIT_AUDIO)) { Mix_CloseAudio(); @@ -80,8 +77,7 @@ void S_done(void) } } -Mix_Chunk * get_chunk(snd_t *s, int r, int v) -{ +static Mix_Chunk *get_chunk (snd_t *s, int r, int v) { int i, fi = -1; for(i=0; i128) snd_vol=128; @@ -149,8 +141,7 @@ void S_volume(int v) Mix_Volume(-1, snd_vol); } -void S_wait() -{ +void S_wait (void) { if (snddisabled) return; while (Mix_Playing(-1)) { SDL_Delay(10); diff --git a/src/sound.h b/src/sound.h index dc46f7c..5f71e34 100644 --- a/src/sound.h +++ b/src/sound.h @@ -24,55 +24,36 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef __cplusplus -extern "C" { -#endif +#ifndef SOUND_H_INCLUDED +#define SOUND_H_INCLUDED // заголовок инструмента (DMI) #pragma pack(1) -typedef struct{ - unsigned int len, // длина в байтах - rate, // частота в Гц. - lstart, // начало повтора в байтах от начала данных - llen; // длина повтора в байтах -}snd_t; +typedef struct { + unsigned int len; // длина в байтах + unsigned int rate; // частота в Гц. + unsigned int lstart; // начало повтора в байтах от начала данных + unsigned int llen; // длина повтора в байтах +} snd_t; #pragma pack() -void S_init(void); +// громкость звука и музыки (0-128) +extern short snd_vol; -void S_done(void); +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); +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); - -void S_updatemusic(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 S_stop (short c); -void F_freemus(void); -void S_initmusic(void); -void S_donemusic(void); +void S_volume (int v); +void free_chunks (void); +void S_wait (void); -#ifdef __cplusplus -} -#endif +#endif /* SOUND_H_INCLUDED */ diff --git a/src/switch.c b/src/switch.c index a046508..b04c303 100644 --- a/src/switch.c +++ b/src/switch.c @@ -28,27 +28,28 @@ #include "player.h" #include "misc.h" #include "map.h" +#include "files.h" +#include "game.h" #include "my.h" +#include "monster.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; +typedef struct { + byte x, y; + byte t, tm; + byte a, b, c, d; byte f; -}sw_t; +} sw_t; #pragma pack() -static sw_t sw[MAXSW]; +int sw_secrets; -static void *sndswn,*sndswx,*sndnoway,*sndbdo,*sndbdc,*sndnotele; +static sw_t sw[MAXSW]; +static void *sndswn, *sndswx, *sndnoway, *sndbdo, *sndbdc, *sndnotele; static int swsnd; - -int sw_secrets; +static byte cht, chto, chf, f_ch; void SW_savegame (FILE *h) { int i, n; @@ -91,31 +92,31 @@ void SW_loadgame (FILE *h) { int SW_load (FILE *h) { int i; switch(blk.t) { - case MB_SWITCH2: - sw_secrets = 0; - for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) { - sw[i].x = myfread8(h); - sw[i].y = myfread8(h); - sw[i].t = myfread8(h); - sw[i].tm = myfread8(h); // unused - sw[i].a = myfread8(h); - sw[i].b = myfread8(h); - sw[i].c = myfread8(h); - sw[i].d = myfread8(h); // unused - sw[i].f = myfread8(h); - sw[i].tm = 0; - sw[i].d = 0; - sw[i].f |= 0x80; - if (sw[i].t == SW_SECRET) { - ++sw_secrets; + case MB_SWITCH2: + sw_secrets = 0; + for (i = 0; i < MAXSW && blk.sz > 0; ++i, blk.sz -= 9) { + sw[i].x = myfread8(h); + sw[i].y = myfread8(h); + sw[i].t = myfread8(h); + sw[i].tm = myfread8(h); // unused + sw[i].a = myfread8(h); + sw[i].b = myfread8(h); + sw[i].c = myfread8(h); + sw[i].d = myfread8(h); // unused + sw[i].f = myfread8(h); + sw[i].tm = 0; + sw[i].d = 0; + sw[i].f |= 0x80; + if (sw[i].t == SW_SECRET) { + ++sw_secrets; + } } - } - return 1; + return 1; } return 0; } -void SW_alloc(void) { +void SW_alloc (void) { sndswn=Z_getsnd("SWTCHN"); sndswx=Z_getsnd("SWTCHX"); sndnoway=Z_getsnd("NOWAY"); @@ -124,15 +125,14 @@ void SW_alloc(void) { sndnotele=Z_getsnd("NOTELE"); } -void SW_init(void) { +void SW_init (void) { int i; - - for(i=0;iy)>=FLDH*CELH+o->h) return; @@ -166,7 +166,7 @@ void Z_water_trap(obj_t *o) { } } -void Z_untrap(byte t) { +void Z_untrap (byte t) { byte *p; word n; @@ -205,7 +205,7 @@ static int shutdoor(int i) { return 1; } -void SW_act(void) { +void SW_act (void) { int i; if(swsnd) --swsnd; @@ -233,7 +233,7 @@ static int doortime(int t) { return 0; } -void SW_cheat_open(void) { +void SW_cheat_open (void) { int i; for(i=0;i +#include // FILE +#include "view.h" // obj_t -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 +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 }; extern int sw_secrets; -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); +void SW_savegame (FILE *h); +void SW_loadgame (FILE *h); +int SW_load (FILE *h); +void SW_alloc (void); +void SW_init (void); +void Z_water_trap (obj_t *o); +void Z_untrap (byte t); +void SW_act (void); +void SW_cheat_open (void); +int SW_press (int x, int y, int r, int h, byte t, int o); + +#endif /* SWITCH_H_INCLUDED */ diff --git a/src/vga.c b/src/vga.c index 0d16859..8347b3a 100644 --- a/src/vga.c +++ b/src/vga.c @@ -33,30 +33,26 @@ // адрес экранного буфера -unsigned char *scra; +//unsigned char *scra; // виртуальный экран -unsigned char scrbuf[64000]; - +//unsigned char scrbuf[64000]; int SCRW = 800; int SCRH = 600; - -SDL_Surface* screen = NULL; - -int cx1,cx2,cy1,cy2; - char fullscreen = OFF; byte bright[256]; byte mixmap[256][256]; byte clrmap[256*12]; +static SDL_Surface* screen = NULL; +static int cx1,cx2,cy1,cy2; static byte flametab[16] = { 0xBC,0xBA,0xB8,0xB6,0xB4,0xB2,0xB0,0xD5,0xD6,0xD7,0xA1,0xA0,0xE3,0xE2,0xE1,0xE0 }; - -extern void *walp[256]; +static int offx = 0; +static int offy = 0; #define HQ 2 @@ -76,8 +72,7 @@ vgaimg *V_loadvgaimg (char *name) { return V_getvgaimg(F_getresid(name)); } -short V_init(void) -{ +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); @@ -88,13 +83,11 @@ short V_init(void) } // переключение в текстовый режим -void V_done(void) -{ +void V_done (void) { SDL_Quit(); } -void draw_rect (int x, int y, int w, int h, int c) -{ +static void draw_rect (int x, int y, int w, int h, int c) { SDL_Rect dstrect; dstrect.x = x*HQ; dstrect.y = y*HQ; @@ -104,8 +97,7 @@ void draw_rect (int x, int y, int w, int h, int c) } // установить область вывода -void V_setrect(short x,short w,short y,short h) -{ +void V_setrect (short x,short w,short y,short h) { SDL_Rect r; r.x=x*HQ; r.y=y*HQ; @@ -123,8 +115,7 @@ void V_setrect(short x,short w,short y,short h) if (cy2>=SCRH) cy2=SCRH-1; } -void putpixel(int x, int y, Uint8 color) -{ +static void putpixel (int x, int y, Uint8 color) { if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { x*=HQ; y*=HQ; @@ -137,8 +128,7 @@ void putpixel(int x, int y, Uint8 color) } } -byte getpixel(int x, int y) -{ +static byte getpixel (int x, int y) { if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { x*=HQ; y*=HQ; @@ -147,29 +137,22 @@ byte getpixel(int x, int y) return 0; } -void mappixel(int x,int y,byte* cmap) -{ +static 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) -{ +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) -{ +void V_offset (int ox, int oy) { offx=ox; offy=oy; } -void draw_spr(short x,short y,vgaimg *i, int d, int c) -{ +static void draw_spr (short x, short y, vgaimg *i, int d, int c) { if (i==NULL) return; x += offx; y += offy; @@ -194,36 +177,30 @@ void draw_spr(short x,short y,vgaimg *i, int d, int c) } } -void V_rotspr (int x, int y, vgaimg* i, int d) -{ +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_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_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); +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) -{ +void V_dot (short x,short y, unsigned char c) { putpixel(x,y,c); } -void smoke_sprf(int x, int y, byte c) -{ +void smoke_sprf (int x, int y, byte c) { byte t = getpixel(x,y); c = c + bright[t]; c += 0x60; @@ -231,15 +208,13 @@ void smoke_sprf(int x, int y, byte c) putpixel(x,y,mixmap[c][t]); } -void flame_sprf(int x, int y, byte c) -{ +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) -{ +void V_sprf (short x,short y,vgaimg *i,spr_f *f) { if (i==NULL) return; x-=i->sx; y-=i->sy; @@ -256,30 +231,20 @@ void V_sprf(short x,short y,vgaimg *i,spr_f *f) } } -void V_spr(short x,short y,vgaimg *i) -{ - draw_spr(x,y,i,0, 0); +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) -{ +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); +void V_clr (short x, short w, short y, short h, unsigned char c) { + draw_rect(x, y, w, h, c); } // установить n цветов, начиная с f, из массива p -void VP_set(void *p,short f,short n) -{ +static void VP_set (void *p, short f, short n) { byte *ptr = (byte*)p; SDL_Color colors[256]; int i; @@ -293,22 +258,24 @@ void VP_set(void *p,short f,short n) SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, f, n); } +// установить палитру из массива p +void VP_setall (void *p) { + VP_set(p, 0, 256); +} + // установить адрес экранного буфера // NULL - реальный экран -void V_setscr(void *p) -{ +void V_setscr (void *p) { if (screen) SDL_Flip(screen); } // скопировать прямоугольник на экран -void V_copytoscr(short x,short w,short y,short h) -{ +void V_copytoscr (short x, short w, short y, short h) { x*=HQ; y*=HQ; w*=HQ; h*=HQ; SDL_UpdateRect(screen, x, y, w, h); } -void V_maptoscr(int x,int w,int y,int h,void *cmap) -{ +void V_maptoscr (int x, int w, int y, int h, void *cmap) { int cx,cy; for (cx=x; cxformat->palette->ncolors; SDL_Color colors[256]; diff --git a/src/vga.h b/src/vga.h index 48392c2..44f1d48 100644 --- a/src/vga.h +++ b/src/vga.h @@ -24,219 +24,95 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef __cplusplus -extern "C" { -#endif +#ifndef VGA_H_INCLUDED +#define VGA_H_INCLUDED + +#include "glob.h" -// заголовок изображения #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; +typedef struct { + unsigned short w, h; // W-ширина,H-высота + short sx, sy; // сдвиг центра изображения +} vgaimg; #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); + +extern int SCRW; +extern int SCRH; +extern char fullscreen; -typedef void spr_f(int, int, unsigned char);//typedef void spr_f(void); +extern byte bright[256]; +extern byte mixmap[256][256]; +extern byte clrmap[256*12]; vgaimg *V_getvgaimg (int id); vgaimg *V_loadvgaimg (char *name); // переключение в режим VGA 320x200,256 цветов // возвращает 0, если все о'кей -short V_init(void); +short V_init (void); // переключение в текстовый режим -void V_done(void); +void V_done (void); // ждать обратного хода луча развертки -void V_wait(void); +void V_wait (void); // вывести картинку i в координатах (x,y) -void V_pic(short x,short y,vgaimg *i); +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 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); +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); +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); +void V_spr2 (short x, short y, vgaimg *i); // вывести точку цвета 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); +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); +void V_clr (short x, short w, short y, short h, unsigned char c); // установить палитру из массива 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 VP_setall (void *p); // установить область вывода -void V_setrect(short x,short w,short y,short h); +void V_setrect (short x, short w, short y, short h); // установить адрес экранного буфера // NULL - реальный экран -void V_setscr(void *); +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 V_copytoscr (short x, short w, short y, short h); -// инициализация экрана -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); +void V_maptoscr (int, int, int, int, void *); // переделать изображение 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); +void V_remap (vgaimg *i, colormap m); -// область вывода -extern short scrw,scrh,scrx,scry; +void V_remap_rect (int x, int y, int w, int h, byte *cmap); -// адрес экранного буфера -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_remap_rect(int x,int y,int w,int h,byte *cmap); - -void V_toggle(); +void V_toggle (void); 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; - +void V_center (int f); +void V_offset (int ox, int oy); -#ifdef __cplusplus -} -#endif +#endif /* VGA_H_INCLUDED */ diff --git a/src/view.c b/src/view.c index 4e1fce7..1819698 100644 --- a/src/view.c +++ b/src/view.c @@ -23,7 +23,6 @@ #include "glob.h" #include #include -#include "vga.h" #include "memory.h" #include "files.h" #include "error.h" @@ -42,22 +41,14 @@ #include "my.h" #include "render.h" -int WD; -int HT; - -extern map_block_t blk; - byte w_horiz=ON; -int w_o,w_x,w_y,sky_type=1; +int sky_type=1; dword walf[256]; byte walswp[256]; 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]; - void W_savegame (FILE* h) { char s[8]; int i; @@ -101,7 +92,7 @@ void W_loadgame (FILE* h) { R_end_load(); } -void W_init(void) { +void W_init (void) { DOT_init(); SMK_init(); FX_init(); @@ -114,7 +105,7 @@ void W_init(void) { free_chunks(); } -static void unpack(void *buf, int len, void *obuf) { +static void unpack (void *buf, int len, void *obuf) { int i = 0; int j = 0; unsigned char *p = buf; diff --git a/src/view.h b/src/view.h index 5f1aad9..33eacd2 100644 --- a/src/view.h +++ b/src/view.h @@ -20,36 +20,11 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// View functions - #ifndef VIEW_H_INCLUDED #define VIEW_H_INCLUDED -#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 -}; +#include "glob.h" +#include // FILE #define FLDW 100 #define FLDH 100 @@ -58,40 +33,45 @@ enum{ #define MAXTXW 16 #define MAXTXH 8 +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 +}; + #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; -typedef struct{ +typedef struct { char n[8]; char t; -}wall_t; - +} wall_t; #pragma pack() +extern byte w_horiz; +extern int sky_type; extern dword walf[256]; extern byte walswp[256]; - -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; // +void W_savegame (FILE *h); +void W_loadgame (FILE *h); +void W_init (void); +int W_load (FILE *h); #endif /* VIEW_H_INCLUDED */ diff --git a/src/weapons.c b/src/weapons.c index 34b5ed4..b3b757d 100644 --- a/src/weapons.c +++ b/src/weapons.c @@ -28,19 +28,19 @@ #include "smoke.h" #include "weapons.h" #include "misc.h" +#include "files.h" +#include "game.h" +#include "player.h" +#include "monster.h" +#include "switch.h" #include "my.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}; weapon_t wp[MAXWPN]; static void *snd[14]; - static void throw(int,int,int,int,int,int,int,int); void WP_savegame (FILE *h) { @@ -85,7 +85,7 @@ void WP_loadgame (FILE *h) { } } -void WP_alloc(void) { +void WP_alloc (void) { int i; static char nm[14][6]={ "PISTOL", @@ -106,13 +106,13 @@ void WP_alloc(void) { for(i=0;i<14;++i) snd[i]=Z_getsnd(nm[i]); } -void WP_init(void) { +void WP_init (void) { int i; for(i=0;i // FILE #define MAXWPN 300 #pragma pack(1) -typedef struct{ +typedef struct { obj_t o; - byte t,s; + byte t, s; int own; short target; -}weapon_t; +} weapon_t; #pragma pack() extern weapon_t wp[MAXWPN]; -void WP_init(void); -void WP_alloc(void); -void WP_act(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); +void WP_savegame (FILE *h); +void WP_loadgame (FILE *h); +void WP_alloc (void); +void WP_init (void); +void WP_act (void); +void WP_gun (int x, int y, int xd, int yd, int o, int v); +void WP_punch (int x, int y, int d, int own); +int WP_chainsaw (int x, int y, int d, int own); +void WP_rocket (int x, int y, int xd, int yd, int o); +void WP_revf (int x, int y, int xd, int yd, int o, int t); +void WP_plasma (int x, int y, int xd, int yd, int o); +void WP_ball1 (int x, int y, int xd, int yd, int o); +void WP_ball2 (int x, int y, int xd, int yd, int o); +void WP_ball7 (int x, int y, int xd, int yd, int o); +void WP_aplasma (int x, int y, int xd, int yd, int o); +void WP_manfire (int x, int y, int xd, int yd, int o); +void WP_bfgshot (int x, int y, int xd, int yd, int o); +void WP_bfghit (int x, int y, int o); +void WP_pistol (int x,int y,int xd,int yd,int o); +void WP_mgun (int x, int y, int xd, int yd, int o); +void WP_shotgun (int x, int y, int xd, int yd, int o); +void WP_dshotgun (int x, int y, int xd, int yd, int o); +void WP_ognemet (int x, int y, int xd, int yd, int xv, int yv, int o); + +#endif /* WEAPONS_H_INLUDES */ -- 2.29.2 From 82b3e1cc221312a5bd549d1f2d14bb682a311751 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 09:19:54 +0300 Subject: [PATCH 04/16] implement optional opengl render --- src/CMakeLists.txt | 64 +- src/files.c | 8 +- src/files.h | 8 +- src/gl/render.c | 1572 +++++++++++++++++++++++++++++++++++++++ src/main.c | 22 +- src/{ => soft}/render.c | 19 +- src/{ => soft}/vga.c | 0 src/{ => soft}/vga.h | 0 8 files changed, 1642 insertions(+), 51 deletions(-) create mode 100644 src/gl/render.c rename src/{ => soft}/render.c (98%) rename src/{ => soft}/vga.c (100%) rename src/{ => soft}/vga.h (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c306571..bee976e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,25 +1,49 @@ -cmake_minimum_required( VERSION 2.6 ) +cmake_minimum_required(VERSION 3.6) +project(doom2d C) -set( BIN doom2d ) -project( ${BIN} ) +option(WITH_OPENGL "Build with OpenGL render" OFF) +option(WITH_SOFTWARE "Build with Software render" ON) -set( SOURCE_ROOT ../src ) +set(D2D_GAME_ROOT .) +set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl) +set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft) find_package(SDL REQUIRED) find_package(SDL_mixer REQUIRED) - -aux_source_directory( ${SOURCE_ROOT} SOURCES ) - -include_directories( "${SOURCE_ROOT}" - "${SDL_INCLUDE_DIR}" - "${SDLMIXER_INCLUDE_DIR}" ) - -set( INSTALL_PATH /usr/local/bin/ ) - -set( CMAKE_CXX_FLAGS "-O2 -Wall -MMD -MP -MF" ) - -add_executable( ${BIN} ${SOURCES} ) - -target_link_libraries( ${BIN} "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" ) - -install( TARGETS ${BIN} DESTINATION ${INSTALL_PATH} ) +if (WITH_OPENGL) + find_package(OpenGL REQUIRED) +endif (WITH_OPENGL) + +aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC) +aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC) +aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif (NOT CMAKE_BUILD_TYPE) +set(CMAKE_C_FLAGS "") +set(CMAKE_C_FLAGS_DEBUG "-g -O2 -Wall") +set(CMAKE_C_FLAGS_RELEASE "-O3") # -DNDEBUG +set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + +message(STATUS "=== BUILD OPTIONS ===") +message(STATUS "BUILD: " ${CMAKE_BUILD_TYPE}) +message(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) + +message(STATUS "=== RENDERS ===") +message(STATUS "SOFTWARE: " ${WITH_SOFTWARE}) +message(STATUS "OPENGL: " ${WITH_OPENGL}) + +if (WITH_OPENGL) + add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_OPENGL_SRC}) + target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}") + target_link_libraries(doom2d-gl "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" "${OPENGL_LIBRARY}") +endif (WITH_OPENGL) + +if (WITH_SOFTWARE) + add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SOFTWARE_SRC}) + target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}") + target_link_libraries(doom2d-soft "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}") +endif (WITH_SOFTWARE) diff --git a/src/files.c b/src/files.c index 597d149..5527171 100644 --- a/src/files.c +++ b/src/files.c @@ -326,7 +326,7 @@ void F_saveres(int r, void *p, dword o, dword l) { */ // get resource id -int F_findres (char *n) { +int F_findres (const char n[8]) { int i; for (i = 0; i < wad_num; i++) { if (strncasecmp(wad[i].n, n, 8) == 0) { @@ -337,7 +337,7 @@ int F_findres (char *n) { } // get resource id -int F_getresid (char *n) { +int F_getresid (const char n[8]) { int i = F_findres(n); if (i == -1) { ERR_fatal("F_getresid: ресурс %.8s не найден", n); @@ -345,12 +345,12 @@ int F_getresid (char *n) { return i; } -void F_getresname (char *n, int r) { +void F_getresname (char n[8], int r) { memcpy(n, wad[r].n, 8); } // get sprite id -int F_getsprid (char n[4], int s, int d) { +int F_getsprid (const char n[4], int s, int d) { int i; byte a,b; diff --git a/src/files.h b/src/files.h index e2d94f0..fbeaa29 100644 --- a/src/files.h +++ b/src/files.h @@ -56,10 +56,10 @@ void F_addwad (char *fn); void F_initwads (void); void F_allocres (void); void F_loadres (int r, void *p, dword o, dword l); -int F_findres (char *n); -int F_getresid (char *n); -void F_getresname (char *n, int r); -int F_getsprid (char n[4], int s, int d); +int F_findres (const char n[8]); +int F_getresid (const char n[8]); +void F_getresname (char n[8], int r); +int F_getsprid (const char n[4], int s, int d); int F_getreslen (int r); void F_nextmus (char *s); void F_randmus (char *s); diff --git a/src/gl/render.c b/src/gl/render.c new file mode 100644 index 0000000..01e4014 --- /dev/null +++ b/src/gl/render.c @@ -0,0 +1,1572 @@ +#include "glob.h" +#include "render.h" +#include "files.h" +#include "memory.h" +#include "misc.h" +#include "error.h" + +#include "menu.h" +#include "game.h" +#include "dots.h" +#include "items.h" + +#include "sound.h" // snd_vol +#include "music.h" // mus_vol + +#include "fx.h" +#include "player.h" +#include "monster.h" +#include "weapons.h" +#include "smoke.h" +#include "view.h" +#include "switch.h" // sw_secrets + +#include +#include // malloc free abs +#include // assert +#include + +#define VGA_TRANSPARENT_COLOR 0 +#define DEFAULT_SKY_COLOR 0x97 +#define MANCOLOR 0xD0 +#define PLAYER_COLOR_OFFSET 7 +#define MAXAIR 1091 +#define ANIT 5 +#define PL_FLASH 90 + +#pragma pack(1) +typedef struct vgaimg { + word w, h; + short x, y; + byte data[]; +} vgaimg; + +typedef struct rgb { + byte r, g, b; +} rgb; + +typedef struct rgba { + byte r, g, b, a; +} rgba; +#pragma pack() + +typedef struct image { + GLuint id; + GLint x, y; + GLuint w, h; + int res; +} image; + +/* Render Specific */ +int SCRW = 320; // public +int SCRH = 200; // public +static int gamma; +static int fullscreen; +static SDL_Surface *surf; +static rgb playpal[256]; +static byte bright[256]; + +/* Game */ +static image scrnh[3]; // TITLEPIC INTERPIC ENDPIC +static image ltn[2][2]; + +/* Smoke */ +static image smk_spr[SMSN]; +static image smk_fspr[FLSN]; + +/* Effects */ +static image fx_spr[15]; +static char fx_sprd[15]; + +/* Weapons */ +static image wp_spr[49*2]; +static char wp_sprd[49*2]; + +/* Items */ +static image item_spr[58]; +static char item_sprd[58]; + +/* Player */ +static image plr_spr[27*2]; +static image plr_msk[27*2]; +static char plr_sprd[27*2]; +static image plr_wpn[11][6]; + +/* Monsters */ +static image pl_spr[2]; +static image pl_msk[2]; +static image mn_spr[MN_TN][29*2]; +static image mn_man_msk[29*2]; +static char mn_sprd[MN_TN][29*2]; +static image mn_fspr[8]; +static image mn_sgun[2]; + +/* Misc */ +static image sth[22]; +static image bfh[160 - '!']; +static image sfh[160 - '!']; +static image stone; +static image stone2; +static image keys[3]; +static int prx = 0; +static int pry = 0; + +/* Menu */ +static int gm_tm; +static image msklh[2]; +static image mbarl; +static image mbarm; +static image mbarr; +static image mbaro; +static image mslotl; +static image mslotm; +static image mslotr; + +/* Map */ +static const char *anm[ANIT - 1][5] = { + {"WALL22_1", "WALL23_1", "WALL23_2", NULL, NULL}, + {"WALL58_1", "WALL58_2", "WALL58_3", NULL, NULL}, + {"W73A_1", "W73A_2", NULL, NULL, NULL}, + {"RP2_1", "RP2_2", "RP2_3", "RP2_4", NULL} +}; +static int max_wall_width; +static int max_wall_height; +static int max_textures; +static image walp[256]; +static byte walani[256]; +static image anip[ANIT][5]; +static byte anic[ANIT]; +static image horiz; + +/* Generic helpers */ + +static void R_init_playpal (void) { + int i; + byte *vgapal = M_lock(F_getresid("PLAYPAL")); + for (i = 0; i < 256; i++) { + playpal[i] = (rgb) { + .r = vgapal[i * 3 + 0] * 255 / 63, + .g = vgapal[i * 3 + 1] * 255 / 63, + .b = vgapal[i * 3 + 2] * 255 / 63, + }; + bright[i] = ((int)vgapal[i * 3 + 0] + vgapal[i * 3 + 1] + vgapal[i * 3 + 2]) * 8 / (63 * 3); + } + M_unlock(vgapal); +} + +static vgaimg *R_getvga (int id) { + int loaded = M_was_locked(id); + vgaimg *v = M_lock(id); + if (v != NULL && !loaded) { + v->w = short2host(v->w); + v->h = short2host(v->h); + v->x = short2host(v->x); + v->y = short2host(v->y); + } + return v; +} + +static rgba *R_extract_flame_spr (vgaimg *v) { + static const byte flametab[16] = { + 0xBC, 0xBA, 0xB8, 0xB6, 0xB4, 0xB2, 0xB0, 0xD5, + 0xD6, 0xD7, 0xA1, 0xA0, 0xE3, 0xE2, 0xE1, 0xE0 + }; + int i, j; + rgba *s = malloc(v->w * v->h * sizeof(rgba)); + if (s != NULL) { + for (j = 0; j < v->h; j++) { + for (i = 0; i < v->w; i++) { + int k = j * v->w + i; + byte c = v->data[k] + bright[DEFAULT_SKY_COLOR]; + s[k] = (rgba) { + .r = playpal[flametab[c]].r, + .g = playpal[flametab[c]].g, + .b = playpal[flametab[c]].b, + .a = v->data[k] == VGA_TRANSPARENT_COLOR ? 0x00 : 0xFF, + }; + } + } + } + return s; +} + +static rgba *R_extract_smoke_spr (vgaimg *v) { + int i, j; + rgba *s = malloc(v->w * v->h * sizeof(rgba)); + if (s != NULL) { + for (j = 0; j < v->h; j++) { + for (i = 0; i < v->w; i++) { + int k = j * v->w + i; + byte c = ((v->data[k] + bright[DEFAULT_SKY_COLOR]) + 0x60) ^ 0x0F; + byte a = 0xFF - ((int)playpal[c].r + playpal[c].g + playpal[c].b) / 3; + s[k] = (rgba) { + .r = playpal[c].r, + .g = playpal[c].g, + .b = playpal[c].b, + .a = v->data[k] == VGA_TRANSPARENT_COLOR ? 0x00 : a, + }; + } + } + } + return s; +} + +static rgba *R_extract_mask_spr (vgaimg *v) { + int i, j; + rgba *s = malloc(v->w * v->h * sizeof(rgba)); + if (s != NULL) { + for (j = 0; j < v->h; j++) { + for (i = 0; i < v->w; i++) { + int k = j * v->w + i; + byte c = v->data[k]; + if (c >= 0x70 && c <= 0x7F) { + byte mask = c - 0x70; + mask = 0xFF - ((mask << 4) | mask); + s[k] = (rgba) { + .r = mask, + .g = mask, + .b = mask, + .a = 0xFF, + }; + } else { + s[k] = (rgba) { + .r = 0, + .g = 0, + .b = 0, + .a = 0, + }; + } + } + } + } + return s; +} + +static rgba *R_extract_rgba_spr (vgaimg *v) { + int i, j; + rgba *s = malloc(v->w * v->h * sizeof(rgba)); + if (s != NULL) { + for (j = 0; j < v->h; j++) { + for (i = 0; i < v->w; i++) { + int k = j * v->w + i; + byte c = v->data[k]; + s[k] = (rgba) { + .r = playpal[c].r, + .g = playpal[c].g, + .b = playpal[c].b, + .a = c == VGA_TRANSPARENT_COLOR ? 0x00 : 0xFF, + }; + } + } + } + return s; +} + +/* OpenGL helpers */ + +static image R_gl_create_image (const rgba *buf, int w, int h) { + GLuint tex = 0; + glGenTextures(1, &tex); + if (tex != 0) { + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); + glBindTexture(GL_TEXTURE_2D, 0); + } + return (image) { + .id = tex, + .w = w, + .h = h, + }; +} + +static image R_gl_get_special_image (int id, rgba *(*fn)(vgaimg*)) { + image img = (image) { .res = -1 }; + vgaimg *v = R_getvga(id); + if (v != NULL) { + rgba *buf = (*fn)(v); + img = R_gl_create_image(buf, v->w, v->h); + img.x = v->x; + img.y = v->y; + img.res = id; + M_unlock(v); + free(buf); + } + return img; +} + +static image R_gl_getimage (int id) { + return R_gl_get_special_image(id, &R_extract_rgba_spr); +} + +static image R_gl_loadimage (const char name[8]) { + return R_gl_getimage(F_getresid(name)); +} + +static image R_gl_get_special_spr (const char n[4], int s, int d, rgba *(*fn)(vgaimg*)) { + return R_gl_get_special_image(F_getsprid(n, s, d), fn); +} + +static void R_gl_free_image (image *img) { + if (img->id != 0 && img->res >= 0) { + glDeleteTextures(1, &img->id); + } + img->id = 0; +} + +static void R_gl_draw_quad (int x, int y, int w, int h) { + glBegin(GL_QUADS); + glVertex2i(x + w, y); + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y + h); + glEnd(); +} + +static void R_gl_draw_textured (image *img, int x, int y, int w, int h, int flip) { + int ax = flip == 0; + int bx = !ax; + glBindTexture(GL_TEXTURE_2D, img->id); + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glTexCoord2f(ax, 0); glVertex2i(x + w, y); + glTexCoord2f(bx, 0); glVertex2i(x, y); + glTexCoord2f(bx, 1); glVertex2i(x, y + h); + glTexCoord2f(ax, 1); glVertex2i(x + w, y + h); + glEnd(); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); +} + +/* fit image into rectangle without applying offset and transparency */ +static void R_gl_draw_image_ext (image *img, int x, int y, int w, int h) { + glDisable(GL_BLEND); + glColor3ub(255, 255, 255); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_textured(img, x, y, w, h, 0); +} + +/* draw sprite with offset and coloring */ +static void R_gl_draw_image_color (image *img, int x, int y, int flip) { + int xx = flip ? x - img->w + img->x : x - img->x; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_textured(img, xx, y - img->y, img->w, img->h, flip); + glDisable(GL_BLEND); +} + +/* draw sprite with offset */ +static void R_gl_draw_image (image *img, int x, int y, int flip) { + int xx = flip ? x - img->w + img->x : x - img->x; + glEnable(GL_BLEND); + glColor3ub(255, 255, 255); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_textured(img, xx, y - img->y, img->w, img->h, flip); +} + +static void R_gl_set_color (byte c) { + glColor3ub(playpal[c].r, playpal[c].g, playpal[c].b); +} + +static void R_gl_setclip (int x, int y, int w, int h) { + glScissor(x, SCRH - h - y, w, h); +} + +static void R_gl_setmatrix (void) { + glScissor(0, 0, SCRW, SCRH); + glViewport(0, 0, SCRW, SCRH); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, SCRW, SCRH, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +/* --- Misc --- */ + +static image Z_getspr (const char n[4], int s, int d, char *dir) { + int h = F_getsprid(n, s, d); + if (dir != NULL) { + *dir = (h & 0x8000) ? 1 : 0; + } + return R_gl_getimage(h); +} + +static void Z_putch_generic (image img[], int off, int ch) { + image *p = NULL; + if (ch > 32 && ch < 160) { + p = &img[ch - '!']; + } + if (p != NULL) { + R_gl_draw_image(p, prx, pry, 0); + prx += p->w - 1; + } else { + prx += off; + } +} + +static void Z_printf_generic (image img[], int off, const char *fmt, va_list ap) { + int i; + char buf[80]; + vsprintf(buf, fmt, ap); + for (i = 0; buf[i]; ++i) { + switch (buf[i]) { + case '\n': + pry += off + 1; + case '\r': + prx = 0; + break; + default: + Z_putch_generic(img, off, (byte)buf[i]); + } + } +} + +static void Z_gotoxy (int x, int y) { + prx = x; + pry = y; +} + +static void Z_printbf (const char *fmt, ...) { + va_list a; + va_start(a, fmt); + Z_printf_generic(bfh, 12, fmt, a); + va_end(a); +} + +static void Z_printsf (const char *fmt, ...) { + va_list a; + va_start(a, fmt); + Z_printf_generic(sfh, 7, fmt, a); + va_end(a); +} + +static void Z_printhf (const char *fmt, ...) { + int i, c; + char buf[80]; + va_list a; + va_start(a, fmt); + vsprintf(buf, fmt, a); + va_end(a); + for (i = 0; buf[i]; ++i) { + switch (buf[i]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + c = buf[i] - '0'; + break; + case '-': + c = 10; + break; + case '%': + c = 11; + break; + case '\n': + pry += 19; + case '\r': + c = -1; + prx = 0; + break; + default: + c = -1; + break; + } + if (c >= 0) { + R_gl_draw_image(&sth[c], prx, pry, 0); + } + prx += 14; + } +} + +/* --- Menu --- */ + +static image *PL_getspr (int s, int d, int msk) { + int i = (s - 'A') * 2 + d; + return msk ? &plr_msk[i] : &plr_spr[i]; +} + +static void GM_draw (void) { + enum {MENU, MSG}; // copypasted from menu.c! + 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 + }; // copypasted from menu.c! + int i, j, k, x, y, cx, cy; + image *img; + gm_tm += 1; + if (mnu != NULL) { + cx = SCRW / 2; + cy = SCRH / 2; + if (mnu->type == MENU) { + y = cy - (mnu->n * 16 - 20) / 2; + Z_gotoxy(cx - mnu->x, y - 10); Z_printbf("%s", mnu->ttl); + for (i = 0; i < mnu->n; i++) { + if (mnu->t[i] == LOAD || mnu->t[i] == SAVE) { + j = y + i * 16 + 29; + R_gl_draw_image(&mslotl, cx - mnu->x, j, 0); + for (k = 8; k < 184; k += 8) { + R_gl_draw_image(&mslotm, cx - mnu->x + k, j, 0); + } + R_gl_draw_image(&mslotr, cx - mnu->x + 184, j, 0); + Z_gotoxy(cx - mnu->x + 4, j - 8); + if (input && i == save_mnu.cur) { + Z_printsf("%s_", ibuf); + } else { + Z_printsf("%s", savname[i]); + } + } else { + x = mnu->t[i] >= SVOLM ? (mnu->t[i] >= PL1CM ? 50 : 152) : 0; + Z_gotoxy(cx - mnu->x + x, y + i * 16 + 20); + Z_printbf("%s", mnu->m[i]); + switch (mnu->t[i]) { + case MUSIC: + Z_printbf(" '%s'", g_music); + break; + case INTERP: + Z_printbf("%s", fullscreen ? "ON" : "OFF"); + break; + case PL1CM: + case PL1CP: + case PL2CM: + case PL2CP: + img = PL_getspr(*panimp, 0, 0); + R_gl_draw_image(img, cx - mnu->x + (mnu->t[i] == PL1CM ? 15 : 35), y + i * 16 + 20 + 14, 0); + img = PL_getspr(*panimp, 0, 1); + R_gl_set_color(pcolortab[(mnu->t[i] == PL1CM) ? p1color : p2color] + PLAYER_COLOR_OFFSET); + R_gl_draw_image_color(img, cx - mnu->x + (mnu->t[i] == PL1CM ? 15 : 35), y + i * 16 + 20 + 14, 0); + break; + case SVOLM: + case SVOLP: + case MVOLM: + case MVOLP: + case GAMMAM: + case GAMMAP: + j = y + i * 16 + 20; + R_gl_draw_image(&mbarl, cx - mnu->x, j, 0); + for (k = 8; k < 144; k += 8) { + R_gl_draw_image(&mbarm, cx - mnu->x + k, j, 0); + } + R_gl_draw_image(&mbarr, cx - mnu->x + 144, j, 0); + switch (mnu->t[i]) { + case SVOLM: + k = snd_vol; + break; + case MVOLM: + k = mus_vol; + break; + case GAMMAM: + k = gamma << 5; + break; + default: + k = 0; + break; + } + R_gl_draw_image(&mbaro, cx - mnu->x + 8 + k, j, 0); + break; + } + } + } + R_gl_draw_image(&msklh[(gm_tm / 6) & 1], cx - mnu->x - 25, y + mnu->cur * 16 + 20 - 8, 0); + } else if (mnu->type == MSG) { + Z_gotoxy(cx - strlen(mnu->ttl) * 7 / 2, cy - 10); Z_printsf(mnu->ttl); + Z_gotoxy(cx - 24, SCRH / 2); Z_printsf("(Y/N)"); + } else { + ERR_fatal("Unknown menu type %i\n", mnu->type); + } + } +} + +/* --- View --- */ + +static void R_draw_fld (byte *fld, int minx, int miny, int maxx, int maxy, int fg) { + int i, j; + assert(minx >= 0 && minx <= FLDW); + assert(miny >= 0 && miny <= FLDH); + assert(maxx >= 0 && maxx <= FLDW); + assert(maxy >= 0 && maxy <= FLDH); + for (j = miny; j < maxy; j++) { + for (i = minx; i < maxx; i++) { + byte id = fld[j * FLDW + i]; + if (id != 0) { + if (walp[id].res < 0) { + if (fg) { + switch (walp[id].id) { + case 1: + glColor4ub(0, 0, 255, 127); + break; + case 2: + glColor4ub(0, 127, 0, 127); + break; + case 3: + glColor4ub(127, 0, 0, 127); + break; + default: + glColor4ub(0, 0, 0, 127); + break; + } + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + R_gl_draw_quad(i * CELW, j * CELW, CELW, CELH); + } + } else { + R_gl_draw_image(&walp[id], i * CELW, j * CELH, 0); + } + } + } + } +} + +static void R_draw_dots (void) { + int i; + glBegin(GL_POINTS); + for (i = 0; i < MAXDOT; i++) { + if (dot[i].t != 0) { + R_gl_set_color(dot[i].c); + glVertex2i(dot[i].o.x, dot[i].o.y + 1); + } + } + glEnd(); +} + +static void R_draw_items (void) { + int i, s; + for (i = 0; i < MAXITEM; ++i) { + s = -1; + if (it[i].t && it[i].s >= 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) { + R_gl_draw_image(&item_spr[s], it[i].o.x, it[i].o.y, item_sprd[s]); + } + } +} + +static int standspr (player_t *p) { + if (p->f & PLF_UP) { + return 'X'; + } else if (p->f & PLF_DOWN) { + return 'Z'; + } else { + return 'E'; + } +} + +static int wpnspr (player_t *p) { + if (p->f & PLF_UP) { + return 'C'; + } else if(p->f & PLF_DOWN) { + return 'E'; + } else { + return 'A'; + } +} + +static void R_draw_player (player_t *p) { + enum {STAND, GO, DIE, SLOP, DEAD, MESS, OUT, FALL}; // copypasted from player.c! + static const int wytab[] = {-1, -2, -1, 0}; + int s = 'A'; + int w = 0; + int wx = 0; + int 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 = plr_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 = plr_dieanim[p->s]; + break; + case SLOP: + s = plr_slopanim[p->s]; + break; + case OUT: + s = 0; + break; + } + if (p->wpn == 0) { + w = 0; + } + if (w) { + R_gl_draw_image(&plr_wpn[(int)p->wpn][w -'A'], p->o.x + wx, p->o.y + wy, p->d); + } + if (s) { + R_gl_draw_image(&plr_spr[(s - 'A') * 2 + p->d], p->o.x, p->o.y, plr_sprd[(s - 'A') * 2 + p->d]); + R_gl_set_color(p->color + PLAYER_COLOR_OFFSET); + R_gl_draw_image_color(&plr_msk[(s - 'A') * 2 + p->d], p->o.x, p->o.y, plr_sprd[(s - 'A') * 2 + p->d]); + } +} + +static void R_draw_monsters (void) { + enum {SLEEP, GO, RUN, CLIMB, DIE, DEAD, ATTACK, SHOOT, PAIN, WAIT, REVIVE, RUNOUT}; // copypasted from monster.c! + int i; + for (i = 0; i < MAXMN; i++) { + if (mn[i].t != MN_NONE) { + int x = mn[i].o.x; + int y = mn[i].o.y; + if (mn[i].t < MN__LAST) { + if ((mn[i].t != MN_SOUL && mn[i].t != MN_PAIN) || mn[i].st != DEAD) { + int ap = mn[i].ap[mn[i].ac]; + int d = (ap - 'A') * 2 + mn[i].d; + int dir = mn_sprd[mn[i].t - 1][d]; + if (mn[i].t == MN_MAN && (ap == 'E' || ap == 'F')) { + R_gl_draw_image(&mn_sgun[ap - 'E'], x, y, mn[i].d); + } + R_gl_draw_image(&mn_spr[mn[i].t - 1][d], x, y, dir); + if (mn[i].t == MN_MAN) { + R_gl_set_color(MANCOLOR + PLAYER_COLOR_OFFSET); + R_gl_draw_image_color(&mn_man_msk[d], x, y, dir); + } + } + if (mn[i].t == MN_VILE && mn[i].st == SHOOT) { + R_gl_draw_image(&mn_fspr[mn[i].ac / 3], mn[i].tx, mn[i].ty, 0); + } + } else if (mn[i].t == MN_PL_DEAD || mn[i].t == MN_PL_MESS) { + int type = mn[i].t - MN_PL_DEAD; + R_gl_draw_image(&pl_spr[type], x, y, 0); + R_gl_set_color(mn[i].d); + R_gl_draw_image_color(&pl_msk[type], x, y, 0); + } + } + } +} + +static void R_draw_weapons (void) { + enum {NONE, ROCKET, PLASMA, APLASMA, BALL1, BALL2, BALL7, BFGBALL, BFGHIT, MANF, REVF, FIRE}; // copypasted from weapons.c! + int i, s, d, x, y; + for (i = 0; i < MAXWPN; ++i) { + s = -1; + d = 0; + switch (wp[i].t) { + case REVF: + case ROCKET: + d = wp[i].s; + if (d < 2) { + d = wp[i].o.xv > 0 ? 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: + s=wp[i].s; + if (s >= 2) { + s /= 2; + break; + } + case PLASMA: + case APLASMA: + case BALL1: + case BALL7: + case BALL2: + s = wp[i].s; + if (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: + s = wp[i].s; + if (s >= 2) { + s = s / 2 + 1; + } + s += 18; + break; + case BFGHIT: + s = wp[i].s / 2 + 26; + break; + } + if (s >= 0) { + R_gl_draw_image(&wp_spr[s * 2 + d], wp[i].o.x, wp[i].o.y, wp_sprd[s * 2 + d]); + } + } +} + +static void R_draw_smoke (void) { + int i, s; + for (i = 0; i < MAXSMOK; ++i) { + if (sm[i].t) { + switch (sm[i].s) { + case 0: + s = sm[i].t; + if (s >= (SMSN - 1) * 3) { + s = 0; + } else { + s = SMSN - 1 - s / 3; + } + R_gl_draw_image(&smk_spr[s], sm[i].x >> 8, (sm[i].y >> 8) + 1, 0); + break; + case 1: + s = sm[i].t; + if (s >= FLSN - 1) { + s = 0; + } else { + s = FLSN - 1 - s; + } + R_gl_draw_image(&smk_fspr[s], sm[i].x >> 8, (sm[i].y >> 8) + 1, 0); + break; + } + } + } +} + +static void R_draw_effects (void) { + enum {NONE, TFOG, IFOG, BUBL}; // copypasted from fx.c + int i, s; + for (i = 0; i < MAXFX; ++i) { + switch (fx[i].t) { + case TFOG: + s = fx[i].s / 2; + R_gl_draw_image(&fx_spr[s], fx[i].x, fx[i].y, fx_sprd[s]); + break; + case IFOG: + s = fx[i].s / 2 + 10; + R_gl_draw_image(&fx_spr[s], fx[i].x, fx[i].y, fx_sprd[s]); + break; + case BUBL: + glBegin(GL_POINTS); + R_gl_set_color(0xC0 + fx[i].s); + glVertex2i(fx[i].x >> 8, (fx[i].y >> 8) + 1); + glEnd(); + break; + } + } +} + +static int get_pu_st (int t) { + if (t >= PL_FLASH) { + return 1; + } else if((t / 9) & 1) { + return 0; + } else { + return 1; + } +} + +static void R_draw_view (int x, int y, int w, int h, int camx, int camy) { + glPushMatrix(); + R_gl_setclip(x, y, w, h); + glTranslatef(x, y, 0); + if (w_horiz && horiz.id != 0) { + R_gl_draw_image_ext(&horiz, 0, 0, w, h); + if (sky_type == 2 && lt_time < 0) { + image *tanderbolt = <n[lt_type][lt_time < -5 ? 0 : 1]; + if (!lt_side) { + R_gl_draw_image(tanderbolt, 0, lt_ypos, 0); + } else { + R_gl_draw_image(tanderbolt, w - 1, lt_ypos, 1); + } + } + } else { + glDisable(GL_BLEND); + R_gl_set_color(DEFAULT_SKY_COLOR); + R_gl_draw_quad(0, 0, w, h); + } + int maxx = min((camx + w) / CELW + 1, FLDW); + int maxy = min((camy + h) / CELH + 1, FLDH); + int minx = max((camx - max_wall_width) / CELW, 0); + int miny = max((camy - max_wall_height) / CELH, 0); + glTranslatef(-camx, -camy, 0); + R_draw_fld((byte*)fldb, minx, miny, maxx, maxy, 0); + R_draw_dots(); + R_draw_items(); + R_draw_player(&pl1); + if (_2pl) { + R_draw_player(&pl2); + } + R_draw_monsters(); + R_draw_weapons(); + R_draw_smoke(); + R_draw_effects(); + R_draw_fld((byte*)fldf, minx, miny, maxx, maxy, 1); + glTranslatef(camx, camy, 0); + if (sky_type == 2 && (lt_time == -4 || lt_time == -2)) { + glColor4ub(255, 255, 255, 255); + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + R_gl_draw_quad(0, 0, w, h); + } + glPopMatrix(); +} + +static void R_draw_player_view (player_t *p, int x, int y, int w, int h) { + p->looky = min(max(p->looky, -SCRH / 4), SCRH / 4); // TODO remove writeback + int st = stone.w; + int cw = w - st; + int cx = min(max(p->o.x, cw / 2), FLDW * CELW - cw / 2); + int cy = min(max(p->o.y - 12 + p->looky, h / 2), FLDH * CELH - h / 2); + int camx = max(cx - cw / 2, 0); + int camy = max(cy - h / 2, 0); + glPushMatrix(); + R_draw_view(x, y + 1, cw, h - 2, camx, camy); + glTranslatef(x, y, 0); + if (p->invl) { + if (get_pu_st(p->invl)) { + glEnable(GL_BLEND); + glColor4ub(191, 191, 191, 255); + glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + R_gl_draw_quad(0, 0, cw, h); + } + } else { + if (p->suit && get_pu_st(p->suit)) { + glEnable(GL_BLEND); + glColor4ub(0, 255, 0, 192); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_quad(0, 0, cw, h); + } + int f = min(max(p->pain * 3, 0), 255); + if (f > 0) { + glEnable(GL_BLEND); + glColor4ub(255, 0, 0, f); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_quad(0, 0, cw, h); + } + } + R_gl_setclip(x, y, w, h); + glTranslatef(-x + cw, 0, 0); + R_gl_draw_image(&stone, 0, 0, 0); + int i = stone.h; + while (i < h) { + R_gl_draw_image(&stone2, 0, i, 0); + i += stone2.h; + } + if (p->drawst & PL_DRAWAIR) { + if (p->air < PL_AIR) { + int a = min(max(p->air, 0), MAXAIR) * 100 / MAXAIR; + glDisable(GL_BLEND); + R_gl_set_color(0xC8); + R_gl_draw_quad(10, 49, a, 2); + } + } + if (p->drawst & PL_DRAWLIFE) { + Z_gotoxy(10, 7); + Z_printhf("%3d%%", p->life); + } + if (p->drawst & PL_DRAWARMOR) { + Z_gotoxy(10, 7 + 19); + Z_printhf("%3d%%", 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 7: + case 8: + i = p->cell; + break; + case 10: + i = p->fuel; + break; + default: + i = -1; + break; + } + // weapon + if (p->wpn >= 0) { + R_gl_draw_image(&sth[12 + p->wpn], st - 88, 58 + 19, 0); + } + // ammo + if (p->wpn >= 2) { + Z_gotoxy(st - 10 - 5 * 14, 58 + 2); + Z_printhf("%5d", i); + } + } + if (p->drawst & PL_DRAWFRAG && g_dm) { + Z_gotoxy(st - 5 - 5 * 14, 77 + 5); + Z_printhf("%5d", p->frag); + } + if (p->drawst & PL_DRAWKEYS) { + int x, k, n; + for (k = p->keys >> 4, n = 0, x = st - 75; n < 3; n++, k >>= 1, x += 9) { + if (k & 1) { + R_gl_draw_image(&keys[n], x, 91, 0); + } + } + } + if (p->drawst & PL_DRAWLIVES && !_2pl) { + Z_gotoxy(st - 35, 17); + Z_printhf("%d", p->lives); + } + glPopMatrix(); +} + +/* --- Game --- */ + +static void pl_info (player_t *p, int x, int y) { + dword t = p->kills * 10920 / g_time; + Z_gotoxy(x + 25, y); Z_printbf("KILLS"); + Z_gotoxy(x + 25, y + 15); Z_printbf("KPM"); + Z_gotoxy(x + 25, y + 30); Z_printbf("SECRETS %u / %u", p->secrets, sw_secrets); + Z_gotoxy(x + 255, y); Z_printbf("%u", p->kills); + Z_gotoxy(x + 255, y + 15); Z_printbf("%u.%u", t / 10, t % 10); +} + +static void R_draw_intermission (void) { + int cx = SCRW / 2; + word hr, mn, sc, h; + Z_gotoxy(cx - 14*12/2, 20); + Z_printbf("LEVEL COMPLETE"); + Z_calc_time(g_time, &hr, &mn, &sc); + Z_gotoxy(cx - 12*12/2, 40); + Z_printbf("TIME %u:%02u:%02u", hr, mn, sc); + h = 40 + SCRH / 10; + if (_2pl) { + Z_gotoxy(cx - 10*12/2, h); + Z_printbf("PLAYER ONE"); + h += 20; + } + pl_info(&pl1, cx - 160, h); + if (_2pl) { + h += 30 + SCRH / 10; + Z_gotoxy(cx - 10*12/2, h); + Z_printbf("PLAYER TWO"); + h += 20; + pl_info(&pl2, cx - 160, h); + } +} + +static void W_act (void) { + int i, a; + if (g_time % 3 == 0) { + for (i = 1; i < max_textures; i++) { + a = walani[i]; + if (a != 0) { + anic[a]++; + if (anip[a][anic[a]].res == -1) { + anic[a] = 0; + } + walp[i] = anip[a][anic[a]]; + } + } + } +} + +void R_draw (void) { + W_act(); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + R_gl_setmatrix(); + switch (g_st) { + case GS_ENDANIM: + case GS_END2ANIM: + case GS_DARKEN: + case GS_BVIDEO: + case GS_EVIDEO: + case GS_END3ANIM: + break; + case GS_TITLE: + R_gl_draw_image_ext(&scrnh[0], 0, 0, SCRW, SCRH); + break; + case GS_INTER: + R_gl_draw_image_ext(&scrnh[1], 0, 0, SCRW, SCRH); + R_draw_intermission(); + break; + case GS_ENDSCR: + R_gl_draw_image_ext(&scrnh[2], 0, 0, SCRW, SCRH); + break; + case GS_GAME: + if (_2pl) { + R_draw_player_view(&pl1, 0, 0, SCRW, SCRH / 2); + R_draw_player_view(&pl2, 0, SCRH / 2, SCRW, SCRH / 2); + } else { + R_draw_player_view(&pl1, 0, 0, SCRW, SCRH); + } + R_gl_setclip(0, 0, SCRW, SCRH); + break; + } + GM_draw(); + SDL_GL_SwapBuffers(); +} + +void R_alloc (void) { + char s[10]; + int i, j, n; + logo("R_alloc: load graphics\n"); + /* Game */ + scrnh[0] = R_gl_loadimage("TITLEPIC"); + scrnh[1] = R_gl_loadimage("INTERPIC"); + scrnh[2] = R_gl_loadimage("ENDPIC"); + for (i = 0; i < 2; i++) { + sprintf(s, "LTN%c", '1' + i); + for (j = 0; j < 2; j++) { + ltn[i][j] = Z_getspr(s, j, 0, NULL); + } + } + /* Smoke */ + for (i = 0; i < SMSN; i++) { + smk_spr[i] = R_gl_get_special_spr("SMOK", i, 0, &R_extract_smoke_spr); + } + for (i = 0; i < FLSN; i++) { + smk_fspr[i] = R_gl_get_special_spr("SMOK", i, 0, &R_extract_flame_spr); + } + /* Effects */ + for (i = 0; i < 10; i++) { + fx_spr[i] = Z_getspr("TFOG", i, 0, fx_sprd + i); + } + for (; i < 15; i++) { + fx_spr[i] = Z_getspr("IFOG", i - 10, 0, fx_sprd + i); + } + /* Weapons */ + for (i = 0; i < 4; i++) { + wp_spr[i * 2] = Z_getspr("MISL", i, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("MISL", i, 2, wp_sprd + i * 2 + 1); + } + for (; i < 6; i++) { + wp_spr[i * 2] = Z_getspr("PLSS", i - 4, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("PLSS", i - 4, 2, wp_sprd + i * 2 + 1); + } + for (; i < 11; i++) { + wp_spr[i * 2] = Z_getspr("PLSE", i - 6, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("PLSE", i - 6, 2, wp_sprd + i * 2 + 1); + } + for (; i < 13; i++) { + wp_spr[i * 2] = Z_getspr("APLS", i - 11, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("APLS", i - 11, 2, wp_sprd + i * 2 + 1); + } + for (; i < 18; i++) { + wp_spr[i * 2] = Z_getspr("APBX", i - 13, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("APBX", i - 13, 2, wp_sprd + i * 2 + 1); + } + for(; i < 20; i++) { + wp_spr[i * 2] = Z_getspr("BFS1", i - 18, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BFS1", i - 18, 2, wp_sprd + i * 2 + 1); + } + for (; i < 26; i++) { + wp_spr[i * 2] = Z_getspr("BFE1", i - 20, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BFE1", i - 20, 2, wp_sprd + i * 2 + 1); + } + for (; i < 30; i++) { + wp_spr[i * 2] = Z_getspr("BFE2", i - 26, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BFE2", i - 26, 2, wp_sprd + i * 2 + 1); + } + for (; i < 32; i++) { + wp_spr[i * 2] = Z_getspr("MISL", i - 30 + 4, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("MISL", i - 30 + 4, 2, wp_sprd + i * 2 + 1); + } + for (; i < 37; i++) { + wp_spr[i * 2] = Z_getspr("BAL1", i - 32, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BAL1", i - 32, 2, wp_sprd + i * 2 + 1); + } + for (; i < 42; i++) { + wp_spr[i * 2] = Z_getspr("BAL7", i - 37, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BAL7", i - 37, 2, wp_sprd + i * 2 + 1); + } + for (; i < 47; i++) { + wp_spr[i * 2] = Z_getspr("BAL2", i - 42, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("BAL2", i - 42, 2, wp_sprd + i * 2 + 1); + } + for (; i < 49; i++) { + wp_spr[i * 2] = Z_getspr("MANF", i - 47, 1, wp_sprd + i * 2); + wp_spr[i * 2 + 1] = Z_getspr("MANF", i - 47, 2, wp_sprd + i * 2 + 1); + } + /* Items */ + static const char snm[18][4] = { + "CLIP", "SHEL", "ROCK", "CELL", "AMMO", "SBOX", "BROK", "CELP", + "STIM", "MEDI", "BPAK", + "CSAW", "SHOT", "SGN2", "MGUN", "LAUN", "PLAS", "BFUG" + }; + static const char n4[4][4] = { + "SOUL", "SMRT", "SMGT", "SMBT" + }; + static const char n3[2][4] = { + "GOR1", "FCAN" + }; + for (i = 0; i < 18; i++) { + item_spr[i] = Z_getspr(snm[i], 0, 0, item_sprd + i); + } + for (; i < 20; i++) { + item_spr[i] = Z_getspr("ARM1", i - 18, 0, item_sprd + i); + item_spr[i + 2] = Z_getspr("ARM2", i - 18, 0, item_sprd + i); + } + i+=2; + for (; i < 26; i++) { + item_spr[i] = Z_getspr("MEGA", i - 22, 0, item_sprd + i); + } + for (; i < 30; i++) { + item_spr[i] = Z_getspr("PINV", i - 26, 0, item_sprd + i); + } + item_spr[30] = Z_getspr("AQUA", 0, 0, item_sprd + 30); + item_spr[31] = Z_getspr("KEYR", 0, 0, item_sprd + 31); + item_spr[32] = Z_getspr("KEYG", 0, 0, item_sprd + 32); + item_spr[33] = Z_getspr("KEYB", 0, 0, item_sprd + 33); + item_spr[34] = Z_getspr("SUIT", 0, 0, item_sprd + 34); + for (n = 35, j = 0; j < 4; j++) { + for (i = 0; i < 4; i++, n++) { + item_spr[n] = Z_getspr(n4[j], i, 0, item_sprd + n); + } + } + for (j = 0; j < 2; j++) { + for (i = 0; i < 3; i++, n++) { + item_spr[n] = Z_getspr(n3[j], i, 0, item_sprd + n); + } + } + item_spr[57] = Z_getspr("GUN2", 0, 0, item_sprd + 57); + /* Player */ + for (i = 0; i < 27; i++) { + plr_spr[i * 2] = Z_getspr("PLAY", i, 1, plr_sprd + i * 2); + plr_msk[i * 2] = R_gl_get_special_spr("PLAY", i, 1, &R_extract_mask_spr); + plr_spr[i * 2 + 1] = Z_getspr("PLAY", i, 2, plr_sprd + i * 2 + 1); + plr_msk[i * 2 + 1] = R_gl_get_special_spr("PLAY", i, 2, &R_extract_mask_spr); + } + strncpy(s, "PWPx", 4); + for (i = 1; i < 11; i++) { + s[3] = (i < 10 ? '0' : 'A' - 10) + i; + for (j = 0; j < 6; j++) { + plr_wpn[i][j] = Z_getspr(s, j, 1, NULL); + } + } + /* Monsters */ + static const char msn[MN_TN][4] = { + "SARG", "TROO", "POSS", "SPOS", "CYBR", "CPOS", "BOSS", "BOS2", "HEAD", "SKUL", + "PAIN", "SPID", "BSPI", "FATT", "SKEL", "VILE", "FISH", "BAR1", "ROBO", "PLAY" + }; + static const int mms[MN_TN] = { + 14*2, 21*2, 21*2, 21*2, 16*2, 20*2, 15*2, 15*2, 12*2, 11*2, + 13*2, 19*2, 16*2, 20*2, 17*2, 29*2, 6*2, 2*2, 17*2, 23*2 + }; + mn_sgun[0] = Z_getspr("PWP4", 0, 1, NULL); + mn_sgun[1] = Z_getspr("PWP4", 1, 1, NULL); + for (j = 0; j < MN_TN; j++) { + for (i = 0; i < mms[j]; i++) { + mn_spr[j][i] = Z_getspr(msn[j], i / 2, (i & 1) + 1, &mn_sprd[j][i]); + if (j == MN_MAN - 1) { + mn_man_msk[i] = R_gl_get_special_spr(msn[j], i / 2, (i & 1) + 1, &R_extract_mask_spr); + } + } + if (j == MN_BARREL - 1) { + for (i = 4; i < 14; i++) { + mn_spr[j][i] = Z_getspr("BEXP", i / 2 - 2, (i & 1) + 1, &mn_sprd[j][i]); + } + } + } + for (i = 0; i < 8; i++) { + mn_fspr[i] = Z_getspr("FIRE", i, 0, NULL); + } + pl_spr[0] = Z_getspr("PLAY", 'N' - 'A', 0, NULL); + pl_msk[0] = R_gl_get_special_spr("PLAY", 'N' - 'A', 0, &R_extract_mask_spr); + pl_spr[1] = Z_getspr("PLAY", 'W' - 'A', 0, NULL); + pl_msk[1] = R_gl_get_special_spr("PLAY", 'W' - 'A', 0, &R_extract_mask_spr); + /* Misc */ + static const char mnm[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 = R_gl_loadimage("STONE"); + stone2 = R_gl_loadimage("STONE2"); + keys[0] = R_gl_loadimage("KEYRA0"); + keys[1] = R_gl_loadimage("KEYGA0"); + keys[2] = R_gl_loadimage("KEYBA0"); + for (i = 0; i < 22; i++) { + sth[i] = R_gl_loadimage(mnm[i]); + } + strcpy(s, "STBF_*"); + for (i = '!'; i < 160; i++) { + s[5] = i; + bfh[i - '!'] = R_gl_getimage(F_findres(s)); + } + for (i = '!'; i < 160; i++) { + sprintf(s, "STCFN%03d", i); + sfh[i - '!'] = R_gl_getimage(F_findres(s)); + } + strcpy(s, "WINUM*"); + for (i = '0'; i <= '9'; i++) { + s[5] = i; + bfh[i - '!'] = R_gl_loadimage(s); + } + bfh[':' - '!'] = R_gl_loadimage("WICOLON"); + // menu + msklh[0] = R_gl_loadimage("M_SKULL1"); + msklh[1] = R_gl_loadimage("M_SKULL2"); + mbarl = R_gl_loadimage("M_THERML"); + mbarm = R_gl_loadimage("M_THERMM"); + mbarr = R_gl_loadimage("M_THERMR"); + mbaro = R_gl_loadimage("M_THERMO"); + mslotl = R_gl_loadimage("M_LSLEFT"); + mslotm = R_gl_loadimage("M_LSCNTR"); + mslotr = R_gl_loadimage("M_LSRGHT"); + // walls + for (i = 1; i < ANIT; i++) { + for (j = 0; anm[i - 1][j]; j++) { + anip[i][j] = R_gl_loadimage(anm[i - 1][j]); + } + for(; j < 5; j++) { + anip[i][j] = (image) { + .w = 8, + .h = 8, + .res = -1, + }; + } + } +} + +void R_init (void) { + Uint32 flags = SDL_OPENGL; + if (fullscreen) { + flags = flags | SDL_FULLSCREEN; + } + if (SCRW <= 0 || SCRH <= 0) { + ERR_failinit("Invalid screen size %ix%i\n", SCRW, SCRH); + } + if (surf == NULL) { + R_init_playpal(); // only onece + } + surf = SDL_SetVideoMode(SCRW, SCRH, 0, flags); + if (surf == NULL) { + ERR_failinit("Unable to set video mode: %s\n", SDL_GetError()); + } + R_alloc(); +} + +void R_done (void) { + // do nothing +} + +void R_setgamma (int g) { + gamma = g < 0 ? 0 : (g > 4 ? 4 : g); +} + +int R_getgamma (void) { + return gamma; +} + +void R_toggle_fullscreen (void) { + fullscreen = !fullscreen; + if (surf) { + R_init(); // recreate window + } +} + +void R_get_name (int n, char s[8]) { + assert(n >= 0 && n < 256); + if (walp[n].res == -1) { + memset(s, 0, 8); + } else if (walp[n].res == -2) { + memcpy(s, "_WATER_", 8); + s[7] = '0' + walp[n].id - 1; + } else if (walani[n] > 0) { + memcpy(s, anm[walani[n] - 1][0], 8); + } else { + F_getresname(s, walp[n].res & 0x7FFF); + } +} + +static short getani (char n[8]) { + short i = 0; + while (i < ANIT && strncasecmp(n, anm[i][0], 8) != 0) { + i++; + } + return i < ANIT ? i + 1 : 0; +} + +int R_get_special_id (int n) { + assert(n >= 0 && n <= 256); + return walp[n].res == -2 ? walp[n].id : -1; +} + +void R_begin_load (void) { + int i; + for (i = 0; i < 256; i++) { + if (walp[i].id != 0 && walp[i].res >= 0 && walani[i] == 0) { + R_gl_free_image(&walp[i]); + } + memset(&walp[i], 0, sizeof(image)); + walp[i].res = -1; + walswp[i] = i; + walani[i] = 0; + } + memset(anic, 0, sizeof(anic)); + max_wall_width = 0; + max_wall_height = 0; + max_textures = 1; +} + +void R_load (char s[8], int f) { + assert(max_textures < 256); + if (!s[0]) { + walp[max_textures] = (image) { + .id = 0, + .x = 0, + .y = 0, + .w = 0, + .h = 0, + .res = -1, + }; + } else if (strncasecmp(s, "_WATER_", 7) == 0) { + walp[max_textures] = (image) { + .id = s[7] - '0' + 1, + .x = 0, + .y = 0, + .w = 8, + .h = 8, + .res = -2, + }; + } else { + walp[max_textures] = R_gl_loadimage(s); + if (f) { + walp[max_textures].res |= 0x8000; + } + if (s[0] == 'S' && s[1] == 'W' && s[4] == '_') { + walswp[max_textures] = 0; + } + walani[max_textures] = getani(s); + } + max_wall_width = max(max_wall_width, walp[max_textures].w); + max_wall_height = max(max_wall_height, walp[max_textures].h); + max_textures++; +} + +void R_end_load (void) { + int i, j, k, g; + char s[8]; + j = max_textures; + for (i = 1; i < 256 && j < 256; i++) { + if (walswp[i] == 0) { + R_get_name(i, s); + s[5] ^= 1; + g = F_getresid(s) | (walp[i].res & 0x8000); + k = 1; + while (k < 256 && walp[k].res != g) { + k += 1; + } + if (k >= 256) { + k = j; + j += 1; + walp[k] = R_gl_getimage(g); + walf[k] = g & 0x8000 ? 1 : 0; + } + walswp[i] = k; + walswp[k] = i; + } + } +} + +void R_loadsky (int sky) { + char s[6]; + logo("R_loadsky(%i)\n", sky); + strcpy(s, "RSKYx"); + s[4] = '0' + sky; + R_gl_free_image(&horiz); + horiz = R_gl_loadimage(s); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 4b6a958..edf7156 100644 --- a/src/main.c +++ b/src/main.c @@ -93,22 +93,16 @@ int main(int argc, char *argv[]) { F_loadmus("MENU"); S_startmusic(0); - Uint32 ticks = 0; - for(;;) { - + Uint32 ticks = SDL_GetTicks(); + for (;;) { updatee_keys(); - S_updatemusic(); - - G_act(); - - R_draw(); - - Uint32 t; - while ((t = SDL_GetTicks())-ticks < DELAY) { - SDL_Delay(1); + Uint32 t = SDL_GetTicks(); + if (t - ticks > DELAY) { + ticks = t; + G_act(); } - ticks = t - t % DELAY; - + R_draw(); + //SDL_Delay(1); } } diff --git a/src/render.c b/src/soft/render.c similarity index 98% rename from src/render.c rename to src/soft/render.c index b0f2485..2036b08 100644 --- a/src/render.c +++ b/src/soft/render.c @@ -99,7 +99,7 @@ static void Z_putbfch (int c) { } } -static void Z_putsfch(int c) { +static void Z_putsfch (int c) { vgaimg *p; if (c > 32 && c < 160) { p = sfh[c - '!']; @@ -119,7 +119,7 @@ static void Z_gotoxy (int x, int y) { pry = y; } -static void Z_printbf(char *s, ...) { +static void Z_printbf (char *s, ...) { int i; va_list ap; char buf[80]; @@ -347,8 +347,8 @@ static int GM_draw (void) { 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); + 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 { @@ -359,7 +359,7 @@ static int GM_draw (void) { Z_printbf(mnu->m[i]); } if (mnu->t[i] == MUSIC) { - Z_printbf(" '%.8s'",g_music); + Z_printbf(" '%.8s'", g_music); } else if(mnu->t[i] == INTERP) { Z_printbf("%s", fullscreen ? "ON" : "OFF"); } else if(mnu->t[i] >= PL1CM) { @@ -391,7 +391,7 @@ static int GM_draw (void) { static void DOT_draw (void) { int i; - for (i = 0; i < MAXDOT; ++i) { + for (i = 0; i < MAXDOT; i++) { if (dot[i].t) { V_dot(dot[i].o.x - w_x + WD / 2, dot[i].o.y - w_y + HT / 2 + 1 + w_o, dot[i].c); } @@ -594,7 +594,7 @@ static void PL_drawst (player_t *p) { static void MN_draw (void) { enum {SLEEP, GO, RUN, CLIMB, DIE, DEAD, ATTACK, SHOOT, PAIN, WAIT, REVIVE, RUNOUT}; // copypasted from monster.c! int i; - for (i = 0; i < MAXMN; ++i) { + for (i = 0; i < MAXMN; i++) { if (mn[i].t) { if (mn[i].t >= 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); @@ -685,7 +685,8 @@ static void WP_draw (void) { break; case MANF: s += 47; - d=(wp[i].o.xv>=0)?1:0;break; + d= wp[i].o.xv>=0 ? 1 : 0; + break; } break; case BFGBALL: @@ -857,7 +858,7 @@ static void pl_info (player_t *p, int y) { static void W_act (void) { int i, a; if (g_time % 3 == 0) { - for (i = 1; i < 256; ++i) { + for (i = 1; i < 256; i++) { a = walani[i]; if (a != 0) { anic[a]++; diff --git a/src/vga.c b/src/soft/vga.c similarity index 100% rename from src/vga.c rename to src/soft/vga.c diff --git a/src/vga.h b/src/soft/vga.h similarity index 100% rename from src/vga.h rename to src/soft/vga.h -- 2.29.2 From c5be09436899f403e3f39c051399b160c8d2f019 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 18:45:03 +0300 Subject: [PATCH 05/16] opengl: implement texture cache --- src/gl/render.c | 218 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 186 insertions(+), 32 deletions(-) diff --git a/src/gl/render.c b/src/gl/render.c index 01e4014..e9dc5b5 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -50,8 +50,21 @@ typedef struct rgba { } rgba; #pragma pack() -typedef struct image { +typedef struct node { + struct cache *base; + struct node *left, *right; + int l, t, r, b; + int leaf; +} node; + +typedef struct cache { + struct cache *next; + struct node root; GLuint id; +} cache; + +typedef struct image { + node *n; GLint x, y; GLuint w, h; int res; @@ -65,6 +78,7 @@ static int fullscreen; static SDL_Surface *surf; static rgb playpal[256]; static byte bright[256]; +static cache *root; /* Game */ static image scrnh[3]; // TITLEPIC INTERPIC ENDPIC @@ -138,6 +152,135 @@ static image anip[ANIT][5]; static byte anic[ANIT]; static image horiz; +/* Texture cache */ + +// https://blackpawn.com/texts/lightmaps/ +static node *R_node_alloc (node *p, int w, int h) { + assert(p); + assert(w > 0); + assert(h > 0); + if (p->left) { + assert(p->right); + node *n = R_node_alloc(p->left, w, h); + return n ? n : R_node_alloc(p->right, w, h); + } else { + int pw = p->r - p->l + 1; + int ph = p->b - p->t + 1; + if (p->leaf || pw < w || ph < h) { + return NULL; + } else if (pw == w && ph == h) { + p->leaf = 1; + return p; + } else { + p->left = malloc(sizeof(node)); + p->right = malloc(sizeof(node)); + if (pw - w > ph - h) { + *p->left = (node) { + .l = p->l, + .t = p->t, + .r = p->l + w - 1, + .b = p->b + }; + *p->right = (node) { + .l = p->l + w, + .t = p->t, + .r = p->r, + .b = p->b + }; + } else { + *p->left = (node) { + .l = p->l, + .t = p->t, + .r = p->r, + .b = p->t + h - 1 + }; + *p->right = (node) { + .l = p->l, + .t = p->t + h, + .r = p->r, + .b = p->b + }; + } + return R_node_alloc(p->left, w, h); + } + } +} + +static cache *R_cache_new (void) { + GLuint id = 0; + GLint size = 0; + cache *c = NULL; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + size /= 2; // TODO remove hack or detect ibook bug + if (size) { + glGenTextures(1, &id); + if (id) { + glBindTexture(GL_TEXTURE_2D, id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + int ok = glGetError() == GL_NO_ERROR; + glBindTexture(GL_TEXTURE_2D, 0); + if (ok) { + c = malloc(sizeof(cache)); + if (c != NULL) { + *c = (cache) { + .id = id, + .root.r = size - 1, + .root.b = size - 1 + }; + } + } + if (c == NULL) { + glDeleteTextures(1, &id); + } + } + } + logo("new cache %p\n", c); + return c; +} + +static node *R_cache_alloc (cache *root, int w, int h) { + assert(root); + assert(w > 0 && h > 0); + node *n = NULL; + cache *p = NULL; + cache *c = root; + while (c && !n) { + n = R_node_alloc(&c->root, w, h); + if (n) { + n->base = c; + } + p = c; + c = c->next; + } + if (!n) { + c = R_cache_new(); + if (c) { + p->next = c; + n = R_node_alloc(&c->root, w, h); + if (n) { + n->base = c; + } + } + } + return n; +} + +static void R_cache_update (node *n, const void *data, int w, int h) { + assert(n); + assert(n->base); + assert(data); + int nw = n->r - n->l + 1; + int nh = n->b - n->t + 1; + assert(w == nw); + assert(h == nh); + glBindTexture(GL_TEXTURE_2D, n->base->id); + glTexSubImage2D(GL_TEXTURE_2D, 0, n->l, n->t, nw, nh, GL_RGBA, GL_UNSIGNED_BYTE, data); + assert(glGetError() == GL_NO_ERROR); + glBindTexture(GL_TEXTURE_2D, 0); +} + /* Generic helpers */ static void R_init_playpal (void) { @@ -265,19 +408,15 @@ static rgba *R_extract_rgba_spr (vgaimg *v) { /* OpenGL helpers */ static image R_gl_create_image (const rgba *buf, int w, int h) { - GLuint tex = 0; - glGenTextures(1, &tex); - if (tex != 0) { - glBindTexture(GL_TEXTURE_2D, tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf); - glBindTexture(GL_TEXTURE_2D, 0); + node *n = R_cache_alloc(root, w, h); + if (n) { + R_cache_update(n, buf, w, h); } return (image) { - .id = tex, + .n = n, .w = w, .h = h, + .res = -1 }; } @@ -309,10 +448,10 @@ static image R_gl_get_special_spr (const char n[4], int s, int d, rgba *(*fn)(vg } static void R_gl_free_image (image *img) { - if (img->id != 0 && img->res >= 0) { - glDeleteTextures(1, &img->id); + if (img->n != NULL && img->res >= 0) { + // TODO delete node } - img->id = 0; + img->n = NULL; } static void R_gl_draw_quad (int x, int y, int w, int h) { @@ -325,18 +464,29 @@ static void R_gl_draw_quad (int x, int y, int w, int h) { } static void R_gl_draw_textured (image *img, int x, int y, int w, int h, int flip) { - int ax = flip == 0; - int bx = !ax; - glBindTexture(GL_TEXTURE_2D, img->id); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glTexCoord2f(ax, 0); glVertex2i(x + w, y); - glTexCoord2f(bx, 0); glVertex2i(x, y); - glTexCoord2f(bx, 1); glVertex2i(x, y + h); - glTexCoord2f(ax, 1); glVertex2i(x + w, y + h); - glEnd(); - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); + if (img->n) { + GLfloat nw = img->n->base->root.r + 1; + GLfloat nh = img->n->base->root.b + 1; + GLfloat ax = (flip ? img->n->l : img->n->r + 1) / nw; + GLfloat bx = (flip ? img->n->r + 1 : img->n->l) / nh; + GLfloat ay = (img->n->t) / nw; + GLfloat by = (img->n->b + 1) / nh; + glBindTexture(GL_TEXTURE_2D, img->n->base->id); + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glTexCoord2f(ax, ay); glVertex2i(x + w, y); + glTexCoord2f(bx, ay); glVertex2i(x, y); + glTexCoord2f(bx, by); glVertex2i(x, y + h); + glTexCoord2f(ax, by); glVertex2i(x + w, y + h); + glEnd(); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } else { + glColor3ub(255, 0, 0); + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + R_gl_draw_quad(x, y, w, h); + } } /* fit image into rectangle without applying offset and transparency */ @@ -599,7 +749,7 @@ static void R_draw_fld (byte *fld, int minx, int miny, int maxx, int maxy, int f if (id != 0) { if (walp[id].res < 0) { if (fg) { - switch (walp[id].id) { + switch (R_get_special_id(id)) { case 1: glColor4ub(0, 0, 255, 127); break; @@ -955,7 +1105,7 @@ static void R_draw_view (int x, int y, int w, int h, int camx, int camy) { glPushMatrix(); R_gl_setclip(x, y, w, h); glTranslatef(x, y, 0); - if (w_horiz && horiz.id != 0) { + if (w_horiz && horiz.n != NULL) { R_gl_draw_image_ext(&horiz, 0, 0, w, h); if (sky_type == 2 && lt_time < 0) { image *tanderbolt = <n[lt_type][lt_time < -5 ? 0 : 1]; @@ -1203,6 +1353,7 @@ void R_alloc (void) { logo("R_alloc: load graphics\n"); /* Game */ scrnh[0] = R_gl_loadimage("TITLEPIC"); + assert(scrnh[0].n); scrnh[1] = R_gl_loadimage("INTERPIC"); scrnh[2] = R_gl_loadimage("ENDPIC"); for (i = 0; i < 2; i++) { @@ -1413,6 +1564,7 @@ void R_alloc (void) { } for(; j < 5; j++) { anip[i][j] = (image) { + .n = NULL, .w = 8, .h = 8, .res = -1, @@ -1436,6 +1588,8 @@ void R_init (void) { if (surf == NULL) { ERR_failinit("Unable to set video mode: %s\n", SDL_GetError()); } + root = R_cache_new(); + assert(root); R_alloc(); } @@ -1464,7 +1618,7 @@ void R_get_name (int n, char s[8]) { memset(s, 0, 8); } else if (walp[n].res == -2) { memcpy(s, "_WATER_", 8); - s[7] = '0' + walp[n].id - 1; + s[7] = '0' + (intptr_t)walp[n].n - 1; } else if (walani[n] > 0) { memcpy(s, anm[walani[n] - 1][0], 8); } else { @@ -1482,13 +1636,13 @@ static short getani (char n[8]) { int R_get_special_id (int n) { assert(n >= 0 && n <= 256); - return walp[n].res == -2 ? walp[n].id : -1; + return walp[n].res == -2 ? (intptr_t)walp[n].n : -1; } void R_begin_load (void) { int i; for (i = 0; i < 256; i++) { - if (walp[i].id != 0 && walp[i].res >= 0 && walani[i] == 0) { + if (walp[i].n != NULL && walp[i].res >= 0 && walani[i] == 0) { R_gl_free_image(&walp[i]); } memset(&walp[i], 0, sizeof(image)); @@ -1506,7 +1660,7 @@ void R_load (char s[8], int f) { assert(max_textures < 256); if (!s[0]) { walp[max_textures] = (image) { - .id = 0, + .n = NULL, .x = 0, .y = 0, .w = 0, @@ -1515,7 +1669,7 @@ void R_load (char s[8], int f) { }; } else if (strncasecmp(s, "_WATER_", 7) == 0) { walp[max_textures] = (image) { - .id = s[7] - '0' + 1, + .n = (void*)(s[7] - '0' + 1), .x = 0, .y = 0, .w = 8, -- 2.29.2 From 9fc47db9cfdb6b22e390e5cd0a57498336a70cc6 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 20:27:59 +0300 Subject: [PATCH 06/16] opengl: fix building on non osx --- src/gl/render.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gl/render.c b/src/gl/render.c index e9dc5b5..c1260da 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -21,7 +21,11 @@ #include "view.h" #include "switch.h" // sw_secrets -#include +#ifdef __APPLE__ +# include +#else +# include +#endif #include // malloc free abs #include // assert #include @@ -1723,4 +1727,4 @@ void R_loadsky (int sky) { s[4] = '0' + sky; R_gl_free_image(&horiz); horiz = R_gl_loadimage(s); -} \ No newline at end of file +} -- 2.29.2 From 4026d71c7c19a786b09ac0f41ea51bd3e1d1a784 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 20:49:22 +0300 Subject: [PATCH 07/16] opengl: fix segfault --- src/gl/render.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl/render.c b/src/gl/render.c index c1260da..e74d6bb 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -1632,10 +1632,10 @@ void R_get_name (int n, char s[8]) { static short getani (char n[8]) { short i = 0; - while (i < ANIT && strncasecmp(n, anm[i][0], 8) != 0) { + while (i < ANIT - 1 && strncasecmp(n, anm[i][0], 8) != 0) { i++; } - return i < ANIT ? i + 1 : 0; + return i < ANIT - 1 ? i + 1 : 0; } int R_get_special_id (int n) { @@ -1673,7 +1673,7 @@ void R_load (char s[8], int f) { }; } else if (strncasecmp(s, "_WATER_", 7) == 0) { walp[max_textures] = (image) { - .n = (void*)(s[7] - '0' + 1), + .n = (void*)((intptr_t)s[7] - '0' + 1), .x = 0, .y = 0, .w = 8, -- 2.29.2 From f333581fff4a1ef2f4d4af740f6a175c8c6dec91 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 21:08:25 +0300 Subject: [PATCH 08/16] opengl: limit cache texture to 512x512 --- src/gl/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/render.c b/src/gl/render.c index e74d6bb..6b62793 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -215,7 +215,7 @@ static cache *R_cache_new (void) { GLint size = 0; cache *c = NULL; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); - size /= 2; // TODO remove hack or detect ibook bug + size = size < 512 ? size : 512; // more can be buggy on older hardware if (size) { glGenTextures(1, &id); if (id) { -- 2.29.2 From 36d2a7e26206ad8112c6a5c3f2117d237c9a0ab7 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Thu, 19 Mar 2020 22:11:46 +0300 Subject: [PATCH 09/16] opengl: rebind texture only when needed --- src/gl/render.c | 77 +++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/src/gl/render.c b/src/gl/render.c index 6b62793..e93bb12 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -82,6 +82,7 @@ static int fullscreen; static SDL_Surface *surf; static rgb playpal[256]; static byte bright[256]; +static GLuint lastTexture; static cache *root; /* Game */ @@ -210,6 +211,12 @@ static node *R_node_alloc (node *p, int w, int h) { } } +static void R_gl_bind_texture (GLuint id) { + if (id != lastTexture) { + glBindTexture(GL_TEXTURE_2D, id); + } +} + static cache *R_cache_new (void) { GLuint id = 0; GLint size = 0; @@ -219,28 +226,23 @@ static cache *R_cache_new (void) { if (size) { glGenTextures(1, &id); if (id) { - glBindTexture(GL_TEXTURE_2D, id); + R_gl_bind_texture(id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - int ok = glGetError() == GL_NO_ERROR; - glBindTexture(GL_TEXTURE_2D, 0); - if (ok) { - c = malloc(sizeof(cache)); - if (c != NULL) { - *c = (cache) { - .id = id, - .root.r = size - 1, - .root.b = size - 1 - }; - } - } - if (c == NULL) { + c = malloc(sizeof(cache)); + if (c != NULL) { + *c = (cache) { + .id = id, + .root.r = size - 1, + .root.b = size - 1 + }; + } else { glDeleteTextures(1, &id); } } } - logo("new cache %p\n", c); + //logo("new cache %p\n", c); return c; } @@ -279,10 +281,8 @@ static void R_cache_update (node *n, const void *data, int w, int h) { int nh = n->b - n->t + 1; assert(w == nw); assert(h == nh); - glBindTexture(GL_TEXTURE_2D, n->base->id); + R_gl_bind_texture(n->base->id); glTexSubImage2D(GL_TEXTURE_2D, 0, n->l, n->t, nw, nh, GL_RGBA, GL_UNSIGNED_BYTE, data); - assert(glGetError() == GL_NO_ERROR); - glBindTexture(GL_TEXTURE_2D, 0); } /* Generic helpers */ @@ -425,7 +425,7 @@ static image R_gl_create_image (const rgba *buf, int w, int h) { } static image R_gl_get_special_image (int id, rgba *(*fn)(vgaimg*)) { - image img = (image) { .res = -1 }; + image img; vgaimg *v = R_getvga(id); if (v != NULL) { rgba *buf = (*fn)(v); @@ -435,6 +435,10 @@ static image R_gl_get_special_image (int id, rgba *(*fn)(vgaimg*)) { img.res = id; M_unlock(v); free(buf); + } else { + img = (image) { + .res = id + }; } return img; } @@ -475,7 +479,7 @@ static void R_gl_draw_textured (image *img, int x, int y, int w, int h, int flip GLfloat bx = (flip ? img->n->r + 1 : img->n->l) / nh; GLfloat ay = (img->n->t) / nw; GLfloat by = (img->n->b + 1) / nh; - glBindTexture(GL_TEXTURE_2D, img->n->base->id); + R_gl_bind_texture(img->n->base->id); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(ax, ay); glVertex2i(x + w, y); @@ -483,12 +487,11 @@ static void R_gl_draw_textured (image *img, int x, int y, int w, int h, int flip glTexCoord2f(bx, by); glVertex2i(x, y + h); glTexCoord2f(ax, by); glVertex2i(x + w, y + h); glEnd(); - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); } else { glColor3ub(255, 0, 0); glDisable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); R_gl_draw_quad(x, y, w, h); } } @@ -507,16 +510,12 @@ static void R_gl_draw_image_color (image *img, int x, int y, int flip) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); R_gl_draw_textured(img, xx, y - img->y, img->w, img->h, flip); - glDisable(GL_BLEND); } /* draw sprite with offset */ static void R_gl_draw_image (image *img, int x, int y, int flip) { - int xx = flip ? x - img->w + img->x : x - img->x; - glEnable(GL_BLEND); glColor3ub(255, 255, 255); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - R_gl_draw_textured(img, xx, y - img->y, img->w, img->h, flip); + R_gl_draw_image_color(img, x, y, flip); } static void R_gl_set_color (byte c) { @@ -769,6 +768,7 @@ static void R_draw_fld (byte *fld, int minx, int miny, int maxx, int maxy, int f } glEnable(GL_BLEND); glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + glDisable(GL_TEXTURE_2D); R_gl_draw_quad(i * CELW, j * CELW, CELW, CELH); } } else { @@ -781,6 +781,9 @@ static void R_draw_fld (byte *fld, int minx, int miny, int maxx, int maxy, int f static void R_draw_dots (void) { int i; + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); glBegin(GL_POINTS); for (i = 0; i < MAXDOT; i++) { if (dot[i].t != 0) { @@ -1086,6 +1089,9 @@ static void R_draw_effects (void) { R_gl_draw_image(&fx_spr[s], fx[i].x, fx[i].y, fx_sprd[s]); break; case BUBL: + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); glBegin(GL_POINTS); R_gl_set_color(0xC0 + fx[i].s); glVertex2i(fx[i].x >> 8, (fx[i].y >> 8) + 1); @@ -1121,6 +1127,8 @@ static void R_draw_view (int x, int y, int w, int h, int camx, int camy) { } } else { glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); R_gl_set_color(DEFAULT_SKY_COLOR); R_gl_draw_quad(0, 0, w, h); } @@ -1146,6 +1154,7 @@ static void R_draw_view (int x, int y, int w, int h, int camx, int camy) { glColor4ub(255, 255, 255, 255); glEnable(GL_BLEND); glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + glDisable(GL_TEXTURE_2D); R_gl_draw_quad(0, 0, w, h); } glPopMatrix(); @@ -1165,22 +1174,25 @@ static void R_draw_player_view (player_t *p, int x, int y, int w, int h) { if (p->invl) { if (get_pu_st(p->invl)) { glEnable(GL_BLEND); - glColor4ub(191, 191, 191, 255); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); + glDisable(GL_TEXTURE_2D); + glColor4ub(191, 191, 191, 255); R_gl_draw_quad(0, 0, cw, h); } } else { if (p->suit && get_pu_st(p->suit)) { glEnable(GL_BLEND); - glColor4ub(0, 255, 0, 192); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glColor4ub(0, 255, 0, 192); R_gl_draw_quad(0, 0, cw, h); } int f = min(max(p->pain * 3, 0), 255); if (f > 0) { glEnable(GL_BLEND); - glColor4ub(255, 0, 0, f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); + glColor4ub(255, 0, 0, f); R_gl_draw_quad(0, 0, cw, h); } } @@ -1196,6 +1208,8 @@ static void R_draw_player_view (player_t *p, int x, int y, int w, int h) { if (p->air < PL_AIR) { int a = min(max(p->air, 0), MAXAIR) * 100 / MAXAIR; glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_TEXTURE_2D); R_gl_set_color(0xC8); R_gl_draw_quad(10, 49, a, 2); } @@ -1316,7 +1330,7 @@ static void W_act (void) { void R_draw (void) { W_act(); glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); R_gl_setmatrix(); switch (g_st) { @@ -1722,7 +1736,6 @@ void R_end_load (void) { void R_loadsky (int sky) { char s[6]; - logo("R_loadsky(%i)\n", sky); strcpy(s, "RSKYx"); s[4] = '0' + sky; R_gl_free_image(&horiz); -- 2.29.2 From b7c39e0d9229a7616c63cf545cdd9576b9bf3e2c Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Fri, 20 Mar 2020 10:49:00 +0300 Subject: [PATCH 10/16] opengl: implement texture deallocator --- src/CMakeLists.txt | 2 +- src/gl/render.c | 72 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bee976e..b01523e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,7 +22,7 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif (NOT CMAKE_BUILD_TYPE) set(CMAKE_C_FLAGS "") -set(CMAKE_C_FLAGS_DEBUG "-g -O2 -Wall") +set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall") set(CMAKE_C_FLAGS_RELEASE "-O3") # -DNDEBUG set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") diff --git a/src/gl/render.c b/src/gl/render.c index e93bb12..b5da71f 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -57,6 +57,7 @@ typedef struct rgba { typedef struct node { struct cache *base; struct node *left, *right; + struct node *up; int l, t, r, b; int leaf; } node; @@ -181,12 +182,14 @@ static node *R_node_alloc (node *p, int w, int h) { p->right = malloc(sizeof(node)); if (pw - w > ph - h) { *p->left = (node) { + .up = p, .l = p->l, .t = p->t, .r = p->l + w - 1, .b = p->b }; *p->right = (node) { + .up = p, .l = p->l + w, .t = p->t, .r = p->r, @@ -194,12 +197,14 @@ static node *R_node_alloc (node *p, int w, int h) { }; } else { *p->left = (node) { + .up = p, .l = p->l, .t = p->t, .r = p->r, .b = p->t + h - 1 }; *p->right = (node) { + .up = p, .l = p->l, .t = p->t + h, .r = p->r, @@ -211,6 +216,44 @@ static node *R_node_alloc (node *p, int w, int h) { } } +static int R_node_have_leaf (node *n) { + return n && (n->leaf || R_node_have_leaf(n->left) || R_node_have_leaf(n->right)); +} + +static void R_node_free_recursive (node *n) { + if (n) { + R_node_free_recursive(n->left); + R_node_free_recursive(n->right); + free(n); + } +} + +static void R_node_free (node *n) { + if (n) { + //logo("free node %p {%i:%i:%i:%i}\n", n, n->l, n->t, n->r, n->b); + assert(n->leaf); + assert(n->left == NULL); + assert(n->right == NULL); + n->leaf = 0; + n->base = NULL; + node *p = n->up; + while (p != NULL) { + assert(p->leaf == 0); + assert(p->left); + assert(p->right); + if (R_node_have_leaf(p) == 0) { + R_node_free_recursive(p->left); + p->left = NULL; + R_node_free_recursive(p->right); + p->right = NULL; + p = p->up; + } else { + p = NULL; + } + } + } +} + static void R_gl_bind_texture (GLuint id) { if (id != lastTexture) { glBindTexture(GL_TEXTURE_2D, id); @@ -246,15 +289,32 @@ static cache *R_cache_new (void) { return c; } +static void R_cache_free (cache *root, int freetexture) { + cache *next; + cache *c = root; + while (c != NULL) { + next = c->next; + R_node_free_recursive(c->root.left); + R_node_free_recursive(c->root.right); + if (freetexture && c->id != 0) { + glDeleteTextures(1, &c->id); + } + free(c); + c = next; + } +} + static node *R_cache_alloc (cache *root, int w, int h) { assert(root); assert(w > 0 && h > 0); node *n = NULL; cache *p = NULL; cache *c = root; + // TODO return null if required size greater than maximum while (c && !n) { n = R_node_alloc(&c->root, w, h); if (n) { + assert(n->leaf); n->base = c; } p = c; @@ -266,15 +326,22 @@ static node *R_cache_alloc (cache *root, int w, int h) { p->next = c; n = R_node_alloc(&c->root, w, h); if (n) { + assert(n->leaf); n->base = c; } } } + if (n) { + //logo("new node %p {%i:%i:%i:%i}\n", n, n->l, n->t, n->r, n->b); + } else { + logo("new node failed\n"); + } return n; } static void R_cache_update (node *n, const void *data, int w, int h) { assert(n); + assert(n->leaf); assert(n->base); assert(data); int nw = n->r - n->l + 1; @@ -457,9 +524,10 @@ static image R_gl_get_special_spr (const char n[4], int s, int d, rgba *(*fn)(vg static void R_gl_free_image (image *img) { if (img->n != NULL && img->res >= 0) { - // TODO delete node + R_node_free(img->n); } img->n = NULL; + img->res = -1; } static void R_gl_draw_quad (int x, int y, int w, int h) { @@ -1612,7 +1680,7 @@ void R_init (void) { } void R_done (void) { - // do nothing + R_cache_free(root, 1); } void R_setgamma (int g) { -- 2.29.2 From 4402c26ec7a3554069c214a648de5130cce3493b Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Fri, 20 Mar 2020 11:30:51 +0300 Subject: [PATCH 11/16] opengl: do not even try to allocate texture with size more than supported by texture cache --- src/gl/render.c | 68 ++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/src/gl/render.c b/src/gl/render.c index b5da71f..91707ef 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -254,6 +254,14 @@ static void R_node_free (node *n) { } } +static void R_cache_get_max_texture_size (int *w, int *h) { + GLint size = 0; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + size = min(max(size, 0), 512); // more can be buggy on older hardware + *w = size; + *h = size; +} + static void R_gl_bind_texture (GLuint id) { if (id != lastTexture) { glBindTexture(GL_TEXTURE_2D, id); @@ -261,24 +269,23 @@ static void R_gl_bind_texture (GLuint id) { } static cache *R_cache_new (void) { - GLuint id = 0; - GLint size = 0; + int w, h; + GLuint id; cache *c = NULL; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); - size = size < 512 ? size : 512; // more can be buggy on older hardware - if (size) { + R_cache_get_max_texture_size(&w, &h); + if (w && h) { glGenTextures(1, &id); if (id) { R_gl_bind_texture(id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); c = malloc(sizeof(cache)); if (c != NULL) { *c = (cache) { .id = id, - .root.r = size - 1, - .root.b = size - 1 + .root.r = w - 1, + .root.b = h - 1 }; } else { glDeleteTextures(1, &id); @@ -310,25 +317,28 @@ static node *R_cache_alloc (cache *root, int w, int h) { node *n = NULL; cache *p = NULL; cache *c = root; - // TODO return null if required size greater than maximum - while (c && !n) { - n = R_node_alloc(&c->root, w, h); - if (n) { - assert(n->leaf); - n->base = c; - } - p = c; - c = c->next; - } - if (!n) { - c = R_cache_new(); - if (c) { - p->next = c; + int maxw, maxh; + R_cache_get_max_texture_size(&maxw, &maxh); + if (w <= maxw && h <= maxh) { + while (c && !n) { n = R_node_alloc(&c->root, w, h); if (n) { assert(n->leaf); n->base = c; } + p = c; + c = c->next; + } + if (!n) { + c = R_cache_new(); + if (c) { + p->next = c; + n = R_node_alloc(&c->root, w, h); + if (n) { + assert(n->leaf); + n->base = c; + } + } } } if (n) { @@ -339,17 +349,17 @@ static node *R_cache_alloc (cache *root, int w, int h) { return n; } -static void R_cache_update (node *n, const void *data, int w, int h) { +static void R_cache_update (node *n, const void *data, int x, int y, int w, int h) { assert(n); assert(n->leaf); assert(n->base); assert(data); - int nw = n->r - n->l + 1; - int nh = n->b - n->t + 1; - assert(w == nw); - assert(h == nh); + assert(x >= 0); + assert(y >= 0); + assert(n->l + x + w - 1 <= n->r); + assert(n->t + y + h - 1 <= n->b); R_gl_bind_texture(n->base->id); - glTexSubImage2D(GL_TEXTURE_2D, 0, n->l, n->t, nw, nh, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexSubImage2D(GL_TEXTURE_2D, 0, n->l + x, n->t + y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); } /* Generic helpers */ @@ -481,7 +491,7 @@ static rgba *R_extract_rgba_spr (vgaimg *v) { static image R_gl_create_image (const rgba *buf, int w, int h) { node *n = R_cache_alloc(root, w, h); if (n) { - R_cache_update(n, buf, w, h); + R_cache_update(n, buf, 0, 0, w, h); } return (image) { .n = n, -- 2.29.2 From de05b18ef2a99168b0a1a8a921a4b18ec7023833 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 21 Mar 2020 18:31:19 +0300 Subject: [PATCH 12/16] system: game itself do not depends on sdl --- src/CMakeLists.txt | 8 +- src/config.c | 30 +--- src/default.cfg | 44 +++--- src/error.c | 19 +-- src/game.c | 17 ++- src/input.c | 233 +++++++++++++++++++++++++++++++ src/input.h | 118 ++++++++++++++++ src/keyb.c | 61 --------- src/keyb.h | 38 ------ src/main.c | 108 --------------- src/menu.c | 334 ++++++++++++++++++++++++++------------------- src/menu.h | 1 + src/my.c | 5 - src/my.h | 2 - src/player.c | 36 ++--- src/sdl/main.c | 245 +++++++++++++++++++++++++++++++++ src/sound.c | 1 + 17 files changed, 860 insertions(+), 440 deletions(-) create mode 100644 src/input.c create mode 100644 src/input.h delete mode 100644 src/keyb.c delete mode 100644 src/keyb.h delete mode 100644 src/main.c create mode 100644 src/sdl/main.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b01523e..1a511c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,13 @@ cmake_minimum_required(VERSION 3.6) project(doom2d C) -option(WITH_OPENGL "Build with OpenGL render" OFF) +option(WITH_OPENGL "Build with OpenGL render" ON) option(WITH_SOFTWARE "Build with Software render" ON) set(D2D_GAME_ROOT .) set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl) set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft) +set(D2D_SDL_ROOT ${D2D_GAME_ROOT}/sdl) find_package(SDL REQUIRED) find_package(SDL_mixer REQUIRED) @@ -17,6 +18,7 @@ endif (WITH_OPENGL) aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC) aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC) aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC) +aux_source_directory(${D2D_SDL_ROOT} D2D_SDL_SRC) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) @@ -37,13 +39,13 @@ message(STATUS "SOFTWARE: " ${WITH_SOFTWARE}) message(STATUS "OPENGL: " ${WITH_OPENGL}) if (WITH_OPENGL) - add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_OPENGL_SRC}) + add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_OPENGL_SRC}) target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}") target_link_libraries(doom2d-gl "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" "${OPENGL_LIBRARY}") endif (WITH_OPENGL) if (WITH_SOFTWARE) - add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SOFTWARE_SRC}) + add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SOFTWARE_SRC}) target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}") target_link_libraries(doom2d-soft "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}") endif (WITH_SOFTWARE) diff --git a/src/config.c b/src/config.c index 0c5bc21..c51e9ee 100644 --- a/src/config.c +++ b/src/config.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "map.h" #include "sound.h" #include "music.h" @@ -35,6 +34,7 @@ #include "files.h" #include "render.h" #include "error.h" +#include "input.h" #include "my.h" enum{NONE,BYTE,WORD,DWORD,STRING,SW_ON,SW_OFF,FILES,KEY}; @@ -154,18 +154,6 @@ next: } } -static int get_key (char *name) { - int i; - for(i=1; i #include #include -#include "keyb.h" #include "sound.h" #include "render.h" #include "memory.h" @@ -35,7 +34,6 @@ void logo (const char *s, ...) { va_list ap; - int x, y; va_start(ap, s); vprintf(s, ap); va_end(ap); @@ -49,14 +47,13 @@ void logo_gas (int cur, int all) { static void close_all (void) { S_done(); S_donemusic(); - K_done(); - R_done(); M_shutdown(); + R_done(); } void ERR_failinit (char *s, ...) { va_list ap; - close_all(); + //close_all(); va_start(ap, s); vprintf(s, ap); va_end(ap); @@ -64,7 +61,7 @@ void ERR_failinit (char *s, ...) { exit(1); } -void ERR_fatal(char *s,...) { +void ERR_fatal (char *s,...) { va_list ap; close_all(); puts("\nКРИТИЧЕСКАЯ ОШИБКА:"); @@ -76,14 +73,8 @@ void ERR_fatal(char *s,...) { } 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); - //} + puts("Спасибо за то, что вы играли в Операцию \"Смятка\"!"); + //F_loadres(F_getresid("ENDOOM"),p,0,4000); close_all(); CFG_save(); exit(0); diff --git a/src/game.c b/src/game.c index 8d14674..b540223 100644 --- a/src/game.c +++ b/src/game.c @@ -26,7 +26,6 @@ #include #include "files.h" #include "memory.h" -#include "keyb.h" #include "sound.h" #include "view.h" #include "bmap.h" @@ -47,8 +46,8 @@ #include "music.h" #include "a8.h" #include "error.h" +#include "input.h" -#include #define LT_DELAY 8 #define LT_HITTIME 6 @@ -273,8 +272,8 @@ void G_act (void) { if(g_st==GS_BVIDEO || g_st==GS_EVIDEO) { - if(!A8_nextframe() || lastkey==SDLK_ESCAPE) { - if(lastkey==SDLK_ESCAPE) lastkey=0; + if (!A8_nextframe() || lastkey == KEY_ESCAPE) { + if (lastkey == KEY_ESCAPE) lastkey = KEY_UNKNOWN; A8_close(); if(g_st==GS_BVIDEO) G_start(); else goto inter; @@ -311,10 +310,14 @@ void G_act (void) { 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(); + if (I_pressed(KEY_SPACE) || I_pressed(KEY_RETURN) || I_pressed(KEY_KP_ENTER)) { + if (!G_beg_video()) { + G_start(); + } else { + g_st = GS_BVIDEO; + F_freemus(); } + } #endif return; } diff --git a/src/input.c b/src/input.c new file mode 100644 index 0000000..825e5d2 --- /dev/null +++ b/src/input.c @@ -0,0 +1,233 @@ +#include "input.h" +#include +#include + +static char keystate[KEY__LAST + 1]; + +const char *I_key_to_string (int key) { + switch (key) { + case KEY_0: return "0"; + case KEY_1: return "1"; + case KEY_2: return "2"; + case KEY_3: return "3"; + case KEY_4: return "4"; + case KEY_5: return "5"; + case KEY_6: return "6"; + case KEY_7: return "7"; + case KEY_8: return "8"; + case KEY_9: return "9"; + case KEY_A: return "A"; + case KEY_B: return "B"; + case KEY_C: return "C"; + case KEY_D: return "D"; + case KEY_E: return "E"; + case KEY_F: return "F"; + case KEY_G: return "G"; + case KEY_H: return "H"; + case KEY_I: return "I"; + case KEY_J: return "J"; + case KEY_K: return "K"; + case KEY_L: return "L"; + case KEY_M: return "M"; + case KEY_N: return "N"; + case KEY_O: return "O"; + case KEY_P: return "P"; + case KEY_Q: return "Q"; + case KEY_R: return "R"; + case KEY_S: return "S"; + case KEY_T: return "T"; + case KEY_U: return "U"; + case KEY_V: return "V"; + case KEY_W: return "W"; + case KEY_X: return "X"; + case KEY_Y: return "Y"; + case KEY_Z: return "Z"; + case KEY_RETURN: return "RETURN"; + case KEY_ESCAPE: return "ESCAPE"; + case KEY_BACKSPACE: return "BACKSPACE"; + case KEY_TAB: return "TAB"; + case KEY_SPACE: return "SPACE"; + case KEY_MINUS: return "MINUS"; + case KEY_EQUALS: return "EQUALS"; + case KEY_LEFTBRACKET: return "LEFTBRACKET"; + case KEY_RIGHTBRACKET: return "RIGHTBRACKET"; + case KEY_BACKSLASH: return "BACKSLASH"; + case KEY_SEMICOLON: return "SEMICOLON"; + case KEY_APOSTROPHE: return "APOSTROPHE"; + case KEY_GRAVE: return "GRAVE"; + case KEY_COMMA: return "COMMA"; + case KEY_PERIOD: return "PERIOD"; + case KEY_SLASH: return "SLASH"; + case KEY_CAPSLOCK: return "CAPSLOCK"; + case KEY_F1: return "F1"; + case KEY_F2: return "F2"; + case KEY_F3: return "F3"; + case KEY_F4: return "F4"; + case KEY_F5: return "F5"; + case KEY_F6: return "F6"; + case KEY_F7: return "F7"; + case KEY_F8: return "F8"; + case KEY_F9: return "F9"; + case KEY_F10: return "F10"; + case KEY_F11: return "F11"; + case KEY_F12: return "F12"; + case KEY_PRINTSCREEN: return "PRINTSCREEN"; + case KEY_SCROLLLOCK: return "SCROLLLOCK"; + case KEY_PAUSE: return "PAUSE"; + case KEY_INSERT: return "INSERT"; + case KEY_HOME: return "HOME"; + case KEY_PAGEUP: return "PAGEUP"; + case KEY_DELETE: return "DELETE"; + case KEY_END: return "END"; + case KEY_PAGEDOWN: return "PAGEDOWN"; + case KEY_RIGHT: return "RIGHT"; + case KEY_LEFT: return "LEFT"; + case KEY_DOWN: return "DOWN"; + case KEY_UP: return "UP"; + case KEY_NUMLOCK: return "NUMLOCK"; + case KEY_KP_DIVIDE: return "KP_DIVIDE"; + case KEY_KP_MULTIPLY: return "KP_MULTIPLY"; + case KEY_KP_MINUS: return "KP_MINUS"; + case KEY_KP_PLUS: return "KP_PLUS"; + case KEY_KP_ENTER: return "KP_ENTER"; + case KEY_KP_0: return "KP_0"; + case KEY_KP_1: return "KP_1"; + case KEY_KP_2: return "KP_2"; + case KEY_KP_3: return "KP_3"; + case KEY_KP_4: return "KP_4"; + case KEY_KP_5: return "KP_5"; + case KEY_KP_6: return "KP_6"; + case KEY_KP_7: return "KP_7"; + case KEY_KP_8: return "KP_8"; + case KEY_KP_9: return "KP_9"; + case KEY_KP_PERIOD: return "KP_PERIOD"; + case KEY_SYSREQ: return "SYSREQ"; + case KEY_LCTRL: return "LCTRL"; + case KEY_LSHIFT: return "LSHIFT"; + case KEY_LALT: return "LALT"; + case KEY_LSUPER: return "LSUPER"; + case KEY_RCTRL: return "RCTRL"; + case KEY_RSHIFT: return "RSHIFT"; + case KEY_RALT: return "RALT"; + case KEY_RSUPER: return "RSUPER"; + default: return "UNKNOWN"; + } +} + +int I_string_to_key (const char *str) { + if (strcasecmp(str, "0") == 0) return KEY_0; + else if (strcasecmp(str, "1") == 0) return KEY_1; + else if (strcasecmp(str, "2") == 0) return KEY_2; + else if (strcasecmp(str, "3") == 0) return KEY_3; + else if (strcasecmp(str, "4") == 0) return KEY_4; + else if (strcasecmp(str, "5") == 0) return KEY_5; + else if (strcasecmp(str, "6") == 0) return KEY_6; + else if (strcasecmp(str, "7") == 0) return KEY_7; + else if (strcasecmp(str, "8") == 0) return KEY_8; + else if (strcasecmp(str, "9") == 0) return KEY_9; + else if (strcasecmp(str, "A") == 0) return KEY_A; + else if (strcasecmp(str, "B") == 0) return KEY_B; + else if (strcasecmp(str, "C") == 0) return KEY_C; + else if (strcasecmp(str, "D") == 0) return KEY_D; + else if (strcasecmp(str, "E") == 0) return KEY_E; + else if (strcasecmp(str, "F") == 0) return KEY_F; + else if (strcasecmp(str, "G") == 0) return KEY_G; + else if (strcasecmp(str, "H") == 0) return KEY_H; + else if (strcasecmp(str, "I") == 0) return KEY_I; + else if (strcasecmp(str, "J") == 0) return KEY_J; + else if (strcasecmp(str, "K") == 0) return KEY_K; + else if (strcasecmp(str, "L") == 0) return KEY_L; + else if (strcasecmp(str, "M") == 0) return KEY_M; + else if (strcasecmp(str, "N") == 0) return KEY_N; + else if (strcasecmp(str, "O") == 0) return KEY_O; + else if (strcasecmp(str, "P") == 0) return KEY_P; + else if (strcasecmp(str, "Q") == 0) return KEY_Q; + else if (strcasecmp(str, "R") == 0) return KEY_R; + else if (strcasecmp(str, "S") == 0) return KEY_S; + else if (strcasecmp(str, "T") == 0) return KEY_T; + else if (strcasecmp(str, "U") == 0) return KEY_U; + else if (strcasecmp(str, "V") == 0) return KEY_V; + else if (strcasecmp(str, "W") == 0) return KEY_W; + else if (strcasecmp(str, "X") == 0) return KEY_X; + else if (strcasecmp(str, "Y") == 0) return KEY_Y; + else if (strcasecmp(str, "Z") == 0) return KEY_Z; + else if (strcasecmp(str, "RETURN") == 0) return KEY_RETURN; + else if (strcasecmp(str, "ESCAPE") == 0) return KEY_ESCAPE; + else if (strcasecmp(str, "BACKSPACE") == 0) return KEY_BACKSPACE; + else if (strcasecmp(str, "TAB") == 0) return KEY_TAB; + else if (strcasecmp(str, "SPACE") == 0) return KEY_SPACE; + else if (strcasecmp(str, "MINUS") == 0) return KEY_MINUS; + else if (strcasecmp(str, "EQUALS") == 0) return KEY_EQUALS; + else if (strcasecmp(str, "LEFTBRACKET") == 0) return KEY_LEFTBRACKET; + else if (strcasecmp(str, "RIGHTBRACKET") == 0) return KEY_RIGHTBRACKET; + else if (strcasecmp(str, "BACKSLASH") == 0) return KEY_BACKSLASH; + else if (strcasecmp(str, "SEMICOLON") == 0) return KEY_SEMICOLON; + else if (strcasecmp(str, "APOSTROPHE") == 0) return KEY_APOSTROPHE; + else if (strcasecmp(str, "GRAVE") == 0) return KEY_GRAVE; + else if (strcasecmp(str, "COMMA") == 0) return KEY_COMMA; + else if (strcasecmp(str, "PERIOD") == 0) return KEY_PERIOD; + else if (strcasecmp(str, "SLASH") == 0) return KEY_SLASH; + else if (strcasecmp(str, "CAPSLOCK") == 0) return KEY_CAPSLOCK; + else if (strcasecmp(str, "F1") == 0) return KEY_F1; + else if (strcasecmp(str, "F2") == 0) return KEY_F2; + else if (strcasecmp(str, "F3") == 0) return KEY_F3; + else if (strcasecmp(str, "F4") == 0) return KEY_F4; + else if (strcasecmp(str, "F5") == 0) return KEY_F5; + else if (strcasecmp(str, "F6") == 0) return KEY_F6; + else if (strcasecmp(str, "F7") == 0) return KEY_F7; + else if (strcasecmp(str, "F8") == 0) return KEY_F8; + else if (strcasecmp(str, "F9") == 0) return KEY_F9; + else if (strcasecmp(str, "F10") == 0) return KEY_F10; + else if (strcasecmp(str, "F11") == 0) return KEY_F11; + else if (strcasecmp(str, "F12") == 0) return KEY_F12; + else if (strcasecmp(str, "PRINTSCREEN") == 0) return KEY_PRINTSCREEN; + else if (strcasecmp(str, "SCROLLLOCK") == 0) return KEY_SCROLLLOCK; + else if (strcasecmp(str, "PAUSE") == 0) return KEY_PAUSE; + else if (strcasecmp(str, "INSERT") == 0) return KEY_INSERT; + else if (strcasecmp(str, "HOME") == 0) return KEY_HOME; + else if (strcasecmp(str, "PAGEUP") == 0) return KEY_PAGEUP; + else if (strcasecmp(str, "DELETE") == 0) return KEY_DELETE; + else if (strcasecmp(str, "END") == 0) return KEY_END; + else if (strcasecmp(str, "PAGEDOWN") == 0) return KEY_PAGEDOWN; + else if (strcasecmp(str, "RIGHT") == 0) return KEY_RIGHT; + else if (strcasecmp(str, "LEFT") == 0) return KEY_LEFT; + else if (strcasecmp(str, "DOWN") == 0) return KEY_DOWN; + else if (strcasecmp(str, "UP") == 0) return KEY_UP; + else if (strcasecmp(str, "NUMLOCK") == 0) return KEY_NUMLOCK; + else if (strcasecmp(str, "KP_DIVIDE") == 0) return KEY_KP_DIVIDE; + else if (strcasecmp(str, "KP_MULTIPLY") == 0) return KEY_KP_MULTIPLY; + else if (strcasecmp(str, "KP_MINUS") == 0) return KEY_KP_MINUS; + else if (strcasecmp(str, "KP_PLUS") == 0) return KEY_KP_PLUS; + else if (strcasecmp(str, "KP_ENTER") == 0) return KEY_KP_ENTER; + else if (strcasecmp(str, "KP_0") == 0) return KEY_KP_0; + else if (strcasecmp(str, "KP_1") == 0) return KEY_KP_1; + else if (strcasecmp(str, "KP_2") == 0) return KEY_KP_2; + else if (strcasecmp(str, "KP_3") == 0) return KEY_KP_3; + else if (strcasecmp(str, "KP_4") == 0) return KEY_KP_4; + else if (strcasecmp(str, "KP_5") == 0) return KEY_KP_5; + else if (strcasecmp(str, "KP_6") == 0) return KEY_KP_6; + else if (strcasecmp(str, "KP_7") == 0) return KEY_KP_7; + else if (strcasecmp(str, "KP_8") == 0) return KEY_KP_8; + else if (strcasecmp(str, "KP_9") == 0) return KEY_KP_9; + else if (strcasecmp(str, "KP_PERIOD") == 0) return KEY_KP_PERIOD; + else if (strcasecmp(str, "SYSREQ") == 0) return KEY_SYSREQ; + else if (strcasecmp(str, "LCTRL") == 0) return KEY_LCTRL; + else if (strcasecmp(str, "LSHIFT") == 0) return KEY_LSHIFT; + else if (strcasecmp(str, "LALT") == 0) return KEY_LALT; + else if (strcasecmp(str, "LSUPER") == 0) return KEY_LSUPER; + else if (strcasecmp(str, "RCTRL") == 0) return KEY_RCTRL; + else if (strcasecmp(str, "RSHIFT") == 0) return KEY_RSHIFT; + else if (strcasecmp(str, "RALT") == 0) return KEY_RALT; + else if (strcasecmp(str, "RSUPER") == 0) return KEY_RSUPER; + else return KEY_UNKNOWN; +} + +int I_pressed (int key) { + assert(key >= 0 && key <= KEY__LAST); + return keystate[key]; +} + +void I_press (int key, int down) { + assert(key >= 0 && key <= KEY__LAST); + keystate[key] = down != 0; +} diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..ad86145 --- /dev/null +++ b/src/input.h @@ -0,0 +1,118 @@ +#ifndef INPUT_H_INCLUDED +#define INPUT_H_INCLUDED + +enum { + KEY_UNKNOWN, + KEY_0, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_A, + KEY_B, + KEY_C, + KEY_D, + KEY_E, + KEY_F, + KEY_G, + KEY_H, + KEY_I, + KEY_J, + KEY_K, + KEY_L, + KEY_M, + KEY_N, + KEY_O, + KEY_P, + KEY_Q, + KEY_R, + KEY_S, + KEY_T, + KEY_U, + KEY_V, + KEY_W, + KEY_X, + KEY_Y, + KEY_Z, + KEY_RETURN, + KEY_ESCAPE, + KEY_BACKSPACE, + KEY_TAB, + KEY_SPACE, + KEY_MINUS, + KEY_EQUALS, + KEY_LEFTBRACKET, + KEY_RIGHTBRACKET, + KEY_BACKSLASH, + KEY_SEMICOLON, + KEY_APOSTROPHE, + KEY_GRAVE, + KEY_COMMA, + KEY_PERIOD, + KEY_SLASH, + KEY_CAPSLOCK, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_F11, + KEY_F12, + KEY_PRINTSCREEN, + KEY_SCROLLLOCK, + KEY_PAUSE, + KEY_INSERT, + KEY_HOME, + KEY_PAGEUP, + KEY_DELETE, + KEY_END, + KEY_PAGEDOWN, + KEY_RIGHT, + KEY_LEFT, + KEY_DOWN, + KEY_UP, + KEY_NUMLOCK, + KEY_KP_DIVIDE, + KEY_KP_MULTIPLY, + KEY_KP_MINUS, + KEY_KP_PLUS, + KEY_KP_ENTER, + KEY_KP_0, + KEY_KP_1, + KEY_KP_2, + KEY_KP_3, + KEY_KP_4, + KEY_KP_5, + KEY_KP_6, + KEY_KP_7, + KEY_KP_8, + KEY_KP_9, + KEY_KP_PERIOD, + KEY_SYSREQ, + KEY_LCTRL, + KEY_LSHIFT, + KEY_LALT, + KEY_LSUPER, + KEY_RCTRL, + KEY_RSHIFT, + KEY_RALT, + KEY_RSUPER, + KEY__LAST = KEY_RSUPER +}; + +const char *I_key_to_string (int key); +int I_string_to_key (const char *str); +int I_pressed (int key); +void I_press (int key, int down); + +#endif /* INPUT_H_INCLUDED */ diff --git a/src/keyb.c b/src/keyb.c deleted file mode 100644 index 7110996..0000000 --- a/src/keyb.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - 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 "error.h" -#include - -// массив клавиш: 0 - отпущена, иначе - нажата -unsigned char *keys = NULL; - -static key_f *key_proc = NULL; - -void K_init (void) { - keys = SDL_GetKeyState(NULL); -} - -void K_done (void) { - // not needed for sdl -} - -// установить функцию обработки клавиш -void K_setkeyproc (key_f *k) { - key_proc = k; -} - -void updatee_keys (void) { - 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 deleted file mode 100644 index d52559a..0000000 --- a/src/keyb.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - Драйвер клавиатуры 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 KEYB_H_INCLUDED -#define KEYB_H_INCLUDED - -typedef void key_f (int k, int pressed); - -extern unsigned char *keys; - -void K_init (void); -void K_done (void); -void K_setkeyproc (key_f *k); -void updatee_keys (void); - -#endif /* KEYB_H_INCLUDED */ diff --git a/src/main.c b/src/main.c deleted file mode 100644 index edf7156..0000000 --- a/src/main.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - 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 "config.h" -#include "memory.h" -#include "keyb.h" -#include "sound.h" -#include "files.h" -#include "view.h" -#include "menu.h" -#include "player.h" -#include "my.h" -#include "render.h" -#include "game.h" -#include "music.h" - -#include - -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(); - char *pw; -#ifndef WIN32 - pw = "/usr/share/doom2d-rembo/doom2d.wad"; -#else - pw = "doom2d.wad"; -#endif - if (fexists(pw)) - F_addwad(pw); - else - F_addwad("doom2d.wad"); - CFG_args(argc, argv); - CFG_load(); - F_initwads(); - M_startup(); - F_allocres(); - G_init(); - K_init(); - logo("S_init: настройка звука\n"); - S_init(); - S_initmusic(); - R_init(); - GM_init(); - F_loadmus("MENU"); - S_startmusic(0); - - Uint32 ticks = SDL_GetTicks(); - for (;;) { - updatee_keys(); - S_updatemusic(); - Uint32 t = SDL_GetTicks(); - if (t - ticks > DELAY) { - ticks = t; - G_act(); - } - R_draw(); - //SDL_Delay(1); - } -} diff --git a/src/menu.c b/src/menu.c index bd225a4..3d797fc 100644 --- a/src/menu.c +++ b/src/menu.c @@ -27,7 +27,6 @@ #include "files.h" #include "memory.h" #include "error.h" -#include "keyb.h" #include "sound.h" #include "view.h" #include "player.h" @@ -40,8 +39,8 @@ #include "player.h" #include "sound.h" #include "music.h" +#include "input.h" -#include #include #define QSND_NUM 14 @@ -336,45 +335,45 @@ 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,','}, + {KEY_SPACE, ' '}, + {KEY_0, '0'}, + {KEY_1, '1'}, + {KEY_2, '2'}, + {KEY_3, '3'}, + {KEY_4, '4'}, + {KEY_5, '5'}, + {KEY_6, '6'}, + {KEY_7, '7'}, + {KEY_8, '8'}, + {KEY_9, '9'}, + //{KEY_UNDERSCORE, '_'}, + {KEY_A, 'A'}, + {KEY_B, 'B'}, + {KEY_C, 'C'}, + {KEY_D, 'D'}, + {KEY_E, 'E'}, + {KEY_F, 'F'}, + {KEY_G, 'G'}, + {KEY_H, 'H'}, + {KEY_I, 'I'}, + {KEY_J, 'J'}, + {KEY_K, 'K'}, + {KEY_L, 'L'}, + {KEY_M, 'M'}, + {KEY_N, 'N'}, + {KEY_O, 'O'}, + {KEY_P, 'P'}, + {KEY_Q, 'Q'}, + {KEY_R, 'R'}, + {KEY_S, 'S'}, + {KEY_T, 'T'}, + {KEY_U, 'U'}, + {KEY_V, 'V'}, + {KEY_W, 'W'}, + {KEY_X, 'X'}, + {KEY_Y, 'Y'}, + {KEY_Z, 'Z'}, + {KEY_COMMA,','}, {0} }; @@ -418,107 +417,165 @@ int GM_act (void) { 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; - } + if (input) { + switch (lastkey) { + case KEY_RETURN: + case KEY_KP_ENTER: + F_savegame(save_mnu.cur, ibuf); + input = 0; + GM_set(NULL); + break; + case KEY_ESCAPE: + input = 0; + GM_set(mnu); + break; + case KEY_BACKSPACE: + if (icur) { + icur -= 1; + ibuf[icur] = 0; + GM_set(mnu); + } + break; + default: + if (icur < 23) { + c = get_keychar(lastkey); + if (c != 0) { + ibuf[icur] = c; + icur += 1; + ibuf[icur] = 0; + GM_set(mnu); + } + } + break; + } + } else { + switch (lastkey) { + case KEY_ESCAPE: + if (mnu == NULL) { + GM_set(&main_mnu); + Z_sound(msnd3, 128); + } else { + GM_set(NULL); + Z_sound(msnd4, 128); + } + break; + case KEY_F5: + if (mnu == NULL) { + Z_sound(msnd3, 128); + GMV_say("_GAMMA"); + GM_set(&gamma_mnu); + } + break; + case KEY_F4: + if (mnu == NULL) { + Z_sound(msnd3, 128); + GMV_say("_VOLUME"); + GM_set(&vol_mnu); + } + break; + case KEY_F2: + if (mnu == NULL && g_st == GS_GAME) { + Z_sound(msnd3, 128); + F_getsavnames(); + GM_set(&save_mnu); + } + break; + case KEY_F3: + if (mnu == NULL) { + Z_sound(msnd3, 128); + F_getsavnames(); + GM_set(&load_mnu); + } + break; + case KEY_F10: + if (mnu == NULL) { + Z_sound(msnd3, 128); + GM_command(QUITGAME); + } + break; + case KEY_UP: + case KEY_KP_8: + if (mnu != NULL && mnu->type == MENU) { + mnu->cur -= 1; + if (mnu->cur < 0) { + mnu->cur = mnu->n - 1; + } + GM_set(mnu); + Z_sound(msnd1, 128); + } + break; + case KEY_DOWN: + case KEY_KP_5: + case KEY_KP_2: + if (mnu != NULL && mnu->type == MENU) { + mnu->cur += 1; + if (mnu->cur >= mnu->n) { + mnu->cur = 0; + } + GM_set(mnu); + Z_sound(msnd1, 128); + } + break; + case KEY_LEFT: + case KEY_RIGHT: + case KEY_KP_4: + case KEY_KP_6: + if (mnu != NULL && mnu->type == MENU && mnu->t[mnu->cur] >= SVOLM) { + GM_command(mnu->t[mnu->cur] + (lastkey == KEY_LEFT || lastkey == KEY_KP_4)); + GM_set(mnu); + if (!movsndt) { + movsndt = Z_sound(lastkey == KEY_LEFT || lastkey == KEY_KP_4 ? msnd5 : msnd6, 255); + } + } + break; + case KEY_RETURN: + case KEY_SPACE: + case KEY_KP_ENTER: + if (mnu != NULL && mnu->type == MENU) { + if (mnu->t[mnu->cur] >= PL1CM) { + Z_sound(msnd2, 128); + GM_command(PLCEND); + break; + } else if (mnu->t[mnu->cur] < SVOLM) { + Z_sound(msnd2,128); + GM_command(mnu->t[mnu->cur]); + } + } + break; + case KEY_Y: + if (mnu != NULL && mnu->type == MSG) { + Z_sound(msnd3, 128); + GM_command(mnu->t[0]); + } + break; + case KEY_N: + if (mnu != NULL && mnu->type == MSG) { + Z_sound(msnd4, 128); + GM_command(mnu->t[1]); + } + break; + case KEY_F1: + if (shot_vga) { + shot(); + Z_sound(msnd4, 128); + } + break; + } } - lastkey=0; - return((mnu)?1:0); + lastkey = KEY_UNKNOWN; + return mnu ? 1 : 0; } -static void G_keyf (int k, int press) { +void G_keyf (int key, int down) { int i; - - lastkey=k; - if(!_2pl || cheat) { - for(i=0;i<31;++i) cbuf[i]=cbuf[i+1]; - cbuf[31]=get_keychar(k); + if (down) { + lastkey = key; + if (!_2pl || cheat) { + for (i = 0; i < 31; ++i) { + cbuf[i] = cbuf[i + 1]; + } + cbuf[31] = get_keychar(key); + } } } @@ -545,5 +602,4 @@ void GM_init (void) { msnd4=Z_getsnd("SWTCHX"); msnd5=Z_getsnd("SUDI"); msnd6=Z_getsnd("TUDI"); - K_setkeyproc(G_keyf); } diff --git a/src/menu.h b/src/menu.h index 3e6c65e..fedd702 100644 --- a/src/menu.h +++ b/src/menu.h @@ -49,6 +49,7 @@ extern byte gm_redraw; extern short lastkey; void GMV_say (char *nm); +void G_keyf (int key, int down); void G_code (void); int GM_act (void); void GM_init (void); diff --git a/src/my.c b/src/my.c index a966eb8..28dba3d 100644 --- a/src/my.c +++ b/src/my.c @@ -20,7 +20,6 @@ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include "glob.h" #include "error.h" #include "misc.h" @@ -126,10 +125,6 @@ void myfwrite32 (int32_t x, FILE *f) { myfwrite(&x, 4, 1, f); } -void myrandomize (void) { - srand(SDL_GetTicks()); -} - int fexists (char *filename) { FILE *f; if ((f = fopen(filename, "r"))) diff --git a/src/my.h b/src/my.h index 15792f1..a278cc2 100644 --- a/src/my.h +++ b/src/my.h @@ -39,8 +39,6 @@ void myfwrite8 (int8_t x, FILE *f); void myfwrite16 (int16_t x, FILE *f); void myfwrite32 (int32_t x, FILE *f); -void myrandomize (void); - int fexists (char *filename); #endif /* MY_H_INCLUDED */ diff --git a/src/player.c b/src/player.c index f593f30..4ade170 100644 --- a/src/player.c +++ b/src/player.c @@ -23,7 +23,6 @@ #include "glob.h" #include #include -#include "keyb.h" #include "view.h" #include "dots.h" #include "smoke.h" @@ -36,6 +35,7 @@ #include "misc.h" #include "my.h" #include "game.h" +#include "input.h" #define PL_RAD 8 #define PL_HT 26 @@ -202,22 +202,22 @@ static void fire(player_t *p) { if(p->cwpn) return; if(p->wpn==8) { if(!p->fire) - if(keys[p->kf] && p->cell>=40) + if(I_pressed(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(!I_pressed(p->kf)) {Z_sound(snd[7],128);p->csnd=13;return;} } - if(keys[p->kf] && !p->fire) { + if(I_pressed(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) { + if(I_pressed(p->kf) || p->wpn==8) { switch(p->wpn) { case 2: case 5: if(!p->ammo) return; @@ -252,10 +252,10 @@ static void fire(player_t *p) { static void chgwpn(player_t *p) { if(p->cwpn) return; if(p->fire && p->wpn!=1) return; - if(keys[p->kwl]) { + if(I_pressed(p->kwl)) { do{ if(--p->wpn<0) p->wpn=10; }while(!(p->wpns&(1<wpn))); p->cwpn=3; - }else if(keys[p->kwr]) { + }else if(I_pressed(p->kwr)) { do{ if(++p->wpn>10) p->wpn=0; }while(!(p->wpns&(1<wpn))); p->cwpn=3; } @@ -277,7 +277,7 @@ static void jump(player_t *p,int st) { } p->drawst|=PL_DRAWAIR; } - if(keys[p->kj]) { + if(I_pressed(p->kj)) { if(p_fly) { p->o.yv=-PL_FLYUP; }else{ @@ -577,14 +577,14 @@ void PL_act (player_t *p) { }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;} + if(I_pressed(p->ku)) {p->f|=PLF_UP;p->looky-=5;} else{ p->f&=0xFFFF-PLF_UP; - if(keys[p->kd]) + if(I_pressed(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(I_pressed(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; @@ -606,15 +606,15 @@ void PL_act (player_t *p) { 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(!I_pressed(p->kl) && !I_pressed(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;} + 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;} + if(p->o.xv>-PL_RUN && I_pressed(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; @@ -622,15 +622,15 @@ void PL_act (player_t *p) { 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;} + if(I_pressed(p->kl)) {p->st=GO;p->s=0;p->d=0;} + else if(I_pressed(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(I_pressed(p->ku) || I_pressed(p->kd) || I_pressed(p->kl) || I_pressed(p->kr) || + I_pressed(p->kf) || I_pressed(p->kj) || I_pressed(p->kp) || I_pressed(p->kwl) || I_pressed(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;} diff --git a/src/sdl/main.c b/src/sdl/main.c new file mode 100644 index 0000000..3aaad80 --- /dev/null +++ b/src/sdl/main.c @@ -0,0 +1,245 @@ +/* + 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 // srand +#include // strcasecmp +#include "input.h" + +#include "my.h" // fexists +#include "player.h" // pl1 pl2 +#include "menu.h" // GM_init G_keyf +#include "error.h" // logo + +#include "files.h" // F_startup F_addwad F_initwads F_allocres +#include "config.h" // CFG_args CFG_load +#include "memory.h" // M_startup +#include "game.h" // G_Init G_act +#include "sound.h" // S_init S_done +#include "music.h" // S_initmusic S_updatemusic S_donemusic +#include "render.h" // R_init R_draw R_done + +static int quit = 0; + +static int sdl_to_key (int code) { + switch (code) { + case SDLK_0: return KEY_0; + case SDLK_1: return KEY_1; + case SDLK_2: return KEY_2; + case SDLK_3: return KEY_3; + case SDLK_4: return KEY_4; + case SDLK_5: return KEY_5; + case SDLK_6: return KEY_6; + case SDLK_7: return KEY_7; + case SDLK_8: return KEY_8; + case SDLK_9: return KEY_9; + case SDLK_a: return KEY_A; + case SDLK_b: return KEY_B; + case SDLK_c: return KEY_C; + case SDLK_d: return KEY_D; + case SDLK_e: return KEY_E; + case SDLK_f: return KEY_F; + case SDLK_g: return KEY_G; + case SDLK_h: return KEY_H; + case SDLK_i: return KEY_I; + case SDLK_j: return KEY_J; + case SDLK_k: return KEY_K; + case SDLK_l: return KEY_L; + case SDLK_m: return KEY_M; + case SDLK_n: return KEY_N; + case SDLK_o: return KEY_O; + case SDLK_p: return KEY_P; + case SDLK_q: return KEY_Q; + case SDLK_r: return KEY_R; + case SDLK_s: return KEY_S; + case SDLK_t: return KEY_T; + case SDLK_u: return KEY_U; + case SDLK_v: return KEY_V; + case SDLK_w: return KEY_W; + case SDLK_x: return KEY_X; + case SDLK_y: return KEY_Y; + case SDLK_z: return KEY_Z; + case SDLK_RETURN: return KEY_RETURN; + case SDLK_ESCAPE: return KEY_ESCAPE; + case SDLK_BACKSPACE: return KEY_BACKSPACE; + case SDLK_TAB: return KEY_TAB; + case SDLK_SPACE: return KEY_SPACE; + case SDLK_MINUS: return KEY_MINUS; + case SDLK_EQUALS: return KEY_EQUALS; + case SDLK_LEFTBRACKET: return KEY_LEFTBRACKET; + case SDLK_RIGHTBRACKET: return KEY_RIGHTBRACKET; + case SDLK_BACKSLASH: return KEY_BACKSLASH; + case SDLK_SEMICOLON: return KEY_SEMICOLON; + case SDLK_QUOTE: return KEY_APOSTROPHE; + case SDLK_BACKQUOTE: return KEY_GRAVE; + case SDLK_COMMA: return KEY_COMMA; + case SDLK_PERIOD: return KEY_PERIOD; + case SDLK_SLASH: return KEY_SLASH; + case SDLK_CAPSLOCK: return KEY_CAPSLOCK; + case SDLK_F1: return KEY_F1; + case SDLK_F2: return KEY_F2; + case SDLK_F3: return KEY_F3; + case SDLK_F4: return KEY_F4; + case SDLK_F5: return KEY_F5; + case SDLK_F6: return KEY_F6; + case SDLK_F7: return KEY_F7; + case SDLK_F8: return KEY_F8; + case SDLK_F9: return KEY_F9; + case SDLK_F10: return KEY_F10; + case SDLK_F11: return KEY_F11; + case SDLK_F12: return KEY_F12; + case SDLK_PRINT: return KEY_PRINTSCREEN; + case SDLK_SCROLLOCK: return KEY_SCROLLLOCK; + case SDLK_PAUSE: return KEY_PAUSE; + case SDLK_INSERT: return KEY_INSERT; + case SDLK_HOME: return KEY_HOME; + case SDLK_PAGEUP: return KEY_PAGEUP; + case SDLK_DELETE: return KEY_DELETE; + case SDLK_END: return KEY_END; + case SDLK_PAGEDOWN: return KEY_PAGEDOWN; + case SDLK_RIGHT: return KEY_RIGHT; + case SDLK_LEFT: return KEY_LEFT; + case SDLK_DOWN: return KEY_DOWN; + case SDLK_UP: return KEY_UP; + case SDLK_NUMLOCK: return KEY_NUMLOCK; + case SDLK_KP_DIVIDE: return KEY_KP_DIVIDE; + case SDLK_KP_MULTIPLY: return KEY_KP_MULTIPLY; + case SDLK_KP_MINUS: return KEY_KP_MINUS; + case SDLK_KP_PLUS: return KEY_KP_PLUS; + case SDLK_KP_ENTER: return KEY_KP_ENTER; + case SDLK_KP0: return KEY_KP_0; + case SDLK_KP1: return KEY_KP_1; + case SDLK_KP2: return KEY_KP_2; + case SDLK_KP3: return KEY_KP_3; + case SDLK_KP4: return KEY_KP_4; + case SDLK_KP5: return KEY_KP_5; + case SDLK_KP6: return KEY_KP_6; + case SDLK_KP7: return KEY_KP_7; + case SDLK_KP8: return KEY_KP_8; + case SDLK_KP9: return KEY_KP_9; + case SDLK_KP_PERIOD: return KEY_KP_PERIOD; + case SDLK_SYSREQ: return KEY_SYSREQ; + case SDLK_LCTRL: return KEY_LCTRL; + case SDLK_LSHIFT: return KEY_LSHIFT; + case SDLK_LALT: return KEY_LALT; + case SDLK_LSUPER: return KEY_LSUPER; + case SDLK_RCTRL: return KEY_RCTRL; + case SDLK_RSHIFT: return KEY_RSHIFT; + case SDLK_RALT: return KEY_RALT; + case SDLK_RSUPER: return KEY_RSUPER; + default: return KEY_UNKNOWN; + } +} + +static void poll_events (void (*h)(int key, int down)) { + int key; + SDL_Event ev; + while (SDL_PollEvent(&ev)) { + switch (ev.type) { + case SDL_QUIT: + ERR_quit(); + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + key = sdl_to_key(ev.key.keysym.sym); + I_press(key, ev.type == SDL_KEYDOWN); + if (h != NULL) { + (*h)(key, ev.type == SDL_KEYDOWN); + } + break; + } + } +} + +int SDL_main (int argc, char *argv[]) { + char *pw; + Uint32 t, ticks; + logo("main: initialize SDL\n"); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) { + logo("main: failed to init SDL: %s\n", SDL_GetError()); + return 1; + } + SDL_WM_SetCaption("Doom 2D v1.351", "Doom 2D"); + pl1.id = -1; // TODO move to generic code + pl2.id = -2; // TODO move to generic code + // Player 1 defaults + pl1.ku = KEY_KP_8; + pl1.kd = KEY_KP_5; + pl1.kl = KEY_KP_4; + pl1.kr = KEY_KP_6; + pl1.kf = KEY_PAGEDOWN; + pl1.kj = KEY_DELETE; + pl1.kwl = KEY_HOME; + pl1.kwr = KEY_END; + pl1.kp = KEY_KP_8; + // Player 2 defaults + pl2.ku = KEY_E; + pl2.kd = KEY_D; + pl2.kl = KEY_S; + pl2.kr = KEY_F; + pl2.kf = KEY_A; + pl2.kj = KEY_Q; + pl2.kwl = KEY_1; + pl2.kwr = KEY_2; + pl2.kp = KEY_E; + srand(SDL_GetTicks()); + F_startup(); +#ifndef WIN32 + pw = "/usr/share/doom2d-rembo/doom2d.wad"; +#else + pw = "doom2d.wad"; +#endif + if (fexists(pw)) { + F_addwad(pw); + } else { + F_addwad("doom2d.wad"); + } + CFG_args(argc, argv); + CFG_load(); + F_initwads(); + M_startup(); + F_allocres(); + G_init(); + S_init(); + S_initmusic(); + R_init(); + GM_init(); // TODO move to game + F_loadmus("MENU"); // TODO move to menu + S_startmusic(0); // TODO move to menu + ticks = SDL_GetTicks(); + while (!quit) { + poll_events(&G_keyf); + S_updatemusic(); + t = SDL_GetTicks(); + if (t - ticks > DELAY) { + ticks = t; + G_act(); + } + R_draw(); + } + R_done(); + S_donemusic(); + S_done(); + M_shutdown(); + SDL_Quit(); + return 0; +} diff --git a/src/sound.c b/src/sound.c index 2fe510b..4a4077d 100644 --- a/src/sound.c +++ b/src/sound.c @@ -38,6 +38,7 @@ static struct { } chunks[NUM_CHUNKS]; void S_init (void) { + logo("S_init: настройка звука\n"); if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { fprintf(stderr, "\nUnable to initialize audio: %s\n", SDL_GetError()); -- 2.29.2 From a79a6e75633c38c64c7f0460f01216bf80703ad3 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sat, 21 Mar 2020 19:07:45 +0300 Subject: [PATCH 13/16] move error.c into system layer --- src/error.c | 81 -------------------------------------------------- src/menu.c | 2 ++ src/player.c | 9 ++++-- src/sdl/main.c | 62 +++++++++++++++++++++++++++++++------- 4 files changed, 59 insertions(+), 95 deletions(-) delete mode 100644 src/error.c diff --git a/src/error.c b/src/error.c deleted file mode 100644 index 0ba3d3b..0000000 --- a/src/error.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - 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 "sound.h" -#include "render.h" -#include "memory.h" -#include "error.h" -#include "config.h" -#include "music.h" - -void logo (const char *s, ...) { - va_list ap; - va_start(ap, s); - vprintf(s, ap); - va_end(ap); - fflush(stdout); -} - -void logo_gas (int cur, int all) { - // stub -} - -static void close_all (void) { - S_done(); - S_donemusic(); - M_shutdown(); - R_done(); -} - -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) { - puts("Спасибо за то, что вы играли в Операцию \"Смятка\"!"); - //F_loadres(F_getresid("ENDOOM"),p,0,4000); - close_all(); - CFG_save(); - exit(0); -} diff --git a/src/menu.c b/src/menu.c index 3d797fc..5a59b87 100644 --- a/src/menu.c +++ b/src/menu.c @@ -602,4 +602,6 @@ void GM_init (void) { msnd4=Z_getsnd("SWTCHX"); msnd5=Z_getsnd("SUDI"); msnd6=Z_getsnd("TUDI"); + F_loadmus("MENU"); + S_startmusic(0); } diff --git a/src/player.c b/src/player.c index 4ade170..ecb8b9e 100644 --- a/src/player.c +++ b/src/player.c @@ -297,9 +297,12 @@ int PL_isdead (player_t *p) { } void PL_init (void) { - p_immortal=0; - PL_JUMP=10;PL_RUN=8; - aitime=0; + pl1.id = -1; + pl2.id = -2; + p_immortal = 0; + PL_JUMP = 10; + PL_RUN = 8; + aitime = 0; } void PL_alloc(void) { diff --git a/src/sdl/main.c b/src/sdl/main.c index 3aaad80..ef757fc 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -21,25 +21,69 @@ */ #include -#include // srand +#include +#include +#include // srand exit #include // strcasecmp #include "input.h" #include "my.h" // fexists #include "player.h" // pl1 pl2 -#include "menu.h" // GM_init G_keyf +#include "menu.h" // G_keyf #include "error.h" // logo #include "files.h" // F_startup F_addwad F_initwads F_allocres -#include "config.h" // CFG_args CFG_load +#include "config.h" // CFG_args CFG_load CFG_save #include "memory.h" // M_startup -#include "game.h" // G_Init G_act +#include "game.h" // G_init G_act #include "sound.h" // S_init S_done #include "music.h" // S_initmusic S_updatemusic S_donemusic #include "render.h" // R_init R_draw R_done static int quit = 0; +void logo (const char *s, ...) { + va_list ap; + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + fflush(stdout); +} + +void logo_gas (int cur, int all) { + // stub +} + +void ERR_failinit (char *s, ...) { + va_list ap; + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + puts(""); + exit(1); +} + +void ERR_fatal (char *s, ...) { + va_list ap; + R_done(); + S_done(); + S_donemusic(); + M_shutdown(); + SDL_Quit(); + puts("\nКРИТИЧЕСКАЯ ОШИБКА:"); + va_start(ap, s); + vprintf(s, ap); + va_end(ap); + puts(""); + exit(1); +} + +void ERR_quit (void) { + puts("Спасибо за то, что вы играли в Операцию \"Смятка\"!"); + //F_loadres(F_getresid("ENDOOM"),p,0,4000); + quit = 1; +} + static int sdl_to_key (int code) { switch (code) { case SDLK_0: return KEY_0; @@ -179,8 +223,6 @@ int SDL_main (int argc, char *argv[]) { return 1; } SDL_WM_SetCaption("Doom 2D v1.351", "Doom 2D"); - pl1.id = -1; // TODO move to generic code - pl2.id = -2; // TODO move to generic code // Player 1 defaults pl1.ku = KEY_KP_8; pl1.kd = KEY_KP_5; @@ -218,13 +260,10 @@ int SDL_main (int argc, char *argv[]) { F_initwads(); M_startup(); F_allocres(); - G_init(); S_init(); S_initmusic(); R_init(); - GM_init(); // TODO move to game - F_loadmus("MENU"); // TODO move to menu - S_startmusic(0); // TODO move to menu + G_init(); ticks = SDL_GetTicks(); while (!quit) { poll_events(&G_keyf); @@ -236,9 +275,10 @@ int SDL_main (int argc, char *argv[]) { } R_draw(); } + CFG_save(); R_done(); - S_donemusic(); S_done(); + S_donemusic(); M_shutdown(); SDL_Quit(); return 0; -- 2.29.2 From dbfaa4949fe7c5be64cf3e98b1875b711656ff67 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 22 Mar 2020 12:13:26 +0300 Subject: [PATCH 14/16] sound: separate and rewrite --- src/CMakeLists.txt | 6 +- src/items.c | 2 +- src/menu.c | 7 +- src/miscc.c | 34 +++---- src/music.c | 233 ------------------------------------------- src/sdlmixer/sound.c | 217 ++++++++++++++++++++++++++++++++++++++++ src/sound.c | 150 ---------------------------- src/sound.h | 38 ++++--- src/view.c | 1 - 9 files changed, 264 insertions(+), 424 deletions(-) delete mode 100644 src/music.c create mode 100644 src/sdlmixer/sound.c delete mode 100644 src/sound.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a511c6..9558278 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ set(D2D_GAME_ROOT .) set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl) set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft) set(D2D_SDL_ROOT ${D2D_GAME_ROOT}/sdl) +set(D2D_SDLMIXER_ROOT ${D2D_GAME_ROOT}/sdlmixer) find_package(SDL REQUIRED) find_package(SDL_mixer REQUIRED) @@ -19,6 +20,7 @@ aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC) aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC) aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC) aux_source_directory(${D2D_SDL_ROOT} D2D_SDL_SRC) +aux_source_directory(${D2D_SDLMIXER_ROOT} D2D_SDLMIXER_SRC) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) @@ -39,13 +41,13 @@ message(STATUS "SOFTWARE: " ${WITH_SOFTWARE}) message(STATUS "OPENGL: " ${WITH_OPENGL}) if (WITH_OPENGL) - add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_OPENGL_SRC}) + add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_OPENGL_SRC}) target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}") target_link_libraries(doom2d-gl "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" "${OPENGL_LIBRARY}") endif (WITH_OPENGL) if (WITH_SOFTWARE) - add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SOFTWARE_SRC}) + add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_SOFTWARE_SRC}) target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}") target_link_libraries(doom2d-soft "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}") endif (WITH_SOFTWARE) diff --git a/src/items.c b/src/items.c index 49f954b..b0f079a 100644 --- a/src/items.c +++ b/src/items.c @@ -208,7 +208,7 @@ static void takesnd (int t) { {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); + tsndtm=Z_sound(snd[0], 255); } void IT_act (void) { diff --git a/src/menu.c b/src/menu.c index 5a59b87..95fbbf6 100644 --- a/src/menu.c +++ b/src/menu.c @@ -159,6 +159,8 @@ static void GMV_stop (void) { } void GMV_say (char *nm) { + // TODO fix this + /* int r,len; snd_t *p; byte *d; @@ -172,6 +174,7 @@ void GMV_say (char *nm) { for(d=(byte*)(p+1);len;--len,++d) *d^=128; voc=p; voc_ch=S_play(voc,-1,1024,255); + */ } static void GM_set (menu_t *m) { @@ -299,8 +302,8 @@ static void GM_command (int c) { 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;timerlen = int2host(snd->len); - snd->rate = int2host(snd->rate); - snd->lstart = int2host(snd->lstart); - snd->llen = int2host(snd->llen); - } - return snd; + s[0] = 'D'; + s[1] = 'S'; + strncpy(&s[2], n, 6); + return S_load(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; +int Z_sound (void *s, int v) { + if (s != NULL) { + S_play(s, 0, v); + // TODO ??? + //S_play(s, -1, 1024, v); + //return F_getreslen(((int*)s)[-1])/605; + return 0; + } else { + return 0; + } } #define GAS_START (MN__LAST-MN_DEMON+5) diff --git a/src/music.c b/src/music.c deleted file mode 100644 index ddd74b0..0000000 --- a/src/music.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - 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 "music.h" -#include "error.h" -#include "game.h" -#include -#include - -short mus_vol = 50; -char music_random = ON; -int music_time = 3; -int music_fade = 5; - -static Uint32 muscount; -static Mix_Music * muslo; -static int musdisabled = 1; -static int volsetcount = 0; - -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) { - if (SDL_WasInit(SDL_INIT_AUDIO)) { - 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); - } -} - -static 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} -}; - -static 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; -} - -static 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/sdlmixer/sound.c b/src/sdlmixer/sound.c new file mode 100644 index 0000000..026e01f --- /dev/null +++ b/src/sdlmixer/sound.c @@ -0,0 +1,217 @@ +#include "glob.h" +#include "sound.h" +#include "music.h" +#include "misc.h" // int2host +#include "memory.h" // M_lock M_unlock +#include "files.h" // F_findres +#include "error.h" + +#include +#include +#include + +#define TAG_MIX1 0x4d495831 + +#pragma pack(1) +struct dmi { + Uint32 len; // length [bytes] + Uint32 rate; // freq [Hz] + Uint32 lstart; // loop start offset [bytes] + Uint32 llen; // loop length [bytes] + Uint8 data[]; // sound data +}; +#pragma pack() + +struct sound { + snd_t base; + Mix_Chunk *c; +}; + +short snd_vol; // public 0..128 + +static int devfreq = MIX_DEFAULT_FREQUENCY; +static Uint32 devformat = AUDIO_S16SYS; // MIX_DEFAULT_FORMAT +static int devchannels = 1; // MIX_DEFAULT_CHANNELS; +static int devchunksize = 1024; +static int devchunkchannels = 8; +static int devinit; + +/* music */ + +short mus_vol; +char music_random; +int music_time; +int music_fade; + +void S_initmusic (void) { + +} + +void S_donemusic (void) { + +} + +void S_startmusic (int time) { + +} + +void S_stopmusic (void) { + +} + +void S_volumemusic (int v) { + +} + +void F_loadmus (char n[8]) { + +} + +void F_freemus (void) { + +} + +void S_updatemusic (void) { + +} + +/* sound */ + +void S_init (void) { + assert(devinit == 0); + logo("S_init: initialize sound\n"); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) == 0) { + if (Mix_OpenAudio(devfreq, devformat, devchannels, devchunksize) == 0) { + Mix_AllocateChannels(devchunkchannels); + devinit = 1; + } else { + logo("S_init: Mix_OpenAudio: %s\n", Mix_GetError()); + } + } else { + logo("S_init: SDL_InitSubSytem: %s\n", SDL_GetError()); + } +} + +static Mix_Chunk *convert_this (int rate, const Uint8 *buf, int len) { + SDL_AudioCVT cvt; + Mix_Chunk *c = NULL; + if (SDL_BuildAudioCVT(&cvt, AUDIO_S8, 1, rate, devformat, devchannels, devfreq) != -1) { + int maxlen = len * cvt.len_mult; + Uint8 *maxbuf = malloc(maxlen); + if (maxbuf != NULL) { + memcpy(maxbuf, buf, len); + cvt.buf = maxbuf; + cvt.len = len; + if (SDL_ConvertAudio(&cvt) == 0) { + c = malloc(sizeof(Mix_Chunk)); + if (c != NULL) { + c->allocated = 0; + c->abuf = maxbuf; + c->alen = len * cvt.len_ratio; + c->volume = MIX_MAX_VOLUME; + } else { + free(maxbuf); + } + } else { + free(maxbuf); + } + } + } + return c; +} + +// TODO load raw sounds with voices + +snd_t *S_get (int id) { + if (!devinit) { + return NULL; + } + struct dmi *snd = M_lock(id); + struct sound *res = NULL; + if (snd != NULL) { + int rlen = F_getreslen(id); + if (rlen > 16) { + Uint32 len = int2host(snd->len); + Uint32 rate = int2host(snd->rate); + Uint32 lstart = int2host(snd->lstart); + Uint32 llen = int2host(snd->llen); + if (len <= rlen - 8 && lstart + llen <= rlen - 16) { + Mix_Chunk *c = convert_this(rate, snd->data, len); + if (c != NULL) { + res = malloc(sizeof(struct sound)); + if (res != NULL) { + res->base.tag = TAG_MIX1; + res->c = c; + // TODO loops + } else { + free(c); + } + } + } else { + logo("S_get(%i): invalid header {len=%u:rate=%u:lstart=%u:llen=%u:rlen=%i}\n", id, len, rate, lstart, llen, rlen); + } + } else { + logo("S_load(%i): too short\n", id); + } + M_unlock(snd); + } else { + logo("S_load(%i): not found\n", id); + } + return (snd_t*)res; +} + +snd_t *S_load (const char name[8]) { + int id = F_findres(name); + return S_get(id); +} + +short S_play (snd_t *s, short c, short v) { + assert(c >= 0 && c <= 8); + assert(v >= 0 && v <= 255); + short channel = 0; + if (devinit) { + if (s) { + struct sound *snd = (struct sound *)s; + assert(snd->base.tag == TAG_MIX1); + // TODO care about global volume level + snd->c->volume = v * MIX_MAX_VOLUME / 255; + channel = Mix_PlayChannel(c <= 0 ? -1 : c - 1, snd->c, 0); + channel = channel == -1 ? 0 : channel + 1; + } + } + return channel; +} + +void S_stop (short c) { + assert(c >= 0 && c <= 8); + if (devinit) { + if (c > 0) { + Mix_HaltChannel(c - 1); + } + } +} + +void S_volume (int v) { + snd_vol = min(max(v, 0), 128); + if (devinit) { + // TODO change relativelly for every channel + Mix_Volume(-1, v * MIX_MAX_VOLUME / 128); + } +} + +void S_wait (void) { + if (devinit) { + while (Mix_Playing(-1) > 0) { + SDL_Delay(10); + } + } +} + +void S_done (void) { + if (devinit) { + // TODO free memory + Mix_AllocateChannels(0); + Mix_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } +} diff --git a/src/sound.c b/src/sound.c deleted file mode 100644 index 4a4077d..0000000 --- a/src/sound.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - 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 "error.h" -#include -#include - -#define NUM_CHANNELS 16 -#define NUM_CHUNKS 300 - -short snd_vol = 50; - -static int snddisabled = 1; -static struct { - snd_t *s; - Mix_Chunk *c; -} chunks[NUM_CHUNKS]; - -void S_init (void) { - logo("S_init: настройка звука\n"); - 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 (void) { - 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 (void) { - if (snddisabled) return; - while (Mix_Playing(-1)) { - SDL_Delay(10); - } -} diff --git a/src/sound.h b/src/sound.h index 5f71e34..ca2e044 100644 --- a/src/sound.h +++ b/src/sound.h @@ -27,33 +27,41 @@ #ifndef SOUND_H_INCLUDED #define SOUND_H_INCLUDED -// заголовок инструмента (DMI) -#pragma pack(1) typedef struct { - unsigned int len; // длина в байтах - unsigned int rate; // частота в Гц. - unsigned int lstart; // начало повтора в байтах от начала данных - unsigned int llen; // длина повтора в байтах + int tag; } snd_t; -#pragma pack() -// громкость звука и музыки (0-128) +// Sound volume 0..128 extern short snd_vol; +// Get sound handle for resource +snd_t *S_get (int id); + +// Get sound handle for resource with name +snd_t *S_load (const char name[8]); + +// Initialize sound subsystem void S_init (void); + +// Deinitialize sound subsystem 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); +// Play sound on channel with volume . +// = sound handle (NULL is ignored) +// = 1..8 or 0 for any free +// = 0..255 +// return used channel or zero on error +short S_play (snd_t *s, short c, short v); -// остановить звук на канале c (1-8) +// Stop sound on channel +// = 0..8 (0 ignored) void S_stop (short c); +// Set sound volume to , also affects variable snd_vol +// = 0..128 void S_volume (int v); -void free_chunks (void); + +// Wait before all sounds end playing void S_wait (void); #endif /* SOUND_H_INCLUDED */ diff --git a/src/view.c b/src/view.c index 1819698..77985e1 100644 --- a/src/view.c +++ b/src/view.c @@ -102,7 +102,6 @@ void W_init (void) { PL_init(); MN_init(); R_loadsky(1); - free_chunks(); } static void unpack (void *buf, int len, void *obuf) { -- 2.29.2 From a71064c15b1d4ffd4c231deb08de711666963d5b Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 22 Mar 2020 12:13:54 +0300 Subject: [PATCH 15/16] sdl: fix linking on linux --- src/sdl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/main.c b/src/sdl/main.c index ef757fc..48aa507 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -214,7 +214,7 @@ static void poll_events (void (*h)(int key, int down)) { } } -int SDL_main (int argc, char *argv[]) { +int main (int argc, char *argv[]) { char *pw; Uint32 t, ticks; logo("main: initialize SDL\n"); -- 2.29.2 From 7e3cef6902ee44ffebb5319fdcf720cb4ef7a1f3 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Mon, 23 Mar 2020 14:56:01 +0300 Subject: [PATCH 16/16] sound: add openal sound driver --- src/CMakeLists.txt | 49 +++++--- src/openal/sound.c | 280 +++++++++++++++++++++++++++++++++++++++++++++ src/sdl/main.c | 2 +- 3 files changed, 316 insertions(+), 15 deletions(-) create mode 100644 src/openal/sound.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9558278..e33b832 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,24 +3,44 @@ project(doom2d C) option(WITH_OPENGL "Build with OpenGL render" ON) option(WITH_SOFTWARE "Build with Software render" ON) +option(SOUND_DRIVER "Build with selected sound driver" "OpenAL") + +set(WITH_OPENAL (SOUND_DRIVER EQUALS "OpenAL")) +set(WITH_SDLMIXER (SOUND_DRIVER EQUALS "SDL_mixer")) set(D2D_GAME_ROOT .) set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl) set(D2D_SOFTWARE_ROOT ${D2D_GAME_ROOT}/soft) set(D2D_SDL_ROOT ${D2D_GAME_ROOT}/sdl) set(D2D_SDLMIXER_ROOT ${D2D_GAME_ROOT}/sdlmixer) - -find_package(SDL REQUIRED) -find_package(SDL_mixer REQUIRED) -if (WITH_OPENGL) - find_package(OpenGL REQUIRED) -endif (WITH_OPENGL) +set(D2D_OPENAL_ROOT ${D2D_GAME_ROOT}/openal) aux_source_directory(${D2D_GAME_ROOT} D2D_GAME_SRC) aux_source_directory(${D2D_OPENGL_ROOT} D2D_OPENGL_SRC) aux_source_directory(${D2D_SOFTWARE_ROOT} D2D_SOFTWARE_SRC) aux_source_directory(${D2D_SDL_ROOT} D2D_SDL_SRC) aux_source_directory(${D2D_SDLMIXER_ROOT} D2D_SDLMIXER_SRC) +aux_source_directory(${D2D_OPENAL_ROOT} D2D_OPENAL_SRC) + +find_package(SDL REQUIRED) +message(STATUS "sound::${SOUND_DRIVER}") +if(WITH_OPENAL) + find_package(OpenAL REQUIRED) + set(D2D_SOUND_SRC "${D2D_OPENAL_SRC}") + set(D2D_SOUND_INCLUDE_DIR "${OPENAL_INCLUDE_DIR}") + set(D2D_SOUND_LIBRARY "${OPENAL_LIBRARY}") +elseif(WITH_SDLMIXER) + find_package(SDL_mixer REQUIRED) + set(D2D_SOUND_SRC "${D2D_SDLMIXER_SRC}") + set(D2D_SOUND_INCLUDE_DIR "${SDLMIXER_INCLUDE_DIR}") + set(D2D_SOUND_LIBRARY "${SDLMIXER_LIBRARY}") +else(WITH_OPENAL) + message(FATAL_ERROR "Select SOUND_DRIVER as OpenAL or SDL_mixer") +endif(WITH_OPENAL) + +if (WITH_OPENGL) + find_package(OpenGL REQUIRED) +endif (WITH_OPENGL) if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) @@ -33,21 +53,22 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") message(STATUS "=== BUILD OPTIONS ===") -message(STATUS "BUILD: " ${CMAKE_BUILD_TYPE}) -message(STATUS "CFLAGS: " ${CMAKE_C_FLAGS}) +message(STATUS "BUILD: " "${CMAKE_BUILD_TYPE}") +message(STATUS "CFLAGS: " "${CMAKE_C_FLAGS}") +message(STATUS "SOUND: " "${SOUND_DRIVER}") message(STATUS "=== RENDERS ===") message(STATUS "SOFTWARE: " ${WITH_SOFTWARE}) message(STATUS "OPENGL: " ${WITH_OPENGL}) if (WITH_OPENGL) - add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_OPENGL_SRC}) - target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}") - target_link_libraries(doom2d-gl "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}" "${OPENGL_LIBRARY}") + add_executable(doom2d-gl ${D2D_GAME_SRC} ${D2D_SOUND_SRC} ${D2D_SDL_SRC} ${D2D_OPENGL_SRC}) + target_include_directories(doom2d-gl PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_INCLUDE_DIR}" "${SDL_INCLUDE_DIR}" "${OPENGL_INCLUDE_DIR}") + target_link_libraries(doom2d-gl "${D2D_SOUND_LIBRARY}" "${SDL_LIBRARY}" "${OPENGL_LIBRARY}") endif (WITH_OPENGL) if (WITH_SOFTWARE) - add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SDL_SRC} ${D2D_SDLMIXER_SRC} ${D2D_SOFTWARE_SRC}) - target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${SDL_INCLUDE_DIR}" "${SDLMIXER_INCLUDE_DIR}") - target_link_libraries(doom2d-soft "${SDL_LIBRARY}" "${SDLMIXER_LIBRARY}") + add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SOUND_SRC} ${D2D_SDL_SRC} ${D2D_SOFTWARE_SRC}) + target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_LIBRARY}" "${SDL_INCLUDE_DIR}") + target_link_libraries(doom2d-soft "${D2D_SOUND_LIBRARY}" "${SDL_LIBRARY}") endif (WITH_SOFTWARE) diff --git a/src/openal/sound.c b/src/openal/sound.c new file mode 100644 index 0000000..af75aa3 --- /dev/null +++ b/src/openal/sound.c @@ -0,0 +1,280 @@ +#include "sound.h" +#include "music.h" + +#include "files.h" // F_findres F_getreslen +#include "memory.h" // M_lock M_unlock +#include "misc.h" // int2host +#include "error.h" // logo + +#include +#include +#include // SDL_BuildAudioCVT SDL_ConvertAudio +#include +#include // malloc +#include // memcpy + +#define TAG_OAL1 0x4F414C31 +#define MAX_CHANNELS 8 + +#pragma pack(1) +typedef struct dmi { + dword len; + dword rate; + dword lstart; + dword llen; + byte data[]; +} dmi; +#pragma pack() + +typedef struct openal_snd { + snd_t base; + ALuint buffer; +} openal_snd; + +typedef struct openal_channel { + ALuint source; +} openal_channel; + +short snd_vol; +short mus_vol; +char music_random; +int music_time; +int music_fade; + +static ALCdevice *device; +static ALCcontext *context; +static ALuint sources[MAX_CHANNELS]; + +/* Music */ + +void S_initmusic (void) { + +} + +void S_donemusic (void) { + +} + +void S_startmusic (int time) { + +} + +void S_stopmusic (void) { + +} + +void S_volumemusic (int v) { + +} + +void F_loadmus (char n[8]) { + +} + +void F_freemus (void) { + +} + +void S_updatemusic (void) { + +} + +/* Sound */ + +static void convert_this_ext (Uint32 src_format, int src_chan, int src_rate, Uint32 dst_format, int dst_chan, int dst_rate, const void *buf, int len, void **maxbuf, int *maxlen) { + SDL_AudioCVT cvt; + *maxlen = 0; + *maxbuf = NULL; + if (SDL_BuildAudioCVT(&cvt, src_format, src_chan, src_rate, dst_format, dst_chan, dst_rate) != -1) { + *maxlen = len * cvt.len_mult; + *maxbuf = malloc(*maxlen); + if (*maxbuf != NULL) { + memcpy(*maxbuf, buf, len); + cvt.buf = *maxbuf; + cvt.len = len; + if (SDL_ConvertAudio(&cvt) == 0) { + *maxlen = len * cvt.len_ratio; + } else { + free(*maxbuf); + *maxbuf = NULL; + *maxlen = 0; + } + } + } +} + +static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dword lstart, dword llen) { + assert(data); + ALuint buffer = 0; + openal_snd *snd = NULL; + void *newdata = NULL; + int newlen = 0; + // for some reason 8bit formats makes psshshshsh + // TODO do this without SDL + convert_this_ext(AUDIO_S8, 1, rate, AUDIO_S16SYS, 1, rate, data, len, &newdata, &newlen); + if (newdata != NULL) { + alGenBuffers(1, &buffer); + if (alGetError() == AL_NO_ERROR) { + alBufferData(buffer, AL_FORMAT_MONO16, newdata, newlen, rate); + if (alGetError() == AL_NO_ERROR) { + snd = malloc(sizeof(openal_snd)); + if (snd != NULL) { + snd->base.tag = TAG_OAL1; + snd->buffer = buffer; + // TODO loops + } else { + alDeleteBuffers(1, &buffer); + } + } else { + alDeleteBuffers(1, &buffer); + } + } + free(newdata); + } + return snd; +} + +snd_t *S_get (int id) { + openal_snd *snd = NULL; + void *handle = M_lock(id); + if (context != NULL && handle != NULL) { + byte *data = handle; + dword len = F_getreslen(id); + dword rate = 8000; + dword lstart = 0; + dword llen = 0; + if (len > 16) { + dmi *hdr = handle; + dword hdr_len = int2host(hdr->len); + dword hdr_rate = int2host(hdr->rate); + dword hdr_lstart = int2host(hdr->lstart); + dword hdr_llen = int2host(hdr->llen); + if (hdr_len <= len - 8 && hdr_lstart + hdr_llen <= len - 16) { + data = hdr->data; + len = hdr_len; + rate = hdr_rate; + lstart = hdr_lstart; + llen = hdr_llen; + } + } + snd = new_openal_snd(data, len, rate, lstart, llen); + M_unlock(handle); + } + return (snd_t*)snd; +} + +snd_t *S_load (const char name[8]) { + return S_get(F_findres(name)); +} + +void S_init (void) { + assert(device == NULL && context == NULL); + const ALCint attrs[] = {ALC_MONO_SOURCES, MAX_CHANNELS, 0}; + device = alcOpenDevice(NULL); + if (device != NULL) { + context = alcCreateContext(device, attrs); + if (context != NULL) { + if (alcMakeContextCurrent(context)) { + alGenSources(MAX_CHANNELS, sources); + if (alGetError() == AL_NO_ERROR) { + alListenerf(AL_GAIN, 1); + alListener3f(AL_POSITION, 0, 0, 0); + alListener3f(AL_VELOCITY, 0, 0, 0); + } else { + logo("S_init: unable to create OpenAL sources\n"); + alcDestroyContext(context); + alcCloseDevice(device); + context = NULL; + device = NULL; + } + } else { + logo("S_init: unable to make OpenAL context current\n"); + alcDestroyContext(context); + alcCloseDevice(device); + context = NULL; + device = NULL; + } + } else { + logo("S_init: unable to create OpenAL context\n"); + alcCloseDevice(device); + device = NULL; + } + } else { + logo("S_init: unable to open OpenAL device\n"); + } +} + +void S_done (void) { + if (context != NULL) { + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + alcCloseDevice(device); + } + context = NULL; + device = NULL; +} + +short S_play (snd_t *s, short c, short v) { + assert(c >= 0 && c <= MAX_CHANNELS); + assert(v >= 0 && v < 256); + ALuint source; + ALint state; + int channel; + if (context != NULL && s != NULL) { + openal_snd *snd = (openal_snd*)s; + assert(snd->base.tag == TAG_OAL1); + if (c == 0) { + for (channel = 0; channel < MAX_CHANNELS; channel++) { + state = AL_PLAYING; + alGetSourcei(sources[channel], AL_SOURCE_STATE, &state); + if (state == AL_STOPPED || state == AL_INITIAL) { + break; // !!! + } + } + } else { + channel = c - 1; + } + if (channel < MAX_CHANNELS) { + source = sources[channel]; + alSourceStop(source); + alSourcei(source, AL_BUFFER, snd->buffer); + alSourcef(source, AL_PITCH, 1); + alSourcef(source, AL_GAIN, v / 255.0); + alSource3f(source, AL_POSITION, 0, 0, 0); + alSource3f(source, AL_VELOCITY, 0, 0, 0); + alSourcei(source, AL_LOOPING, AL_FALSE); + alSourcePlay(source); + } + } + return 0; +} + +void S_stop (short c) { + assert(c >= 0 && c <= MAX_CHANNELS); + if (context != NULL) { + if (c != 0) { + alSourceStop(sources[c - 1]); + } + } +} + +void S_volume (int v) { + assert(v >= 0 && v <= 128); + snd_vol = v; + if (context != NULL) { + alListenerf(AL_GAIN, v / 128.0); + } +} + +void S_wait (void) { + int i; + ALint state; + if (context != NULL) { + for (i = 0; i < MAX_CHANNELS; i++) { + do { + state = AL_STOPPED; + alGetSourcei(sources[i], AL_SOURCE_STATE, &state); + } while (state == AL_PLAYING); + } + } +} diff --git a/src/sdl/main.c b/src/sdl/main.c index 48aa507..15ce855 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -277,8 +277,8 @@ int main (int argc, char *argv[]) { } CFG_save(); R_done(); - S_done(); S_donemusic(); + S_done(); M_shutdown(); SDL_Quit(); return 0; -- 2.29.2