HUD map

What do you want to see in Armagetron soon? Any new feature ideas? Let's ponder these ground breaking ideas...
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

HUD map

Post by Jonathan »

Here it is. :D

Code: Select all

#define DONTDOIT
#include "rRender.h"
#include "gWall.h"
#include "gCycle.h"
#include "eAdvWall.h"
#include "eRectangle.h"
#include "eTimer.h"
#include "ePlayer.h"

extern tList<gNetPlayerWall> gridded_sg_netPlayerWalls;

static void DrawRimWalls(tList<eWallRim> &list) {
	glColor4f(1, 1, 1, .5);
	glBegin(GL_LINES);
	unsigned i, len=list.Len();
	for(i=0; i<len; i++) {
		eWallRim *wall = list[i];
		const eCoord &begin = wall->EndPoint(0), &end = wall->EndPoint(1);
		glVertex2f(begin.x, begin.y);
		glVertex2f(end.x, end.y);
	}
	glEnd();
}

static void DrawWalls(tList<gNetPlayerWall> &list) {
	unsigned i, len=list.Len();
	double currentTime = se_GameTime();
	double wallsLength = gCycle::WallsLength();
	double wallsStayUpDelay = gCycle::WallsStayUpDelay();
	bool limitedLength = wallsLength > 0;
	glBegin(GL_LINES);
	for(i=0; i<len; i++) {
		gNetPlayerWall *wall = list[i];
		gCycle *cycle = wall->Cycle();
		if(!cycle) continue;
		double alpha = 1;
		if(!cycle->Alive()) {
			alpha -= 2 * (currentTime - cycle->DeathTime() - wallsStayUpDelay);
			if(alpha <= 0) continue;
		}
		glColor4f(cycle->color_.r, cycle->color_.g, cycle->color_.b, alpha);
		double cycleDist = cycle->GetDistance();
		double minDist = limitedLength && cycleDist > wallsLength ? cycleDist - wallsLength : 0;
		const eCoord &begPos = wall->EndPoint(0), &endPos = wall->EndPoint(1);
		tArray<gPlayerWallCoord> &coords = wall->Coords();
		double begDist = wall->BegPos();
		double lenDist = wall->EndPos() - begDist;
		unsigned j, numcoords = coords.Len();
		if(numcoords < 2) continue;
		bool prevDangerous = coords[0].IsDangerous;
		double prevDist = coords[0].Pos;
		if(prevDist < minDist) prevDist = minDist;
		prevDist = (prevDist - begDist) / lenDist;
		for(j=1; j<numcoords; j++) {
			bool curDangerous = coords[j].IsDangerous;
			double curDist = coords[j].Pos;
			if(curDist < minDist) curDist = minDist;
			curDist = (curDist - begDist) / lenDist;
			glVertex2f((1 - prevDist) * begPos.x + prevDist * endPos.x, (1 - prevDist) * begPos.y + prevDist * endPos.y);
			glVertex2f((1 - curDist) * begPos.x + curDist * endPos.x, (1 - curDist) * begPos.y + curDist * endPos.y);
			prevDangerous = curDangerous;
			prevDist = curDist;
		}
	}
	glEnd();
}

static void DrawCycles(tList<ePlayerNetID> &list, double xscale, double yscale) {
	unsigned i, len=list.Len();
	double currentTime = se_GameTime();
	for(i=0; i<len; i++) {
		const gCycle *cycle = dynamic_cast<gCycle *>(list[i]->Object());
		if(cycle) {
			double alpha = 1;
			if(!cycle->Alive()) {
				alpha -= 2 * (currentTime - cycle->DeathTime());
				if(alpha <= 0) continue;
			}
			glColor4f(cycle->color_.r, cycle->color_.g, cycle->color_.b, alpha);
			eCoord pos = cycle->Position(), dir = cycle->Direction();
			glPushMatrix();
			GLfloat m[16] = {
				xscale * dir.x, yscale * dir.y, 0, 0,
				-xscale * dir.y, yscale * dir.x, 0, 0,
				0, 0, 1, 0,
				pos.x, pos.y, 0, 1
			};
			glMultMatrixf(m);
			glBegin(GL_TRIANGLES);
			glVertex2f(.5, 0);
			glVertex2f(-.5, .5);
			glVertex2f(-.5, -.5);
			glEnd();
			glPopMatrix();
		}
	}
}

/*
 * rimWalls    draw rim walls?
 * cycleWalls  draw cycle walls?
 * cycles      draw cycles?
 * cycleSize   size of cycles in real-world units
 * border      border around bounds
 * x y w h     the map will always fit in this rectangle
 * rw rh       width and height of the rectangle in real-world units
 * ix iy       position where inside?
 */
void DrawMap(bool rimWalls, bool cycleWalls, bool cycles,
			 double cycleSize, double border,
			 double x, double y, double w, double h,
			 double rw, double rh, double ix, double iy) {
	if(!rimWalls && !cycleWalls && !cycles) return;
	const eRectangle &bounds = eWallRim::GetBounds();
	double lx = bounds.GetLow().x - border, hx = bounds.GetHigh().x + border;
	double ly = bounds.GetLow().y - border, hy = bounds.GetHigh().y + border;
	double mw = hx - lx, mh = hy - ly;
	double xpos, ypos, xscale, yscale;
	double xrat = (rw * mh) / (rh * mw);
	double yrat = (rh * mw) / (rw * mh);
	if(xrat > yrat) {
		xscale = (w * rh) / (mh * rw);
		yscale = h / mh;
		xpos = x + ix * (w - w * yrat);
		ypos = y;
	} else {
		xscale = w / mw;
		yscale = (h * rw) / (mw * rh);
		xpos = x;
		ypos = y + iy * (h - h * xrat);
	}
	glPushMatrix();
	GLfloat m[16] = {
		xscale, 0, 0, 0,
		0, yscale, 0, 0,
		0, 0, 1, 0,
		xpos - xscale * lx, ypos - yscale * ly, 0, 1
	};
	glMultMatrixf(m);
	if(rimWalls)
		DrawRimWalls(se_rimWalls);
	if(cycleWalls) {
		DrawWalls(gridded_sg_netPlayerWalls);
		DrawWalls(sg_netPlayerWalls);
	}
	if(cycles)
		DrawCycles(se_PlayerNetIDs, (cycleSize * w) / (rw * xscale), (cycleSize * h) / (rh * yscale));
	glPopMatrix();
}
This one doesn't have headlights (it was fun on the other map, but it's a map) or much testing, but it does have easy positioning. I recommend that you call it with the modelview matrix selected.

PS. I tend to use doubles all over the place. floats should be fine.
ˌɑrməˈɡɛˌtrɑn
User avatar
dlh
Formerly That OS X Guy
Posts: 2035
Joined: Fri Jan 02, 2004 12:05 am
Contact:

Post by dlh »

Checking it out now. Edit to come soon.
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Try calling it like

Code: Select all

DrawMap(true, true, true,
       5.5, 10,
       .5, -1, .5, .5 * (w / h),
       .25 * w, .25 * w, 1, 0);
if your viewport is of size (w, h) and the range is [-1, 1] in both dimensions.
ˌɑrməˈɡɛˌtrɑn
User avatar
dlh
Formerly That OS X Guy
Posts: 2035
Joined: Fri Jan 02, 2004 12:05 am
Contact:

Post by dlh »

Could you just upload it as a file (or diff)? The <code> tags have inserted lots of invisible characters that are causing errors.

Edit: And what is DONTDOIT? Should we be doing it?
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Ask z-man about DONTDOIT. If you don't define it you can't use glBegin, glEnd and glMatrixMode directly. See rRender.h.
Attachments
rMap.cpp.gz
Is rMap a good name?
(1.55 KiB) Downloaded 209 times
ˌɑrməˈɡɛˌtrɑn
User avatar
Z-Man
God & Project Admin
Posts: 11710
Joined: Sun Jan 23, 2005 6:01 pm
Location: Cologne
Contact:

Post by Z-Man »

Uhh, that DONTDOIT thing was not supposed to be left lying around. It was part of the attempt to get rid of all explicit OpenGL calls in the code and use the rRender.h stuff instead. DONTDOIT was intended to ease the transitional period where some files still used pure OpenGL. What can I say, I got bored in the middle of it, so it's still there. I'll rename it to ALLOW_OPENGL.
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Forgot to mention, you need to add this to gNetPlayerWall:

Code: Select all

tArray<gPlayerWallCoord> &Coords() { return coords_; }
ˌɑrməˈɡɛˌtrɑn
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

So how do you actually make it work? Patches anyone? :?

Jon, I'm assuming you're using CVS code for this?

Code: Select all

cvs diff -u
:)
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Luke-Jr wrote:So how do you actually make it work? Patches anyone? :?
Call my function from the HUD?
Jon, I'm assuming you're using CVS code for this?

Code: Select all

cvs diff -u
:)
That isn't going to help as I added it to a simple HUD replacement. I could code another HUD that only draws the map as an example. It should be easy to add to the gHud (which needs a bit more than a single function call: it needs width and height), but I don't feel like it.
ˌɑrməˈɡɛˌtrɑn
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

Jonathan wrote:
Luke-Jr wrote:So how do you actually make it work? Patches anyone? :?
Call my function from the HUD?
Doesn't do anything... I put this at the bottom of display_hud_subby_all

Code: Select all

DrawMap(true, true, true, 2, 0, 0, 0, 500, 500, 500, 500, 250, 250);
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Luke-Jr wrote:

Code: Select all

DrawMap(true, true, true, 2, 0, 0, 0, 500, 500, 500, 500, 250, 250);
Next time call it with sane input. :)

Code: Select all

/*
 * rimWalls    draw rim walls?
 * cycleWalls  draw cycle walls?
 * cycles      draw cycles?
 * cycleSize   size of cycles in real-world units
 * border      border around bounds (in grid units)
 * x y w h     the map will always fit in this rectangle (in OpenGL units)
 * rw rh       width and height of the rectangle in real-world units
 * ix iy       position where inside? (range [0, 1], used if there's room left due to nonmatching aspect ratio)
 */
ˌɑrməˈɡɛˌtrɑn
Luke-Jr
Dr Z Level
Posts: 2246
Joined: Sun Mar 20, 2005 4:03 pm
Location: IM: luke@dashjr.org

Post by Luke-Jr »

Jonathan wrote:
Luke-Jr wrote:

Code: Select all

DrawMap(true, true, true, 2, 0, 0, 0, 500, 500, 500, 500, 250, 250);
Next time call it with sane input. :)
Looks sane to me.
Jonathan wrote:

Code: Select all

/*
 * rimWalls    draw rim walls?
 * cycleWalls  draw cycle walls?
 * cycles      draw cycles?
 * cycleSize   size of cycles in real-world units
 * border      border around bounds (in grid units)
 * x y w h     the map will always fit in this rectangle (in OpenGL units)
 * rw rh       width and height of the rectangle in real-world units
 * ix iy       position where inside? (range [0, 1], used if there's room left due to nonmatching aspect ratio)
 */
WTF is a so-called "real-world unit"? Inches? Centimetres???
How about OpenGL units?
"position where inside"-- huh???
The comments tell me nothing useful past the booleans...
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Luke-Jr wrote:WTF is a so-called "real-world unit"? Inches? Centimetres???
Whatever you want, as long as you use the same unit everywhere. Could be pixels. It's meant to get correct aspect ratios.
How about OpenGL units?
Depends on the current matrices. With the identity matrix, the bottom left corner is at (-1, -1), and the top right at (1, 1).
"position where inside"-- huh???
Indeed not a good description. If width/height of the box in which it is allowed to be drawn is greater than width/height of the map, and the map is scaled to fit, there's room left horizontally. If so, ix (ranging [0, 1]) specifies where it is positioned horizontally.
ˌɑrməˈɡɛˌtrɑn
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Try

Code: Select all

#define DONTDOIT
#include "rRender.h"
#include "rScreen.h"
#include "tConfiguration.h"

void DrawMap(bool rimWalls, bool cycleWalls, bool cycles,
             double cycleSize, double border,
             double x, double y, double w, double h,
             double rw, double rh, double ix, double iy);

static int simplemapmode = 0;
static tConfItem<int> simplemapmode_con("SIMPLE_MAP", simplemapmode);

static void drawsimplemap() {
	// I haven't checked possible initial matrix state, so init to identity and modelview
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	if(simplemapmode & 1)
		DrawMap(true, true, true,
		        5.5, 10,
		        .5, -1, .5, .5 * sr_screenWidth / sr_screenHeight,
		        .25 * sr_screenWidth, .25 * sr_screenWidth, 1, 0);
	if(simplemapmode & 2)
		DrawMap(true, true, true,
		        5.5, 10,
		        -1, -1, 2, 2,
		        sr_screenWidth, sr_screenHeight, .5, .5);
}

static rPerFrameTask simplemaptask(&drawsimplemap);
Mode 1 draws it in the square box in the bottom right that has sides of 1/4th screen width. Mode 2 draws it centered on your screen.

Edit: Changed to bitmask for more fun.
ˌɑrməˈɡɛˌtrɑn
User avatar
Jonathan
A Brave Victim
Posts: 3391
Joined: Thu Feb 03, 2005 12:50 am
Location: Not really lurking anymore

Post by Jonathan »

Screenshot
Attachments
twomaps.png
ˌɑrməˈɡɛˌtrɑn
Post Reply