Esempio n. 1
0
GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
{
	Sync(1);

	const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;

	int w = DISPFB.FBW * 64;
	int h = GetFrameRect(i).bottom;

	// TODO: round up bottom

	if(m_dev->ResizeTexture(&m_texture[i], w, h))
	{
		static int pitch = 1024 * 4;

		GSVector4i r(0, 0, w, h);

		const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[DISPFB.PSM];

		(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), r.ralign<Align_Outside>(psm.bs), m_output, pitch, m_env.TEXA);

		m_texture[i]->Update(r, m_output, pitch);

		if(s_dump)
		{
			if(s_savef && s_n >= s_saven)
			{
				m_texture[i]->Save(m_dump_root + format("%05d_f%lld_fr%d_%05x_%s.bmp", s_n, m_perfmon.GetFrame(), i, (int)DISPFB.Block(), psm_str(DISPFB.PSM)));
			}
		}
	}

	return m_texture[i];
}
Esempio n. 2
0
// Draw the full restart menu. Nothing is done with selections.
static void
DrawRestartMenuGraphic (MENU_STATE *pMS)
{
	RECT r;
	STAMP s;
	TEXT t;
	UNICODE buf[64];

	s.frame = pMS->CurFrame;
	GetFrameRect (s.frame, &r);
	s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1;
	s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
	
	SetContextBackGroundColor (BLACK_COLOR);
	BatchGraphics ();
	ClearDrawable ();
	FlushColorXForms ();
	DrawStamp (&s);

	// Put the version number in the bottom right corner.
	SetContextFont (TinyFont);
	t.pStr = buf;
	t.baseline.x = SCREEN_WIDTH - 3;
	t.baseline.y = SCREEN_HEIGHT - 2;
	t.align = ALIGN_RIGHT;
	t.CharCount = (COUNT)~0;
	sprintf (buf, "v%d.%d.%d%s", UQM_MAJOR_VERSION, UQM_MINOR_VERSION,
			UQM_PATCH_VERSION, UQM_EXTRA_VERSION);
	SetContextForeGroundColor (WHITE_COLOR);
	font_DrawText (&t);

	UnbatchGraphics ();
}
Esempio n. 3
0
GSTexture* GSRendererHW::GetOutput(int i)
{
	const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;

	GIFRegTEX0 TEX0;

	TEX0.TBP0 = DISPFB.Block();
	TEX0.TBW = DISPFB.FBW;
	TEX0.PSM = DISPFB.PSM;

	// TRACE(_T("[%d] GetOutput %d %05x (%d)\n"), (int)m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM);

	GSTexture* t = NULL;

	if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GetFrameRect(i).bottom))
	{
		t = rt->m_texture;

		if(s_dump)
		{
			if(s_savef && s_n >= s_saven)
			{
				t->Save(root_hw + format("%05d_f%lld_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM));
			}
		}

		s_n++; // Alaways increment it
	}

	return t;
}
Esempio n. 4
0
GSTexture* GSRendererHW::GetOutput(int i, int& y_offset)
{
	const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;

	GIFRegTEX0 TEX0;

	TEX0.TBP0 = DISPFB.Block();
	TEX0.TBW = DISPFB.FBW;
	TEX0.PSM = DISPFB.PSM;

	// TRACE(_T("[%d] GetOutput %d %05x (%d)\n"), (int)m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM);

	GSTexture* t = NULL;

	if(GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GetFrameRect(i).bottom))
	{
		t = rt->m_texture;

		int delta = TEX0.TBP0 - rt->m_TEX0.TBP0;
		if (delta > 0) {
			// Code was corrected to use generic format. But I'm not sure behavior is correct.
			// Let's keep the warning to easily spot game that trigger this code path.
#ifndef DISABLE_WIP_ASSERTION
			ASSERT(DISPFB.PSM == PSM_PSMCT32 || DISPFB.PSM == PSM_PSMCT24);
#endif

			int pages = delta >> 5u;
			int y_pages = pages / DISPFB.FBW;
			y_offset = y_pages * GSLocalMemory::m_psm[DISPFB.PSM].pgs.y;
			GL_CACHE("Frame y offset %d pixels, unit %d", y_offset, i);
		}
Esempio n. 5
0
static void
RefreshResponses (ENCOUNTER_STATE *pES)
{
	COORD y;
	BYTE response, extra_y; // JMS_GFX
	SIZE leading;
	STAMP s;


	SetContext (SpaceContext);
	GetContextFontLeading (&leading);
	BatchGraphics ();

	DrawSISComWindow ();
	y = SLIDER_Y + SLIDER_HEIGHT + RES_SCALE(1); // JMS_GFX
	for (response = pES->top_response; response < pES->num_responses;
			++response)
	{
		extra_y = (response == pES->top_response ? 0 : IF_HD(22)); // JMS_GFX
		
		pES->response_list[response].response_text.baseline.x = TEXT_X_OFFS + RES_SCALE(8); // JMS_GFX
		pES->response_list[response].response_text.baseline.y = y + leading + extra_y; // JMS_GFX
		pES->response_list[response].response_text.align = ALIGN_LEFT;
		if (response == pES->cur_response)
			y = add_text (-1, &pES->response_list[response].response_text);
		else
			y = add_text (-2, &pES->response_list[response].response_text);
	}

	if (pES->top_response)
	{
		s.origin.y = SLIDER_Y + SLIDER_HEIGHT + 1;
		s.frame = SetAbsFrameIndex (ActivityFrame, 6);
	}
	else if (y > SIS_SCREEN_HEIGHT)
	{
		s.origin.y = SIS_SCREEN_HEIGHT - 2;
		s.frame = SetAbsFrameIndex (ActivityFrame, 7);
	}
	else
		s.frame = 0;
	if (s.frame)
	{
		RECT r;

		GetFrameRect (s.frame, &r);
		s.origin.x = SIS_SCREEN_WIDTH - r.extent.width - 1;
		DrawStamp (&s);
	}

	UnbatchGraphics ();
}
Esempio n. 6
0
static void
pump_up_collision (ELEMENT *ElementPtr0, POINT *pPt0,
                   ELEMENT *ElementPtr1, POINT *pPt1)
{
    RECT r;
    BYTE old_thrust_wait;
    HELEMENT hBlastElement;

    GetFrameRect (ElementPtr0->next.image.frame, &r);

    old_thrust_wait = ElementPtr0->thrust_wait;
    ElementPtr0->blast_offset = r.extent.width >> 1;
    hBlastElement = weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1);
    // This new section kills suspended blaster pulses after sustaining massive burst damage.
    if (ElementPtr1->mass_points >= ElementPtr0->mass_points)
    {
        ElementPtr0->postprocess_func = 0;
        ElementPtr0->thrust_wait = 0;
        ElementPtr0->state_flags |= DISAPPEARING;
    }
    else
        ElementPtr0->thrust_wait = old_thrust_wait;

    if (hBlastElement)
    {
        ELEMENT *BlastElementPtr;

        LockElement (hBlastElement, &BlastElementPtr);

        BlastElementPtr->life_span =
            MIN_PUMPITUDE_ANIMS
            + (ElementPtr0->turn_wait & ~REVERSE_DIR);
        BlastElementPtr->turn_wait = BlastElementPtr->next_turn = 0;
        {
            BlastElementPtr->preprocess_func = animate;
        }

        BlastElementPtr->current.image.farray = ElementPtr0->next.image.farray;
        BlastElementPtr->current.image.frame =
            SetAbsFrameIndex (BlastElementPtr->current.image.farray[0],
                              MAX_PUMP * NUM_PUMP_ANIMS);

        UnlockElement (hBlastElement);
    }
}
Esempio n. 7
0
void GSRendererSW::VSync(int field)
{
	Sync(0); // IncAge might delete a cached texture in use

	if(0) if(LOG)
	{
		fprintf(s_fp, "%llu\n", m_perfmon.GetFrame());

		GSVector4i dr = GetDisplayRect();
		GSVector4i fr = GetFrameRect();

		fprintf(s_fp, "dr %d %d %d %d, fr %d %d %d %d\n",
			dr.x, dr.y, dr.z, dr.w,
			fr.x, fr.y, fr.z, fr.w);

		m_regs->Dump(s_fp);

		fflush(s_fp);
	}

	/*
	int draw[8], sum = 0;

	for(size_t i = 0; i < countof(draw); i++)
	{
		draw[i] = m_perfmon.CPU(GSPerfMon::WorkerDraw0 + i);
		sum += draw[i];
	}

	printf("CPU %d Sync %d W %d %d %d %d %d %d %d %d (%d)\n",
		m_perfmon.CPU(GSPerfMon::Main),
		m_perfmon.CPU(GSPerfMon::Sync),
		draw[0], draw[1], draw[2], draw[3], draw[4], draw[5], draw[6], draw[7], sum);

	//
	*/

	GSRenderer::VSync(field);

	m_tc->IncAge();

	// if((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
}
Esempio n. 8
0
GSTexture* GSRendererCL::GetOutput(int i)
{
	const GSRegDISPFB& DISPFB = m_regs->DISP[i].DISPFB;

	int w = DISPFB.FBW * 64;
	int h = GetFrameRect(i).bottom;

	// TODO: round up bottom

	if(m_dev->ResizeTexture(&m_texture[i], w, h))
	{
		static int pitch = 1024 * 4;

		GSVector4i r(0, 0, w, h);

		const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[DISPFB.PSM];

		GIFRegBITBLTBUF BITBLTBUF;

		BITBLTBUF.SBP = DISPFB.Block();
		BITBLTBUF.SBW = DISPFB.FBW;
		BITBLTBUF.SPSM = DISPFB.PSM;

		InvalidateLocalMem(BITBLTBUF, r);

		(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), r.ralign<Align_Outside>(psm.bs), m_output, pitch, m_env.TEXA);

		m_texture[i]->Update(r, m_output, pitch);

		if(s_dump)
		{
			if(s_save && s_n >= s_saven)
			{
				m_texture[i]->Save(format("c:\\temp1\\_%05d_f%lld_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)DISPFB.Block(), (int)DISPFB.PSM));
			}

			s_n++;
		}
	}

	return m_texture[i];
}
Esempio n. 9
0
static void
DrawRestartMenuGraphic (MENU_STATE *pMS)
{
	RECT r;
	STAMP s;

	s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM));
	pMS->CurFrame = s.frame;
	GetFrameRect (s.frame, &r);
	s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1;
	s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
	
	SetContextBackGroundColor (BLACK_COLOR);
	BatchGraphics ();
	ClearDrawable ();
	FlushColorXForms ();
	LockMutex (GraphicsLock);
	DrawStamp (&s);
	UnlockMutex (GraphicsLock);
	UnbatchGraphics ();
}
Esempio n. 10
0
DirectKey::~DirectKey()
{
	DEC_NDOBJ_RTCLS

	s_Rect = GetFrameRect();
	
	SAFE_DELETE(m_picNormal);
	
	SAFE_DELETE(m_picDown);
	
	SAFE_DELETE(m_picCenterNormal);
	
	SAFE_DELETE(m_picCenterShrink);
	
	if (!m_addShrink) 
	{
		SAFE_DELETE_NODE(m_btnShrink);
	}
	
	delete m_timer;
}
Esempio n. 11
0
static void
pump_up_collision (ELEMENT *ElementPtr0, POINT *pPt0,
		ELEMENT *ElementPtr1, POINT *pPt1)
{
	RECT r;
	BYTE old_thrust_wait;
	HELEMENT hBlastElement;

	GetFrameRect (ElementPtr0->next.image.frame, &r);

	old_thrust_wait = ElementPtr0->thrust_wait;
	ElementPtr0->blast_offset = r.extent.width >> 1;
	hBlastElement = weapon_collision (ElementPtr0, pPt0, ElementPtr1, pPt1);
	ElementPtr0->thrust_wait = old_thrust_wait;

	if (hBlastElement)
	{
		ELEMENT *BlastElementPtr;

		LockElement (hBlastElement, &BlastElementPtr);

		BlastElementPtr->life_span =
				MIN_PUMPITUDE_ANIMS
				+ (ElementPtr0->turn_wait & ~REVERSE_DIR);
		BlastElementPtr->turn_wait = BlastElementPtr->next_turn = 0;
		{
			BlastElementPtr->preprocess_func = animate;
		}

		BlastElementPtr->current.image.farray = ElementPtr0->next.image.farray;
		BlastElementPtr->current.image.frame =
				SetAbsFrameIndex (BlastElementPtr->current.image.farray[0],
				MAX_PUMP * NUM_PUMP_ANIMS);

		UnlockElement (hBlastElement);
	}
}
Esempio n. 12
0
// Draw the value of the fleet in the top right of the PickMeleeFrame.
// Pre: caller holds the graphics lock.
static void
UpdatePickMeleeFleetValue (FRAME frame, COUNT which_player)
{
	CONTEXT OldContext;
	COUNT value;
	RECT r;
	TEXT t;
	UNICODE buf[40];
	
	value = GetRaceQueueValue (&race_q[which_player]);

	OldContext = SetContext (OffScreenContext);
	SetContextFGFrame (frame);

	// Erase the old value text.
	GetFrameRect (frame, &r);
	r.extent.width -= RES_SCALE(4);
	t.baseline.x = r.extent.width;
	r.corner.x = r.extent.width - RES_SCALE(6 * 3); // JMS_GFX
	r.corner.y = RES_SCALE(2); // JMS_GFX
	r.extent.width = RES_SCALE(6 * 3); // JMS_GFX
	r.extent.height = RES_SCALE(7 - 2) + RESOLUTION_FACTOR; // JMS_GFX
	SetContextForeGroundColor (PICK_BG_COLOR);
	DrawFilledRectangle (&r);

	// Draw the new value text.
	sprintf (buf, "%d", value);
	t.baseline.y = RES_SCALE(7);
	t.align = ALIGN_RIGHT;
	t.pStr = buf;
	t.CharCount = (COUNT)~0;
	SetContextFont (TinyFont);
	SetContextForeGroundColor (PICK_VALUE_COLOR);
	font_DrawText (&t);
	
	SetContext (OldContext);
}
Esempio n. 13
0
// Draw the full restart menu. Nothing is done with selections.
static void
DrawRestartMenuGraphic (MENU_STATE *pMS)
{
	RECT r;
	STAMP s;
	TEXT t; 
	char *Credit;
	UNICODE buf[64];

	// Re-load all of the restart menu fonts so the text shows in correct size after changing the resolution.
	if (optRequiresRestart || !PacksInstalled()) {	
		DestroyFont (TinyFont);
		DestroyFont (PlyrFont);
		DestroyFont (StarConFont);
	}	

	// DC: Load the different menus and fonts depending on the resolution factor	
	switch (resolutionFactor){
		case 1:
			if (optRequiresRestart || !PacksInstalled()) {
				TinyFont = LoadFont (TINY_FALLBACK_TO2X_FONT);
				PlyrFont = LoadFont (PLYR_FALLBACK_TO2X_FONT);
				StarConFont = LoadFont (SCON_FALLBACK_TO2X_FONT);
			}
			pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM2x));
			break;
		case 2:
			if (optRequiresRestart || !PacksInstalled()) {
				TinyFont = LoadFont (TINY_FALLBACK_TO4X_FONT);
				PlyrFont = LoadFont (PLYR_FALLBACK_TO4X_FONT);
				StarConFont = LoadFont (SCON_FALLBACK_TO4X_FONT);
			}
			pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM4x));
			break;
		case 0:
		default:
			if (optRequiresRestart || !PacksInstalled()) {
				TinyFont = LoadFont (TINY_FALLBACK_TO1X_FONT);
				PlyrFont = LoadFont (PLYR_FALLBACK_TO1X_FONT);
				StarConFont = LoadFont (SCON_FALLBACK_TO1X_FONT);
			}
			pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM));
			break;
	}

	s.frame = pMS->CurFrame;
	GetFrameRect (s.frame, &r);
	s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1;
	s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
	
	SetContextBackGroundColor (BLACK_COLOR);
	BatchGraphics ();
	ClearDrawable ();
	FlushColorXForms ();
	DrawStamp (&s);

	// Put the version number in the bottom right corner.
	SetContextFont (TinyFont);
	t.pStr = buf;
	t.baseline.x = SCREEN_WIDTH - RES_SCALE(2);
	t.baseline.y = SCREEN_HEIGHT - RES_SCALE(2);
	t.align = ALIGN_RIGHT;
	t.CharCount = (COUNT)~0;
	sprintf (buf, "v%d.%d.%d %s", UQM_MAJOR_VERSION, UQM_MINOR_VERSION, UQM_PATCH_VERSION, UQM_EXTRA_VERSION);
	SetContextForeGroundColor (WHITE_COLOR);
	font_DrawText (&t);

	// Put the main menu music credit in the bottom left corner.
	memset(&buf[0], 0, sizeof(buf));
	t.baseline.x = RES_SCALE(2);
	t.baseline.y = SCREEN_HEIGHT - RES_SCALE(2);
	t.align = ALIGN_LEFT;
	Credit = (Rando == 0 ? "Saibuster" : (Rando == 1 ? "Rush AX" : "Mark Vera"));
	sprintf (buf, "Main Menu Music by %s", Credit);
	font_DrawText (&t);

	UnbatchGraphics ();
}
Esempio n. 14
0
void WebDropBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	WEBC_BOOL focused = (mFlags & DISPLAY_FLAG_FOCUS) || (mState == DROPBOX_STATE_DROPPED);

	mListbox.CalculateTextMetrics(gc);

	WebRect oldClip;
	gc->GetClip(&oldClip);
	WebRect clip;
	clip.top = y;
	clip.left = x;
	clip.bottom = y + Height() - 1;
	clip.right = x + Width() - 1;
	clip.And(&oldClip);

	gc->SetClip(&clip);

	WebRect rect;
	rect.top = y;
	rect.left = x;
	rect.bottom = y + Height() - 1;
	rect.right = x + Width() - 1;

//	gc->StartBuffer();

	WebColor hilite, lolite, blue, white, black;
	HTMLColor col = HTML_RGBAToColor(0,0,0,0);
	black = hilite = gc->RGBToColor(col);

	col = HTML_RGBAToColor(0xff,0xff,0xff,0);
	white = lolite = gc->RGBToColor(col);

	col = HTML_RGBAToColor(0,0,0xff,0);
	blue = gc->RGBToColor(col);

	if (focused)
	{
		gc->Rectangle(&rect, black, black, WEBC_FALSE);
	}

	GetFrameRect(&rect);
	rect.Shift(x,y);
	DrawFrame(&rect, gc);

	GetContentRect(&rect);
	rect.Shift(x,y);

	if (focused)
	{
		gc->Rectangle(&rect, GetSelectColor(gc), GetSelectColor(gc), WEBC_TRUE);
	}
	else
	{
		gc->Rectangle(&rect, GetBgColor(gc), GetBgColor(gc), WEBC_TRUE);
	}

	if (mpText && mFont.GetFont())
	{
		DISPLAY_INT offset = (rect.Height() - gc->TextHeight(mpText, mFont.GetFont())) / 2;

		clip.Set(&rect);
		clip.And(&oldClip);
		gc->SetClip(&clip);
		gc->Text(rect.left + DROPBOX_PADDING,
			 rect.top + DROPBOX_PADDING + offset,
			 mpText, (focused) ? GetBgColor(gc) : GetTextColor(gc),
			 0, WEBC_FALSE, mFont.GetFont());
	}

//	gc->EndBuffer();
	gc->SetClip(&oldClip);

}
Esempio n. 15
0
bool GSRenderer::Merge(int field)
{
	bool en[2];

	GSVector4i fr[2];
	GSVector4i dr[2];

	GSVector2i display_baseline = { INT_MAX, INT_MAX };
	GSVector2i frame_baseline = { INT_MAX, INT_MAX };

	for(int i = 0; i < 2; i++)
	{
		en[i] = IsEnabled(i);

		if(en[i])
		{
			fr[i] = GetFrameRect(i);
			dr[i] = GetDisplayRect(i);

			display_baseline.x = min(dr[i].left, display_baseline.x);
			display_baseline.y = min(dr[i].top, display_baseline.y);
			frame_baseline.x = min(fr[i].left, frame_baseline.x);
			frame_baseline.y = min(fr[i].top, frame_baseline.y);

			//printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i].x,fr[i].y,fr[i].z,fr[i].w , dr[i].x,dr[i].y,dr[i].z,dr[i].w);
		}
	}

	if(!en[0] && !en[1])
	{
		return false;
	}

	GL_PUSH("Renderer Merge %d (0: enabled %d 0x%x, 1: enabled %d 0x%x)", s_n, en[0], m_regs->DISP[0].DISPFB.Block(), en[1], m_regs->DISP[1].DISPFB.Block());

	// try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero)
	//
	// NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending)

	bool samesrc =
		en[0] && en[1] &&
		m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP &&
		m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW &&
		m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM;

	if(samesrc /*&& m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80*/)
	{
		// persona 4:
		//
		// fr[0] = 0 0 640 448
		// fr[1] = 0 1 640 448
		// dr[0] = 159 50 779 498
		// dr[1] = 159 50 779 497
		//
		// second image shifted up by 1 pixel and blended over itself
		//
		// god of war:
		//
		// fr[0] = 0 1 512 448
		// fr[1] = 0 0 512 448
		// dr[0] = 127 50 639 497
		// dr[1] = 127 50 639 498
		//
		// same just the first image shifted
		//
		// These kinds of cases are now fixed by the more generic frame_diff code below, as the code here was too specific and has become obsolete.
		// NOTE: Persona 4 and God Of War are not rare exceptions, many games have the same(or very similar) offsets.

		int topDiff = fr[0].top - fr[1].top;
		if (dr[0].eq(dr[1]) && (fr[0].eq(fr[1] + GSVector4i(0, topDiff, 0, topDiff)) || fr[1].eq(fr[0] + GSVector4i(0, topDiff, 0, topDiff))))
		{
			// dq5:
			//
			// fr[0] = 0 1 512 445
			// fr[1] = 0 0 512 444
			// dr[0] = 127 50 639 494
			// dr[1] = 127 50 639 494

			int top = min(fr[0].top, fr[1].top);
			int bottom = min(fr[0].bottom, fr[1].bottom);

			fr[0].top = fr[1].top = top;
			fr[0].bottom = fr[1].bottom = bottom;
		}
	}

	GSVector2i fs(0, 0);
	GSVector2i ds(0, 0);

	GSTexture* tex[3] = {NULL, NULL, NULL};
	int y_offset[3]   = {0, 0, 0};

	s_n++;

	bool feedback_merge = m_regs->EXTWRITE.WRITE == 1;

	if(samesrc && fr[0].bottom == fr[1].bottom && !feedback_merge)
	{
		tex[0]      = GetOutput(0, y_offset[0]);
		tex[1]      = tex[0]; // saves one texture fetch
		y_offset[1] = y_offset[0];
	}
	else
	{
		if(en[0]) tex[0] = GetOutput(0, y_offset[0]);
		if(en[1]) tex[1] = GetOutput(1, y_offset[1]);
		if(feedback_merge) tex[2] = GetFeedbackOutput();
	}

	GSVector4 src[2];
	GSVector4 src_hw[2];
	GSVector4 dst[2];

	for(int i = 0; i < 2; i++)
	{
		if(!en[i] || !tex[i]) continue;

		GSVector4i r = fr[i];
		GSVector4 scale = GSVector4(tex[i]->GetScale()).xyxy();

		src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy();
		src_hw[i] = (GSVector4(r) + GSVector4 (0, y_offset[i], 0, y_offset[i])) * scale / GSVector4(tex[i]->GetSize()).xyxy();

		GSVector2 off(0);
		GSVector2i display_diff(dr[i].left - display_baseline.x, dr[i].top - display_baseline.y);
		GSVector2i frame_diff(fr[i].left - frame_baseline.x, fr[i].top - frame_baseline.y);

		// Time Crisis 2/3 uses two side by side images when in split screen mode.
		// Though ignore cases where baseline and display rectangle offsets only differ by 1 pixel, causes blurring and wrong resolution output on FFXII
		if(display_diff.x > 2)
		{
			off.x = tex[i]->GetScale().x * display_diff.x;
		}
		// If the DX offset is too small then consider the status of frame memory offsets, prevents blurring on Tenchu: Fatal Shadows, Worms 3D
		else if(display_diff.x != frame_diff.x)
		{
			off.x = tex[i]->GetScale().x * frame_diff.x;
		}

		if(display_diff.y >= 4) // Shouldn't this be >= 2?
		{
			off.y = tex[i]->GetScale().y * display_diff.y;

			if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD)
			{
				off.y /= 2;
			}
		}
		else if(display_diff.y != frame_diff.y)
		{
			off.y = tex[i]->GetScale().y * frame_diff.y;
		}

		dst[i] = GSVector4(off).xyxy() + scale * GSVector4(r.rsize());

		fs.x = max(fs.x, (int)(dst[i].z + 0.5f));
		fs.y = max(fs.y, (int)(dst[i].w + 0.5f));
	}

	ds = fs;

	if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD)
	{
		ds.y *= 2;
	}
	m_real_size = ds;

	bool slbg = m_regs->PMODE.SLBG;

	if(tex[0] || tex[1])
	{
		if(tex[0] == tex[1] && !slbg && (src[0] == src[1] & dst[0] == dst[1]).alltrue())
		{
			// the two outputs are identical, skip drawing one of them (the one that is alpha blended)

			tex[0] = NULL;
		}

		GSVector4 c = GSVector4((int)m_regs->BGCOLOR.R, (int)m_regs->BGCOLOR.G, (int)m_regs->BGCOLOR.B, (int)m_regs->PMODE.ALP) / 255;

		m_dev->Merge(tex, src_hw, dst, fs, m_regs->PMODE, m_regs->EXTBUF, c);

		if(m_regs->SMODE2.INT && m_interlace > 0)
		{
			if(m_interlace == 7 && m_regs->SMODE2.FFMD) // Auto interlace enabled / Odd frame interlace setting
			{
				int field2 = 0;
				int mode = 2;
				m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
			}
			else
			{
				int field2 = 1 - ((m_interlace - 1) & 1);
				int mode = (m_interlace - 1) >> 1;
				m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
			}
		}

		if(m_shadeboost)
		{
			m_dev->ShadeBoost();
		}

		if(m_shaderfx)
		{
			m_dev->ExternalFX();
		}

		if(m_fxaa)
		{
			m_dev->FXAA();
		}
	}

	return true;
}
Esempio n. 16
0
// Put the ship icons in the PickMeleeFrame, and create a queue
// for each player.
// XXX TODO: split off creating the queue into a separate function.
void
FillPickMeleeFrame (MeleeSetup *setup)
{
	COUNT i;
	CONTEXT OldContext;

	OldContext = SetContext (OffScreenContext);

	for (i = 0; i < NUM_SIDES; ++i)
	{
		COUNT side;
		COUNT sideI;
		RECT r;
		TEXT t;
		STAMP s;
		UNICODE buf[30];
		FleetShipIndex index;

		sideI = GetPlayerOrder (i);
		side = !sideI;

		s.frame = SetAbsFrameIndex (PickMeleeFrame, side);
		SetContextFGFrame (s.frame);

		GetFrameRect (s.frame, &r);
		t.baseline.x = r.extent.width >> 1;
		t.baseline.y = r.extent.height - NAME_AREA_HEIGHT + RES_SCALE(4);

		r.corner.x += RES_SCALE(2);
		r.corner.y += RES_SCALE(2);
		r.extent.width -= RES_SCALE((2 * 2) + (RES_DESCALE(ICON_WIDTH) + 2) + 1); // JMS_GFX
		r.extent.height -= RES_SCALE(2 * 2) + NAME_AREA_HEIGHT; // JMS_GFX
		SetContextForeGroundColor (PICK_BG_COLOR);
		DrawFilledRectangle (&r);

		r.corner.x += RES_SCALE(2); // JMS_GFX
		r.extent.width += RES_SCALE((RES_DESCALE(ICON_WIDTH) + 2) - (2 * 2)); // JMS_GFX
		r.corner.y += r.extent.height;
		r.extent.height = NAME_AREA_HEIGHT;
		DrawFilledRectangle (&r);

		// Team name at the bottom of the frame:
		t.align = ALIGN_CENTER;
		t.pStr = MeleeSetup_getTeamName (setup, sideI);
		t.CharCount = (COUNT) ~0;
		SetContextFont (TinyFont);
		SetContextForeGroundColor (PICKSHIP_TEAM_NAME_TEXT_COLOR);
		font_DrawText (&t);

		// Total team value of the starting team:
		sprintf (buf, "%u", MeleeSetup_getFleetValue (setup, sideI));
		t.baseline.x = RES_SCALE(4);
		t.baseline.y = RES_SCALE(7);
		t.align = ALIGN_LEFT;
		t.pStr = buf;
		t.CharCount = (COUNT)~0;
		SetContextForeGroundColor (PICKSHIP_TEAM_START_VALUE_COLOR);
		font_DrawText (&t);

		assert (CountLinks (&race_q[side]) == 0);

		for (index = 0; index < MELEE_FLEET_SIZE; index++)
		{
			MeleeShip StarShip;

			StarShip = MeleeSetup_getShip (setup, sideI, index);
			if (StarShip == MELEE_NONE)
				continue;

			{
				BYTE row, col;
				BYTE ship_cost;
				HMASTERSHIP hMasterShip;
				HSTARSHIP hBuiltShip;
				MASTER_SHIP_INFO *MasterPtr;
				STARSHIP *BuiltShipPtr;
				BYTE captains_name_index;

				hMasterShip = GetStarShipFromIndex (&master_q, StarShip);
				MasterPtr = LockMasterShip (&master_q, hMasterShip);

				captains_name_index = NameCaptain (&race_q[side],
						MasterPtr->SpeciesID);
				hBuiltShip = Build (&race_q[side], MasterPtr->SpeciesID);

				// Draw the icon.
				row = PickMelee_GetShipRow (index);
				col = PickMelee_GetShipColumn (index);
				s.origin.x = RES_SCALE(4) + ((ICON_WIDTH + RES_SCALE(2)) * col); // JMS_GFX
				s.origin.y = RES_SCALE(10) + ((ICON_HEIGHT + RES_SCALE(2)) * row);
				s.frame = MasterPtr->ShipInfo.icons;
				DrawStamp (&s);

				ship_cost = MasterPtr->ShipInfo.ship_cost;
				UnlockMasterShip (&master_q, hMasterShip);

				BuiltShipPtr = LockStarShip (&race_q[side], hBuiltShip);
				BuiltShipPtr->index = index;
				BuiltShipPtr->ship_cost = ship_cost;
				BuiltShipPtr->playerNr = side;
				BuiltShipPtr->captains_name_index = captains_name_index;
				// The next ones are not used in Melee
				BuiltShipPtr->crew_level = 0;
				BuiltShipPtr->max_crew = 0;
				BuiltShipPtr->race_strings = 0;
				BuiltShipPtr->icons = 0;
				BuiltShipPtr->RaceDescPtr = 0;
				UnlockStarShip (&race_q[side], hBuiltShip);
			}
		}
	}

	SetContext (OldContext);
}
Esempio n. 17
0
// Draw the full restart menu. Nothing is done with selections.
static void
DrawRestartMenuGraphic (MENU_STATE *pMS)
{
	RECT r;
	STAMP s;
	TEXT t;
	UNICODE buf[64];
	COUNT svn_revision = 0; // JMS

	//DC: Load the different menus depending on the resolution factor
	if (resolutionFactor < 1)
		s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM));
	if (resolutionFactor == 1)
		s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM2x));
	if (resolutionFactor > 1)
		s.frame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM4x));

	// Re-load the info box font so the text shows in correct size after changing the resolution.
	if (resFactorWasChanged)
	{	
		DestroyFont (StarConFont);
		
		if (resolutionFactor < 1)
			StarConFont = LoadFont (FALLBACK_TO1X_FONT);
		if (resolutionFactor == 1)
			StarConFont = LoadFont (FALLBACK_TO2X_FONT);
		if (resolutionFactor > 1)
			StarConFont = LoadFont (FALLBACK_TO4X_FONT);
	}
	
	pMS->CurFrame = s.frame;
	GetFrameRect (s.frame, &r);
	s.origin.x = (SCREEN_WIDTH - r.extent.width) >> 1;
	s.origin.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
	
	SetContextBackGroundColor (BLACK_COLOR);
	BatchGraphics ();
	ClearDrawable ();
	FlushColorXForms ();
	LockMutex (GraphicsLock);
	DrawStamp (&s);

	// JMS: Hack for printing out the correct SVN revision number.
	{
		UNICODE svn_buf[64] = {0};
		char *colonPtr;
		
		strcpy(svn_buf, UQMHD_SVN_REVISION);
		colonPtr = strchr(svn_buf, ':');
		
		// The revision number is in format rXXX
		if (colonPtr == NULL)
		{
			// Let's just take the only number and be happy.
			svn_revision = atoi(svn_buf);
		}
		// the revision number is in format rXXX:ZZZ
		else
		{
			// Now we need to extract only the ZZZ number.
			UNICODE svn_buf2[10];
			strcpy(svn_buf2, colonPtr+1);
			svn_revision = atoi(svn_buf2);
		}
		
		// Think about this for a while ;)
		++svn_revision;
	}
	
	// Put the version number in the bottom right corner.
	SetContextFont (TinyFont);
	t.pStr = buf;
	t.baseline.x = SCREEN_WIDTH - 3;
	t.baseline.y = SCREEN_HEIGHT - 2;
	t.align = ALIGN_RIGHT;
	t.CharCount = (COUNT)~0;
	sprintf (buf, "v%d.%d.%d%s - SVN r%d", UQM_MAJOR_VERSION, UQM_MINOR_VERSION, UQM_PATCH_VERSION, UQM_EXTRA_VERSION, svn_revision);
	SetContextForeGroundColor (WHITE_COLOR);
	font_DrawText (&t);

	UnlockMutex (GraphicsLock);
	UnbatchGraphics ();
}
Esempio n. 18
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);
}
Esempio n. 19
0
bool GSRenderer::Merge(int field)
{
	bool en[2];

	GSVector4i fr[2];
	GSVector4i dr[2];

	int baseline = INT_MAX;

	for(int i = 0; i < 2; i++)
	{
		en[i] = IsEnabled(i);

		if(en[i])
		{
			fr[i] = GetFrameRect(i);
			dr[i] = GetDisplayRect(i);

			baseline = min(dr[i].top, baseline);

			//printf("[%d]: %d %d %d %d, %d %d %d %d\n", i, fr[i].x,fr[i].y,fr[i].z,fr[i].w , dr[i].x,dr[i].y,dr[i].z,dr[i].w);
		}
	}

	if(!en[0] && !en[1])
	{
		return false;
	}

	// try to avoid fullscreen blur, could be nice on tv but on a monitor it's like double vision, hurts my eyes (persona 4, guitar hero)
	//
	// NOTE: probably the technique explained in graphtip.pdf (Antialiasing by Supersampling / 4. Reading Odd/Even Scan Lines Separately with the PCRTC then Blending)

	bool samesrc =
		en[0] && en[1] &&
		m_regs->DISP[0].DISPFB.FBP == m_regs->DISP[1].DISPFB.FBP &&
		m_regs->DISP[0].DISPFB.FBW == m_regs->DISP[1].DISPFB.FBW &&
		m_regs->DISP[0].DISPFB.PSM == m_regs->DISP[1].DISPFB.PSM;

	// bool blurdetected = false;

	if(samesrc /*&& m_regs->PMODE.SLBG == 0 && m_regs->PMODE.MMOD == 1 && m_regs->PMODE.ALP == 0x80*/)
	{
		if(fr[0].eq(fr[1] + GSVector4i(0, -1, 0, 0)) && dr[0].eq(dr[1] + GSVector4i(0, 0, 0, 1))
		|| fr[1].eq(fr[0] + GSVector4i(0, -1, 0, 0)) && dr[1].eq(dr[0] + GSVector4i(0, 0, 0, 1)))
		{
			// persona 4:
			//
			// fr[0] = 0 0 640 448
			// fr[1] = 0 1 640 448
			// dr[0] = 159 50 779 498
			// dr[1] = 159 50 779 497
			//
			// second image shifted up by 1 pixel and blended over itself
			//
			// god of war:
			//
			// fr[0] = 0 1 512 448
			// fr[1] = 0 0 512 448
			// dr[0] = 127 50 639 497
			// dr[1] = 127 50 639 498
			//
			// same just the first image shifted

			int top = min(fr[0].top, fr[1].top);
			int bottom = max(dr[0].bottom, dr[1].bottom);

			fr[0].top = top;
			fr[1].top = top;
			dr[0].bottom = bottom;
			dr[1].bottom = bottom;

			// blurdetected = true;
		}
		else if(dr[0].eq(dr[1]) && (fr[0].eq(fr[1] + GSVector4i(0, 1, 0, 1)) || fr[1].eq(fr[0] + GSVector4i(0, 1, 0, 1))))
		{
			// dq5:
			//
			// fr[0] = 0 1 512 445
			// fr[1] = 0 0 512 444
			// dr[0] = 127 50 639 494
			// dr[1] = 127 50 639 494

			int top = min(fr[0].top, fr[1].top);
			int bottom = min(fr[0].bottom, fr[1].bottom);

			fr[0].top = fr[1].top = top;
			fr[0].bottom = fr[1].bottom = bottom;

			// blurdetected = true;
		}
		//printf("samesrc = %d blurdetected = %d\n",samesrc,blurdetected);
	}

	GSVector2i fs(0, 0);
	GSVector2i ds(0, 0);

	GSTexture* tex[2] = {NULL, NULL};

	if(samesrc && fr[0].bottom == fr[1].bottom)
	{
		tex[0] = GetOutput(0);
		tex[1] = tex[0]; // saves one texture fetch
	}
	else
	{
		if(en[0]) tex[0] = GetOutput(0);
		if(en[1]) tex[1] = GetOutput(1);
	}

	GSVector4 src[2];
	GSVector4 dst[2];

	for(int i = 0; i < 2; i++)
	{
		if(!en[i] || !tex[i]) continue;

		GSVector4i r = fr[i];

		// overscan hack

		if(dr[i].height() > 512) // hmm
		{
			int y = GetDeviceSize(i).y;
			if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD) y /= 2;
			r.bottom = r.top + y;
		}

		GSVector4 scale = GSVector4(tex[i]->GetScale()).xyxy();

		src[i] = GSVector4(r) * scale / GSVector4(tex[i]->GetSize()).xyxy();

		GSVector2 o(0, 0);

		if(dr[i].top - baseline >= 4) // 2?
		{
			o.y = tex[i]->GetScale().y * (dr[i].top - baseline);

			if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD)
			{
				o.y /= 2;
			}
		}

		dst[i] = GSVector4(o).xyxy() + scale * GSVector4(r.rsize());

		fs.x = max(fs.x, (int)(dst[i].z + 0.5f));
		fs.y = max(fs.y, (int)(dst[i].w + 0.5f));
	}

	ds = fs;

	if(m_regs->SMODE2.INT && m_regs->SMODE2.FFMD)
	{
		ds.y *= 2;
	}

	bool slbg = m_regs->PMODE.SLBG;
	bool mmod = m_regs->PMODE.MMOD;

	if(tex[0] || tex[1])
	{
		if(tex[0] == tex[1] && !slbg && (src[0] == src[1] & dst[0] == dst[1]).alltrue())
		{
			// the two outputs are identical, skip drawing one of them (the one that is alpha blended)

			tex[0] = NULL;
		}

		GSVector4 c = GSVector4((int)m_regs->BGCOLOR.R, (int)m_regs->BGCOLOR.G, (int)m_regs->BGCOLOR.B, (int)m_regs->PMODE.ALP) / 255;

		m_dev->Merge(tex, src, dst, fs, slbg, mmod, c);

		if(m_regs->SMODE2.INT && m_interlace > 0)
		{
			if (m_interlace == 7 && m_regs->SMODE2.FFMD == 1) // Auto interlace enabled / Odd frame interlace setting
			{
				int field2 = 0;
				int mode = 2;
				m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
			}
			else
			{
				int field2 = 1 - ((m_interlace - 1) & 1);
				int mode = (m_interlace - 1) >> 1;
				m_dev->Interlace(ds, field ^ field2, mode, tex[1] ? tex[1]->GetScale().y : tex[0]->GetScale().y);
			}
		}

		if(m_shadeboost)
		{
			m_dev->ShadeBoost();
		}

		if (m_shaderfx)
		{
			m_dev->ExternalFX();
		}

		if(m_fxaa)
		{
			m_dev->FXAA();
		}
	}

	return true;
}
Esempio n. 20
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;
}
Esempio n. 21
0
void WebEditBox::DrawThisOnly (DISPLAY_INT x, DISPLAY_INT y, WebGraphics *gc)
{
	WebChar c;
	long line;

	WebRect box;
	GetFrameRect(&box);
	box.Shift(x,y);

//	gc->StartBuffer();                      // begin buffering graphics commands
	gc->Rectangle(&box, GetBgColor(gc), GetBgColor(gc), 1);	// draw background
	DrawFrame(&box, gc);

	// save the current graphics context clip rectangle and set clipping to the
	//  text display region of the widget
	GetTextRect(&box);
	box.Shift(x,y);
	WebRect clipSave;
	gc->GetClip(&clipSave);
	if (clipSave.Overlaps(&box))
	{
		WebRect clip(box);
		clip.And(&clipSave);
		gc->SetClip(&clip);

		miXOffset = (mpHScroll)? mpHScroll->GetPosition() : 0;
		miYOffset = (mpVScroll)? mpVScroll->GetPosition() : 0;

		// render our text
		WebFont font = mFont.GetFont();
		if (mpText && font)
		{
			// this loop draws up to the last line
			for (line=0; line<(miNumLines-1); line++)
			{
				c = mpText[GetLineOffset(line+1)];
				mpText[GetLineOffset(line+1)] = 0;
				DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line * WEB_FONT_HEIGHT(font)),
				         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);
				mpText[GetLineOffset(line+1)] = c;
			}

			// now draw the last line of text.
			DrawText(gc, box.left - miXOffset, box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
			         mpText + GetLineOffset(line), GetTextColor(gc), 0, 0, font);

			// if we have the focus, draw the cursor
			if ((mFlags & DISPLAY_FLAG_FOCUS) && !(mFlags & DISPLAY_FLAG_DISABLED))
			{
				// now render the selected portion in reverse video (if we have one)
				if (mEditFlags & EDIT_FLAG_HAS_SELECTION)
				{
					long begin = EBSMIN(miCursorPos, miSelectBegin);
					long end = EBSMAX(miCursorPos, miSelectBegin);
					long beginLine = FindLine(begin), endLine = FindLine(end);
					DISPLAY_INT textLeft;
					long currentBegin, currentEnd;

					for (line=beginLine; line<=endLine; line++)
					{
						currentBegin = EBSMAX(begin, GetLineOffset(line));
						if (line == endLine)
						{
							currentEnd = end;
						}
						else
						{
							currentEnd = EBSMIN(end, GetLineOffset(line+1));
						}
						textLeft = gc->TextWidthLen(mpText + GetLineOffset(line), font, EBSMAX(0, begin - GetLineOffset(line)));

						c = mpText[currentEnd];
						mpText[currentEnd] = 0;
						DrawText(gc, box.left - miXOffset + textLeft,
						             box.top - miYOffset + (line*WEB_FONT_HEIGHT(font)),
						             mpText + currentBegin, GetBgColor(gc), GetSelectColor(gc), 1, font);
						mpText[currentEnd] = c;
					}
				}

				DISPLAY_INT cursorX = box.left - miXOffset +
					gc->TextWidthLen(mpText + GetLineOffset(miCurrentLine), font, miCursorPos - GetLineOffset(miCurrentLine)) ;
				box.Set(cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*miCurrentLine,
				        cursorX, box.top - miYOffset + WEB_FONT_HEIGHT(font)*(miCurrentLine+1));
				gc->Rectangle(&box, GetSelectColor(gc), GetSelectColor(gc), 1);
			}

		}

		gc->SetClip(&clipSave);	 // restore the clip rectangle
	} // if clip overlaps

/*	if (mpVScroll && mpHScroll)
	{
		GetCornerRect(&box);
		box.Shift(x,y);
		gc->Rectangle(&box, LIGHTGRAY, LIGHTGRAY, 1);
	}*/

//	gc->EndBuffer();	     // send all buffered commands to the display

}
Esempio n. 22
0
void
spawn_ion_trail (ELEMENT *ElementPtr)
{
	STARSHIP *StarShipPtr;
	SHIP_INFO *ShipInfoPtr;
	HELEMENT hIonElement;

	assert (ElementPtr->state_flags & PLAYER_SHIP);

	// JMS: Get the pointers to element's owner ship.
	// They are needed to see if the ship's thrust is damaged
	GetElementStarShip (ElementPtr, &StarShipPtr);
	ShipInfoPtr = &StarShipPtr->RaceDescPtr->ship_info;

	hIonElement = AllocElement ();
	if (hIonElement)
	{
#define ION_LIFE 1
		COUNT angle;
		RECT r;
		ELEMENT *IonElementPtr;
		STARSHIP *StarShipPtr;

		GetElementStarShip (ElementPtr, &StarShipPtr);
		angle = FACING_TO_ANGLE (StarShipPtr->ShipFacing) + HALF_CIRCLE;
		GetFrameRect (StarShipPtr->RaceDescPtr->ship_data.ship[0], &r);
		r.extent.height = DISPLAY_TO_WORLD (r.extent.height + r.corner.y);

		InsertElement (hIonElement, GetHeadElement ());
		LockElement (hIonElement, &IonElementPtr);
		IonElementPtr->playerNr = NEUTRAL_PLAYER_NUM;
		IonElementPtr->state_flags = APPEARING | FINITE_LIFE | NONSOLID;
		IonElementPtr->thrust_wait = ION_LIFE;
		IonElementPtr->life_span = IonElementPtr->thrust_wait;
				// When the element "dies", in the death_func
				// 'cycle_ion_trail', it is given new life a number of
				// times, by setting life_span to thrust_wait.
		SetPrimType (&DisplayArray[IonElementPtr->PrimIndex], POINT_PRIM);
		// JMS: Damaged thruster emits differently colored particles
		if (ShipInfoPtr->damage_flags & DAMAGE_THRUST)
		{
			SetPrimColor (&DisplayArray[IonElementPtr->PrimIndex],
				      START_ION_COLOR_DAMAGED);
		}
		else
		{
			SetPrimColor (&DisplayArray[IonElementPtr->PrimIndex],
				      START_ION_COLOR);
		}

		IonElementPtr->colorCycleIndex = 0;
		IonElementPtr->current.image.frame =
				DecFrameIndex (stars_in_space);
		IonElementPtr->current.image.farray = &stars_in_space;
		IonElementPtr->current.location = ElementPtr->current.location;
		IonElementPtr->current.location.x +=
				(COORD)COSINE (angle, r.extent.height);
		IonElementPtr->current.location.y +=
				(COORD)SINE (angle, r.extent.height);
		IonElementPtr->death_func = cycle_ion_trail;

		SetElementStarShip (IonElementPtr, StarShipPtr);

		{
			/* normally done during preprocess, but because
			 * object is being inserted at head rather than
			 * appended after tail it may never get preprocessed.
			 */
			IonElementPtr->next = IonElementPtr->current;
			--IonElementPtr->life_span;
			IonElementPtr->state_flags |= PRE_PROCESS;
		}

		UnlockElement (hIonElement);
	}
}
Esempio n. 23
0
void GSRendererSW::VSync(int field)
{
	Sync(0); // IncAge might delete a cached texture in use

	if(0) if(LOG)
	{
		fprintf(s_fp, "%lld\n", m_perfmon.GetFrame());

		GSVector4i dr = GetDisplayRect();
		GSVector4i fr = GetFrameRect();
		GSVector2i ds = GetDeviceSize();

		fprintf(s_fp, "dr %d %d %d %d, fr %d %d %d %d, ds %d %d\n",
			dr.x, dr.y, dr.z, dr.w,
			fr.x, fr.y, fr.z, fr.w,
			ds.x, ds.y);

		for(int i = 0; i < 2; i++)
		{
			if(i == 0 && !m_regs->PMODE.EN1) continue;
			if(i == 1 && !m_regs->PMODE.EN2) continue;

			fprintf(s_fp, "DISPFB[%d] BP=%05x BW=%d PSM=%d DBX=%d DBY=%d\n", 
				i,
				m_regs->DISP[i].DISPFB.Block(),
				m_regs->DISP[i].DISPFB.FBW,
				m_regs->DISP[i].DISPFB.PSM,
				m_regs->DISP[i].DISPFB.DBX,
				m_regs->DISP[i].DISPFB.DBY
				);

			fprintf(s_fp, "DISPLAY[%d] DX=%d DY=%d DW=%d DH=%d MAGH=%d MAGV=%d\n", 
				i,
				m_regs->DISP[i].DISPLAY.DX,
				m_regs->DISP[i].DISPLAY.DY,
				m_regs->DISP[i].DISPLAY.DW,
				m_regs->DISP[i].DISPLAY.DH,
				m_regs->DISP[i].DISPLAY.MAGH,
				m_regs->DISP[i].DISPLAY.MAGV
				);
		}

		fprintf(s_fp, "PMODE EN1=%d EN2=%d CRTMD=%d MMOD=%d AMOD=%d SLBG=%d ALP=%d\n", 
			m_regs->PMODE.EN1,
			m_regs->PMODE.EN2,
			m_regs->PMODE.CRTMD,
			m_regs->PMODE.MMOD,
			m_regs->PMODE.AMOD,
			m_regs->PMODE.SLBG,
			m_regs->PMODE.ALP
			);

		fprintf(s_fp, "SMODE1 CLKSEL=%d CMOD=%d EX=%d GCONT=%d LC=%d NVCK=%d PCK2=%d PEHS=%d PEVS=%d PHS=%d PRST=%d PVS=%d RC=%d SINT=%d SLCK=%d SLCK2=%d SPML=%d T1248=%d VCKSEL=%d VHP=%d XPCK=%d\n",
			m_regs->SMODE1.CLKSEL,
			m_regs->SMODE1.CMOD,
			m_regs->SMODE1.EX,
			m_regs->SMODE1.GCONT,
			m_regs->SMODE1.LC,
			m_regs->SMODE1.NVCK,
			m_regs->SMODE1.PCK2,
			m_regs->SMODE1.PEHS,
			m_regs->SMODE1.PEVS,
			m_regs->SMODE1.PHS,
			m_regs->SMODE1.PRST,
			m_regs->SMODE1.PVS,
			m_regs->SMODE1.RC,
			m_regs->SMODE1.SINT,
			m_regs->SMODE1.SLCK,
			m_regs->SMODE1.SLCK2,
			m_regs->SMODE1.SPML,
			m_regs->SMODE1.T1248,
			m_regs->SMODE1.VCKSEL,
			m_regs->SMODE1.VHP,
			m_regs->SMODE1.XPCK
			);

		fprintf(s_fp, "SMODE2 INT=%d FFMD=%d DPMS=%d\n", 
			m_regs->SMODE2.INT,
			m_regs->SMODE2.FFMD,
			m_regs->SMODE2.DPMS
			);

		fprintf(s_fp, "SRFSH %08x_%08x\n", 
			m_regs->SRFSH.u32[0],
			m_regs->SRFSH.u32[1]
			);

		fprintf(s_fp, "SYNCH1 %08x_%08x\n", 
			m_regs->SYNCH1.u32[0],
			m_regs->SYNCH1.u32[1]
			);

		fprintf(s_fp, "SYNCH2 %08x_%08x\n", 
			m_regs->SYNCH2.u32[0],
			m_regs->SYNCH2.u32[1]
			);

		fprintf(s_fp, "SYNCV %08x_%08x\n", 
			m_regs->SYNCV.u32[0],
			m_regs->SYNCV.u32[1]
			);

		fprintf(s_fp, "CSR %08x_%08x\n", 
			m_regs->CSR.u32[0],
			m_regs->CSR.u32[1]
			);

		fflush(s_fp);
	}

	/*
	int draw[8], sum = 0;

	for(size_t i = 0; i < countof(draw); i++)
	{
		draw[i] = m_perfmon.CPU(GSPerfMon::WorkerDraw0 + i);
		sum += draw[i];
	}

	printf("CPU %d Sync %d W %d %d %d %d %d %d %d %d (%d)\n",
		m_perfmon.CPU(GSPerfMon::Main),
		m_perfmon.CPU(GSPerfMon::Sync),
		draw[0], draw[1], draw[2], draw[3], draw[4], draw[5], draw[6], draw[7], sum);

	//
	*/

	GSRenderer::VSync(field);

	m_tc->IncAge();

	// if((m_perfmon.GetFrame() & 255) == 0) m_rl->PrintStats();
}
Esempio n. 24
0
void
AbandonShip (ELEMENT *ShipPtr, ELEMENT *TargetPtr,
		COUNT crew_loss)
{
	SIZE dx, dy;
	COUNT direction;
	RECT r;
	STARSHIP *StarShipPtr;
	HELEMENT hCrew;
	INTERSECT_CONTROL ShipIntersect;

	GetElementStarShip (ShipPtr, &StarShipPtr);
	if (StarShipPtr->RaceDescPtr->ship_info.ship_flags & CREW_IMMUNE)
		return;

	ShipIntersect = ShipPtr->IntersectControl;
	GetFrameRect (ShipIntersect.IntersectStamp.frame, &r);

	if ((direction = GetVelocityTravelAngle (
			&ShipPtr->velocity)) == FULL_CIRCLE)
		dx = dy = 0;
	else
	{
#define MORE_THAN_ENOUGH 100
		direction += HALF_CIRCLE;
		dx = COSINE (direction, MORE_THAN_ENOUGH);
		dy = SINE (direction, MORE_THAN_ENOUGH);
	}

	while (crew_loss-- && (hCrew = AllocElement ()))
	{
#define CREW_LIFE 300
		ELEMENT *CrewPtr;

		DeltaCrew (ShipPtr, -1);

		PutElement (hCrew);
		LockElement (hCrew, &CrewPtr);
		CrewPtr->playerNr = NEUTRAL_PLAYER_NUM;
		CrewPtr->hit_points = 1;
		CrewPtr->state_flags = APPEARING | FINITE_LIFE | CREW_OBJECT;
		CrewPtr->life_span = CREW_LIFE;
		SetPrimType (&DisplayArray[CrewPtr->PrimIndex], POINT_PRIM);
		SetPrimColor (&DisplayArray[CrewPtr->PrimIndex],
				BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x00), 0x02));
		CrewPtr->current.image.frame = DecFrameIndex (stars_in_space);
		CrewPtr->current.image.farray = &stars_in_space;
		CrewPtr->preprocess_func = crew_preprocess;
		CrewPtr->collision_func = crew_collision;

		SetElementStarShip (CrewPtr, StarShipPtr);

		GetElementStarShip (TargetPtr, &StarShipPtr);
		CrewPtr->hTarget = StarShipPtr->hShip;

		{
			SIZE w, h;
			INTERSECT_CONTROL CrewIntersect;

			ShipIntersect.IntersectStamp.origin =
					ShipPtr->IntersectControl.EndPoint;

			w = (SIZE)((COUNT)TFB_Random () % r.extent.width);
			h = (SIZE)((COUNT)TFB_Random () % r.extent.height);
			CrewIntersect.EndPoint = ShipIntersect.EndPoint;
			CrewIntersect.IntersectStamp.frame = DecFrameIndex (stars_in_space);
			if (dx == 0 && dy == 0)
			{
				CrewIntersect.EndPoint.x += w - (r.extent.width >> 1);
				CrewIntersect.EndPoint.y += h - (r.extent.height >> 1);
				CrewIntersect.IntersectStamp.origin =
						TargetPtr->IntersectControl.EndPoint;
			}
			else
			{
				if (dx == 0)
					CrewIntersect.EndPoint.x += w - (r.extent.width >> 1);
				else if (dx > 0)
					CrewIntersect.EndPoint.x += w;
				else
					CrewIntersect.EndPoint.x -= w;
				if (dy == 0)
					CrewIntersect.EndPoint.y += h - (r.extent.height >> 1);
				else if (dy > 0)