port: modconfig: add user defined extended weather config

includes a way to specify weatherproof rooms and other hardcoded stuff

this might break something, as it removes some hardcoded checks
This commit is contained in:
fgsfds committed 2023-09-27 19:44:51 +02:00
1 parent d98575d77b
commit 704015deac
7 files changed
+517 -69

No files matched your search

+210 -66
View File
@@ -13,6 +13,35 @@
extern struct stagemusic g_StageTracks[];
extern struct stageallocation g_StageAllocations8Mb[];
#define PARSE_STAGE_FLOAT(sec, name, v, min, max) \
p = modConfigParseFloatValue(p, token, &v); \
if (!p || v < (min) || v > (max)) { \
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: " sec " invalid " name " value: %s", stagenum, token); \
return NULL; \
}
#define PARSE_STAGE_INT(sec, name, v, min, max) \
p = modConfigParseIntValue(p, token, &v); \
if (!p || v < (min) || v > (max)) { \
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: " sec " invalid " name " value: %s", stagenum, token); \
return NULL; \
}
#define PARSE_STAGE_FILENAME(sec, name, v) \
p = modConfigParseFileValue(p, token, &v); \
if (!p) { \
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: " sec " invalid " name " value: %s", stagenum, token); \
return NULL; \
}
#define PARSE_STAGE_STRING(sec, name, v) \
p = strParseToken(p, token, NULL); \
if (!p) { \
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: " sec " invalid " name " value: %s", stagenum, token); \
return NULL; \
} \
v = strUnquote(token);
static inline char *modConfigParseFileValue(char *p, char *token, s32 *filenum)
{
p = strParseToken(p, token, NULL);
@@ -35,7 +64,7 @@ static inline char *modConfigParseFileValue(char *p, char *token, s32 *filenum)
return NULL;
}
static inline char *modConfigParseNumericValue(char *p, char *token, s32 *out)
static inline char *modConfigParseIntValue(char *p, char *token, s32 *out)
{
p = strParseToken(p, token, NULL);
if (!token[0]) {
@@ -50,7 +79,22 @@ static inline char *modConfigParseNumericValue(char *p, char *token, s32 *out)
return p;
}
static inline char *modConfigParseStageMusic(char *p, char *token, s32 stagenum)
static inline char *modConfigParseFloatValue(char *p, char *token, f32 *out)
{
p = strParseToken(p, token, NULL);
if (!token[0]) {
return NULL; // empty
}
char *endp = token;
const f32 num = strtof(token, &endp);
if (num == 0.f && (endp == token || *endp != '\0')) {
return NULL;
}
*out = num;
return p;
}
static char *modConfigParseStageMusic(char *p, char *token, s32 stagenum)
{
struct stagemusic *smus = NULL;
for (struct stagemusic *p = g_StageTracks; p->stagenum; ++p) {
@@ -76,25 +120,13 @@ static inline char *modConfigParseStageMusic(char *p, char *token, s32 stagenum)
p = strParseToken(p, token, NULL);
while (p && token[0] && strcmp(token, "}") != 0) {
if (!strcmp(token, "primarytrack")) {
p = modConfigParseNumericValue(p, token, &tmp);
if (!p || tmp < 0 || tmp > 128) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: music: invalid primarytrack value: %s", stagenum, token);
return NULL;
}
PARSE_STAGE_INT("music:", "primarytrack", tmp, 0, 128);
smus->primarytrack = tmp;
} else if (!strcmp(token, "ambienttrack")) {
p = modConfigParseNumericValue(p, token, &tmp);
if (!p || tmp < 0 || tmp > 128) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: music: invalid ambienttrack value: %s", stagenum, token);
return NULL;
}
PARSE_STAGE_INT("music:", "ambienttrack", tmp, 0, 128);
smus->ambienttrack = tmp;
} else if (!strcmp(token, "xtrack")) {
p = modConfigParseNumericValue(p, token, &tmp);
if (!p || tmp < 0 || tmp > 128) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: music: invalid xtrack value: %s", stagenum, token);
return NULL;
}
PARSE_STAGE_INT("music:", "xtrack", tmp, 0, 128);
smus->xtrack = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: music: invalid key: %s", stagenum, token);
@@ -111,7 +143,136 @@ static inline char *modConfigParseStageMusic(char *p, char *token, s32 stagenum)
return p;
}
static inline char *modConfigParseStage(char *p, char *token)
static char *modConfigParseStageWeatherRooms(char *p, char *token, s32 stagenum, struct weathercfg *wcfg)
{
// determine where we can start adding rooms
s32 idx;
for (idx = 0; idx < WEATHERCFG_MAX_SKIPROOMS && wcfg->skiprooms[idx]; ++idx);
// eat opening bracket
p = strParseToken(p, token, NULL);
if (token[0] != '{' || token[1] != '\0') {
return NULL;
}
// check if user wants to clear the whole list
p = strParseToken(p, token, NULL);
if (!strcmp(token, "clear")) {
memset(wcfg->skiprooms, 0, sizeof(wcfg->skiprooms));
idx = 0;
p = strParseToken(p, token, NULL);
}
s32 tmp = 0;
while (p && token[0] && strcmp(token, "}") != 0) {
if (token[0] == ',' && !token[1]) {
p = strParseToken(p, token, NULL);
continue;
}
tmp = strtol(token, NULL, 0);
if (tmp <= 0 || tmp > 32767) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: weather: rooms: invalid room %s", stagenum, token);
return NULL;
}
if (idx < WEATHERCFG_MAX_SKIPROOMS) {
wcfg->skiprooms[idx++] = tmp;
}
p = strParseToken(p, token, NULL);
}
if (token[0] != '}') {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: weather: unterminated rooms block", stagenum);
return NULL;
}
return p;
}
static char *modConfigParseStageWeather(char *p, char *token, s32 stagenum)
{
s32 wi;
struct weathercfg *wcfg = NULL;
for (wi = 0; wi < ARRAYCOUNT(g_WeatherConfig) && g_WeatherConfig[wi].stagenum; ++wi) {
if (g_WeatherConfig[wi].stagenum == stagenum) {
break;
}
}
if (wi >= WEATHERCFG_MAX_STAGES) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: no more space for weather config", stagenum);
return NULL;
}
wcfg = &g_WeatherConfig[wi];
if (!wcfg->stagenum) {
// new weather config; initialize with defaults
*wcfg = g_DefaultWeatherConfig;
wcfg->stagenum = stagenum;
} else {
// flags have to be re-specified
wcfg->flags = 0;
}
// eat opening bracket
p = strParseToken(p, token, NULL);
if (token[0] != '{' || token[1] != '\0') {
return NULL;
}
// parse keyvalues until } is reached
s32 tmpi = 0;
f32 tmpf = 0.f;
p = strParseToken(p, token, NULL);
while (p && token[0] && strcmp(token, "}") != 0) {
if (!strcmp(token, "include_rooms") || !strcmp(token, "exclude_rooms")) {
// include_rooms | exclude_rooms { ROOM_NUMBERS... }
const s32 include = (token[0] == 'i');
p = modConfigParseStageWeatherRooms(p, token, stagenum, wcfg);
if (!p) {
return NULL;
}
if (wcfg->skiprooms[0] && include) {
wcfg->flags |= WEATHERFLAG_INCLUDE;
}
} else if (!strcmp(token, "cutscene_only")) {
wcfg->flags |= WEATHERFLAG_CUTSCENE_ONLY;
} else if (!strcmp(token, "constant_wind")) {
PARSE_STAGE_FLOAT("weather:", "constant_wind (0)", wcfg->windanglerad, -M_TAU, M_TAU);
PARSE_STAGE_FLOAT("weather:", "constant_wind (1)", wcfg->windspeedx, -1024.f, 1024.f);
PARSE_STAGE_FLOAT("weather:", "constant_wind (2)", wcfg->windspeedz, -1024.f, 1024.f);
wcfg->flags |= WEATHERFLAG_FORCE_WINDDIR;
} else if (!strcmp(token, "windspeed")) {
PARSE_STAGE_FLOAT("weather:", "windspeed", tmpf, -1024.f, 1024.f);
wcfg->windspeed = tmpf;
} else if (!strcmp(token, "ymin")) {
PARSE_STAGE_FLOAT("weather:", "ymin", tmpf, -65536.f, 65536.f);
wcfg->ymin = tmpf;
} else if (!strcmp(token, "ymax")) {
PARSE_STAGE_FLOAT("weather:", "ymax", tmpf, -65536.f, 65536.f);
wcfg->ymax = tmpf;
} else if (!strcmp(token, "zmax")) {
PARSE_STAGE_FLOAT("weather:", "zmax", tmpf, -65536.f, 65536.f);
wcfg->zmax = tmpf;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: weather: invalid key: %s", stagenum, token);
return NULL;
}
p = strParseToken(p, token, NULL);
}
if (token[0] != '}') {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: unterminated weather block", stagenum);
return NULL;
}
return p;
}
static char *modConfigParseStage(char *p, char *token)
{
// stage number
p = strParseToken(p, token, NULL);
@@ -132,6 +293,9 @@ static inline char *modConfigParseStage(char *p, char *token)
const s32 sidx = stageGetIndex(stagenum);
if (sidx >= 0) {
stab = &g_Stages[sidx];
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: unknown stage number", stagenum);
return NULL;
}
for (struct stageallocation *p = g_StageAllocations8Mb; p->stagenum; ++p) {
if (p->stagenum == stagenum) {
@@ -142,65 +306,36 @@ static inline char *modConfigParseStage(char *p, char *token)
// parse keyvalues until } is reached
s32 tmp = 0;
char *tmps = NULL;
p = strParseToken(p, token, NULL);
while (p && token[0] && strcmp(token, "}") != 0) {
if (!strcmp(token, "bgfile")) {
// bg FILE_NAME_OR_NUM
p = modConfigParseFileValue(p, token, &tmp);
if (p && stab) {
stab->bgfileid = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid bgfile value: %s", stagenum, token);
return NULL;
}
PARSE_STAGE_FILENAME("", "bgfile", tmp);
stab->bgfileid = tmp;
} else if (!strcmp(token, "tilesfile")) {
// tiles FILE_NAME_OR_NUM
p = modConfigParseFileValue(p, token, &tmp);
if (p && stab) {
stab->tilefileid = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid tilesfile value: %s", stagenum, token);
return NULL;
}
// tilesfile FILE_NAME_OR_NUM
PARSE_STAGE_FILENAME("", "tilesfile", tmp);
stab->tilefileid = tmp;
} else if (!strcmp(token, "padsfile")) {
// tiles FILE_NAME_OR_NUM
p = modConfigParseFileValue(p, token, &tmp);
if (p && stab) {
stab->padsfileid = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid padsfile value: %s", stagenum, token);
return NULL;
}
// padsfile FILE_NAME_OR_NUM
PARSE_STAGE_FILENAME("", "padsfile", tmp);
stab->padsfileid = tmp;
} else if (!strcmp(token, "setupfile")) {
// setup FILE_NAME_OR_NUM
p = modConfigParseFileValue(p, token, &tmp);
if (p && stab) {
stab->setupfileid = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid setupfile value: %s", stagenum, token);
return NULL;
}
// setupfile FILE_NAME_OR_NUM
PARSE_STAGE_FILENAME("", "setupfile", tmp);
stab->setupfileid = tmp;
} else if (!strcmp(token, "mpsetupfile")) {
// mpsetup FILE_NAME_OR_NUM
p = modConfigParseFileValue(p, token, &tmp);
if (p && stab) {
stab->mpsetupfileid = tmp;
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid mpsetupfile value: %s", stagenum, token);
return NULL;
}
// mpsetupfile FILE_NAME_OR_NUM
PARSE_STAGE_FILENAME("", "mpsetupfile", tmp);
stab->mpsetupfileid = tmp;
} else if (!strcmp(token, "allocation")) {
// allocation "ALLOCSTRING"
p = strParseToken(p, token, NULL);
char *str = strUnquote(token);
if (!p || !str[0] || !salloc) {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid allocation value: %s", stagenum, token);
return NULL;
}
PARSE_STAGE_STRING("", "allocation", tmps);
// FIXME: this leaks
str = strDuplicate(str);
if (str) {
salloc->string = str;
tmps = strDuplicate(tmps);
if (tmps) {
salloc->string = tmps;
}
} else if (!strcmp(token, "music")) {
// music { KEYVALUES... }
@@ -208,6 +343,15 @@ static inline char *modConfigParseStage(char *p, char *token)
if (!p) {
return NULL;
}
} else if (!strcmp(token, "weather")) {
// weather { KEYVALUES... }
p = modConfigParseStageWeather(p, token, stagenum);
if (!p) {
return NULL;
}
} else {
sysLogPrintf(LOG_ERROR, "modconfig: stage 0x%02x: invalid key: %s", stagenum, token);
return NULL;
}
p = strParseToken(p, token, NULL);
}
+3
View File
@@ -1686,6 +1686,9 @@ void bgBuildTables(s32 stagenum)
g_Rooms[i].unk4d = 0;
g_Rooms[i].lightop = 0;
g_Rooms[i].unk4e_04 = 0;
#ifndef PLATFORM_N64
g_Rooms[i].extra_flags = 0;
#endif
}
bgSetStageTranslationThing(g_Stages[g_StageIndex].unk14);
+219 -2
View File
@@ -24,6 +24,179 @@
struct weatherdata *g_WeatherData = NULL;
#ifndef PLATFORM_N64
struct weathercfg g_WeatherConfig[WEATHERCFG_MAX_STAGES] = {
{
STAGE_G5BUILDING,
WEATHERFLAG_CUTSCENE_ONLY,
20.f,
-800.f, 800.f,
0.f,
},
{
STAGE_CHICAGO,
0,
20.f,
-800.f, 800.f,
0.f,
{
ROOM_PETE_0062,
ROOM_PETE_0061,
ROOM_PETE_000F,
ROOM_PETE_0052,
ROOM_PETE_0045,
ROOM_PETE_0044,
ROOM_PETE_0043,
ROOM_PETE_003D,
ROOM_PETE_000E,
ROOM_PETE_000D,
ROOM_PETE_000C,
ROOM_PETE_000B,
ROOM_PETE_000A,
ROOM_PETE_0009,
ROOM_PETE_0008,
ROOM_PETE_0007,
ROOM_PETE_0006,
ROOM_PETE_0005,
ROOM_PETE_0004,
ROOM_PETE_0037,
ROOM_PETE_005B,
ROOM_PETE_005F,
ROOM_PETE_0060,
ROOM_PETE_005D,
ROOM_PETE_001D,
ROOM_PETE_001F,
ROOM_PETE_0027,
ROOM_PETE_0050,
ROOM_PETE_002C,
ROOM_PETE_002F,
ROOM_PETE_0030,
ROOM_PETE_0011,
ROOM_PETE_0024,
ROOM_PETE_0033,
ROOM_PETE_0034,
ROOM_PETE_0035,
ROOM_PETE_0036,
ROOM_PETE_003C,
ROOM_PETE_0046,
ROOM_PETE_0047,
ROOM_PETE_0049,
ROOM_PETE_0055,
ROOM_PETE_0056,
ROOM_PETE_005E,
ROOM_PETE_0063,
ROOM_PETE_0069,
ROOM_PETE_0003,
ROOM_PETE_0016,
ROOM_PETE_004F,
ROOM_PETE_004B,
ROOM_PETE_003F,
ROOM_PETE_0013,
ROOM_PETE_0019,
0
}
},
{
STAGE_AIRBASE,
WEATHERFLAG_INCLUDE | WEATHERFLAG_FORCE_WINDDIR,
5.f,
-800.f, 800.f,
-2000.f,
{
ROOM_CAVE_0088,
ROOM_CAVE_0091,
ROOM_CAVE_0087,
ROOM_CAVE_0090,
ROOM_CAVE_0086,
ROOM_CAVE_0080,
ROOM_CAVE_0083,
ROOM_CAVE_0084,
ROOM_CAVE_0085,
ROOM_CAVE_007F,
ROOM_CAVE_007E,
ROOM_CAVE_0082,
ROOM_CAVE_008F,
ROOM_CAVE_008E,
ROOM_CAVE_007B,
ROOM_CAVE_007C,
ROOM_CAVE_007D,
ROOM_CAVE_0081,
ROOM_CAVE_006F,
0
},
1.5707963705063f,
0.f,
-5.f
},
{
STAGE_CRASHSITE,
0,
10.f,
-500.f, 500.f,
0.f,
{
ROOM_AZT_001F,
ROOM_AZT_0020,
ROOM_AZT_0021,
ROOM_AZT_0022,
ROOM_AZT_0023,
ROOM_AZT_0024,
ROOM_AZT_0051,
ROOM_AZT_0052,
ROOM_AZT_0053,
ROOM_AZT_0054,
ROOM_AZT_0055,
ROOM_AZT_0056,
ROOM_AZT_0057,
ROOM_AZT_0058,
ROOM_AZT_0059,
ROOM_AZT_005A,
ROOM_AZT_005B,
ROOM_AZT_005C,
ROOM_AZT_005D,
ROOM_AZT_005E,
ROOM_AZT_005F,
ROOM_AZT_0060,
ROOM_AZT_0061,
ROOM_AZT_0062,
ROOM_AZT_0063,
ROOM_AZT_0064,
ROOM_AZT_002D,
ROOM_AZT_0040,
ROOM_AZT_0041,
ROOM_AZT_0042,
ROOM_AZT_0043,
ROOM_AZT_0044,
ROOM_AZT_0045,
ROOM_AZT_0046,
ROOM_AZT_0047,
ROOM_AZT_0048,
ROOM_AZT_0049,
ROOM_AZT_004A,
ROOM_AZT_004B,
ROOM_AZT_004C,
ROOM_AZT_004D,
ROOM_AZT_004E,
ROOM_AZT_004F,
ROOM_AZT_0050,
0
}
},
};
const struct weathercfg g_DefaultWeatherConfig = {
0,
0,
20.f,
-800.f, 800.f,
0.f
};
const struct weathercfg *g_CurWeatherConfig = &g_DefaultWeatherConfig;
#endif
Gfx *weatherRender(Gfx *gdl)
{
struct weatherdata *weather;
@@ -32,6 +205,7 @@ Gfx *weatherRender(Gfx *gdl)
return gdl;
}
#ifdef PLATFORM_N64
if (g_StageIndex == STAGEINDEX_AIRBASE && g_Vars.currentplayer->cam_pos.z < -2000.0f) {
return gdl;
}
@@ -39,6 +213,15 @@ Gfx *weatherRender(Gfx *gdl)
if (g_StageIndex == STAGEINDEX_G5BUILDING && g_Vars.tickmode != TICKMODE_CUTSCENE) {
return gdl;
}
#else
if (g_CurWeatherConfig->zmax && g_Vars.currentplayer->cam_pos.z < g_CurWeatherConfig->zmax) {
return gdl;
}
if ((g_CurWeatherConfig->flags & WEATHERFLAG_CUTSCENE_ONLY) && g_Vars.tickmode != TICKMODE_CUTSCENE) {
return gdl;
}
#endif
weather = g_WeatherData;
@@ -89,11 +272,15 @@ struct weatherparticledata *weatherAllocateParticles(void)
weatherSetBoundaries(data, 0, -800, 800);
#ifdef PLATFORM_N64
if ((u32)g_StageIndex == STAGEINDEX_CRASHSITE) {
weatherSetBoundaries(data, 1, -500, 500);
} else {
weatherSetBoundaries(data, 1, -800, 800);
}
#else
weatherSetBoundaries(data, 1, g_CurWeatherConfig->ymin, g_CurWeatherConfig->ymax);
#endif
weatherSetBoundaries(data, 2, -800, 800);
@@ -340,12 +527,22 @@ void weatherTickRain(struct weatherdata *weather)
}
}
#ifdef PLATFORM_N64
if (g_StageIndex == STAGEINDEX_AIRBASE) {
// Force weather direction - but Air Base doesn't use rain...
weather->windanglerad = 1.5707963705063f;
weather->windspeedz = -weather->windspeed;
weather->windspeedx = 0;
} else if (weather->unk10 > 0) {
}
#else
if (g_CurWeatherConfig->flags & WEATHERFLAG_FORCE_WINDDIR) {
// force weather direction if requested
weather->windanglerad = g_CurWeatherConfig->windanglerad;
weather->windspeedz = g_CurWeatherConfig->windspeedz;
weather->windspeedx = g_CurWeatherConfig->windspeedx;
}
#endif
else if (weather->unk10 > 0) {
s32 lvupdate = g_Vars.lvupdate60;
if (weather->unk10 < lvupdate) {
@@ -437,11 +634,21 @@ void weatherTickSnow(struct weatherdata *weather)
mainOverrideVariable("snowspeed", &g_SnowSpeed);
mainOverrideVariable("snowspeedxtra", &g_SnowSpeedExtra);
#ifdef PLATFORM_N64
if (g_StageIndex == STAGEINDEX_AIRBASE) {
weather->windanglerad = 1.5707963705063f;
weather->windspeedz = -weather->windspeed;
weather->windspeedx = 0;
} else if (weather->unk10 > 0) {
}
#else
if (g_CurWeatherConfig->flags & WEATHERFLAG_FORCE_WINDDIR) {
// force weather direction if requested
weather->windanglerad = g_CurWeatherConfig->windanglerad;
weather->windspeedz = g_CurWeatherConfig->windspeedz;
weather->windspeedx = g_CurWeatherConfig->windspeedx;
}
#endif
else if (weather->unk10 > 0) {
s32 lvupdate = g_Vars.lvupdate60;
if (weather->unk10 < lvupdate) {
@@ -618,6 +825,7 @@ void weatherConfigureSnow(u32 intensity)
bool weatherIsRoomWeatherProof(s32 room)
{
#ifdef PLATFORM_N64
if (g_StageIndex == STAGEINDEX_CHICAGO) {
// Rooms listed do not have weather
if (room == ROOM_PETE_0062
@@ -757,6 +965,15 @@ bool weatherIsRoomWeatherProof(s32 room)
return false;
}
#else
if (room >= 0 && room < g_Vars.roomcount) {
// check room's extra_flags
if (g_Rooms[room].extra_flags & ROOMFLAG_EX_WEATHERPROOF) {
// this room has no weather
return true;
}
}
#endif
return false;
}
+50 -1
View File
@@ -11,16 +11,59 @@ u32 var800623f4 = 0x00000000;
u32 var800623f8 = 0x00000000;
u32 var800623fc = 0x00000000;
#ifndef PLATFORM_N64
static void weatherResetRooms(void)
{
if (g_CurWeatherConfig->flags & WEATHERFLAG_INCLUDE) {
// weather is present only in skiprooms, so mark every room as weatherproof
for (s32 i = 0; i < g_Vars.roomcount; ++i) {
g_Rooms[i].extra_flags |= ROOMFLAG_EX_WEATHERPROOF;
}
// then unmark skiprooms
for (s32 i = 0; i < WEATHERCFG_MAX_SKIPROOMS && g_CurWeatherConfig->skiprooms[i]; ++i) {
const RoomNum room = g_CurWeatherConfig->skiprooms[i];
if (room >= 0 && room < g_Vars.roomcount) {
g_Rooms[room].extra_flags &= ~ROOMFLAG_EX_WEATHERPROOF;
}
}
} else {
// weather is present in all rooms except skiprooms
for (s32 i = 0; i < WEATHERCFG_MAX_SKIPROOMS && g_CurWeatherConfig->skiprooms[i]; ++i) {
const RoomNum room = g_CurWeatherConfig->skiprooms[i];
if (room >= 0 && room < g_Vars.roomcount) {
g_Rooms[room].extra_flags |= ROOMFLAG_EX_WEATHERPROOF;
}
}
}
}
#endif
void weatherReset(void)
{
g_WeatherActive = false;
g_WeatherData = NULL;
#ifndef PLATFORM_N64
// find the weather config for this stage, if any
g_CurWeatherConfig = &g_DefaultWeatherConfig;
for (s32 i = 0; i < ARRAYCOUNT(g_WeatherConfig) && g_WeatherConfig[i].stagenum; ++i) {
if (g_WeatherConfig[i].stagenum == g_Stages[g_StageIndex].id) {
g_CurWeatherConfig = &g_WeatherConfig[i];
break;
}
}
if (g_CurWeatherConfig != &g_DefaultWeatherConfig)
#else
if ((g_StageIndex == STAGEINDEX_CHICAGO
|| g_StageIndex == STAGEINDEX_AIRBASE
|| g_StageIndex == STAGEINDEX_G5BUILDING
|| g_StageIndex == STAGEINDEX_CRASHSITE)
&& PLAYERCOUNT() < 2) {
&& PLAYERCOUNT() < 2)
#endif
{
g_WeatherData = mempAlloc(sizeof(struct weatherdata), MEMPOOL_STAGE);
g_WeatherData->particledata[0] = weatherAllocateParticles();
g_WeatherData->type = -1;
@@ -28,6 +71,7 @@ void weatherReset(void)
g_WeatherData->unk0c = 0;
g_WeatherData->unk10 = 1;
#ifdef PLATFORM_N64
if (g_StageIndex == STAGEINDEX_CHICAGO || g_StageIndex == STAGEINDEX_G5BUILDING) {
g_WeatherData->windspeed = 20;
} else if (g_StageIndex == STAGEINDEX_CRASHSITE) {
@@ -35,6 +79,11 @@ void weatherReset(void)
} else {
g_WeatherData->windspeed = 5;
}
#else
g_WeatherData->windspeed = g_CurWeatherConfig->windspeed;
// set up the weatherproof flags in all rooms
weatherResetRooms();
#endif
g_WeatherData->audiohandles[0] = 0;
g_WeatherData->audiohandles[1] = 0;
+10
View File
@@ -3594,6 +3594,9 @@
#define ROOMFLAG_PLAYAMBIENTTRACK 0x4000
#define ROOMFLAG_OUTDOORS 0x8000
// flags for the extra_flags field
#define ROOMFLAG_EX_WEATHERPROOF 0x0001
#define RUMBLESTATE_1 1
#define RUMBLESTATE_ENABLED_STOPPED 2
#define RUMBLESTATE_ENABLED_STARTING 3
@@ -4490,6 +4493,13 @@ enum weaponnum {
#define WEATHERTYPE_RAIN 0
#define WEATHERTYPE_SNOW 1
#define WEATHERCFG_MAX_SKIPROOMS 128
#define WEATHERCFG_MAX_STAGES 16
#define WEATHERFLAG_INCLUDE 0x0001 // rooms listed in skiprooms are the only ones that have weather
#define WEATHERFLAG_CUTSCENE_ONLY 0x0002 // weather only in cutscenes
#define WEATHERFLAG_FORCE_WINDDIR 0x0004 // force constant wind direction
// Reasons for playing X music
#define XREASON_0 0
#define XREASON_DEFAULT 1
+4
View File
@@ -531,6 +531,10 @@ extern struct menudialogdef g_HangarListMenuDialog;
#ifndef PLATFORM_N64
extern struct weathercfg g_WeatherConfig[WEATHERCFG_MAX_STAGES];
extern const struct weathercfg g_DefaultWeatherConfig;
extern const struct weathercfg *g_CurWeatherConfig;
extern f32 g_PlayerCrosshairSway;
extern f32 g_PlayerDefaultFovY;
extern s32 g_PlayerMouseAimMode;
+21
View File
@@ -3670,6 +3670,10 @@ struct room {
/*0x80*/ s32 gfxdatalen; // when inflated
/*0x84*/ struct wallhit *opawallhits; // opaque
/*0x88*/ struct wallhit *xluwallhits; // translucent
#ifndef PLATFORM_N64
/*0x8c*/ u16 extra_flags;
#endif
};
struct fireslotthing {
@@ -4892,6 +4896,23 @@ struct weatherparticledata {
/*0x3efc*/ u32 unk3efc;
};
#ifndef PLATFORM_N64
struct weathercfg {
s32 stagenum;
u32 flags;
f32 windspeed;
f32 ymin;
f32 ymax;
f32 zmax;
RoomNum skiprooms[WEATHERCFG_MAX_SKIPROOMS]; // if flags has WEATHERFLAG_INCLUDE, rooms that have weather, else rooms that don't
f32 windanglerad; // wind fields only used if flags has WEATHERFLAG_FORCE_WINDDIR
f32 windspeedx;
f32 windspeedz;
};
#endif
struct texture {
u32 soundsurfacetype : 4;
u32 surfacetype : 4;