Merge branch 'radiomode' into 'master'

Radio mode

See merge request STJr/SRB2Internal!443
This commit is contained in:
MascaraSnake 2019-11-13 04:16:38 -05:00
commit d591554a5d
16 changed files with 768 additions and 55 deletions

View File

@ -1286,6 +1286,7 @@ void D_SRB2Main(void)
I_StartupSound();
I_InitMusic();
S_InitSfxChannels(cv_soundvolume.value);
S_InitMusicDefs();
}
CONS_Printf("ST_Init(): Init status bar.\n");

View File

@ -3848,13 +3848,14 @@ static void Gravity_OnChange(void)
static void SoundTest_OnChange(void)
{
INT32 sfxfreeint = (INT32)sfxfree;
if (cv_soundtest.value < 0)
{
CV_SetValue(&cv_soundtest, NUMSFX-1);
CV_SetValue(&cv_soundtest, sfxfreeint-1);
return;
}
if (cv_soundtest.value >= NUMSFX)
if (cv_soundtest.value >= sfxfreeint)
{
CV_SetValue(&cv_soundtest, 0);
return;

View File

@ -8656,6 +8656,8 @@ static const char *const MENUTYPES_LIST[] = {
"SR_LEVELSELECT",
"SR_UNLOCKCHECKLIST",
"SR_EMBLEMHINT",
"SR_PLAYER",
"SR_SOUNDTEST",
// Addons (Part of MISC, but let's make it our own)
"AD_MAIN",

View File

@ -137,7 +137,7 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, const UINT8 *colormap)
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
{
FOutVector v[4];
FBITFIELD flags;
@ -182,6 +182,8 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
dupx = dupy = (dupx < dupy ? dupx : dupy);
fscalew = fscaleh = FIXED_TO_FLOAT(pscale);
if (vscale != pscale)
fscaleh = FIXED_TO_FLOAT(vscale);
// See my comments in v_video.c's V_DrawFixedPatch
// -- Monster Iestyn 29/10/18

View File

@ -42,7 +42,7 @@ void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum)
void HWR_InitTextureMapping(void);
void HWR_SetViewSize(void);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_CreatePlanePolygons(INT32 bspnum);

View File

@ -551,6 +551,33 @@ static int libd_drawScaled(lua_State *L)
return 0;
}
static int libd_drawStretched(lua_State *L)
{
fixed_t x, y, hscale, vscale;
INT32 flags;
patch_t *patch;
const UINT8 *colormap = NULL;
HUDONLY
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
hscale = luaL_checkinteger(L, 3);
if (hscale < 0)
return luaL_error(L, "negative horizontal scale");
vscale = luaL_checkinteger(L, 4);
if (vscale < 0)
return luaL_error(L, "negative vertical scale");
patch = *((patch_t **)luaL_checkudata(L, 5, META_PATCH));
flags = luaL_optinteger(L, 6, 0);
if (!lua_isnoneornil(L, 7))
colormap = *((UINT8 **)luaL_checkudata(L, 7, META_COLORMAP));
flags &= ~V_PARAMMASK; // Don't let crashes happen.
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap);
return 0;
}
static int libd_drawNum(lua_State *L)
{
INT32 x, y, flags, num;
@ -902,6 +929,7 @@ static luaL_Reg lib_draw[] = {
// drawing
{"draw", libd_draw},
{"drawScaled", libd_drawScaled},
{"drawStretched", libd_drawStretched},
{"drawNum", libd_drawNum},
{"drawPaddedNum", libd_drawPaddedNum},
{"drawFill", libd_drawFill},

View File

@ -228,6 +228,7 @@ static void M_GetAllEmeralds(INT32 choice);
static void M_DestroyRobots(INT32 choice);
static void M_LevelSelectWarp(INT32 choice);
static void M_Credits(INT32 choice);
static void M_SoundTest(INT32 choice);
static void M_PandorasBox(INT32 choice);
static void M_EmblemHints(INT32 choice);
static void M_HandleChecklist(INT32 choice);
@ -336,8 +337,8 @@ static void M_DrawGenericMenu(void);
static void M_DrawGenericScrollMenu(void);
static void M_DrawCenteredMenu(void);
static void M_DrawAddons(void);
static void M_DrawSkyRoom(void);
static void M_DrawChecklist(void);
static void M_DrawSoundTest(void);
static void M_DrawEmblemHints(void);
static void M_DrawPauseMenu(void);
static void M_DrawServerMenu(void);
@ -706,6 +707,11 @@ static menuitem_t SR_UnlockChecklistMenu[] =
{IT_KEYHANDLER | IT_STRING, NULL, "", M_HandleChecklist, 0},
};
static menuitem_t SR_SoundTestMenu[] =
{
{IT_KEYHANDLER | IT_STRING, NULL, "", M_HandleSoundTest, 0},
};
static menuitem_t SR_EmblemHintMenu[] =
{
{IT_STRING|IT_CVAR, NULL, "Emblem Radar", &cv_itemfinder, 10},
@ -1603,18 +1609,8 @@ menu_t SR_PandoraDef =
0,
M_ExitPandorasBox
};
menu_t SR_MainDef =
{
MN_SR_MAIN,
"M_SECRET",
sizeof (SR_MainMenu)/sizeof (menuitem_t),
&MainDef,
SR_MainMenu,
M_DrawSkyRoom,
60, 40,
0,
NULL
};
menu_t SR_MainDef = DEFAULTMENUSTYLE(MN_SR_MAIN, "M_SECRET", SR_MainMenu, &MainDef, 60, 40);
menu_t SR_LevelSelectDef = MAPPLATTERMENUSTYLE(
MN_SR_MAIN + (MN_SR_LEVELSELECT << 6),
@ -1632,6 +1628,20 @@ menu_t SR_UnlockChecklistDef =
0,
NULL
};
menu_t SR_SoundTestDef =
{
MN_SR_MAIN + (MN_SR_SOUNDTEST << 6),
NULL,
sizeof (SR_SoundTestMenu)/sizeof (menuitem_t),
&SR_MainDef,
SR_SoundTestMenu,
M_DrawSoundTest,
60, 150,
0,
NULL
};
menu_t SR_EmblemHintDef =
{
MN_SR_MAIN + (MN_SR_EMBLEMHINT << 6),
@ -2319,6 +2329,11 @@ void M_InitMenuPresTables(void)
strncpy(menupres[i].musname, "_nitat", 7);
else if (i == MN_SP_PLAYER || i == MN_SR_PLAYER)
strncpy(menupres[i].musname, "_chsel", 7);
else if (i == MN_SR_SOUNDTEST)
{
*menupres[i].musname = '\0';
menupres[i].musstop = true;
}
}
}
@ -6973,7 +6988,7 @@ static void M_DrawEmblemHints(void)
M_DrawGenericMenu();
}
static void M_DrawSkyRoom(void)
/*static void M_DrawSkyRoom(void)
{
INT32 i, y = 0;
@ -7000,6 +7015,266 @@ static void M_DrawSkyRoom(void)
}
if (cv_soundtest.value)
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name);
}*/
static musicdef_t *curplaying = NULL;
static INT32 st_sel = 0, st_cc = 0;
static tic_t st_time = 0;
static patch_t* st_radio[9];
static patch_t* st_launchpad[4];
static void M_SoundTest(INT32 choice)
{
INT32 ul = skyRoomMenuTranslations[choice-1];
UINT8 i;
char buf[8];
soundtestpage = (UINT8)(unlockables[ul].variable);
if (!soundtestpage)
soundtestpage = 1;
if (!S_PrepareSoundTest())
{
M_StartMessage(M_GetText("No selectable tracks found.\n"),NULL,MM_NOTHING);
return;
}
STRBUFCPY(buf, "M_RADIOn");
for (i = 0; i < 9; i++)
{
if (st_radio[i])
W_UnlockCachedPatch(st_radio[i]);
buf[7] = (char)('0'+i);
st_radio[i] = W_CachePatchName(buf, PU_STATIC);
}
STRBUFCPY(buf, "M_LPADn");
for (i = 0; i < 4; i++)
{
if (st_launchpad[i])
W_UnlockCachedPatch(st_launchpad[i]);
buf[6] = (char)('0'+i);
st_launchpad[i] = W_CachePatchName(buf, PU_STATIC);
}
curplaying = NULL;
st_time = 0;
st_sel = 0;
st_cc = cv_closedcaptioning.value; // hack;
cv_closedcaptioning.value = 1; // hack
M_SetupNextMenu(&SR_SoundTestDef);
}
static void M_DrawSoundTest(void)
{
INT32 x, y, i;
fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0;
UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY};
// let's handle the ticker first. ideally we'd tick this somewhere else, BUT...
if (curplaying)
{
if (curplaying == &soundtestsfx)
{
if (cv_soundtest.value)
{
frame[1] = (2-st_time);
frame[2] = ((cv_soundtest.value - 1) % 9);
frame[3] += (((cv_soundtest.value - 1) / 9) % (MAXSKINCOLORS - frame[3]));
if (st_time < 2)
st_time++;
}
}
else
{
if (curplaying->stoppingtics && st_time >= curplaying->stoppingtics)
{
curplaying = NULL;
st_time = 0;
}
else
{
fixed_t work, bpm = curplaying->bpm;
angle_t ang;
//bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpm); -- bake this in on load
work = st_time<<FRACBITS;
work %= bpm;
if (st_time >= (FRACUNIT>>1)) // prevent overflow jump - takes about 15 minutes of loop on the same song to reach
st_time = (work>>FRACBITS);
work = FixedDiv(work*180, bpm);
frame[0] = 8-(work/(20<<FRACBITS));
ang = (FixedAngle(work)>>ANGLETOFINESHIFT) & FINEMASK;
bounce = (FINESINE(ang) - FRACUNIT/2);
hscale -= bounce/16;
vscale += bounce/16;
st_time++;
}
}
}
x = 90<<FRACBITS;
y = (BASEVIDHEIGHT-32)<<FRACBITS;
V_DrawStretchyFixedPatch(x, y,
hscale, vscale,
0, st_radio[frame[0]], NULL);
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, st_launchpad[0], NULL);
for (i = 0; i < 9; i++)
{
if (i == frame[2])
{
UINT8 *colmap = R_GetTranslationColormap(TC_RAINBOW, frame[3], GTC_CACHE);
V_DrawFixedPatch(x, y + (frame[1]<<FRACBITS), FRACUNIT/2, 0, st_launchpad[frame[1]+1], colmap);
}
else
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, st_launchpad[1], NULL);
if ((i % 3) == 2)
{
x -= ((2*28) + 25)<<(FRACBITS-1);
y -= ((2*7) - 11)<<(FRACBITS-1);
}
else
{
x += 28<<(FRACBITS-1);
y += 7<<(FRACBITS-1);
}
}
y = (BASEVIDWIDTH-(vid.width/vid.dupx))/2;
V_DrawFill(y, 20, vid.width/vid.dupx, 24, 159);
{
static fixed_t st_scroll = -1;
const char* titl;
x = 16;
V_DrawString(x, 10, 0, "NOW PLAYING:");
if (curplaying)
{
if (curplaying->alttitle[0])
titl = va("%s - %s - ", curplaying->title, curplaying->alttitle);
else
titl = va("%s - ", curplaying->title);
}
else
titl = "NONE - ";
i = V_LevelNameWidth(titl);
if (++st_scroll >= i)
st_scroll %= i;
x -= st_scroll;
while (x < BASEVIDWIDTH-y)
x += i;
while (x > y)
{
x -= i;
V_DrawLevelTitle(x, 24, 0, titl);
}
if (curplaying)
V_DrawRightAlignedString(BASEVIDWIDTH-16, 46, V_ALLOWLOWERCASE, curplaying->authors);
}
V_DrawFill(165, 60, 140, 112, 159);
{
INT32 t, b, q, m = 112;
if (numsoundtestdefs <= 7)
{
t = 0;
b = numsoundtestdefs - 1;
i = 0;
}
else
{
q = m;
m = (5*m)/numsoundtestdefs;
if (st_sel < 3)
{
t = 0;
b = 6;
i = 0;
}
else if (st_sel >= numsoundtestdefs-4)
{
t = numsoundtestdefs - 7;
b = numsoundtestdefs - 1;
i = q-m;
}
else
{
t = st_sel - 3;
b = st_sel + 3;
i = (t * (q-m))/(numsoundtestdefs - 7);
}
}
V_DrawFill(165+140-1, 60 + i, 1, m, 0);
if (t != 0)
V_DrawString(165+140+4, 60+4 - (skullAnimCounter/5), V_YELLOWMAP, "\x1A");
if (b != numsoundtestdefs - 1)
V_DrawString(165+140+4, 60+112-12 + (skullAnimCounter/5), V_YELLOWMAP, "\x1B");
x = 169;
y = 64;
while (t <= b)
{
if (t == st_sel)
V_DrawFill(165, y-4, 140-1, 16, 155);
if (!soundtestdefs[t]->allowed)
{
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, "???");
}
else if (soundtestdefs[t] == &soundtestsfx)
{
const char *sfxstr = va("SFX %s", cv_soundtest.string);
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0), sfxstr);
if (t == st_sel)
{
V_DrawCharacter(x - 10 - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false);
V_DrawCharacter(x + 2 + V_StringWidth(sfxstr, 0) + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false);
}
if (curplaying == soundtestdefs[t])
{
sfxstr = (cv_soundtest.value) ? S_sfx[cv_soundtest.value].name : "N/A";
i = V_StringWidth(sfxstr, 0);
V_DrawFill(165+140-9-i, y-4, i+8, 16, 150);
V_DrawRightAlignedString(165+140-5, y, V_YELLOWMAP, sfxstr);
}
}
else
{
V_DrawString(x, y, (t == st_sel ? V_YELLOWMAP : 0)|V_ALLOWLOWERCASE, soundtestdefs[t]->title);
if (curplaying == soundtestdefs[t])
{
V_DrawFill(165+140-9, y-4, 8, 16, 150);
//V_DrawCharacter(165+140-8, y, '\x19' | V_YELLOWMAP, false);
V_DrawFixedPatch((165+140-9)<<FRACBITS, (y<<FRACBITS)-(bounce*4), FRACUNIT, 0, hu_font['\x19'-HU_FONTSTART], V_GetStringColormap(V_YELLOWMAP));
}
}
t++;
y += 16;
}
}
}
static void M_HandleSoundTest(INT32 choice)
@ -7009,27 +7284,102 @@ static void M_HandleSoundTest(INT32 choice)
switch (choice)
{
case KEY_DOWNARROW:
M_NextOpt();
S_StartSound(NULL, sfx_menu1);
if (st_sel++ >= numsoundtestdefs-1)
st_sel = 0;
{
cv_closedcaptioning.value = st_cc; // hack
S_StartSound(NULL, sfx_menu1);
cv_closedcaptioning.value = 1; // hack
}
break;
case KEY_UPARROW:
M_PrevOpt();
S_StartSound(NULL, sfx_menu1);
if (!st_sel--)
st_sel = numsoundtestdefs-1;
{
cv_closedcaptioning.value = st_cc; // hack
S_StartSound(NULL, sfx_menu1);
cv_closedcaptioning.value = 1; // hack
}
break;
case KEY_PGDN:
if (st_sel < numsoundtestdefs-1)
{
st_sel += 3;
if (st_sel >= numsoundtestdefs-1)
st_sel = numsoundtestdefs-1;
cv_closedcaptioning.value = st_cc; // hack
S_StartSound(NULL, sfx_menu1);
cv_closedcaptioning.value = 1; // hack
}
break;
case KEY_PGUP:
if (st_sel)
{
st_sel -= 3;
if (st_sel < 0)
st_sel = 0;
cv_closedcaptioning.value = st_cc; // hack
S_StartSound(NULL, sfx_menu1);
cv_closedcaptioning.value = 1; // hack
}
break;
case KEY_BACKSPACE:
if (curplaying)
{
S_StopSounds();
S_StopMusic();
curplaying = NULL;
st_time = 0;
cv_closedcaptioning.value = st_cc; // hack
S_StartSound(NULL, sfx_skid);
cv_closedcaptioning.value = 1; // hack
}
break;
case KEY_ESCAPE:
exitmenu = true;
break;
case KEY_RIGHTARROW:
CV_AddValue(&cv_soundtest, 1);
if (soundtestdefs[st_sel] == &soundtestsfx && soundtestdefs[st_sel]->allowed)
{
S_StopSounds();
S_StopMusic();
curplaying = soundtestdefs[st_sel];
st_time = 0;
CV_AddValue(&cv_soundtest, 1);
}
break;
case KEY_LEFTARROW:
CV_AddValue(&cv_soundtest, -1);
if (soundtestdefs[st_sel] == &soundtestsfx && soundtestdefs[st_sel]->allowed)
{
S_StopSounds();
S_StopMusic();
curplaying = soundtestdefs[st_sel];
st_time = 0;
CV_AddValue(&cv_soundtest, -1);
}
break;
case KEY_ENTER:
S_StopSounds();
S_StartSound(NULL, cv_soundtest.value);
S_StopMusic();
st_time = 0;
if (soundtestdefs[st_sel]->allowed)
{
curplaying = soundtestdefs[st_sel];
if (curplaying == &soundtestsfx)
{
// S_StopMusic() -- is this necessary?
if (cv_soundtest.value)
S_StartSound(NULL, cv_soundtest.value);
}
else
S_ChangeMusicInternal(curplaying->name, !curplaying->stoppingtics);
}
else
{
curplaying = NULL;
S_StartSound(NULL, sfx_lose);
}
break;
default:
@ -7037,6 +7387,11 @@ static void M_HandleSoundTest(INT32 choice)
}
if (exitmenu)
{
Z_Free(soundtestdefs);
soundtestdefs = NULL;
cv_closedcaptioning.value = st_cc; // undo hack
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
@ -7111,8 +7466,8 @@ static void M_SecretsMenu(INT32 choice)
SR_MainMenu[i].itemaction = M_Credits;
break;
case SECRET_SOUNDTEST:
SR_MainMenu[i].status = IT_STRING|IT_KEYHANDLER;
SR_MainMenu[i].itemaction = M_HandleSoundTest;
SR_MainMenu[i].status = IT_STRING|IT_CALL;
SR_MainMenu[i].itemaction = M_SoundTest;
default:
break;
}

View File

@ -106,6 +106,7 @@ typedef enum
MN_SR_UNLOCKCHECKLIST,
MN_SR_EMBLEMHINT,
MN_SR_PLAYER,
MN_SR_SOUNDTEST,
// Addons (Part of MISC, but let's make it our own)
MN_AD_MAIN,

View File

@ -3477,6 +3477,11 @@ boolean P_AddWadFile(const char *wadfilename)
R_PatchSkins(wadnum); // toast: PATCH PATCH
ST_ReloadSkinFaceGraphics();
//
// edit music defs
//
S_LoadMusicDefs(wadnum);
//
// search for maps
//

View File

@ -38,6 +38,7 @@ extern INT32 msg_id;
#include "p_local.h" // camera info
#include "fastcmp.h"
#include "m_misc.h" // for tunes command
#include "m_cond.h" // for conditionsets
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
#include "lua_hook.h" // MusicChange hook
@ -1425,6 +1426,274 @@ static UINT32 queue_fadeinms;
static tic_t pause_starttic;
/// ------------------------
/// Music Definitions
/// ------------------------
musicdef_t soundtestsfx = {
"_STSFX", // prevents exactly one valid track name from being used on the sound test
"Sound Effects",
"",
"SEGA, Sonic Team Jr, other sources",
1, // show on soundtest page 1
0, // with no conditions
0,
0,
false,
NULL
};
musicdef_t *musicdefstart = &soundtestsfx;
//
// search for music definition in wad
//
static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
{
UINT16 i;
lumpinfo_t *lump_p;
lump_p = wadfiles[wadid]->lumpinfo;
for (i = 0; i < wadfiles[wadid]->numlumps; i++, lump_p++)
if (memcmp(lump_p->name, "MUSICDEF", 8) == 0)
return i;
return INT16_MAX; // not found
}
void S_LoadMusicDefs(UINT16 wadnum)
{
UINT16 lump;
char *buf;
char *buf2;
char *stoken;
char *value;
size_t size;
INT32 i;
musicdef_t *def = NULL;
UINT16 line = 1; // for better error msgs
lump = W_CheckForMusicDefInPwad(wadnum);
if (lump == INT16_MAX)
return;
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lump);
// for strtok
buf2 = malloc(size+1);
if (!buf2)
I_Error("S_LoadMusicDefs: No more free memory\n");
M_Memcpy(buf2,buf,size);
buf2[size] = '\0';
stoken = strtok (buf2, "\r\n ");
// Find music def
while (stoken)
{
/*if ((stoken[0] == '/' && stoken[1] == '/')
|| (stoken[0] == '#')) // skip comments
{
stoken = strtok(NULL, "\r\n"); // skip end of line
if (def)
stoken = strtok(NULL, "\r\n= ");
else
stoken = strtok(NULL, "\r\n ");
line++;
}
else*/ if (!stricmp(stoken, "lump"))
{
value = strtok(NULL, "\r\n ");
if (!value)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Lump '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_lump;
}
// No existing musicdefs
/*if (!musicdefstart)
{
musicdefstart = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(musicdefstart->name, value);
strlwr(musicdefstart->name);
def = musicdefstart;
//CONS_Printf("S_LoadMusicDefs: Initialized musicdef w/ song '%s'\n", def->name);
}
else*/
{
musicdef_t *prev = NULL;
def = musicdefstart;
// Search if this is a replacement
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
while (def)
{
if (!stricmp(def->name, value))
{
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
break;
}
prev = def;
def = def->next;
}
// Nothing found, add to the end.
if (!def)
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(def->name, value);
strlwr(def->name);
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
if (prev != NULL)
prev->next = def;
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
}
}
skip_lump:
stoken = strtok(NULL, "\r\n ");
line++;
}
else
{
value = strtok(NULL, "\r\n= ");
if (!value)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_field;
}
if (!def)
{
CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
free(buf2);
return;
}
i = atoi(value);
if (!stricmp(stoken, "usage")) {
#if 0 // Ignore for now
STRBUFCPY(def->usage, value);
for (value = def->usage; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
#endif
} else if (!stricmp(stoken, "source")) {
#if 0 // Ignore for now
STRBUFCPY(def->source, value);
for (value = def->source; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage);
#endif
} else if (!stricmp(stoken, "title")) {
STRBUFCPY(def->title, value);
for (value = def->title; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source);
} else if (!stricmp(stoken, "alttitle")) {
STRBUFCPY(def->alttitle, value);
for (value = def->alttitle; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source);
} else if (!stricmp(stoken, "authors")) {
STRBUFCPY(def->authors, value);
for (value = def->authors; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source);
} else if (!stricmp(stoken, "soundtestpage")) {
def->soundtestpage = (UINT8)i;
} else if (!stricmp(stoken, "soundtestcond")) {
// Convert to map number
if (value[0] >= 'A' && value[0] <= 'Z' && value[2] == '\0')
i = M_MapNumber(value[0], value[1]);
def->soundtestcond = (INT16)i;
} else if (!stricmp(stoken, "stoppingtime")) {
double stoppingtime = atof(value)*TICRATE;
def->stoppingtics = (tic_t)stoppingtime;
} else if (!stricmp(stoken, "bpm")) {
double bpm = atof(value);
fixed_t bpmf = FLOAT_TO_FIXED(bpm);
if (bpmf > 0)
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
} else {
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
}
skip_field:
stoken = strtok(NULL, "\r\n= ");
line++;
}
}
free(buf2);
return;
}
//
// S_InitMusicDefs
//
// Simply load music defs in all wads.
//
void S_InitMusicDefs(void)
{
UINT16 i;
for (i = 0; i < numwadfiles; i++)
S_LoadMusicDefs(i);
}
musicdef_t **soundtestdefs = NULL;
INT32 numsoundtestdefs = 0;
UINT8 soundtestpage = 1;
//
// S_PrepareSoundTest
//
// Prepare sound test. What am I, your butler?
//
boolean S_PrepareSoundTest(void)
{
musicdef_t *def;
INT32 pos = numsoundtestdefs = 0;
for (def = musicdefstart; def; def = def->next)
{
if (!(def->soundtestpage & soundtestpage))
continue;
def->allowed = false;
numsoundtestdefs++;
}
if (!numsoundtestdefs)
return false;
if (soundtestdefs)
Z_Free(soundtestdefs);
if (!(soundtestdefs = Z_Malloc(numsoundtestdefs*sizeof(musicdef_t *), PU_STATIC, NULL)))
I_Error("S_PrepareSoundTest(): could not allocate soundtestdefs.");
for (def = musicdefstart; def /*&& i < numsoundtestdefs*/; def = def->next)
{
if (!(def->soundtestpage & soundtestpage))
continue;
soundtestdefs[pos++] = def;
if (def->soundtestcond > 0 && !(mapvisited[def->soundtestcond-1] & MV_BEATEN))
continue;
if (def->soundtestcond < 0 && !M_Achieved(1-def->soundtestcond))
continue;
def->allowed = true;
}
return true;
}
/// ------------------------
/// Music Status
/// ------------------------

View File

@ -188,6 +188,39 @@ boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
// Set Speed of Music
boolean S_SpeedMusic(float speed);
// Music definitions
typedef struct musicdef_s
{
char name[7];
char title[32];
char alttitle[64];
char authors[256];
//char usage[256]; -- probably never going to be relevant to vanilla
/*
the trouble here is that kart combines what we call "title"
and "authors" into one string. we need to split it for sound
test reasons. they might split it later like we did, but...
*/
//char source[256];
UINT8 soundtestpage;
INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here
tic_t stoppingtics;
fixed_t bpm;
boolean allowed; // question marks or listenable on sound test?
struct musicdef_s *next;
} musicdef_t;
extern musicdef_t soundtestsfx;
extern musicdef_t *musicdefstart;
extern musicdef_t **soundtestdefs;
extern INT32 numsoundtestdefs;
extern UINT8 soundtestpage;
void S_LoadMusicDefs(UINT16 wadnum);
void S_InitMusicDefs(void);
boolean S_PrepareSoundTest(void);
//
// Music Seeking
//

View File

@ -857,35 +857,45 @@ void S_InitRuntimeSounds (void)
}
}
sfxenum_t sfxfree = sfx_freeslot0;
// Add a new sound fx into a free sfx slot.
//
sfxenum_t S_AddSoundFx(const char *name, boolean singular, INT32 flags, boolean skinsound)
{
sfxenum_t i, slot;
sfxenum_t i;
if (skinsound)
slot = sfx_skinsoundslot0;
else
slot = sfx_freeslot0;
for (i = slot; i < NUMSFX; i++)
{
if (!S_sfx[i].priority)
for (i = sfx_skinsoundslot0; i < NUMSFX; i++)
{
strncpy(freeslotnames[i-sfx_freeslot0], name, 6);
S_sfx[i].singularity = singular;
S_sfx[i].priority = 60;
S_sfx[i].pitch = flags;
S_sfx[i].volume = -1;
S_sfx[i].lumpnum = LUMPERROR;
S_sfx[i].skinsound = -1;
S_sfx[i].usefulness = -1;
/// \todo if precached load it here
S_sfx[i].data = NULL;
return i;
if (S_sfx[i].priority)
continue;
break;
}
}
else
i = sfxfree;
if (i < NUMSFX)
{
strncpy(freeslotnames[i-sfx_freeslot0], name, 6);
S_sfx[i].singularity = singular;
S_sfx[i].priority = 60;
S_sfx[i].pitch = flags;
S_sfx[i].volume = -1;
S_sfx[i].lumpnum = LUMPERROR;
S_sfx[i].skinsound = -1;
S_sfx[i].usefulness = -1;
/// \todo if precached load it here
S_sfx[i].data = NULL;
if (!skinsound)
sfxfree++;
return i;
}
CONS_Alert(CONS_WARNING, M_GetText("No more free sound slots\n"));
return 0;
}

View File

@ -879,6 +879,7 @@ typedef enum
void S_InitRuntimeSounds(void);
sfxenum_t S_AddSoundFx(const char *name, boolean singular, INT32 flags, boolean skinsound);
extern sfxenum_t sfxfree; // sound test and slotting
void S_RemoveSoundFx(sfxenum_t id);
#endif

View File

@ -541,12 +541,12 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix
}
// Draws a patch scaled to arbitrary size.
void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT32 alphalevel = 0;
fixed_t col, ofs, colfrac, rowfrac, fdup;
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dupx, dupy;
const column_t *column;
UINT8 *desttop, *dest, *deststart, *destend;
@ -563,7 +563,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
//if (rendermode != render_soft && !con_startup) // Why?
if (rendermode != render_soft)
{
HWR_DrawFixedPatch((GLPatch_t *)patch, x, y, pscale, scrn, colormap);
HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap);
return;
}
#endif
@ -618,9 +618,11 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
// only use one dup, to avoid stretching (har har)
dupx = dupy = (dupx < dupy ? dupx : dupy);
fdup = FixedMul(dupx<<FRACBITS, pscale);
fdup = vdup = FixedMul(dupx<<FRACBITS, pscale);
if (vscale != pscale)
vdup = FixedMul(dupx<<FRACBITS, vscale);
colfrac = FixedDiv(FRACUNIT, fdup);
rowfrac = FixedDiv(FRACUNIT, fdup);
rowfrac = FixedDiv(FRACUNIT, vdup);
// So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible
// For now let's just at least give V_OFFSET the ability to support V_FLIP
@ -637,7 +639,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
// top offset
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
offsety = FixedMul(SHORT(patch->topoffset)<<FRACBITS, pscale);
offsety = FixedMul(SHORT(patch->topoffset)<<FRACBITS, vscale);
if ((scrn & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
{
@ -653,13 +655,14 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
if (splitscreen && (scrn & V_PERPLAYER))
{
fixed_t adjusty = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1);
fdup >>= 1;
vdup >>= 1;
rowfrac <<= 1;
y >>= 1;
#ifdef QUADS
if (splitscreen > 1) // 3 or 4 players
{
fixed_t adjustx = ((scrn & V_NOSCALESTART) ? vid.height : BASEVIDHEIGHT)<<(FRACBITS-1));
fdup >>= 1;
colfrac <<= 1;
x >>= 1;
if (stplyr == &players[displayplayer])
@ -825,7 +828,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*vid.width;
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
{

View File

@ -140,7 +140,8 @@ extern RGBA_t *pMasterPalette;
#define V_DrawSmallTranslucentPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, s, p, NULL)
#define V_DrawTinyTranslucentPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/4, s, p, NULL)
#define V_DrawSciencePatch(x,y,s,p,sc) V_DrawFixedPatch(x,y,sc,s,p,NULL)
void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, const UINT8 *colormap);
#define V_DrawFixedPatch(x,y,sc,s,p,c) V_DrawStretchyFixedPatch(x,y,sc,sc,s,p,c)
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap);
void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor);

View File

@ -1891,6 +1891,7 @@ int W_VerifyNMUSlumps(const char *filename)
{"STT", 3}, // Acceptable HUD changes (Score Time Rings)
{"YB_", 3}, // Intermission graphics, goes with the above
{"M_", 2}, // As does menu stuff
{"MUSICDEF", 8}, // Song definitions (thanks kart)
{NULL, 0},
};