示例#1
0
void ConfigureFOV()
{
	static const double default_ratio = 4.0 / 3.0;
	const uint32_t width = HorizontalResolution;
	const uint32_t height = VerticalResolution;

	WriteJump(SetupScreen, SetupScreenFix);

	// Taking advantage of a nullsub call.
	WriteCall((void*)0x00513A88, DisplayVideoFrame_FixAspectRatio);

	// 4:3 and "tallscreen" (5:4, portrait, etc)
	// We don't need to do anything since these resolutions work fine with the default code.
	if ((height * default_ratio) == width || (height * default_ratio) > width)
		return;

	fov_rads = 0.96712852;	// 55.412382 degrees
	fov_bams = NJM_RAD_ANG(fov_rads);

	// Function hooks
	WriteJump(njSetPerspective, njSetPerspective_hook);
	WriteJump(njSetScreenDist, njSetScreenDist_hook);

	// Code patches
	WriteJump((void*)0x0079124A, SetFOV);
	WriteData((float**)0x00781525, &dummy); // Dirty hack to disable a write to ClippingRelated and keep the floating point stack balanced.
	WriteData((Angle**)0x0040872B, &last_bams); // Fixes a case of direct access to HorizontalFOV_BAMS
	WriteData((Angle**)0x00402F01, &last_bams); // Changes return value of GetHorizontalFOV_BAMS

	njSetPerspective_hook(bams_default);

	// Stops the Pause Menu from using horizontal stretch in place of vertical stretch in coordinate calculation
	// Main Pause Menu
	WriteData((float**)0x00457F69, &VerticalStretch); // Elipse/Oval
	WriteData((float**)0x004584EE, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x0045802F, &VerticalStretch); // Pause Menu Options
	// Camera options
	WriteData((float**)0x00458D5C, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x00458DF4, &VerticalStretch); // Auto Cam
	WriteData((float**)0x00458E3A, &VerticalStretch); // Free Cam
	// Controls
	WriteData((float**)0x0045905A, &VerticalStretch); // Blue Transparent Box
	WriteData((float**)0x004590BB, &VerticalStretch); // Each Control Element
	WriteData((float**)0x00459133, &VerticalStretch); // Default Button
}
示例#2
0
static void DrawElement(Uint32 playerIndex, Uint32 textureIndex)
{
	EntityData1* player = CharObj1Ptrs[playerIndex];

	if (player == nullptr)
		return;

	Uint8 charid = MetalSonicFlag && player->CharID == Characters_Sonic ? Characters_MetalSonic : player->CharID;
	NJS_SPRITE* sp = &sprites[playerIndex];
	NJS_POINT2 projected;
	NJS_VECTOR pos = player->Position;
	pos.y += PhysicsArray[charid].CollisionSize;

	njProjectScreen(nullptr, &pos, &projected);

	sp->p = { projected.x, projected.y - (sp->tanim[0].sy + sp->tanim[1].sy), 0.0f };

	bool isVisible =
		sp->p.x < MARGIN_RIGHT &&
		sp->p.x > MARGIN_LEFT &&
		sp->p.y < MARGIN_BOTTOM &&
		sp->p.y > MARGIN_TOP;

	ClampToScreen(sp->p);
	int flags = NJD_SPRITE_COLOR | NJD_SPRITE_ALPHA;
	sp->ang = 0;

	if (textureIndex == arrow)
	{
		if (!isVisible)
		{
			flags |= NJD_SPRITE_ANGLE;
			sp->ang = NJM_RAD_ANG(GetAngle((NJS_POINT2*)&sp->p, &projected)) - 0x4000;
		}

		// TODO: Ellipse rotation around player number
		sp->tanim[arrow].cy = Indicator_TEXANIM[arrow].cy - ((isVisible) ? 0 : 12);
	}
	
	SetSpriteColor(IsControllerEnabled((Uint8)playerIndex) ? &colors[charid] : &colors[9]);
	Draw2DSprite(sp, textureIndex, -1.0f, flags, 0);
}