Ejemplo n.º 1
0
bool CBaseOperThread::ReStart()
{
	if( m_hThread == NULL )
	{
		if( !CreateThread( NULL, 0, EntryPoint, this, CREATE_SUSPENDED ))
		{
			return false;
		}
		if( ResumeThread( m_hThread ) == -1) 
		{
			return false;
		}
		else
		{
			ClearSemaphore();
			m_bIsExit = false;
			return true;
		}
	}
	return false;
}
Ejemplo n.º 2
0
COUNT
ActivateStarShip (COUNT which_ship, SIZE state)
{
	HSTARSHIP hStarShip, hNextShip;

	hStarShip = GetStarShipFromIndex (
			&GLOBAL (avail_race_q), which_ship
			);
	if (hStarShip)
	{
		switch (state)
		{
			case SPHERE_TRACKING:
			case SPHERE_KNOWN:
			{
				EXTENDED_SHIP_FRAGMENTPTR StarShipPtr;

				StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				if (state == SPHERE_KNOWN)
					which_ship = StarShipPtr->ShipInfo.known_strength;
				else if (StarShipPtr->ShipInfo.actual_strength == 0)
				{
					if (!(StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY)))
						which_ship = 0;
				}
				else if (StarShipPtr->ShipInfo.known_strength == 0
						&& StarShipPtr->ShipInfo.actual_strength != (COUNT)~0)
				{
					StarShipPtr->ShipInfo.known_strength = 1;
					StarShipPtr->ShipInfo.known_loc =
							StarShipPtr->ShipInfo.loc;
				}
				UnlockStarShip (
						&GLOBAL (avail_race_q), hStarShip
						);
				return (which_ship);
			}
			case ESCORT_WORTH:
				which_ship = 0;
			case ESCORTING_FLAGSHIP:
			{
				COUNT ShipCost[] =
				{
					RACE_SHIP_COST
				};

				for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
						hStarShip; hStarShip = hNextShip)
				{
					BYTE ship_type;
					SHIP_FRAGMENTPTR StarShipPtr;

					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);
					hNextShip = _GetSuccLink (StarShipPtr);
					if (state == ESCORT_WORTH)
						which_ship += ShipCost[GET_RACE_ID (StarShipPtr)];
					else
						ship_type = GET_RACE_ID (StarShipPtr);
					UnlockStarShip (
							&GLOBAL (built_ship_q), hStarShip
							);

					if (state != ESCORT_WORTH
							&& (COUNT)ship_type == which_ship)
						return (1);
				}

				return (state == ESCORTING_FLAGSHIP ? 0 : which_ship);
			}
			case FEASIBILITY_STUDY:
				return (MAX_BUILT_SHIPS
						- CountLinks (&GLOBAL (built_ship_q)));
			default:
			{
				SHIP_FRAGMENTPTR StarShipPtr;

				if (state <= 0)
				{
					StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
					if (state == CHECK_ALLIANCE)
					{
						state = StarShipPtr->ShipInfo.ship_flags
								& (GOOD_GUY | BAD_GUY);
						UnlockStarShip (
								&GLOBAL (avail_race_q), hStarShip
								);
						return ((COUNT)state);
					}
					else if (StarShipPtr->ShipInfo.ship_flags
							& (GOOD_GUY | BAD_GUY))
					{
						StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY);
						if (state == 0)
							StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY;
						else
						{
							StarShipPtr->ShipInfo.ship_flags |= BAD_GUY;
							if (which_ship == ORZ_SHIP)
							{
								BOOLEAN ShipRemoved;

								ShipRemoved = FALSE;
								for (hStarShip = GetHeadLink (
										&GLOBAL (built_ship_q
										)); hStarShip; hStarShip = hNextShip)
								{
									BOOLEAN RemoveShip;
									SHIP_FRAGMENTPTR StarShipPtr;

									StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);
									hNextShip = _GetSuccLink (StarShipPtr);
									RemoveShip = (BOOLEAN)(
											GET_RACE_ID (StarShipPtr) == ORZ_SHIP
											);
									UnlockStarShip (
											&GLOBAL (built_ship_q),
											hStarShip
											);

									if (RemoveShip)
									{
										ShipRemoved = TRUE;

										RemoveQueue (
												&GLOBAL (built_ship_q),
												hStarShip
												);
										FreeStarShip (
												&GLOBAL (built_ship_q),
												hStarShip
												);
									}
								}
								
								if (ShipRemoved)
								{
									SetSemaphore (GraphicsSem);
									DeltaSISGauges (UNDEFINED_DELTA,
											UNDEFINED_DELTA, UNDEFINED_DELTA);
									ClearSemaphore (GraphicsSem);
								}
							}
						}
					}
					UnlockStarShip (
							&GLOBAL (avail_race_q), hStarShip
							);
				}
				else
				{
					BYTE which_window;
						COUNT i;

					which_window = 0;
					for
						(
								i = 0;
								
								i < (COUNT)state
							&&
								(
										hStarShip = CloneShipFragment
										(
												(COUNT)which_ship,
												(PQUEUE)(&GLOBAL (built_ship_q)),
												(BYTE)
												(
														(
																which_ship == SPATHI_SHIP &&
																								GET_GAME_STATE (FOUND_PLUTO_SPATHI)
														) == 1 ? 1 : 0
												)
										)
								);

							i++
						)
					{
						HSTARSHIP hOldShip;

						RemoveQueue (
								&GLOBAL (built_ship_q),
								hStarShip
								);

						while ((hOldShip = GetStarShipFromIndex (
								&GLOBAL (built_ship_q),
								which_window++
								)))
						{
							BYTE win_loc;

							StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							win_loc = GET_GROUP_LOC (StarShipPtr);
							UnlockStarShip (
									&GLOBAL (built_ship_q), hOldShip
									);
							if (which_window <= win_loc)
								break;
						}

						StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);
						SET_GROUP_LOC (StarShipPtr, which_window - 1);
						if (which_ship == SPATHI_SHIP
								&& GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1)
						{
							OwnStarShip (StarShipPtr,
									GOOD_GUY,
									NAME_OFFSET + NUM_CAPTAINS_NAMES);
						}
						UnlockStarShip (
								&GLOBAL (built_ship_q), hStarShip
								);

						InsertQueue (
								&GLOBAL (built_ship_q),
								hStarShip, hOldShip
								);
					}

					SetSemaphore (GraphicsSem);
					DeltaSISGauges (UNDEFINED_DELTA,
							UNDEFINED_DELTA, UNDEFINED_DELTA);
					ClearSemaphore (GraphicsSem);
					return (i);
				}
				break;
			}
		}

		return (1);
	}

	return (0);
}
Ejemplo n.º 3
0
// Only call from main() thread!!
void
TFB_FlushGraphics (void)
{
	int commands_handled;
	BOOLEAN livelock_deterrence;

	// This is technically a locking violation on DrawCommandQueue.Size,
	// but it is likely to not be very destructive.
	if (DrawCommandQueue.Size == 0)
	{
		static int last_fade = 255;
		static int last_transition = 255;
		int current_fade = GetFadeAmount ();
		int current_transition = TransitionAmount;
		
		if ((current_fade != 255 && current_fade != last_fade) ||
			(current_transition != 255 &&
			current_transition != last_transition) ||
			(current_fade == 255 && last_fade != 255) ||
			(current_transition == 255 && last_transition != 255))
		{
			TFB_SwapBuffers (TFB_REDRAW_FADING);
					// if fading, redraw every frame
		}
		else
		{
			TaskSwitch ();
		}
		
		last_fade = current_fade;
		last_transition = current_transition;
		BroadcastCondVar (RenderingCond);
		return;
	}

	if (GfxFlags & TFB_GFXFLAGS_SHOWFPS)
		computeFPS ();

	commands_handled = 0;
	livelock_deterrence = FALSE;

	if (DrawCommandQueue.FullSize > DCQ_FORCE_BREAK_SIZE)
	{
		TFB_BatchReset ();
	}

	if (DrawCommandQueue.Size > DCQ_FORCE_SLOWDOWN_SIZE)
	{
		Lock_DCQ (-1);
		livelock_deterrence = TRUE;
	}

	TFB_BBox_Reset ();

	for (;;)
	{
		TFB_DrawCommand DC;

		if (!TFB_DrawCommandQueue_Pop (&DC))
		{
			// the Queue is now empty.
			break;
		}

		++commands_handled;
		if (!livelock_deterrence && commands_handled + DrawCommandQueue.Size
				> DCQ_LIVELOCK_MAX)
		{
			// log_add (log_Debug, "Initiating livelock deterrence!");
			livelock_deterrence = TRUE;
			
			Lock_DCQ (-1);
		}

		switch (DC.Type)
		{
			case TFB_DRAWCOMMANDTYPE_SETMIPMAP:
			{
				TFB_DrawCommand_SetMipmap *cmd = &DC.data.setmipmap;
				TFB_DrawImage_SetMipmap (cmd->image, cmd->mipmap,
						cmd->hotx, cmd->hoty);
				break;
			}

			case TFB_DRAWCOMMANDTYPE_IMAGE:
			{
				TFB_DrawCommand_Image *cmd = &DC.data.image;
				TFB_Image *DC_image = cmd->image;
				const int x = cmd->x;
				const int y = cmd->y;

				TFB_DrawCanvas_Image (DC_image, x, y,
						cmd->scale, cmd->scaleMode, cmd->colormap,
						cmd->drawMode,
						TFB_GetScreenCanvas (cmd->destBuffer));

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
				{
					LockMutex (DC_image->mutex);
					if (cmd->scale)
						TFB_BBox_RegisterCanvas (DC_image->ScaledImg,
								x - DC_image->last_scale_hs.x,
								y - DC_image->last_scale_hs.y);
					else
						TFB_BBox_RegisterCanvas (DC_image->NormalImg,
								x - DC_image->NormalHs.x,
								y - DC_image->NormalHs.y);
					UnlockMutex (DC_image->mutex);
				}

				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_FILLEDIMAGE:
			{
				TFB_DrawCommand_FilledImage *cmd = &DC.data.filledimage;
				TFB_Image *DC_image = cmd->image;
				const int x = cmd->x;
				const int y = cmd->y;

				TFB_DrawCanvas_FilledImage (DC_image, x, y,
						cmd->scale, cmd->scaleMode, cmd->color,
						cmd->drawMode,
						TFB_GetScreenCanvas (cmd->destBuffer));

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
				{
					LockMutex (DC_image->mutex);
					if (cmd->scale)
						TFB_BBox_RegisterCanvas (DC_image->ScaledImg,
								x - DC_image->last_scale_hs.x,
								y - DC_image->last_scale_hs.y);
					else
						TFB_BBox_RegisterCanvas (DC_image->NormalImg,
								x - DC_image->NormalHs.x,
								y - DC_image->NormalHs.y);
					UnlockMutex (DC_image->mutex);
				}

				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_FONTCHAR:
			{
				TFB_DrawCommand_FontChar *cmd = &DC.data.fontchar;
				TFB_Char *DC_char = cmd->fontchar;
				const int x = cmd->x;
				const int y = cmd->y;

				TFB_DrawCanvas_FontChar (DC_char, cmd->backing, x, y,
						cmd->drawMode, TFB_GetScreenCanvas (cmd->destBuffer));

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
				{
					RECT r;
					
					r.corner.x = x - DC_char->HotSpot.x;
					r.corner.y = y - DC_char->HotSpot.y;
					r.extent.width = DC_char->extent.width;
					r.extent.height = DC_char->extent.height;

					TFB_BBox_RegisterRect (&r);
				}

				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_LINE:
			{
				TFB_DrawCommand_Line *cmd = &DC.data.line;

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
				{
					TFB_BBox_RegisterPoint (cmd->x1, cmd->y1);
					TFB_BBox_RegisterPoint (cmd->x2, cmd->y2);
				}
				TFB_DrawCanvas_Line (cmd->x1, cmd->y1, cmd->x2, cmd->y2,
						cmd->color, cmd->drawMode,
						TFB_GetScreenCanvas (cmd->destBuffer));
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_RECTANGLE:
			{
				TFB_DrawCommand_Rect *cmd = &DC.data.rect;

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
					TFB_BBox_RegisterRect (&cmd->rect);
				TFB_DrawCanvas_Rect (&cmd->rect, cmd->color, cmd->drawMode,
						TFB_GetScreenCanvas (cmd->destBuffer));

				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_SCISSORENABLE:
			{
				TFB_DrawCommand_Scissor *cmd = &DC.data.scissor;

				TFB_DrawCanvas_SetClipRect (
						TFB_GetScreenCanvas (TFB_SCREEN_MAIN), &cmd->rect);
				TFB_BBox_SetClipRect (&DC.data.scissor.rect);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_SCISSORDISABLE:
				TFB_DrawCanvas_SetClipRect (
						TFB_GetScreenCanvas (TFB_SCREEN_MAIN), NULL);
				TFB_BBox_SetClipRect (NULL);
				break;
			
			case TFB_DRAWCOMMANDTYPE_COPYTOIMAGE:
			{
				TFB_DrawCommand_CopyToImage *cmd = &DC.data.copytoimage;
				TFB_Image *DC_image = cmd->image;
				const POINT dstPt = {0, 0};

				if (DC_image == 0)
				{
					log_add (log_Debug, "DCQ ERROR: COPYTOIMAGE passed null "
							"image ptr");
					break;
				}
				LockMutex (DC_image->mutex);
				TFB_DrawCanvas_CopyRect (
						TFB_GetScreenCanvas (cmd->srcBuffer), &cmd->rect,
						DC_image->NormalImg, dstPt);
				UnlockMutex (DC_image->mutex);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_COPY:
			{
				TFB_DrawCommand_Copy *cmd = &DC.data.copy;
				const RECT r = cmd->rect;

				if (cmd->destBuffer == TFB_SCREEN_MAIN)
					TFB_BBox_RegisterRect (&cmd->rect);

				TFB_DrawCanvas_CopyRect	(
						TFB_GetScreenCanvas (cmd->srcBuffer), &r,
						TFB_GetScreenCanvas (cmd->destBuffer), r.corner);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_DELETEIMAGE:
			{
				TFB_Image *DC_image = DC.data.deleteimage.image;
				TFB_DrawImage_Delete (DC_image);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_DELETEDATA:
			{
				void *data = DC.data.deletedata.data;
				HFree (data);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_SENDSIGNAL:
				ClearSemaphore (DC.data.sendsignal.sem);
				break;
			
			case TFB_DRAWCOMMANDTYPE_REINITVIDEO:
			{
				TFB_DrawCommand_ReinitVideo *cmd = &DC.data.reinitvideo;
				int oldDriver = GraphicsDriver;
				int oldFlags = GfxFlags;
				int oldWidth = ScreenWidthActual;
				int oldHeight = ScreenHeightActual;
				// JMS_GFX: Added resolutionFactor
				if (TFB_ReInitGraphics (cmd->driver, cmd->flags,
						cmd->width, cmd->height, resolutionFactor))
				{
					log_add (log_Error, "Could not provide requested mode: "
							"reverting to last known driver.");
					// We don't know what exactly failed, so roll it all back
					if (TFB_ReInitGraphics (oldDriver, oldFlags,
							oldWidth, oldHeight, resolutionFactor))
					{
						log_add (log_Fatal,
								"Couldn't reinit at that point either. "
								"Your video has been somehow tied in knots.");
						exit (EXIT_FAILURE);
					}
				}
				TFB_SwapBuffers (TFB_REDRAW_YES);
				break;
			}
			
			case TFB_DRAWCOMMANDTYPE_CALLBACK:
			{
				DC.data.callback.callback (DC.data.callback.arg);
				break;
			}
		}
	}
	
	if (livelock_deterrence)
		Unlock_DCQ ();

	TFB_SwapBuffers (TFB_REDRAW_NO);
	RenderedFrames++;
	BroadcastCondVar (RenderingCond);
}
Ejemplo n.º 4
0
BOOLEAN
PauseGame (void)
{
	RECT r;
	STAMP s;
	BOOLEAN ClockActive;
	CONTEXT OldContext;
	FRAME F;
	HOT_SPOT OldHot;

	if (ActivityFrame == 0
			|| (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_PAUSE))
			|| (LastActivity & (CHECK_LOAD | CHECK_RESTART)))
		return (FALSE);
		
	GLOBAL (CurrentActivity) |= CHECK_PAUSE;

	ClockActive = (BOOLEAN)(
			LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE
			&& GameClockRunning ()
			);
	if (ClockActive)
		SuspendGameClock ();
	else if (CommData.ConversationPhrases && PlayingTrack ())
		PauseTrack ();

	SetSemaphore (GraphicsSem);
	OldContext = SetContext (ScreenContext);
	OldHot = SetFrameHot (Screen, MAKE_HOT_SPOT (0, 0));

	GetFrameRect (ActivityFrame, &r);
	r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1;
	r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
	s.origin = r.corner;
	s.frame = ActivityFrame;
	F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0));
	DrawStamp (&s);

	FlushGraphics ();

	{
		BYTE scan;

		scan = KBDToUNICODE (SK_F1);
		while (KeyDown (scan))
			TaskSwitch ();
	}

	FlushInput ();
	while (KeyHit () != SK_F1)
		TaskSwitch ();

	s.frame = F;
	DrawStamp (&s);
	DestroyDrawable (ReleaseDrawable (s.frame));

	SetFrameHot (Screen, OldHot);
	SetContext (OldContext);

	WaitForNoInput (ONE_SECOND / 4);
	FlushInput ();
	ClearSemaphore (GraphicsSem);

	if (ClockActive)
		ResumeGameClock ();
	else if (CommData.ConversationPhrases && PlayingTrack ())
		ResumeTrack ();

	TaskSwitch ();
	GLOBAL (CurrentActivity) &= ~CHECK_PAUSE;
	return (TRUE);
}