552 lines · 12.5 KB · C
RawDownload
#include "terminals.h" #include <stdlib.h>#include "util.h"#include "datatypes.h"#include "mazes.h"#include "parse.h"#include "audio.h"#include "gui.h" /*Copyright (c) 2013-2021 Devine Lu Linvega2018 web port by rezmason2021 C89 port by rezmason Permission to use, copy, modify, and distribute this software for anypurpose with or without fee is hereby granted, provided that the abovecopyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIESWITH REGARD TO THIS SOFTWARE.*/ static Terminal (*terminals)[] = NULL;static int numTerminals;static int _isOpen = 0; static voidsetupAudio(TerminalData *data, int *isOpen, GameState *state){	NodeModifier modifier = state->audio ? MODIFIER_ON : MODIFIER_NONE;	double fadeDelay = state->audio ? 0.1 : 0;	(void)data;	(void)isOpen;	GUI_ShowNode(state->nodeName, state->orientation, modifier, 0.3, fadeDelay);	GUI_ShowAudio(state->audio);} static intchangeAudio(TerminalData *data, int *isOpen, GameState *state){	(void)isOpen;	state->audio = !state->audio;	Audio_SetActive(state->audio);	setupAudio(data, isOpen, state);	return 1;} static voidsetupProgress(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	GUI_ShowProgressScreen(state->chapter);} static voidupdateClock(GameState *state, int refresh){	GUI_ShowClockFace(state->clock, refresh);	GUI_ShowClock(state->clock);} static voidsetupClock(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	updateClock(state, 0);	Audio_PlayEffect(EFFECT_ACTION_ENERGY_INIT);} static intchangeClock(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	state->clock = (state->clock + 1) % 3;	updateClock(state, 1);	Audio_PlayEffect(EFFECT_ACTION_ENERGY_ACTIVE);	return 1;} static voidupdateSeal(TerminalData *data, GameState *state){	int i, numSeals = 0, hasSeal = 0;	double fadeDuration = 0.2, fadeDelay = 0.2;	NodeModifier modifier = MODIFIER_NONE;	GUI_ShowSeals(state->seals[0], state->seals[1]); 	/*		Look to see how many seals the player has,		and if they have this one, what index it's at	*/	for(i = 0; i < 2; i++) {		if(state->seals[i] == data->seal) {			hasSeal = 1;		}		if(state->seals[i] != ZONE_NONE) {			numSeals++;		}	} 	if(hasSeal) {		modifier = numSeals == 2 ? MODIFIER_SEAL_2 : MODIFIER_SEAL_1;		fadeDuration = 0.1;		fadeDelay = 0.1;	} 	GUI_ShowNode(state->nodeName, state->orientation, modifier, fadeDuration, fadeDelay);} static voidsetupSeal(TerminalData *data, int *isOpen, GameState *state){	(void)isOpen;	updateSeal(data, state);	Audio_PlayEffect(EFFECT_ACTION_SEAL_INIT);} static intchangeSeal(TerminalData *data, int *isOpen, GameState *state){	int i, filledIndex = -1, emptyIndex = -1;	(void)isOpen; 	/*		Look to see what, if any, empty seal slot the player has,		and if they have this seal, what index it's at	*/	for(i = 0; i < 2; i++) {		if(emptyIndex == -1 && state->seals[i] == ZONE_NONE) {			emptyIndex = i;		}		if(filledIndex == -1 && state->seals[i] == data->seal) {			filledIndex = i;			break;		}	} 	if(filledIndex != -1) {		Audio_PlayEffect(EFFECT_ACTION_SEAL_INACTIVE);		state->seals[filledIndex] = ZONE_NONE;	} else if(emptyIndex != -1) {		Audio_PlayEffect(EFFECT_ACTION_SEAL_ACTIVE);		state->seals[emptyIndex] = data->seal;	} else {		Audio_PlayEffect(EFFECT_ACTION_ENERGY_STACK);		GUI_ShowSealAlert();	} 	updateSeal(data, state);	return 1;} static voidupdateEnergy(TerminalData *data, int *isOpen, GameState *state){	NodeModifier modifier = MODIFIER_NONE;	int holdsFuse = 0;	GUI_ShowEnergy(state->energy); 	if(*isOpen) {		/*			Find out whether this terminal is filled,			aka whether this terminal is listed			in the state's list of terminal locations		*/		int i, filled = 0;		for(i = 0; i < 3; i++) {			if(strcmp(state->fuseLocationNames[i], data->energyTerminalData.fuseName) == 0) {				filled = 1;				break;			}		}		modifier = filled ? MODIFIER_ENERGY_FILLED : MODIFIER_ENERGY_EMPTY;		holdsFuse = !filled && state->energy > 0;	}	GUI_ShowNode(state->nodeName, state->orientation, modifier, 0.1, 0);	GUI_EnableFuseCursor(holdsFuse);} static voidsetupEnergy(TerminalData *data, int *isOpen, GameState *state){	*isOpen = 0;	updateEnergy(data, isOpen, state);	Audio_PlayEffect(EFFECT_ACTION_ENERGY_INIT);} static intchangeEnergy(TerminalData *data, int *isOpen, GameState *state){	int success = 1;	if(!*isOpen) {		*isOpen = 1;	} else {		int i, filledIndex = -1, emptyIndex = -1; 		/*			Look to see what, if any, empty fuse location slot the player has,			and if they have this fuse, what index it's at		*/		for(i = 0; i < 3; i++) {			if(filledIndex == -1 && strcmp(state->fuseLocationNames[i], data->energyTerminalData.fuseName) == 0) {				filledIndex = i;			} else if(emptyIndex == -1 && strcmp(state->fuseLocationNames[i], "") == 0) {				emptyIndex = i;			}		} 		if(filledIndex != -1) {			strcpy(state->fuseLocationNames[filledIndex], "");			state->energy++;		} else if(state->energy > 0 && emptyIndex != -1) {			strcpy(state->fuseLocationNames[emptyIndex], data->energyTerminalData.fuseName);			state->energy--;		} else {			GUI_ShowEnergy(state->energy);			GUI_ShowEnergyAlert();			success = 0;		}	}	if(success) {		updateEnergy(data, isOpen, state);	}	return success;} static voidresetEnergy(TerminalData *data, GameState *state){	int i;	if(!data->energyTerminalData.isFilledAtStart) {		return;	} 	/*		Fill the first empty fuse location slot in the state		with the name of this terminal	*/	for(i = 0; i < 3; i++) {		if(strcmp(state->fuseLocationNames[i], "") == 0) {			strcpy(state->fuseLocationNames[i], data->energyTerminalData.fuseName);			break;		}	}} static voidfindStudioSeals(TerminalData *data, GameState *state, int *hasSeal1, int *hasSeal2){	/*		Look to see whether the player state		lists both seals	*/	int i;	for(i = 0; i < 2; i++) {		if(state->seals[i] == data->sealLock[0]) {			*hasSeal1 = 1;		}		if(state->seals[i] == data->sealLock[1]) {			*hasSeal2 = 1;		}	}} static voidupdateStudio(TerminalData *data, GameState *state){	NodeModifier modifier = MODIFIER_NONE;	if(state->studio) {		modifier = MODIFIER_STUDIO_UNLOCKED;	} else {		int hasSeal1 = 0, hasSeal2 = 0;		findStudioSeals(data, state, &hasSeal1, &hasSeal2);		if(hasSeal1 && hasSeal2) {			modifier = MODIFIER_STUDIO_SEAL_BOTH;		} else if(hasSeal1) {			modifier = MODIFIER_STUDIO_SEAL_1;		} else if(hasSeal2) {			modifier = MODIFIER_STUDIO_SEAL_2;		}	}	GUI_ShowNode(state->nodeName, state->orientation, modifier, 0.1, 0.1);} static voidsetupStudio(TerminalData *data, int *isOpen, GameState *state){	(void)isOpen;	updateStudio(data, state);	Audio_PlayEffect(EFFECT_ACTION_DOOR_INIT);} static intchangeStudio(TerminalData *data, int *isOpen, GameState *state){	int hasSeal1 = 0, hasSeal2 = 0;	(void)isOpen;	if(state->studio) {		return 0;	} 	findStudioSeals(data, state, &hasSeal1, &hasSeal2); 	if(hasSeal1 && hasSeal2) {		state->studio = 1;		updateStudio(data, state);		Audio_PlayEffect(EFFECT_ACTION_ENERGY_ACTIVE);		return 1;	}	return 0;} static voidsetupEntente(TerminalData *data, int *isOpen, GameState *state){	(void)isOpen;	GUI_ShowMazeInstruction(data->axis, Mazes_GetInstruction(data->axis, state));} static voidsetupEntenteProgress(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	(void)state;	GUI_ShowEntenteScreen();} static intchangeEndgame(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	state->completed = 1;	return 1;} static voidsetupSecret(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	if(state->secret) {		GUI_ShowNode(state->nodeName, state->orientation, MODIFIER_ON, 0.3, 0.1);	} else {		GUI_ShowNode(state->nodeName, state->orientation, MODIFIER_NONE, 0, 0);	}} static intchangeSecret(TerminalData *data, int *isOpen, GameState *state){	state->secret = !state->secret;	setupSecret(data, isOpen, state);	return 1;} static voidnothing(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	(void)state;} static intchangeNothing(TerminalData *data, int *isOpen, GameState *state){	(void)data;	(void)isOpen;	(void)state;	return 1;} static voidresetNothing(TerminalData *data, GameState *state){	(void)data;	(void)state;} static voidparseTerminal(Terminal *terminal, char *line, int lineNumber){	int missing = 0;	char name[40] = "", type[30] = "";	char params[200];	int numFound; 	strcpy(name, "");	strcpy(type, "");	strcpy(params, ""); 	/*		example: type("name", params);	*/ 	numFound = sscanf(line, "%[^(](\"%[^\"]\", %[^)]);", type, name, params);	if(numFound < 3) {		printf("Terminal data error: only %d terms matched on line %d: %s\n", numFound, lineNumber, line);		sprintf(name, "BROKEN_%d", lineNumber);	} 	strcpy(terminal->name, name);	terminal->setup = nothing;	terminal->change = changeNothing;	terminal->reset = resetNothing; 	if(strcmp(type, "audioTerminal") == 0) {		terminal->setup = setupAudio;		terminal->change = changeAudio;	} else if(strcmp(type, "progressTerminal") == 0) {		terminal->setup = setupProgress;	} else if(strcmp(type, "clockTerminal") == 0) {		terminal->setup = setupClock;		terminal->change = changeClock;	} else if(strcmp(type, "sealTerminal") == 0) {		/*			example: ANTECHANNEL		*/		char sealName[20];		strcpy(sealName, "");		missing = 1 - sscanf(params, "%[A-Z]", sealName);		parseZone(&terminal->data.seal, sealName);		terminal->setup = setupSeal;		terminal->change = changeSeal;	} else if(strcmp(type, "energyTerminal") == 0) {		/*			example: 1		*/		missing = 1 - sscanf(params, "%d", &terminal->data.energyTerminalData.isFilledAtStart);		strcpy(terminal->data.energyTerminalData.fuseName, name);		terminal->setup = setupEnergy;		terminal->change = changeEnergy;		terminal->reset = resetEnergy;	} else if(strcmp(type, "studioTerminal") == 0) {		/*			example: {FOREST, RAINRE}		*/		char sealNames[2][20];		strcpy(sealNames[0], "NONE");		strcpy(sealNames[1], "NONE");		missing = 2 - sscanf(params, "{%[^,], %[^}]", sealNames[0], sealNames[1]);		parseZone(&terminal->data.sealLock[0], sealNames[0]);		parseZone(&terminal->data.sealLock[1], sealNames[1]);		terminal->setup = setupStudio;		terminal->change = changeStudio;	} else if(strcmp(type, "ententeTerminal") == 0) {		/*			example: X		*/		char axisName[5];		strcpy(axisName, "");		missing = 1 - sscanf(params, "%s", axisName);		parseMazeAxis(&terminal->data.axis, axisName);		terminal->setup = setupEntente;	} else if(strcmp(type, "ententeProgressTerminal") == 0) {		terminal->setup = setupEntenteProgress;	} else if(strcmp(type, "secretTerminal") == 0) {		terminal->setup = setupSecret;		terminal->change = changeSecret;	} else if(strcmp(type, "endgame") == 0) {		terminal->change = changeEndgame;	} else {		printf("Terminal data error: unknown terminal type on line %d: %s\n", lineNumber, type);	} 	if(missing > 0) {		printf("Terminal data error: missing %d params on line %d: %s\n", missing, lineNumber, line);	}} intTerminals_Init(char *data){	const char *lineDelim = "\n";	char *lineSave = NULL;	int i = 0, lineNumber = 1;	char *line; 	if(terminals != NULL) {		printf("Terminal data error: the terminals were already initialized.\n");		return 0;	} 	numTerminals = getNumLines(data);	terminals = calloc(numTerminals, sizeof(Terminal)); 	line = getNextToken(data, lineDelim, &lineSave);	while(line != NULL) {		parseTerminal(&(*terminals)[i], line, lineNumber);		line = getNextToken(NULL, lineDelim, &lineSave);		lineNumber++;		i++;	} 

Lines 1–500 of 552.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t