emp_atomic, also chris0132's fabulous blog.

Discussion in 'Mapping' started by Chris0132', Jan 31, 2011.

Thread Status:
Not open for further replies.
  1. MOOtant

    MOOtant Member

    Messages:
    4,047
    Likes Received:
    0
    Trophy Points:
    0
    If you can get any kind of sphere exported from 3ds and compiled, it should work (takes 5 minutes). Here's shader code:

    VS:
    Code:
    //	STATIC: "MODEL"					"0..1"
    
    //	DYNAMIC: "COMPRESSED_VERTS"		"0..1"
    //	DYNAMIC: "SKINNING"				"0..1"
    
    #include "common_vs_fxc.h"
    
    static const bool g_bSkinning		= SKINNING ? true : false;
    static const bool g_bModel			= MODEL ? true : false;
    
    const float4 cBumpTexCoordTransform[2]	:  register( SHADER_SPECIFIC_CONST_1 );
    
    struct VS_INPUT
    {
    	float4 vPos							: POSITION;
    	float4 vBoneWeights					: BLENDWEIGHT;
    	float4 vBoneIndices					: BLENDINDICES;
    	float4 vNormal						: NORMAL;
    	float4 vBaseTexCoord				: TEXCOORD0;
    #if !MODEL
    	float3 vTangentS					: TANGENT;
    	float3 vTangentT					: BINORMAL0;
    #else
    	float4 vUserData					: TANGENT;
    #endif
    };
    
    struct VS_OUTPUT
    {
        float4 vProjPos_POSITION		: POSITION;	
    	float  vFog						: FOG;
    	float2 vBumpTexCoord			: TEXCOORD0;
    	float3 vTangentEyeVect			: TEXCOORD1;
    	float3x3 tangentSpaceTranspose	: TEXCOORD2;
    	float3 vRefractXYW				: TEXCOORD5;
    	float4 projNormal_screenCoordW	: TEXCOORD6;
    	float4 worldPos_projPosZ		: TEXCOORD7;
    	float4 fogFactorW				: COLOR1;
    };
    
    VS_OUTPUT main( const VS_INPUT v )
    {
    	VS_OUTPUT o = ( VS_OUTPUT )0;
    
    	float3 worldNormal, worldPos, worldTangentS, worldTangentT;
    
    	float3 vObjNormal;
    #if MODEL
    	float4 vObjTangent;
    	DecompressVertex_NormalTangent( v.vNormal, v.vUserData, vObjNormal, vObjTangent );
    
    	SkinPositionNormalAndTangentSpace( 
    			g_bSkinning, 
    			v.vPos, vObjNormal, vObjTangent,
    			v.vBoneWeights, v.vBoneIndices,
    			worldPos, worldNormal, worldTangentS, worldTangentT );
    #else
    	DecompressVertex_Normal( v.vNormal, vObjNormal );
    
    	worldPos = mul( v.vPos, cModel[0] );
    	worldTangentS = mul( v.vTangentS, ( const float3x3 )cModel[0] );
    	worldTangentT = mul( v.vTangentT, ( const float3x3 )cModel[0] );
    	worldNormal = mul( vObjNormal, ( float3x3 )cModel[0] );
    #endif
    
    
    	// Projected position
    	float4 vProjPos = mul( float4( worldPos, 1 ), cViewProj );
    	o.vProjPos_POSITION = vProjPos;
    	o.projNormal_screenCoordW.xyz = mul( worldNormal, cViewProj );
    	
    	o.worldPos_projPosZ = float4( worldPos.xyz, vProjPos.z );
    
    	// Map projected position to the refraction texture
    	float2 vRefractPos;
    	vRefractPos.x = vProjPos.x;
    	vRefractPos.y = -vProjPos.y; // invert Y
    	vRefractPos = (vRefractPos + vProjPos.w) * 0.5f;
    
    	// Refraction transform
    	o.vRefractXYW = float3(vRefractPos.x, vRefractPos.y, vProjPos.w);
    
    	// Compute fog based on the position
    	float3 vWorldPos = mul( v.vPos, cModel[0] );
    	o.fogFactorW = o.vFog = CalcFog( vWorldPos, vProjPos, FOGTYPE_RANGE );
    
    	// Eye vector
    	float3 vWorldEyeVect = cEyePos - vWorldPos;
    	// Transform to the tangent space
    	o.vTangentEyeVect.x = dot( vWorldEyeVect, worldTangentS );
    	o.vTangentEyeVect.y = dot( vWorldEyeVect, worldTangentT );
    	o.vTangentEyeVect.z = dot( vWorldEyeVect, worldNormal );
    
    	// Tranform bump coordinates
    	o.vBumpTexCoord.x = dot( v.vBaseTexCoord, cBumpTexCoordTransform[0] );
    	o.vBumpTexCoord.y = dot( v.vBaseTexCoord, cBumpTexCoordTransform[1] );
    
    	o.tangentSpaceTranspose[0] = worldTangentS;
    	o.tangentSpaceTranspose[1] = worldTangentT;
    	o.tangentSpaceTranspose[2] = worldNormal;
    
    	return o;
    }
    
     
  2. MOOtant

    MOOtant Member

    Messages:
    4,047
    Likes Received:
    0
    Trophy Points:
    0
    PS:

    Code:
    //====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
    //
    // Purpose: 
    //
    //=============================================================================
    
    // STATIC: "CONVERT_TO_SRGB"		"0..1"	[ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
    // STATIC: "CONVERT_TO_SRGB"		"0..0"	[= 0] [XBOX]
    // STATIC: "CUBEMAP"				"0..1"
    // STATIC: "FLOWMAP"				"0..1"
    // STATIC: "CORECOLORTEXTURE"		"0..1"
    // STATIC: "REFRACT"				"0..1"
    // DYNAMIC: "PIXELFOGTYPE"			"0..1"
    
    // SKIP: ( $REFRACT || $CORECOLORTEXTURE ) && $CUBEMAP
    
    #include "common_ps_fxc.h"
    
    sampler RefractSampler	: register( s2 );
    sampler NormalSampler	: register( s3 );
    #if CUBEMAP
    sampler EnvmapSampler			: register( s4 );
    #endif
    #if FLOWMAP
    sampler FlowmapSampler			: register( s6 );
    #endif
    
    #if CORECOLORTEXTURE
    sampler CoreColorSampler			: register( s7 );
    #endif
    
    const HALF3 g_EnvmapTint			: register( c0 );
    const HALF3 g_RefractTint : register( c1 );
    const HALF3 g_EnvmapContrast		: register( c2 );
    const HALF3 g_EnvmapSaturation		: register( c3 );
    const HALF2  g_RefractScale : register( c5 );
    #if FLOWMAP
    const float g_Time								: register( c6 );
    const float2 g_FlowScrollRate	: register( c7 );
    //const float3 g_SphereCenter		: register( c9 );
    //const float3 g_SphereRadius		: register( c10 );
    const float g_CoreColorTexCoordOffset : register( c9 );
    #endif
    
    const float3 g_EyePos			: register( c8 );
    const float4 g_FogParams		: register( c11 );
    
    float LengthThroughSphere( float3 vecRayOrigin, float3 vecRayDelta, 
    						  float3 vecSphereCenter, float flRadius, out float alpha )
    {
    	// Solve using the ray equation + the sphere equation
    	// P = o + dt
    	// (x - xc)^2 + (y - yc)^2 + (z - zc)^2 = r^2
    	// (ox + dx * t - xc)^2 + (oy + dy * t - yc)^2 + (oz + dz * t - zc)^2 = r^2
    	// (ox - xc)^2 + 2 * (ox-xc) * dx * t + dx^2 * t^2 +
    	//		(oy - yc)^2 + 2 * (oy-yc) * dy * t + dy^2 * t^2 +
    	//		(oz - zc)^2 + 2 * (oz-zc) * dz * t + dz^2 * t^2 = r^2
    	// (dx^2 + dy^2 + dz^2) * t^2 + 2 * ((ox-xc)dx + (oy-yc)dy + (oz-zc)dz) t +
    	//		(ox-xc)^2 + (oy-yc)^2 + (oz-zc)^2 - r^2 = 0
    	// or, t = (-b +/- sqrt( b^2 - 4ac)) / 2a
    	// a = DotProduct( vecRayDelta, vecRayDelta );
    	// b = 2 * DotProduct( vecRayOrigin - vecCenter, vecRayDelta )
    	// c = DotProduct(vecRayOrigin - vecCenter, vecRayOrigin - vecCenter) - flRadius * flRadius;
    
    	float3 vecSphereToRay;
    	vecSphereToRay = vecRayOrigin - vecSphereCenter;
    
    	float a = dot( vecRayDelta, vecRayDelta );
    
    	// This would occur in the case of a zero-length ray
    	//	if ( a == 0.0f )
    	//	{
    	//		*pT1 = *pT2 = 0.0f;
    	//		return vecSphereToRay.LengthSqr() <= flRadius * flRadius;
    	//	}
    
    	float b = 2 * dot( vecSphereToRay, vecRayDelta );
    	float c = dot( vecSphereToRay, vecSphereToRay ) - flRadius * flRadius;
    	float flDiscrim = b * b - 4 * a * c;
    	//	if ( flDiscrim < 0.0f )
    	//		return 0.0f;
    
    	float hack = flDiscrim;
    	flDiscrim = sqrt( flDiscrim );
    	float oo2a = 0.5f / a;
    	
    
    	//if( hack < 0.0f )
    	//{
    	//	alpha = 0.0f;
    	//	return 0.0f;
    	//}
    	//else
    	//{
    	//	alpha = 1.0f;
    	//	return abs( flDiscrim ) * 2 * oo2a;
    	//}
    	
    	//replacing the if's above because if's in hlsl are bad.....
    	float fHackGreaterThanZero = step( 0.0f, hack );
    	alpha = fHackGreaterThanZero;
    	return (fHackGreaterThanZero * (abs( flDiscrim ) * 2 * oo2a));
    
    
    	//	*pT1 = ( - b - flDiscrim ) * oo2a;
    	//	*pT2 = ( - b + flDiscrim ) * oo2a;
    	//	return true;
    }
    
    
    struct PS_INPUT
    {
    	float2 vBumpTexCoord			: TEXCOORD0; // dudvMapAndNormalMapTexCoord
    	HALF3 vWorldVertToEyeVector		: TEXCOORD1;
    	HALF3x3 tangentSpaceTranspose	: TEXCOORD2;
    	float3 vRefractXYW				: TEXCOORD5; 
    	float3 projNormal				: TEXCOORD6;
    	float4 worldPos_projPosZ		: TEXCOORD7;
    };
    
    float4 main( PS_INPUT i ) : COLOR
    {
    	HALF3 result = 0.0f;
    
    	HALF blend = 1.0f;
    
    #if FLOWMAP
    	// hack
    	float3 g_SphereCenter = { 2688.0f, 12139.0f, 5170.0f };
    	float g_SphereDiameter = 430.0f;
    	float g_SphereRadius = g_SphereDiameter * 0.5f;
    
    	float3 tmp = i.worldPos_projPosZ.xyz - g_SphereCenter;
    	float hackRadius = 1.05f * sqrt( dot( tmp, tmp ) );
    
    	float sphereAlpha;
    	float lengthThroughSphere = LengthThroughSphere( g_EyePos, normalize( i.worldPos_projPosZ.xyz - g_EyePos ),
    		g_SphereCenter, /*g_SphereRadius*/ hackRadius, sphereAlpha );
    
    	float normalizedLengthThroughSphere = lengthThroughSphere / g_SphereDiameter;
    
    
    	float3 hackWorldSpaceNormal = normalize( i.worldPos_projPosZ.xyz - g_SphereCenter );
    	float3 realFuckingNormal = abs( hackWorldSpaceNormal );
    	hackWorldSpaceNormal = 0.5f * ( hackWorldSpaceNormal + 1.0f );
    
    	//	hackWorldSpaceNormal = abs( hackWorldSpaceNormal );
    
    	//	return float4( hackWorldSpaceNormal.x, 0.0f, 0.0f, 1.0f );
    
    	i.vBumpTexCoord.xy = 0.0f;
    	i.vBumpTexCoord.xy = realFuckingNormal.z * tex2D( FlowmapSampler, hackWorldSpaceNormal.xy );
    	i.vBumpTexCoord.xy += realFuckingNormal.y * tex2D( FlowmapSampler, hackWorldSpaceNormal.xz );
    	i.vBumpTexCoord.xy += realFuckingNormal.x * tex2D( FlowmapSampler, hackWorldSpaceNormal.yz );
    	i.vBumpTexCoord.xy += g_Time * g_FlowScrollRate;
    	//	return float4( i.vBumpTexCoord.xy, 0.0f, 0.0f );
    #endif
    
    	// Load normal and expand range
    	HALF4 vNormalSample = tex2D( NormalSampler, i.vBumpTexCoord );
    	//	return vNormalSample;
    	HALF3 tangentSpaceNormal = vNormalSample * 2.0 - 1.0;
    
    	HALF3 refractTintColor = g_RefractTint;
    
    	// Perform division by W only once
    	float ooW = 1.0f / i.vRefractXYW.z;
    
    	// Compute coordinates for sampling refraction
    	float2 vRefractTexCoordNoWarp = i.vRefractXYW.xy * ooW;
    	float2 vRefractTexCoord = tangentSpaceNormal.xy;
    	HALF scale = vNormalSample.a * g_RefractScale.x;
    #if FLOWMAP
    	scale *= normalizedLengthThroughSphere;
    #endif
    	vRefractTexCoord *= scale;
    #if FLOWMAP
    	float2 hackOffset = vRefractTexCoord;
    #endif
    	vRefractTexCoord += vRefractTexCoordNoWarp;
    
    	float3 colorWarp = tex2D( RefractSampler, vRefractTexCoord.xy );
    	float3 colorNoWarp = tex2D( RefractSampler, vRefractTexCoordNoWarp.xy );
    
    	colorWarp *= refractTintColor;
    #if REFRACT
    	result = lerp( colorNoWarp, colorWarp, blend );
    	//	return float4( 1.0f, 0.0f, 0.0f, 1.0f );
    #endif
    
    #if CUBEMAP
    	HALF specularFactor = vNormalSample.a;
    
    	HALF3 worldSpaceNormal = mul( i.tangentSpaceTranspose, tangentSpaceNormal );
    
    	HALF3 reflectVect = CalcReflectionVectorUnnormalized( worldSpaceNormal, i.vWorldVertToEyeVector );
    	HALF3 specularLighting = texCUBE( EnvmapSampler, reflectVect );
    	specularLighting *= specularFactor;
    	specularLighting *= g_EnvmapTint;
    	HALF3 specularLightingSquared = specularLighting * specularLighting;
    	specularLighting = lerp( specularLighting, specularLightingSquared, g_EnvmapContrast );
    	HALF3 greyScale = dot( specularLighting, HALF3( 0.299f, 0.587f, 0.114f ) );
    	specularLighting = lerp( greyScale, specularLighting, g_EnvmapSaturation );
    	result += specularLighting;
    #endif
    
    #if CORECOLORTEXTURE && FLOWMAP
    	float4 coreColorTexel = tex2D( CoreColorSampler, hackOffset + float2( normalizedLengthThroughSphere, g_CoreColorTexCoordOffset ) );
    	HALF4 rgba = HALF4( lerp( result, coreColorTexel, coreColorTexel.a /*normalizedLengthThroughSphere*/ ), sphereAlpha );
    #else
    	HALF4 rgba = HALF4( result, vNormalSample.a );
    #endif
    
    
    	float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
    	return FinalOutput( rgba, fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_NONE );
    }
    
     
  3. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
    The episode 1 core is made, as far as I recall, out of a model and an entity, the model itself doesn't really do anything, and I don't think it even works properly if you just spawn it as a prop_dynamic. The entity itself is what makes it act and look like the episode 1 core.

    The shader as far as I know is just for the distortion texture or something. But the entity that makes the episode 1 core is prop_coreball or something and is only available in episode 1.

    http://developer.valvesoftware.com/wiki/Prop_coreball

    Even if it did work on brushes, all it would give me is a refracting texture, I can't make a spherical brush because source snaps all its points to the grid and creates an impossible solid when you save the map.

    The bit in the middle is just two sprites, I can update it with a particle system later if I need it to look better.

    If I was going to model anything it would be the rings, but I don't have time at the moment.
     
  4. MOOtant

    MOOtant Member

    Messages:
    4,047
    Likes Received:
    0
    Trophy Points:
    0
    ent_prop_ball only changes bone transform in cycles.
    Code:
    //====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
    //
    // Purpose: 
    //
    //=============================================================================
    
    #include "cbase.h"
    
    class C_PropCoreBall : public C_BaseAnimating
    {
    	DECLARE_CLASS( C_PropCoreBall, C_BaseAnimating );
    	DECLARE_CLIENTCLASS();
    	DECLARE_DATADESC();
    
    public:
    
    	C_PropCoreBall();
    
    	void ApplyBoneMatrixTransform( matrix3x4_t& transform );
    
    	float m_flScaleX;
    	float m_flScaleY;
    	float m_flScaleZ;
    
    	float m_flLerpTimeX;
    	float m_flLerpTimeY;
    	float m_flLerpTimeZ;
    
    	float m_flGoalTimeX;
    	float m_flGoalTimeY;
    	float m_flGoalTimeZ;
    
    	float m_flCurrentScale[3];
    	bool  m_bRunningScale[3];
    	float m_flTargetScale[3];
    	
    private:
    
    };
    
    void RecvProxy_ScaleX( const CRecvProxyData *pData, void *pStruct, void *pOut )
    {
    	C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
    
    	pCoreData->m_flScaleX = pData->m_Value.m_Float;
    	
    	if ( pCoreData->m_bRunningScale[0] == true )
    	{
    		pCoreData->m_flTargetScale[0] = pCoreData->m_flCurrentScale[0];
    	}
    }
    
    void RecvProxy_ScaleY( const CRecvProxyData *pData, void *pStruct, void *pOut )
    {
    	C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
    
    	pCoreData->m_flScaleY = pData->m_Value.m_Float;
    
    	if ( pCoreData->m_bRunningScale[1] == true )
    	{
    		pCoreData->m_flTargetScale[1] = pCoreData->m_flCurrentScale[1];
    	}
    }
    
    void RecvProxy_ScaleZ( const CRecvProxyData *pData, void *pStruct, void *pOut )
    {
    	C_PropCoreBall *pCoreData = (C_PropCoreBall *) pStruct;
    
    	pCoreData->m_flScaleZ = pData->m_Value.m_Float;
    
    	if ( pCoreData->m_bRunningScale[2] == true )
    	{
    		pCoreData->m_flTargetScale[2] = pCoreData->m_flCurrentScale[2];
    	}
    }
    
    IMPLEMENT_CLIENTCLASS_DT( C_PropCoreBall, DT_PropCoreBall, CPropCoreBall )
    	RecvPropFloat( RECVINFO( m_flScaleX ), 0, RecvProxy_ScaleX ),
    	RecvPropFloat( RECVINFO( m_flScaleY ), 0, RecvProxy_ScaleY ),
    	RecvPropFloat( RECVINFO( m_flScaleZ ), 0, RecvProxy_ScaleZ ),
    
    	RecvPropFloat( RECVINFO( m_flLerpTimeX ) ),
    	RecvPropFloat( RECVINFO( m_flLerpTimeY ) ),
    	RecvPropFloat( RECVINFO( m_flLerpTimeZ ) ),
    
    	RecvPropFloat( RECVINFO( m_flGoalTimeX ) ),
    	RecvPropFloat( RECVINFO( m_flGoalTimeY ) ),
    	RecvPropFloat( RECVINFO( m_flGoalTimeZ ) ),
    END_RECV_TABLE()
    
    
    BEGIN_DATADESC( C_PropCoreBall )
    	DEFINE_AUTO_ARRAY( m_flTargetScale, FIELD_FLOAT ),
    	DEFINE_AUTO_ARRAY( m_bRunningScale, FIELD_BOOLEAN ),
    END_DATADESC()
    
    C_PropCoreBall::C_PropCoreBall( void )
    {
    	m_flTargetScale[0] = 1.0f;
    	m_flTargetScale[1] = 1.0f;
    	m_flTargetScale[2] = 1.0f;
    
    	m_bRunningScale[0] = false;
    	m_bRunningScale[1] = false;
    	m_bRunningScale[2] = false;
    }
    
    void C_PropCoreBall::ApplyBoneMatrixTransform( matrix3x4_t& transform )
    {
    	BaseClass::ApplyBoneMatrixTransform( transform );
    
    	float flVal[3] = { m_flTargetScale[0], m_flTargetScale[1], m_flTargetScale[2] };
    	float *flTargetScale[3] = { &m_flTargetScale[0], &m_flTargetScale[1], &m_flTargetScale[2] };
    	float flScale[3] = { m_flScaleX, m_flScaleY, m_flScaleZ };
    	float flLerpTime[3] = { m_flLerpTimeX, m_flLerpTimeY, m_flLerpTimeZ };
    	float flGoalTime[3] = { m_flGoalTimeX, m_flGoalTimeY, m_flGoalTimeZ };
    	bool *bRunning[3] = { &m_bRunningScale[0], &m_bRunningScale[1], &m_bRunningScale[2] };
    		
    	for ( int i = 0; i < 3; i++ )
    	{
    		if ( *flTargetScale[i] != flScale[i] )
    		{
    			float deltaTime = (float)( gpGlobals->curtime - flGoalTime[i]) / flLerpTime[i];
    			float flRemapVal = SimpleSplineRemapVal( deltaTime, 0.0f, 1.0f, *flTargetScale[i], flScale[i] );
    
    			*bRunning[i] = true;
    
    			if ( deltaTime >= 1.0f )
    			{
    				*flTargetScale[i] = flScale[i];
    				*bRunning[i] = false;
    			}
    
    			flVal[i] = flRemapVal;
    			m_flCurrentScale[i] = flVal[i];
    		}
    	}
    
    	VectorScale( transform[0], flVal[0], transform[0] );
    	VectorScale( transform[1], flVal[1], transform[1] );
    	VectorScale( transform[2], flVal[2], transform[2] );
    }
    
     
  5. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
    You know I don't think I can actually do anything with all this code, I'm fairly sure hammer doesn't have a func_append_cpp entity.
     
  6. MOOtant

    MOOtant Member

    Messages:
    4,047
    Likes Received:
    0
    Trophy Points:
    0
    (Next post due to post character limit)

    Don't bullshit anyone about the time. Opening 3ds, clicking polysphere and export takes 5-10 minutes. If you're slow with QC and such 15. Smithy can do it in 1 minute. :P

    The bit in the middle can be 2 silly sprites but it can be so much better when using the flow map.

    That ent doesn't make core ball look like it does. It's the shader. You'd know if you read the shader code I pasted. To make it work correctly on an entity I'd need to fix Valve's hack - hardcoded sphere center for ep1 core ball room. Still, you can just use it as it is. First piece of "code" I pasted describes shader parameters you can pass in .vmt.

    Material (VTF+VMT) is in episode 1 shared.gcf/materials/props_combine/core*. Fallbacks for DX lower than 90 are not necessary because it's been disabled in code.
     
    Last edited: Mar 25, 2011
  7. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
    Oh exporting a sphere would be easy yes, but I don't really want to. Not least because I'd have to install 3ds max.

    Like I said, the core doesn't use any spheres, it's just using sprites, if I was going to do something I would either model the rings (and properly, to make them look good, otherwise there's no point) or I'd make a particle system for it. It's supposed to be this blinding glow you can't look directly at, it isn't supposed to be something you stare at. For that particles are ideal, just throw a bunch of really bright sprites in there to make an inconstant glowy thing that's really damn bright.

    Mootant I can't read any code, I am not a programmer, you know that.
     
  8. MOOtant

    MOOtant Member

    Messages:
    4,047
    Likes Received:
    0
    Trophy Points:
    0
    id software artists can read code, so should you. Especially shader code. :P First C++ paste was just shader param list, it just happens to be done in C++.
     
  9. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
    I'll be sure to learn if I plan to become an id software artist.

    Which is unlikely given that I'm a level designer.

    Living in England.

    With no desire to work in the games industry.
     
  10. w00kie

    w00kie Mustachioed Mexican

    Messages:
    3,863
    Likes Received:
    13
    Trophy Points:
    0
    where to DL. I want to suggest it to Vicky :=)
     
  11. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
  12. LordDz

    LordDz Capitan Rainbow Flowers

    Messages:
    5,221
    Likes Received:
    0
    Trophy Points:
    0
    Hi University! I'm me, Contact me for all the details you need.
     
  13. Chris0132'

    Chris0132' Developer

    Messages:
    9,482
    Likes Received:
    0
    Trophy Points:
    0
    Yeah the tutors probably aren't going to be particularly impressed with the thread. But the third party timestamps are what I need.
     
  14. Trickster

    Trickster Retired Developer

    Messages:
    16,576
    Likes Received:
    46
    Trophy Points:
    0
    The other thread will be totally better right?
     
  15. Empty

    Empty Member

    Messages:
    14,912
    Likes Received:
    11
    Trophy Points:
    0
    Locked per OP request.
     
Thread Status:
Not open for further replies.

Share This Page