You can use the values for cl_leveloverview to determine how to transform world coordinates into screen coordinates.
Overview: scale 8.40, pos_x -7516, pos_y 4299
Here's some pseudocode for how I implemented it:
Point world = new Point(playerX, playerY);
int pos_X = -7516;
int pos_Y = 4299;
double scale = 8.4;
double height = 1024 * scale; // 1024 is a magic number straight from cl_leveloverview code
double originalWidth = height * (16.0 / 9.0); // aspect ratio of your screen when you took the screenshot
double width = height * (MapImage.RenderWidth / MapImage.RenderHeight);
var centerWorld = new Point(pos_X + (originalWidth / 2), pos_Y - (height / 2));
var topLeftWorld = new Point(centerWorld.X - (width / 2), centerWorld.Y + (height / 2));
var bottomRightWorld = new Point(topLeftWorld.X + width, topLeftWorld.Y - height);
return new Point(
Rescale(0, MapImage.RenderWidth, topLeftWorld.X, bottomRightWorld.X, world.X),
Rescale(0, MapImage.RenderHeight, topLeftWorld.Y, bottomRightWorld.Y, world.Y));
Bonus C#:
public static double Lerp(double param1, double param2, double x)
{
return (param1 + (param2 - param1) * x);
}
// Interpolates linearly from a to b as t goes from x to y.
public static double Rescale(double a, double b, double x, double y, double t)
{
return Lerp(a, b, (t - x) / (y - x));
}
If you're interested, here's the actual code that drives cl_leveloverview:
void CViewRender::SetUpOverView()
{
static int oldCRC = 0;
m_View.m_bOrtho = true;
float aspect = (float)m_View.width/(float)m_View.height;
int size_y = 1024.0f * cl_leveloverview.GetFloat(); // scale factor, 1024 = OVERVIEW_MAP_SIZE
int size_x = size_y * aspect; // standard screen aspect
m_View.origin.x -= size_x / 2;
m_View.origin.y += size_y / 2;
m_View.m_OrthoLeft = 0;
m_View.m_OrthoTop = -size_y;
m_View.m_OrthoRight = size_x;
m_View.m_OrthoBottom = 0;
m_View.angles = QAngle( 90, 90, 0 );
// simple movement detector, show position if moved
int newCRC = m_View.origin.x + m_View.origin.y + m_View.origin.z;
if ( newCRC != oldCRC )
{
Msg( "Overview: scale %.2f, pos_x %.0f, pos_y %.0f\n", cl_leveloverview.GetFloat(),
m_View.origin.x, m_View.origin.y );
oldCRC = newCRC;
}
CMatRenderContextPtr pRenderContext( materials );
pRenderContext->ClearColor4ub( 0, 255, 0, 255 );
// render->DrawTopView( true );
}
EDIT: I really like how code tags don't work inside of spoiler tags