Ingame Apps

I got the idea for this while trying out the toolgun minigames and I think this would open up quite a lot of possibilities. Unfortunately, I don’t have any spare time to implement this, as I’m working on a different project.


Device BaseDevice

string Name()				the name of the device
string Caption()			the display name of the device
int Version()				interface version (in case this gets extended)
int Width()					horizontal resolution in surface-mode
int Height()							vertical resolution in surface-mode
Catch(bool)								true => catches all user input
										false => player can move and look around
										requires "catch"
player Caught()							returns a caught player or nil
										requires "catch"
vector TracePos()						returns the origin for a trace (SWEPs should use Player:GetShootPos())
										requires "pointer"
vector TraceAng()						returns the angle for a trace (SWEPs should use Player:GetAimVector())
										requires "pointer"
bool ZoomState()						true => zoomed in
										false => pointer mode or animating
										requires "zoom"
bool Zooming()							true => zooming in or out
										false => fixed position
										requires "zoom"
Initialize()							called when the device is created or reset
float RenderWidth						width of the screen in render-mode
										requires "render"
float RenderHeight						height of the screen in render-mode
										requires "render"
vector VolumetricSize()					the size of the larges cuboid that fits into the render-volume
										requires "volumetric"
Add(app)								adds an app to the device
Remove(app)								removes an app from the device
Switch(app)								switches to an app if it is installed
Zoom(bool)								true => zoom in
										false => pointer mode
										doesn't work if zooming
										requires "zoom"
SetRenderMode(bool)						true => draw using the render library, deactivate other modes
										false => draw on surface (like toolgun)
										requires "render"
bool RenderMode()						true => drawing using the render library
										false => drawing on surface (like toolgun)
										requires "render"
SetVolumetricMode(bool)					true => draw in render volume, deactivate other modes
										false => don't draw in render volume
										requires "volumetric"
bool VolumetricMode()					true => drawing in render volume
										false => not drawing in render volume
										requires "volumetric"
App Menu()								the app representing the menu
										requires "menu"
SetMenu(App)							registers an installed app as the menu
										requires "menu"
Click(invoker, float posX, float posY)	clicks on the screen
										the position is relative to the center of the screen or render-volume
										the units are share of Width() and Height() or share of RenderWidth() and RenderHeight(), respectively, depending on mode (usually ranging from -0.5 to 0.5)
										requires "click"
Click(invoker, vector pos, vector ang)	clicks on the screen
										the position is relative to the center of the screen, or, in volumetric mode, relative to the center of the assured render-volume
										the position units are share of Width() and Height(), share of RenderWidth() and RenderHeight() or share of the values in VolumetricSize(), respectively, depending on mode
										requires "click3D"
vector GetCursor()						returns the position of the cursor or nil
										requires "cursor"
table:string Flags()					defines device flags indicating non standard behavior or features (as defined for each version)
										flags:				shade => can display color shades
															color => can display colors (usually used with "mono")
															render => supports render-mode
															passive => screen requires external light source (see above)
															click => can be clicked
															world => app is rendered on world model
															zoom => can zoom
															catch => can catch user input (for portable devices, seats and vehicles)
															pointer => can be pointed at something
															menu => supports a menu for choosing an app
															click3D => supports clicking with additional data
															cursor => supports a cursor
															volumetric => supports volumetric rendering
Notes:

Non standard behavior should be implemented in the device. Apps are not supposed to limit the display colors if there's a "mono"-tag. Use a shader instead.
Each Pixel in surface-mode should be a square.
If you're creating a device supporting render mode don't forget to push a clip plane and/or a model matrix if necessary (and don't forget shearing).
A device in render-mode should mask the players screen space.
The app's Draw()- and Render()-functions should only be called if the device really displays the output. Consider checking for visibility when the screen is a world model.
Initialize() should do a full reset and remove all apps.
Add() and Remove() should notify the app and must create a new (and unique) reference.
Each app must be switched to in surface-mode.
RenderWidth and RenderHeight indicate the largest rectangle visible in render-mode. At least one of these should be 1.0 unless the screen isn't a rectangle.
The device is supposed to do all the initialisation so the app only needs to call surface.draw() etc.
The device really should support render-mode unless it's some cheap RP stuff.
Switching to an app doesn't imply calling OnActivate() (unless the device is used at the moment or it's a world model with a screen).
SetMenu() must check if the app defines "menu".
When Initialize() is called, the caller should add an app and switch to it.
Holding reload a few seconds should reset the active app and switch to the menu after some more time. If this is not possible, there should be other means of resetting (like a button on the back of a screen).
All vectors use local coordinates.
A device in render-mode should use the stencil buffer to limit the screen space, one in volumetric-mode should use clip planes.
All methods should be defined in the base device, along with a short desription, and should throw exceptions when called there.
The device shouldn't implement error handling for missing functions.


App BaseApp

string Name()										the name of the app (must be unique)
string Caption()									the display name of the app
int Version()										interface version (in case this gets extended)
Initialize()										called when the app instance is created or the app is reset
AddReference(entity)								adds a reference
RemoveReference(entity)								removes a reference
OnAdd(device)										called when the app is added to a device
OnRemove(device)									called when the app is removed from a device
OnActivate(device)									called when the app is displayed on a device
OnDeactivate(device)								called when the app isn't displayed anymore
Draw()												used for drawing in surface-mode
Render()											used for drawing in render-mode
													requires "render"
RenderVolume()										used for drawing in volumetric-mode
													requires "volumetric"
OnClick(device, invoker, float posX, float posY)	called when someone or something clicks
													requires "click"
OnClick3D(device, invoker, vector pos, vector ang)	called when someone or something clicks
													requires "click3D"
table:string flags()								defines app flags indicating non standard behavior or features (as defined for each version)
													flags:				menu => app can be used as menu
																		click => app can receive clicks
																		render => app uses render-mode
																		click3D => app can receive 3D clicks
																		volumetric => app uses volumetric mode
Notes:
Initialize() is called only once when the app instance is created. Transferring an initialized app shouldn't call it again (unless explicitly wanted).
Initialize should do a full reset.
The app should support being added to more than one entity. It is possible that one entity supports render-mode, while another doesn't.
The app should at least display an error message in the Draw()-function when in render-mode.
RemoveReference() should remove the app if the last reference is removed.
If the app requires a special feature, it should look it up first and then display a descriptive error message if it isn't available. If the feature is not essential, the app should do nothing.
If you want to trace something then you should use the pointer function of the device.
Don't assume the invoker in OnClick() is a player.
All methods should be defined in the base app, along with a short desription, and should throw exceptions when called there.
The app shouldn't implement error handling for missing functions.

This is basically an interface for devices and apps running on them.

Features:

  • Modular: You can use the same app on a remote control, screen or vehicle.
  • Perfect for rendering camera inputs: In render-mode this shouldn’t have any visible pixelation at all.
  • Supports this:

http://images.absoluteastronomy.com/images/encyclopediaimages/l/la/laser_plasma_volumetric_display.jpg

(with better graphics and without setting the air on fire)

Possible uses:

  • Configuring an entity without breaking immersion or wiring it up
  • a remote control with video support
  • a shooting range
  • a spaceship navigation system

The base entitys should only implement stuff working without a model like switching, adding and removing apps.