diff --git a/code/Am_map.c b/code/Am_map.c index cb36ad1367..5ad5da0dc4 100644 --- a/code/Am_map.c +++ b/code/Am_map.c @@ -81,7 +81,7 @@ cvar_t *am_overlay; cvar_t *am_showsecrets, *am_showmonsters, *am_showtime; // drawing stuff -#define FB (screens[0]) +#define FB (screen) #define AM_PANDOWNKEY KEY_DOWNARROW #define AM_PANUPKEY KEY_UPARROW @@ -278,7 +278,6 @@ static cheatseq_t cheat_amap = { cheat_amap_seq, 0 }; static BOOL stopped = true; extern BOOL viewactive; -//extern byte screens[][SCREENWIDTH*SCREENHEIGHT]; void AM_rotatePoint (fixed_t *x, fixed_t *y); @@ -394,11 +393,11 @@ void AM_findMinMaxBoundaries(void) min_w = 2*PLAYERRADIUS; // const? never changed? min_h = 2*PLAYERRADIUS; - a = FixedDiv((screens[0].width)<colors; else palette = NULL; @@ -516,7 +515,7 @@ void AM_initColors (BOOL overlayed) if (b < 0) b += 32; - if (screens[0].is8bit) + if (screen.is8bit) AlmostBackground = BestColor (DefaultPalette->basecolors, r, g , b, DefaultPalette->numcolors); else AlmostBackground = MAKERGB(r,g,b); @@ -721,19 +720,19 @@ BOOL AM_Responder (event_t *ev) case AM_FOLLOWKEY: followplayer = !followplayer; f_oldloc.x = MAXINT; - Printf (PRINT_HIGH, followplayer ? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF); + Printf (PRINT_HIGH, "%s\n", followplayer ? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF); break; case AM_GRIDKEY: grid = !grid; - Printf (PRINT_HIGH, grid ? AMSTR_GRIDON : AMSTR_GRIDOFF); + Printf (PRINT_HIGH, "%s\n", grid ? AMSTR_GRIDON : AMSTR_GRIDOFF); break; case AM_MARKKEY: - Printf (PRINT_HIGH, "%s %d", AMSTR_MARKEDSPOT, markpointnum); + Printf (PRINT_HIGH, "%s %d\n", AMSTR_MARKEDSPOT, markpointnum); AM_addMark(); break; case AM_CLEARMARKKEY: AM_clearMarks(); - Printf (PRINT_HIGH, AMSTR_MARKSCLEARED); + Printf (PRINT_HIGH, "%s\n", AMSTR_MARKSCLEARED); break; default: cheatstate=0; @@ -836,7 +835,7 @@ void AM_clearFB (int color) { int y; - if (screens[0].is8bit) { + if (screen.is8bit) { if (f_w == f_p) memset (fb, color, f_w*f_h); else @@ -1013,7 +1012,7 @@ void AM_drawFline (fline_t *fl, int color) if (ax > ay) { d = ay - ax/2; - if (screens[0].is8bit) { + if (screen.is8bit) { while (1) { PUTDOTP(x,y,(byte)color); if (x == fl->b.x) @@ -1040,7 +1039,7 @@ void AM_drawFline (fline_t *fl, int color) } } else { d = ax - ay/2; - if (screens[0].is8bit) { + if (screen.is8bit) { while (1) { PUTDOTP(x, y, (byte)color); if (y == fl->b.y) @@ -1298,7 +1297,7 @@ void AM_drawPlayers(void) if (p->powers[pw_invisibility]) color = AlmostBackground; - else if (screens[0].is8bit) + else if (screen.is8bit) color = BestColor (DefaultPalette->basecolors, RPART(p->userinfo.color), GPART(p->userinfo.color), @@ -1391,14 +1390,14 @@ void AM_Drawer (void) if (!automapactive) return; - fb = screens[0].buffer; + fb = screen.buffer; if (!viewactive) { // [RH] Set f_? here now to handle automap overlaying // and view size adjustments. f_x = f_y = 0; - f_w = screens[0].width; + f_w = screen.width; f_h = ST_Y; - f_p = screens[0].pitch; + f_p = screen.pitch; AM_clearFB(Background); } else { @@ -1406,7 +1405,7 @@ void AM_Drawer (void) f_y = viewwindowy; f_w = realviewwidth; f_h = realviewheight; - f_p = screens[0].pitch; + f_p = screen.pitch; } AM_activateNewScale(); @@ -1446,7 +1445,7 @@ void AM_Drawer (void) sprintf (line, TEXTCOLOR_RED "SECRETS:" TEXTCOLOR_NORMAL " %d / %d", level.found_secrets, level.total_secrets); - V_DrawTextClean (CR_GREY, screens[0].width - V_StringWidth (line) * CleanXfac, y, line); + V_DrawTextClean (CR_GREY, screen.width - V_StringWidth (line) * CleanXfac, y, line); } y += height; @@ -1468,7 +1467,7 @@ void AM_Drawer (void) if (am_showtime->value) { sprintf (line, " %02d:%02d:%02d", time/3600, (time%3600)/60, time%60); // Time - V_DrawTextClean (CR_RED, screens[0].width - V_StringWidth (line) * CleanXfac, y, line); + V_DrawTextClean (CR_RED, screen.width - V_StringWidth (line) * CleanXfac, y, line); } } diff --git a/code/C_cmds.c b/code/C_cmds.c index 21d35ba978..998ce43263 100644 --- a/code/C_cmds.c +++ b/code/C_cmds.c @@ -3,6 +3,12 @@ #include #include +#ifdef _WIN32 +#include +#else +#include +#endif + #include "version.h" #include "c_consol.h" #include "c_cmds.h" @@ -113,6 +119,7 @@ struct CmdDispatcher CmdList[] = { { "stop", Cmd_Stop }, { "soundlist", Cmd_Soundlist }, { "soundlinks", Cmd_Soundlinks }, + { "dir", Cmd_Dir }, { NULL } }; @@ -283,13 +290,13 @@ void Cmd_idmus (player_t *plyr, int argc, char **argv) char *map; int l; - Printf (PRINT_HIGH, STSTR_NOMUS); if (argc > 1) { if (gamemode == commercial) { l = atoi (argv[1]); if (l <= 99) map = CalcMapName (0, l); else { + Printf (PRINT_HIGH, "%s\n", STSTR_NOMUS); return; } } else { @@ -301,7 +308,8 @@ void Cmd_idmus (player_t *plyr, int argc, char **argv) S_ChangeMusic (info->music, 1); Printf (PRINT_HIGH, "%s\n", STSTR_MUS); } - } + } else + Printf (PRINT_HIGH, "%s\n", STSTR_NOMUS); } } @@ -442,3 +450,56 @@ void Cmd_Error (player_t *plyr, int argc, char **argv) free (text); I_Error (textcopy); } + +void Cmd_Dir (player_t *plyr, int argc, char **argv) +{ + char dir[256], curdir[256]; + char *match; + findstate_t c_file; + long file; + + if (!getcwd (curdir, 256)) { + Printf (PRINT_HIGH, "Current path too long\n"); + return; + } + + if (argc == 1 || chdir (argv[1])) { + match = argc == 1 ? "./*" : argv[1]; + + ExtractFilePath (match, dir); + if (dir[0]) { + match += strlen (dir); + } else { + dir[0] = '.'; + dir[1] = '/'; + dir[2] = '\0'; + } + if (!match[0]) + match = "*"; + + if (chdir (dir)) { + Printf (PRINT_HIGH, "%s not found\n", dir); + return; + } + } else { + match = "*"; + strcpy (dir, argv[1]); + if (dir[strlen(dir) - 1] != '/') + strcat (dir, "/"); + } + + if ( (file = I_FindFirst (match, &c_file)) == -1) + Printf (PRINT_HIGH, "Nothing matching %s%s\n", dir, match); + else { + Printf (PRINT_HIGH, "Listing of %s%s:\n", dir, match); + do { + if (I_FindAttr (&c_file) & FA_DIREC) + Printf_Bold ("%s \n", I_FindName (&c_file)); + else + Printf (PRINT_HIGH, "%s\n", I_FindName (&c_file)); + } while (I_FindNext (file, &c_file) == 0); + I_FindClose (file); + } + + chdir (curdir); +} diff --git a/code/D_dehack.c b/code/D_dehack.c index 9116edc169..04e2c0385d 100644 --- a/code/D_dehack.c +++ b/code/D_dehack.c @@ -246,6 +246,8 @@ char *SoundMap[] = { // Functions used in a .bex [CODEPTR] chunk void A_FireRailgun(player_t*, pspdef_t*); +void A_FireRailgunLeft(player_t*, pspdef_t*); +void A_FireRailgunRight(player_t*, pspdef_t*); void A_RailWait(player_t*, pspdef_t*); void A_Light0(player_t*, pspdef_t*); void A_WeaponReady(player_t*, pspdef_t*); @@ -321,6 +323,10 @@ void A_BrainSpit(mobj_t*); void A_SpawnSound(mobj_t*); void A_SpawnFly(mobj_t*); void A_BrainExplode(mobj_t*); +void A_Die(mobj_t*); +void A_Detonate(mobj_t*); +void A_Mushroom(mobj_t*); +void A_MonsterRail(mobj_t*); struct CodePtr { char *name; @@ -329,7 +335,10 @@ struct CodePtr { static const struct CodePtr CodePtrs[] = { { "NULL", {(actionf_p1)NULL} }, + { "MonsterRail", {(actionf_p1)A_MonsterRail} }, { "FireRailgun", {(actionf_p1)A_FireRailgun} }, + { "FireRailgunLeft",{(actionf_p1)A_FireRailgunLeft} }, + { "FireRailgunRight",{(actionf_p1)A_FireRailgunRight} }, { "RailWait", {(actionf_p1)A_RailWait} }, { "Light0", {(actionf_p1)A_Light0} }, { "WeaponReady", {(actionf_p1)A_WeaponReady} }, @@ -405,6 +414,9 @@ static const struct CodePtr CodePtrs[] = { { "SpawnSound", {(actionf_p1)A_SpawnSound} }, { "SpawnFly", {(actionf_p1)A_SpawnFly} }, { "BrainExplode", {(actionf_p1)A_BrainExplode} }, + { "Die", {(actionf_p1)A_Die} }, + { "Detonate", {(actionf_p1)A_Detonate} }, + { "Mushroom", {(actionf_p1)A_Mushroom} }, { NULL, } }; diff --git a/code/D_main.c b/code/D_main.c index 3320117208..eaef531258 100644 --- a/code/D_main.c +++ b/code/D_main.c @@ -229,8 +229,8 @@ void D_Display (void) // [RH] change the screen mode if needed if (setmodeneeded) { - int oldwidth = screens[0].width; - int oldheight = screens[0].height; + int oldwidth = screen.width; + int oldheight = screen.height; int oldid = DisplayID; // Change screen mode. @@ -269,7 +269,7 @@ void D_Display (void) // save the current screen if about to wipe BorderNeedRefresh = true; wipe = true; - wipe_StartScreen(0, 0, screens[0].width, screens[0].height); + wipe_StartScreen(0, 0, screen.width, screen.height); wipegamestate = gamestate; } else @@ -317,7 +317,7 @@ void D_Display (void) int y; y = (automapactive && !viewactive) ? 4 : viewwindowy + 4; - V_DrawPatchCleanNoMove((screens[0].width-(pause->width)*CleanXfac)/2,y,&screens[0],pause); + V_DrawPatchCleanNoMove((screen.width-(pause->width)*CleanXfac)/2,y,&screen,pause); } // [RH] Draw icon, if any @@ -329,7 +329,7 @@ void D_Display (void) patch_t *p = W_CacheLumpNum (lump, PU_CACHE); V_DrawPatchIndirect (160-SHORT(p->width)/2, 100-SHORT(p->height)/2, - &screens[0], p); + &screen, p); } NoWipe = 10; } @@ -346,7 +346,7 @@ void D_Display (void) int wipestart, nowtime, tics; BOOL done; - wipe_EndScreen(0, 0, screens[0].width, screens[0].height); + wipe_EndScreen(0, 0, screen.width, screen.height); I_FinishUpdateNoBlit (); wipestart = I_GetTime () - 1; @@ -361,7 +361,7 @@ void D_Display (void) wipestart = nowtime; I_BeginUpdate (); done = wipe_ScreenWipe(wipe_Melt, - 0, 0, screens[0].width, screens[0].height, tics); + 0, 0, screen.width, screen.height, tics); C_DrawConsole (); M_Drawer (); // menu is drawn even on top of wipes I_FinishUpdate (); // page flip or blit buffer @@ -487,7 +487,7 @@ void D_PageTicker (void) // void D_PageDrawer (void) { - V_DrawPatchIndirect (0,0, &screens[0], W_CacheLumpName(pagename, PU_CACHE)); + V_DrawPatchIndirect (0,0, &screen, W_CacheLumpName(pagename, PU_CACHE)); } @@ -1021,24 +1021,49 @@ void D_DoomMain (void) { cvar_t *var = cvar ("transsouls", "0.75", CVAR_ARCHIVE|CVAR_CALLBACK); var->u.callback = TransSoulsCallback; + TransSoulsCallback (var); } FindResponseFile (); DoLooseFiles(); // Ty 08/29/98 - handle "loose" files on command line { - // [RH] Make sure zdoom.wad is always loaded, since - // it contains stuff we need. + // [RH] Make sure zdoom.wad is always loaded, + // as it contains stuff we need. char *zdoomwad = Z_Malloc (strlen (progdir) + 10, PU_STATIC, 0); sprintf (zdoomwad, "%szdoom.wad", progdir); D_AddFile (zdoomwad); sprintf (zdoomwad, "%szvox.wad", progdir); D_AddFile (zdoomwad); + Z_Free (zdoomwad); } I_SetTitleString (IdentifyVersion ()); + // [RH] Add any .wad files in the skins directory + { + char skinname[256]; + findstate_t findstate; + long handle; + int stuffstart; + + stuffstart = sprintf (skinname, "%sskins/", progdir); + strcpy (skinname + stuffstart, "*.wad"); + if ((handle = I_FindFirst (skinname, &findstate)) != -1) + { + do + { + if (!(I_FindAttr (&findstate) & FA_DIREC)) + { + strcpy (skinname + stuffstart, I_FindName (&findstate)); + D_AddFile (skinname); + } + } while (I_FindNext (handle, &findstate) == 0); + I_FindClose (handle); + } + } + modifiedgame = false; p = M_CheckParm ("-file"); diff --git a/code/F_finale.c b/code/F_finale.c index ad326a5356..925ab530bf 100644 --- a/code/F_finale.c +++ b/code/F_finale.c @@ -26,7 +26,6 @@ #include #include -// Functions. #include "i_system.h" #include "m_swap.h" #include "z_zone.h" @@ -34,20 +33,11 @@ #include "v_text.h" #include "w_wad.h" #include "s_sound.h" - -// Data. #include "dstrings.h" - #include "doomstat.h" #include "r_state.h" - #include "hu_stuff.h" -// ? -//#include "doomstat.h" -//#include "r_local.h" -//#include "f_finale.h" - // Stage of animation: // 0 = text, 1 = art screen, 2 = character cast unsigned int finalestage; @@ -56,7 +46,6 @@ int finalecount; #define TEXTSPEED 2 #define TEXTWAIT 250 -static int TextSpeed; // [RH] Var for (ha ha) compatibility with old demos char* finaletext; char* finaleflat; @@ -107,8 +96,8 @@ void F_StartFinale (char *music, char *flat, char *text) finalestage = 0; finalecount = 0; - - TextSpeed = TEXTSPEED; + V_SetBlend (0,0,0,0); + S_StopAllChannels (); } @@ -139,8 +128,8 @@ void F_Ticker (void) break; if (i < MAXPLAYERS) { - if (finalecount < (signed)(strlen (finaletext)*TextSpeed)) { - finalecount = strlen (finaletext)*TextSpeed; + if (finalecount < (signed)(strlen (finaletext)*TEXTSPEED)) { + finalecount = strlen (finaletext)*TEXTSPEED; } else { if (!strncmp (level.nextmap, "EndGame", 7)) { if (level.nextmap[7] == 'C') { @@ -189,10 +178,10 @@ void F_TextWrite (void) // erase the entire screen to a tiled background { int lump = R_FlatNumForName (finaleflat) + firstflat; - V_FlatFill (0,0,screens[0].width,screens[0].height,&screens[0], + V_FlatFill (0,0, screen.width, screen.height, &screen, W_CacheLumpNum (lump, PU_CACHE)); } - V_MarkRect (0, 0, screens[0].width, screens[0].height); + V_MarkRect (0, 0, screen.width, screen.height); // draw some of the text onto the screen cx = 10; @@ -202,7 +191,7 @@ void F_TextWrite (void) if (finalecount < 11) return; - count = (finalecount - 10)/TextSpeed; + count = (finalecount - 10)/TEXTSPEED; for ( ; count ; count-- ) { c = *ch++; @@ -223,9 +212,9 @@ void F_TextWrite (void) } w = SHORT (hu_font[c]->width); - if (cx+w > screens[0].width) + if (cx+w > screen.width) break; - V_DrawPatchClean(cx, cy, &screens[0], hu_font[c]); + V_DrawPatchClean(cx, cy, &screen, hu_font[c]); cx+=w; } @@ -489,19 +478,6 @@ BOOL F_CastResponder (event_t* ev) return true; } - -void F_CastPrint (char *text) -{ - char text2[80], *t2 = text2; - - while (*text) - *t2++ = *text++ ^ 0x80; - *t2 = 0; - V_DrawTextClean (CR_RED, - (screens[0].width - V_StringWidth (text2) * CleanXfac) >> 1, - (screens[0].height * 180) / 200, text2); -} - int V_DrawPatchFlipped (int, int, screen_t *, patch_t *); // // F_CastDrawer @@ -515,21 +491,23 @@ void F_CastDrawer (void) patch_t* patch; // erase the entire screen to a background - V_DrawPatchIndirect (0,0,&screens[0], W_CacheLumpName ("BOSSBACK", PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen, W_CacheLumpName ("BOSSBACK", PU_CACHE)); - F_CastPrint (castorder[castnum].name); + V_DrawTextClean (CR_RED, + (screen.width - V_StringWidth (castorder[castnum].name) * CleanXfac)/2, + (screen.height * 180) / 200, castorder[castnum].name); // draw the current frame in the middle of the screen sprdef = &sprites[castsprite]; - sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK]; + sprframe = &sprdef->spriteframes[caststate->frame & FF_FRAMEMASK]; lump = sprframe->lump[0]; flip = (BOOL)sprframe->flip[0]; patch = W_CacheLumpNum (lump, PU_CACHE); if (flip) - V_DrawPatchFlipped (160,170,&screens[0],patch); + V_DrawPatchFlipped (160,170,&screen,patch); else - V_DrawPatchIndirect (160,170,&screens[0],patch); + V_DrawPatchIndirect (160,170,&screen,patch); } @@ -653,7 +631,7 @@ void F_BunnyScroll (void) p1 = W_CacheLumpName ("PFUB2", PU_LEVEL); p2 = W_CacheLumpName ("PFUB1", PU_LEVEL); - V_MarkRect (0, 0, screens[0].width, screens[0].height); + V_MarkRect (0, 0, screen.width, screen.height); scrolled = 320 - (finalecount-230)/2; if (scrolled > 320) @@ -664,9 +642,9 @@ void F_BunnyScroll (void) for ( x=0 ; x<320 ; x++) { if (x+scrolled < 320) - F_DrawPatchCol (x, p1, x+scrolled, &screens[0]); + F_DrawPatchCol (x, p1, x+scrolled, &screen); else - F_DrawPatchCol (x, p2, x+scrolled - 320, &screens[0]); + F_DrawPatchCol (x, p2, x+scrolled - 320, &screen); } if (finalecount < 1130) @@ -674,7 +652,7 @@ void F_BunnyScroll (void) if (finalecount < 1180) { V_DrawPatchIndirect ((320-13*8)/2, - (200-8*8)/2,&screens[0], W_CacheLumpName ("END0",PU_CACHE)); + (200-8*8)/2,&screen, W_CacheLumpName ("END0",PU_CACHE)); laststage = 0; return; } @@ -689,7 +667,7 @@ void F_BunnyScroll (void) } sprintf (name,"END%i",stage); - V_DrawPatchIndirect ((320-13*8)/2, (200-8*8)/2,&screens[0], W_CacheLumpName (name,PU_CACHE)); + V_DrawPatchIndirect ((320-13*8)/2, (200-8*8)/2,&screen, W_CacheLumpName (name,PU_CACHE)); } @@ -708,21 +686,21 @@ void F_Drawer (void) { case '1': if (gamemode == retail) - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("CREDIT",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("CREDIT",PU_CACHE)); else - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("HELP2",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE)); break; case '2': - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("VICTORY2",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("VICTORY2",PU_CACHE)); break; case '3': F_BunnyScroll (); break; case '4': - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("ENDPIC",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("ENDPIC",PU_CACHE)); break; default: - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("HELP2",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE)); break; } break; diff --git a/code/F_wipe.c b/code/F_wipe.c index 31dc9d35b6..60925bc263 100644 --- a/code/F_wipe.c +++ b/code/F_wipe.c @@ -176,7 +176,7 @@ int wipe_doMelt (int width, int height, int ticks) else if (y[i] < height) { dy = (y[i] < 16) ? y[i]+1 : 8; - dy = (dy * screens[0].height) / 200; + dy = (dy * screen.height) / 200; if (y[i]+dy >= height) dy = height - y[i]; s = &wipe_scr_end[i*height+y[i]]; d = &((short *)wipe_scr->buffer)[y[i]*(wipe_scr->pitch/2)+i]; @@ -214,7 +214,7 @@ int wipe_exitMelt (int width, int height, int ticks) int wipe_StartScreen (int x, int y, int width, int height) { - wipe_scr = &screens[0]; + wipe_scr = &screen; if (wipe_scr->is8bit) wipe_scr_start = (short *)Malloc (width * height); @@ -254,7 +254,7 @@ int wipe_ScreenWipe (int wipeno, int x, int y, int width, int height, int ticks) { go = 1; // wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG - wipe_scr = &screens[0]; + wipe_scr = &screen; (*wipes[wipeno*3])(width, height, ticks); } diff --git a/code/Info.c b/code/Info.c index e29c0b7c78..03571250c1 100644 --- a/code/Info.c +++ b/code/Info.c @@ -136,6 +136,8 @@ void A_BrainExplode(mobj_t*); void A_Ambient(mobj_t*); // [RH] Play ambient sound void P_RemoveMobj(mobj_t*); // [RH] Used by temporary switch mobj +void A_MonsterRail(mobj_t*); + state_t states[NUMSTATES] = { {SPR_TROO,0,-1,{NULL},S_NULL,0,0}, // S_NULL {SPR_SHTG,4,0,{A_Light0},S_NULL,0,0}, // S_LIGHTDONE diff --git a/code/M_menu.c b/code/M_menu.c index c79616e445..db2c098b55 100644 --- a/code/M_menu.c +++ b/code/M_menu.c @@ -584,7 +584,7 @@ void M_DrawLoad(void) { int i; - V_DrawPatchClean (72, 28, &screens[0], W_CacheLumpName ("M_LOADG",PU_CACHE)); + V_DrawPatchClean (72, 28, &screen, W_CacheLumpName ("M_LOADG",PU_CACHE)); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder (LoadDef.x, LoadDef.y+LINEHEIGHT*i, 24); @@ -602,15 +602,15 @@ void M_DrawSaveLoadBorder (int x, int y, int len) { int i; - V_DrawPatchClean (x-8, y+7, &screens[0], W_CacheLumpName ("M_LSLEFT",PU_CACHE)); + V_DrawPatchClean (x-8, y+7, &screen, W_CacheLumpName ("M_LSLEFT",PU_CACHE)); for (i = 0; i < len; i++) { - V_DrawPatchClean (x, y+7, &screens[0], W_CacheLumpName ("M_LSCNTR",PU_CACHE)); + V_DrawPatchClean (x, y+7, &screen, W_CacheLumpName ("M_LSCNTR",PU_CACHE)); x += 8; } - V_DrawPatchClean (x, y+7, &screens[0], W_CacheLumpName ("M_LSRGHT",PU_CACHE)); + V_DrawPatchClean (x, y+7, &screen, W_CacheLumpName ("M_LSRGHT",PU_CACHE)); } @@ -656,7 +656,7 @@ void M_DrawSave(void) { int i; - V_DrawPatchClean (72,28,&screens[0],W_CacheLumpName("M_SAVEG",PU_CACHE)); + V_DrawPatchClean (72,28,&screen,W_CacheLumpName("M_SAVEG",PU_CACHE)); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i,24); @@ -803,12 +803,12 @@ void M_DrawReadThis1(void) switch ( gamemode ) { case commercial: - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("HELP",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP",PU_CACHE)); break; case shareware: case registered: case retail: - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("HELP1",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP1",PU_CACHE)); break; default: break; @@ -829,11 +829,11 @@ void M_DrawReadThis2(void) case retail: case commercial: // This hack keeps us from having to change menus. - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("CREDIT",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("CREDIT",PU_CACHE)); break; case shareware: case registered: - V_DrawPatchIndirect (0,0,&screens[0],W_CacheLumpName("HELP2",PU_CACHE)); + V_DrawPatchIndirect (0,0,&screen,W_CacheLumpName("HELP2",PU_CACHE)); break; default: break; @@ -847,7 +847,7 @@ void M_DrawReadThis2(void) // void M_DrawMainMenu(void) { - V_DrawPatchClean (94,2,&screens[0],W_CacheLumpName("M_DOOM",PU_CACHE)); + V_DrawPatchClean (94,2,&screen,W_CacheLumpName("M_DOOM",PU_CACHE)); } @@ -858,8 +858,8 @@ void M_DrawMainMenu(void) // void M_DrawNewGame(void) { - V_DrawPatchClean (96,14,&screens[0],W_CacheLumpName("M_NEWG",PU_CACHE)); - V_DrawPatchClean (54,38,&screens[0],W_CacheLumpName("M_SKILL",PU_CACHE)); + V_DrawPatchClean (96,14,&screen,W_CacheLumpName("M_NEWG",PU_CACHE)); + V_DrawPatchClean (54,38,&screen,W_CacheLumpName("M_SKILL",PU_CACHE)); } void M_NewGame(int choice) @@ -884,7 +884,7 @@ int epi; void M_DrawEpisode(void) { - V_DrawPatchClean (54,38,&screens[0],W_CacheLumpName("M_EPISOD",PU_CACHE)); + V_DrawPatchClean (54,38,&screen,W_CacheLumpName("M_EPISOD",PU_CACHE)); } void M_VerifyNightmare(int ch) @@ -940,7 +940,7 @@ void M_Episode (int choice) // void M_DrawOptions(void) { - V_DrawPatchClean (108,15,&screens[0],W_CacheLumpName("M_OPTTTL",PU_CACHE)); + V_DrawPatchClean (108,15,&screen,W_CacheLumpName("M_OPTTTL",PU_CACHE)); } void M_Options(int choice) @@ -1006,6 +1006,8 @@ void M_ReadThis2(int choice) void M_FinishReadThis(int choice) { choice = 0; + drawSkull = true; + MenuStackDepth = 0; M_SetupNextMenu(&MainDef); } @@ -1121,7 +1123,7 @@ static void M_PlayerSetupDrawer (void) V_DrawPatchClean (160 - (SHORT(patch->width) >> 1), PSetupDef.y - (SHORT(patch->height) * 3), - &screens[0], patch); + &screen, patch); } // Draw player name box @@ -1142,10 +1144,10 @@ static void M_PlayerSetupDrawer (void) { int x = 320 - 88 - 32, y = PSetupDef.y + LINEHEIGHT*3 - 14; - x = (x-160)*CleanXfac+(screens[0].width>>1); - y = (y-100)*CleanYfac+(screens[0].height>>1); + x = (x-160)*CleanXfac+(screen.width>>1); + y = (y-100)*CleanYfac+(screen.height>>1); if (!FireGood) { - V_Clear (x, y, x + 72 * CleanXfac, y + 72 * CleanYfac, &screens[0], 34); + V_Clear (x, y, x + 72 * CleanXfac, y + 72 * CleanYfac, &screen, 34); } else { // [RH] The following fire code is based on the PTC fire demo int a, b; @@ -1213,11 +1215,11 @@ static void M_PlayerSetupDrawer (void) } y--; - pitch = screens[0].pitch; + pitch = screen.pitch; switch (CleanXfac) { case 1: for (b = 0; b < FireScreen.height; b++) { - byte *to = screens[0].buffer + y * screens[0].pitch + x; + byte *to = screen.buffer + y * screen.pitch + x; from = FireScreen.buffer + b * FireScreen.pitch; y += CleanYfac; @@ -1231,7 +1233,7 @@ static void M_PlayerSetupDrawer (void) case 2: for (b = 0; b < FireScreen.height; b++) { - byte *to = screens[0].buffer + y * screens[0].pitch + x; + byte *to = screen.buffer + y * screen.pitch + x; from = FireScreen.buffer + b * FireScreen.pitch; y += CleanYfac; @@ -1247,7 +1249,7 @@ static void M_PlayerSetupDrawer (void) case 3: for (b = 0; b < FireScreen.height; b++) { - byte *to = screens[0].buffer + y * screens[0].pitch + x; + byte *to = screen.buffer + y * screen.pitch + x; from = FireScreen.buffer + b * FireScreen.pitch; y += CleanYfac; @@ -1265,7 +1267,7 @@ static void M_PlayerSetupDrawer (void) case 4: default: for (b = 0; b < FireScreen.height; b++) { - byte *to = screens[0].buffer + y * screens[0].pitch + x; + byte *to = screen.buffer + y * screen.pitch + x; from = FireScreen.buffer + b * FireScreen.pitch; y += CleanYfac; @@ -1290,11 +1292,11 @@ static void M_PlayerSetupDrawer (void) V_ColorMap = translationtables + consoleplayer * 256; V_DrawTranslatedPatchClean (320 - 52 - 32, PSetupDef.y + LINEHEIGHT*3 + 46, - &screens[0], + &screen, W_CacheLumpNum (sprframe->lump[0], PU_CACHE)); } V_DrawPatchClean (320 - 88 - 32 + 36, PSetupDef.y + LINEHEIGHT*3 + 22, - &screens[0], + &screen, W_CacheLumpName ("M_PBOX", PU_CACHE)); // Draw player color sliders @@ -1511,13 +1513,13 @@ static void M_SlidePlayerBlue (int choice) // void M_DrawEmptyCell (oldmenu_t *menu, int item) { - V_DrawPatchClean (menu->x - 10, menu->y+item*LINEHEIGHT - 1, &screens[0], + V_DrawPatchClean (menu->x - 10, menu->y+item*LINEHEIGHT - 1, &screen, W_CacheLumpName("M_CELL1",PU_CACHE)); } void M_DrawSelCell (oldmenu_t *menu, int item) { - V_DrawPatchClean (menu->x - 10, menu->y+item*LINEHEIGHT - 1, &screens[0], + V_DrawPatchClean (menu->x - 10, menu->y+item*LINEHEIGHT - 1, &screen, W_CacheLumpName("M_CELL2",PU_CACHE)); } @@ -1604,14 +1606,15 @@ BOOL M_Responder (event_t* ev) case KEY_ESCAPE: genStringEnter = 0; + M_ClearMenus (); strcpy(&savegamestrings[saveSlot][0],saveOldString); break; case KEY_ENTER: genStringEnter = 0; + M_ClearMenus (); if (savegamestrings[saveSlot][0]) genStringEnd(saveSlot); // [RH] Function to call when enter is pressed - BorderNeedRefresh = true; break; default: @@ -1809,7 +1812,7 @@ void M_Drawer (void) // Horiz. & Vertically center string and print it. if (messageToPrint) { - V_DimScreen (&screens[0]); + V_DimScreen (&screen); BorderNeedRefresh = true; SB_state = -1; @@ -1842,7 +1845,7 @@ void M_Drawer (void) if (!menuactive) return; - V_DimScreen (&screens[0]); + V_DimScreen (&screen); BorderNeedRefresh = true; SB_state = -1; @@ -1860,7 +1863,7 @@ void M_Drawer (void) for (i=0;imenuitems[i].name[0]) - V_DrawPatchClean (x,y,&screens[0], + V_DrawPatchClean (x,y,&screen, W_CacheLumpName(currentMenu->menuitems[i].name ,PU_CACHE)); y += LINEHEIGHT; } @@ -1868,7 +1871,7 @@ void M_Drawer (void) // DRAW SKULL if (drawSkull) { - V_DrawPatchClean(x + SKULLXOFF,currentMenu->y - 5 + itemOn*LINEHEIGHT, &screens[0], + V_DrawPatchClean(x + SKULLXOFF,currentMenu->y - 5 + itemOn*LINEHEIGHT, &screen, W_CacheLumpName(skullName[whichSkull],PU_CACHE)); } } @@ -1886,9 +1889,10 @@ void M_ClearMenus (void) } menuactive = MenuStackDepth = 0; drawSkull = true; - I_ResumeMouse (); // [RH] Recapture the mouse in windowed modes. M_DemoNoPlay = false; C_HideConsole (); // [RH] Hide the console if we can. + I_ResumeMouse (); // [RH] Recapture the mouse in windowed modes. + BorderNeedRefresh = true; // if (!netgame && usergame && paused) // sendpause = true; } diff --git a/code/M_misc.c b/code/M_misc.c index a6aa6b455a..0519a2bc13 100644 --- a/code/M_misc.c +++ b/code/M_misc.c @@ -387,27 +387,27 @@ void M_ScreenShot (char *filename) } else { lbmname = autoname; } - if (!FindFreeName (lbmname, "tga\0pcx" + (screens[0].is8bit << 2))) { + if (!FindFreeName (lbmname, "tga\0pcx" + (screen.is8bit << 2))) { Printf (PRINT_HIGH, "M_ScreenShot: Delete some screenshots\n"); return; } filename = autoname; } - if (screens[0].is8bit) { + if (screen.is8bit) { // munge planar buffer to linear - linear = Malloc (screens[0].width * screens[0].height); + linear = Malloc (screen.width * screen.height); I_ReadScreen (linear); // save the pcx file WritePCXfile (filename, linear, - screens[0].width, screens[0].height, + screen.width, screen.height, IndexedPalette); free (linear); } else { // save the tga file - //I_WriteTGAfile (filename, &screens[0]); + //I_WriteTGAfile (filename, &screen); } Printf (PRINT_HIGH, "screen shot\n"); } diff --git a/code/P_ceilng.c b/code/P_ceilng.c index 3462932700..6f310b4ef6 100644 --- a/code/P_ceilng.c +++ b/code/P_ceilng.c @@ -453,6 +453,7 @@ void P_ActivateInStasisCeiling (int tag) if (scan->tag == tag && scan->direction == 0) { scan->direction = scan->olddirection; scan->thinker.function.acp1 = (actionf_p1) T_MoveCeiling; + PlayCeilingSound (scan); } scan = scan->next; } @@ -472,6 +473,7 @@ BOOL EV_CeilingCrushStop (int tag) while (scan) { if (scan->tag == tag && scan->direction != 0) { + SN_StopSequence ((mobj_t *)&scan->sector->soundorg); scan->olddirection = scan->direction; scan->thinker.function.acv = (actionf_v) NULL; scan->direction = 0; // in-stasis; diff --git a/code/P_doors.c b/code/P_doors.c index 2fa41d067d..9a6c7a74ff 100644 --- a/code/P_doors.c +++ b/code/P_doors.c @@ -72,7 +72,7 @@ void T_VerticalDoor (vldoor_t *door) // WAITING if (!--door->topcountdown) { - switch(door->type) + switch (door->type) { case doorRaise: door->direction = -1; // time to go back down @@ -94,7 +94,7 @@ void T_VerticalDoor (vldoor_t *door) // INITIAL WAIT if (!--door->topcountdown) { - switch(door->type) + switch (door->type) { case doorRaiseIn5Mins: door->direction = 1; @@ -117,7 +117,7 @@ void T_VerticalDoor (vldoor_t *door) if (res == pastdest) { SN_StopSequence ((mobj_t *)&door->sector->soundorg); - switch(door->type) + switch (door->type) { case doorRaise: case doorClose: @@ -136,7 +136,7 @@ void T_VerticalDoor (vldoor_t *door) } else if (res == crushed) { - switch(door->type) + switch (door->type) { case doorClose: // DO NOT GO BACK UP! break; @@ -159,7 +159,7 @@ void T_VerticalDoor (vldoor_t *door) if (res == pastdest) { SN_StopSequence ((mobj_t *)&door->sector->soundorg); - switch(door->type) + switch (door->type) { case doorRaise: door->direction = 0; // wait at top @@ -254,12 +254,19 @@ BOOL EV_DoDoor (vldoor_e type, line_t *line, mobj_t *thing, if (sec->ceilingdata) //jff 2/22/98 { vldoor_t *door = sec->ceilingdata; //jff 2/22/98 - if (type == doorRaise) { - // ONLY FOR "RAISE" DOORS, NOT "OPEN"s - if (door->direction == -1) { + + // [RH] Make sure it really is a door + if (door->thinker.function.acp1 != (actionf_p1) T_VerticalDoor) + return false; + + // ONLY FOR "RAISE" DOORS, NOT "OPEN"s + if (door->type == doorRaise && type == doorRaise) + { + if (door->direction == -1) + { door->direction = 1; // go back up } - else if (GET_SPAC(line->flags) == SPAC_PUSH) + else if (GET_SPAC(line->flags) != SPAC_PUSH) // [RH] activate push doors don't go back down when you // run into them (otherwise opening them would be // a real pain). @@ -268,6 +275,12 @@ BOOL EV_DoDoor (vldoor_e type, line_t *line, mobj_t *thing, return false; // JDC: bad guys never close doors door->direction = -1; // start going down immediately + + // [RH] If this sector doesn't have a specific sound + // attached to it, start the door close sequence. + // Otherwise, just let the current one continue. + if (sec->seqType == -1) + DoorSound (door, door->speed, false); } return true; } diff --git a/code/P_enemy.c b/code/P_enemy.c index c916caad06..f20b7cf089 100644 --- a/code/P_enemy.c +++ b/code/P_enemy.c @@ -887,11 +887,50 @@ void A_FaceTarget (mobj_t *actor) if (actor->target->flags & MF_SHADOW) { - int t = P_Random(pr_facetarget); - actor->angle += (t-P_Random(pr_facetarget))<<21; + int t = P_Random(pr_facetarget); + actor->angle += (t-P_Random(pr_facetarget))<<21; } } +// +// [RH] A_MonsterRail +// +// New function to let monsters shoot a railgun +// +void A_MonsterRail (mobj_t *actor) +{ + if (!actor->target) + return; + + // [RH] Andy Baker's stealth monsters + if (actor->flags & MF_STEALTH) + { + P_IncreaseVisibility(actor); + } + + actor->flags &= ~MF_AMBUSH; + + actor->angle = R_PointToAngle2 (actor->x, + actor->y, + actor->target->x, + actor->target->y); + + actor->pitch = FixedDiv (P_AimLineAttack (actor, actor->angle, MISSILERANGE), -40960); + + // Let the aim trail behind the player + actor->angle = R_PointToAngle2 (actor->x, + actor->y, + actor->target->x - actor->target->momx * 3, + actor->target->y - actor->target->momy * 3); + + if (actor->target->flags & MF_SHADOW) + { + int t = P_Random(pr_facetarget); + actor->angle += (t-P_Random(pr_facetarget))<<21; + } + + P_RailAttack (actor, actor->damage, 0); +} // // A_PosAttack @@ -1719,8 +1758,6 @@ void A_Pain (mobj_t *actor) void A_Fall (mobj_t *actor) { - int n; - // [RH] Andy Baker's stealth monsters if (actor->flags & MF_STEALTH) { @@ -1733,14 +1770,36 @@ void A_Fall (mobj_t *actor) // So change this if corpse objects // are meant to be obstacles. +#if 0 // [RH] Toss some gibs //if (actor->health < -80) - if (testgibs->value) - for (n = 0; n < 6; n++) - ThrowGib (actor, MT_GIB0 + (int)(P_Random(pr_gengib) >> 5), -actor->health); + { + int n; + + if (testgibs->value) + for (n = 0; n < 6; n++) + ThrowGib (actor, MT_GIB0 + (int)(P_Random(pr_gengib) >> 5), -actor->health); + } +#endif } +// killough 11/98: kill an object +void A_Die (mobj_t *actor) +{ + P_DamageMobj (actor, NULL, NULL, actor->health, MOD_UNKNOWN); +} + +// +// A_Detonate +// killough 8/9/98: same as A_Explode, except that the damage is variable +// + +void A_Detonate (mobj_t *mo) +{ + P_RadiusAttack (mo, mo->target, mo->info->damage, MOD_UNKNOWN); +} + // // A_Explode // @@ -1764,6 +1823,34 @@ void A_Explode (mobj_t *thing) P_RadiusAttack (thing, thing->target, 128, mod); } +// +// killough 9/98: a mushroom explosion effect, sorta :) +// Original idea: Linguica +// + +void A_Mushroom (mobj_t *actor) +{ + int i, j, n = actor->info->damage; + + A_Explode (actor); // First make normal explosion + + // Now launch mushroom cloud + for (i = -n; i <= n; i += 8) + { + for (j = -n; j <= n; j += 8) + { + mobj_t target = *actor, *mo; + target.x += i << FRACBITS; // Aim in many directions from source + target.y += j << FRACBITS; + target.z += P_AproxDistance(i,j) << (FRACBITS+2); // Aim up fairly high + mo = P_SpawnMissile (actor, &target, MT_FATSHOT); // Launch fireball + mo->momx >>= 1; + mo->momy >>= 1; // Slow it down a bit + mo->momz >>= 1; + mo->flags &= ~MF_NOGRAVITY; // Make debris fall under gravity + } + } +} // // A_BossDeath diff --git a/code/P_inter.c b/code/P_inter.c index 8498f1c193..f380a198a7 100644 --- a/code/P_inter.c +++ b/code/P_inter.c @@ -58,8 +58,18 @@ int clipammo[NUMAMMO] = {10, 4, 20, 1}; static void PickupMessage (mobj_t *toucher, const char *message) { - if (toucher == players[consoleplayer].camera) + // Some maps have multiple items stacked on top of each other. + // It looks odd to display pickup messages for all of them. + static int lastmessagetic; + static const char *lastmessage = NULL; + + if (toucher == players[consoleplayer].camera + && (lastmessagetic != gametic || lastmessage != message)) + { + lastmessagetic = gametic; + lastmessage = message; Printf (PRINT_LOW, "%s\n", message); + } } // @@ -653,18 +663,28 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher) } P_RemoveMobj (special); player->bonuscount += BONUSADD; - switch (sound) { - case 0: - case 3: - S_Sound (player->mo, CHAN_ITEM, "misc/i_pkup", 1, ATTN_NORM); - break; - case 1: - S_Sound (player->mo, CHAN_ITEM, "misc/p_pkup", 1, - (player->mo == players[consoleplayer].camera) ? ATTN_SURROUND : ATTN_NORM); - break; - case 2: - S_Sound (player->mo, CHAN_ITEM, "misc/w_pkup", 1, ATTN_NORM); - break; + + { + mobj_t *ent; + + if (player->mo == players[consoleplayer].camera) + ent = NULL; + else + ent = player->mo; + + switch (sound) { + case 0: + case 3: + S_Sound (ent, CHAN_ITEM, "misc/i_pkup", 1, ATTN_NORM); + break; + case 1: + S_Sound (ent, CHAN_ITEM, "misc/p_pkup", 1, + !ent ? ATTN_SURROUND : ATTN_NORM); + break; + case 2: + S_Sound (ent, CHAN_ITEM, "misc/w_pkup", 1, ATTN_NORM); + break; + } } } @@ -1066,7 +1086,7 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor) target->player->playerstate = PST_DEAD; P_DropWeapon (target->player); - if (target->player == &players[consoleplayer] && automapactive) + if (target == players[consoleplayer].camera && automapactive) { // don't die in auto map, switch view prior to dying AM_Stop (); diff --git a/code/P_local.h b/code/P_local.h index e7c5ec7011..388cf1d641 100644 --- a/code/P_local.h +++ b/code/P_local.h @@ -265,7 +265,7 @@ extern mobj_t* linetarget; // who got hit (or NULL) fixed_t P_AimLineAttack (mobj_t *t1, angle_t angle, fixed_t distance); void P_LineAttack (mobj_t *t1, angle_t angle, fixed_t distance, fixed_t slope, int damage); -void P_RailAttack (mobj_t *source, int damage); // [RH] Shoot a railgun +void P_RailAttack (mobj_t *source, int damage, int offset); // [RH] Shoot a railgun int P_HitFloor (mobj_t *thing); // [RH] Position the chasecam diff --git a/code/P_map.c b/code/P_map.c index 99578dac86..ebdade26e9 100644 --- a/code/P_map.c +++ b/code/P_map.c @@ -2005,12 +2005,17 @@ BOOL PTR_RailTraverse (intercept_t *in) return true; } -void P_RailAttack (mobj_t *source, int damage) +void P_RailAttack (mobj_t *source, int damage, int offset) { angle_t angle; - fixed_t x2, y2; + fixed_t x1, y1, x2, y2; vec3_t start, end; + x1 = source->x; + y1 = source->y; + angle = (source->angle - ANG90) >> ANGLETOFINESHIFT; + x1 += offset*finecosine[angle]; + y1 += offset*finesine[angle]; angle = source->angle >> ANGLETOFINESHIFT; x2 = source->x + 8192*finecosine[angle]; y2 = source->y + 8192*finesine[angle]; @@ -2019,9 +2024,9 @@ void P_RailAttack (mobj_t *source, int damage) aimslope = FixedMul (source->pitch, -40960); shootthing = source; NumRailHits = 0; - VectorFixedSet (start, source->x, source->y, shootz); + VectorFixedSet (start, x1, y1, shootz); - if (P_PathTraverse (source->x, source->y, x2, y2, PT_ADDLINES|PT_ADDTHINGS, PTR_RailTraverse)) { + if (P_PathTraverse (x1, y1, x2, y2, PT_ADDLINES|PT_ADDTHINGS, PTR_RailTraverse)) { // Nothing hit, so just shoot the air FixedAngleToVector (source->angle, source->pitch, end); VectorMA (start, 8192, end, end); @@ -2417,22 +2422,19 @@ void P_RadiusAttack (mobj_t *spot, mobj_t *source, int damage, int mod) // int crushchange; BOOL nofit; - +extern cvar_t *cl_bloodtype; // // PIT_ChangeSector // BOOL PIT_ChangeSector (mobj_t *thing) { - mobj_t *mo; - int t; - if (P_ThingHeightClip (thing)) { // keep checking return true; } - + // crunch bodies to giblets if (thing->health <= 0) { @@ -2443,7 +2445,7 @@ BOOL PIT_ChangeSector (mobj_t *thing) thing->radius = 0; // keep checking - return true; + return true; } // crunch dropped items @@ -2452,15 +2454,15 @@ BOOL PIT_ChangeSector (mobj_t *thing) P_RemoveMobj (thing); // keep checking - return true; + return true; } if (! (thing->flags & MF_SHOOTABLE) ) { // assume it is bloody gibs or something - return true; + return true; } - + nofit = true; if ((crushchange >= 0) && !(level.time&3) ) @@ -2468,18 +2470,36 @@ BOOL PIT_ChangeSector (mobj_t *thing) P_DamageMobj (thing, NULL, NULL, crushchange, MOD_CRUSH); // spray blood in a random direction - mo = P_SpawnMobj (thing->x, - thing->y, - thing->z + thing->height/2, MT_BLOOD); - - t = P_Random (pr_changesector); - mo->momx = (t - P_Random (pr_changesector)) << 12; - t = P_Random (pr_changesector); - mo->momy = (t - P_Random (pr_changesector)) << 12; + if ((!(thing->flags&MF_NOBLOOD)) && + (!(thing->flags2&MF2_INVULNERABLE))) + { + if (cl_bloodtype->value <= 1) + { + mobj_t *mo; + int t; + + mo = P_SpawnMobj (thing->x, + thing->y, + thing->z + thing->height/2, MT_BLOOD); + + t = P_Random (pr_changesector); + mo->momx = (t - P_Random (pr_changesector)) << 12; + t = P_Random (pr_changesector); + mo->momy = (t - P_Random (pr_changesector)) << 12; + } + if (cl_bloodtype->value >= 1) + { + angle_t an; + + an = (M_Random () - 128) << 24; + P_DrawSplash2 (32, thing->x, thing->y, + thing->z + thing->height/2, an, 2, 0); + } + } } - // keep checking (crush other things) - return true; + // keep checking (crush other things) + return true; } // diff --git a/code/P_mobj.c b/code/P_mobj.c index 52d6f758e5..8deb348aef 100644 --- a/code/P_mobj.c +++ b/code/P_mobj.c @@ -97,8 +97,8 @@ BOOL P_SetMobjState (mobj_t *mobj, statenum_t state) st = &states[state]; mobj->state = st; mobj->tics = st->tics; - if (!mobj->player) // [RH] Only change sprite if not a player - mobj->sprite = st->sprite; + if (!mobj->player || st->sprite != SPR_PLAY) + mobj->sprite = st->sprite; // [RH] Only change sprite if not a player mobj->frame = st->frame; // Modified handling. @@ -286,13 +286,26 @@ void P_XYMovement (mobj_t *mo) P_SlideMove (mo); } else - { // slide againt mobj + { // slide against mobj if (P_TryMove (mo, mo->x, ptryy, true)) + { mo->momx = 0; + } else if (P_TryMove (mo, ptryx, mo->y, true)) + { mo->momy = 0; + } else + { mo->momx = mo->momy = 0; + } + if (player && player->mo == mo) + { + if (mo->momx == 0) + player->momx = 0; + if (mo->momy == 0) + player->momy = 0; + } } } else if (mo->flags & MF_MISSILE) @@ -301,9 +314,9 @@ void P_XYMovement (mobj_t *mo) { if (BlockingMobj) { - if ((BlockingMobj->flags2&MF2_REFLECTIVE) || + if ((BlockingMobj->flags2 & MF2_REFLECTIVE) || ((!BlockingMobj->player) && - (!(BlockingMobj->flags&MF_COUNTKILL)))) + (!(BlockingMobj->flags & MF_COUNTKILL)))) { fixed_t speed; @@ -408,28 +421,23 @@ void P_XYMovement (mobj_t *mo) // killough 11/98: // Stop voodoo dolls that have come to rest, despite any - // moving corresponding player, except in old demos: - if (mo->momx > -STOPSPEED - && mo->momx < STOPSPEED - && mo->momy > -STOPSPEED - && mo->momy < STOPSPEED - && (!player - || !(player->cmd.ucmd.forwardmove | player->cmd.ucmd.sidemove) || - (player->mo != mo))) + // moving corresponding player: + if (mo->momx > -STOPSPEED && mo->momx < STOPSPEED + && mo->momy > -STOPSPEED && mo->momy < STOPSPEED + && (!player || (player->mo != mo) + || !(player->cmd.ucmd.forwardmove | player->cmd.ucmd.sidemove))) { // if in a walking frame, stop moving - if (player && (unsigned)((player->mo->state - states)- S_PLAY_RUN1) < 4) - P_SetMobjState (player->mo, S_PLAY); - // killough 10/98: // Don't affect main player when voodoo dolls stop: - if (player && (unsigned)(player->mo->state - states - S_PLAY_RUN1) < 4 + if (player && (unsigned)((player->mo->state - states) - S_PLAY_RUN1) < 4 && (player->mo == mo)) - P_SetMobjState (player->mo, S_PLAY); + { + P_SetMobjState (player->mo, S_PLAY); + } mo->momx = mo->momy = 0; - // killough 10/98: kill any bobbing momentum too (except in voodoo dolls) if (player && player->mo == mo) player->momx = player->momy = 0; @@ -506,7 +514,7 @@ void P_ZMovement (mobj_t *mo) if (mo->z <= mo->floorz) { // hit the floor - if (mo->flags & MF_MISSILE) + if ((mo->flags & MF_MISSILE) && !(mo->flags & MF_NOCLIP)) { mo->z = mo->floorz; if (mo->flags2 & MF2_FLOORBOUNCE) @@ -583,12 +591,7 @@ void P_ZMovement (mobj_t *mo) mo->momz -= (fixed_t)(sv_gravity->value * mo->subsector->sector->gravity * 81.92); } - if (mo->z + mo->height > mo->ceilingz - // [RH] For some reason, the shots spawned by the brain on MAP30 are - // getting stuck in the ceiling. I have no idea why, since it worked - // the last time I checked (and that was *after* I integrated Hexen's - // z-checking code. - && mo->type != MT_SPAWNSHOT) + if (mo->z + mo->height > mo->ceilingz) { // hit the ceiling mo->z = mo->ceilingz - mo->height; @@ -609,7 +612,7 @@ void P_ZMovement (mobj_t *mo) // the skull slammed into something mo->momz = -mo->momz; } - if (mo->flags & MF_MISSILE) + if (mo->flags & MF_MISSILE && !(mo->flags & MF_NOCLIP)) { if (mo->subsector->sector->ceilingpic == skyflatnum) { diff --git a/code/P_pspr.c b/code/P_pspr.c index 4b9ae64820..9c74b64dbd 100644 --- a/code/P_pspr.c +++ b/code/P_pspr.c @@ -570,6 +570,8 @@ void A_FirePlasma (player_t *player, pspdef_t *psp) // // [RH] A_FireRailgun // +static int RailOffset; + void A_FireRailgun (player_t *player, pspdef_t *psp) { int damage; @@ -594,7 +596,20 @@ void A_FireRailgun (player_t *player, pspdef_t *psp) else damage = 150; - P_RailAttack (player->mo, damage); + P_RailAttack (player->mo, damage, RailOffset); + RailOffset = 0; +} + +void A_FireRailgunRight (player_t *player, pspdef_t *psp) +{ + RailOffset = 10; + A_FireRailgun (player, psp); +} + +void A_FireRailgunLeft (player_t *player, pspdef_t *psp) +{ + RailOffset = -10; + A_FireRailgun (player, psp); } void A_RailWait (player_t *player, pspdef_t *psp) diff --git a/code/P_setup.c b/code/P_setup.c index 6e52841efe..4f40ad36a2 100644 --- a/code/P_setup.c +++ b/code/P_setup.c @@ -443,7 +443,7 @@ void P_LoadThings (int lump) mt2.y = SHORT(mt->y); mt2.angle = SHORT(mt->angle); mt2.type = SHORT(mt->type); - + P_SpawnMapThing (&mt2, 0); } diff --git a/code/P_user.c b/code/P_user.c index d14b54a768..a6ec8cc60c 100644 --- a/code/P_user.c +++ b/code/P_user.c @@ -99,15 +99,19 @@ void P_CalcHeight (player_t *player) // it causes bobbing jerkiness when the player moves from ice to non-ice, // and vice-versa. - player->bob = FixedMul (player->momx,player->momx) - + FixedMul (player->momy,player->momy); - player->bob >>= 2; - - if (player->bob > MAXBOB) - player->bob = MAXBOB; - if ((player->mo->flags2 & MF2_FLY) && !onground) + { player->bob = FRACUNIT / 2; + } + else + { + player->bob = FixedMul (player->momx, player->momx) + + FixedMul (player->momy, player->momy); + player->bob >>= 2; + + if (player->bob > MAXBOB) + player->bob = MAXBOB; + } if (!onground || (player->cheats & CF_NOMOMENTUM)) { @@ -132,8 +136,7 @@ void P_CalcHeight (player_t *player) player->viewheight = VIEWHEIGHT; player->deltaviewheight = 0; } - - if (player->viewheight < VIEWHEIGHT/2) + else if (player->viewheight < VIEWHEIGHT/2) { player->viewheight = VIEWHEIGHT/2; if (player->deltaviewheight <= 0) @@ -185,15 +188,12 @@ void P_MovePlayer (player_t *player) int friction, movefactor; movefactor = P_GetMoveFactor (mo, &friction); + bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; if (!onground && !(player->mo->flags2 & MF2_FLY)) { // [RH] allow very limited movement if not on ground. movefactor >>= 8; - bobfactor = 0; - } - else - { - bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; + bobfactor >>= 8; } forwardmove = (cmd->ucmd.forwardmove * movefactor) >> 8; sidemove = (cmd->ucmd.sidemove * movefactor) >> 8; @@ -205,7 +205,7 @@ void P_MovePlayer (player_t *player) } if (sidemove) { - P_Bob (player, mo->angle, (cmd->ucmd.sidemove * bobfactor) >> 8); + P_Bob (player, mo->angle-ANG90, (cmd->ucmd.sidemove * bobfactor) >> 8); P_Thrust (player, mo->angle-ANG90, sidemove); } diff --git a/code/Po_man.c b/code/Po_man.c index 5e794fcecb..51cd8ecb9a 100644 --- a/code/Po_man.c +++ b/code/Po_man.c @@ -100,7 +100,6 @@ void T_RotatePoly (polyevent_t *pe) poly->specialdata = NULL; } SN_StopSequence((mobj_t *)&poly->startSpot); -// P_PolyobjFinished(poly->tag); P_RemoveThinker(&pe->thinker); } if(pe->dist < (unsigned)absSpeed) @@ -223,7 +222,6 @@ void T_MovePoly (polyevent_t *pe) poly->specialdata = NULL; } SN_StopSequence((mobj_t *)&poly->startSpot); -// P_PolyobjFinished(poly->tag); P_RemoveThinker(&pe->thinker); } if(pe->dist < (unsigned)absSpeed) @@ -322,7 +320,7 @@ void T_PolyDoor (polydoor_t *pd) switch(pd->type) { case PODOOR_SLIDE: - if(PO_MovePolyobj(pd->polyobj, pd->xSpeed, pd->ySpeed)) + if(pd->dist <= 0 || PO_MovePolyobj(pd->polyobj, pd->xSpeed, pd->ySpeed)) { absSpeed = abs(pd->speed); pd->dist -= absSpeed; @@ -346,7 +344,6 @@ void T_PolyDoor (polydoor_t *pd) { poly->specialdata = NULL; } -// P_PolyobjFinished(poly->tag); P_RemoveThinker(&pd->thinker); } } @@ -360,7 +357,7 @@ void T_PolyDoor (polydoor_t *pd) } else { // open back up - pd->dist = pd->totalDist-pd->dist; + pd->dist = pd->totalDist - pd->dist; pd->direction = (ANGLE_MAX>>ANGLETOFINESHIFT)- pd->direction; pd->xSpeed = -pd->xSpeed; @@ -397,7 +394,6 @@ void T_PolyDoor (polydoor_t *pd) { poly->specialdata = NULL; } -// P_PolyobjFinished(poly->tag); P_RemoveThinker(&pd->thinker); } } @@ -1204,8 +1200,7 @@ static void SpawnPolyobj (int index, int tag, BOOL crush) polyobjs[index].crush = crush; polyobjs[index].tag = tag; polyobjs[index].seqType = segs[i].linedef->args[2]; - if (polyobjs[index].seqType < 0 - || polyobjs[index].seqType >= NumSequences) + if (polyobjs[index].seqType < 0 || polyobjs[index].seqType > 63) { polyobjs[index].seqType = 0; } diff --git a/code/R_draw.c b/code/R_draw.c index 1078a3bde7..fbaa18ff08 100644 --- a/code/R_draw.c +++ b/code/R_draw.c @@ -137,9 +137,9 @@ void R_DrawColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) { + || dc_yh >= screen.height) { Printf (PRINT_HIGH, "R_DrawColumnP_C: %i to %i at %i\n", dc_yl, dc_yh, dc_x); return; } @@ -198,9 +198,9 @@ void R_StretchColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) { + || dc_yh >= screen.height) { Printf (PRINT_HIGH, "R_StretchColumnP_C: %i to %i at %i\n", dc_yl, dc_yh, dc_x); return; } @@ -238,9 +238,9 @@ void R_FillColumnP (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) { + || dc_yh >= screen.height) { Printf (PRINT_HIGH, "R_StretchColumnP_C: %i to %i at %i\n", dc_yl, dc_yh, dc_x); return; } @@ -265,7 +265,7 @@ void R_FillColumnP (void) // // [RH] FUZZTABLE changed from 50 to 64 #define FUZZTABLE 64 -#define FUZZOFF (screens[0].pitch) +#define FUZZOFF (screen.pitch) int fuzzoffset[FUZZTABLE]; @@ -297,9 +297,9 @@ void R_InitFuzzTable (void) int i; int fuzzoff; - V_LockScreen (&screens[0]); + V_LockScreen (&screen); fuzzoff = FUZZOFF << detailyshift; - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); for (i = 0; i < FUZZTABLE; i++) fuzzoffset[i] = fuzzinit[i] * fuzzoff; @@ -336,8 +336,8 @@ void R_DrawFuzzColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width - || dc_yl < 0 || dc_yh >= screens[0].height) + if (dc_x >= screen.width + || dc_yl < 0 || dc_yh >= screen.height) { I_Error ("R_DrawFuzzColumnP_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -395,9 +395,9 @@ void R_DrawTranslucentColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) + || dc_yh >= screen.height) { I_Error ( "R_DrawTranslucentColumnP_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -453,9 +453,9 @@ void R_DrawTranslatedColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) + || dc_yh >= screen.height) { I_Error ( "R_DrawTranslatedColumnP_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -507,9 +507,9 @@ void R_DrawTlatedLucentColumnP_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) + || dc_yh >= screen.height) { I_Error ( "R_DrawTlatedLucentColumnP_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -588,8 +588,8 @@ void R_DrawSpanP (void) #ifdef RANGECHECK if (ds_x2 < ds_x1 || ds_x1<0 - || ds_x2>=screens[0].width - || ds_y>screens[0].height) + || ds_x2>=screen.width + || ds_y>screen.height) { I_Error( "R_DrawSpan: %i to %i at %i", ds_x1,ds_x2,ds_y); @@ -647,8 +647,8 @@ void R_FillSpan (void) #ifdef RANGECHECK if (ds_x2 < ds_x1 || ds_x1<0 - || ds_x2>=screens[0].width - || ds_y>screens[0].height) + || ds_x2>=screen.width + || ds_y>screen.height) { I_Error( "R_FillSpan: %i to %i at %i", ds_x1,ds_x2,ds_y); @@ -691,9 +691,9 @@ void R_DrawColumnD_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) { + || dc_yh >= screen.height) { Printf (PRINT_HIGH, "R_DrawColumnD_C: %i to %i at %i\n", dc_yl, dc_yh, dc_x); return; } @@ -742,8 +742,8 @@ void R_DrawFuzzColumnD_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width - || dc_yl < 0 || dc_yh >= screens[0].height) + if (dc_x >= screen.width + || dc_yl < 0 || dc_yh >= screen.height) { I_Error ("R_DrawFuzzColumnD_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -786,9 +786,9 @@ void R_DrawTranslucentColumnD_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) + || dc_yh >= screen.height) { I_Error ( "R_DrawTranslucentColumnD_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -831,9 +831,9 @@ void R_DrawTranslatedColumnD_C (void) count++; #ifdef RANGECHECK - if (dc_x >= screens[0].width + if (dc_x >= screen.width || dc_yl < 0 - || dc_yh >= screens[0].height) + || dc_yh >= screen.height) { I_Error ( "R_DrawTranslatedColumnD_C: %i to %i at %i", dc_yl, dc_yh, dc_x); @@ -876,8 +876,8 @@ void R_DrawSpanD (void) #ifdef RANGECHECK if (ds_x2 < ds_x1 || ds_x1<0 - || ds_x2>=screens[0].width - || ds_y>screens[0].height) + || ds_x2>=screen.width + || ds_y>screen.height) { I_Error( "R_DrawSpan: %i to %i at %i", ds_x1,ds_x2,ds_y); @@ -1039,11 +1039,11 @@ void R_InitBuffer (int width, int height) // Handle resize, // e.g. smaller view windows // with border and/or status bar. - viewwindowx = (screens[0].width-(width<>1; + viewwindowx = (screen.width-(width<>1; // [RH] Adjust column offset according to bytes per pixel // and detail mode - xshift = (screens[0].is8bit) ? 0 : 2; + xshift = (screen.is8bit) ? 0 : 2; xshift += detailxshift; // Column offset. For windows @@ -1051,15 +1051,15 @@ void R_InitBuffer (int width, int height) columnofs[i] = viewwindowx + (i << xshift); // Same with base row offset. - if ((width<> 1; - V_LockScreen (&screens[0]); - buffer = screens[0].buffer; - pitch = screens[0].pitch; - V_UnlockScreen (&screens[0]); + V_LockScreen (&screen); + buffer = screen.buffer; + pitch = screen.pitch; + V_UnlockScreen (&screen); // Precalculate all row offsets. for (i=0 ; i status bar width. // Will draw borders around itself, too. - if (screens[0].width > 320) + if (screen.width > 320) { SB_state = -1; } - if (realviewwidth == screens[0].width) { + if (realviewwidth == screen.width) { return; } - R_DrawBorder (0, 0, screens[0].width, viewwindowy); + R_DrawBorder (0, 0, screen.width, viewwindowy); R_DrawBorder (0, viewwindowy, viewwindowx, realviewheight + viewwindowy); - R_DrawBorder (viewwindowx + realviewwidth, viewwindowy, screens[0].width, realviewheight + viewwindowy); - R_DrawBorder (0, viewwindowy + realviewheight, screens[0].width, ST_Y); + R_DrawBorder (viewwindowx + realviewwidth, viewwindowy, screen.width, realviewheight + viewwindowy); + R_DrawBorder (0, viewwindowy + realviewheight, screen.width, ST_Y); for (x = viewwindowx; x < viewwindowx + realviewwidth; x += 8) { - V_DrawPatch (x, viewwindowy - 8, &screens[0], W_CacheLumpName ("brdr_t", PU_CACHE)); - V_DrawPatch (x, viewwindowy + realviewheight, &screens[0], W_CacheLumpName ("brdr_b", PU_CACHE)); + V_DrawPatch (x, viewwindowy - 8, &screen, W_CacheLumpName ("brdr_t", PU_CACHE)); + V_DrawPatch (x, viewwindowy + realviewheight, &screen, W_CacheLumpName ("brdr_b", PU_CACHE)); } for (y = viewwindowy; y < viewwindowy + realviewheight; y += 8) { - V_DrawPatch (viewwindowx - 8, y, &screens[0], W_CacheLumpName ("brdr_l", PU_CACHE)); - V_DrawPatch (viewwindowx + realviewwidth, y, &screens[0], W_CacheLumpName ("brdr_r", PU_CACHE)); + V_DrawPatch (viewwindowx - 8, y, &screen, W_CacheLumpName ("brdr_l", PU_CACHE)); + V_DrawPatch (viewwindowx + realviewwidth, y, &screen, W_CacheLumpName ("brdr_r", PU_CACHE)); } // Draw beveled edge. V_DrawPatch (viewwindowx-8, viewwindowy-8, - &screens[0], + &screen, W_CacheLumpName ("brdr_tl",PU_CACHE)); V_DrawPatch (viewwindowx+realviewwidth, viewwindowy-8, - &screens[0], + &screen, W_CacheLumpName ("brdr_tr",PU_CACHE)); V_DrawPatch (viewwindowx-8, viewwindowy+realviewheight, - &screens[0], + &screen, W_CacheLumpName ("brdr_bl",PU_CACHE)); V_DrawPatch (viewwindowx+realviewwidth, viewwindowy+realviewheight, - &screens[0], + &screen, W_CacheLumpName ("brdr_br",PU_CACHE)); - V_MarkRect (0,0,screens[0].width, ST_Y); + V_MarkRect (0,0,screen.width, ST_Y); } /* @@ -1160,28 +1160,28 @@ void R_DrawTopBorder (void) { int x, y; - if (realviewwidth == screens[0].width) + if (realviewwidth == screen.width) return; - R_DrawBorder (0, 0, screens[0].width, 34); + R_DrawBorder (0, 0, screen.width, 34); if (viewwindowy < 35) { for (x = viewwindowx; x < viewwindowx + realviewwidth; x += 8) { - V_DrawPatch (x, viewwindowy-8, &screens[0], W_CacheLumpName("brdr_t", PU_CACHE)); + V_DrawPatch (x, viewwindowy-8, &screen, W_CacheLumpName("brdr_t", PU_CACHE)); } for (y = viewwindowy; y < 35; y += 8) { - V_DrawPatch(viewwindowx-8, y, &screens[0], + V_DrawPatch(viewwindowx-8, y, &screen, W_CacheLumpName ("brdr_l", PU_CACHE)); - V_DrawPatch(viewwindowx+realviewwidth, y, &screens[0], + V_DrawPatch(viewwindowx+realviewwidth, y, &screen, W_CacheLumpName("brdr_r", PU_CACHE)); } - V_DrawPatch(viewwindowx-8, viewwindowy-8, &screens[0], + V_DrawPatch(viewwindowx-8, viewwindowy-8, &screen, W_CacheLumpName("brdr_tl", PU_CACHE)); - V_DrawPatch(viewwindowx+realviewwidth, viewwindowy-8, &screens[0], + V_DrawPatch(viewwindowx+realviewwidth, viewwindowy-8, &screen, W_CacheLumpName("brdr_tr", PU_CACHE)); } } @@ -1194,12 +1194,12 @@ void R_DetailDouble (void) switch ((detailxshift << 1) | detailyshift) { case 1: // y-double { - int rowsize = realviewwidth << ((screens[0].is8bit) ? 0 : 2); - int pitch = screens[0].pitch; + int rowsize = realviewwidth << ((screen.is8bit) ? 0 : 2); + int pitch = screen.pitch; int y; byte *line; - line = screens[0].buffer + viewwindowy*pitch + viewwindowx; + line = screen.buffer + viewwindowy*pitch + viewwindowx; for (y = 0; y < viewheight; y++, line += pitch<<1) { memcpy (line+pitch, line, rowsize); } @@ -1209,11 +1209,11 @@ void R_DetailDouble (void) case 2: // x-double { int rowsize = realviewwidth >> 2; - int pitch = screens[0].pitch >> (2-detailyshift); + int pitch = screen.pitch >> (2-detailyshift); int y,x; unsigned *line,a,b; - line = (unsigned *)(screens[0].buffer + viewwindowy*screens[0].pitch + viewwindowx); + line = (unsigned *)(screen.buffer + viewwindowy*screen.pitch + viewwindowx); for (y = 0; y < viewheight; y++, line += pitch) { for (x = 0; x < rowsize; x += 2) { a = line[x+0]; @@ -1230,12 +1230,12 @@ void R_DetailDouble (void) case 3: // x- and y-double { int rowsize = realviewwidth >> 2; - int pitch = screens[0].pitch >> (2-detailyshift); - int realpitch = screens[0].pitch >> 2; + int pitch = screen.pitch >> (2-detailyshift); + int realpitch = screen.pitch >> 2; int y,x; unsigned *line,a,b; - line = (unsigned *)(screens[0].buffer + viewwindowy*screens[0].pitch + viewwindowx); + line = (unsigned *)(screen.buffer + viewwindowy*screen.pitch + viewwindowx); for (y = 0; y < viewheight; y++, line += pitch) { for (x = 0; x < rowsize; x += 2) { a = line[x+0]; @@ -1258,7 +1258,7 @@ void R_InitColumnDrawers (BOOL is8bit) { if (is8bit) { #ifdef USEASM - if (screens[0].height <= 240) + if (screen.height <= 240) R_DrawColumn = R_DrawColumnP_Unrolled; else R_DrawColumn = R_DrawColumnP_ASM; @@ -1266,7 +1266,7 @@ void R_InitColumnDrawers (BOOL is8bit) R_DrawFuzzColumn = R_DrawFuzzColumnP_ASM; R_DrawTranslucentColumn = R_DrawTranslucentColumnP_ASM; R_DrawTranslatedColumn = R_DrawTranslatedColumnP_C; - if (screens[0].width <= 320) + if (screen.width <= 320) R_DrawSpan = R_DrawSpanP_Unrolled; else R_DrawSpan = R_DrawSpanP; diff --git a/code/R_main.c b/code/R_main.c index c7a87aa902..27ab3f81f8 100644 --- a/code/R_main.c +++ b/code/R_main.c @@ -556,7 +556,7 @@ void R_InitLightTables (void) int level; int startmap; int scale; - int lightmapsize = 8 + (screens[0].is8bit ? 0 : 2); + int lightmapsize = 8 + (screen.is8bit ? 0 : 2); // Calculate the light levels to use // for each level / distance combination. @@ -578,7 +578,7 @@ void R_InitLightTables (void) } } - lightscalexmul = ((320<>(screens[0].is8bit ? 0 : 2))); + realviewwidth = ((setblocks*screen.width)/10) & (~(15>>(screen.is8bit ? 0 : 2))); realviewheight = ((setblocks*ST_Y)/10)&~7; - freelookviewheight = ((setblocks*screens[0].height)/10)&~7; + freelookviewheight = ((setblocks*screen.height)/10)&~7; } if (setblocks == 11) @@ -695,8 +695,8 @@ void R_ExecuteSetViewSize (void) centerxfrac = centerx<> detailxshift; - virtheight = screens[0].height >> detailyshift; + virtwidth = screen.width >> detailxshift; + virtheight = screen.height >> detailyshift; // [RH] aspect ratio stuff (based on Doom Legacy's) aspectx = ((virtheight * centerx * 320) / 200) / virtwidth * FRACUNIT; @@ -767,7 +767,7 @@ void R_ExecuteSetViewSize (void) startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS; for (j=0 ; j>detailxshift))/((viewwidth*DISTMAP)); + level = startmap - (j*(screen.width>>detailxshift))/((viewwidth*DISTMAP)); if (level < 0) level = 0; else if (level >= NUMCOLORMAPS) @@ -919,7 +919,7 @@ void R_SetupFrame (player_t *player) const sector_t *s = camera->subsector->sector->heightsec + sectors; newblend = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ? s->topmap : s->midmap; - if (!screens[0].is8bit) + if (!screen.is8bit) newblend = R_BlendForColormap (newblend); else if (APART(newblend) == 0 && newblend >= numfakecmaps) newblend = 0; @@ -954,7 +954,7 @@ void R_SetupFrame (player_t *player) fixedlightlev = player->fixedcolormap*256; fixedcolormap = DefaultPalette->maps.colormaps; } else { - if (screens[0].is8bit) + if (screen.is8bit) fixedcolormap = DefaultPalette->maps.colormaps + player->fixedcolormap*256; @@ -1071,22 +1071,22 @@ void R_MultiresInit (void) extern byte **ylookup; extern int *columnofs; - ylookup = Realloc (ylookup, screens[0].height * sizeof(byte *)); - columnofs = Realloc (columnofs, screens[0].width * sizeof(int)); - r_dscliptop = Realloc (r_dscliptop, screens[0].width * sizeof(short)); - r_dsclipbot = Realloc (r_dsclipbot, screens[0].width * sizeof(short)); + ylookup = Realloc (ylookup, screen.height * sizeof(byte *)); + columnofs = Realloc (columnofs, screen.width * sizeof(int)); + r_dscliptop = Realloc (r_dscliptop, screen.width * sizeof(short)); + r_dsclipbot = Realloc (r_dsclipbot, screen.width * sizeof(short)); // Moved from R_InitSprites() - negonearray = Realloc (negonearray, sizeof(short) * screens[0].width); + negonearray = Realloc (negonearray, sizeof(short) * screen.width); - for (i=0 ; i>ANGLETOFINESHIFT; // left to right mapping // scale will be unit scale at SCREENWIDTH/2 distance basexscale = FixedDiv (finecosine[angle], centerxfrac); @@ -235,8 +235,8 @@ static visplane_t *new_visplane(unsigned hash) visplane_t *check = freetail; if (!check) { - check = Calloc (1, sizeof(*check) + sizeof(*check->top)*(screens[0].width*2)); - check->bottom = &check->top[screens[0].width+2]; + check = Calloc (1, sizeof(*check) + sizeof(*check->top)*(screen.width*2)); + check->bottom = &check->top[screen.width+2]; } else if (!(freetail = freetail->next)) freehead = &freetail; @@ -282,10 +282,10 @@ visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel, check->xoffs = xoffs; // killough 2/28/98: Save offsets check->yoffs = yoffs; check->colormap = basecolormap; // [RH] Save colormap - check->minx = screens[0].width; + check->minx = screen.width; check->maxx = -1; - memset (check->top, 0xff, sizeof(*check->top) * screens[0].width); + memset (check->top, 0xff, sizeof(*check->top) * screen.width); return check; } @@ -348,7 +348,7 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop) pl = new_pl; pl->minx = start; pl->maxx = stop; - memset (pl->top, 0xff, sizeof(*pl->top) * screens[0].width); + memset (pl->top, 0xff, sizeof(*pl->top) * screen.width); } return pl; } @@ -612,18 +612,18 @@ BOOL R_PlaneInitData (void) if (cachedxstep) free (cachedxstep); if (cachedystep) free (cachedystep); - floorclip = Malloc (screens[0].width * sizeof(*floorclip)); - ceilingclip = Malloc (screens[0].width * sizeof(*ceilingclip)); + floorclip = Malloc (screen.width * sizeof(*floorclip)); + ceilingclip = Malloc (screen.width * sizeof(*ceilingclip)); - spanstart = Calloc (screens[0].height, sizeof(*spanstart)); - spanstop = Calloc (screens[0].height, sizeof(*spanstop)); + spanstart = Calloc (screen.height, sizeof(*spanstart)); + spanstop = Calloc (screen.height, sizeof(*spanstop)); - yslopetab = Calloc ((screens[0].height<<1)+(screens[0].height>>1), sizeof(*yslopetab)); - distscale = Calloc (screens[0].width, sizeof(*distscale)); - cachedheight = Calloc (screens[0].height, sizeof(*cachedheight)); - cacheddistance = Calloc (screens[0].height, sizeof(*cacheddistance)); - cachedxstep = Calloc (screens[0].height, sizeof(*cachedxstep)); - cachedystep = Calloc (screens[0].height, sizeof(*cachedystep)); + yslopetab = Calloc ((screen.height<<1)+(screen.height>>1), sizeof(*yslopetab)); + distscale = Calloc (screen.width, sizeof(*distscale)); + cachedheight = Calloc (screen.height, sizeof(*cachedheight)); + cacheddistance = Calloc (screen.height, sizeof(*cacheddistance)); + cachedxstep = Calloc (screen.height, sizeof(*cachedxstep)); + cachedystep = Calloc (screen.height, sizeof(*cachedystep)); // Free all visplanes and let them be re-allocated as needed. { diff --git a/code/R_segs.c b/code/R_segs.c index 625e00f441..e7fa47c4d4 100644 --- a/code/R_segs.c +++ b/code/R_segs.c @@ -125,7 +125,7 @@ static void BlastMaskedColumn (void (*blastfunc)(column_t *column), int texnum) (__int64) dc_texturemid * spryscale; // [RH] This doesn't work properly as-is with freelook. Probably just me. // if (t + (__int64) textureheight[texnum] * spryscale < 0 || -// t > (__int64) screens[0].height << FRACBITS*2) +// t > (__int64) screen.height << FRACBITS*2) // continue; // skip if the texture is out of screen's range sprtopscreen = (long)(t >> FRACBITS); } diff --git a/code/R_things.c b/code/R_things.c index 17c1688e5d..e91d91b3b6 100644 --- a/code/R_things.c +++ b/code/R_things.c @@ -1474,11 +1474,11 @@ static void R_DrawCrosshair (void) if (transparent) V_DrawLucentPatch (realviewwidth / 2 + viewwindowx, realviewheight / 2 + viewwindowy, - &screens[0], patch); + &screen, patch); else V_DrawPatch (realviewwidth / 2 + viewwindowx, realviewheight / 2 + viewwindowy, - &screens[0], patch); + &screen, patch); } } diff --git a/code/S_sound.c b/code/S_sound.c index 6f12303c50..30cd9fdddc 100644 --- a/code/S_sound.c +++ b/code/S_sound.c @@ -66,6 +66,7 @@ typedef struct float volume; int pitch; int priority; + BOOL loop; } channel_t; // [RH] Hacks for pitch variance @@ -127,7 +128,7 @@ static fixed_t P_AproxDistance2 (mobj_t *listener, fixed_t x, fixed_t y) void S_NoiseDebug (void) { fixed_t ox, oy; - int i, y; + int i, y, color; y = 32 * CleanYfac; if (gametic & 16) @@ -143,7 +144,7 @@ void S_NoiseDebug (void) V_DrawText (CR_GREY, 280, y, "chan"); y += 8; - for (i = 0; i < numChannels && y < screens[0].height - 16; i++, y += 8) { + for (i = 0; i < numChannels && y < screen.height - 16; i++, y += 8) { if (Channel[i].sfxinfo) { char temp[16]; mobj_t *origin = Channel[i].mo; @@ -159,21 +160,22 @@ void S_NoiseDebug (void) ox = Channel[i].x; oy = Channel[i].y; } + color = Channel[i].loop ? CR_BROWN : CR_GREY; strcpy (temp, lumpinfo[Channel[i].sfxinfo->lumpnum].name); temp[8] = 0; - V_DrawText (CR_GREY, 0, y, temp); + V_DrawText (color, 0, y, temp); sprintf (temp, "%d", ox / FRACUNIT); - V_DrawText (CR_GREY, 70, y, temp); + V_DrawText (color, 70, y, temp); sprintf (temp, "%d", oy / FRACUNIT); - V_DrawText (CR_GREY, 120, y, temp); + V_DrawText (color, 120, y, temp); sprintf (temp, "%ld", Channel[i].sfxinfo - S_sfx); - V_DrawText (CR_GREY, 170, y, temp); + V_DrawText (color, 170, y, temp); sprintf (temp, "%d", Channel[i].priority); - V_DrawText (CR_GREY, 200, y, temp); + V_DrawText (color, 200, y, temp); sprintf (temp, "%d", P_AproxDistance2 (players[consoleplayer].camera, ox, oy) / FRACUNIT); - V_DrawText (CR_GREY, 240, y, temp); + V_DrawText (color, 240, y, temp); sprintf (temp, "%d", Channel[i].entchannel); - V_DrawText (CR_GREY, 280, y, temp); + V_DrawText (color, 280, y, temp); } else { V_DrawText (CR_GREY, 0, y, "------"); } @@ -283,7 +285,7 @@ void S_Start (void) // be specified both by id and by name. Also borrowed some stuff from // Hexen and parameters from Quake. static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, - int sound_id, float volume, int attenuation) + int sound_id, float volume, int attenuation, BOOL looping) { sfxinfo_t *sfx; int dist, vol; @@ -459,7 +461,7 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, else Channel[i].pitch = NORM_PITCH; - Channel[i].handle = I_StartSound (sfx, vol, sep, Channel[i].pitch, i); + Channel[i].handle = I_StartSound (sfx, vol, sep, Channel[i].pitch, i, looping); Channel[i].sound_id = sound_id; Channel[i].mo = ent; Channel[i].sfxinfo = sfx; @@ -470,6 +472,7 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, Channel[i].volume = volume; Channel[i].x = x; Channel[i].y = y; + Channel[i].loop = looping; if (sfx->usefulness < 0) sfx->usefulness = 1; @@ -479,11 +482,16 @@ static void S_StartSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, void S_SoundID (mobj_t *ent, int channel, int sound_id, float volume, int attenuation) { - S_StartSound (ent, 0, 0, channel, sound_id, volume, attenuation); + S_StartSound (ent, 0, 0, channel, sound_id, volume, attenuation, false); +} + +void S_LoopedSoundID (mobj_t *ent, int channel, int sound_id, float volume, int attenuation) +{ + S_StartSound (ent, 0, 0, channel, sound_id, volume, attenuation, true); } static void S_StartNamedSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, - char *name, float volume, int attenuation) + char *name, float volume, int attenuation, BOOL looping) { int sfx_id; @@ -513,17 +521,22 @@ static void S_StartNamedSound (mobj_t *ent, fixed_t x, fixed_t y, int channel, if (sfx_id == -1) DPrintf ("Unknown sound %s\n", name); - S_StartSound (ent, x, y, channel, sfx_id, volume, attenuation); + S_StartSound (ent, x, y, channel, sfx_id, volume, attenuation, looping); } void S_Sound (mobj_t *ent, int channel, char *name, float volume, int attenuation) { - S_StartNamedSound (ent, 0, 0, channel, name, volume, attenuation); + S_StartNamedSound (ent, 0, 0, channel, name, volume, attenuation, false); +} + +void S_LoopedSound (mobj_t *ent, int channel, char *name, float volume, int attenuation) +{ + S_StartNamedSound (ent, 0, 0, channel, name, volume, attenuation, true); } void S_PositionedSound (fixed_t x, fixed_t y, int channel, char *name, float volume, int attenuation) { - S_StartNamedSound ((mobj_t *)(~0), x, y, channel, name, volume, attenuation); + S_StartNamedSound ((mobj_t *)(~0), x, y, channel, name, volume, attenuation, false); } // S_StopSoundID from Hexen (albeit, modified somewhat) @@ -581,7 +594,6 @@ void S_StopSound (mobj_t *ent, int channel) S_StopChannel (i); } -// Used by the cast finale void S_StopAllChannels (void) { int i; @@ -1101,16 +1113,28 @@ void A_Ambient (mobj_t *actor) { if (S_GetSoundPlayingInfo (actor, S_FindSound (ambient->sound))) return; + + if (ambient->sound[0]) { + S_LoopedSound (actor, CHAN_BODY, ambient->sound, ambient->volume, + ambient->type & POSITIONAL ? ATTN_NORM : + (ambient->type & SURROUND ? ATTN_SURROUND : ATTN_NONE)); + + SetTicker (&actor->tics, ambient); + } else { + P_RemoveMobj (actor); + } } + else + { + if (ambient->sound[0]) { + S_Sound (actor, CHAN_BODY, ambient->sound, ambient->volume, + ambient->type & POSITIONAL ? ATTN_NORM : + (ambient->type & SURROUND ? ATTN_SURROUND : ATTN_NONE)); - if (ambient->sound[0]) { - S_Sound (actor, CHAN_BODY, ambient->sound, ambient->volume, - ambient->type & POSITIONAL ? ATTN_NORM : - (ambient->type & SURROUND ? ATTN_SURROUND : ATTN_NONE)); - - SetTicker (&actor->tics, ambient); - } else { - P_RemoveMobj (actor); + SetTicker (&actor->tics, ambient); + } else { + P_RemoveMobj (actor); + } } } diff --git a/code/S_sound.h b/code/S_sound.h index 6315c61fee..9282443817 100644 --- a/code/S_sound.h +++ b/code/S_sound.h @@ -38,6 +38,7 @@ struct sfxinfo_struct { char name[MAX_SNDNAME+1]; // [RH] Sound name defined in SNDINFO void* data; // sound data + void* loopdata; // Sound data for looping sounds struct sfxinfo_struct *link; @@ -73,8 +74,10 @@ void S_Start(void); // Start sound for thing at void S_Sound (struct mobj_s *ent, int channel, char *name, float volume, int attenuation); +void S_LoopedSound (struct mobj_s *ent, int channel, char *name, float volume, int attenuation); void S_PositionedSound (int x, int y, int channel, char *name, float volume, int attenuation); void S_SoundID (struct mobj_s *ent, int channel, int sfxid, float volume, int attenuation); +void S_LoopedSoundID (struct mobj_s *ent, int channel, int sfxid, float volume, int attenuation); // sound channels // channel 0 never willingly overrides diff --git a/code/ST_LIB.H b/code/St_lib.h similarity index 99% rename from code/ST_LIB.H rename to code/St_lib.h index 6bca37c014..c3cfc2464e 100644 --- a/code/ST_LIB.H +++ b/code/St_lib.h @@ -35,7 +35,7 @@ extern screen_t stbarscreen; extern screen_t stnumscreen; #define BG (stbarscreen) -#define FG (screens[0]) +#define FG (screen) diff --git a/code/St_new.c b/code/St_new.c index 1d5cfc7ff8..97def7187c 100644 --- a/code/St_new.c +++ b/code/St_new.c @@ -115,42 +115,42 @@ void ST_newDraw (void) int y, i; ammotype_t ammo = weaponinfo[plyr->readyweapon].ammo; - y = screens[0].height - (numheight + 4) * CleanYfac; + y = screen.height - (numheight + 4) * CleanYfac; // Draw health - V_DrawPatchCleanNoMove (20 * CleanXfac, screens[0].height-2*CleanYfac, - &screens[0], medi); - ST_DrawNum (40 * CleanXfac, y, &screens[0], plyr->health); + V_DrawPatchCleanNoMove (20 * CleanXfac, screen.height-2*CleanYfac, + &screen, medi); + ST_DrawNum (40 * CleanXfac, y, &screen, plyr->health); // Draw armor if (plyr->armortype && plyr->armorpoints) { if (armors[plyr->armortype]) V_DrawPatchCleanNoMove (20 * CleanXfac, y - 4*CleanYfac, - &screens[0], armors[plyr->armortype-1]); + &screen, armors[plyr->armortype-1]); ST_DrawNum (40*CleanXfac, y - (SHORT(armors[0]->height)+3)*CleanYfac, - &screens[0], plyr->armorpoints); + &screen, plyr->armorpoints); } // Draw ammo if (ammo < NUMAMMO) { patch_t *ammopatch = ammos[weaponinfo[plyr->readyweapon].ammo]; - V_DrawPatchCleanNoMove (screens[0].width - 14 * CleanXfac, - screens[0].height - 4 * CleanYfac, - &screens[0], ammopatch); - ST_DrawNumRight (screens[0].width - 25 * CleanXfac, y, &screens[0], plyr->ammo[ammo]); + V_DrawPatchCleanNoMove (screen.width - 14 * CleanXfac, + screen.height - 4 * CleanYfac, + &screen, ammopatch); + ST_DrawNumRight (screen.width - 25 * CleanXfac, y, &screen, plyr->ammo[ammo]); } if (deathmatch->value) { // Draw frags (in DM) - ST_DrawNumRight (screens[0].width - 2, 1, &screens[0], plyr->fragcount); + ST_DrawNumRight (screen.width - 2, 1, &screen, plyr->fragcount); } else { // Draw keys (not DM) y = CleanYfac; for (i = 0; i < 6; i++) { if (plyr->cards[i]) { - V_DrawPatchCleanNoMove (screens[0].width - 10*CleanXfac, y, - &screens[0], keys[i]); + V_DrawPatchCleanNoMove (screen.width - 10*CleanXfac, y, + &screen, keys[i]); y += (8 + (i < 3 ? 0 : 2)) * CleanYfac; } } @@ -169,7 +169,7 @@ void ST_nameDraw (int y) else color = CR_GREEN; - x = (screens[0].width - V_StringWidth (plyr->userinfo.netname)*CleanXfac) >> 1; + x = (screen.width - V_StringWidth (plyr->userinfo.netname)*CleanXfac) >> 1; if (level.time < NameUp) V_DrawTextClean (color, x, y, plyr->userinfo.netname); else diff --git a/code/St_stuff.c b/code/St_stuff.c index 99b8824667..f2c8bfc974 100644 --- a/code/St_stuff.c +++ b/code/St_stuff.c @@ -105,7 +105,7 @@ float BaseBlendA; #define ST_FACESTRIDE \ (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES) -#define ST_NUMEXTRAFACES 2 +#define ST_NUMEXTRAFACES 2 #define ST_NUMFACES \ (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES) @@ -856,7 +856,6 @@ void ST_updateFaceWidget(void) st_facecount = 1; } - } // look left or look right if the facecount has timed out @@ -1085,7 +1084,7 @@ void ST_Drawer (void) "Demo was recorded with a different version\n" "of ZDoom. Expect it to go out of sync."); - if (realviewheight == screens[0].height && viewactive) + if (realviewheight == screen.height && viewactive) { if (DrawNewHUD) ST_newDraw (); @@ -1114,7 +1113,7 @@ void ST_Drawer (void) if (viewheight <= ST_Y) ST_nameDraw (ST_Y - 11 * CleanYfac); else - ST_nameDraw (screens[0].height - 11 * CleanYfac); + ST_nameDraw (screen.height - 11 * CleanYfac); // Do red-/gold-shifts from damage/items ST_doPaletteStuff(); @@ -1127,15 +1126,29 @@ void ST_Drawer (void) players[consoleplayer].camera->y/FRACUNIT); } +static patch_t *LoadFaceGraphic (char *name, int namespc) +{ + char othername[9]; + int lump; + + lump = (W_CheckNumForName)(name, namespc); + if (lump == -1) { + strcpy (othername, name); + othername[0] = 'S'; othername[1] = 'T'; othername[2] = 'F'; + lump = W_GetNumForName (othername); + } + return W_CacheLumpNum (lump, PU_STATIC); +} + void ST_loadGraphics(void) { playerskin_t *skin; int i, j; int namespc; int facenum; - char namebuf[9]; + namebuf[8] = 0; if (plyr) skin = &skins[plyr->userinfo.skin]; else @@ -1204,31 +1217,31 @@ void ST_loadGraphics(void) for (j = 0; j < ST_NUMSTRAIGHTFACES; j++) { sprintf(namebuf+3, "ST%d%d", i, j); - faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); } sprintf(namebuf+3, "TR%d0", i); // turn right - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); sprintf(namebuf+3, "TL%d0", i); // turn left - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); sprintf(namebuf+3, "OUCH%d", i); // ouch! - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); sprintf(namebuf+3, "EVL%d", i); // evil grin ;) - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); sprintf(namebuf+3, "KILL%d", i); // pissed off - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); } strcpy (namebuf+3, "GOD0"); - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); strcpy (namebuf+3, "DEAD0"); - faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC); + faces[facenum++] = LoadFaceGraphic (namebuf, namespc); } -void ST_loadData(void) +void ST_loadData (void) { ST_loadGraphics(); } -void ST_unloadGraphics(void) +void ST_unloadGraphics (void) { int i; @@ -1499,12 +1512,12 @@ void ST_ChangeScale (cvar_t *var) if (var->value) { // Stretch status bar to fill fill width of screen - ST_WIDTH = screens[0].width; + ST_WIDTH = screen.width; if (ST_WIDTH == 320) { // Do not scale height for 320 x 2X0 screens ST_HEIGHT = 32; } else { - ST_HEIGHT = (32 * screens[0].height) / 200; + ST_HEIGHT = (32 * screen.height) / 200; } } else { // Do not stretch status bar @@ -1513,8 +1526,8 @@ void ST_ChangeScale (cvar_t *var) ST_HEIGHT = 32; } - ST_X = (screens[0].width-ST_WIDTH)/2; - ST_Y = screens[0].height - ST_HEIGHT; + ST_X = (screen.width-ST_WIDTH)/2; + ST_Y = screen.height - ST_HEIGHT; setsizeneeded = true; SB_state = -1; diff --git a/code/V_video.c b/code/V_video.c index d5c48afd33..39ab65c678 100644 --- a/code/V_video.c +++ b/code/V_video.c @@ -69,8 +69,9 @@ extern int DisplayID; -// [RH] Screens are no longer mere byte arrays. -screen_t screens[1]; +// [RH] The framebuffer is no longer a mere byte array. +// There's also only one, not four. +screen_t screen; int dirtybox[4]; @@ -464,24 +465,24 @@ void BuildTransTable (byte *transtab, unsigned int *palette) C_InitTicker (NULL, 0); } -void V_LockScreen (screen_t *screen) +void V_LockScreen (screen_t *scrn) { - screen->lockcount++; - if (screen->lockcount == 1) { - I_LockScreen (screen); + scrn->lockcount++; + if (scrn->lockcount == 1) { + I_LockScreen (scrn); - if (screen == &screens[0]) { - if (dc_pitch != screen->pitch << detailyshift) { - dc_pitch = screen->pitch << detailyshift; + if (scrn == &screen) { + if (dc_pitch != scrn->pitch << detailyshift) { + dc_pitch = scrn->pitch << detailyshift; R_InitFuzzTable (); #ifdef USEASM ASM_PatchPitch (); #endif } - if ((screen->is8bit ? 1 : 4) << detailxshift != ds_colsize) { - ds_colsize = (screen->is8bit ? 1 : 4) << detailxshift; - ds_colshift = (screen->is8bit ? 0 : 2) + detailxshift; + if ((scrn->is8bit ? 1 : 4) << detailxshift != ds_colsize) { + ds_colsize = (scrn->is8bit ? 1 : 4) << detailxshift; + ds_colshift = (scrn->is8bit ? 0 : 2) + detailxshift; #ifdef USEASM ASM_PatchColSize (); #endif @@ -509,7 +510,6 @@ void V_Blit (screen_t *src, int srcx, int srcy, int srcwidth, int srcheight, // BOOL V_DoModeSetup (int width, int height, int id) { - int i; int bpp; CleanXfac = width / 320; @@ -517,24 +517,20 @@ BOOL V_DoModeSetup (int width, int height, int id) CleanWidth = width / CleanXfac; CleanHeight = height / CleanYfac; - // [RH] Screens are no longer byte arrays - for (i = 0; i < 1; i++) - if (screens[i].impdata) - V_FreeScreen (&screens[i]); + // Free the virtual framebuffer + V_FreeScreen (&screen); I_SetMode (width, height, id); bpp = (id == 1010) ? 8 : 32; - for (i = 0; i < 1; i++) { - if (!I_AllocateScreen (&screens[i], width, height, bpp)) - return false; - } + // Allocate a new virtual framebuffer + I_AllocateScreen (&screen, width, height, bpp); V_ForceBlend (0,0,0,0); if (bpp == 8) RefreshPalettes (); - R_InitColumnDrawers (screens[0].is8bit); + R_InitColumnDrawers (screen.is8bit); R_MultiresInit (); return true; @@ -545,12 +541,12 @@ BOOL V_SetResolution (int width, int height, int id) int oldwidth, oldheight; int oldID; - if (screens[0].impdata) { - oldwidth = screens[0].width; - oldheight = screens[0].height; + if (screen.impdata) { + oldwidth = screen.width; + oldheight = screen.height; oldID = DisplayID; } else { - // Harmless if screens[0] wasn't allocated + // Harmless if screen wasn't allocated oldwidth = width; oldheight = height; oldID = id; @@ -584,7 +580,7 @@ BOOL V_SetResolution (int width, int height, int id) void Cmd_Vid_SetMode (void *plyr, int argc, char **argv) { BOOL goodmode = false; - int width = 0, height = screens[0].height; + int width = 0, height = screen.height; int id = DisplayID; if (argc > 1) { @@ -692,11 +688,11 @@ void V_Init (void) if (!V_SetResolution (width, height, id)) { I_FatalError ("Could not set resolution to %d x %d (%s)", width, height, IdStrings[id-1000]); } else { - Printf (PRINT_HIGH, "Resolution: %d x %d (%s)\n", screens[0].width, screens[0].height, IdStrings[id-1000]); + Printf (PRINT_HIGH, "Resolution: %d x %d (%s)\n", screen.width, screen.height, IdStrings[id-1000]); } V_InitConChars (0xf7); - C_InitConsole (screens[0].width, screens[0].height, true); + C_InitConsole (screen.width, screen.height, true); V_Palette = DefaultPalette->colors; diff --git a/code/V_video.h b/code/V_video.h index b30d0b10b6..129330bb7f 100644 --- a/code/V_video.h +++ b/code/V_video.h @@ -62,9 +62,8 @@ typedef struct screen_s screen_t; extern palette_t *DefaultPalette; -// Screen 0 is the screen updated by I_Update screen. -// Screen 1 is used to be an extra buffer for wipes. -extern screen_t screens[1]; +// This is the screen updated by I_FinishUpdate. +extern screen_t screen; extern int dirtybox[4]; diff --git a/code/Wi_stuff.c b/code/Wi_stuff.c index d7947f78bd..b8c9e1e221 100644 --- a/code/Wi_stuff.c +++ b/code/Wi_stuff.c @@ -238,7 +238,7 @@ static char names[NUMEPISODES][NUMMAPS][8] = { // // Locally used stuff. // -#define FB (screens[0]) +#define FB (screen) // States for single-player @@ -356,7 +356,7 @@ static screen_t background; void WI_slamBackground (void) { V_Blit (&background, 0, 0, background.width, background.height, - &screens[0], 0, 0, screens[0].width, screens[0].height); + &FB, 0, 0, FB.width, FB.height); } static int WI_DrawName (char *str, int x, int y) @@ -1760,5 +1760,6 @@ void WI_Start (wbstartstruct_t *wbstartstruct) else WI_initStats(); V_SetBlend (0,0,0,0); + S_StopAllChannels (); SN_StopAllSequences (); } diff --git a/code/c_cmds.h b/code/c_cmds.h index af79014c6e..962b77035a 100644 --- a/code/c_cmds.h +++ b/code/c_cmds.h @@ -92,6 +92,7 @@ CMD(Cmd_ChangeMap) CMD(Cmd_Quit) CMD(Cmd_Puke) CMD(Cmd_Error) +CMD(Cmd_Dir) // d_net.c CMD(Cmd_Pings) diff --git a/code/c_consol.c b/code/c_consol.c index d89efbf9d6..fbd1c3ae9e 100644 --- a/code/c_consol.c +++ b/code/c_consol.c @@ -316,9 +316,9 @@ void C_AddNotifyString (int printlevel, const char *source) return; if (con_scaletext->value) - width = screens[0].width / CleanXfac; + width = screen.width / CleanXfac; else - width = screens[0].width; + width = screen.width; if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel) { sprintf (work, "%s%s", NotifyStrings[NUMNOTIFIES-1].text, source); @@ -518,14 +518,14 @@ void C_FlushDisplay (void) void C_AdjustBottom (void) { if (gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP) - ConBottom = screens[0].height; - else if (ConBottom > screens[0].height / 2 || ConsoleState == c_down) - ConBottom = screens[0].height / 2; + ConBottom = screen.height; + else if (ConBottom > screen.height / 2 || ConsoleState == c_down) + ConBottom = screen.height / 2; } void C_NewModeAdjust (void) { - C_InitConsole (screens[0].width, screens[0].height, true); + C_InitConsole (screen.width, screen.height, true); C_FlushDisplay (); C_AdjustBottom (); } @@ -560,13 +560,13 @@ void C_Ticker (void) } if (ConsoleState == c_falling) { - ConBottom += (gametic - lasttic) * (screens[0].height*2/25); - if (ConBottom >= screens[0].height / 2) { - ConBottom = screens[0].height / 2; + ConBottom += (gametic - lasttic) * (screen.height*2/25); + if (ConBottom >= screen.height / 2) { + ConBottom = screen.height / 2; ConsoleState = c_down; } } else if (ConsoleState == c_rising) { - ConBottom -= (gametic - lasttic) * (screens[0].height*2/25); + ConBottom -= (gametic - lasttic) * (screen.height*2/25); if (ConBottom <= 0) { ConsoleState = c_up; ConBottom = 0; @@ -661,18 +661,18 @@ void C_DrawConsole (void) int visheight, realheight; visheight = ConBottom; - realheight = (visheight * conback.height) / screens[0].height; + realheight = (visheight * conback.height) / screen.height; V_Blit (&conback, 0, conback.height - realheight, conback.width, realheight, - &screens[0], 0, 0, screens[0].width, visheight); + &screen, 0, 0, screen.width, visheight); if (ConBottom >= 12) { - V_PrintStr (screens[0].width - 8 - strlen(VersionString) * 8, + V_PrintStr (screen.width - 8 - strlen(VersionString) * 8, ConBottom - 12, VersionString, strlen (VersionString)); if (TickerMax) { char tickstr[256]; - unsigned int i, tickend = ConCols - screens[0].width / 90 - 6; + unsigned int i, tickend = ConCols - screen.width / 90 - 6; unsigned int tickbegin = 0; if (TickerLabel) { @@ -1117,7 +1117,7 @@ void C_MidPrint (char *msg) if (MidMsg) V_FreeBrokenLines (MidMsg); - if ( (MidMsg = V_BreakLines (con_scaletext->value ? screens[0].width / CleanXfac : screens[0].width, msg)) ) { + if ( (MidMsg = V_BreakLines (con_scaletext->value ? screen.width / CleanXfac : screen.width, msg)) ) { MidTicker = (int)(con_midtime->value * TICRATE) + gametic; for (i = 0; MidMsg[i].width != -1; i++) @@ -1143,7 +1143,7 @@ void C_DrawMid (void) } y = 8 * yscale; - x = screens[0].width >> 1; + x = screen.width >> 1; for (i = 0, line = (ST_Y * 3) / 8 - MidLines * 4 * yscale; i < MidLines; i++, line += y) { textfunc (PrintColors[PRINTLEVELS], x - (MidMsg[i].width >> 1) * xscale, diff --git a/code/ct_chat.c b/code/ct_chat.c index 41268e0c04..c32eabd313 100644 --- a/code/ct_chat.c +++ b/code/ct_chat.c @@ -199,14 +199,14 @@ void CT_Drawer (void) drawfunc = V_DrawWrapper; } - y += (screens[0].height == realviewheight && viewactive) ? screens[0].height : ST_Y; + y += (screen.height == realviewheight && viewactive) ? screen.height : ST_Y; promptwidth = V_StringWidth (prompt) * scalex; x = SHORT(hu_font['_' - HU_FONTSTART]->width) * scalex * 2 + promptwidth; // figure out if the text is wider than the screen. // if so, only draw the right-most portion of it. - for (i = len - 1; i >= 0 && x < screens[0].width; i--) + for (i = len - 1; i >= 0 && x < screen.width; i--) { c = toupper(ChatQueue[i] & 0x7f) - HU_FONTSTART; if (c < 0 || c >= HU_FONTSIZE) @@ -373,7 +373,7 @@ void HU_DrawScores (player_t *plyr) } } - x = (screens[0].width >> 1) - (((maxwidth + 32 + 32 + 16) * CleanXfac) >> 1); + x = (screen.width >> 1) - (((maxwidth + 32 + 32 + 16) * CleanXfac) >> 1); margin = x + 40 * CleanXfac; y = (ST_Y >> 1) - (MAXPLAYERS * 6); @@ -397,19 +397,19 @@ void HU_DrawScores (player_t *plyr) else sprintf (str, "Level ends in %02d:%02d", minutes, seconds); - V_DrawTextClean (CR_GREY, screens[0].width/2 - V_StringWidth (str)/2*CleanXfac, y - 12 * CleanYfac, str); + V_DrawTextClean (CR_GREY, screen.width/2 - V_StringWidth (str)/2*CleanXfac, y - 12 * CleanYfac, str); } for (i = 0; i < MAXPLAYERS && y < ST_Y - 12 * CleanYfac; i++) { int color = players[sortedplayers[i]].userinfo.color; if (playeringame[sortedplayers[i]]) { - if (screens[0].is8bit) + if (screen.is8bit) color = BestColor (DefaultPalette->basecolors, RPART(color), GPART(color), BPART(color), DefaultPalette->numcolors); - V_Clear (x, y, x + 24 * CleanXfac, y + SHORT(hu_font[0]->height) * CleanYfac, &screens[0], color); + V_Clear (x, y, x + 24 * CleanXfac, y + SHORT(hu_font[0]->height) * CleanYfac, &screen, color); sprintf (str, "%d", players[sortedplayers[i]].fragcount); V_DrawTextClean (sortedplayers[i] == player ? CR_GREEN : CR_BRICK, diff --git a/code/djgpp/I_input.c b/code/djgpp/I_input.c index 453672c7ca..098f4cfb50 100644 --- a/code/djgpp/I_input.c +++ b/code/djgpp/I_input.c @@ -12,13 +12,19 @@ #include "c_cvars.h" #include "i_video.h" +// from allegro.h +#define END_OF_FUNCTION(x) void x##_end() { } +#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void *)&x, sizeof(x)) +#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x, (long)x##_end - (long)x) static void I_StartupKeyboard (void); static void I_ShutdownKeyboard (void); +static void I_StartupMouse (void); +static void I_ShutdownMouse (void); +#if 0 static void I_StartupJoystick (void); static void I_JoystickEvents (void); -static void mouse_init (void); -static void mouse_uninit (void); +#endif #define KEYBOARDINT 9 @@ -28,17 +34,47 @@ static void mouse_uninit (void); #define _inbyte(x) (inp(x)) #define _inhword(x) (inpw(x)) -#define SC_RSHIFT 0x36 -#define SC_LSHIFT 0x2a -#define SC_UPARROW 0x48 -#define SC_DOWNARROW 0x50 -#define SC_LEFTARROW 0x4b -#define SC_RIGHTARROW 0x4d - +#define DIK_LSHIFT 0x2A +#define DIK_RSHIFT 0x36 +#define DIK_MULTIPLY 0x37 /* * on numeric keypad */ +#define DIK_1 0x02 +#define DIK_2 0x03 +#define DIK_3 0x04 +#define DIK_4 0x05 +#define DIK_5 0x06 +#define DIK_6 0x07 +#define DIK_7 0x08 +#define DIK_8 0x09 +#define DIK_9 0x0A +#define DIK_0 0x0B +#define DIK_NUMPAD7 0x47 +#define DIK_NUMPAD8 0x48 +#define DIK_NUMPAD9 0x49 +#define DIK_SUBTRACT 0x4A /* - on numeric keypad */ +#define DIK_NUMPAD4 0x4B +#define DIK_NUMPAD5 0x4C +#define DIK_NUMPAD6 0x4D +#define DIK_ADD 0x4E /* + on numeric keypad */ +#define DIK_NUMPAD1 0x4F +#define DIK_NUMPAD2 0x50 +#define DIK_NUMPAD3 0x51 +#define DIK_NUMPAD0 0x52 +#define DIK_DECIMAL 0x53 /* . on numeric keypad */ +#define DIK_DIVIDE 0xB5 /* / on numeric keypad */ +#define DIK_HOME 0xC7 /* Home on arrow keypad */ +#define DIK_UP 0xC8 /* UpArrow on arrow keypad */ +#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */ +#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */ +#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */ +#define DIK_END 0xCF /* End on arrow keypad */ +#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */ +#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */ +#define DIK_INSERT 0xD2 /* Insert on arrow keypad */ +#define DIK_DELETE 0xD3 /* Delete on arrow keypad */ #define KBDQUESIZE 32 static byte keyboardque[KBDQUESIZE]; -static int kbdtail, kbdhead; +static unsigned int kbdtail, kbdhead; static BOOL shiftdown; // Used by the console for making keys repeat @@ -46,6 +82,7 @@ int KeyRepeatDelay; int KeyRepeatRate; extern constate_e ConsoleState; +extern BOOL menuactive; cvar_t *i_remapkeypad; cvar_t *usejoystick; @@ -56,7 +93,7 @@ BOOL I_InitInput (void) atexit (I_ShutdownInput); Printf (PRINT_HIGH, "I_StartupMouse\n"); - mouse_init (); + I_StartupMouse (); // Printf (PRINT_HIGH, "I_StartupJoystick\n"); // I_StartupJoystick (); Printf (PRINT_HIGH, "I_StartupKeyboard\n"); @@ -72,7 +109,7 @@ BOOL I_InitInput (void) // Free all input resources void I_ShutdownInput (void) { - mouse_uninit (); + I_ShutdownMouse (); I_ShutdownKeyboard (); } @@ -118,8 +155,6 @@ static const byte Convert_Shift [256] = static _go32_dpmi_seginfo oldkeyboardisr, newkeyboardisr; static BOOL keyboardinited; -static int lastpress; - /* ================ = @@ -133,7 +168,7 @@ void I_KeyboardISR (void) asm volatile ("cli; pusha"); // Get the scan code - keyboardque[kbdhead&(KBDQUESIZE-1)] = lastpress = _inbyte(0x60); + keyboardque[kbdhead&(KBDQUESIZE-1)] = _inbyte(0x60); kbdhead++; // acknowledge the interrupt @@ -141,16 +176,16 @@ void I_KeyboardISR (void) _outbyte(0x20,0x20); asm volatile ("popa; sti"); } -void __End_of_I_KeyboardISR (void) { } + +END_OF_FUNCTION(I_KeyboardISR) static void I_StartupKeyboard (void) { #ifndef NOKBD - _go32_dpmi_lock_code (I_KeyboardISR, (long)__End_of_I_KeyboardISR - (long)I_KeyboardISR); - _go32_dpmi_lock_data ((void *)keyboardque, sizeof(keyboardque)); - _go32_dpmi_lock_data ((void *)kbdhead, sizeof(kbdhead)); - _go32_dpmi_lock_data ((void *)lastpress, sizeof(lastpress)); + LOCK_FUNCTION (I_KeyboardISR); + LOCK_VARIABLE (keyboardque); + LOCK_VARIABLE (kbdhead); asm volatile ("cli"); newkeyboardisr.pm_offset = (int)I_KeyboardISR; @@ -190,17 +225,13 @@ static void I_ReadKeyboard (void) k = keyboardque[kbdtail&(KBDQUESIZE-1)]; kbdtail++; - if (k == lastk) - continue; // ignore repeating keys - - lastk = k; // extended keyboard shift key bullshit - if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT ) + if ( (k&0x7f)==DIK_LSHIFT || (k&0x7f)==DIK_RSHIFT ) { if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 ) continue; k &= 0x80; - k |= SC_LSHIFT; + k |= DIK_LSHIFT; } if (k==0xe0) @@ -245,17 +276,108 @@ static void I_ReadKeyboard (void) } } - ev.data1 = k; + if ((k | (ev.type<<8)) == lastk) + continue; // ignore repeating keys + + lastk = k | (ev.type<<8); ev.data2 = 0; switch (k) { - case SC_LSHIFT: + case DIK_LSHIFT: shiftdown = ev.type == ev_keydown; break; default: + if (!menuactive && + (ConsoleState == c_falling || ConsoleState == c_down)) { + switch (k) { + case DIK_NUMPAD4: + k = DIK_4; + break; + case DIK_NUMPAD6: + k = DIK_6; + break; + case DIK_NUMPAD8: + k = DIK_8; + break; + case DIK_NUMPAD2: + k = DIK_2; + break; + case DIK_NUMPAD7: + k = DIK_7; + break; + case DIK_NUMPAD9: + k = DIK_9; + break; + case DIK_NUMPAD3: + k = DIK_3; + break; + case DIK_NUMPAD1: + k = DIK_1; + break; + case DIK_NUMPAD0: + k = DIK_0; + break; + case DIK_NUMPAD5: + k = DIK_5; + break; + } + } else if (i_remapkeypad->value) { + switch (k) { + case DIK_NUMPAD4: + k = DIK_LEFT; + break; + case DIK_NUMPAD6: + k = DIK_RIGHT; + break; + case DIK_NUMPAD8: + k = DIK_UP; + break; + case DIK_NUMPAD2: + k = DIK_DOWN; + break; + case DIK_NUMPAD7: + k = DIK_HOME; + break; + case DIK_NUMPAD9: + k = DIK_PRIOR; + break; + case DIK_NUMPAD3: + k = DIK_NEXT; + break; + case DIK_NUMPAD1: + k = DIK_END; + break; + case DIK_NUMPAD0: + k = DIK_INSERT; + break; + case DIK_DECIMAL: + k = DIK_DELETE; + break; + } + } ev.data2 = Convert[k]; break; } + ev.data1 = k; + if (ConsoleState == c_falling || ConsoleState == c_down) { + switch (k) { + case DIK_DIVIDE: + ev.data2 = '/'; + break; + case DIK_MULTIPLY: + ev.data2 = '*'; + break; + case DIK_ADD: + ev.data2 = '+'; + break; + case DIK_SUBTRACT: + ev.data2 = '-'; + break; + case DIK_DECIMAL: + ev.data2 = '.'; + break; + } + } if (shiftdown) ev.data3 = Convert_Shift[k]; else @@ -270,7 +392,7 @@ static void I_ReadKeyboard (void) static BOOL mouse_present; static int num_buttons; -static void mouse_init (void) +static void I_StartupMouse (void) { __dpmi_regs r; @@ -290,7 +412,7 @@ static void mouse_init (void) num_buttons = 4; } -static void mouse_uninit (void) +static void I_ShutdownMouse (void) { // We don't need to do anything here. } diff --git a/code/djgpp/I_sound.c b/code/djgpp/I_sound.c index d847b01fa0..6bee76d7b3 100644 --- a/code/djgpp/I_sound.c +++ b/code/djgpp/I_sound.c @@ -113,25 +113,16 @@ void MIDASerror(void) /* Loads a sound and adds it to MIDAS * Really returns a MIDAS sample handle */ -static void *getsfx (sfxinfo_t *sfx) +static void getsfx (sfxinfo_t *sfx) { char sndtemp[128]; byte *sfxdata; + byte *sfxcopy; int size; int i; int error; static sdSample smp; - unsigned sampleHandle; - - /* No loop: */ - smp.loopMode = sdLoopNone; - smp.loop1Start = smp.loop1End = 0; - smp.loop1Type = loopNone; - - /* No loop 2: */ - smp.loop2Start = smp.loop2End = 0; - smp.loop2Type = loopNone; // Get the sound data from the WAD and register it with MIDAS @@ -161,7 +152,9 @@ badwave: DPrintf ("Linked to %s (%d)\n", S_sfx[i].name, i); sfx->link = S_sfx + i; sfx->ms = S_sfx[i].ms; - return S_sfx[i].data; + sfx->data = S_sfx[i].data; + sfx->loopdata = S_sfx[i].loopdata; + return; } size = W_LumpLength (sfx->lumpnum); @@ -277,30 +270,44 @@ badwave: } } + /* No loop 2: */ + smp.loop2Start = smp.loop2End = 0; + smp.loop2Type = loopNone; + + sfxcopy = Malloc (smp.sampleLength); + memcpy (sfxcopy, smp.sample, smp.sampleLength); + Z_Free (sfxdata); + smp.sample = sfxcopy; + /* Add the sample to the Sound Device: */ -#ifdef _MSC_VER { // Avoid using __fastcall for this function - typedef int (__cdecl *blargh_t)(sdSample*, int, unsigned *); + typedef int (STACK_ARGS *blargh_t)(sdSample*, int, unsigned *); blargh_t blargh = (blargh_t)midasSD->AddSample; - if ( (error = blargh (&smp, 1, &sampleHandle)) != OK) + /* No loop: */ + smp.loopMode = sdLoopNone; + smp.loop1Start = smp.loop1End = 0; + smp.loop1Type = loopNone; + + if ( (error = blargh (&smp, 0, (unsigned *)&sfx->data)) != OK) + I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); + + /* With loop: */ + smp.loopMode = sdLoop1; + smp.loop1Start = 0; + smp.loop1End = smp.sampleLength; + smp.loop1Type = loopUnidir; + + if ( (error = blargh (&smp, 0, (unsigned *)&sfx->loopdata)) != OK) I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); } -#else - if ( (error = midasSD->AddSample (&smp, 1, &sampleHandle)) != OK) - I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); -#endif // Remove the cached lump. - Z_Free (sfxdata); if (sfx->frequency == 0) sfx->frequency = 11025; sfx->ms = (sfx->ms * 1000) / (sfx->frequency); - - /* Return sample handle: (damn ugly) */ - return (void*) sampleHandle; } @@ -354,7 +361,7 @@ void I_SetSfxVolume (int volume) // e.g. a pointer to the raw data, // it is ignored. // -int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel) +int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel, BOOL looping) { int id = sfx - S_sfx; int volume; @@ -375,7 +382,9 @@ int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel) else if ( pan > MIDAS_PAN_RIGHT) pan = MIDAS_PAN_RIGHT; } - ChannelMap[channel].playHandle = MIDASplaySample ((MIDASsample)sfx->data, + ChannelMap[channel].playHandle = MIDASplaySample ( + looping ? (MIDASsample)sfx->loopdata + : (MIDASsample)sfx->data, ChannelMap[channel].midasChannel, 0, PITCH(sfx->frequency,pitch), @@ -451,7 +460,7 @@ void I_LoadSound (struct sfxinfo_struct *sfx) int i = sfx - S_sfx; DPrintf ("loading sound \"%s\" (%d)\n", sfx->name, i); - sfx->data = getsfx (sfx); + getsfx (sfx); } } @@ -602,10 +611,15 @@ void STACK_ARGS I_ShutdownSound (void) // [RH] Free all loaded samples for (i = 0; i < numsfx; i++) { - if (S_sfx[i].data && !S_sfx[i].link) { - MIDASfreeSample ((MIDASsample)S_sfx[i].data); - len += S_sfx[i].length; - c++; + if (!S_sfx[i].link) { + if (S_sfx[i].data) { + MIDASfreeSample ((MIDASsample)S_sfx[i].data); + len += S_sfx[i].length; + c++; + } + if (S_sfx[i].loopdata) { + MIDASfreeSample ((MIDASsample)S_sfx[i].loopdata); + } } S_sfx[i].data = S_sfx[i].link = NULL; } diff --git a/code/djgpp/I_sound.h b/code/djgpp/I_sound.h index 64973eedb8..cad2b26ba7 100644 --- a/code/djgpp/I_sound.h +++ b/code/djgpp/I_sound.h @@ -34,22 +34,30 @@ void I_InitSound(); // ... shut down and relase at program termination. -void I_ShutdownSound(void); +void STACK_ARGS I_ShutdownSound (void); -void I_SetSfxVolume(int volume); +void I_SetSfxVolume (int volume); // // SFX I/O // // Initialize channels -void I_SetChannels(); +void I_SetChannels (int); // load a sound from disk void I_LoadSound (struct sfxinfo_struct *sfx); // Starts a sound in a particular sound channel. -int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int priority); +int +I_StartSound +( struct sfxinfo_struct *sfx, + int vol, + int sep, + int pitch, + int channel, + BOOL looping ); + // Stops a sound channel. void I_StopSound(int handle); @@ -61,6 +69,11 @@ int I_SoundIsPlaying(int handle); // Updates the volume, separation, // and pitch of a sound channel. -void I_UpdateSoundParams (int handle, int vol, int sep, int pitch); +void +I_UpdateSoundParams +( int handle, + int vol, + int sep, + int pitch ); #endif diff --git a/code/djgpp/I_system.c b/code/djgpp/I_system.c index 0cc52eb272..68a443cad9 100644 --- a/code/djgpp/I_system.c +++ b/code/djgpp/I_system.c @@ -320,3 +320,23 @@ void I_PrintStr (int xp, const char *cp, int count, BOOL scroll) { fputs (string, stdout); fflush (stdout); } + +long I_FindFirst (char *filespec, findstate_t *fileinfo) +{ + int res; + + res = findfirst (filespec, fileinfo, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | + FA_DIREC | FA_ARCH); + + return res ? -1 : 1; +} + +int I_FindNext (long handle, findstate_t *fileinfo) +{ + return findnext (fileinfo); +} + +int I_FindClose (long handle) +{ + return 0; +} diff --git a/code/djgpp/I_system.h b/code/djgpp/I_system.h index 9708167ebc..9ed39f2a5f 100644 --- a/code/djgpp/I_system.h +++ b/code/djgpp/I_system.h @@ -22,6 +22,8 @@ #ifndef __I_SYSTEM__ #define __I_SYSTEM__ +#include + #include "d_ticcmd.h" #include "d_event.h" @@ -101,4 +103,15 @@ unsigned int I_MSTime (void); // [RH] Title string to display at bottom of console during startup extern char DoomStartupTitle[256]; +// Directory searching routines + +typedef struct ffblk findstate_t; + +long I_FindFirst (char *filespec, findstate_t *fileinfo); +int I_FindNext (long handle, findstate_t *fileinfo); +int I_FindClose (long handle); + +#define I_FindName(a) ((a)->ff_name) +#define I_FindAttr(a) ((a)->ff_attrib) + #endif diff --git a/code/djgpp/I_video.cpp b/code/djgpp/I_video.cpp index bf1de02ed8..29ca668068 100644 --- a/code/djgpp/I_video.cpp +++ b/code/djgpp/I_video.cpp @@ -201,7 +201,7 @@ void I_ShutdownGraphics (void) // void I_BeginUpdate (void) { - V_LockScreen (&screens[0]); + V_LockScreen (&screen); } // @@ -209,7 +209,7 @@ void I_BeginUpdate (void) // void I_FinishUpdateNoBlit (void) { - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); } // @@ -229,14 +229,14 @@ void I_FinishUpdate (void) if (tics > 20) tics = 20; for (i = 0; i < tics * 2; i += 2) - screens[0].buffer[ (screens[0].height-1)*screens[0].pitch + i] = 0xff; + screen.buffer[ (screen.height-1)*screen.pitch + i] = 0xff; for (; i < 20*2; i +=2 ) - screens[0].buffer[ (screens[0].height-1)*screens[0].pitch + i] = 0x0; + screen.buffer[ (screen.height-1)*screen.pitch + i] = 0x0; } - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); - ((Surface *)(screens[0].impdata))->Update (); + ((Surface *)(screen.impdata))->Update (); } @@ -248,16 +248,16 @@ void I_ReadScreen (byte *scr) int x, y; byte *source; - V_LockScreen (&screens[0]); + V_LockScreen (&screen); - for (y = 0; y < screens[0].height; y++) { - source = screens[0].buffer + y * screens[0].pitch; - for (x = 0; x < screens[0].width; x++) { + for (y = 0; y < screen.height; y++) { + source = screen.buffer + y * screen.pitch; + for (x = 0; x < screen.width; x++) { *scr++ = *source++; } } - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); } @@ -284,8 +284,8 @@ void I_SetPalette (unsigned int *pal) DisPal->Unlock (); - if (screens[0].is8bit) - ((Surface *)(screens[0].impdata))->SetPalette (*DisPal); + if (screen.is8bit) + ((Surface *)(screen.impdata))->SetPalette (*DisPal); // Only set the display palette if it is indexed color FORMAT format = ptc.GetFormat (); @@ -320,8 +320,8 @@ void I_SetMode (int width, int height, int id) mode.x, mode.y, IdStrings[DisplayID-1000]); } - // cheapo hack to make sure current display BPP is stored in screens[0] - screens[0].Bpp = IdTobpp[DisplayID-1000] >> 3; + // cheapo hack to make sure current display BPP is stored in screen + screen.Bpp = IdTobpp[DisplayID-1000] >> 3; } static void refreshDisplay (void) { @@ -414,7 +414,7 @@ void Cmd_Vid_DescribeModes (struct player_s *p, int argc, char **argv) void Cmd_Vid_DescribeCurrentMode (struct player_s *p, int argc, char **argv) { - Printf (PRINT_HIGH, "%dx%d (%s)\n", screens[0].width, screens[0].height, IdStrings[DisplayID-1000]); + Printf (PRINT_HIGH, "%dx%d (%s)\n", screen.width, screen.height, IdStrings[DisplayID-1000]); } @@ -435,7 +435,7 @@ BOOL I_AllocateScreen (screen_t *scrn, int width, int height, int Bpp) scrn->Bpp = IdTobpp[DisplayID-1000] >> 3; scrn->palette = NULL; - if (scrn == &screens[0]) { + if (scrn == &screen) { surface = new Surface (ptc, width, height, (Bpp == 8) ? INDEX8 : ARGB8888); } else { surface = new Surface (width, height, (Bpp == 8) ? INDEX8 : ARGB8888); diff --git a/code/docs/Rh-log.txt b/code/docs/Rh-log.txt index 0ff046fe54..d5dd481e13 100644 --- a/code/docs/Rh-log.txt +++ b/code/docs/Rh-log.txt @@ -1,3 +1,82 @@ +February 21, 1999 +- Found a problem with sliding polyobj doors: If, when they try to close, + they can't move anywhere from their open position, they would move + slightly further open and leave a gap when they managed to close. Fixed. +- Added support for auto-loading of skins if they're in a skins directory + in the same directory as the executable. +- Added support for C-style formatting codes to ACS print statements. +- Fixed a problem where, when a player turns into a pile of bloody gibs + (from e.g. a crushing ceiling), they would assume their standing position. + This is because the gibs are a different sprite, and I wasn't letting + player mobjs change their sprite. +- Fixed ceilings so that they stop making noise when they get put in stasis. +- PIT_ChangeSector() can spawn particle blood now. +- Fixed R_DrawSplash2() so that it doesn't draw all the particles to the + left of the impact point. +- Added an A_MonsterRail function so monsters can shoot a railgun too. +- Fixed the railgun sound when you're not the one shooting it. My algorithm + for finding the closest point on the line was wrong and still should + remnants from when I was calculating the distance from the line. +- Fixed some player bobbing problems. + +February 20, 1999 +- Changed sparks to play with static attenuation. +- Found out why pickup messages would sometimes seemingly print several + times for a single item. Some maps have several of the same item on top + of each other so that a player can get more than they would normally + without even realizing it. I get around this by disallowing two identical + pickup messages from being printed back-to-back in a single tic. +- Fixed transsouls. I wasn't calling its callback at initialization, so it + wouldn't take effect until the next time it was changed at the console. +- Recompiled PTC with DDFLIP_WAIT enabled. I had accidentally left it off + from my testing run on January 8. +- Dug up the DirectDraw code from 1.12 and used it to add DirectDraw support + back into the game. Now even people who can't get PTC to work should be + able to use it. + One interesting thing I noticed is that IDirectDrawSurface's Blt method + is horribly slow for blitting between system and video memory. I tried it, + thinking it would be optimized, but it wasn't even close. +- Added the A_Die, A_Detonate, and A_Mushroom routines from MBF. +- Removed the screens array and replaced it with a single variable named + (oddly enough) screen. +- Added a V_SetBlend() to F_StartFinale() to get rid of any palette flashes + that might have been on screen (such as after finishing E1M8). +- Discovered the real reason why the brain shooter wasn't working. DOOM + doesn't explode noclip missiles when they go above the ceiling or below + the floor; it just adjusts their positions. Hexen doesn't have that check + for noclip, so it will explode/remove it. I guess I didn't check MAP30 + after adding Hexen's z-checking. + +February 19, 1999 +- Finally got around to fixing V_DrawPatchFlipped(). Wow, that was easy. I + wonder why I was having so much trouble with it the last time I touched it + many months ago. +- Changed the item pickup sounds to play with a NULL entity for the local + player (like before), but still play on CHAN_ITEM for other players. +- Fixed the problem of monster names not being drawn in the cast finale: I + was still xoring each character with 0x80 to make it red under the old + text system. +- Changed the keyboard code so that the keypad isn't translated into number + keys in full console mode with the menu active. +- Fixed the Read This! sequence of menus in Ultimate Doom. When it's + finished, it's supposed to re-enable the skull and empty the stack. +- Fixed a problem with raise doors. In Doom, you can close them prematurely + by activating them again. I had the right idea: + if (GET_SPAC(line->flags) == SPAC_PUSH) + but it should have been + if (GET_SPAC(line->flags) != SPAC_PUSH) + +February 18, 1999 +- Release 1.17 again, hopefully this time for good. +- Fixed some problems that were already found with 1.17: + * The cubes spawned by the boss on DOOM2/MAP30 would be in the ceiling and + disappear right away. (All I can say is that it worked before; I don't + know why it stopped.) + * Because of my quick hack for voodoo doll obituaries, getting killed by + the world would crash. + * Open scripts above 255 wouldn't properly restart when the level + reloaded because the game thought they were still running. + February 17, 1999 - Made a final "final" compile of 1.17. - Removed the hack that could transform normal exits into Teleport_NewMaps diff --git a/code/m_option.c b/code/m_option.c index 139a00b224..dabade07b6 100644 --- a/code/m_option.c +++ b/code/m_option.c @@ -589,12 +589,12 @@ void M_DrawSlider (int x, int y, float min, float max, float cur) cur -= min; - V_DrawPatchClean (x, y, &screens[0], W_CacheLumpName ("LSLIDE", PU_CACHE)); + V_DrawPatchClean (x, y, &screen, W_CacheLumpName ("LSLIDE", PU_CACHE)); for (i = 1; i < 11; i++) - V_DrawPatchClean (x + i*8, y, &screens[0], W_CacheLumpName ("MSLIDE", PU_CACHE)); - V_DrawPatchClean (x + 88, y, &screens[0], W_CacheLumpName ("RSLIDE", PU_CACHE)); + V_DrawPatchClean (x + i*8, y, &screen, W_CacheLumpName ("MSLIDE", PU_CACHE)); + V_DrawPatchClean (x + 88, y, &screen, W_CacheLumpName ("RSLIDE", PU_CACHE)); - V_DrawPatchClean (x + 5 + (int)((cur * 78.0) / range), y, &screens[0], W_CacheLumpName ("CSLIDE", PU_CACHE)); + V_DrawPatchClean (x + 5 + (int)((cur * 78.0) / range), y, &screen, W_CacheLumpName ("CSLIDE", PU_CACHE)); } int M_FindCurVal (float cur, value_t *values, int numvals) @@ -617,7 +617,7 @@ void M_OptDrawer (void) title = W_CacheLumpName (CurrentMenu->title, PU_CACHE); - V_DrawPatchClean (160-title->width/2,10,&screens[0],title); + V_DrawPatchClean (160-title->width/2,10,&screen,title); // for (i = 0, y = 20 + title->height; i < CurrentMenu->numitems; i++, y += 8) { for (i = 0, y = 15 + title->height; i < CurrentMenu->numitems; i++, y += 8) { // TIJ @@ -710,7 +710,7 @@ void M_OptDrawer (void) } if (i == CurrentItem && (skullAnimCounter < 6 || WaitingForKey)) { - V_DrawPatchClean (CurrentMenu->indent + 3, y, &screens[0], W_CacheLumpName ("LITLCURS", PU_CACHE)); + V_DrawPatchClean (CurrentMenu->indent + 3, y, &screen, W_CacheLumpName ("LITLCURS", PU_CACHE)); } } else { @@ -740,7 +740,7 @@ void M_OptDrawer (void) } if (i == CurrentItem && ((item->a.selmode != -1 && (skullAnimCounter < 6 || WaitingForKey)) || testingmode)) { - V_DrawPatchClean (item->a.selmode * 104 + 8, y, &screens[0], W_CacheLumpName ("LITLCURS", PU_CACHE)); + V_DrawPatchClean (item->a.selmode * 104 + 8, y, &screen, W_CacheLumpName ("LITLCURS", PU_CACHE)); } } @@ -868,7 +868,7 @@ void M_OptResponder (event_t *ev) // Hack hack. Rebuild list of resolutions if (item->e.values == Depths) - BuildModesList (screens[0].width, screens[0].height, DisplayID); + BuildModesList (screen.width, screen.height, DisplayID); } S_Sound (NULL, CHAN_VOICE, "plats/pt1_mid", 1, ATTN_NONE); break; @@ -929,7 +929,7 @@ void M_OptResponder (event_t *ev) // Hack hack. Rebuild list of resolutions if (item->e.values == Depths) - BuildModesList (screens[0].width, screens[0].height, DisplayID); + BuildModesList (screen.width, screen.height, DisplayID); } S_Sound (NULL, CHAN_VOICE, "plats/pt1_mid", 1, ATTN_NONE); break; @@ -973,8 +973,8 @@ void M_OptResponder (event_t *ev) SetCVarFloat (fullscreen, DummyFSCvar.value); #endif if (!(item->type == screenres && GetSelectedSize (CurrentItem, &NewWidth, &NewHeight))) { - NewWidth = screens[0].width; - NewHeight = screens[0].height; + NewWidth = screen.width; + NewHeight = screen.height; } NewID = IDTranslate[(int)DummyDepthCvar.value]; setmodeneeded = true; @@ -997,7 +997,7 @@ void M_OptResponder (event_t *ev) // Hack hack. Rebuild list of resolutions if (item->e.values == Depths) - BuildModesList (screens[0].width, screens[0].height, DisplayID); + BuildModesList (screen.width, screen.height, DisplayID); S_Sound (NULL, CHAN_VOICE, "plats/pt1_mid", 1, ATTN_NONE); } else if (item->type == control) { @@ -1028,11 +1028,11 @@ void M_OptResponder (event_t *ev) SetCVarFloat (fullscreen, DummyFSCvar.value); #endif if (!(item->type == screenres && GetSelectedSize (CurrentItem, &NewWidth, &NewHeight))) { - NewWidth = screens[0].width; - NewHeight = screens[0].height; + NewWidth = screen.width; + NewHeight = screen.height; } - OldWidth = screens[0].width; - OldHeight = screens[0].height; + OldWidth = screen.width; + OldHeight = screen.height; OldID = DisplayID; NewID = IDTranslate[(int)DummyDepthCvar.value]; setmodeneeded = true; @@ -1042,10 +1042,10 @@ void M_OptResponder (event_t *ev) } } else if (ev->data2 == 'd' && CurrentMenu == &ModesMenu) { // Make current resolution the default - SetCVarFloat (vid_defwidth, (float)screens[0].width); - SetCVarFloat (vid_defheight, (float)screens[0].height); + SetCVarFloat (vid_defwidth, (float)screen.width); + SetCVarFloat (vid_defheight, (float)screen.height); SetCVar (vid_defid, IdStrings[DisplayID-1000]); - SetModesMenu (screens[0].width, screens[0].height, DisplayID); + SetModesMenu (screen.width, screen.height, DisplayID); } break; } @@ -1248,7 +1248,7 @@ void M_RestoreMode (void) static void SetVidMode (void) { - SetModesMenu (screens[0].width, screens[0].height, DisplayID); + SetModesMenu (screen.width, screen.height, DisplayID); if (ModesMenu.items[ModesMenu.lastOn].type == screenres) { if (ModesMenu.items[ModesMenu.lastOn].a.selmode == -1) { ModesMenu.items[ModesMenu.lastOn].a.selmode++; diff --git a/code/p_acs.c b/code/p_acs.c index 56a34ad2f5..caef6e10d7 100644 --- a/code/p_acs.c +++ b/code/p_acs.c @@ -14,15 +14,16 @@ #include "c_consol.h" #include "s_sndseq.h" +#define NEXTWORD (*(script->pc)++) +#define STACK(a) (script->stack[script->sp - (a)]) + +void strbin (char *str); script_t *LastScript; script_t *Scripts; script_t *RunningScripts[1000]; -#define NEXTWORD (*(script->pc)++) -#define STACK(a) (script->stack[script->sp - (a)]) - void P_ClearScripts (void) { int i; @@ -784,7 +785,10 @@ static void T_ACS (script_t *script) script->sp = script->stringstart; if (pcd == PCD_ENDPRINTBOLD || script->activator == NULL || (script->activator->player - players == consoleplayer)) + { + strbin (work); C_MidPrint (work); + } } break; @@ -1085,3 +1089,75 @@ void P_TerminateScript (int script, char *map) else SetScriptState (script, removeThisThingNow); } + +void strbin (char *str) +{ + char *p = str, c; + int i; + + while ( (c = *p++) ) { + if (c != '\\') { + *str++ = c; + } else { + switch (*p) { + case 'c': + *str++ = '\x8a'; + break; + case 'n': + *str++ = '\n'; + break; + case 't': + *str++ = '\t'; + break; + case 'r': + *str++ = '\r'; + break; + case '\n': + break; + case 'x': + case 'X': + c = 0; + p++; + for (i = 0; i < 2; i++) { + c <<= 4; + if (*p >= '0' && *p <= '9') + c += *p-'0'; + else if (*p >= 'a' && *p <= 'f') + c += 10 + *p-'a'; + else if (*p >= 'A' && *p <= 'F') + c += 10 + *p-'A'; + else + break; + p++; + } + *str++ = c; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + c = 0; + for (i = 0; i < 3; i++) { + c <<= 3; + if (*p >= '0' && *p <= '7') + c += *p-'0'; + else + break; + p++; + } + *str++ = c; + break; + default: + *str++ = *p; + break; + } + p++; + } + } + *str = 0; +} + diff --git a/code/p_effect.c b/code/p_effect.c index bd4eb9dd97..3be03666cc 100644 --- a/code/p_effect.c +++ b/code/p_effect.c @@ -292,7 +292,6 @@ void P_DrawSplash (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, in void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int updown, int kind) { int color1, color2, zvel, zspread, zadd; - angle_t perpan; switch (kind) { case 0: // Blood @@ -313,10 +312,8 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i zvel = -128; zspread = updown ? -6000 : 6000; - perpan = angle - ANG90; zadd = (updown == 2) ? -128 : 0; - for (; count; count--) { particle_t *p = NewParticle (); angle_t an; @@ -339,7 +336,7 @@ void P_DrawSplash2 (int count, fixed_t x, fixed_t y, fixed_t z, angle_t angle, i p->accy = p->vely >> 4; } p->z = z + (M_Random () + zadd) * zspread; - an = (perpan + ((M_Random() - 128) << 22)) >> ANGLETOFINESHIFT; + an = (angle + ((M_Random() - 128) << 22)) >> ANGLETOFINESHIFT; p->x = x + (M_Random () & 31)*finecosine[an]; p->y = y + (M_Random () & 31)*finesine[an]; } @@ -357,27 +354,30 @@ void P_DrawRailTrail (vec3_t start, vec3_t end) steps = (int)(length*0.3333f); if (length) { - // The railgun's sound is a special case. How loud it sounds to a player - // depends on how far the player is from the slug's path (not the start - // of the path). The sound is also not attenuated once it start's either. + // The railgun's sound is a special case. It gets played from the + // point on the slug's trail that is closest to the hearing player. mobj_t *mo = players[consoleplayer].camera; vec3_t point; - float dist; + float r; + float dirz; length = 1 / length; - if ((mo->x & ~65535) == (FLOAT2FIXED(start[0]) & ~65535) - && (mo->y & ~65535) == (FLOAT2FIXED(start[1]) & ~65535)) - { // This player fired the railgun + if (abs(mo->x - FLOAT2FIXED(start[0])) < 20 * FRACUNIT + && (mo->y - FLOAT2FIXED(start[1])) < 20 * FRACUNIT) + { // This player (probably) fired the railgun S_Sound (mo, CHAN_WEAPON, "weapons/railgf", 1, ATTN_NORM); } else { // Only consider sound in 2D (for now, anyway) - dist = (float)fabs (((start[1] - FIXED2FLOAT(mo->y)) * (start[1] - end[1]) - - (start[0] - FIXED2FLOAT(mo->x)) * (start[0] - end[0])) * length); + r = ((start[1] - FIXED2FLOAT(mo->y)) * (-dir[1]) - + (start[0] - FIXED2FLOAT(mo->x)) * (dir[0])) * length * length; - VectorMA (start, dist, dir, point); + dirz = dir[2]; + dir[2] = 0; + VectorMA (start, r, dir, point); + dir[2] = dirz; S_PositionedSound (FLOAT2FIXED(point[0]), FLOAT2FIXED(point[1]), CHAN_WEAPON, "weapons/railgf", 1, ATTN_NORM); diff --git a/code/p_things.c b/code/p_things.c index 2bdaccc7b9..9f5984816e 100644 --- a/code/p_things.c +++ b/code/p_things.c @@ -282,7 +282,7 @@ BOOL P_ActivateMobj (mobj_t *mobj) P_DrawSplash (count, mobj->x, mobj->y, mobj->z, mobj->angle, 1); sprintf (sound, "world/spark%d", 1+(M_Random() % 3)); - S_Sound (mobj, CHAN_AUTO, sound, 1, ATTN_IDLE); + S_Sound (mobj, CHAN_AUTO, sound, 1, ATTN_STATIC); break; } case MT_FOUNTAIN: diff --git a/code/s_sndseq.c b/code/s_sndseq.c index 6cdc92d648..f18863307c 100644 --- a/code/s_sndseq.c +++ b/code/s_sndseq.c @@ -492,12 +492,17 @@ void SN_UpdateActiveSequences (void) } for (node = SequenceListHead; node; node = node->next) { - if (node->delayTics) + if (node->delayTics > 0) { node->delayTics--; continue; } sndPlaying = S_GetSoundPlayingInfo (node->mobj, node->currentSoundID); + if (node->delayTics < 0 && sndPlaying) + { + node->delayTics++; + continue; + } switch (GetCommand(*node->sequencePtr)) { case SS_CMD_PLAY: @@ -524,16 +529,16 @@ void SN_UpdateActiveSequences (void) // Does not advance sequencePtr, so it will repeat // as necessary node->currentSoundID = GetData(*node->sequencePtr); - S_SoundID (node->mobj, CHAN_BODY, node->currentSoundID, + S_LoopedSoundID (node->mobj, CHAN_BODY, node->currentSoundID, node->volume, node->atten); } break; case SS_CMD_PLAYLOOP: - S_SoundID (node->mobj, CHAN_BODY, GetData(*node->sequencePtr), + node->currentSoundID = GetData(*node->sequencePtr); + S_LoopedSoundID (node->mobj, CHAN_BODY, node->currentSoundID, node->volume, node->atten); - node->currentSoundID = -1; - node->delayTics = GetData(*(node->sequencePtr+1)); + node->delayTics = -(signed)GetData(*(node->sequencePtr+1)); break; case SS_CMD_DELAY: diff --git a/code/v_draw.c b/code/v_draw.c index 9afea593b5..14ef95282f 100644 --- a/code/v_draw.c +++ b/code/v_draw.c @@ -400,7 +400,7 @@ void V_DrawWrapper (int drawer, int x, int y, screen_t *scrn, patch_t *patch) pitch = scrn->pitch; - if (scrn == &screens[0]) + if (scrn == &screen) V_MarkRect (x, y, SHORT(patch->width), SHORT(patch->height)); col = 0; @@ -486,7 +486,7 @@ void V_DrawSWrapper (int drawer, int x0, int y0, screen_t *scrn, patch_t *patch, colstep = 4; } - if (scrn == &screens[0]) + if (scrn == &screen) V_MarkRect (x0, y0, destwidth, destheight); col = 0; @@ -594,14 +594,77 @@ void V_CopyRect (int srcx, int srcy, screen_t *srcscrn, int width, int height, // Masks a column based masked pic to the screen. // Flips horizontally, e.g. to mirror face. // -// [RH] This is only called in f_finale.c, so I changed it to behave -// much like V_DrawPatchIndirect() instead of adding yet another function -// solely to handle virtual stretching of this function. +// Like V_DrawIWrapper except it only uses one drawing function and draws +// the patch flipped horizontally. // void V_DrawPatchFlipped (int x0, int y0, screen_t *scrn, patch_t *patch) { - // I must be dumb or something... - V_DrawPatchIndirect (x0, y0, scrn, patch); + column_t* column; + byte* desttop; + int pitch; + vdrawsfunc drawfunc; + int colstep; + int destwidth, destheight; + + int xinc, yinc, col, w, ymul, xmul; + + x0 = (scrn->width * x0) / 320; + y0 = (scrn->height * y0) / 200; + destwidth = (scrn->width * SHORT(patch->width)) / 320; + destheight = (scrn->height * SHORT(patch->height)) / 200; + + xinc = (SHORT(patch->width) << 16) / destwidth; + yinc = (SHORT(patch->height) << 16) / destheight; + xmul = (destwidth << 16) / SHORT(patch->width); + ymul = (destheight << 16) / SHORT(patch->height); + + y0 -= (SHORT(patch->topoffset) * ymul) >> 16; + x0 -= (SHORT(patch->leftoffset) * xmul) >> 16; + +#ifdef RANGECHECK + if (x0<0 + || x0+destwidth > scrn->width + || y0<0 + || y0+destheight> scrn->height) + { + //Printf ("Patch at %d,%d exceeds LFB\n", x0,y0 ); + DPrintf ("V_DrawPatchFlipped: bad patch (ignored)\n"); + return; + } +#endif + + if (scrn->is8bit) { + drawfunc = vdrawsPfuncs[V_DRAWPATCH]; + colstep = 1; + } else { + drawfunc = vdrawsDfuncs[V_DRAWPATCH]; + colstep = 4; + } + + if (scrn == &screen) + V_MarkRect (x0, y0, destwidth, destheight); + + w = destwidth * xinc; + col = w - xinc; + pitch = scrn->pitch; + desttop = scrn->buffer + y0*scrn->pitch + x0 * colstep; + + for ( ; col >= 0 ; col -= xinc, desttop += colstep) + { + column = (column_t *)((byte *)patch + LONG(patch->columnofs[col >> 16])); + + // step through the posts in a column + while (column->topdelta != 0xff ) + { + drawfunc ((byte *)column + 3, + desttop + (((column->topdelta * ymul)) >> 16) * pitch, + (column->length * ymul) >> 16, + pitch, + yinc); + column = (column_t *)( (byte *)column + column->length + + 4 ); + } + } } diff --git a/code/v_palett.c b/code/v_palett.c index a966316de1..a534432c96 100644 --- a/code/v_palett.c +++ b/code/v_palett.c @@ -63,7 +63,7 @@ void GammaCallback (cvar_t *var) newgamma[i] = (byte)(255.0 * pow (i / 255.0, invgamma)); } GammaAdjustPalettes (); - if (screens[0].is8bit) { + if (screen.is8bit) { DoBlending (DefPal.colors, IndexedPalette, DefPal.numcolors, newgamma[BlendR], newgamma[BlendG], newgamma[BlendB], BlendA); I_SetPalette (IndexedPalette); @@ -286,7 +286,7 @@ void RefreshPalette (palette_t *pal) unsigned l,c,r,g,b; unsigned colors[256]; - if (screens[0].is8bit) { + if (screen.is8bit) { if (pal->flags & PALETTEF_SHADE) { byte *shade; @@ -428,7 +428,7 @@ void V_ForceBlend (int blendr, int blendg, int blendb, int blenda) BlendB = blendb; BlendA = blenda; - if (screens[0].is8bit) { + if (screen.is8bit) { DoBlending (DefPal.colors, IndexedPalette, DefPal.numcolors, newgamma[BlendR], newgamma[BlendG], newgamma[BlendB], BlendA); I_SetPalette (IndexedPalette); @@ -568,7 +568,7 @@ void BuildColoredLights (byte *maps, int lr, int lg, int lb, int r, int g, int b byte *shade; // The default palette is assumed to contain the maps for white light. - if (!screens[0].is8bit || !maps) + if (!screen.is8bit || !maps) return; // build normal (but colored) light mappings diff --git a/code/v_palett.h b/code/v_palett.h index c37d7c294c..c45cb4e5e7 100644 --- a/code/v_palett.h +++ b/code/v_palett.h @@ -15,7 +15,7 @@ struct palette_s { struct palette_s *next, *prev; union { - // Which of these is used is determined by screens[0].is8bit + // Which of these is used is determined by screen.is8bit byte *colormaps; // Colormaps for 8-bit graphics unsigned *shades; // ARGB8888 values for 32-bit graphics diff --git a/code/v_text.c b/code/v_text.c index f764dcdb50..ae0d257caa 100644 --- a/code/v_text.c +++ b/code/v_text.c @@ -36,13 +36,13 @@ void V_InitConChars (byte transcolor) chars = W_CacheLumpName ("CONCHARS", PU_CACHE); { - long *screen, fill; + long *scrn, fill; fill = (transcolor << 24) | (transcolor << 16) | (transcolor << 8) | transcolor; for (y = 0; y < 128; y++) { - screen = (long *)(temp.buffer + temp.pitch * y); + scrn = (long *)(temp.buffer + temp.pitch * y); for (x = 0; x < 128/4; x++) { - *screen++ = fill; + *scrn++ = fill; } } V_DrawPatch (0, 0, &temp, chars); @@ -89,10 +89,10 @@ void V_PrintStr (int x, int y, const byte *str, int count) byte *temp; long *charimg; - if (!screens[0].buffer) + if (!screen.buffer) return; - if (y > (screens[0].height - 8) || y<0) + if (y > (screen.height - 8) || y<0) return; if (x < 0) { @@ -109,13 +109,13 @@ void V_PrintStr (int x, int y, const byte *str, int count) } x &= ~3; - temp = screens[0].buffer + y * screens[0].pitch; + temp = screen.buffer + y * screen.pitch; - while (count && x <= (screens[0].width - 8)) { + while (count && x <= (screen.width - 8)) { charimg = (long *)&ConChars[(*str) * 128]; - if (screens[0].is8bit) { + if (screen.is8bit) { #ifdef USEASM - PrintChar1P (charimg, temp + x, screens[0].pitch); + PrintChar1P (charimg, temp + x, screen.pitch); #else int z; long *writepos; @@ -125,7 +125,7 @@ void V_PrintStr (int x, int y, const byte *str, int count) *writepos = (*writepos & charimg[2]) ^ charimg[0]; writepos++; *writepos = (*writepos & charimg[3]) ^ charimg[1]; - writepos += (screens[0].pitch >> 2) - 1; + writepos += (screen.pitch >> 2) - 1; charimg += 4; } #endif @@ -151,7 +151,7 @@ void V_PrintStr (int x, int y, const byte *str, int count) SPOT(7); #undef SPOT #undef BYTEIMG - writepos += screens[0].pitch >> 2; + writepos += screen.pitch >> 2; charimg += 4; } } @@ -170,7 +170,7 @@ void V_PrintStr2 (int x, int y, const byte *str, int count) byte *temp; long *charimg; - if (y > (screens[0].height - 16)) + if (y > (screen.height - 16)) return; if (x < 0) { @@ -187,13 +187,13 @@ void V_PrintStr2 (int x, int y, const byte *str, int count) } x &= ~3; - temp = screens[0].buffer + y * screens[0].pitch; + temp = screen.buffer + y * screen.pitch; - while (count && x <= (screens[0].width - 16)) { + while (count && x <= (screen.width - 16)) { charimg = (long *)&ConChars[(*str) * 128]; #ifdef USEASM if (UseMMX) { - PrintChar2P_MMX (charimg, temp + x, screens[0].pitch); + PrintChar2P_MMX (charimg, temp + x, screen.pitch); } else #endif { @@ -213,30 +213,30 @@ void V_PrintStr2 (int x, int y, const byte *str, int count) buildbits[0] = buildbits[1] = image[0]; buildbits[2] = buildbits[3] = image[1]; writepos[0] = (writepos[0] & m1) ^ s1; - writepos[screens[0].pitch/4] = (writepos[screens[0].pitch/4] & m1) ^ s1; + writepos[screen.pitch/4] = (writepos[screen.pitch/4] & m1) ^ s1; buildmask[0] = buildmask[1] = image[10]; buildmask[2] = buildmask[3] = image[11]; buildbits[0] = buildbits[1] = image[2]; buildbits[2] = buildbits[3] = image[3]; writepos[1] = (writepos[1] & m1) ^ s1; - writepos[1+screens[0].pitch/4] = (writepos[1+screens[0].pitch/4] & m1) ^ s1; + writepos[1+screen.pitch/4] = (writepos[1+screen.pitch/4] & m1) ^ s1; buildmask[0] = buildmask[1] = image[12]; buildmask[2] = buildmask[3] = image[13]; buildbits[0] = buildbits[1] = image[4]; buildbits[2] = buildbits[3] = image[5]; writepos[2] = (writepos[2] & m1) ^ s1; - writepos[2+screens[0].pitch/4] = (writepos[2+screens[0].pitch/4] & m1) ^ s1; + writepos[2+screen.pitch/4] = (writepos[2+screen.pitch/4] & m1) ^ s1; buildmask[0] = buildmask[1] = image[14]; buildmask[2] = buildmask[3] = image[15]; buildbits[0] = buildbits[1] = image[6]; buildbits[2] = buildbits[3] = image[7]; writepos[3] = (writepos[3] & m1) ^ s1; - writepos[3+screens[0].pitch/4] = (writepos[3+screens[0].pitch/4] & m1) ^ s1; + writepos[3+screen.pitch/4] = (writepos[3+screen.pitch/4] & m1) ^ s1; - writepos += screens[0].pitch >> 1; + writepos += screen.pitch >> 1; image += 16; } @@ -313,10 +313,10 @@ static void drawtext (int drawer, int normalcolor, int x, int y, const byte *str } w = SHORT (hu_font[c]->width); - if (cx+w > screens[0].width) + if (cx+w > screen.width) break; - V_DrawWrapper (drawer, cx, cy, &screens[0], hu_font[c]); + V_DrawWrapper (drawer, cx, cy, &screen, hu_font[c]); cx+=w; } } @@ -376,10 +376,10 @@ static void drawscaledtext (int drawer, int normalcolor, int x, int y, const byt } w = SHORT (hu_font[c]->width) * CleanXfac; - if (cx+w > screens[0].width) + if (cx+w > screen.width) break; - V_DrawCNMWrapper (drawer, cx, cy, &screens[0], hu_font[c]); + V_DrawCNMWrapper (drawer, cx, cy, &screen, hu_font[c]); cx+=w; } } @@ -407,8 +407,8 @@ void V_DrawTextCleanLuc (int normalcolor, int x, int y, const byte *string) void V_DrawTextCleanMove (int normalcolor, int x, int y, const byte *string) { drawscaledtext (V_DRAWTRANSLATEDPATCH, normalcolor, - (x - 160) * CleanXfac + screens[0].width / 2, - (y - 100) * CleanYfac + screens[0].height / 2, + (x - 160) * CleanXfac + screen.width / 2, + (y - 100) * CleanYfac + screen.height / 2, string); } diff --git a/code/version.h b/code/version.h index 20be695d8d..0514760dbb 100644 --- a/code/version.h +++ b/code/version.h @@ -4,7 +4,7 @@ // Lots of different representations for the version number enum { VERSION = 117 }; #define VERSIONSTR "117" -#define DOTVERSIONSTR "1.17" +#define DOTVERSIONSTR "1.17:" #define GAMEVER (0x0111) #define SAVESIG "ZDOOMSAVE117 " // Needs to be exactly 16 chars long diff --git a/code/win32/I_input.c b/code/win32/I_input.c index 1c614661a1..94f9f235cd 100644 --- a/code/win32/I_input.c +++ b/code/win32/I_input.c @@ -963,7 +963,8 @@ static void KeyRead (void) { key = 0; break; default: - if (ConsoleState == c_falling || ConsoleState == c_down) { + if (!menuactive && + (ConsoleState == c_falling || ConsoleState == c_down)) { switch (key) { case DIK_NUMPAD4: key = DIK_4; @@ -1095,9 +1096,6 @@ void I_GetEvent(void) else MouseRead_Win32 (); } - - if (usejoystick->value) - DI_JoyCheck (); } @@ -1108,3 +1106,12 @@ void I_StartTic (void) { I_GetEvent (); } + +// +// I_StartFrame +// +void I_StartFrame (void) +{ + if (usejoystick->value) + DI_JoyCheck (); +} diff --git a/code/win32/I_sound.c b/code/win32/I_sound.c index d847b01fa0..6bee76d7b3 100644 --- a/code/win32/I_sound.c +++ b/code/win32/I_sound.c @@ -113,25 +113,16 @@ void MIDASerror(void) /* Loads a sound and adds it to MIDAS * Really returns a MIDAS sample handle */ -static void *getsfx (sfxinfo_t *sfx) +static void getsfx (sfxinfo_t *sfx) { char sndtemp[128]; byte *sfxdata; + byte *sfxcopy; int size; int i; int error; static sdSample smp; - unsigned sampleHandle; - - /* No loop: */ - smp.loopMode = sdLoopNone; - smp.loop1Start = smp.loop1End = 0; - smp.loop1Type = loopNone; - - /* No loop 2: */ - smp.loop2Start = smp.loop2End = 0; - smp.loop2Type = loopNone; // Get the sound data from the WAD and register it with MIDAS @@ -161,7 +152,9 @@ badwave: DPrintf ("Linked to %s (%d)\n", S_sfx[i].name, i); sfx->link = S_sfx + i; sfx->ms = S_sfx[i].ms; - return S_sfx[i].data; + sfx->data = S_sfx[i].data; + sfx->loopdata = S_sfx[i].loopdata; + return; } size = W_LumpLength (sfx->lumpnum); @@ -277,30 +270,44 @@ badwave: } } + /* No loop 2: */ + smp.loop2Start = smp.loop2End = 0; + smp.loop2Type = loopNone; + + sfxcopy = Malloc (smp.sampleLength); + memcpy (sfxcopy, smp.sample, smp.sampleLength); + Z_Free (sfxdata); + smp.sample = sfxcopy; + /* Add the sample to the Sound Device: */ -#ifdef _MSC_VER { // Avoid using __fastcall for this function - typedef int (__cdecl *blargh_t)(sdSample*, int, unsigned *); + typedef int (STACK_ARGS *blargh_t)(sdSample*, int, unsigned *); blargh_t blargh = (blargh_t)midasSD->AddSample; - if ( (error = blargh (&smp, 1, &sampleHandle)) != OK) + /* No loop: */ + smp.loopMode = sdLoopNone; + smp.loop1Start = smp.loop1End = 0; + smp.loop1Type = loopNone; + + if ( (error = blargh (&smp, 0, (unsigned *)&sfx->data)) != OK) + I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); + + /* With loop: */ + smp.loopMode = sdLoop1; + smp.loop1Start = 0; + smp.loop1End = smp.sampleLength; + smp.loop1Type = loopUnidir; + + if ( (error = blargh (&smp, 0, (unsigned *)&sfx->loopdata)) != OK) I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); } -#else - if ( (error = midasSD->AddSample (&smp, 1, &sampleHandle)) != OK) - I_FatalError ("getsfx: AddSample failed: %s", MIDASgetErrorMessage(error)); -#endif // Remove the cached lump. - Z_Free (sfxdata); if (sfx->frequency == 0) sfx->frequency = 11025; sfx->ms = (sfx->ms * 1000) / (sfx->frequency); - - /* Return sample handle: (damn ugly) */ - return (void*) sampleHandle; } @@ -354,7 +361,7 @@ void I_SetSfxVolume (int volume) // e.g. a pointer to the raw data, // it is ignored. // -int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel) +int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel, BOOL looping) { int id = sfx - S_sfx; int volume; @@ -375,7 +382,9 @@ int I_StartSound (sfxinfo_t *sfx, int vol, int sep, int pitch, int channel) else if ( pan > MIDAS_PAN_RIGHT) pan = MIDAS_PAN_RIGHT; } - ChannelMap[channel].playHandle = MIDASplaySample ((MIDASsample)sfx->data, + ChannelMap[channel].playHandle = MIDASplaySample ( + looping ? (MIDASsample)sfx->loopdata + : (MIDASsample)sfx->data, ChannelMap[channel].midasChannel, 0, PITCH(sfx->frequency,pitch), @@ -451,7 +460,7 @@ void I_LoadSound (struct sfxinfo_struct *sfx) int i = sfx - S_sfx; DPrintf ("loading sound \"%s\" (%d)\n", sfx->name, i); - sfx->data = getsfx (sfx); + getsfx (sfx); } } @@ -602,10 +611,15 @@ void STACK_ARGS I_ShutdownSound (void) // [RH] Free all loaded samples for (i = 0; i < numsfx; i++) { - if (S_sfx[i].data && !S_sfx[i].link) { - MIDASfreeSample ((MIDASsample)S_sfx[i].data); - len += S_sfx[i].length; - c++; + if (!S_sfx[i].link) { + if (S_sfx[i].data) { + MIDASfreeSample ((MIDASsample)S_sfx[i].data); + len += S_sfx[i].length; + c++; + } + if (S_sfx[i].loopdata) { + MIDASfreeSample ((MIDASsample)S_sfx[i].loopdata); + } } S_sfx[i].data = S_sfx[i].link = NULL; } diff --git a/code/win32/I_sound.h b/code/win32/I_sound.h index 47959c430a..cad2b26ba7 100644 --- a/code/win32/I_sound.h +++ b/code/win32/I_sound.h @@ -55,7 +55,8 @@ I_StartSound int vol, int sep, int pitch, - int channel ); + int channel, + BOOL looping ); // Stops a sound channel. diff --git a/code/win32/I_system.c b/code/win32/I_system.c index bb0c20fbe2..64a885a1d1 100644 --- a/code/win32/I_system.c +++ b/code/win32/I_system.c @@ -55,8 +55,6 @@ BOOL STACK_ARGS CheckMMX (char *vendorid); #endif -static void Cmd_Dir (void *plyr, int argc, char **argv); - extern HWND Window; BOOL UseMMX; @@ -241,7 +239,6 @@ void I_Init (void) I_InitSound(); I_InitInput (Window); - C_RegisterCommand ("dir", Cmd_Dir); } // @@ -313,40 +310,6 @@ void STACK_ARGS I_Error (char *error, ...) char DoomStartupTitle[256] = { 0 }; -/* -void I_PaintConsole (void) -{ - PAINTSTRUCT paint; - HDC dc; - - if (dc = BeginPaint (Window, &paint)) { - if (paint.rcPaint.top < OemHeight) { - SetTextColor (dc, RGB(255,0,0)); - SetBkColor (dc, RGB(195,195,195)); - SetBkMode (dc, OPAQUE); - - TextOut (dc, 0, 0, Title, ConCols); - } - if (Last && paint.rcPaint.bottom > OemHeight) { - char *row; - int line, last, top, bottom; - - SetTextColor (dc, RGB(0,255,255)); - SetBkMode (dc, TRANSPARENT); - - top = (paint.rcPaint.top >= OemHeight) ? paint.rcPaint.top - OemHeight : 0; - bottom = paint.rcPaint.bottom - OemHeight - 1; - line = top / OemHeight; - last = bottom / OemHeight; - for (row = Last - (PhysRows - 2 - line) * (ConCols + 2); line <= last; line++) { - TextOut (dc, 0, (line + 1) * OemHeight, row + 2, row[1]); - row += ConCols + 2; - } - } - EndPaint (Window, &paint); - } -} -*/ void I_SetTitleString (const char *title) { int i; @@ -356,74 +319,19 @@ void I_SetTitleString (const char *title) } void I_PrintStr (int xp, const char *cp, int count, BOOL scroll) { -/* MSG mess; - RECT rect; - - if (count) - TextOut (WinDC, xp * OemWidth, WinHeight - OemHeight, cp, count); - if (scroll) { - rect.left = 0; - rect.top = OemHeight; - rect.right = WinWidth; - rect.bottom = WinHeight; - ScrollWindowEx (Window, 0, -OemHeight, NULL, &rect, NULL, NULL, SW_ERASE|SW_INVALIDATE); - UpdateWindow (Window); - } - while (PeekMessage (&mess, Window, 0, 0, PM_REMOVE)) { - if (mess.message == WM_QUIT) - exit (mess.wParam); - TranslateMessage (&mess); - DispatchMessage (&mess); - } -*/ + // used in the DOS version } -static void Cmd_Dir (void *plyr, int argc, char **argv) +long I_FindFirst (char *filespec, findstate_t *fileinfo) { - char dir[256], curdir[256]; - char *match; - struct _finddata_t c_file; - long file; - - if (!getcwd (curdir, 256)) { - Printf (PRINT_HIGH, "Current path too long\n"); - return; - } - - if (argc == 1 || chdir (argv[1])) { - match = argc == 1 ? "./*" : argv[1]; - - ExtractFilePath (match, dir); - if (dir[0]) { - match += strlen (dir); - } else { - dir[0] = '.'; - dir[1] = '/'; - dir[2] = '\0'; - } - if (!match[0]) - match = "*"; - - if (chdir (dir)) { - Printf (PRINT_HIGH, "%s not found\n", dir); - return; - } - } else { - match = "*"; - strcpy (dir, argv[1]); - if (dir[strlen(dir) - 1] != '/') - strcat (dir, "/"); - } - - if ( (file = _findfirst (match, &c_file)) == -1) - Printf (PRINT_HIGH, "Nothing matching %s%s\n", dir, match); - else { - Printf (PRINT_HIGH, "Listing of %s%s:\n", dir, match); - do { - Printf (PRINT_HIGH, "%s%s\n", c_file.name, c_file.attrib & _A_SUBDIR ? " " : ""); - } while (_findnext (file, &c_file) == 0); - _findclose (file); - } - - chdir (curdir); + return _findfirst (filespec, fileinfo); +} +int I_FindNext (long handle, findstate_t *fileinfo) +{ + return _findnext (handle, fileinfo); +} + +int I_FindClose (long handle) +{ + return _findclose (handle); } diff --git a/code/win32/I_system.h b/code/win32/I_system.h index 1ab6b905f4..74ecbcfc34 100644 --- a/code/win32/I_system.h +++ b/code/win32/I_system.h @@ -23,6 +23,8 @@ #ifndef __I_SYSTEM__ #define __I_SYSTEM__ +#include + #include "d_ticcmd.h" #include "d_event.h" @@ -125,6 +127,24 @@ unsigned int I_MSTime (void); // [RH] Title string to display at bottom of console during startup extern char DoomStartupTitle[256]; + +// Directory searching routines + +typedef struct _finddata_t findstate_t; + +long I_FindFirst (char *filespec, findstate_t *fileinfo); +int I_FindNext (long handle, findstate_t *fileinfo); +int I_FindClose (long handle); + +#define I_FindName(a) ((a)->name) +#define I_FindAttr(a) ((a)->attrib) + +#define FA_RDONLY _A_RDONLY +#define FA_HIDDEN _A_HIDDEN +#define FA_SYSTEM _A_SYSTEM +#define FA_DIREC _A_SUBDIR +#define FA_ARCH _A_ARCH + #endif //----------------------------------------------------------------------------- // diff --git a/code/win32/I_video.cpp b/code/win32/I_video.cpp index 3963b09db5..8b6e16e822 100644 --- a/code/win32/I_video.cpp +++ b/code/win32/I_video.cpp @@ -1,11 +1,25 @@ -/* -** i_video.cpp: Low level DOOM graphics routines. -** This version uses PTC. (Prometheus True Color) -** -** There are two reasons why I switched from DirectDraw to PTC: -** 1. PTC makes windowed modes easy without any special work. -** 2. PTC makes it easy to support *all* hi- and true-color modes. -*/ +//************************************************************************** +//** +//** i_video.cpp: Low level DOOM graphics routines. +//** This version uses PTC. (Prometheus True Color) +//** NEW (1.17a): Support for DirectDraw is back! +//** +//** There are two reasons why I switched from DirectDraw to PTC: +//** 1. PTC makes windowed modes easy without any special work. +//** 2. PTC makes it easy to support *all* hi- and true-color modes. +//** +//************************************************************************** + +// HEADER FILES ------------------------------------------------------------ + +#ifndef INITGUID +#define INITGUID +#endif + +#include +#include +#include +#include #include "ptc.h" @@ -26,44 +40,73 @@ extern "C" { #include "m_argv.h" #include "d_main.h" #include "m_alloc.h" - #include "c_consol.h" #include "c_cvars.h" #include "c_dispch.h" #include "st_stuff.h" - #include "doomdef.h" #include "z_zone.h" +// MACROS ------------------------------------------------------------------ + +#define true TRUE +#define false FALSE + +// TYPES ------------------------------------------------------------------- + +struct screenchain { + screen_t *scr; + struct screenchain *next; +} *chain; + +typedef struct modelist_s { + modelist_s *next; + int width, height, bpp; + int id; +} modelist_t; + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +void I_StartModeIterator (int id); +BOOLI_NextMode (int *width, int *height); + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +struct player_s; +static void Cmd_Vid_DescribeModes (struct player_s*,int,char**); +static void Cmd_Vid_DescribeCurrentMode (struct player_s*,int,char**); + +static void AddMode (int x, int y, int bpp, int id, modelist_t **lastmode); +static void FreeModes (void); +static void MakeModesList (void); +static char *GetFormatName (const int id); +static void ReinitPTC (char *iface); +static void refreshDisplay (void); +static void stretchChanged (cvar_t *var); +static void fullChanged (cvar_t *var); + +static HRESULT WINAPI EnumDDModesCB (LPDDSURFACEDESC desc, void *modes); +static void InitDDraw (void); +static void NewDDMode (int width, int height); + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern HWND Window; extern BOOL vidactive; // Checked to avoid annoying flashes on console - // during startup if developer is true. + // during startup if developer is true extern BOOL setmodeneeded; extern int NewWidth, NewHeight, NewID; +// PUBLIC DATA DEFINITIONS ------------------------------------------------- cvar_t *I_ShowFPS; cvar_t *ticker; cvar_t *win_stretchx; cvar_t *win_stretchy; cvar_t *fullscreen; - - -struct player_s; -static void Cmd_Vid_DescribeModes (struct player_s*,int,char**); -static void Cmd_Vid_DescribeCurrentMode (struct player_s*,int,char**); - -static char WindowedIFace[8]; -static char FullscreenIFace[8]; - BOOL Fullscreen; - -static struct CmdDispatcher VidCommands[] = { - { "vid_currentmode", Cmd_Vid_DescribeCurrentMode }, - { "vid_listmodes", Cmd_Vid_DescribeModes }, - { NULL, } -}; +static modelist_t *IteratorMode; +static int IteratorID; char *IdStrings[22] = { "ARGB8888", @@ -95,43 +138,52 @@ byte IdTobpp[22] = { 18, 18, 18, 14, 14, 14, 12, 12, 12, 8, 8 }; +int DisplayID; +int DisplayBPP; // Number of bits-per-pixel of output device +int DisplayWidth, DisplayHeight; // Display size -#define true TRUE -#define false FALSE - -struct screenchain { - screen_t *scr; - struct screenchain *next; -} *chain; - -typedef struct modelist_s { - modelist_s *next; - int width, height, bpp; - int id; -} modelist_t; +// PRIVATE DATA DEFINITIONS ------------------------------------------------ static modelist_t *Modes = NULL; - -int DisplayID; -// Number of bits-per-pixel of output device -int DisplayBPP; - -// Display size -int DisplayWidth, DisplayHeight; - -} - +static char WindowedIFace[8]; +static char FullscreenIFace[8]; static int nummodes = 0; +static struct CmdDispatcher VidCommands[] = { + { "vid_currentmode", Cmd_Vid_DescribeCurrentMode }, + { "vid_listmodes", Cmd_Vid_DescribeModes }, + { NULL, } +}; -/* The PTC interface object */ -PTC ptc; +} // extern "C" -/* The display palette */ -Palette *DisPal; +static PTC ptc; // the PTC interface object +static Palette *DisPal; // the display palette -static void addmode (int x, int y, int bpp, int id, modelist_t **lastmode) +static IDirectDraw *DDObj; +static LPDIRECTDRAWPALETTE DDPalette; +static LPDIRECTDRAWSURFACE DDPrimary; +static LPDIRECTDRAWSURFACE DDBack; +static int NeedPalChange; +static BOOL CalledCoInitialize; + +static union { + PALETTEENTRY pe[256]; + uint ui[256]; +} PalEntries; + +extern "C" { + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// AddMode +// +//========================================================================== + +static void AddMode (int x, int y, int bpp, int id, modelist_t **lastmode) { modelist_t *newmode = (modelist_t *)Z_Malloc (sizeof (modelist_t), PU_STATIC, 0); @@ -146,6 +198,32 @@ static void addmode (int x, int y, int bpp, int id, modelist_t **lastmode) *lastmode = newmode; } +//========================================================================== +// +// FreeModes +// +//========================================================================== + +static void FreeModes (void) +{ + modelist_t *mode = Modes, *tempmode; + + while (mode) + { + tempmode = mode; + mode = mode->next; + Z_Free (tempmode); + } + Modes = NULL; + nummodes = 0; +} + +//========================================================================== +// +// MakeModesList +// +//========================================================================== + static void MakeModesList (void) { modelist_t *lastmode = (modelist_t *)&Modes; @@ -173,7 +251,8 @@ static void MakeModesList (void) if (ptcmode->y <= 1024 && ptcmode->format.id == INDEX8) { nummodes++; - addmode (ptcmode->x, ptcmode->y, ptcmode->format.bits, ptcmode->format.id, &lastmode); + AddMode (ptcmode->x, ptcmode->y, ptcmode->format.bits, + ptcmode->format.id, &lastmode); if (ptcmode->x == 320 && ptcmode->format.bits == 8) { if (ptcmode->y == 200) have320x200x8 = true; @@ -191,74 +270,98 @@ static void MakeModesList (void) // add the Mode X modes here. if (!have320x200x8) - addmode (320, 200, 8, INDEX8, &lastmode); + AddMode (320, 200, 8, INDEX8, &lastmode); if (!have320x240x8) - addmode (320, 240, 8, INDEX8, &lastmode); + AddMode (320, 240, 8, INDEX8, &lastmode); } } +//========================================================================== +// +// GetFormatName +// +//========================================================================== + static char *GetFormatName (const int id) { return IdStrings[id-1000]; } - -extern "C" { +//========================================================================== +// +// I_ShutdownGraphics +// +//========================================================================== void STACK_ARGS I_ShutdownGraphics (void) { - { - modelist_t *mode = Modes, *tempmode; - - while (mode) { - tempmode = mode; - mode = mode->next; - Z_Free (tempmode); - } - Modes = NULL; - } + FreeModes (); while (chain) { I_FreeScreen (chain->scr); } - if (DisPal) { - delete DisPal; - DisPal = NULL; + if (DDObj) + { + if (DDPalette) + { + DDPalette->Release(); + DDPalette = NULL; + } + if (DDPrimary) + { + DDPrimary->Release(); + DDPrimary = NULL; + } + DDObj->Release(); + DDObj = NULL; + } + else + { + if (DisPal) + { + delete DisPal; + DisPal = NULL; + } + + ptc.Close (); } - ptc.Close (); + if (CalledCoInitialize) + { + CoUninitialize (); + CalledCoInitialize = false; + } } -// -// I_StartFrame -// -void I_StartFrame (void) -{ - // er? - -} - - +//========================================================================== // // [RH] I_BeginUpdate // +//========================================================================== + void I_BeginUpdate (void) { - V_LockScreen (&screens[0]); + V_LockScreen (&screen); } +//========================================================================== // // I_FinishUpdateNoBlit // +//========================================================================== + void I_FinishUpdateNoBlit (void) { - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); } +//========================================================================== // // I_FinishUpdate // +//========================================================================== + void I_FinishUpdate (void) { static int lasttic, lastms = 0, lastsec = 0; @@ -276,8 +379,8 @@ void I_FinishUpdate (void) howlong, lastcount); chars = strlen (fpsbuff); - V_Clear (0, screens[0].height - 8, chars * 8, screens[0].height, &screens[0], 0); - V_PrintStr (0, screens[0].height - 8, (byte *)&fpsbuff[0], chars); + V_Clear (0, screen.height - 8, chars * 8, screen.height, &screen, 0); + V_PrintStr (0, screen.height - 8, (byte *)&fpsbuff[0], chars); if (lastsec != ms / 1000) { lastcount = framecount; framecount = 0; @@ -295,68 +398,167 @@ void I_FinishUpdate (void) if (tics > 20) tics = 20; for (i=0 ; iUpdate (); + HRESULT dderr; + DDSURFACEDESC ddsd; + + memset (&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(DDSURFACEDESC); + + do + { + dderr = DDBack->Lock (NULL, &ddsd, DDLOCK_WRITEONLY | + DDLOCK_SURFACEMEMORYPTR, NULL); + } while ((dderr == DDERR_WASSTILLDRAWING) || (dderr == DDERR_SURFACEBUSY)); + + if (dderr == DDERR_SURFACELOST) { + dderr = DDPrimary->Restore (); + do + { + dderr = DDBack->Lock (NULL, &ddsd, DDLOCK_WRITEONLY | + DDLOCK_SURFACEMEMORYPTR, NULL); + } while ((dderr == DDERR_WASSTILLDRAWING) || (dderr == DDERR_SURFACEBUSY)); + } + + if (dderr == DD_OK) { + byte *to = (byte *)ddsd.lpSurface; + byte *from = screen.buffer; + int y; + + if (ddsd.lPitch == screen.width && screen.width == screen.pitch) { + memcpy (to, from, screen.width * screen.height); + } else { + for (y = 0; y < screen.height; y++) { + memcpy (to, from, screen.width); + to += ddsd.lPitch; + from += screen.pitch; + } + } + do + { + dderr = DDBack->Unlock (ddsd.lpSurface); + } while ((dderr == DDERR_WASSTILLDRAWING) || (dderr == DDERR_SURFACEBUSY)); + } + + V_UnlockScreen (&screen); + + while (1) + { + dderr = DDPrimary->Flip (NULL, DDFLIP_WAIT); + if (dderr == DDERR_SURFACELOST) + { + dderr = DDPrimary->Restore (); + if (dderr != DD_OK) + break; + } + if (dderr != DDERR_WASSTILLDRAWING) + break; + } + + if (NeedPalChange > 0) + { + NeedPalChange--; + DDPalette->SetEntries (0, 0, 256, PalEntries.pe); + } + } + else + { + V_UnlockScreen (&screen); + ((Surface *)(screen.impdata))->Update (); + + if (DisPal && NeedPalChange > 0) + { + uint *palentries; + + if (palentries = (uint *)DisPal->Lock ()) + { + NeedPalChange--; + memcpy (palentries, PalEntries.ui, 256*sizeof(uint)); + DisPal->Unlock (); + + if (screen.is8bit) + ((Surface *)(screen.impdata))->SetPalette (*DisPal); + + // Only set the display palette if it is indexed color + FORMAT format = ptc.GetFormat (); + + if (format.type == INDEXED && format.model != GREYSCALE) + ptc.SetPalette (*DisPal); + } + } + } } - +//========================================================================== // // I_ReadScreen // +//========================================================================== + void I_ReadScreen (byte *scr) { - int x, y; + int y; byte *source; - V_LockScreen (&screens[0]); + V_LockScreen (&screen); + source = screen.buffer; - for (y = 0; y < screens[0].height; y++) { - source = screens[0].buffer + y * screens[0].pitch; - for (x = 0; x < screens[0].width; x++) { - *scr++ = *source++; - } + for (y = 0; y < screen.height; y++) + { + memcpy (scr, source, screen.width); + scr += screen.width; + source += screen.pitch; } - V_UnlockScreen (&screens[0]); + V_UnlockScreen (&screen); } +//========================================================================== // // I_SetPalette // +//========================================================================== + void I_SetPalette (unsigned int *pal) { - uint *palentries; - - if (!DisPal || !pal) + if (!pal) return; - palentries = (uint *)DisPal->Lock (); - if (!palentries) { - DPrintf ("Failed to set palette\n"); - return; + if (DDPalette) + { + int i; + + for (i = 0; i < 256; i++) + { + PalEntries.pe[i].peRed = RPART(pal[i]); + PalEntries.pe[i].peGreen = GPART(pal[i]); + PalEntries.pe[i].peBlue = BPART(pal[i]); + } } - - memcpy (palentries, pal, 256*sizeof(uint)); - - DisPal->Unlock (); - - if (screens[0].is8bit) - ((Surface *)(screens[0].impdata))->SetPalette (*DisPal); - - // Only set the display palette if it is indexed color - FORMAT format = ptc.GetFormat (); - - if (format.type == INDEXED && format.model != GREYSCALE) - ptc.SetPalette (*DisPal); + else + { + memcpy (PalEntries.ui, pal, 256*sizeof(uint)); + } + NeedPalChange++; } +//========================================================================== +// +// ReinitPTC +// +//========================================================================== + static void ReinitPTC (char *iface) { if (!ptc.Init (iface, (WINDOW)Window)) @@ -369,6 +571,12 @@ static void ReinitPTC (char *iface) Printf (PRINT_HIGH, "PTC reinitialized to use %s\n\n", iface); } +//========================================================================== +// +// I_SetMode +// +//========================================================================== + void I_SetMode (int width, int height, int id) { DisplayWidth = width; @@ -377,79 +585,120 @@ void I_SetMode (int width, int height, int id) ShowWindow (Window, SW_SHOW); - if (Fullscreen) { - if (!fullscreen->value) { - Fullscreen = FALSE; - // Get out of fullscreen mode - ptc.Close (); - //ReinitPTC (WindowedIFace); - } - } else { - if (fullscreen->value) { - Fullscreen = TRUE; - ReinitPTC (FullscreenIFace); - I_ResumeMouse (); // Make sure mouse pointer is grabbed. - } - } - - if (Fullscreen) { - ptc.SetMode (width, height, id); - } else { - width *= win_stretchx->value; - height *= win_stretchy->value; - - height += GetSystemMetrics (SM_CYFIXEDFRAME) * 2 + - GetSystemMetrics (SM_CYCAPTION); - width += GetSystemMetrics (SM_CXFIXEDFRAME) * 2; - - SetWindowPos (Window, NULL, 0, 0, width, height, SWP_DRAWFRAME| - SWP_NOACTIVATE| - SWP_NOCOPYBITS| - SWP_NOMOVE| - SWP_NOZORDER); - - // Let PTC know about the new window size - ReinitPTC (WindowedIFace); - - // If the menu is active, make sure the mouse is released. - if (menuactive || gamestate == GS_FULLCONSOLE) - I_PauseMouse (); - } + if (DDObj) { - MODE mode = ptc.GetMode(); + NewDDMode (width, height); + } + else + { + if (Fullscreen) + { + if (!fullscreen->value) + { + Fullscreen = FALSE; + // Get out of fullscreen mode + ptc.Close (); + //ReinitPTC (WindowedIFace); + } + } + else + { + if (fullscreen->value) + { + Fullscreen = TRUE; + ReinitPTC (FullscreenIFace); + I_ResumeMouse (); // Make sure mouse pointer is grabbed. + } + } - DisplayBPP = mode.format.bits; - if (developer->value && vidactive) - Printf (PRINT_HIGH, "Mode set: %dx%d (%s)\n", mode.x, mode.y, IdStrings[DisplayID-1000]); + if (Fullscreen) + { + ptc.SetMode (width, height, id); + } + else + { + width *= win_stretchx->value; + height *= win_stretchy->value; + + height += GetSystemMetrics (SM_CYFIXEDFRAME) * 2 + + GetSystemMetrics (SM_CYCAPTION); + width += GetSystemMetrics (SM_CXFIXEDFRAME) * 2; + + SetWindowPos (Window, NULL, 0, 0, width, height, SWP_DRAWFRAME| + SWP_NOACTIVATE| + SWP_NOCOPYBITS| + SWP_NOMOVE| + SWP_NOZORDER); + + // Let PTC know about the new window size + ReinitPTC (WindowedIFace); + + // If the menu is active, make sure the mouse is released. + if (menuactive || gamestate == GS_FULLCONSOLE) + I_PauseMouse (); + + MODE mode = ptc.GetMode(); + + DisplayBPP = mode.format.bits; + if (developer->value && vidactive) + Printf (PRINT_HIGH, "Mode set: %dx%d (%s)\n", mode.x, mode.y, + IdStrings[DisplayID-1000]); + } } - // cheapo hack to make sure current display BPP is stored in screens[0] - screens[0].Bpp = IdTobpp[DisplayID-1000] >> 3; + // cheapo hack to make sure current display BPP is stored in screen + screen.Bpp = IdTobpp[DisplayID-1000] >> 3; } -static void refreshDisplay (void) { +//========================================================================== +// +// refreshDisplay +// +//========================================================================== + +static void refreshDisplay (void) +{ NewWidth = DisplayWidth; NewHeight = DisplayHeight; NewID = DisplayID; setmodeneeded = true; } +//========================================================================== +// +// stretchChanged +// +//========================================================================== + static void stretchChanged (cvar_t *var) { - if (!Fullscreen) + if (!Fullscreen && !DDObj) refreshDisplay (); } +//========================================================================== +// +// fullChanged +// +//========================================================================== + static void fullChanged (cvar_t *var) { - if (Fullscreen != var->value) + if (!DDObj && Fullscreen != var->value) refreshDisplay (); } +//========================================================================== +// +// I_InitGraphics +// +//========================================================================== + void I_InitGraphics (void) { char num[8], *iface; modelist_t *mode = (modelist_t *)&Modes; + cvar_t *vid_noptc; I_DetectOS (); @@ -460,6 +709,7 @@ void I_InitGraphics (void) win_stretchx = cvar ("win_stretchx", "1.0", CVAR_ARCHIVE|CVAR_CALLBACK); win_stretchy = cvar ("win_stretchy", "1.0", CVAR_ARCHIVE|CVAR_CALLBACK); fullscreen = cvar ("fullscreen", "1", CVAR_ARCHIVE|CVAR_CALLBACK); + vid_noptc = cvar ("vid_noptc", "0", CVAR_ARCHIVE); Fullscreen = (BOOL)fullscreen->value; @@ -469,29 +719,176 @@ void I_InitGraphics (void) C_RegisterCommands (VidCommands); - MakeModesList (); - sprintf (num, "%d", nummodes); - cvar ("vid_nummodes", num, CVAR_NOSET); - - if (Fullscreen) - iface = FullscreenIFace; + if (vid_noptc->value || M_CheckParm ("-noptc")) + { + Printf_Bold ("Bypassing PTC\n"); + InitDDraw (); + } else - iface = WindowedIFace; + { + MakeModesList (); + sprintf (num, "%d", nummodes); + cvar ("vid_nummodes", num, CVAR_NOSET); - if (!ptc.Init (iface, Window)) - I_FatalError ("Could not initialize PTC"); + if (Fullscreen) + iface = FullscreenIFace; + else + iface = WindowedIFace; + if (!ptc.Init (iface, Window)) + { + Printf_Bold ("Failed to initialize PTC. You won't be\n"); + Printf_Bold ("able to play in a window. (Terrible, huh?)\n"); + InitDDraw (); + } + else + { #ifdef _DEBUG - // We don't want our priority class bumped up! - SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS); + // We don't want our priority class bumped up! + SetPriorityClass (GetCurrentProcess(), NORMAL_PRIORITY_CLASS); #endif - - if (!(DisPal = new Palette)) - I_FatalError ("Could not create palette"); + if (!(DisPal = new Palette)) + { + FreeModes (); + I_FatalError ("Could not create palette"); + } + } + } atexit (I_ShutdownGraphics); } +//========================================================================== +// +// InitDDraw +// +//========================================================================== + +static void InitDDraw (void) +{ + modelist_t *lastmode = (modelist_t *)&Modes; + HRESULT dderr; + char num[8]; + + CoInitialize (NULL); + CalledCoInitialize = true; + + dderr = CoCreateInstance (CLSID_DirectDraw, 0, CLSCTX_INPROC_SERVER, + IID_IDirectDraw, (void **)&DDObj); + + if (FAILED(dderr)) + I_FatalError ("Could not create DirectDraw object: %x", dderr); + + dderr = DDObj->Initialize (0); + if (FAILED(dderr)) + { + DDObj->Release (); + I_FatalError ("Could not initialize DirectDraw object"); + } + + dderr = DDObj->SetCooperativeLevel (Window, DDSCL_EXCLUSIVE | + DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT | DDSCL_ALLOWMODEX); + if (FAILED(dderr)) + { + DDObj->Release (); + I_FatalError ("Could not set cooperative level: %x", dderr); + } + + FreeModes (); + dderr = DDObj->EnumDisplayModes (0, NULL, &lastmode, EnumDDModesCB); + if (FAILED(dderr)) + { + DDObj->Release (); + I_FatalError ("Could not enumerate display modes: %x", dderr); + } + + sprintf (num, "%d", nummodes); + cvar_forceset ("vid_nummodes", num); +} + +//========================================================================== +// +// EnumDDModesCallback +// +//========================================================================== + +static HRESULT WINAPI EnumDDModesCB (LPDDSURFACEDESC desc, void *modes) +{ + if (desc->ddpfPixelFormat.dwRGBBitCount == 8 && + desc->dwHeight <= 1024) + { + nummodes++; + AddMode (desc->dwWidth, desc->dwHeight, 8, INDEX8, (modelist_t **)modes); + } + + return DDENUMRET_OK; +} + +//========================================================================== +// +// NewDDMode +// +//========================================================================== + +static void NewDDMode (int width, int height) +{ + DDSURFACEDESC ddsd; + DDSCAPS ddscaps; + HRESULT err; + + err = DDObj->SetDisplayMode (width, height, 8); + if (err != DD_OK) + I_FatalError ("Could not set display mode: %x", err); + + if (DDPrimary) DDPrimary->Release(), DDPrimary = NULL; + if (DDPalette) DDPalette->Release(), DDPalette = NULL; + + memset (&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX | + DDSCAPS_VIDEOMEMORY; + ddsd.dwBackBufferCount = 2; + + // try to get a triple buffered video memory surface. + err = DDObj->CreateSurface (&ddsd, &DDPrimary, NULL); + + if (err != DD_OK) + { + // try to get a double buffered video memory surface. + ddsd.dwBackBufferCount = 1; + err = DDObj->CreateSurface (&ddsd, &DDPrimary, NULL); + } + + if (err != DD_OK) + { + // settle for a main memory surface. + ddsd.ddsCaps.dwCaps &= ~DDSCAPS_VIDEOMEMORY; + err = DDObj->CreateSurface (&ddsd, &DDPrimary, NULL); + } + + Printf_Bold ("%s-buffering\n", ddsd.dwBackBufferCount == 2 ? "triple" : "double"); + + ddscaps.dwCaps = DDSCAPS_BACKBUFFER; + err = DDPrimary->GetAttachedSurface (&ddscaps, &DDBack); + if (err != DD_OK) + I_FatalError ("Could not get back buffer: %x", err); + + err = DDObj->CreatePalette (DDPCAPS_8BIT|DDPCAPS_ALLOW256, PalEntries.pe, + &DDPalette, NULL); + if (err != DD_OK) + I_FatalError ("Could not create palette: %x", err); + DDPrimary->SetPalette (DDPalette); +} + +//========================================================================== +// +// I_CheckResolution +// +//========================================================================== + BOOL I_CheckResolution (int width, int height, int id) { modelist_t *mode = Modes; @@ -505,8 +902,11 @@ BOOL I_CheckResolution (int width, int height, int id) return false; } -static modelist_t *IteratorMode; -static int IteratorID; +//========================================================================== +// +// I_StartModeIteratior +// +//========================================================================== void I_StartModeIterator (int id) { @@ -514,6 +914,12 @@ void I_StartModeIterator (int id) IteratorID = id; } +//========================================================================== +// +// I_NextMode +// +//========================================================================== + BOOL I_NextMode (int *width, int *height) { if (IteratorMode) { @@ -530,7 +936,13 @@ BOOL I_NextMode (int *width, int *height) return false; } -void Cmd_Vid_DescribeModes (struct player_s *p, int c, char **v) +//========================================================================== +// +// Cmd_Vid_DescribeModes +// +//========================================================================== + +static void Cmd_Vid_DescribeModes (struct player_s *p, int c, char **v) { modelist_t *mode = Modes; @@ -548,20 +960,26 @@ void Cmd_Vid_DescribeModes (struct player_s *p, int c, char **v) } } +//========================================================================== +// +// Cmd_Vid_DescribeCurrentMode +// +//========================================================================== + void Cmd_Vid_DescribeCurrentMode (struct player_s *p, int c, char **v) { - Printf (PRINT_HIGH, "%dx%d (%s)\n", screens[0].width, screens[0].height, IdStrings[DisplayID-1000]); + Printf (PRINT_HIGH, "%dx%d (%s)\n", screen.width, screen.height, + IdStrings[DisplayID-1000]); } - - -// [RH] New routines to handle screens as surfaces with -// possible hardware acceleration. +//========================================================================== +// +// I_AllocateScreen +// +//========================================================================== BOOL I_AllocateScreen (screen_t *scrn, int width, int height, int Bpp) { - Surface *surface; - if (scrn->impdata) I_FreeScreen (scrn); @@ -572,49 +990,100 @@ BOOL I_AllocateScreen (screen_t *scrn, int width, int height, int Bpp) scrn->Bpp = IdTobpp[DisplayID-1000] >> 3; scrn->palette = NULL; - if (scrn == &screens[0]) - surface = new Surface (ptc, width, height, (Bpp == 8) ? INDEX8 : ARGB8888); - else - surface = new Surface (width, height, (Bpp == 8) ? INDEX8 : ARGB8888); + if (DDObj) + { + DDSURFACEDESC ddsd; + HRESULT dderr; + LPDIRECTDRAWSURFACE surface; - if (surface) { - screenchain *tracer = (screenchain *)Malloc (sizeof(struct screenchain)); + if (!scrn->is8bit) + I_FatalError ("Only 8-bit screens are supported"); - scrn->impdata = surface; - tracer->scr = scrn; - tracer->next = chain; - chain = tracer; + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + ddsd.dwWidth = width; + ddsd.dwHeight = height; - if (developer->value && vidactive) { - Printf_Bold ("Allocated new surface. (%dx%dx%d)\n", - surface->GetWidth (), - surface->GetHeight (), - surface->GetBitsPerPixel ()); - Printf (PRINT_HIGH, "Orientation: %d\n", surface->GetOrientation ()); - Printf (PRINT_HIGH, "Layout: %d\n", surface->GetLayout ()); - Printf (PRINT_HIGH, "Advance: %d\n", surface->GetAdvance ()); - Printf (PRINT_HIGH, "Pitch: %d\n", surface->GetPitch ()); - Printf (PRINT_HIGH, "Format: %s\n\n", GetFormatName ((surface->GetFormat ()).id)); + dderr = DDObj->CreateSurface (&ddsd, &surface, NULL); + if (SUCCEEDED(dderr)) + { + screenchain *tracer = (screenchain *)Malloc (sizeof(*tracer)); + + scrn->impdata = surface; + tracer->scr = scrn; + tracer->next = chain; + chain = tracer; + + return true; } - - return true; - } else { - return false; } + else + { + Surface *surface; + + if (scrn == &screen) + surface = new Surface (ptc, width, height, (Bpp == 8) ? INDEX8 : ARGB8888); + else + surface = new Surface (width, height, (Bpp == 8) ? INDEX8 : ARGB8888); + + if (surface) + { + screenchain *tracer = (screenchain *)Malloc (sizeof(*tracer)); + + scrn->impdata = surface; + tracer->scr = scrn; + tracer->next = chain; + chain = tracer; + + if (developer->value && vidactive) + { + Printf_Bold ("Allocated new surface. (%dx%dx%d)\n", + surface->GetWidth (), + surface->GetHeight (), + surface->GetBitsPerPixel ()); + Printf (PRINT_HIGH, "Orientation: %d\n", surface->GetOrientation ()); + Printf (PRINT_HIGH, "Layout: %d\n", surface->GetLayout ()); + Printf (PRINT_HIGH, "Advance: %d\n", surface->GetAdvance ()); + Printf (PRINT_HIGH, "Pitch: %d\n", surface->GetPitch ()); + Printf (PRINT_HIGH, "Format: %s\n\n", GetFormatName ((surface->GetFormat ()).id)); + } + return true; + } + } + return false; } +//========================================================================== +// +// I_FreeScreen +// +//========================================================================== + void I_FreeScreen (screen_t *scrn) { struct screenchain *thisone, *prev; - if (scrn->impdata) { - // Make sure the surface is unlocked - if (scrn->lockcount) - ((Surface *)(scrn->impdata))->Unlock (); + if (scrn->impdata) + { + if (DDObj) + { + // Make sure the surface is unlocked + if (scrn->lockcount) + ((LPDIRECTDRAWSURFACE)(scrn->impdata))->Unlock (NULL); - // Release it - delete (Surface *)(scrn->impdata); - scrn->impdata = NULL; + ((LPDIRECTDRAWSURFACE)(scrn->impdata))->Release (); + scrn->impdata = NULL; + } + else + { + // Make sure the surface is unlocked + if (scrn->lockcount) + ((Surface *)(scrn->impdata))->Unlock (); + + delete (Surface *)(scrn->impdata); + scrn->impdata = NULL; + } } V_DetachPalette (scrn); @@ -637,28 +1106,78 @@ void I_FreeScreen (screen_t *scrn) } } +//========================================================================== +// +// I_LockScreen +// +//========================================================================== + void I_LockScreen (screen_t *scrn) { - if (scrn->impdata) { - scrn->buffer = (byte *)((Surface *)(scrn->impdata))->Lock (); + if (scrn->impdata) + { + if (DDObj) + { + DDSURFACEDESC ddsd; + HRESULT dderr; - if (scrn->buffer == NULL) - I_FatalError ("Could not lock surface"); + memset (&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + do + { + dderr = ((LPDIRECTDRAWSURFACE)(scrn->impdata))->Lock (NULL, + &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + } while (dderr == DDERR_SURFACEBUSY || dderr == DDERR_WASSTILLDRAWING); - scrn->pitch = ((Surface *)(scrn->impdata))->GetPitch (); + // the surface is always in system memory, so it should never be lost + if (FAILED(dderr)) + I_FatalError ("Could not lock surface: %x", dderr); + + scrn->buffer = (byte *)ddsd.lpSurface; + scrn->pitch = ddsd.lPitch; + } + else + { + scrn->buffer = (byte *)((Surface *)(scrn->impdata))->Lock (); + + if (scrn->buffer == NULL) + I_FatalError ("Could not lock surface"); + + scrn->pitch = ((Surface *)(scrn->impdata))->GetPitch (); + } } else { scrn->lockcount--; } } +//========================================================================== +// +// I_UnlockScreen +// +//========================================================================== + void I_UnlockScreen (screen_t *scrn) { - if (scrn->impdata) { - ((Surface *)(scrn->impdata))->Unlock (); + if (scrn->impdata) + { + if (DDObj) + { + ((LPDIRECTDRAWSURFACE)(scrn->impdata))->Unlock (scrn->buffer); + } + else + { + ((Surface *)(scrn->impdata))->Unlock (); + } scrn->buffer = NULL; } } +//========================================================================== +// +// I_Blit +// +//========================================================================== + void I_Blit (screen_t *src, int srcx, int srcy, int srcwidth, int srcheight, screen_t *dest, int destx, int desty, int destwidth, int destheight) { @@ -752,4 +1271,7 @@ void I_Blit (screen_t *src, int srcx, int srcy, int srcwidth, int srcheight, #endif } +// NON-PTC DIRECTDRAW STUFF FOLLOWS ---------------------------------------- + + } // extern "C" \ No newline at end of file diff --git a/code/zdoom.dsp b/code/zdoom.dsp index a5f77f7819..7617a975e7 100644 --- a/code/zdoom.dsp +++ b/code/zdoom.dsp @@ -1830,6 +1830,15 @@ SOURCE=.\win32\resource.h # Begin Source File SOURCE=.\win32\zdoom.rc + +!IF "$(CFG)" == "zdoom - Win32 Release" + +!ELSEIF "$(CFG)" == "zdoom - Win32 Debug" + +!ELSEIF "$(CFG)" == "zdoom - Win32 Profiling" + +!ENDIF + # End Source File # End Group # End Target diff --git a/readme.txt b/readme.txt index 8be37e4650..4b92562ed1 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,4 @@ -This is the source code for ZDoom 1.17 released on 17 February 1999. +This is the source code for ZDoom 1.17a released on 21 February 1999. It is based on the Linux DOOM sources that were prepared by B. Krenheimer and generously released by John Carmack shortly before Christmas, 1997. If