Exemple #1
0
static int
flash_ship_task (void *data)
{
	DWORD TimeIn;
	COLOR c;
	Task task = (Task) data;

	c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
	TimeIn = GetTimeCounter ();
	while (!Task_ReadState (task, TASK_EXIT))
	{
		STAMP s;
		SHIP_FRAGMENTPTR StarShipPtr;
		COLOR OldColor;
		CONTEXT OldContext;

		LockMutex (GraphicsLock);
		s.origin = pMenuState->first_item;
		StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
				&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame);
		s.frame = StarShipPtr->ShipInfo.icons;
		UnlockStarShip (&GLOBAL (built_ship_q),
				(HSTARSHIP)pMenuState->CurFrame);
		OldContext = SetContext (StatusContext);
		if (c >= BUILD_COLOR (MAKE_RGB15 (0x1F, 0x19, 0x19), 0x24))
			c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
		else
			c += BUILD_COLOR (MAKE_RGB15 (0x00, 0x02, 0x02), 0x00);
		OldColor = SetContextForeGroundColor (c);
		DrawFilledStamp (&s);
		SetContextForeGroundColor (OldColor);
		SetContext (OldContext);
		UnlockMutex (GraphicsLock);
		SleepThreadUntil (TimeIn + ONE_SECOND / 15);
		TimeIn = GetTimeCounter ();
	}
	FinishTask (task);
	return 0;
}
Exemple #2
0
// Pre: caller holds the graphics lock.
void
MeleeGameOver (void)
{
	COUNT playerI;
	DWORD TimeOut;
	BOOLEAN PressState, ButtonState;

	// Show the battle result.
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
		DrawPickMeleeFrame (playerI);
	

#ifdef NETPLAY
	negotiateReadyConnections(true, NetState_inSetup);
#endif

	TimeOut = GetTimeCounter () + (ONE_SECOND * 4);

	PressState = PulsedInputState.menu[KEY_MENU_SELECT] ||
			PulsedInputState.menu[KEY_MENU_CANCEL];
	do
	{
		UpdateInputState ();
		ButtonState = PulsedInputState.menu[KEY_MENU_SELECT] ||
				PulsedInputState.menu[KEY_MENU_CANCEL];
		if (PressState)
		{
			PressState = ButtonState;
			ButtonState = FALSE;
		}

		Async_process ();
		TaskSwitch ();
	} while (!(GLOBAL (CurrentActivity) & CHECK_ABORT) && (!ButtonState
			&& (!(PlayerControl[0] & PlayerControl[1] & PSYTRON_CONTROL)
			|| GetTimeCounter () < TimeOut)));

}
Exemple #3
0
static void
BackgroundInitKernel (DWORD TimeOut)
{
	LoadMasterShipList (TaskSwitch);
	TaskSwitch ();
	InitGameKernel ();

	while ((GetTimeCounter () <= TimeOut) &&
	       !(GLOBAL (CurrentActivity) & CHECK_ABORT))
	{
		UpdateInputState ();
		TaskSwitch ();
	}
}
// This function figures out the chunk that should be playing based on
// 'offset' into the total playing time of all tracks. It then sets
// the speech source's sample to the necessary decoder and seeks the
// decoder to the proper point.
// XXX: This means that whatever speech has already been queued on the
//   source will continue playing, so we may need some small timing
//   adjustments. It may be simpler to just call PlayStream().
static void
seek_track (sint32 offset)
{
    TFB_SoundChunk *cur;
    TFB_SoundChunk *last_tag = NULL;

    if (!sound_sample)
        return; // nothing to recompute

    if (offset < 0)
        offset = 0;
    else if ((uint32)offset > tracks_length)
        offset = tracks_length + 1;

    // Adjusting the stream start time is the only way we can arbitrarily
    // seek the stream right now
    soundSource[SPEECH_SOURCE].start_time = GetTimeCounter () - offset;

    // Find the chunk that should be playing at this time offset
    for (cur = chunks_head; cur && offset >= chunk_end_time (cur);
            cur = cur->next)
    {
        // .. looking for the last callback as we go along
        // XXX: this effectively set the last point where Fot is looking at.
        // TODO: this should be somehow changed if we implement more
        //   callbacks, like Melnorme trading, offloading at Starbase, etc.
        if (cur->tag_me)
            last_tag = cur;
    }

    if (cur)
    {
        cur_chunk = cur;
        SoundDecoder_Seek (cur->decoder, (uint32) (((float)offset / ONE_SECOND
                           - cur->start_time) * 1000));
        sound_sample->decoder = cur->decoder;

        if (cur->tag_me)
            last_tag = cur;
        if (last_tag)
            DoTrackTag (last_tag);
    }
    else
    {   // The offset is beyond the length of all tracks
        StopStream (SPEECH_SOURCE);
        cur_chunk = NULL;
        cur_sub_chunk = NULL;
    }
}
Exemple #5
0
void
InitCommAnimations (void)
{
	COUNT i;
	
	ActiveMask = 0;

	TalkDesc = CommData.AlienTalkDesc;
	TransitDesc = CommData.AlienTransitionDesc;
	
	// JMS: Shofixti Colony comm screen is blacked out upon the first encounter.
	if (CommData.AlienConv == SHOFIXTICOLONY_CONVERSATION)
	{
		if (GET_GAME_STATE (SHOFIXTI_COLONY_MET) < 2)
			TalkDesc.AnimFlags |= ANIM_DISABLED;
	
		for (i = 0; i < CommData.NumAnimations; ++i)
		{
			ANIMATION_DESC *ADPtr = &CommData.AlienAmbientArray[i];
		
			// JMS: Turn on the anims & disable black screen when the time is right.
			if ((GET_GAME_STATE (SHOFIXTI_COLONY_MET) == 0 && i < CommData.NumAnimations - 1)
				|| (GET_GAME_STATE (SHOFIXTI_COLONY_MET) >= 1 && i == CommData.NumAnimations - 1)
				)
				ADPtr->AnimFlags |= ANIM_DISABLED;
		}
	}

	// Animation sequences have to be drawn in reverse, and
	// talk animations have to be drawn last (so we add them first)
	TotalSequences = 0;
	// Transition animation last
	Transit = Sequences + TotalSequences;
	SetupTalkSequence (Transit, &TransitDesc);
	++TotalSequences;
	// Talk animation second last
	Talk = Sequences + TotalSequences;
	SetupTalkSequence (Talk, &TalkDesc);
	++TotalSequences;
	FirstAmbient = TotalSequences;
	SetupAmbientSequences (Sequences + FirstAmbient, CommData.NumAnimations);
	TotalSequences += CommData.NumAnimations;

	LastTime = GetTimeCounter ();
}
Exemple #6
0
static void
flashSelectedTeam (MELEE_STATE *pMS)
{
#define FLASH_RATE (ONE_SECOND / 9)
	static TimeCount NextTime = 0;
	static int hilite = 0;
	TimeCount Now = GetTimeCounter ();

	if (Now >= NextTime)
	{
		CONTEXT OldContext;

		NextTime = Now + FLASH_RATE;
		hilite ^= 1;

		OldContext = SetContext (SpaceContext);
		SelectFileString (pMS, hilite);
		SetContext (OldContext);
	}
}
Exemple #7
0
void
ResetKeyRepeat (void)
{
	DWORD initTime = GetTimeCounter ();
	int i, j;
	for (i = 0; i < NUM_TEMPLATES; i++)
	{
		for (j = 0; j < NUM_KEYS; j++)
		{
			RepeatDelays.key[i][j] = _max_accel;
			Times.key[i][j] = initTime;
		}
	}
	for (i = 0; i < NUM_MENU_KEYS; i++)
	{
		RepeatDelays.menu[i] = _max_accel;
		Times.menu[i] = initTime;
	}
	GestaltRepeatDelay = _max_accel;
	GestaltTime = initTime;
}
Exemple #8
0
void
PrintThreadsStats_SDL (void)
{
	TrueThread ptr;
	int now;
	
	now = GetTimeCounter ();
	SDL_mutexP (threadQueueMutex);
	fprintf(stderr, "--- Active threads ---\n");
	for (ptr = threadQueue; ptr != NULL; ptr = ptr->next) {
		fprintf (stderr, "Thread named '%s'.\n", ptr->name);
		fprintf (stderr, "Started %d.%d minutes ago.\n",
				(now - ptr->startTime) / 60000,
				((now - ptr->startTime) / 1000) % 60);
		LocalStats (ptr->native);
		if (ptr->next != NULL)
			fprintf(stderr, "\n");
	}
	SDL_mutexV (threadQueueMutex);
	fprintf(stderr, "----------------------\n");
	fflush (stderr);
}
Exemple #9
0
static void
computeFPS (void)
{
	static TimeCount last_time;
	static TimePeriod fps_counter;
	TimeCount current_time;
	TimePeriod delta_time;

	current_time = GetTimeCounter ();
	delta_time = current_time - last_time;
	last_time = current_time;
	
	fps_counter += delta_time;
	if (fps_counter > FPS_PERIOD)
	{
		log_add (log_User, "fps %.2f, effective %.2f",
				(float)ONE_SECOND / delta_time,
				(float)ONE_SECOND * RenderedFrames / fps_counter);

		fps_counter = 0;
		RenderedFrames = 0;
	}
}
Exemple #10
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;
	
	if(optSuperMelee && !optLoadGame && PacksInstalled()){
		pMS->CurState = PLAY_SUPER_MELEE;
		PulsedInputState.menu[KEY_MENU_SELECT] = 65535;
	}
	if(optLoadGame && !optSuperMelee && PacksInstalled()){
		pMS->CurState = LOAD_SAVED_GAME;
		PulsedInputState.menu[KEY_MENU_SELECT] = 65535;
	}

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic && !comingFromInit)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		
		pMS->hMusic = loadMainMenuMusic (Rando);
		InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND;

		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 14, 0,
				(6 * ONE_SECOND) / 14, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);

		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		Flash_start (pMS->flashContext);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
		if (!comingFromInit){
			FadeMusic(0,0);
			PlayMusic (pMS->hMusic, TRUE, 1);
		
			if (optMainMenuMusic)
				FadeMusic (NORMAL_VOLUME+70, ONE_SECOND * 3);
		}
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		//BYTE fade_buf[1];
		COUNT oldresfactor;

		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				if (!RestartMessage(pMS, TimeIn)) {
					LastActivity = CHECK_LOAD;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
					optLoadGame = FALSE;
				} else
					return TRUE;
				break;
			case START_NEW_GAME:
				if (!RestartMessage(pMS, TimeIn)) {
					LastActivity = CHECK_LOAD | CHECK_RESTART;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				} else
					return TRUE;
				break;
			case PLAY_SUPER_MELEE:
				if (!RestartMessage(pMS, TimeIn)) {
					GLOBAL (CurrentActivity) = SUPER_MELEE;
					optSuperMelee = FALSE;
				} else
					return TRUE;
				break;
			case SETUP_GAME:
				oldresfactor = resolutionFactor;
				
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);

				InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND;

				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				// JMS_GFX: This prevents drawing an annoying wrong-sized "Setup" frame when changing resolution. 
				if (oldresfactor < resolutionFactor)
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, TRUE);
				
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame, FALSE);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		// JMS: After changing resolution mode, prevent displaying credits
		// (until the next time the game is restarted). This is to prevent
		// showing the credits with the wrong resolution mode's font&background.
		if (GetTimeCounter () - LastInputTime > InactTimeOut
			&& !optRequiresRestart && PacksInstalled())
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND/2));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}
	comingFromInit = FALSE;
	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Exemple #11
0
BOOLEAN
ProcessCommAnimations (BOOLEAN FullRedraw, BOOLEAN paused)
{
	if (paused)
	{	// Drive colormap xforms and nothing else
		XFormColorMap_step ();
		return FALSE;
	}
	else
	{
		COUNT i;
		SEQUENCE *pSeq;
		BOOLEAN Change;
		BOOLEAN CanTalk = TRUE;
		TimeCount CurTime;
		DWORD ElapsedTicks;
		DWORD NextActiveMask;

		CurTime = GetTimeCounter ();
		ElapsedTicks = CurTime - LastTime;
		LastTime = CurTime;

		// Process ambient animations
		NextActiveMask = ActiveMask;
		pSeq = Sequences + FirstAmbient;
		for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq)
		{
			ANIMATION_DESC *ADPtr = pSeq->ADPtr;
			DWORD ActiveBit = 1L << i;

			if (ADPtr->AnimFlags & ANIM_DISABLED)
				continue;
			
			if (pSeq->Direction == NO_DIR)
			{	// animation is paused
				if (!conflictsWithTalkingAnim (pSeq))
				{	// start it up
					pSeq->Direction = UP_DIR;
				}
			}
			else if (pSeq->Alarm > ElapsedTicks)
			{	// not time yet
				pSeq->Alarm -= ElapsedTicks;
			}
			else if (ActiveMask & ADPtr->BlockMask)
			{	// animation is blocked
				assert (!(ActiveMask & ActiveBit) &&
						"Check animations' mutual blocking masks");
				assert (animAtNeutralIndex (pSeq));
				// reschedule
				pSeq->Alarm = randomRestartRate (pSeq) + 1;
				continue;
			}
			else
			{	// Time to start or advance the animation
				if (AdvanceAmbientSequence (pSeq))
				{	// Animation is active this frame and the next
					ActiveMask |= ActiveBit;
					NextActiveMask |= ActiveBit;
				}
				else
				{	// Animation remains active this frame but not the next
					// This keeps any conflicting animations (BlockMask)
					// from activating in the same frame and scribbling over
					// our last image.
					NextActiveMask &= ~ActiveBit;
				}
			}

			if (pSeq->AnimType == PICTURE_ANIM && pSeq->Direction != NO_DIR
					&& conflictsWithTalkingAnim (pSeq))
			{
				// We want to talk, but this is a running picture animation
				// which conflicts with the talking animation
				// See if it is safe to stop it now.
				if (animAtNeutralIndex (pSeq))
				{	// pause the animation
					pSeq->Direction = NO_DIR;
					NextActiveMask &= ~ActiveBit;
					// Talk animation is drawn last, so it's not a conflict
					// for this frame. The talk animation will be drawn
					// over the neutral frame.
				}
				else
				{	// Otherwise, let the animation run until it's safe
					CanTalk = FALSE;
				}
			}			
			
			// BW: to be checked. I've tried to remove what's supposed to be removed while keeping the Syreen zoom-in feature.
			// It may have to be re-programmed in the new commanim style.
			if (pSeq->AnimType == PICTURE_ANIM
				&& (ADPtr->AnimFlags & CommData.AlienTalkDesc.AnimFlags & WAIT_TALKING)
				&& pSeq->Direction != NO_DIR)
			{
				// JMS: Cut marked animations short when starting talk.
				// The animations are marked with FAST_STOP_AT_TALK_START in the races' comm source codes.
				if (ADPtr->AnimFlags & FAST_STOP_AT_TALK_START)
				{	CanTalk = TRUE;
					//pSeq->AnimObj.CurFrame = SetAbsFrameIndex(pSeq->AnimObj.CurFrame, ADPtr->StartIndex);
					pSeq->Direction = NO_DIR;
				}
			}
			
			// JMS: This handles ambient animations which should occur only during talk
			// A lot of conditions are necessary to eliminate unwanted animations
			// from the duration of talk transition!
			if (pSeq->AnimType == PICTURE_ANIM
				&& ADPtr->AnimFlags & WHEN_TALKING 
				&& (!(CommData.AlienTalkDesc.AnimFlags & WAIT_TALKING) 
					|| (CommData.AlienTalkDesc.AnimFlags & TALK_INTRO)
					|| (CommData.AlienTalkDesc.AnimFlags & TALK_DONE))
				&& !(CommData.AlienTransitionDesc.AnimFlags & PAUSE_TALKING)
				&& pSeq->Direction != NO_DIR)
			{
				// Stop the anim if not talking
				pSeq->Direction = NO_DIR;
			}
		}
		// All ambient animations have been processed. Advance the mask.
		ActiveMask = NextActiveMask;

		// Process the talking and transition animations
		if (CanTalk	&& haveTalkingAnim () && runningTalkingAnim ())
		{
			BOOLEAN done = FALSE;

			if (signaledStopTalkingAnim () && haveTransitionAnim ())
			{	// Run the transition. We will clear everything
				// when it is done
				CommData.AlienTransitionDesc.AnimFlags |= TALK_DONE;
			}

			if (CommData.AlienTransitionDesc.AnimFlags
					& (TALK_INTRO | TALK_DONE))
			{	// Transitioning in or out of talking
				if ((CommData.AlienTransitionDesc.AnimFlags & TALK_DONE)
						&& Transit->Direction == NO_DIR)
				{	// This is needed when switching talking anims
					ResetSequence (Talk);
				}
				done = AdvanceTransitSequence (Transit, ElapsedTicks);
			}
			else if (!signaledStopTalkingAnim ())
			{	// Talking, transition is done
				AdvanceTalkingSequence (Talk, ElapsedTicks);
			}
			else
			{	// Not talking
				ResetSequence (Talk);
				done = TRUE;
			}

			if (signaledStopTalkingAnim () && done)
			{
				clearRunTalkingAnim ();
				clearStopTalkingAnim ();
			}
		}
		else
		{	// Not talking -- disable talking anim if it is done
			if (Talk->Direction == NO_DIR)
				TalkDesc.AnimFlags |= ANIM_DISABLED;
		}

		BatchGraphics ();

		// Draw all animations
		{
			BOOLEAN ColorChange = XFormColorMap_step ();

			if (ColorChange)
				FullRedraw = TRUE;

			// Colormap animations are processed separately
			// from picture anims (see XFormColorMap_step)
			ProcessColormapAnims (Sequences + FirstAmbient,
					CommData.NumAnimations);

			Change = DrawAlienFrame (Sequences, TotalSequences, FullRedraw);
			if (FullRedraw)
				Change = TRUE;
		}
		
		UnbatchGraphics ();

		// Post-process ambient animations
		pSeq = Sequences + FirstAmbient;
		for (i = 0; i < CommData.NumAnimations; ++i, ++pSeq)
		{
			ANIMATION_DESC *ADPtr = pSeq->ADPtr;
			DWORD ActiveBit = 1L << i;

			if (ADPtr->AnimFlags & ANIM_DISABLED)
				continue;

			// We can only disable a one-shot anim here, otherwise the
			// last frame will not be drawn
			if ((ADPtr->AnimFlags & ONE_SHOT_ANIM)
					&& !(NextActiveMask & ActiveBit))
			{	// One-shot animation, inactive next frame
				ADPtr->AnimFlags |= ANIM_DISABLED;
			}
		}

		return Change;
	}
}
Exemple #12
0
static DWORD
XFormPLUT (COLORMAPPTR ColorMapPtr, SIZE TimeInterval)
{
	TFB_ColorMap *map;
	XFORM_CONTROL *control;
	int index;
	int x;
	int first_avail = -1;
	DWORD EndTime;
	DWORD Now;

	Now = GetTimeCounter ();
	index = *(UBYTE*)ColorMapPtr;

	LockMutex (XFormControl.Lock);
	// Find an available slot, or reuse if required
	for (x = 0; x <= XFormControl.Highest
			&& index != XFormControl.TaskControl[x].CMapIndex;
			++x)
	{
		if (first_avail == -1 && XFormControl.TaskControl[x].CMapIndex == -1)
			first_avail = x;
	}

	if (index == XFormControl.TaskControl[x].CMapIndex)
	{	// already xforming this colormap -- cancel and reuse slot
		finish_colormap_xform (x);
	}
	else if (first_avail >= 0)
	{	// picked up a slot along the way
		x = first_avail;
	}
	else if (x >= MAX_XFORMS)
	{	// flush some xforms if the queue is full
		log_add (log_Debug, "WARNING: XFormPLUT(): no slots available");
		x = XFormControl.Highest;
		finish_colormap_xform (x);
	}
	// take next unused one
	control = &XFormControl.TaskControl[x];
	if (x > XFormControl.Highest)
		XFormControl.Highest = x;

	// make a copy of the current map
	LockMutex (maplock);
	map = colormaps[index];
	if (!map)
	{
		UnlockMutex (maplock);
		UnlockMutex (XFormControl.Lock);
		log_add (log_Warning, "BUG: XFormPLUT(): no current map");
		return (0);
	}
	GetColorMapColors (control->OldCMap, map);
	UnlockMutex (maplock);

	control->CMapIndex = index;
	control->CMapPtr = ColorMapPtr;
	control->Ticks = TimeInterval;
	if (control->Ticks < 0)
		control->Ticks = 0; /* prevent negative fade */
	control->StartTime = Now;
	control->EndTime = EndTime = Now + control->Ticks;

	UnlockMutex (XFormControl.Lock);

	return (EndTime);
}
Exemple #13
0
/* This gives the XFormColorMap task a timeslice to do its thing
 * Only one thread should ever be allowed to be calling this at any time
 */
BOOLEAN
XFormColorMap_step (void)
{
	BOOLEAN Changed = FALSE;
	int x;
	DWORD Now = GetTimeCounter ();

	LockMutex (XFormControl.Lock);

	for (x = 0; x <= XFormControl.Highest; ++x)
	{
		XFORM_CONTROL *control = &XFormControl.TaskControl[x];
		int index = control->CMapIndex;
		int TicksLeft = control->EndTime - Now;
		TFB_ColorMap *curmap;

		if (index < 0)
			continue; // unused slot

		LockMutex (maplock);

		curmap = colormaps[index];
		if (!curmap)
		{
			UnlockMutex (maplock);
			log_add (log_Error, "BUG: XFormColorMap_step(): no current map");
			finish_colormap_xform (x);
			continue;
		}

		if (TicksLeft > 0)
		{
#define XFORM_SCALE 0x10000
			TFB_ColorMap *newmap = NULL;
			UBYTE *newClr;
			Color *oldClr;
			int frac;
			int i;

			newmap = clone_colormap (curmap, index);

			oldClr = control->OldCMap;
			newClr = (UBYTE*)control->CMapPtr + 2;

			frac = (int)(control->Ticks - TicksLeft) * XFORM_SCALE
					/ control->Ticks;

			for (i = 0; i < NUMBER_OF_PLUTVALS; ++i, ++oldClr,
					newClr += PLUTVAL_BYTE_SIZE)
			{
				Color color;

				color.a = 0xff;
				color.r = blendChan (oldClr->r, newClr[PLUTVAL_RED],
						frac, XFORM_SCALE);
				color.g = blendChan (oldClr->g, newClr[PLUTVAL_GREEN],
						frac, XFORM_SCALE);
				color.b = blendChan (oldClr->b, newClr[PLUTVAL_BLUE],
						frac, XFORM_SCALE);
				SetNativePaletteColor (newmap->palette, i, color);
			}

			colormaps[index] = newmap;
			release_colormap (curmap);
		}

		UnlockMutex (maplock);

		if (TicksLeft <= 0)
		{	// asked for immediate xform or already done
			finish_colormap_xform (x);
		}
		
		Changed = TRUE;
	}

	UnlockMutex (XFormControl.Lock);

	return Changed;
}
Exemple #14
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		pMS->hMusic = LoadMusic (MAINMENU_MUSIC);
		InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND;
		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 16, 0,
				(6 * ONE_SECOND) / 16, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		Flash_start (pMS->flashContext);
		PlayMusic (pMS->hMusic, TRUE, 1);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		//BYTE fade_buf[1];
		COUNT oldresfactor;
		BOOLEAN packsInstalled;
		
		if (resolutionFactor == 0)
			packsInstalled = TRUE;
		else if (resolutionFactor == 1 && hires2xPackPresent)
			packsInstalled = TRUE;
		else if (resolutionFactor == 2 && hires4xPackPresent)
			packsInstalled = TRUE;
		else
			packsInstalled = FALSE;
		
		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					LastActivity = CHECK_LOAD;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				}
				break;
			case START_NEW_GAME:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					LastActivity = CHECK_LOAD | CHECK_RESTART;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				}				
				break;
			case PLAY_SUPER_MELEE:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					GLOBAL (CurrentActivity) = SUPER_MELEE;
				}
				break;
			case SETUP_GAME:
				oldresfactor = resolutionFactor;
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);
				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				
				// JMS_GFX: This prevents drawing an annoying wrong-sized "Setup" frame when changing resolution. 
				if (oldresfactor < resolutionFactor)
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, TRUE);
				
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame, FALSE);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		if (GetTimeCounter () - LastInputTime > InactTimeOut)
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}

	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Exemple #15
0
static BOOLEAN
DoRestart (PMENU_STATE pMS)
{
	static DWORD InTime;
	static DWORD InactTimeOut;

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (!pMS->Initialized)
	{
		if (pMS->hMusic)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		pMS->hMusic = LoadMusic (MAINMENU_MUSIC);
		InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND;
		
		PlayMusic (pMS->hMusic, TRUE, 1);
		DrawRestartMenu ((BYTE)~0, pMS->CurState, pMS->CurFrame);
		pMS->Initialized = TRUE;

		{
			BYTE clut_buf[] = {FadeAllToColor};
			DWORD TimeOut = XFormColorMap ((COLORMAPPTR)clut_buf, ONE_SECOND / 2);
			while ((GetTimeCounter () <= TimeOut) &&
			       !(GLOBAL (CurrentActivity) & CHECK_ABORT))
			{
				UpdateInputState ();
				TaskSwitch ();
			}
		}
	}
#ifdef TESTING
else if (InputState & DEVICE_EXIT) return (FALSE);
#endif /* TESTING */
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return (FALSE);
	}
	else if (!(PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_DOWN] ||
			PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT] ||
			PulsedInputState.menu[KEY_MENU_SELECT] || MouseButtonDown))

	{
		if (GetTimeCounter () - InTime < InactTimeOut)
			return (TRUE);

		SleepThreadUntil (FadeMusic (0, ONE_SECOND));
		StopMusic ();
		FadeMusic (NORMAL_VOLUME, 0);

		GLOBAL (CurrentActivity) = (ACTIVITY)~0;
		return (FALSE);
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		BYTE fade_buf[1];

		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				LastActivity = CHECK_LOAD;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case START_NEW_GAME:
				LastActivity = CHECK_LOAD | CHECK_RESTART;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case PLAY_SUPER_MELEE:
				GLOBAL (CurrentActivity) = SUPER_MELEE;
				break;
			case SETUP_GAME:
				LockMutex (GraphicsLock);
				SetFlashRect (NULL_PTR, (FRAME)0);
				UnlockMutex (GraphicsLock);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);
				InTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				DrawRestartMenu ((BYTE)~0, pMS->CurState, pMS->CurFrame);
				ScreenTransition (3, NULL);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				fade_buf[0] = FadeAllToBlack;
				SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));

				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		LockMutex (GraphicsLock);
		SetFlashRect (NULL_PTR, (FRAME)0);
		UnlockMutex (GraphicsLock);

		return (FALSE);
	}
	else
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState-- == START_NEW_GAME)
				NewState = QUIT_GAME;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState++ == QUIT_GAME)
				NewState = START_NEW_GAME;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS->CurState, NewState, pMS->CurFrame);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}
	}

//	if (MouseButtonDown)
//	{
//		LockMutex (GraphicsLock);
//		SetFlashRect (NULL_PTR, (FRAME)0);
//		UnlockMutex (GraphicsLock);
//		MouseError ();
//		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
//		SetTransitionSource (NULL);
//		BatchGraphics ();
//		DrawRestartMenuGraphic (pMS);
//		DrawRestartMenu ((BYTE)~0, pMS->CurState, pMS->CurFrame);
//		ScreenTransition (3, NULL);
//		UnbatchGraphics ();
//	}
	if (MouseButtonDown)
	{
        // TODO WTF FIX GAME CONTROLS
    }
    
	InTime = GetTimeCounter ();
	return (TRUE);
}
Exemple #16
0
BOOLEAN
Battle (BattleFrameCallback *callback)
{
	SIZE num_ships;

	LockMutex (GraphicsLock);

#if !(DEMO_MODE || CREATE_JOURNAL)
	if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE) {
		// In Supermelee, the RNG is already initialised.
		TFB_SeedRandom (GetTimeCounter ());
	}
#else /* DEMO_MODE */
	if (BattleSeed == 0)
		BattleSeed = TFB_Random ();
	TFB_SeedRandom (BattleSeed);
	BattleSeed = TFB_Random (); /* get next battle seed */
#endif /* DEMO_MODE */

	BattleSong (FALSE);
	
	num_ships = InitShips ();

	if (instantVictory)
	{
		num_ships = 0;
		battle_counter[0] = 1;
		battle_counter[1] = 0;
		instantVictory = FALSE;
	}
	
	if (num_ships)
	{
		BATTLE_STATE bs;

		GLOBAL (CurrentActivity) |= IN_BATTLE;
		battle_counter[0] = CountLinks (&race_q[0]);
		battle_counter[1] = CountLinks (&race_q[1]);
		
		if (optMeleeScale != TFB_SCALE_STEP)
			SetGraphicScaleMode (optMeleeScale);

		setupBattleInputOrder ();
#ifdef NETPLAY
		initBattleInputBuffers ();
#ifdef NETPLAY_CHECKSUM
		initChecksumBuffers ();
#endif  /* NETPLAY_CHECKSUM */
		battleFrameCount = 0;
		ResetWinnerStarShip ();
		setBattleStateConnections (&bs);
#endif  /* NETPLAY */

		if (!selectAllShips (num_ships)) {
			GLOBAL (CurrentActivity) |= CHECK_ABORT;

			goto AbortBattle;
		}

		BattleSong (TRUE);
		bs.NextTime = 0;
#ifdef NETPLAY
		initBattleStateDataConnections ();
		{
			bool allOk = negotiateReadyConnections (true, NetState_inBattle);
			if (!allOk) {
				GLOBAL (CurrentActivity) |= CHECK_ABORT;
				goto AbortBattle;
			}
		}
#endif  /* NETPLAY */
		bs.InputFunc = DoBattle;
		bs.frame_cb = callback;
		bs.first_time = (BOOLEAN)(LOBYTE (GLOBAL (CurrentActivity)) ==
				IN_HYPERSPACE);

		UnlockMutex (GraphicsLock);
		DoInput (&bs, FALSE);
		LockMutex (GraphicsLock);

AbortBattle:
		if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE)
		{
			if (GLOBAL (CurrentActivity) & CHECK_ABORT)
			{
				// Do not return to the main menu when a game is aborted,
				// (just to the supermelee menu).
#ifdef NETPLAY
				UnlockMutex (GraphicsLock);
				waitResetConnections(NetState_inSetup);
						// A connection may already be in inSetup (set from
						// GetMeleeStarship). This is not a problem, although
						// it will generate a warning in debug mode.
				LockMutex (GraphicsLock);
#endif

				GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
			}
			else
			{
				// Show the result of the battle.
				MeleeGameOver ();
			}
		}

#ifdef NETPLAY
		uninitBattleInputBuffers();
#ifdef NETPLAY_CHECKSUM
		uninitChecksumBuffers ();
#endif  /* NETPLAY_CHECKSUM */
		setBattleStateConnections (NULL);
#endif  /* NETPLAY */

		StopDitty ();
		StopMusic ();
		StopSound ();
	}

	UninitShips ();
	FreeBattleSong ();

	UnlockMutex (GraphicsLock);
	
	return (BOOLEAN) (num_ships < 0);
}
Exemple #17
0
// Post: the NetState for all players is NetState_interBattle
static BOOLEAN
GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships)
{
	COUNT playerI;
	BOOLEAN ok;
	GETMELEE_STATE gmstate;
	TimeCount now;
	COUNT i;

#ifdef NETPLAY
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		NetConnection *conn;

		if ((playerMask & (1 << playerI)) == 0)
			continue;

		// XXX: This does not have to be done per connection.
		conn = netConnections[playerI];
		if (conn != NULL) {
			BattleStateData *battleStateData;
			battleStateData =
					(BattleStateData *) NetConnection_getStateData (conn);
			battleStateData->getMeleeState = &gmstate;
		}
	}
#endif
	
	ok = true;

	now = GetTimeCounter ();
	gmstate.InputFunc = DoGetMelee;
	gmstate.Initialized = FALSE;
	for (i = 0; i < NUM_PLAYERS; ++i)
	{
		// We have to use TFB_Random() results in specific order
		playerI = GetPlayerOrder (i);
		gmstate.player[playerI].selecting =
				(playerMask & (1 << playerI)) != 0;
		gmstate.player[playerI].ships_left = battle_counter[playerI];

		// We determine in advance which ship would be chosen if the player
		// wants a random ship, to keep it simple to keep network parties
		// synchronised.
		gmstate.player[playerI].randomIndex =
				(COUNT)TFB_Random () % gmstate.player[playerI].ships_left;
		gmstate.player[playerI].done = FALSE;

		if (!gmstate.player[playerI].selecting)
			continue;

		gmstate.player[playerI].timeIn = now;
		gmstate.player[playerI].row = 0;
		gmstate.player[playerI].col = NUM_PICKMELEE_COLUMNS;
#ifdef NETPLAY
		gmstate.player[playerI].remoteSelected = FALSE;
#endif

		gmstate.player[playerI].flashContext =
				Flash_createHighlight (ScreenContext, NULL);
		Flash_setMergeFactors (gmstate.player[playerI].flashContext,
				2, 3, 2);
		Flash_setFrameTime (gmstate.player[playerI].flashContext,
				ONE_SECOND / 16);
#ifdef NETPLAY
		if (PlayerControl[playerI] & NETWORK_CONTROL)
			Flash_setSpeed (gmstate.player[playerI].flashContext,
					ONE_SECOND / 2, 0, ONE_SECOND / 2, 0);
		else
#endif
		{
			Flash_setSpeed (gmstate.player[playerI].flashContext,
					0, ONE_SECOND / 16, 0, ONE_SECOND / 16);
		}
		PickMelee_ChangedSelection (&gmstate, playerI);
		Flash_start (gmstate.player[playerI].flashContext);
	}

#ifdef NETPLAY
	{
		// NB. gmstate.player[].randomIndex and gmstate.player[].done must
		// be initialised before negotiateReadyConnections is completed, to
		// ensure that they are initialised when the SelectShip packet
		// arrives.
		bool allOk = negotiateReadyConnections (true, NetState_selectShip);
		if (!allOk)
		{
			// Some network connection has been reset.
			ok = false;
		}
	}
#endif
	SetDefaultMenuRepeatDelay ();
	
	SetContext (OffScreenContext);


	DoInput (&gmstate, FALSE);
	WaitForSoundEnd (0);


	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		if (!gmstate.player[playerI].selecting)
			continue;
		
		if (gmstate.player[playerI].done)
		{
			// Flash rectangle is already terminated.
			ships[playerI] = gmstate.player[playerI].hBattleShip;
		}
		else
		{
			Flash_terminate (gmstate.player[playerI].flashContext);
			gmstate.player[playerI].flashContext = NULL;
			ok = false;
		}
	}

#ifdef NETPLAY
	if (ok)
	{
		if (!negotiateReadyConnections (true, NetState_interBattle))
			ok = false;
	}
	else
		setStateConnections (NetState_interBattle);
#endif

	if (!ok)
	{
		// Aborting.
		GLOBAL (CurrentActivity) &= ~IN_BATTLE;
	}

#ifdef NETPLAY
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		NetConnection *conn;

		if ((playerMask & (1 << playerI)) == 0)
			continue;

		// XXX: This does not have to be done per connection.
		conn = netConnections[playerI];
		if (conn != NULL && NetConnection_isConnected (conn))
		{
			BattleStateData *battleStateData;
			battleStateData =
					(BattleStateData *) NetConnection_getStateData (conn);
			battleStateData->getMeleeState = NULL;
		}
	}
#endif

	return ok;
}
Exemple #18
0
static BOOLEAN
DoTalkSegue (TALKING_STATE *pTS)
{
	bool left = false;
	bool right = false;
	COUNT curTrack;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		pTS->ended = true;
		return FALSE;
	}
	
	if (PulsedInputState.menu[KEY_MENU_CANCEL])
	{
		JumpTrack ();
		pTS->ended = true;
		return FALSE;
	}

	if (optSmoothScroll == OPT_PC)
	{
		left = PulsedInputState.menu[KEY_MENU_LEFT] != 0;
		right = PulsedInputState.menu[KEY_MENU_RIGHT] != 0;
	}
	else if (optSmoothScroll == OPT_3DO)
	{
		left = CurrentInputState.menu[KEY_MENU_LEFT] != 0;
		right = CurrentInputState.menu[KEY_MENU_RIGHT] != 0;
	}

#if DEMO_MODE || CREATE_JOURNAL
	left = false;
	right = false;
#endif

	if (right)
	{
		SetSliderImage (SetAbsFrameIndex (ActivityFrame, 3));
		if (optSmoothScroll == OPT_PC)
			FastForward_Page ();
		else if (optSmoothScroll == OPT_3DO)
			FastForward_Smooth ();
		pTS->seeking = true;
	}
	else if (left || pTS->rewind)
	{
		pTS->rewind = false;
		SetSliderImage (SetAbsFrameIndex (ActivityFrame, 4));
		if (optSmoothScroll == OPT_PC)
			FastReverse_Page ();
		else if (optSmoothScroll == OPT_3DO)
			FastReverse_Smooth ();
		pTS->seeking = true;
	}
	else if (pTS->seeking)
	{
		// This is only done once the seeking is over (in the smooth
		// scroll case, once the user releases the seek button)
		pTS->seeking = false;
		SetSliderImage (SetAbsFrameIndex (ActivityFrame, 2));
	}
	else
	{
		// This used to have a buggy guard condition, which
		// would cause the animations to remain paused in a couple cases
		// after seeking back to the beginning.
		// Broken cases were: Syreen "several hours later" and Starbase
		// VUX Beast analysis by the scientist.
		CheckSubtitles ();
	}

	// XXX: When seeking, all animations (talking and ambient) stop
	// progressing. This is an original 3DO behavior, and I see no
	// reason why the animations cannot continue while seeking.
	UpdateAnimations (pTS->seeking);
	UpdateSpeechGraphics ();

	curTrack = PlayingTrack ();
	pTS->ended = !pTS->seeking && !curTrack;

	SleepThreadUntil (pTS->NextTime);
	// Need a high enough framerate for 3DO smooth seeking
	pTS->NextTime = GetTimeCounter () + ONE_SECOND / 60;

	return pTS->seeking || (curTrack && curTrack <= pTS->waitTrack);
}
Exemple #19
0
BOOLEAN
DoLoadTeam (MELEE_STATE *pMS)
{
	DWORD TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		return FALSE;

	SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN | MENU_SOUND_PAGEUP |
			MENU_SOUND_PAGEDOWN, MENU_SOUND_SELECT);

	if (!pMS->Initialized)
	{
		LockMutex (GraphicsLock);
		DrawFileStrings (pMS);
		SelectFileString (pMS, true);
		pMS->Initialized = TRUE;
		pMS->InputFunc = DoLoadTeam;
		UnlockMutex (GraphicsLock);
		return TRUE;
	}

	if (PulsedInputState.menu[KEY_MENU_SELECT] ||
			PulsedInputState.menu[KEY_MENU_CANCEL])
	{
		if (PulsedInputState.menu[KEY_MENU_SELECT])
		{
			// Copy the selected fleet to the player.
			Melee_LocalChange_team (pMS, pMS->side,
					pMS->load.view[pMS->load.cur - pMS->load.top]);
		}

		pMS->InputFunc = DoMelee;
		pMS->LastInputTime = GetTimeCounter ();
		{
			RECT r;
			
			GetFrameRect (SetAbsFrameIndex (MeleeFrame, 28), &r);
			LockMutex (GraphicsLock);
			RepairMeleeFrame (&r);
			UnlockMutex (GraphicsLock);
		}
		return TRUE;
	}
	
	{
		COUNT newTop = pMS->load.top;
		COUNT newIndex = pMS->load.cur;

		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (newIndex > 0)
			{
				newIndex--;
				if (newIndex < newTop)
					newTop = (newTop < LOAD_TEAM_VIEW_SIZE) ?
							0 : newTop - LOAD_TEAM_VIEW_SIZE;
			}
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			COUNT numEntries = pMS->load.numIndices + pMS->load.preBuiltCount;
			if (newIndex + 1 < numEntries)
			{
				newIndex++;
				if (newIndex >= pMS->load.bot)
					newTop = pMS->load.bot;
			}
		}
		else if (PulsedInputState.menu[KEY_MENU_PAGE_UP])
		{
			newIndex = (newIndex < LOAD_TEAM_VIEW_SIZE) ?
					0 : newIndex - LOAD_TEAM_VIEW_SIZE;
			newTop = (newTop < LOAD_TEAM_VIEW_SIZE) ?
					0 : newTop - LOAD_TEAM_VIEW_SIZE;
		}
		else if (PulsedInputState.menu[KEY_MENU_PAGE_DOWN])
		{
			COUNT numEntries = pMS->load.numIndices + pMS->load.preBuiltCount;
			if (newIndex + LOAD_TEAM_VIEW_SIZE < numEntries)
			{
				newIndex += LOAD_TEAM_VIEW_SIZE;
				newTop += LOAD_TEAM_VIEW_SIZE;
			}
			else
			{
				newIndex = numEntries - 1;
				if (newTop + LOAD_TEAM_VIEW_SIZE < numEntries &&
						numEntries > LOAD_TEAM_VIEW_SIZE)
					newTop = numEntries - LOAD_TEAM_VIEW_SIZE;
			}
		}

		if (newIndex != pMS->load.cur)
		{
			// The cursor has been moved.
			LockMutex (GraphicsLock);
			if (newTop == pMS->load.top)
			{
				// The view itself hasn't changed.
				SelectFileString (pMS, false);
			}
			else
			{
				// The view is changed.
				pMS->load.top = newTop;
				DrawFileStrings (pMS);
			}
			pMS->load.cur = newIndex;
			UnlockMutex (GraphicsLock);
		}
	}

	flashSelectedTeam (pMS);

	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Exemple #20
0
//=============================================================================
// 更新処理
//=============================================================================
void UpdateGameManager(void)
{
#ifdef _DEBUG
	if(GetKeyboardTrigger(DIK_F1))
	{
		g_nGameMode = SELECTMODE_PLAY;
	}
	if(GetKeyboardTrigger(DIK_F2))
	{
		g_nGameMode = SELECTMODE_WALLEDIT;
	}
	if(GetKeyboardTrigger(DIK_F3))
	{
		g_nGameMode = SELECTMODE_GIMMICKEDIT;
	}
	if(GetKeyboardTrigger(DIK_F4))
	{
		g_nGameMode = SELECTMODE_PLAYEREDIT;
	}
	if(GetKeyboardTrigger(DIK_F5))
	{
		g_nGameMode = SELECTMODE_DELETE;
	}
	if(GetKeyboardTrigger(DIK_F6))
	{
		g_nGameMode = SELECTMODE_SCENECHANGE;
	}
	if(GetKeyboardTrigger(DIK_F7))
	{
		g_nGameMode = SELECTMODE_PLAYERBAR_NUM;
	}
	if(GetKeyboardTrigger(DIK_F8))
	{
		g_nGameMode = SELECTMODE_ITEMNUMEDIT;
	}
	if(g_nGameMode != SELECTMODE_PLAY)
		GetBackG()[BACKGROUND_EDIT_NET].bUse = true;
	else
		GetBackG()[BACKGROUND_EDIT_NET].bUse = false;

#endif

	switch (g_nGameMode)
	{
	case SELECTMODE_PLAY:
	{
		PrintDebugProc("【ゲームモード】\n");
		if(GetTimeCounter()->fCurrentTime > TIME_15)
			g_bIsPlay = false;

		if(!g_bIsPlay)
		{
			if(IsMouseRightTriggered())
			{
				int nGimNum = -1;
				int nItemNum = GetItemNum()->nItemLockTime;
				bool bIsLock = false;

				if(IsGimmickLock(&nGimNum, &bIsLock, &nItemNum) == true)
				{
					if(bIsLock == true)
					{
						SetItem(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), ITEM_TYPE_01, nGimNum);
						UpdataItemNum(-1);
					}
					else
					{
						DeleteItem(nGimNum);
						UpdataItemNum(1);
					}
				}
			}
		}
		break;
	}
	case SELECTMODE_WALLEDIT:
	{
		PrintDebugProc("【壁を編集するモード】\n");
		WallCreateMode();
		break;
	}
	case SELECTMODE_GIMMICKEDIT:
	{
		PrintDebugProc("【ギミック編集モード】\n");
		GimmickCreateMode();
		break;
	}
	case SELECTMODE_PLAYEREDIT:
	{
		PrintDebugProc("【プレイヤー編集モード】\n");
		if(IsMouseLeftPressed())
			IsMouseHitPlayer();
		PlayerEdit();
		break;
	}
	case SELECTMODE_DELETE:
	{
		PrintDebugProc("【削除モード】\n");
		DeleteGimmick();
		DeleteWall();
		break;
	}
	case SELECTMODE_SCENECHANGE:
	{
		PrintDebugProc("【ステージ切り替えるモード】\n");
		if(IsMouseRightTriggered())
		{
			if(*GetSceneNum() < SCENE_TYPE_MAX)
				(*GetSceneNum())++;
			if(*GetSceneNum() == SCENE_TYPE_MAX)
				*GetSceneNum() = 0;
			g_bIsSceneInit = true;
		}

		if(g_bIsSceneInit == true)
		{
			g_bIsSceneInit = false;
			switch (*GetSceneNum())
			{
			case SCENE_01:
				// 从文件中读取
				LoadData(SCENE_01);
				break;
			case SCENE_02:
				// 从文件中读取
				LoadData(SCENE_02);
				break;
			case SCENE_03:
				// 从文件中读取
				LoadData(SCENE_03);
				break;
			case SCENE_04:
				// 从文件中读取
				LoadData(SCENE_04);
				break;
			case SCENE_05:
				// 从文件中读取
				LoadData(SCENE_05);
				break;
			default:
				break;
			}
			// 読み込むデータを初期化
			InitDataPlayer();
			InitDataWall();
			InitDataGimmick();
			InitDataPlayerbar();

			for(int nCntGim = 0; nCntGim < MAX_GIMMICK; nCntGim++)
			{
				// 根据补完的数据对机关场景进行位置和运动预处理
				SetupGimmickTrack(nCntGim);
				*GetCleanupSwitch() = false;
			}
		}
		break;
	}
	case SELECTMODE_PLAYERBAR_NUM:
	{
		PrintDebugProc("【時間軸編集モード】\n");
		PrintDebugProc("数字キー「1」 時間軸数:1\n");
		PrintDebugProc("数字キー「2」 時間軸数:2\n");
		PrintDebugProc("数字キー「3」 時間軸数:3\n");
		if(GetKeyboardTrigger(DIK_1))
		{
			for(int nCntPlayBar = 0; nCntPlayBar < MAX_PLAYBAR; nCntPlayBar++)
			{
				//if(g_pPlaybar_GM[nCntPlayBar].bUse == true)
					g_pPlaybar_GM[nCntPlayBar].bUse = false;
			}
			for(int nCntGim = 0; nCntGim < MAX_GIMMICK; nCntGim++)
			{
				if(g_pGimmick_GM[nCntGim].bUse)
				{
					g_pGimmick_GM[nCntGim].nPriorityNum01 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum02 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum03 = -1;
				}
			}
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_1);
			PlaybarNumCount();
		}
		if(GetKeyboardTrigger(DIK_2))
		{
			for(int nCntPlayBar = 0; nCntPlayBar < MAX_PLAYBAR; nCntPlayBar++)
			{
				//if(g_pPlaybar_GM[nCntPlayBar].bUse == true)
					g_pPlaybar_GM[nCntPlayBar].bUse = false;
			}
			for(int nCntGim = 0; nCntGim < MAX_GIMMICK; nCntGim++)
			{
				if(g_pGimmick_GM[nCntGim].bUse)
				{
					g_pGimmick_GM[nCntGim].nPriorityNum01 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum02 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum03 = -1;
				}
			}
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_1);
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_2);
			PlaybarNumCount();
		}
		if(GetKeyboardTrigger(DIK_3))
		{
			for(int nCntPlayBar = 0; nCntPlayBar < MAX_PLAYBAR; nCntPlayBar++)
			{
				//if(g_pPlaybar_GM[nCntPlayBar].bUse == true)
					g_pPlaybar_GM[nCntPlayBar].bUse = false;
			}
			for(int nCntGim = 0; nCntGim < MAX_GIMMICK; nCntGim++)
			{
				if(g_pGimmick_GM[nCntGim].bUse)
				{
					g_pGimmick_GM[nCntGim].nPriorityNum01 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum02 = -1;
					g_pGimmick_GM[nCntGim].nPriorityNum03 = -1;
				}
			}
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_1);
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_2);
			SetPlaybar(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f), PLAYBAR_3_3);
			PlaybarNumCount();
		}
		break;
	}
	case SELECTMODE_ITEMNUMEDIT:
	{
		PrintDebugProc("【アイテム個数編集モード】\n");
		PrintDebugProc("【メニュー】    【アイテム】    【個数】\n");
		PrintDebugProc("数字キー「1」 時間固定アイテム:%d\n\n", g_pItemNum_GM->nItemLockTime);

		if(GetKeyboardTrigger(DIK_1))
		{
			g_nMenuSelect_GM = 1;
		}

		switch (g_nMenuSelect_GM)
		{

			case 1:
				PrintDebugProc("矢印キー【左】、【右】   【プラス/マイナス 1】\n");
				PrintDebugProc("矢印キー【上】、【下】   【プラス/マイナス 5】\n");

				if(GetKeyboardRepeat(DIK_LEFT))
				{
					g_pItemNum_GM->nItemLockTime -= 1;
					if(g_pItemNum_GM->nItemLockTime < 0)
						g_pItemNum_GM->nItemLockTime = 0;
				}
				if(GetKeyboardRepeat(DIK_RIGHT))
				{
					g_pItemNum_GM->nItemLockTime += 1;
					if(g_pItemNum_GM->nItemLockTime > 9)
						g_pItemNum_GM->nItemLockTime = 9;
				}
				if(GetKeyboardRepeat(DIK_DOWN))
				{
					g_pItemNum_GM->nItemLockTime -= 5;
					if(g_pItemNum_GM->nItemLockTime < 0)
						g_pItemNum_GM->nItemLockTime = 0;
				}
				if(GetKeyboardRepeat(DIK_UP))
				{
					g_pItemNum_GM->nItemLockTime += 5;
					if(g_pItemNum_GM->nItemLockTime > 9)
						g_pItemNum_GM->nItemLockTime = 9;
				}
				break;
			default:
				break;
		}

	}
	default:
		break;
	}

	if(!g_bIsPlay)
	{
		switch (*GetSceneNum())
		{
		case SCENE_01:
			PrintDebugProc("【SCENE_01】\n");
			// 今のシーンをセーフする
			if(IsMouseCenterTriggered())
				SaveData(SCENE_01);
			break;

		case SCENE_02:
			PrintDebugProc("【SCENE_02】\n");
			if(IsMouseCenterTriggered())
				SaveData(SCENE_02);
			break;

		case SCENE_03:
			PrintDebugProc("【SCENE_03】\n");
			if(IsMouseCenterTriggered())
				SaveData(SCENE_03);
			break;

		case SCENE_04:
			PrintDebugProc("【SCENE_04】\n");
			if(IsMouseCenterTriggered())
				SaveData(SCENE_04);
			break;

		case SCENE_05:
			PrintDebugProc("【SCENE_05】\n");
			if(IsMouseCenterTriggered())
				SaveData(SCENE_05);
			break;

		default:
			break;
		}
	}

	switch(*GetMode())
	{
	case GAMEMODE_LOGO:
		break;

	case GAMEMODE_TITLE:
	{
		if(GetKeyboardTrigger(DIK_RETURN) || IsMouseLeftTriggered())
			SetFade(FADE_OUT, FADE_IN, GAMEMODE_STAGE_SELECT);
		break;
	}
	case GAMEMODE_STAGE_SELECT:
	{
		g_bIsStop = true;
		g_bIsPlay = false;

		if(GetKeyboardTrigger(DIK_RETURN))
			SetFade(FADE_OUT, FADE_IN, GAMEMODE_GAME);

		if(IsMouseLeftTriggered())
		{
			int pIconNum = 0;
			if(IsMouseHitIcon(&pIconNum) == true)
			{
				*GetSceneNum() = GetGameElement()[pIconNum].nType;
				g_bIsSceneInit = true;
			}
		}

		if(g_bIsSceneInit == true)
		{
			g_bIsSceneInit = false;
			switch (*GetSceneNum())
			{
			case SCENE_01:
				// 从文件中读取
				LoadData(SCENE_01);
				break;
			case SCENE_02:
				// 从文件中读取
				LoadData(SCENE_02);
				break;
			case SCENE_03:
				// 从文件中读取
				LoadData(SCENE_03);
				break;
			case SCENE_04:
				// 从文件中读取
				LoadData(SCENE_04);
				break;
			case SCENE_05:
				// 从文件中读取
				LoadData(SCENE_05);
				break;
			default:
				break;
			}
			// 読み込むデータを初期化
			InitDataPlayer();
			InitDataWall();
			InitDataGimmick();
			InitDataPlayerbar();

			for(int nCntGim = 0; nCntGim < MAX_GIMMICK; nCntGim++)
			{
				// 根据补完的数据对机关场景进行位置和运动预处理
				SetupGimmickTrack(nCntGim);
				*GetCleanupSwitch() = false;
			}
			//*GetMode() = GAMEMODE_GAME;

			SetFade(FADE_OUT, FADE_IN, GAMEMODE_GAME);
		}
		
		break;
	}
	case GAMEMODE_GAME:
		break;

	case GAMEMODE_END:
		break;

	default:
		break;
	}



}
Exemple #21
0
static void
DoSell (RESPONSE_REF R)
{
	BYTE num_new_rainbows;
	UWORD rainbow_mask;
	SIZE added_credit;
	int what_to_sell_queued = 0;

	rainbow_mask = MAKE_WORD (
			GET_GAME_STATE (RAINBOW_WORLD0),
			GET_GAME_STATE (RAINBOW_WORLD1)
			);
	num_new_rainbows = (BYTE)(-GET_GAME_STATE (MELNORME_RAINBOW_COUNT));
	while (rainbow_mask)
	{
		if (rainbow_mask & 1)
			++num_new_rainbows;

		rainbow_mask >>= 1;
	}

	if (!PLAYER_SAID (R, sell))
	{
		if (PLAYER_SAID (R, sell_life_data))
		{
			DWORD TimeIn;

			added_credit = GLOBAL_SIS (TotalBioMass) * BIO_CREDIT_VALUE;

			NPCPhrase (SOLD_LIFE_DATA1);
			NPCPhrase (-(int)GLOBAL_SIS (TotalBioMass));
			NPCPhrase (SOLD_LIFE_DATA2);
			NPCPhrase (-(int)added_credit);
			NPCPhrase (SOLD_LIFE_DATA3);
			// queue WHAT_TO_SELL before talk-segue
			if (num_new_rainbows)
			{
				NPCPhrase (WHAT_TO_SELL);
				what_to_sell_queued = 1;
			}
			AlienTalkSegue (1);

			DrawCargoStrings ((BYTE)~0, (BYTE)~0);
			SleepThread (ONE_SECOND / 2);
			TimeIn = GetTimeCounter ();
			DrawCargoStrings (
					(BYTE)NUM_ELEMENT_CATEGORIES,
					(BYTE)NUM_ELEMENT_CATEGORIES
					);
			do
			{
				TimeIn = GetTimeCounter ();
				if (AnyButtonPress (TRUE))
				{
					DeltaCredit (GLOBAL_SIS (TotalBioMass) * BIO_CREDIT_VALUE);
					GLOBAL_SIS (TotalBioMass) = 0;
				}
				else
				{
					--GLOBAL_SIS (TotalBioMass);
					DeltaCredit (BIO_CREDIT_VALUE);
				}
				DrawCargoStrings (
						(BYTE)NUM_ELEMENT_CATEGORIES,
						(BYTE)NUM_ELEMENT_CATEGORIES
						);
			} while (GLOBAL_SIS (TotalBioMass));
			SleepThread (ONE_SECOND / 2);

			LockMutex (GraphicsLock);
			ClearSISRect (DRAW_SIS_DISPLAY);
			UnlockMutex (GraphicsLock);
		}
		else /* if (R == sell_rainbow_locations) */
		{
			added_credit = num_new_rainbows * (250 * BIO_CREDIT_VALUE);

			NPCPhrase (SOLD_RAINBOW_LOCATIONS1);
			NPCPhrase (-(int)num_new_rainbows);
			NPCPhrase (SOLD_RAINBOW_LOCATIONS2);
			NPCPhrase (-(int)added_credit);
			NPCPhrase (SOLD_RAINBOW_LOCATIONS3);

			num_new_rainbows += GET_GAME_STATE (MELNORME_RAINBOW_COUNT);
			SET_GAME_STATE (MELNORME_RAINBOW_COUNT, num_new_rainbows);
			num_new_rainbows = 0;

			DeltaCredit (added_credit);
		}
		
		AskedToBuy = FALSE;
	}

	if (GLOBAL_SIS (TotalBioMass) || num_new_rainbows)
	{
		if (!what_to_sell_queued)
			NPCPhrase (WHAT_TO_SELL);

		if (GLOBAL_SIS (TotalBioMass))
			Response (sell_life_data, DoSell);
		if (num_new_rainbows)
			Response (sell_rainbow_locations, DoSell);
		Response (done_selling, NatureOfConversation);
	}
	else
	{
		if (PLAYER_SAID (R, sell))
			NPCPhrase (NOTHING_TO_SELL);
		DISABLE_PHRASE (sell);

		NatureOfConversation (R);
	}
}
Exemple #22
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		pMS->hMusic = LoadMusic (MAINMENU_MUSIC);
		InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND;
		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 16, 0,
				(6 * ONE_SECOND) / 16, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
		Flash_start (pMS->flashContext);
		PlayMusic (pMS->hMusic, TRUE, 1);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				LastActivity = CHECK_LOAD;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case START_NEW_GAME:
				LastActivity = CHECK_LOAD | CHECK_RESTART;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case PLAY_SUPER_MELEE:
				GLOBAL (CurrentActivity) = SUPER_MELEE;
				break;
			case SETUP_GAME:
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);
				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		if (GetTimeCounter () - LastInputTime > InactTimeOut)
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}

	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Exemple #23
0
static BOOLEAN
DoBattle (BATTLE_STATE *bs)
{
	extern UWORD nth_frame;
	RECT r;
	BYTE battle_speed;

	SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);

#if defined (NETPLAY) && defined (NETPLAY_CHECKSUM)
	if (getNumNetConnections() > 0 &&
			battleFrameCount % NETPLAY_CHECKSUM_INTERVAL == 0)
	{
		crc_State state;
		Checksum checksum;

		crc_init(&state);
		crc_processState (&state);
		checksum = (Checksum) crc_finish (&state);

		Netplay_NotifyAll_checksum ((uint32) battleFrameCount,
				(uint32) checksum);
		flushPacketQueues ();
		addLocalChecksum (battleFrameCount, checksum);
	}
#endif
	ProcessInput ();
			// Also calls NetInput()
#if defined (NETPLAY) && defined (NETPLAY_CHECKSUM)
	if (getNumNetConnections() > 0)
	{
		size_t delay = getBattleInputDelay();

		if (battleFrameCount >= delay
				&& (battleFrameCount - delay) % NETPLAY_CHECKSUM_INTERVAL == 0)
		{
			if (!(GLOBAL (CurrentActivity) & CHECK_ABORT))
			{
				if (!verifyChecksums (battleFrameCount - delay)) {
					GLOBAL(CurrentActivity) |= CHECK_ABORT;
					resetConnections (ResetReason_syncLoss);
				}
			}
		}
	}
#endif

	LockMutex (GraphicsLock);
	if (bs->first_time)
	{
		r.corner.x = SIS_ORG_X;
		r.corner.y = SIS_ORG_Y;
		r.extent.width = SIS_SCREEN_WIDTH;
		r.extent.height = SIS_SCREEN_HEIGHT;
		SetTransitionSource (&r);
	}
	BatchGraphics ();

	// Call the callback function, if set
	if (bs->frame_cb)
		bs->frame_cb ();

	RedrawQueue (TRUE);

	if (bs->first_time)
	{
		bs->first_time = FALSE;
		ScreenTransition (3, &r);
	}
	UnbatchGraphics ();
	UnlockMutex (GraphicsLock);
	if ((!(GLOBAL (CurrentActivity) & IN_BATTLE)) ||
			(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD)))
	{
		return FALSE;
	}

	battle_speed = HIBYTE (nth_frame);
	if (battle_speed == (BYTE)~0)
	{	// maximum speed, nothing rendered at all
		TaskSwitch ();
	}
	else
	{
		SleepThreadUntil (bs->NextTime
				+ BATTLE_FRAME_RATE / (battle_speed + 1));
		bs->NextTime = GetTimeCounter ();
	}

	if ((GLOBAL (CurrentActivity) & IN_BATTLE) == 0)
		return FALSE;

#ifdef NETPLAY
	battleFrameCount++;
#endif
	return TRUE;
}