<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7235819</id><updated>2011-12-02T20:23:12.110Z</updated><category term='unrealscript udk tutorial'/><category term='lisp blender python toolchain'/><category term='blender lua'/><category term='unreal udk unrealscript tutorial'/><category term='udk emacs unrealscript'/><category term='clojure'/><category term='c++ gamedev opengl mingw'/><category term='bricolage c++ gamedev'/><category term='lisp sbcl glfw opengl'/><category term='Emacs Lisp Google Firefox Help'/><category term='slime emacs commonlisp etags'/><category term='c++ lisp boost'/><category term='emacs help lisp f1'/><category term='commonlisp asdf newbies'/><category term='python procedural gamedev'/><category term='c++ boost lisp'/><title type='text'>Bad Byte Bootstrap Blues</title><subtitle type='html'>General rambling about game development and design by a professional games developer. Musings on the evil of Microsoft, and the nugartory epiphenonemon that is Open Source. Pickings at Python, complaints about C, lashings of Lisp.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default?start-index=101&amp;max-results=100'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>114</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7235819.post-3240883336905596427</id><published>2011-12-02T20:04:00.001Z</published><updated>2011-12-02T20:07:27.025Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unreal udk unrealscript tutorial'/><title type='text'>Unrealscript Overview Part Six : Actor</title><content type='html'>&lt;p&gt;We don't actually place bubbles in the world. We use an object placed in the level as a point to spawn bubbles from, particle - system style. BubbleSpawner is this object. Note that it is marked as a placable so that it can be placed in the editor. The variables qualified by the (Bubble) suffix in their declaration appear as editiable properties in-game. This is an important mechanism to allow designers and artists to tweak the game without programmer input, letting you get on with core logic implementation.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In PostBeginPlay we vary the spawnCounter a bit, to be sure that mutliple emitters aren't in phase. Tick() just counts down using delta time, waiting until the time calsle to spawn a bubble. When it comes, the Spawn() function is called to randomly create a new BubblePawn somewhere randomly around the general vicinity of the spawner. That's all it takes to dynamically create a new in-world actor - the Pawn itself should take care of spawning it's controller.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;class BubbleSpawner extends Actor placeable;&lt;br /&gt;&lt;br /&gt;var(Bubble) float spawnRange;&lt;br /&gt;var float spawnCountDown;&lt;br /&gt;var(Bubble) float spawnInterval;&lt;br /&gt;&lt;br /&gt;event PostBeginPlay()&lt;br /&gt;{&lt;br /&gt;   spawnCountDown = spawnInterval * 2.5;&lt;br /&gt;   super.PostBeginPlay();&lt;br /&gt;   SetHidden(True);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;event Tick(float DeltaTime)&lt;br /&gt;{&lt;br /&gt;   local Vector SpawnLocation;&lt;br /&gt;   spawnCountDown -= DeltaTime;&lt;br /&gt;   if (spawnCountDown &amp;lt; 0)&lt;br /&gt;   {&lt;br /&gt;   SpawnLocation = self.Location;&lt;br /&gt;   SpawnLocation.X += -spawnRange + FRand() * (spawnRange * 2.0);&lt;br /&gt;   SpawnLocation.Y += -spawnRange + FRand() * (spawnRange * 2.0);&lt;br /&gt;   spawnCountDown = spawnInterval;&lt;br /&gt;   Spawn(class'LavaLamp.BubblePawn', Self,, SpawnLocation );&lt;br /&gt;   }  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;defaultproperties&lt;br /&gt;{&lt;br /&gt;   spawnInterval = 0.75&lt;br /&gt;   spawnRange    = 64.0&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3240883336905596427?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3240883336905596427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3240883336905596427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3240883336905596427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3240883336905596427'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/unrealscript-overview-part-six-actor.html' title='Unrealscript Overview Part Six : Actor'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2319657360147717948</id><published>2011-12-02T19:40:00.005Z</published><updated>2011-12-02T20:23:12.118Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unrealscript udk tutorial'/><title type='text'>Unrealscript Overview Part Five : Player Controller and Camera</title><content type='html'>&lt;p&gt;The PlayerController, derived from GamePlayerController, is the Player counterpart of the NPC GameAIController. The Player is put into the walking state by default. We co straight from here to the Spectating state, suitable for a free-flying camera. The states are implemented in GamePlayerController and it's base classes. The UpdateRotation() method is called from the base controllers Tick(). It's job is to transfer changes in PlayerInput and translate them into actual motion that sets the position and orientation of the player. ProcessMove() simply updates the Pawn's acceleration and leaves it to the base clases to update the Pawns velocity and position accordingly.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;Player Controller&lt;/h4&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class LavaLampPlayerController extends GamePlayerController;&lt;br /&gt;&lt;br /&gt;defaultproperties &lt;br /&gt;{&lt;br /&gt; CameraClass=class'LavaLamp.LavaLampPlayerCamera'&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;simulated event PostBeginPlay()&lt;br /&gt;{&lt;br /&gt; super.PostBeginPlay();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* The default state for the player controller&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;state PlayerWalking&lt;br /&gt;{&lt;br /&gt; event BeginState(Name PreviousStateName)&lt;br /&gt; {&lt;br /&gt;  GotoState('Spectating');&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* The default state for the lava lamp demo&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;state PlayerSpectating&lt;br /&gt;{&lt;br /&gt; event BeginState(Name PreviousStateName)&lt;br /&gt; {&lt;br /&gt;  bCollideWorld = false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)&lt;br /&gt; {&lt;br /&gt;  if( Pawn == None )&lt;br /&gt;  {&lt;br /&gt;   return;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (Role == ROLE_Authority)&lt;br /&gt;  {&lt;br /&gt;   // Update ViewPitch for remote clients&lt;br /&gt;   Pawn.SetRemoteViewPitch( Rotation.Pitch );&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  Pawn.Acceleration = NewAccel;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; function UpdateRotation( float DeltaTime )&lt;br /&gt; {&lt;br /&gt;  local Rotator   DeltaRot, newRotation, ViewRotation;&lt;br /&gt;&lt;br /&gt;  ViewRotation = Rotation;&lt;br /&gt;  if (Pawn!=none)&lt;br /&gt;  {&lt;br /&gt;   Pawn.SetDesiredRotation(ViewRotation);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  // Calculate Delta to be applied on ViewRotation&lt;br /&gt;  DeltaRot.Yaw      = PlayerInput.aTurn;&lt;br /&gt;  DeltaRot.Pitch    = PlayerInput.aLookUp;&lt;br /&gt;&lt;br /&gt;  ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot );&lt;br /&gt;&lt;br /&gt;  SetRotation(ViewRotation);&lt;br /&gt;  NewRotation = ViewRotation;&lt;br /&gt;  NewRotation.Roll = Rotation.Roll;&lt;br /&gt;  if ( Pawn != None ) {&lt;br /&gt;   Pawn.FaceRotation(NewRotation, deltatime);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Player Camera&lt;/h4&gt; &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class LavaLampPlayerCamera extends Camera;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)&lt;br /&gt;{&lt;br /&gt; local CameraActor   CamActor;&lt;br /&gt; local Pawn     TPawn;&lt;br /&gt;&lt;br /&gt; // Don't update outgoing viewtarget during an interpolation &lt;br /&gt;&lt;br /&gt; if( PendingViewTarget.Target != None &amp;&amp; OutVT == ViewTarget &amp;&amp; BlendParams.bLockOutgoing )&lt;br /&gt; {&lt;br /&gt;  return;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // Default FOV on viewtarget&lt;br /&gt; OutVT.POV.FOV = DefaultFOV;&lt;br /&gt;&lt;br /&gt; // Viewing through a camera actor.&lt;br /&gt; CamActor = CameraActor(OutVT.Target);&lt;br /&gt;&lt;br /&gt; if( CamActor != None )&lt;br /&gt; {&lt;br /&gt;  CamActor.GetCameraView(DeltaTime, OutVT.POV);&lt;br /&gt;&lt;br /&gt;  // Grab aspect ratio from the CameraActor.&lt;br /&gt;  bConstrainAspectRatio   = bConstrainAspectRatio || CamActor.bConstrainAspectRatio;&lt;br /&gt;  OutVT.AspectRatio   = CamActor.AspectRatio;&lt;br /&gt;&lt;br /&gt;  // See if the CameraActor wants to override the PostProcess settings used.&lt;br /&gt;  CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha;&lt;br /&gt;  CamPostProcessSettings = CamActor.CamOverridePostProcess;&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  TPawn = Pawn(OutVT.Target);&lt;br /&gt;&lt;br /&gt;  // Give Pawn Viewtarget a chance to dictate the camera position.&lt;br /&gt;  // If Pawn doesn't override the camera view, then we proceed with our own defaults&lt;br /&gt;  if( TPawn == None || !TPawn.CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) )&lt;br /&gt;  {   &lt;br /&gt;   // for this demo, we just follow the player controller&lt;br /&gt;   OutVT.POV.Rotation = PCOwner.Rotation;              &lt;br /&gt;   OutVT.POV.Location = PCOwner.Location;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; // Apply camera modifiers at the end (view shakes for example)&lt;br /&gt; ApplyCameraModifiers(DeltaTime, OutVT.POV);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;defaultproperties&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2319657360147717948?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2319657360147717948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2319657360147717948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2319657360147717948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2319657360147717948'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/unrealscript-overview-part-five-player.html' title='Unrealscript Overview Part Five : Player Controller and Camera'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4739452537571434637</id><published>2011-12-02T19:35:00.002Z</published><updated>2011-12-02T19:38:28.187Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unreal udk unrealscript tutorial'/><title type='text'>Unrealscript Overview Part Four : Player Pawn</title><content type='html'>&lt;p&gt;Our "Player" class is much less interesting than you might expect, as we are not implementing a player as such but a simple free camera. We override GetBaseAimRotation to control the viewpoint of the Pawn. We ensure that the Pawn can have it's view updated fully by the rotation pitch, roll and yaw angles. If we wanted to limit the viewing direction we would hard code tempRot.pitch = 0 in this routine to disable looking up and down for instance. BecomeViewTarget is called when a camera focuses on the player, and is our chance to block the request. Here, we allow it. As there is no mesh associated with our "Player" the light enviroment is redundant.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class LavaLampPawn extends GamePawn;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var DynamicLightEnvironmentComponent LightEnvironment;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//override to make player mesh visible by default&lt;br /&gt;&lt;br /&gt;simulated event BecomeViewTarget( PlayerController PC )&lt;br /&gt;{&lt;br /&gt; Super.BecomeViewTarget(PC);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;simulated singular event Rotator GetBaseAimRotation()&lt;br /&gt;{&lt;br /&gt; local Rotator tempRot;&lt;br /&gt; tempRot = Rotation;&lt;br /&gt; SetRotation(tempRot);&lt;br /&gt; return tempRot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;defaultproperties&lt;br /&gt;{&lt;br /&gt; bCanWalk = true&lt;br /&gt; bCanSwim = false&lt;br /&gt; bCanFly  = false&lt;br /&gt; bCanClimbLadders = false&lt;br /&gt; bWorldGeometry = true&lt;br /&gt; bCollideActors = false&lt;br /&gt; bCollideWorld  = false&lt;br /&gt; bBlockActors   = false&lt;br /&gt; Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment&lt;br /&gt;  bSynthesizeSHLight=TRUE&lt;br /&gt;  bIsCharacterLightEnvironment=TRUE&lt;br /&gt;  bUseBooleanEnvironmentShadowing=FALSE&lt;br /&gt; End Object&lt;br /&gt;&lt;br /&gt; Components.Add(MyLightEnvironment)&lt;br /&gt; LightEnvironment=MyLightEnvironment&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4739452537571434637?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4739452537571434637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4739452537571434637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4739452537571434637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4739452537571434637'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/unrealscript-overview-part-four-player.html' title='Unrealscript Overview Part Four : Player Pawn'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3296078247811428427</id><published>2011-12-02T18:38:00.005Z</published><updated>2011-12-02T19:40:12.798Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unreal udk unrealscript tutorial'/><title type='text'>Unrealscript Overview Part Three : NPC Controller</title><content type='html'>&lt;p&gt;However, a pawn is not enough to give you a full NPC. A controller is also needed. Think of this as a model - view - controller set up. The view is handled by the rendering engine iteslf, the model is the unrealscript code for the pawn, and the actual controller is the controller class associated with the Pawn itself. Nearly all NPC or player pawns will have a controller associated with them. In the case of NPCs this will derive from AIController, which derives from GameController. These base classes define some logic for simple pathfollowing which may or may not be useful. In our example, the BubbleController does not use this derived class code.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;AI Controllers usually are implemented as State machines. Unrealscript has a state construct that makes this easy. Code enclosed in a named state block is executed only when the object enters that state. The controller has an explicit method for switching state called GotoState(). As this is a simple example I have not overridden any methods inside the state block, but have written short fragments of code that can be executed latentley. Latent functions are Unrealscript speak for functions that run in the background. There are a small group of these available to you (grepping through the Controller, Actor and Pawn classes should reaval them), mostly related to Pawn movmement. Here, the rising state sets the Pawn velocity when it is etered, and then periodically checks to see if the bubble has risen too far. When it has, it enters the Popping state, wherein it stands still for a second, and then is destroyed.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Destroy() function brings us to another point. Objects derived from actor have a special property in that they are spawned rather than created with the new() operator. In our BubblePawn class we called a base method called SpawnDefaultController(), and set ControllerClass to class'LavaLamp.BubbleController'. SpawnDefaultController will then create an instance of that controller class, and ensure that the controller Poseses (ie controls/owns) the Pawn by calling Posses. It is perfectly theoretially possible to pass a pawn around different controllers to implement different behaviours - although the state mechanism makes this less useful than it might sound.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class BubbleController extends AIController;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var float RisingDistance;&lt;br /&gt;&lt;br /&gt;var float ExtraVelocity;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;simulated Event SetInitialState() &lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; ExtraVelocity = FRand() * 1.25;&lt;br /&gt;&lt;br /&gt; bScriptInitialized = true;&lt;br /&gt;&lt;br /&gt; GotoState('Rising');&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;state Rising&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;Begin: &lt;br /&gt;&lt;br /&gt; Pawn.Velocity = vect(0.0, 0.0, 0.85);&lt;br /&gt;&lt;br /&gt; Pawn.Velocity.Z += ExtraVelocity;&lt;br /&gt;&lt;br /&gt;RisingLoop:&lt;br /&gt;&lt;br /&gt; if (Pawn.Location.Z  &gt; RisingDistance)  {&lt;br /&gt;&lt;br /&gt;  StopLatentExecution();&lt;br /&gt;&lt;br /&gt;  GotoState('Popping');&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; Sleep(1);&lt;br /&gt;&lt;br /&gt; goto 'RisingLoop';&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;state Popping&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;Begin:&lt;br /&gt;&lt;br /&gt; Pawn.Velocity = vect(0.0, 0.0, 0.0);&lt;br /&gt;&lt;br /&gt;PoppingLoop:&lt;br /&gt;&lt;br /&gt; Sleep(1);&lt;br /&gt;&lt;br /&gt; Pawn.Destroy();&lt;br /&gt;&lt;br /&gt; Pawn = None;&lt;br /&gt;&lt;br /&gt; Destroy();&lt;br /&gt;&lt;br /&gt; goto 'PoppingLoop';&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;defaultproperties&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; RisingDistance = 2048.0&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3296078247811428427?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3296078247811428427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3296078247811428427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3296078247811428427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3296078247811428427'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/however-pawn-is-not-enough-to-give-you.html' title='Unrealscript Overview Part Three : NPC Controller'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3931947692141538819</id><published>2011-12-02T18:34:00.003Z</published><updated>2011-12-02T19:39:28.987Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='unreal udk unrealscript tutorial'/><title type='text'>Unrealscript Overview Part Two : NPC Pawn</title><content type='html'>&lt;p&gt;The second class to look at is Pawn. The Pawn class extends the Object and Actor class and is responsible for most in-game entities. PostBeginPlay() is the method that is called when all engine-side initialisation of an actor is complete, so we usually do setup in here. In the case of the player, this means also spawning a default controller.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In BubblePawn, we are also initalising a material instance, an instance of a Material created with the Material Editor and given some named parameters within that editor. Creating a Material Instance lets us vary those parameters on a per-instance basis without creating a whole new material.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Tick() is the routine called every time the game state is updated. Overriding it enables you to completely alter the behavior of a given Pawn. In our case we are simply moving the bubble upward and varying it's scale to give a throbbing effect.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We are using dynamic lighting in our environment and thus we define properties for dynamic lighting of the object in our default properties. To aid speed we also turn off as many collision checks as possible. The static mesh component that we add is the mesh drawn by the renderer for this Pawn. The components are simply entries in a dynamic array of components and may be created or destroyed dynamically. The sprite removal is to simly remove a default placeholder sprite automatically added by the system, as this is a placeable and can actually be placed in the editor in the scene. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class BubblePawn extends Pawn placeable;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var float   accumulatedTime;&lt;br /&gt;&lt;br /&gt;var StaticMeshComponent BubbleMesh;&lt;br /&gt;&lt;br /&gt;var MaterialInstanceConstant MatInst;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;simulated event PostBeginPlay()&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; local LinearColor specularColor;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; accumulatedTime = FRand() * 180.0;&lt;br /&gt;&lt;br /&gt; super.PostBeginPlay();&lt;br /&gt;&lt;br /&gt; `log("spawning bubble ... ");&lt;br /&gt;&lt;br /&gt; SpawnDefaultController();&lt;br /&gt;&lt;br /&gt; MatInst = new(None) Class'MaterialInstanceConstant';&lt;br /&gt;&lt;br /&gt; MatInst.SetParent(BubbleMesh.GetMaterial(0)); &lt;br /&gt;&lt;br /&gt; BubbleMesh.SetMaterial(0, MatInst);&lt;br /&gt;&lt;br /&gt; MatInst.SetScalarParameterValue('LavaEmissiveMultiplier', FRand());&lt;br /&gt;&lt;br /&gt; MatInst.SetScalarParameterValue('LavaSpecularPower', FRand() * 16.0); &lt;br /&gt;&lt;br /&gt; specularColor = makeLinearColor(FRand(), FRand(), FRand(), 1.0);&lt;br /&gt;&lt;br /&gt; MatInst.SetVectorParameterValue('LavalSpecularColor', specularColor);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;event Tick(float DeltaTime) &lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; accumulatedTime += DeltaTime;&lt;br /&gt;&lt;br /&gt; SetDrawScale( 1.0 + 0.75 * Sin(accumulatedTime) );&lt;br /&gt;&lt;br /&gt; Move(self.Velocity);&lt;br /&gt;&lt;br /&gt; super.Tick(DeltaTime);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;defaultproperties&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; WalkingPhysics=Phys_NONE&lt;br /&gt;&lt;br /&gt; bCollideActors=false&lt;br /&gt;&lt;br /&gt; bCollideWorld=false&lt;br /&gt;&lt;br /&gt; DrawScale3D=(X=32.0,Y=32.0,Z=32.0)&lt;br /&gt;&lt;br /&gt; bNoEncroachCheck = true&lt;br /&gt;&lt;br /&gt; bIgnoreEncroachers = true&lt;br /&gt;&lt;br /&gt; ControllerClass=class'LavaLamp.BubbleController'&lt;br /&gt;&lt;br /&gt;Begin Object Class=DynamicLightEnvironmentComponent Name=BubbleLightEnvironment&lt;br /&gt;&lt;br /&gt; ModShadowFadeoutTime=0.25&lt;br /&gt;&lt;br /&gt; MinTimeBetweenFullUpdates=0.2&lt;br /&gt;&lt;br /&gt; AmbientGlow=(R=.25,G=.25,B=.25,A=1)&lt;br /&gt;&lt;br /&gt; AmbientShadowColor=(R=0.15,G=0.15,B=0.15)&lt;br /&gt;&lt;br /&gt; LightShadowMode=LightShadow_ModulateBetter&lt;br /&gt;&lt;br /&gt; ShadowFilterQuality=SFQ_High&lt;br /&gt;&lt;br /&gt; bSynthesizeSHLight=TRUE&lt;br /&gt;&lt;br /&gt;End Object&lt;br /&gt;&lt;br /&gt;Components.Add(BubbleLightEnvironment)&lt;br /&gt;&lt;br /&gt;Begin Object Class=StaticMeshComponent Name=InitialMesh&lt;br /&gt;&lt;br /&gt; StaticMesh=StaticMesh'Lava.Meshes.Bubble'&lt;br /&gt;&lt;br /&gt; bOwnerNoSee=false&lt;br /&gt;&lt;br /&gt; LightEnvironment=BubbleLightEnvironment;&lt;br /&gt;&lt;br /&gt; BlockRigidBody=false&lt;br /&gt;&lt;br /&gt; CollideActors=false&lt;br /&gt;&lt;br /&gt; BlockZeroExtent=false&lt;br /&gt;&lt;br /&gt; BlockNonZeroExtent=false&lt;br /&gt;&lt;br /&gt;End Object&lt;br /&gt;&lt;br /&gt;Components.Add(InitialMesh);&lt;br /&gt;&lt;br /&gt;Components.Remove(Sprite);&lt;br /&gt;&lt;br /&gt;BubbleMesh = InitialMesh&lt;br /&gt;&lt;br /&gt;name='Bubble';&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3931947692141538819?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3931947692141538819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3931947692141538819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3931947692141538819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3931947692141538819'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/unrealscript-overview-part-two.html' title='Unrealscript Overview Part Two : NPC Pawn'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2259551228126436491</id><published>2011-12-02T11:45:00.004Z</published><updated>2011-12-02T11:49:33.307Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='blender lua'/><title type='text'>Dumping Blender Scenes as Lua</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Following on to the previous post where I dumped blender scenes as Lisp, I've also written a modified version which is more usual for mainstream use that dumps the entire active object as an enormous Lua literal. I think this would be more useful for mainstream use as the Lua could then be compiled to binary and loaded into a tool, which could pick out and use the useful bits on a per-project basis. My next project is to investigate if such a thing is also possible with FBX &amp;amp; Python - again for more mainstream use.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once more, here is the source Luke - use it :-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1422954.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2259551228126436491?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2259551228126436491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2259551228126436491' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2259551228126436491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2259551228126436491'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/12/dumping-blender-scenes-as-lua.html' title='Dumping Blender Scenes as Lua'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-1993490792015203617</id><published>2011-11-15T12:21:00.003Z</published><updated>2011-11-19T17:47:05.392Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++ lisp boost'/><title type='text'>Implementing Lisp in C++</title><content type='html'>I've been spending some time implementing a small Lisp for embedding and bootstrapping in C++, somewhat in the spirit of &lt;a href="http://michaux.ca/articles/scheme-from-scratch-introduction"&gt;Scheme from Scratch&lt;/a&gt;. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The brief I've given myself is a bit contradictory in that I'm eschewing the use of virtual functions (as they make linking C to C++ more complicated) but, for now I'm still allowing boost as a dependency. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turns out that Boost is highly useful for implementing polymorphic objects, since it contains &lt;a href="http://www.boost.org/doc/libs/1_47_0/doc/html/variant.html"&gt;variant&lt;/a&gt; - which can be used instead of the usual tagged unions. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To implement the basic Lisp Object I've created a template that implements the properties of the lisp object (copyable, assignable, and freely convertible to a base C type) and created a boost variant of all the different specialisations of this template which is the base class of our object.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This template should save writing boatloads of boilerplate code when contrasted with C and it should be much more easy to plug in new types. This has to be a win over C. The other big advantage (as noted before when I wrote the simpler Lisp) is that shared_ptr gives reference counted garbage collection more - or - less for free.&lt;br /&gt;&lt;br /&gt;As usual, here's the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;script src="https://gist.github.com/1366973.js"&gt; &lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-1993490792015203617?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/1993490792015203617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=1993490792015203617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1993490792015203617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1993490792015203617'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/11/implementing-lisp-in-c.html' title='Implementing Lisp in C++'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-172654136636740031</id><published>2011-10-20T12:28:00.003+01:00</published><updated>2011-10-20T12:45:41.595+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp blender python toolchain'/><title type='text'>Exporting Lisp From Blender</title><content type='html'>Writing a custom scene exporter for Blender turns out to be ridiculously easy compared to just about every other 3d package I've come across, mainly due to the power of Python introspection. This &lt;a href="https://svn.blender.org/svnroot/bf-blender/branches/nurbs-merge/source/blender/python/rna_dump.py"&gt;Python script&lt;/a&gt; shows how easy it is to introspect over a Blender Scene. After some fiddling I ended up with the Python script at the bottom of the post, which dumps the entire scene as an S-Expression for a Lisp instance to read. &lt;script src="https://gist.github.com/1280971.js?file=dump_sexp.py"&gt;&lt;/script&gt;&lt;br /&gt;My Lisp-based export problems are over!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-172654136636740031?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/172654136636740031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=172654136636740031' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/172654136636740031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/172654136636740031'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/10/exporting-from-blender.html' title='Exporting Lisp From Blender'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2319340318826567607</id><published>2011-09-07T10:59:00.002+01:00</published><updated>2011-12-02T20:07:54.251Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='clojure'/><title type='text'>Things that freak me out about Clojure</title><content type='html'>Coming from a Common Lisp/C++ background to Clojure is kind of .. interesting... there are several things that have made me take pause and wonder if Common Lisp is doing things the right way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Maps and Sets are functions.  You can apply a value to a set and it returns that value if it's a member, nil if it's not. Similarly with maps. Apply a value to a map and it either returns nil, or the value the value maps to in the map. Seems strange at first but it allows some neat filtering &lt;a href="http://blog.jayfields.com/2010/08/clojure-using-sets-and-maps-as.html"&gt;tricks&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* Keywords are functions. Keywords evaluate to themselves, just like in CL. Unlike in CL they are also functions so (:keyword map) actually tests map for membership of :keyword and returns the value mapped to the keyword. Again, this is handy.&lt;br /&gt;&lt;br /&gt;* -&amp;gt; : This macro flattens out nested function calls so (-&amp;gt; fn1 fn2 fn3) is (fn1 (fn2 (fn3))). I really dislike this: I can see how coming from Java it would seemingly make code easier to read, and reduce syntatic noise, but I find the parens useful as a guide for indentation. This might be down to taste.&lt;br /&gt;&lt;br /&gt;* Iteration is totally different. There's nothing like the LOOP or ITERATE. There is a while and a loop/recur, but the sequence handling is sufficently powerful that this is a fallback. It forces me to think differently and this is definitely a good thing.&lt;br /&gt;&lt;br /&gt;* Probably more to come, but meanwhile I'll keep in mind these &lt;a href="http://twoguysarguing.wordpress.com/2010/07/26/7-rules-for-writing-clojure-programs/"&gt;rules&lt;/a&gt; for writing Clojure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2319340318826567607?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2319340318826567607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2319340318826567607' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2319340318826567607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2319340318826567607'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/09/things-that-freak-me-out-about-clojure.html' title='Things that freak me out about Clojure'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3630985602565714897</id><published>2011-08-13T11:33:00.003+01:00</published><updated>2011-08-13T21:16:07.871+01:00</updated><title type='text'>Code Kata For Game Developers</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've spent some time wondering what a  set of &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html#more"&gt;Code Katas&lt;/a&gt; for game developers would look like. I'm thinking mostly in the context of learning a new language. Here's the list I have so far.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Mandelbrot set plotting&lt;/li&gt;&lt;li&gt;Simple raytracer.&lt;/li&gt;&lt;li&gt;Breakout clone.&lt;/li&gt;&lt;li&gt;Simple MUD.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Each kata would conentrate on different aspects of coding. The first, the Mandelbrot set is an old standard. Once it's done, you will know the mechanics of creating a 2d display, drawing on it, and getting decent performance out of simple numeric computation. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The raytracer, our second kata, takes us through the basics of 3d math and rendering, without actually requiring interactivity and will allow us to deploy most of the maths code needed to support 3d games on the platform. The two games suggested as exercies are Breakout and a simple MUD. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Breakout is a 2D graphical game, which would build on what was learnt performing the Mandelbrot set kata, and in addition require realtime interactivity and input, something not covered by the previous two katas, and also be a "proper" game with an initalisation phase, along with an update and render loop, giving us a framework to build our actual games around.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The final kata, the MUD concentrates on areas neglected until now: networking and text processing. These are important aspects of any platform and multi-player play. It should have enough game logic to support NPCs, and containers at the very least, but can be elaborated indefinitely..&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I think these four kata would leave you in a very good position to go on to implement games on the platform you were exploring.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm wondering if there should be a fifth kata? I don't want this to become an exhaustive list - it needs to be a set of exercises that should take little more than a day each. One working week seems a reasonable time for a professional game developer to explore a new platform. What would he/she do on the fifth day. Any suggestions?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3630985602565714897?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3630985602565714897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3630985602565714897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3630985602565714897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3630985602565714897'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/08/code-kata-for-game-developers.html' title='Code Kata For Game Developers'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4713871620228560535</id><published>2011-06-01T19:53:00.003+01:00</published><updated>2011-06-01T21:08:09.843+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unrealscript udk tutorial'/><title type='text'>Unrealscript Overview Part One: The Game Info Class</title><content type='html'>&lt;div&gt;A lot of Unrealscript source code ships with Unreal, and it's hard to know where to begin. This tutorial is to get you started and point out the major classes to extend, and methods to override. Its intended for programmers who already know one decent langauge like JavaScript, C++ or Java, to let them quickly locate key classes and methods and show how they fit together. The example centres round a simple level full of bubbles that keep continouosly spawning, with a a material, size and speed that varies per bubble.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;The most central one is probably GameInfo. So, lets start there. GameInfo is the class that defines the Game rules and creates, tracks and destroys objects in the game world itself, and controls the game flow, as outlined on &lt;a href="http://udn.epicgames.com/Three/UnrealScriptGameFlow.html"&gt;UDN&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/1003014.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;The very basic version of GameInfo needs to know only two things - the class which is used to implement the player Pawn and Controller. This is added in a &lt;span style="font-weight:bold;"&gt;defaultproperties&lt;/span&gt; section that usually comes after any code and is used to initialise variables at instance creation time. The PostLogin() is called by the engine after the player has been spawned and is meant to call StartMatch(), StartHumans(), RestartPlayer(), and SpawnDefaultPawnFor() in order to run the game. We override PostLogin() in our demo as we are implementing a demo and not a game, and do not want death and restart logic to apply to the player.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4713871620228560535?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4713871620228560535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4713871620228560535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4713871620228560535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4713871620228560535'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/06/unrealscript-overview-part-one-game.html' title='Unrealscript Overview Part One: The Game Info Class'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-227022176209032467</id><published>2011-05-16T11:31:00.004+01:00</published><updated>2011-05-16T11:52:33.341+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='udk emacs unrealscript'/><title type='text'>Emas and the Unreal Development Kit Workflow</title><content type='html'>I've been spending some more time with the Unreal Development Kit, as it seems to be trending in the world of games development, and partly to keep my hand in. I've been developing an Emacs based workflow and I thought I'd just quickly blog about it, in case my Emacs Lisp is of any help to any Emacs oldbies confronting this tech. The usual way to develop for it is with nFringe's pixel Mine and Visual Studio. And while Visual Studio is an excellent debugger, it lacks in the actual text editing department, as even Vi users know...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My tools of choice are Emacs &lt;a href="http://cx4a.org/software/auto-complete/"&gt;AutoComplete&lt;/a&gt; mode, which gives Emacs intelli-sense like capabilities over a broad range of languages (it's pretty magical with Lisp, as you'd expect) and the good old&lt;a href="http://ctags.sourceforge.net/"&gt; Exuberant Ctags&lt;/a&gt;, primed to tag Unrealscript, with the following regular expressions in ~/ectags.cnf. I have to say &lt;a href="http://www.emacswiki.org/emacs/EtagsSelect"&gt;ectags-select&lt;/a&gt; is very handy for working with these, as an alternative to the usual way of working with tags in Emacs as it lets you browse the enormous range of options that pop up.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These are the expressions to use for Exubrerant Ctags when tagging Unrealscript.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/974216.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;This is the support code I have: a set of interactive functions for invoking the udk, building code, running the editor. It creates a group of settings that can be customised with &lt;b&gt;M-x customize-group udk&lt;/b&gt;. I watch the log in an emacs buffer via global-revert-tail mode. I have not yet added support for UDK log files to compilation mode, but thats an obvious tweak I'll try at some point. I've had enough fiddling with regular expressions for now.&lt;br /&gt;&lt;script src="https://gist.github.com/974208.js"&gt; &lt;/script&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;PS: I thought I'd reproduce the unrealscript mode here, just in case. It lives where you put your other extra mode files. &lt;br /&gt;&lt;script src="https://gist.github.com/974226.js"&gt; &lt;/script&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-227022176209032467?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/227022176209032467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=227022176209032467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/227022176209032467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/227022176209032467'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/05/emas-and-unreal-development-kit.html' title='Emas and the Unreal Development Kit Workflow'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-7460103628595522791</id><published>2011-04-07T07:15:00.003+01:00</published><updated>2011-04-07T07:21:39.836+01:00</updated><title type='text'>Bricolage - Now with font rendering.</title><content type='html'>&lt;p&gt;The next step for the bricolage engine I'm writing is to add font rendering. Something one should add early on in development, so you can read all those panic messages from your machine and keep an eye on CPU usage and memory usage as you go along. For this I have been using Angel Code's &lt;a href="http://www.angelcode.com/products/bmfont/"&gt;BMFont&lt;/a&gt; tool, which is noticeably better than any other I've seen: even supports signed distance fields..&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-PI6CywljOFA/TZ1XIsOkCHI/AAAAAAAAAEk/1L3s1CsD79Q/s1600/bricolage_two.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 250px;" src="http://2.bp.blogspot.com/-PI6CywljOFA/TZ1XIsOkCHI/AAAAAAAAAEk/1L3s1CsD79Q/s320/bricolage_two.png" alt="" id="BLOGGER_PHOTO_ID_5592722119086835826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-7460103628595522791?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/7460103628595522791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=7460103628595522791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7460103628595522791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7460103628595522791'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/04/bricolage-now-with-font-rendering.html' title='Bricolage - Now with font rendering.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-PI6CywljOFA/TZ1XIsOkCHI/AAAAAAAAAEk/1L3s1CsD79Q/s72-c/bricolage_two.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-7016062728415834625</id><published>2011-03-14T11:58:00.005Z</published><updated>2011-03-14T12:02:13.866Z</updated><title type='text'>Bricolage engine starts rendering</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-XhzoUNSgDIo/TX4DVMzqkMI/AAAAAAAAADw/OcEi8k82ToE/s1600/bricolage_one.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 180px;" src="http://3.bp.blogspot.com/-XhzoUNSgDIo/TX4DVMzqkMI/AAAAAAAAADw/OcEi8k82ToE/s320/bricolage_one.png" alt="" id="BLOGGER_PHOTO_ID_5583904250736054466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;My experimental bricolage lash-up has started rendering (actually, two weeks ago) .. here's a screenshot of it rendering the &lt;a href="http://archive.gamedev.net/community/forums/mod/journal/journal.asp?jn=323357&amp;amp;cmonth=7&amp;amp;cyear=2009&amp;amp;cday=9"&gt;videogame testcard&lt;/a&gt;..next step is to get a nice font rendering module and debugging console going..before delving into 3d..&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;img src="file:///C:/Users/Zaba/AppData/Local/Temp/moz-screenshot.png" alt="" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-7016062728415834625?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/7016062728415834625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=7016062728415834625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7016062728415834625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7016062728415834625'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/03/bricolage-engine-starts-rendering.html' title='Bricolage engine starts rendering'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-XhzoUNSgDIo/TX4DVMzqkMI/AAAAAAAAADw/OcEi8k82ToE/s72-c/bricolage_one.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4825126207065635285</id><published>2011-02-04T15:46:00.002Z</published><updated>2011-02-04T16:08:46.472Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='bricolage c++ gamedev'/><title type='text'>Bricolage progress.</title><content type='html'>The initial version of the &lt;a href="https://bitbucket.org/johnfredcee/bricolage/overview"&gt;Bricolage&lt;/a&gt; engine is complete. It uses &lt;a href="http://www.nedprod.com/programs/portable/nedmalloc/"&gt;nedmalloc&lt;/a&gt; for memory allocation, &lt;a href="https://github.com/paulhodge/EASTL"&gt;EASTL&lt;/a&gt; for generic containers and &lt;a href="http://glew.sourceforge.net/"&gt;GLEW&lt;/a&gt; and &lt;a href="http://www.glfw.org/"&gt;GLFW&lt;/a&gt; for OpenGL and platform abstraction layers, although at the moment the only platform I'm supporting is Windows. It should be more than enough to get an image on the screen, run a shader, and build some basic component - entity architecture. So, here we go...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4825126207065635285?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4825126207065635285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4825126207065635285' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4825126207065635285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4825126207065635285'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/02/bricolage-progress.html' title='Bricolage progress.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-1944751813910967960</id><published>2011-01-25T15:12:00.008Z</published><updated>2011-01-27T14:30:39.945Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++ gamedev opengl mingw'/><title type='text'>A New Engine</title><content type='html'>&lt;p&gt;I am between projects at the moment, in a phase of experimentation. One thing I've wanted to do is construct a good testbed engine for experiments. However an entire engine is a major undertaking - three months to get the basics down pat. A third party engine always takes time to learn, though. There's nothing to replace the familiarity of something you coded yourself.&lt;/p&gt;&lt;p&gt;It occured to me that there is a third alternative. Bricolage - to assemble an engine or as much as possible of an engine from the multitude of FOSS libraries that are available. Such would be in accord with the UNIX philosophy: to have small programs or tools that do one thing well, and arrange it so that the sum of the parts are greater than the whole. This should give me a platform for experimentation in a much faster time than full self-assembly, but have the advantage of familiarity that comes with self-designed API's. &lt;/p&gt;&lt;p&gt;With no further ado, I introduce the &lt;a href="https://bitbucket.org/johnfredcee/bricolage/overview"&gt;Bricolage&lt;/a&gt; engine. I will blog about each component as I add it. Eventually it should be a reasonably featured engine that works with mingw on Windows and is ready for porting to other platforms. To quote Wikipedia: &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;pre&gt;Bricolage is a term used in several disciplines, among them the visual arts&lt;br /&gt;and literature, to refer to the construction or creation of a work from a&lt;br /&gt;diverse range of things that happen to be available, or a work created by&lt;br /&gt;such a process. The term is borrowed from the French word bricolage, from&lt;br /&gt;the verb bricoler, the core meaning in French being, "fiddle, tinker" and,&lt;br /&gt;by extension, "to make creative and resourceful use of whatever materials&lt;br /&gt;are at hand (regardless of their original purpose)"&lt;/pre&gt;&lt;p&gt;My main goal is portability. I need to be able to support mutiple renderers and platforms if at all possible. This pretty much limits me to gcc as a compiler and OpenGL  (and it's junior cousin, OpenGLES) as a rendering API. I chose SCons as a build tool, mainly for reasons of tast. It's as portable as Python is and I know it and Python reasonably well. CMake or autotools are equally valid choices.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-1944751813910967960?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/1944751813910967960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=1944751813910967960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1944751813910967960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1944751813910967960'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2011/01/new-engine.html' title='A New Engine'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2296854136199093278</id><published>2010-12-14T16:35:00.004Z</published><updated>2010-12-14T16:36:51.294Z</updated><title type='text'>How network games work...</title><content type='html'>Highly handy comment from PlayerController.uc in the Unreal Development Kit: Multiplayer net games 101..&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;========================================================================&lt;br /&gt;Here's how player movement prediction, replication and correction works in network games:&lt;br /&gt;&lt;br /&gt;Every tick, the PlayerTick() function is called.  It calls the PlayerMove() function (which is implemented&lt;br /&gt;in various states).  PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove()&lt;br /&gt;(for single player or listen servers), or ReplicateMove() (if its a network client).&lt;br /&gt;&lt;br /&gt;ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move&lt;br /&gt;to the server by calling the replicated function ServerMove() - passing the movement parameters, the client's&lt;br /&gt;resultant position, and a timestamp.&lt;br /&gt;&lt;br /&gt;ServerMove() is executed on the server.  It decodes the movement parameters and causes the appropriate movement&lt;br /&gt;to occur.  It then looks at the resulting position and if enough time has passed since the last response, or the&lt;br /&gt;position error is significant enough, the server calls ClientAdjustPosition(), a replicated function.&lt;br /&gt;&lt;br /&gt;ClientAdjustPosition() is executed on the client.  The client sets its position to the servers version of position,&lt;br /&gt;and sets the bUpdatePosition flag to true.&lt;br /&gt;&lt;br /&gt;When PlayerTick() is called on the client again, if bUpdatePosition is true, the client will call&lt;br /&gt;ClientUpdatePosition() before calling PlayerMove().  ClientUpdatePosition() replays all the moves in the pending&lt;br /&gt;move list which occured after the timestamp of the move the server was adjusting.&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2296854136199093278?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2296854136199093278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2296854136199093278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2296854136199093278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2296854136199093278'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2010/12/how-network-games-work.html' title='How network games work...'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-747508202772648478</id><published>2010-12-01T17:39:00.002Z</published><updated>2011-12-02T20:08:31.879Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='udk emacs unrealscript'/><title type='text'>Unrealscript Mode for Emacs Reloaded</title><content type='html'>&lt;p&gt;I actually started picking up Unreal again, and Unrealscript. My previous attempt at an Unrealscript mode was badly flawed. It was based on CC-mode, which I did not fully pursuade to understand the syntax of Unrealscript. This time, I've gone back to first principles and created simple progmode not derived from cc-mode. This means a loss of functionality, but it does mean correct indenting, and true case insensitivity. I found CC mode would have to be patched to handle a case insensitive language like UnrealScript. Anyway, without further ado, here it is. I reccomend it over the previous ones.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defvar unrealscript-mode-hook nil)&lt;br /&gt;&lt;br /&gt;(defvar unrealscript-mode-map&lt;br /&gt;  (let ((unrealscript-mode-map (make-sparse-keymap)))&lt;br /&gt; (define-key unrealscript-mode-map "\C-j" 'newline-and-indent)&lt;br /&gt; unrealscript-mode-map)&lt;br /&gt;  "Keymap for UNREALSCRIPT major mode")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defconst unrealscript-font-lock-keywords-1&lt;br /&gt;  (list&lt;br /&gt;   '("\\&lt;\\(?:break\\|c\\(?:\\(?:as\\|ontinu\\)e\\)\\|do\\|e\\(?:lse\\|xtends\\)\\|for\\(?:each\\)?\\|i\\(?:f\\|nterface\\)\\|new\\|return\\|switch\\|var\\|while\\|class\\)\\&gt;" . font-lock-keyword-face))&lt;br /&gt;  "Minimal highlighting expressions for UNREALSCRIPT mode.")&lt;br /&gt;&lt;br /&gt;(defconst unrealscript-font-lock-keywords-2&lt;br /&gt;  (append unrealscript-font-lock-keywords-1&lt;br /&gt;    (list&lt;br /&gt;     '("\\&lt;\\(?:array\\|b\\(?:ool\\|yte\\)\\|c\\(?:lass\\|o\\(?:erce\\|lor\\|ords\\)\\)\\|de\\(?:faultproperties\\|legate\\)\\|e\\(?:num\\|vent\\)\\|f\\(?:alse\\|loat\\|unction\\)\\|int\\|local\\|name\\|o\\(?:ptional\\|ut\\)\\|plane\\|r\\(?:egion\\|otator\\)\\|st\\(?:ate\\|r\\(?:ing\\|uct\\)\\)\\|true\\|v\\(?:\\(?:a\\|ecto\\)r\\)\\)\\&gt;" . font-lock-keyword-face)))&lt;br /&gt;  "Additional Keywords to highlight in UNREALSCRIPT mode.")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defconst unrealscript-font-lock-keywords-3&lt;br /&gt;  (append unrealscript-font-lock-keywords-2&lt;br /&gt;    (list&lt;br /&gt;     '("\\&lt;\\(?:A\\(?:bstract\\|llowAbstract\\|uto\\(?:Comment\\|ExpandCategories\\)\\)\\|Co\\(?:llapseCategories\\|nfig\\)\\|D\\(?:ep\\(?:endsOn\\|recated\\)\\|isplayName\\|ontCollapseCategories\\)\\|Edit\\(?:Condition\\|InlineNew\\)\\|FriendlyName\\|Hide\\(?:Categories\\|DropDown\\)\\|I\\(?:\\(?:mplemen\\|nheri\\)ts\\)\\|N\\(?:ative\\(?:Replication\\)?\\|o\\(?:Export\\|nTransient\\|t\\(?:EditInlineNew\\|Placeable\\)\\)\\)\\|P\\(?:erObject\\(?:Config\\|Localized\\)\\|laceable\\)\\|ShowCategories\\|T\\(?:oolTip\\|ransient\\)\\|Within\\)\\&gt;" . font-lock-type-face)&lt;br /&gt;     '("\\&lt;\\(?:auto\\|c\\(?:lient\\|on\\(?:fig\\|st\\)\\)\\|d\\(?:atabinding\\|eprecated\\|uplicatetransient\\)\\|e\\(?:dit\\(?:const\\|fixedsize\\|inline\\(?:use\\)?\\|oronly\\)\\|x\\(?:ec\\|port\\)\\)\\|globalconfig\\|i\\(?:gnores\\|n\\(?:it\\|put\\|stanced\\|terp\\)\\|terator\\)\\|l\\(?:atent\\|ocalized\\)\\|n\\(?:ative\\(?:replication\\)?\\|o\\(?:clear\\|export\\|import\\|ntransactional\\|tforconsole\\)\\)\\|operator\\|p\\(?:o\\(?:\\(?:inte\\|stoperato\\)r\\)\\|r\\(?:eoperator\\|ivate\\|otected\\)\\|ublic\\)\\|re\\(?:liable\\|pnotify\\)\\|s\\(?:erver\\|i\\(?:mulated\\|ngular\\)\\|kip\\|tatic\\)\\|tra\\(?:nsient\\|vel\\)\\|unreliable\\)\\&gt;" . font-lock-keyword-face)&lt;br /&gt;     '("\\&lt;\\(?:A\\(?:bs\\|cos\\|dd\\(?:Item\\)?\\|llActors\\|s\\(?:c\\|in\\)\\|tan\\)\\|B\\(?:asedActors\\|egin\\(?:Play\\|State\\)\\)\\|C\\(?:aps\\|eil\\|h\\(?:ildActors\\|r\\)\\|l\\(?:amp\\|earTimer\\)\\|o\\(?:\\(?:llidingActor\\)?s\\)\\)\\|D\\(?:estroyed\\|i\\(?:\\(?:sabl\\|vid\\)e\\)\\|ynamicActors\\)\\|E\\(?:mpty\\|n\\(?:\\(?:abl\\|dStat\\)e\\)\\|val\\|xp\\)\\|F\\(?:Clamp\\|M\\(?:ax\\|in\\)\\|Rand\\|astTrace\\|in\\(?:d\\|ish\\(?:Anim\\|Interpolation\\)\\)\\)\\|G\\(?:etTimer\\(?:Count\\|Rate\\)\\|oTo\\(?:State\\)?\\)\\|I\\(?:n\\(?:Str\\|itGame\\|sert\\(?:Item\\)?\\|vert\\)\\|s\\(?:\\(?:InStat\\|TimerActiv\\)e\\)\\)\\|L\\(?:e\\(?:ft\\|n\\|rp\\)\\|o\\(?:cs\\|ge\\)\\)\\|M\\(?:ax\\|i\\(?:rrorVectorByNormal\\|[dn]\\)\\)\\|Normal\\|OverlappingActors\\|P\\(?:o\\(?:pState\\|stBeginPlay\\)\\|reBeginPlay\\|ushState\\)\\|R\\(?:and\\|e\\(?:move\\(?:I\\(?:ndex\\|tem\\)\\)?\\|pl\\(?:ace\\)?\\)\\|ight\\|ound\\)\\|S\\(?:et\\(?:State\\|Timer\\)\\|in\\|leep\\|merp\\|p\\(?:awn\\|lit\\)\\|q\\(?:rt\\|uare\\)\\)\\|T\\(?:an\\|ick\\|ouchingActors\\|race\\(?:Actors\\)?\\)\\|V\\(?:Rand\\|Size\\|isible\\(?:\\(?:Colliding\\)?Actors\\)\\)\\|\\(?:ro\\|vec\\)t\\)\\&gt;" . font-lock-function-name-face)))&lt;br /&gt;  "Balls-out highlighting in UNREALSCRIPT mode.")&lt;br /&gt;&lt;br /&gt;(defvar unrealscript-font-lock-keywords unrealscript-font-lock-keywords-3&lt;br /&gt;  "Default highlighting expressions for UNREALSCRIPT mode.")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defvar unrealscript-indent-width 4)&lt;br /&gt;&lt;br /&gt;(defun looking-at-unrealscript-indent-keyword ()&lt;br /&gt;  (or (looking-at "^[\t ]*while") (looking-at "^[\t ]*if") (looking-at "^[\t ]*else") (looking-at "^[\t ]*for")))&lt;br /&gt;&lt;br /&gt;(defun looking-at-unrealscript-block-end ()  &lt;br /&gt;  (or (looking-at "^[\t ]*end") (and (looking-at "^.*}[ \t]*$") (not (looking-at "^.*{")))))&lt;br /&gt;&lt;br /&gt;(defun looking-at-unrealscript-block-start ()&lt;br /&gt;  (or (looking-at "^[\t ]*begin") (and (looking-at "^.*{") (not (looking-at "^.*}[ \t]*$")))))&lt;br /&gt;&lt;br /&gt;;; Function to control indenting.&lt;br /&gt;(defun unrealscript-indent-line ()&lt;br /&gt;  "Indent current line as Unrealscript code"&lt;br /&gt;  (interactive)&lt;br /&gt;  ;; Set the point to beginning of line.&lt;br /&gt;  (beginning-of-line)&lt;br /&gt;  (if (bobp)&lt;br /&gt;   (indent-line-to 0)&lt;br /&gt; (let ((not-indented t) (lines-back 0) cur-indent)&lt;br /&gt;   (if  (looking-at-unrealscript-block-end) ; Check for closing brace&lt;br /&gt;    ;; if we are at the end of a block&lt;br /&gt;    (progn&lt;br /&gt;   (save-excursion&lt;br /&gt;     (forward-line -1)&lt;br /&gt;     (setq lines-back (+ lines-back 1))&lt;br /&gt;     (setq cur-indent (- (current-indentation) unrealscript-indent-width)))&lt;br /&gt;   ;; Safety check to make sure we don't indent negative.&lt;br /&gt;   (if (&lt; cur-indent 0)&lt;br /&gt;    (setq cur-indent 0)))&lt;br /&gt;  ;; else scan backward &lt;br /&gt;  (save-excursion&lt;br /&gt;    (if (looking-at-unrealscript-block-start) ; Opening block     &lt;br /&gt;     (progn&lt;br /&gt;    (forward-line -1)&lt;br /&gt;    (setq lines-back (+ lines-back 1))&lt;br /&gt;    (setq cur-indent (current-indentation))&lt;br /&gt;    (setq not-indented nil))&lt;br /&gt;   (while not-indented&lt;br /&gt;     (forward-line -1)&lt;br /&gt;     (setq lines-back (+ lines-back 1))&lt;br /&gt;     (if (looking-at-unrealscript-block-end) ;; Closing Block&lt;br /&gt;      (progn&lt;br /&gt;     (setq cur-indent (current-indentation))&lt;br /&gt;     (setq not-indented nil))&lt;br /&gt;    (if (looking-at-unrealscript-block-start)&lt;br /&gt;     (progn&lt;br /&gt;       (setq cur-indent (+ (current-indentation) unrealscript-indent-width))&lt;br /&gt;       (setq not-indented nil))&lt;br /&gt;      (if (looking-at-unrealscript-indent-keyword)&lt;br /&gt;       (progn&lt;br /&gt;      (setq cur-indent (current-indentation))&lt;br /&gt;      (forward-line 1)&lt;br /&gt;      (setq lines-back (- lines-back 1))&lt;br /&gt;      (if (looking-at-unrealscript-block-start)&lt;br /&gt;       (setq not-indented nil) ;; has block&lt;br /&gt;        (if (zerop lines-back) ;; no block&lt;br /&gt;         (progn&lt;br /&gt;        (setq cur-indent (+ cur-indent unrealscript-indent-width))       &lt;br /&gt;        (setq not-indented nil))&lt;br /&gt;       (setq not-indented nil))))&lt;br /&gt;     (if (bobp)&lt;br /&gt;      (setq not-indented nil)))))))))&lt;br /&gt;   (if cur-indent&lt;br /&gt;    (indent-line-to cur-indent)&lt;br /&gt;  (indent-line-to 0))))) &lt;br /&gt;&lt;br /&gt;(defun unrealscript-populate-syntax-table (table)&lt;br /&gt;  "Populate the given syntax table as necessary for a C-like language.&lt;br /&gt;This includes setting ' and \" as string delimiters, and setting up&lt;br /&gt;the comment syntax to handle both line style \"//\" and block style&lt;br /&gt;\"/*\" \"*/\" comments."&lt;br /&gt;&lt;br /&gt;  (modify-syntax-entry ?_  "_"    table)&lt;br /&gt;  (modify-syntax-entry ?\\ "\\"    table)&lt;br /&gt;  (modify-syntax-entry ?+  "."    table)&lt;br /&gt;  (modify-syntax-entry ?-  "."    table)&lt;br /&gt;  (modify-syntax-entry ?=  "."    table)&lt;br /&gt;  (modify-syntax-entry ?%  "."    table)&lt;br /&gt;  (modify-syntax-entry ?&lt;  "."    table)&lt;br /&gt;  (modify-syntax-entry ?&gt;  "."    table)&lt;br /&gt;  (modify-syntax-entry ?&amp;  "."    table)&lt;br /&gt;  (modify-syntax-entry ?|  "."    table)&lt;br /&gt;  (modify-syntax-entry ?\' "\""    table)&lt;br /&gt;  (modify-syntax-entry ?\240 "."  table)&lt;br /&gt;&lt;br /&gt;  ;; Set up block and line oriented comments.  The new C&lt;br /&gt;  ;; standard mandates both comment styles even in C, so since&lt;br /&gt;  ;; all languages now require dual comments, we make this the&lt;br /&gt;  ;; default.&lt;br /&gt;  (modify-syntax-entry ?/  ". 124b" table)&lt;br /&gt;  (modify-syntax-entry ?*  ". 23" table)&lt;br /&gt;&lt;br /&gt;  (modify-syntax-entry ?\n "&gt; b" table)&lt;br /&gt;  ;; Give CR the same syntax as newline, for selective-display&lt;br /&gt;  (modify-syntax-entry ?\^m "&gt; b" table)&lt;br /&gt;  table)&lt;br /&gt;&lt;br /&gt;(defvar unrealscript-mode-syntax-table&lt;br /&gt;  (let ((unrealscript-mode-syntax-table (unrealscript-populate-syntax-table (make-syntax-table))))&lt;br /&gt; unrealscript-mode-syntax-table)&lt;br /&gt;  "Syntax table for unrealscript-mode")&lt;br /&gt;&lt;br /&gt;(defun unrealscript-mode ()&lt;br /&gt;  "Major mode for editing Unrealscript files"&lt;br /&gt;  (interactive)&lt;br /&gt;  (kill-all-local-variables)&lt;br /&gt;  (set-syntax-table unrealscript-mode-syntax-table)&lt;br /&gt;  (use-local-map unrealscript-mode-map)&lt;br /&gt;  (setq indent-line-function 'unrealscript-indent-line)&lt;br /&gt;  (setq font-lock-defaults '(unrealscript-font-lock-keywords nil t))&lt;br /&gt;  (setq major-mode 'unrealscript-mode)&lt;br /&gt;  (setq mode-name "UNREALSCRIPT")&lt;br /&gt;  (run-hooks 'unrealscript-mode-hook)&lt;br /&gt;  (setq case-fold-search t)&lt;br /&gt;  (setq font-lock-keywords-case-fold-search t))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(provide 'unrealscript-mode)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-747508202772648478?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/747508202772648478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=747508202772648478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/747508202772648478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/747508202772648478'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2010/12/unrealscript-mode-for-emacs-reloaded.html' title='Unrealscript Mode for Emacs Reloaded'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-6390273837785184127</id><published>2010-09-15T22:18:00.007+01:00</published><updated>2010-09-15T22:55:58.960+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++ boost lisp'/><title type='text'>A micro manual for Lisp in C++</title><content type='html'>&lt;p&gt;It was with some interest that I read &lt;a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/"&gt;A Micro Manual for Lisp in C&lt;/a&gt;. One thing I have noticed about such efforts is that they are nearly always implemented in idiomatic C. I thought (out of idle curiosity, mainly) I'd see what a similar thing implemented in idomatic C++ would look like.&lt;/p&gt;&lt;br /&gt;The main practical advantage that it offered in the end was the fact that boost::shared_ptr gave me rudimentary garbage collection for free. I used boost::variant to give me polymorphic lisp objects and thus did not have to use naked pointers anywhere, which seems to me to be an improvement in code safety. The price of this is a nosier syntax. You pay your money and you takes your choice..&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As a concrete example here is what the implementation of CONS looked like.&lt;/p&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #b2e4ff;"&gt;fn_cons&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;args&lt;/span&gt;,&lt;br /&gt;                                        &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;env&lt;/span&gt;) {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;list&lt;/span&gt; = make_cons(car(args), &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt;());&lt;br /&gt;    args = car(cdr(args));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;while&lt;/span&gt; ((args != &lt;span style="color: #7fffd4;"&gt;NULL&lt;/span&gt;) &amp;amp;&amp;amp; (args-&amp;gt;which() == &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::e_CONS)) {&lt;br /&gt;        append(list, car(args));&lt;br /&gt;        args = cdr(args);&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;return&lt;/span&gt; list;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Its probably also worth noting that avoiding naked pointers meant using boost::function for function objects, thusly..&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;enum&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;kind&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #eedd82;"&gt;e_ATOM&lt;/span&gt; = 0,&lt;br /&gt;        &lt;span style="color: #eedd82;"&gt;e_CONS&lt;/span&gt;,&lt;br /&gt;        &lt;span style="color: #eedd82;"&gt;e_FUNC&lt;/span&gt;,&lt;br /&gt;        &lt;span style="color: #eedd82;"&gt;e_LAMBDA&lt;/span&gt;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;struct&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;atom&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;string&lt;/span&gt; &lt;span style="color: #eedd82;"&gt;name&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #b2e4ff;"&gt;atom&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;const&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;string&lt;/span&gt;&amp;amp; &lt;span style="color: #eedd82;"&gt;n&lt;/span&gt;) : name(n) {&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;struct&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;cons&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;car&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;cdr&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #b2e4ff;"&gt;cons&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;first&lt;/span&gt;, &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;second&lt;/span&gt;) : car(first), cdr(second) {&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;typedef&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;function&lt;/span&gt;&amp;lt; &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; (&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt;,&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt;) &amp;gt; &lt;span style="color: #98fb98;"&gt;lisp_func&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;struct&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;func&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #98fb98;"&gt;lisp_func&lt;/span&gt; &lt;span style="color: #eedd82;"&gt;fn&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #b2e4ff;"&gt;func&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;const&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;lisp_func&lt;/span&gt;&amp;amp; &lt;span style="color: #eedd82;"&gt;f&lt;/span&gt;) : fn(f) {&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;struct&lt;/span&gt; &lt;span style="color: #98fb98;"&gt;lambda&lt;/span&gt; {&lt;br /&gt;        &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;args&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;sexp&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #b2e4ff;"&gt;lambda&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;object&amp;gt; &lt;span style="color: #eedd82;"&gt;a&lt;/span&gt;, &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;object&amp;gt; &lt;span style="color: #eedd82;"&gt;s&lt;/span&gt;) : args(a), sexp(s) {&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;typedef&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;variant&lt;/span&gt;&amp;lt; atom, cons, func, &lt;span style="color: #98fb98;"&gt;lambda&lt;/span&gt; &amp;gt; &lt;span style="color: #98fb98;"&gt;base_object&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And creating the environment like so...&lt;/p&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #b2e4ff;"&gt;init_env&lt;/span&gt;() {&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;nul&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_quote&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"QUOTE"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_quote&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_quote));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_car&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"CAR"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_car&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_car));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_cdr&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"CDR"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_cdr&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_cdr));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_cons&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"CONS"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_cons&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_cons));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_equal&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"EQUAL"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_equal&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_equal));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_atom&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"ATOM"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_atom&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_atom));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_cond&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"COND"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_cond&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_cond));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_lambda&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"LAMBDA"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_lambda&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_lambda));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_label&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"LABEL"&lt;/span&gt;)));&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;f_label&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(fn_label));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;env&lt;/span&gt; = make_cons(make_cons(a_quote,make_cons(f_quote,nul)),nul);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    append(env,make_cons(a_car,   make_cons(f_car,nul)));&lt;br /&gt;    append(env,make_cons(a_cdr,   make_cons(f_cdr,nul)));&lt;br /&gt;    append(env,make_cons(a_cons,  make_cons(f_cons,nul)));&lt;br /&gt;    append(env,make_cons(a_equal, make_cons(f_equal,nul)));&lt;br /&gt;    append(env,make_cons(a_atom,  make_cons(f_atom,nul)));&lt;br /&gt;    append(env,make_cons(a_cond,  make_cons(f_cond,nul)));&lt;br /&gt;    append(env,make_cons(a_lambda, make_cons(f_lambda,nul)));&lt;br /&gt;    append(env,make_cons(a_label,  make_cons(f_label,nul)));&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #7fffd4;"&gt;boost&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;shared_ptr&lt;/span&gt;&amp;lt;&lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;&amp;gt; &lt;span style="color: #eedd82;"&gt;a_tee&lt;/span&gt;(&lt;span style="color: #a0ffff;"&gt;new&lt;/span&gt; &lt;span style="color: #7fffd4;"&gt;lisp&lt;/span&gt;::&lt;span style="color: #98fb98;"&gt;object&lt;/span&gt;(&lt;span style="color: #7fffd4;"&gt;std&lt;/span&gt;::string(&lt;span style="color: #efca10;"&gt;"#T"&lt;/span&gt;)));&lt;br /&gt;    tee = a_tee;&lt;br /&gt;    nil = make_cons(nul,nul);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a0ffff;"&gt;return&lt;/span&gt; env;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-6390273837785184127?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/6390273837785184127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=6390273837785184127' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6390273837785184127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6390273837785184127'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2010/09/micro-manual-for-lisp-in-c.html' title='A micro manual for Lisp in C++'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-6226782880869729525</id><published>2010-08-11T20:35:00.002+01:00</published><updated>2010-08-11T21:02:15.750+01:00</updated><title type='text'>OpenGL Development on Windows with Slime</title><content type='html'>&lt;p&gt;&lt;br /&gt;I've been playing with OpenGL, Common Lisp (SBCL, CCL, Lispworks Personal) and SLIME again. Mostly I've been establishing a S-Expression exporter for Blender so I can export entire scenes to the engine I'm working on. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I did discover some wrinkles of working on OpenGL development with SLIME in Windows. CCL uses the :spawn communication style in SLIME which uses it's multi-threaded nature to run each repl request in a seperate thread from the executing lisp code. So if you have your OpenGL app running in the background as you develop it, if you write an experimental form at the repl that includes OpenGL calls, its going to fail, since it will not be executing in the main OpenGL thread.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The solution is to fall back on the nil communication style, which is not threaded and is blocking. This has the less than desirable effect of blocking your repl until the executing app finishes. This can be circumvented by calling swank-handle-requests - like so&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(iterate &lt;br /&gt; (initially (progn ,init-forms))&lt;br /&gt; (with-simple-restart &lt;br /&gt;  (skip-photons-loop "Skip photons loop body")&lt;br /&gt;  ,@body)&lt;br /&gt; #+photons-debug &lt;br /&gt; (with-simple-restart&lt;br /&gt;  (skip-swank-request "Skip swank evaluation")&lt;br /&gt;  (let ((connection&lt;br /&gt;   (or swank::*emacs-connection* (swank::default-connection))))&lt;br /&gt; (swank::handle-requests connection t)))&lt;br /&gt; (glfwSwapBuffers)&lt;br /&gt; (until ,exit-test)&lt;br /&gt; (finally (progn ,exit-forms))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;There are actually some subtelties here. The skip-photons-loop restart allows you to recover from an error in the loop body, by recompiling the offending form, when the handle-requests function is called, while the skip-swank-request restart allows you to recover from entering an invalid form at the repl without losing the application.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-6226782880869729525?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/6226782880869729525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=6226782880869729525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6226782880869729525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6226782880869729525'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2010/08/opengl-development-on-windows-with.html' title='OpenGL Development on Windows with Slime'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-7616997381398119712</id><published>2009-09-14T22:41:00.003+01:00</published><updated>2009-09-14T22:44:42.309+01:00</updated><title type='text'>Rooms at last</title><content type='html'>&lt;p&gt;You might have noticed a hiatus on this project, but finally I returned to it to finish off the floorplan: here it is. The rooms were generated mainly by using polar coordinates around the space defined by the corridoor end points, and turned out to be relatively straightforward.&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_2j0bDLIFhtA/Sq64vpoVa8I/AAAAAAAAACY/aSKBlSNVaVU/s1600-h/gotsomerooms.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 250px;" src="http://4.bp.blogspot.com/_2j0bDLIFhtA/Sq64vpoVa8I/AAAAAAAAACY/aSKBlSNVaVU/s320/gotsomerooms.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5381441733522713538" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;At this point, the project really needs to switch away from pyglet to something more useful, that can do the needed 3d extrusion more easily...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-7616997381398119712?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/7616997381398119712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=7616997381398119712' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7616997381398119712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7616997381398119712'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/09/rooms-at-last.html' title='Rooms at last'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_2j0bDLIFhtA/Sq64vpoVa8I/AAAAAAAAACY/aSKBlSNVaVU/s72-c/gotsomerooms.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2298563071386107167</id><published>2009-07-05T08:17:00.003+01:00</published><updated>2009-07-05T08:23:05.535+01:00</updated><title type='text'>Dungeon Generation Part 4: Clearing space for the rooms</title><content type='html'>Here we are, we now have spaces where the rooms are going to go: my initial attempts at creating rooms did not go so well, so I had to backtrack and refactor the code, in order to get this to work.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_2j0bDLIFhtA/SlBUlLLhq0I/AAAAAAAAACQ/pV0eHgl9ZbQ/s1600-h/space_for_dungeons.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 250px;" src="http://4.bp.blogspot.com/_2j0bDLIFhtA/SlBUlLLhq0I/AAAAAAAAACQ/pV0eHgl9ZbQ/s320/space_for_dungeons.PNG" alt="" id="BLOGGER_PHOTO_ID_5354872954576546626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Its actually a fairly simple computation: work out the length of the corridor, scale it, and re-adjust the co-ordinates of each end. This requires some book keeping in terms of data structures: knowing which end terminates at which room, so that you don't accidentally srhink the worong end.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2298563071386107167?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2298563071386107167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2298563071386107167' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2298563071386107167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2298563071386107167'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/07/dungeon-generation-part-4-clearing.html' title='Dungeon Generation Part 4: Clearing space for the rooms'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_2j0bDLIFhtA/SlBUlLLhq0I/AAAAAAAAACQ/pV0eHgl9ZbQ/s72-c/space_for_dungeons.PNG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-1478861615420612395</id><published>2009-06-17T22:50:00.003+01:00</published><updated>2009-06-17T23:09:45.260+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python procedural gamedev'/><title type='text'>Dungeon Generation Part 3 : Doors</title><content type='html'>&lt;p&gt; Thinking about key points in positioning a room, I decided doors were a good idea, so I tried to code up a routine that would reasonably place doors. I interpolated about 30% up along a line and placed a small black perpendicular line prependicular to the line along the centre of the corridor. I went with the simple rule of thumb that a point that connected more than two corridors was the centre of the room. I got this:&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_2j0bDLIFhtA/SjlpOWsaV5I/AAAAAAAAACI/sDX7M0W81-U/s1600-h/doors.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 250px;" src="http://3.bp.blogspot.com/_2j0bDLIFhtA/SjlpOWsaV5I/AAAAAAAAACI/sDX7M0W81-U/s320/doors.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5348421727810115474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Not bad, but not quite right. Probably the best way forward is to decide on an overall radius that will establish the size of the room and fit the doors to that.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-1478861615420612395?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/1478861615420612395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=1478861615420612395' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1478861615420612395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1478861615420612395'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/06/dungeon-generation-part-3-doors.html' title='Dungeon Generation Part 3 : Doors'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_2j0bDLIFhtA/SjlpOWsaV5I/AAAAAAAAACI/sDX7M0W81-U/s72-c/doors.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3321760019367693098</id><published>2009-06-15T22:35:00.003+01:00</published><updated>2009-06-15T22:46:08.013+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python procedural gamedev'/><title type='text'>Dungeon Generation Part Two: Corridors</title><content type='html'>&lt;p&gt;And once the network is complete, we do corridors. This is straigtforward geometry: extrude two lines at either end of our connecting line, perpendicular to said line, then join them up. When you do that you get this: &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_2j0bDLIFhtA/SjbAAldBUJI/AAAAAAAAACA/jFHOfSCOHs4/s1600-h/coridors.png"&gt;&lt;img style="float:center; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 313px;" src="http://4.bp.blogspot.com/_2j0bDLIFhtA/SjbAAldBUJI/AAAAAAAAACA/jFHOfSCOHs4/s400/coridors.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5347672723835408530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;A floorplan which should extrude nicely into the third dimension. However there's one more thing to do before we tackle this, and that is the actual rooms. Which is where things get a tad harder..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3321760019367693098?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3321760019367693098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3321760019367693098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3321760019367693098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3321760019367693098'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/06/dungeon-generation-part-two-corridors.html' title='Dungeon Generation Part Two: Corridors'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_2j0bDLIFhtA/SjbAAldBUJI/AAAAAAAAACA/jFHOfSCOHs4/s72-c/coridors.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-8056952787257219008</id><published>2009-06-11T13:05:00.003+01:00</published><updated>2009-06-11T14:31:19.056+01:00</updated><title type='text'>Dungeon generation for fun and..well, fun...</title><content type='html'>&lt;p&gt;Recently I was inspired by the &lt;a href="http://www.youtube.com/watch?v=-d2-PtK4F6Y"&gt;PixelCity&lt;/a&gt; series of articles. I was impressed what could be achieved by judicious application of basic OpenGL and some clever aesthetic decisions. I'm inspired enough to try the same thing, only with dungeons. My weapons of choice are &lt;a href="http://www.pyglet.org/"&gt;pyglet&lt;/a&gt; and Python.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The first and most obvious thing to try was to generate a network of corridors. Here's what I ended up with.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_2j0bDLIFhtA/SjEGsT4i_hI/AAAAAAAAAB4/86Kk497Wf1M/s1600-h/network.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 313px;" src="http://3.bp.blogspot.com/_2j0bDLIFhtA/SjEGsT4i_hI/AAAAAAAAAB4/86Kk497Wf1M/s400/network.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5346061590986948114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I generated this mainly by picking a point and then connecting it to one of it's closest neighbours. The points are initially distributed on a grid and peturbed by a random amount to make the layout less "manhattan" like. The order the points are picked in is related to the grid order, which is why you see a "spine" at the side of the dungeon. I thought this would make for interersting gameplay: monster - infested branches connected by a relatively safe trunk. So this is what I went with. In the next part, we will get some corridoor walls. Once I have a decent looking dungeon, I will release the source.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-8056952787257219008?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/8056952787257219008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=8056952787257219008' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8056952787257219008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8056952787257219008'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/06/dungeon-generation-for-fun-andwell-fun.html' title='Dungeon generation for fun and..well, fun...'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_2j0bDLIFhtA/SjEGsT4i_hI/AAAAAAAAAB4/86Kk497Wf1M/s72-c/network.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-7762140474510083710</id><published>2009-02-07T00:07:00.003Z</published><updated>2009-02-07T00:11:53.639Z</updated><title type='text'>Give it a kick, it might still be going..</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_2j0bDLIFhtA/SYzRC69wl3I/AAAAAAAAABw/00ynqp3BNRI/s1600-h/MeshMixer.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://2.bp.blogspot.com/_2j0bDLIFhtA/SYzRC69wl3I/AAAAAAAAABw/00ynqp3BNRI/s400/MeshMixer.png" alt="" id="BLOGGER_PHOTO_ID_5299840709626468210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Just to prove I haven't been completely inactive on the project front since my flirtation with Lisp (which isn't over yet, either, just maturing slowly), here's a screenshot of yet another thing. Basically this is a mesh importer for the excellent OGRE engine, powered by wxWidgets and The Open Asset Import Library. It doesn't handle textures or bones yet, but it does more than enough for now as the Open Asset Import Library imports an ungodly number of formats, it should be possible to magpie bits of free art from the web in whatever format and assemble them into a passable scene using this thing..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-7762140474510083710?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/7762140474510083710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=7762140474510083710' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7762140474510083710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/7762140474510083710'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2009/02/give-it-kick-it-might-still-be-going.html' title='Give it a kick, it might still be going..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_2j0bDLIFhtA/SYzRC69wl3I/AAAAAAAAABw/00ynqp3BNRI/s72-c/MeshMixer.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3581567045835394118</id><published>2008-12-16T14:42:00.003Z</published><updated>2008-12-26T15:52:21.471Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='emacs help lisp f1'/><title type='text'>More Emacs Help</title><content type='html'>As well as keying the help provided by Google in Emacs to the major-mode, it's possible to use it with multiple libraries as well. For instance, the following snippet lets me look up documentation for one library (OGRE) by pressing 'o' and for another by pressing 'a' , rather like the Slime selector, discussed previously. It's a huseful way of pulling together doxygen API documentation when working on clonk-loads of libraries, as is all to typical of C++ or Java development.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun search-site-url (keyword &amp;amp;optional site inurl lucky)&lt;br /&gt; "Do a Google search for KEYWORD. Restrict to SITE and INURL, if specified.&lt;br /&gt;Jump to best match (I Feel Lucky) if LUCKY set.&lt;br /&gt;"&lt;br /&gt;;;  (message (list keyword site inurl lucky))&lt;br /&gt; (concat "http://www.google.com/"&lt;br /&gt;         (format "search?q=%s" (url-hexify-string keyword))&lt;br /&gt;         (if site (format "+site:%s" (url-hexify-string site)))&lt;br /&gt;         (if inurl (format "+inurl:%s" (url-hexify-string inurl)))&lt;br /&gt;         (if lucky "&amp;amp;btnI")))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defun help-selector ()&lt;br /&gt; (interactive)&lt;br /&gt; (message "Select [%s]: "&lt;br /&gt;          (apply #'string (mapcar #'car help-selector-methods)))&lt;br /&gt; (let* ((ch (save-window-excursion&lt;br /&gt;              (select-window (minibuffer-window))&lt;br /&gt;              (read-char)))&lt;br /&gt;        (params (find ch help-selector-methods :key #'car)))&lt;br /&gt;   (browse-url (apply #'search-site-url (thing-at-point 'symbol) (list   (third params) (fourth params) (fifth params))))))&lt;br /&gt;&lt;br /&gt;(defvar help-selector-methods '(( ?a "Assimp"&lt;br /&gt;                                    "assimp.sourceforge.net" "/lib_html/" t)&lt;br /&gt;                               ( ?o "Ogre"&lt;br /&gt;                                    "www.ogre3d.org"  "/docs/api/html/" t)&lt;br /&gt;                               ( ?w "WxWidgets"&lt;br /&gt;                                     "docs.wxwidgets.org" "/stable/" t)))&lt;br /&gt;&lt;br /&gt;(global-set-key [(shift f1)] 'help-selector)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3581567045835394118?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3581567045835394118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3581567045835394118' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3581567045835394118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3581567045835394118'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/12/more-emacs-help.html' title='More Emacs Help'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-5096933452982633210</id><published>2008-08-21T02:59:00.002+01:00</published><updated>2008-08-21T03:03:46.218+01:00</updated><title type='text'>Lambda of the Daleks</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_2j0bDLIFhtA/SKzM84vMvBI/AAAAAAAAABo/Q-BNP0sALgk/s1600-h/screenshot-0259.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_2j0bDLIFhtA/SKzM84vMvBI/AAAAAAAAABo/Q-BNP0sALgk/s400/screenshot-0259.png" alt="" id="BLOGGER_PHOTO_ID_5236785813119613970" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;As promised, the Daleks appear. They have been loaded dynamically from an md2 whilst the framework was running. Sometimes I find myself fighting my C++ reflexes. There's no need to bring the framework down in order to change it. It still seems like magic when I edit a function definition, compile it and *bam* the change appears in the game window...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;...one day, all software will be developed this way. Onwards..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-5096933452982633210?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/5096933452982633210/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=5096933452982633210' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/5096933452982633210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/5096933452982633210'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/08/lambda-of-daleks.html' title='Lambda of the Daleks'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_2j0bDLIFhtA/SKzM84vMvBI/AAAAAAAAABo/Q-BNP0sALgk/s72-c/screenshot-0259.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2358380807128001931</id><published>2008-08-17T17:02:00.002+01:00</published><updated>2008-08-17T17:04:32.153+01:00</updated><title type='text'>And now for a bit of swank..</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_2j0bDLIFhtA/SKhL_hbIawI/AAAAAAAAABg/_IXIy3KH0bM/s1600-h/screenshot-1701.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_2j0bDLIFhtA/SKhL_hbIawI/AAAAAAAAABg/_IXIy3KH0bM/s400/screenshot-1701.png" alt="" id="BLOGGER_PHOTO_ID_5235518121494211330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Now my testbed talks happily to emacs via slime. That's the "exploratory" part of "exploratory game developement.". Next up: Daleks...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2358380807128001931?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2358380807128001931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2358380807128001931' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2358380807128001931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2358380807128001931'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/08/and-now-for-bit-of-swank.html' title='And now for a bit of swank..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_2j0bDLIFhtA/SKhL_hbIawI/AAAAAAAAABg/_IXIy3KH0bM/s72-c/screenshot-1701.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3194732145912730894</id><published>2008-08-17T00:19:00.004+01:00</published><updated>2008-08-17T00:22:37.152+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp sbcl glfw opengl'/><title type='text'>And now for something completley different.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_2j0bDLIFhtA/SKdg27OF37I/AAAAAAAAABY/OUmejvbMxkM/s1600-h/screenshot-0017.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_2j0bDLIFhtA/SKdg27OF37I/AAAAAAAAABY/OUmejvbMxkM/s400/screenshot-0017.png" alt="" id="BLOGGER_PHOTO_ID_5235259588567490482" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;You guessed it - another testbed. This time, in 100% Common Lisp (SBCL), just for comparison.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3194732145912730894?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3194732145912730894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3194732145912730894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3194732145912730894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3194732145912730894'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/08/and-now-for-something-completly.html' title='And now for something completley different.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_2j0bDLIFhtA/SKdg27OF37I/AAAAAAAAABY/OUmejvbMxkM/s72-c/screenshot-0017.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-9033330248725110266</id><published>2008-08-13T11:33:00.003+01:00</published><updated>2008-08-13T11:36:22.588+01:00</updated><title type='text'>More testbed</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_2j0bDLIFhtA/SKK46E3whUI/AAAAAAAAABQ/hk2AKlhdj-c/s1600-h/Testbed1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_2j0bDLIFhtA/SKK46E3whUI/AAAAAAAAABQ/hk2AKlhdj-c/s400/Testbed1.png" alt="" id="BLOGGER_PHOTO_ID_5233949024837469506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I've done some more playing around with that testbed, integrating ECL and G3Ds Shape API. It works ok, apart from a few wrinkles. It might even be the beginnings of a nice educational app for learning 3d transforms and the like. The main improvement is that the REPL gives you error feedback rather than crashing the app when you give it a bad form. A distinct must for interactivity...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-9033330248725110266?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/9033330248725110266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=9033330248725110266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/9033330248725110266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/9033330248725110266'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/08/more-testbed.html' title='More testbed'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_2j0bDLIFhtA/SKK46E3whUI/AAAAAAAAABQ/hk2AKlhdj-c/s72-c/Testbed1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-5802334484664821421</id><published>2008-07-22T12:42:00.003+01:00</published><updated>2008-07-22T12:48:36.375+01:00</updated><title type='text'>What next?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_2j0bDLIFhtA/SIXIenef-4I/AAAAAAAAAA0/MfQZanHKyK0/s1600-h/testbed.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_2j0bDLIFhtA/SIXIenef-4I/AAAAAAAAAA0/MfQZanHKyK0/s400/testbed.png" alt="" id="BLOGGER_PHOTO_ID_5225803370951867266" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Embedding&lt;a href="http://ecls.sourceforge.net/"&gt; ECLS &lt;/a&gt;in a 3D Engine - &lt;a href="http://g3d-cpp.sourceforge.net/"&gt;G3D&lt;/a&gt; - proved remarkably easy. The question is - now what. What should live on the Lisp side and what should live on the C++ side? Geometry for C++? AI for Lisp..what about collisions, then? Hmm..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-5802334484664821421?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/5802334484664821421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=5802334484664821421' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/5802334484664821421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/5802334484664821421'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/07/what-next.html' title='What next?'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_2j0bDLIFhtA/SIXIenef-4I/AAAAAAAAAA0/MfQZanHKyK0/s72-c/testbed.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2116233505706487590</id><published>2008-07-16T16:34:00.010+01:00</published><updated>2008-07-17T09:17:33.273+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Emacs Lisp Google Firefox Help'/><title type='text'>Using Google for Context Sensitive Help in Emacs</title><content type='html'>&lt;p&gt;&lt;br /&gt;Here's a hack that combines three of the most useful things in the known Universe: Google, Emacs and Firefox. Emacs 22.x has a standard method for invoking a browser: the browse URL function. To customise it use:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;M-x customize-group browse-url&lt;br /&gt;&lt;/pre&gt;We are interested in the settings: &lt;b&gt;Browse Url Browser Function&lt;/b&gt; which should be set to &lt;pre&gt;browse-url-firefox&lt;/pre&gt;Then there is &lt;b&gt;Browse Url Firefox Program&lt;/b&gt; which should be set to the full path of wherever firefox lives on your machine, and &lt;b&gt;Browse Url Firefox New Window Is Tab&lt;/b&gt; which should be on to prevent multiple firefoxen cluttering up your windows when you try this.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now that you have customized everything, you drop a crafted function into your .emacs and bind it to a key:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; -- INTEGRATED HELP&lt;br /&gt;(require 'url)&lt;br /&gt;(defun search-site-url (site url keyword)&lt;br /&gt;(concat "http://www.google.com/"&lt;br /&gt;    (format "search?q=%s+site:%s+inurl:%s&amp;amp;btnI"  &lt;br /&gt;        (url-hexify-string keyword)  &lt;br /&gt;        (url-hexify-string site)  &lt;br /&gt;        (url-hexify-string url))))&lt;br /&gt;&lt;br /&gt;(defun wxhelp ()&lt;br /&gt;"Open a window showing the wxWidgets documentation for the word under the point"&lt;br /&gt;(interactive)&lt;br /&gt;(browse-url (search-site-url  "docs.wxwidgets.org" "2\\\\.8\\\\.6" &lt;br /&gt;               (thing-at-point 'symbol))))&lt;br /&gt;&lt;br /&gt;(global-set-key "\C-h\C-w" 'wxhelp)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Now, if you type Control H Control W while the cursor is over a symbol, Emacs will look it up via Google. For instance, if your cursor is over wxApp, by the magic of "I'm feeling Lucky", Google will find &lt;b&gt;http://docs.wxwidgets.org/2.8.6/wx_wxapp.html&lt;/b&gt; which is the manual page for &lt;b&gt;wxApp&lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Obviously the interesting function here is &lt;pre&gt;site-search-url&lt;/pre&gt;which munges up an URL to feed to google to make it search a specific site for a keyword, filtering URLs that do not contain a certian string. The highly escaped \\\\ is to ensure that 2\.8\.6 appears in the final URL so that Google treats . as a literal.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The great utility of this hack is its universiality. It will work for any language or library with a sanely organised reference web site. Language specific lookup  functions based on sites like &lt;a href="http://www.cppreference.com"&gt;cppreference.com&lt;/a&gt; are left as an exercise for the reader...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2116233505706487590?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2116233505706487590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2116233505706487590' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2116233505706487590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2116233505706487590'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/07/using-google-for-context-sensitive-help.html' title='Using Google for Context Sensitive Help in Emacs'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-8917271239286487502</id><published>2008-03-14T06:25:00.003Z</published><updated>2008-03-14T06:49:14.930Z</updated><title type='text'>Emacs Selectors</title><content type='html'>&lt;p&gt;One of the nicer things that comes with slime is the slime-selector: it's just a little buffer switching thing, that lets you press r to switch to the repl buffer, d to switch to the debugger buffer, s to switch to the scratch buffer and so forth. Bound to a function key, it's an extraordinarily convenient way of switching to a specific buffer.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Of course, it's geared to SLIME and Lisp, but when coding C++ on the day job I often find myself switching between code, the debugger, shell and compilation buffer, so without further ado, here is the C equivalent, which is easily hacked up to include other buffers, too: actually, I'm beginning to think something like this functionality should be in emacs by default, as it eliminates a lot of keyboard gymnastics.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; slime selector clone for c  ----------------------------------&lt;br /&gt;&lt;br /&gt;(defvar c-selector-methods nil)&lt;br /&gt;&lt;br /&gt;(defun c-selector ()&lt;br /&gt;  (interactive)&lt;br /&gt;  (message "Select [%s]: "&lt;br /&gt;           (apply #'string (mapcar #'car c-selector-methods)))&lt;br /&gt;  (let* ((ch (save-window-excursion&lt;br /&gt;               (select-window (minibuffer-window))&lt;br /&gt;                              (read-char)))&lt;br /&gt;         (method (find ch c-selector-methods :key #'car)))&lt;br /&gt;    (cond ((null method)&lt;br /&gt;           (message (format "No method for charachter: %s" ch))&lt;br /&gt;           (ding)&lt;br /&gt;           (sleep-for 1)&lt;br /&gt;           (discard-input)&lt;br /&gt;           (c-selector))&lt;br /&gt;          (t &lt;br /&gt;           (funcall (third method))))))&lt;br /&gt;          &lt;br /&gt;         &lt;br /&gt;(defmacro def-c-selector-method (key description &amp;rest body)&lt;br /&gt;  `(setq c-selector-methods&lt;br /&gt;         (sort* (cons (list ,key ,description&lt;br /&gt;                            (lambda () &lt;br /&gt;                              (let ((buffer (progn ,@body)))&lt;br /&gt;                                (cond ((get-buffer buffer)&lt;br /&gt;                                       (switch-to-buffer buffer))&lt;br /&gt;                                      (t&lt;br /&gt;                                       (message  "No such buffer")&lt;br /&gt;                                       (ding))))))&lt;br /&gt;                      (remove* ,key c-selector-methods :key #'car))&lt;br /&gt;                #'&lt; :key #'car)))&lt;br /&gt;  &lt;br /&gt;(def-c-selector-method ?d "GDB debugger buffer"&lt;br /&gt;  gud-comint-buffer)&lt;br /&gt;&lt;br /&gt;(def-c-selector-method ?g "Grep buffer"&lt;br /&gt;  grep-last-buffer)&lt;br /&gt;&lt;br /&gt;(def-c-selector-method ?l "Buffer List"&lt;br /&gt;  (let ((result (get-buffer "*buffer-selection*")))&lt;br /&gt;    (if result&lt;br /&gt;        result&lt;br /&gt;      ((bs-show)&lt;br /&gt;       (get-buffer "*buffer-selection*")))))&lt;br /&gt;&lt;br /&gt;(def-c-selector-method ?c "Compilation buffer"&lt;br /&gt;  (let ((result (get-buffer "*compilation*")))&lt;br /&gt;    (if result&lt;br /&gt;        result&lt;br /&gt;      (compilation-find-buffer))))&lt;br /&gt;&lt;br /&gt;(def-c-selector-method ?s "Shell buffer"&lt;br /&gt;  (get-buffer "*shell*"))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-8917271239286487502?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/8917271239286487502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=8917271239286487502' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8917271239286487502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8917271239286487502'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/03/emacs-selectors.html' title='Emacs Selectors'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-8344371585250340378</id><published>2008-02-22T17:36:00.006Z</published><updated>2008-02-23T07:12:28.396Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='commonlisp asdf newbies'/><title type='text'>ASDF for the slightly confused</title><content type='html'>&lt;p&gt;Well, you have a shiny new lisp compiler/interpreter/environment on your machine, and like an eager and smart newbie you want to do something with it. Right there and then many lisp newbies go SPLAT and end up as a bug on a windscreen, later to be scraped off and fed to Guido's pet snake. So here is &lt;a href="http://www.cliki.net/asdf"&gt;ASDF&lt;/a&gt; for confused newbies (a very different proposition from a dummy, who should go back to reading bright yellow paperbacks and programming Java in the enterprise shop window).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;ASDF is about 500 lines of lisp source, and a dot asd file is the lisp equivalent of the ubqutious make; you can't do anything in a serious modern lisp environment without it, so lets take you through it step by step. An asd file describes a system that contains modules and components. Components are usually individual files. Modules are collections of files, usually in subdirectories. Let's look at an example dot asd file: this one is for cowl - a simple opengl gui written by William Robinson who is working on Cityscape, a promising&lt;br /&gt;game found at &lt;a href="https://trac.wvr.me.uk/cityscape"&gt;this &lt;/a&gt;address.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;(defsystem #:cowl-ftgl&lt;br /&gt; :depends-on (#:cffi)&lt;br /&gt; :description "FTGL Common Lisp wrapper for Cowl."&lt;br /&gt; :components ((:module "src"&lt;br /&gt;              :components &lt;br /&gt;             ((:file "cowl-ftgl")))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The defsystem form then defines a system with one component which is a module called src which in turn contains one component in a file called cowl-ftgl, which will be a lisp file, naturally: since it's in a module called src, it will be loaded in the src directory below the directory that holds the dot asd file. Sometimes it is necessary to wrap the defsystem form in it's own package using defpackage and a throwaway package name. We do not do that here because we do not define any symbols that we would need to refer to externally, but we would need to if we were defining new component classes or methods to be used in the system, examples of which will follow later in the article.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Components, modules and systems are defined as CLOS objects in asdf.lisp, so of course they can be operated upon with generic functions, and there are quite a few that come with asdf. The key one is named with Arc-like gnomicness: "oos" - which I imagine is short for "Operate on System". It takes at least two parameters:  the operation to perform and the system to perform it on.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The operation you are most likely to perfom is load-op: this loads and compiles a system, and the form is simply:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;(asdf:oos 'asdf:load-op 'system-name)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Other operations are &lt;span style="font-weight: bold;"&gt;compile-op&lt;/span&gt;, and &lt;span style="font-weight: bold;"&gt;test-op&lt;/span&gt;: the latter will only have meaning if the author of your system has provided tests, as some packages do.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;ASDF will search for systems using the list of functions referred to by *system-definition-search-functions* used to search for .asd files in the filesystem. By default this contains only one function, (sysdef-central-registry-search) which is perfectly adequate for file systems with symbolic links. The modus operandi on such system is to have a share/common-lisp/systems directory populated with symbolic links to dot asd files which may be downloaded and untarred in any part of the fs tree to which the user has access. Then the (sysdef-central-registry-search) scans the list of directories referred to by *central-registry* for dot asd files containing the system which it needs to operate on.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;To put it another way, procedurally this translates to:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; Download your asdf package &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Unzip - say to ~/thinngy/cl-blab &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Note that ~/thinngy/cl-blab/cl-blab.asd is the system. &lt;/li&gt;&lt;br /&gt;&lt;li&gt; Create a ~/share/common-lisp/systems directory for systems&lt;br /&gt;&lt;/li&gt;&lt;li&gt; &lt;pre&gt;cd ~/share/common-lisp/system&lt;br /&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt; &lt;pre&gt;ln -s ~/thinggy/cl-blab/cl-blab.asd cl-blab.asd&lt;br /&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt; now fire up your lisp and enter..&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; for systems that don't do (require 'asdf)&lt;br /&gt;(load #"/path/to/asdf.lisp")&lt;br /&gt;&lt;br /&gt;;; the / on the end of the path is important, don't forget it&lt;br /&gt;(push #"/home/me/share/common-lisp/systems/" asdf:*central-registry*)&lt;br /&gt;&lt;br /&gt;(asdf:oos 'asdf:load-op 'cl-blab)&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;For Windows the situation is sligtly more complicated: either you write your own search function *or*, more practically apply a &lt;a href="http://www.lichteblau.com/blubba/shortcut/"&gt;patch &lt;/a&gt;that lets you use shortcuts in place of symlinks.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You'd be right to point out that this is on the laborious side, but the purpose of this article is to demonstrate how asdf *works*. There are two packages for automating lisp package and  asdf system installation: &lt;a href="http://www.cliki.net/ASDF-Install"&gt;asdf-install&lt;/a&gt; and &lt;a href="http://common-lisp.net/project/clbuild/"&gt;clbuild&lt;/a&gt;, which I encourage newbies to investigate, in the usual sadistic exercise for the reader.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Why go through all this palaver with asdf? Well the beauty of asdf is that systems, components and modules are in fact CLOS objects, so we can do tricks like this:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(cffi:load-foreign-library &lt;br /&gt; (make-pathname &lt;br /&gt;  :name "cftgl" &lt;br /&gt;  :type "so" &lt;br /&gt;  :directory (directory-namestring (asdf:component-pathname &lt;br /&gt;                                    (asdf:find-system :cowl-ftgl)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;..which loads "clftgl.so" which is found in the same directory as the dot asd file containing the system definition. Highly useful when distributing a C shared lib that wraps a C++ library so that it can be called into from Lisp.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The fact that source files are component, lets us write specialist methods for different kinds of source file such as c-source-file, java-source-file, html-file (all defined in asdf.lisp) allows asdf to work as a make replacement, operating on non-lisp source, thus:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defmethod output-files ((op compile-op) (c c-source-file))&lt;br /&gt;    (list (make-pathname :type "o" :defaults&lt;br /&gt;                                                 (component-pathname c))))&lt;br /&gt;&lt;br /&gt;(defmethod perform ((op compile-op) (c c-source-file))&lt;br /&gt;    (unless&lt;br /&gt;       (= 0 (run-shell-command "/usr/bin/gcc -fPIC -o ~S -c ~S"&lt;br /&gt;                               (unix-name (car (output-files op c)))&lt;br /&gt;                               (unix-name (component-pathname c))))&lt;br /&gt;     (error 'operation-error :operation op :component c)))&lt;br /&gt;&lt;br /&gt;(defmethod perform ((operation load-op) (c c-source-file))&lt;br /&gt;    t)   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;There is an extended example of this kind of thing where asdf is extended to work with a fortran to lisp converter &lt;a href="http://prxq.wordpress.com/2007/05/06/asdf-system-definition-files-for-fortran-77-codes/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;p&gt;To conclude: like many things in Lisp, asdf is prickly for newbies and takes time to get to know and use well. However, when you do you can do things with it for which you'd normally need another build system, independent of your language. As Brucio would observe: Lisp does not have this limitation and Common Lispers laugh at things like ant.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-8344371585250340378?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/8344371585250340378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=8344371585250340378' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8344371585250340378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8344371585250340378'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2008/02/asdf-for-slightly-confused.html' title='ASDF for the slightly confused'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4617240653245589017</id><published>2007-12-28T14:47:00.003Z</published><updated>2008-02-22T17:47:43.334Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='slime emacs commonlisp etags'/><title type='text'>Hippie Expand and Autocompletion in Emacs</title><content type='html'>&lt;p&gt;The Emacs way of doing auto - completion is known as &lt;a href="http://www.emacswiki.org/cgi-bin/wiki/HippieExpand"&gt;Hippie Expand&lt;/a&gt; which is a function that uses a variety of methods to try and expand an incomplete word near the point. Why it's called Hippie Expand I have no idea. The name is a bit misleading; for a long time I thought it was related to zippy or pinhead. Perhaps it's something to do with Emacs being used and written by hippies, who knows?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The nice thing about hippie expand is that like many things in Emacs, it can be customized and expanded, via the make-hippie-expand function. For instance, here is the hippie-expand function I use for c-mode&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(make-hippie-expand-function&lt;br /&gt;'(try-expand-dabbrev-visible&lt;br /&gt; try-expand-dabbrev-from-kill&lt;br /&gt; try-expand-dabbrev-all-buffers&lt;br /&gt; try-complete-file-name-partially&lt;br /&gt; try-complete-file-name)))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;This function first tries to expand the thing found at the point as a dynamic abbreviation, which is based on a scan of existing text for words or symbols with the same beginning as the one at the point. For instance, if "catalogue" is in the buffer, and you expand "cat", then "catalogue" will be one of the expansions offered, which is useful if "catalogue" is a variable name you use a lot.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The hippie expand function is bound to a key (I use M-/) and each press of that key will cycle through the possible completions for you. It's not Intellisense, but it does cut down on typing if you use descriptive variable names.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It's also fairly trivial to write your own hippie-expand function. Here is an example of a hippie expand function which does completion based on a list of current tags - which are sometimes more useful than dabbrevs.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; This is a simple function to return the point at the beginning of the symbol to be completed&lt;br /&gt;(defun he-tag-beg ()&lt;br /&gt;(let ((p&lt;br /&gt;      (save-excursion&lt;br /&gt;        (backward-word 1)&lt;br /&gt;        (point))))&lt;br /&gt; p))&lt;br /&gt;&lt;br /&gt;;; The actual expansion function&lt;br /&gt;(defun try-expand-tag (old)&lt;br /&gt;;; old is true if we have already attempted an expansion&lt;br /&gt;(unless  old&lt;br /&gt; ;; he-init-string is used to capture the string we are trying to complete&lt;br /&gt; (he-init-string (he-tag-beg) (point))&lt;br /&gt; ;; he-expand list is the list of possible expansions&lt;br /&gt; (setq he-expand-list (sort&lt;br /&gt;                       (all-completions he-search-string 'tags-complete-tag) 'string-lessp)))&lt;br /&gt;;; now we go through the list, looking for an expansion that isn't in the table of previously&lt;br /&gt;;; tried expansions&lt;br /&gt;(while (and he-expand-list&lt;br /&gt;           (he-string-member (car he-expand-list) he-tried-table))&lt;br /&gt;           (setq he-expand-list (cdr he-expand-list)))&lt;br /&gt;;; if we didn't have any expansions left, reset the expansion list&lt;br /&gt;(if (null he-expand-list)&lt;br /&gt;   (progn&lt;br /&gt;     (when old (he-reset-string))&lt;br /&gt;     ())&lt;br /&gt; ;; otherwise offer the expansion at the head of the list&lt;br /&gt; (he-substitute-string (car he-expand-list))&lt;br /&gt; ;; and put that expansion into the tried expansions list&lt;br /&gt; (setq he-expand-list (cdr he-expand-list))&lt;br /&gt; t))&lt;br /&gt;;; done, now we just use it as a clause in our make-hippie-expand-function (as above)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Hippie-expand isn't the only auto-completion gizmo I work with in Emacs; there is also slime-complete-symbol which does symbol completion for my while I am working in &lt;a href="http://www.emacswiki.org/cgi-bin/wiki/SlimeMode"&gt;SLIME&lt;/a&gt;. This can be neatly integrated into hippie-expand, like so..&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;;; hippie expand slime symbol&lt;br /&gt;(defun he-slime-symbol-beg ()&lt;br /&gt;(let ((p&lt;br /&gt;      (slime-symbol-start-pos)))&lt;br /&gt; p))&lt;br /&gt;&lt;br /&gt;(defun try-expand-slime-symbol (old)&lt;br /&gt;(unless  old&lt;br /&gt; (he-init-string (he-slime-symbol-beg) (point))&lt;br /&gt; (setq he-expand-list (sort&lt;br /&gt;                       (car (slime-contextual-completions (slime-symbol-start-pos) (slime-symbol-end-pos))) 'string-lessp)))&lt;br /&gt;(while (and he-expand-list&lt;br /&gt;           (he-string-member (car he-expand-list) he-tried-table))&lt;br /&gt;           (setq he-expand-list (cdr he-expand-list)))&lt;br /&gt;(if (null he-expand-list)&lt;br /&gt;   (progn&lt;br /&gt;     (when old (he-reset-string))&lt;br /&gt;     ())&lt;br /&gt; (he-substitute-string (car he-expand-list))&lt;br /&gt; (setq he-expand-list (cdr he-expand-list))&lt;br /&gt; t))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;EDIT&lt;/span&gt;: With newer (CVS and 3.0) versions of SLIME the api for symbol completion&lt;br /&gt;has changed and the hippie-expand function for slime symbol completion is..&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; hippie expand slime symbol&lt;br /&gt;(defun he-slime-symbol-beg ()&lt;br /&gt;(let ((p&lt;br /&gt;      (slime-symbol-start-pos)))&lt;br /&gt; p))&lt;br /&gt;&lt;br /&gt;(defun try-expand-slime-symbol (old)&lt;br /&gt;(unless  old&lt;br /&gt; (he-init-string (he-slime-symbol-beg) (point))&lt;br /&gt; (setq he-expand-list (sort&lt;br /&gt;                       (car (slime-simple-completions&lt;br /&gt;                             (buffer-substring-no-properties (slime-symbol-start-pos) (slime-symbol-end-pos))))&lt;br /&gt;                       'string-lessp)))&lt;br /&gt;(while (and he-expand-list&lt;br /&gt;           (he-string-member (car he-expand-list) he-tried-table))&lt;br /&gt;           (setq he-expand-list (cdr he-expand-list)))&lt;br /&gt;(if (null he-expand-list)&lt;br /&gt;   (progn&lt;br /&gt;     (when old (he-reset-string))&lt;br /&gt;     ())&lt;br /&gt; (he-substitute-string (car he-expand-list))&lt;br /&gt; (setq he-expand-list (cdr he-expand-list))&lt;br /&gt; t))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4617240653245589017?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4617240653245589017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4617240653245589017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4617240653245589017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4617240653245589017'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/12/hippie-expand-and-autocompletion-in.html' title='Hippie Expand and Autocompletion in Emacs'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4111521988800406584</id><published>2007-12-20T17:04:00.000Z</published><updated>2007-12-20T17:15:24.684Z</updated><title type='text'>Final Results of Informal Programming Language Comparison.</title><content type='html'>&lt;p&gt;A recent post on programming.reddit.com about profanity in comments was highly amusing if you are childish enough to be amused by such things - I am, anyway - set me to thinking about the Google Code search thing and whether it could be used in  any profitable way to compare programming languages. I quicky hit upon the hypothesis that programmers content with their language would be more likely to type comments along the lines of "this rocks" and ones more disaffected might type comments along the lines of "this sucks".&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Hence, all that was required was to write a bit of code to tabutlate the search results by language and a clear winner would emerge. It did, and it wasn't the one I was expecting.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;My final choice of metric was the ratio of incidence of the word "sucks" and the word "rocks" scaled by the frequency of a netural control word such as "okay" (and even so, poor old FORTH did not get a lookin as it got zero hits on any of these). I call this the suckage to rockage ration and henceforth regard it as the gold standard of programming metrics. Without further ado, here are the charts and the code.&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qh62Z7RjI/AAAAAAAAAAk/Q7LZXDlhnXw/s1600-h/languages.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qh62Z7RjI/AAAAAAAAAAk/Q7LZXDlhnXw/s400/languages.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5146103556632954418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Controversy is roughly the distance between suckage and rockage - high if the language arouses strong feelings, low if it's boring, staple stuff.&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_2j0bDLIFhtA/R2qiJmZ7RkI/AAAAAAAAAAs/RrVm8Y2sxaQ/s1600-h/suckage-to-rockage.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_2j0bDLIFhtA/R2qiJmZ7RkI/AAAAAAAAAAs/RrVm8Y2sxaQ/s400/suckage-to-rockage.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5146103810036024898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;C!? I really didn't expect this. It might be due to the inability of the search to separate out C and C++. It's almost certianly due to a low suckage rather than a high rockage.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The code, which is Public Domain, if anyone is inclined to tinker.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(asdf:oos 'asdf:load-op 'drakma)&lt;br /&gt;(asdf:oos 'asdf:load-op 's-xml)&lt;br /&gt;(asdf:oos 'asdf:load-op 'clot)&lt;br /&gt;&lt;br /&gt;(defpackage :code-index (:use :cl :clot :drakma :s-xml))&lt;br /&gt;&lt;br /&gt;(in-package :code-index)&lt;br /&gt;&lt;br /&gt;(defun code-search (regexp &amp;key language license file package (output-type :sxml))&lt;br /&gt;  (let ((url (concatenate 'string&lt;br /&gt;                    "http://google.com/codesearch/feeds/search?q=" &lt;br /&gt;                    (when language (concatenate 'string  "lang:" language "+"))&lt;br /&gt;                    (when license (concatenate 'string "license:" license "+"))&lt;br /&gt;                    (when file (concatenate 'string "file:" file "+"))&lt;br /&gt;                    (when package (concatenate 'string "package:" package "+"))&lt;br /&gt;                    regexp)))&lt;br /&gt;  (multiple-value-bind (body-or-stream status-code headers uri stream must-close reason-phrase)       &lt;br /&gt;      (drakma::http-request url&lt;br /&gt;        :force-binary t)&lt;br /&gt;    (declare (ignore headers must-close stream reason-phrase))&lt;br /&gt;    (format t "Request for ~A~%" uri)&lt;br /&gt;    (format t "Status code ~A~%" status-code)&lt;br /&gt;    (parse-xml-string (flexi-streams:octets-to-string  body-or-stream :external-format (flexi-streams:make-external-format :utf-8)) ))))&lt;br /&gt;&lt;br /&gt;;; google returns a malformed string every time - wallies!&lt;br /&gt;;;(code-search "sucks" :language "pascal")&lt;br /&gt;&lt;br /&gt;(defun code-search-hit-count (results)&lt;br /&gt;  (parse-integer (cadr (nth 5 results))))&lt;br /&gt;&lt;br /&gt;(defun calculate-index-for-language (lang)&lt;br /&gt;  (format t "~&amp;For Langauge : ~A~&amp;" lang)  &lt;br /&gt;  (let* ((control-index &lt;br /&gt;         (code-search-hit-count (code-search "okay" :language lang)))&lt;br /&gt;        (suckage-index &lt;br /&gt;         (/ (code-search-hit-count (code-search "sucks" :language lang))&lt;br /&gt;            control-index))&lt;br /&gt;        (rockage-index  &lt;br /&gt;         (/  (code-search-hit-count (code-search "rocks" :language lang)) &lt;br /&gt;             control-index)))&lt;br /&gt;     (format t "Suckage index ~D~&amp;" suckage-index)&lt;br /&gt;     (format t "Rockage index ~D~&amp;" rockage-index)&lt;br /&gt;     (format t "Controversy index ~F~&amp;" (sqrt (+ (* rockage-index rockage-index) (* suckage-index suckage-index))))&lt;br /&gt;;;     ;; admittedly it's a bust if no one ever says that language Y sucks, but how probable is that ;-)&lt;br /&gt;;;    ;; but forth managed it...&lt;br /&gt;     (format t "Suckage/Rockage ratio ~D~&amp;" (/ rockage-index suckage-index))&lt;br /&gt;    (list control-index suckage-index rockage-index &lt;br /&gt;                   (sqrt (+ (* rockage-index rockage-index) (* suckage-index suckage-index)))&lt;br /&gt;                   (/ rockage-index suckage-index))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defun compare-languages ()&lt;br /&gt;  (let* ((language-list '("c"  "ruby" "perl" "pascal"  "erlang" "javascript" "java" "smalltalk" "python" "lisp" "haskell" "ocaml"))&lt;br /&gt;         (language-results  (mapcar #'calculate-index-for-language language-list))&lt;br /&gt;         (control-list (append (list "Frequency" "brown") (mapcar #'(lambda (x) (nth 0 x)) language-results)))&lt;br /&gt;         (suckage-list (append  (list "Suckage" "red") (mapcar #'(lambda (x) (nth 1 x)) language-results)))&lt;br /&gt;         (rockage-list (append  (list "Rockage" "green") (mapcar #'(lambda (x) (nth 2 x)) language-results)))&lt;br /&gt;         (controversy-list (append (list "Controversy" "blue") (mapcar #'(lambda (x) (nth 3 x)) language-results)))&lt;br /&gt;         (suckage/rockage-list (append (list "Rockage to Suckage ratio" "yellow") (mapcar #'(lambda (x) (nth 4 x)) language-results))))&lt;br /&gt;      (cl-gd:with-image* (640 480)&lt;br /&gt;        (fill-image 0 0 :color "white")&lt;br /&gt;        (plot-bar-chart (list suckage-list rockage-list controversy-list) :x-axis-labels language-list :bar-width .8 :vgrid t)&lt;br /&gt;        (cl-gd:write-image-to-file&lt;br /&gt;         (make-pathname :defaults clot-system:*base-directory* :name "languages" :type "png") :if-exists :supersede))&lt;br /&gt;      (cl-gd:with-image* (640 480)&lt;br /&gt;        (fill-image 0 0 :color "white")&lt;br /&gt;        (plot-bar-chart (list suckage/rockage-list) :x-axis-labels language-list :bar-width .8 :vgrid t)&lt;br /&gt;        (cl-gd:write-image-to-file&lt;br /&gt;         (make-pathname :defaults clot-system:*base-directory* :name "suckage-to-rockage" :type "png") :if-exists :supersede))))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4111521988800406584?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4111521988800406584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4111521988800406584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4111521988800406584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4111521988800406584'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/12/final-results-of-informal-programming.html' title='Final Results of Informal Programming Language Comparison.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qh62Z7RjI/AAAAAAAAAAk/Q7LZXDlhnXw/s72-c/languages.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4237878446568332792</id><published>2007-12-20T16:33:00.001Z</published><updated>2007-12-20T16:36:42.219Z</updated><title type='text'>Programming Language Comparison</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qZ_2Z7RiI/AAAAAAAAAAc/Pbkux060DJ4/s1600-h/languages.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qZ_2Z7RiI/AAAAAAAAAAc/Pbkux060DJ4/s400/languages.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5146094846439278114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;First cut.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4237878446568332792?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4237878446568332792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4237878446568332792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4237878446568332792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4237878446568332792'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/12/programming-language-comparison.html' title='Programming Language Comparison'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_2j0bDLIFhtA/R2qZ_2Z7RiI/AAAAAAAAAAc/Pbkux060DJ4/s72-c/languages.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-6836032975732406043</id><published>2007-11-27T21:26:00.000Z</published><updated>2007-11-27T21:29:14.580Z</updated><title type='text'>Devhelp Inform Designers Manual</title><content type='html'>&lt;p&gt;Another devhelp file courtesy of &lt;a href="http://developer.berlios.de/projects/htmlhelp/"&gt;pyhtmlhelp&lt;/a&gt;. This time it's the &lt;a href="http://www.yagc.ndo.co.uk/code/inform.tar.bz2"&gt;Inform Designers manual.&lt;/a&gt;. Yes, I'm writing  interactive fiction, again..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-6836032975732406043?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/6836032975732406043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=6836032975732406043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6836032975732406043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/6836032975732406043'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/11/devhelp-inform-designers-manual.html' title='Devhelp Inform Designers Manual'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-8386415560739286327</id><published>2007-10-14T08:53:00.000+01:00</published><updated>2007-10-14T08:56:08.748+01:00</updated><title type='text'>Change-class extensibility</title><content type='html'>&lt;p&gt;I made an interesting minor discovery today: change-class is extensible in much the way &lt;br /&gt;initialize-instance is...&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CL-USER&gt; (defclass test-class () ((a-slot :initarg :a-slot-value :initform 0)))&lt;br /&gt;#&lt;STANDARD-CLASS TEST-CLASS&gt;&lt;br /&gt;CL-USER&gt; (defclass derived-class (test-class) ())&lt;br /&gt;#&lt;STANDARD-CLASS DERIVED-CLASS&gt;&lt;br /&gt;CL-USER&gt; (defmethod update-instance-for-different-class :after ((old test-class) (new derived-class) &amp;key fixup-information)&lt;br /&gt;           (format t "~A " fixup-information))&lt;br /&gt;#&lt;STANDARD-METHOD UPDATE-INSTANCE-FOR-DIFFERENT-CLASS :AFTER (TEST-CLASS&lt;br /&gt;                                                              DERIVED-CLASS) {A97F421}&gt;&lt;br /&gt;CL-USER&gt; (make-instance 'test-class :a-slot-value 27)&lt;br /&gt;#&lt;TEST-CLASS {B27F3A9}&gt;&lt;br /&gt;CL-USER&gt; (defparameter *test-instance* (make-instance 'test-class :a-slot-value 27))&lt;br /&gt;*TEST-INSTANCE*&lt;br /&gt;CL-USER&gt; (change-class *test-instance* 'derived-class :fixup-information "Hello World")&lt;br /&gt;Hello World &lt;br /&gt;#&lt;DERIVED-CLASS {B2D2BF1}&gt;&lt;br /&gt;CL-USER&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I'm not sure I actually &lt;b&gt;want&lt;/b&gt; to use this, but it's nice to know it's there..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-8386415560739286327?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/8386415560739286327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=8386415560739286327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8386415560739286327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/8386415560739286327'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/10/change-class-extensibility.html' title='Change-class extensibility'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-37382324176893598</id><published>2007-08-29T12:01:00.000+01:00</published><updated>2007-08-29T12:15:21.640+01:00</updated><title type='text'>Automating Visual Studio</title><content type='html'>&lt;p&gt;Visual Studio is both a curse and a boon. A boon because it is a very good IDE for debugging. A curse because it's restricted to a single platform and tends to lock out third-party editors, such as Emacs, jEdit, SlickEdit, or whatever it is you use.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Most decent editors expect to be able to compile a file via a shell command, capture that commands output, and then scan the output for errors, enabling you to jump to the exact locaton. This can be via make, scons, and the regexp can be modified for different compilers.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;However the 'Export Makefile' command dissapeared from Visual Studio with version six. The functionality to compile individual files from the command line has gone, leaving the non-Microsoft editor user with a dilemma. Whether to change their editing habits for the sake of a peaceful life with the GUI, or forsake the ability to compile individual files - whole projects can still be built via the DevEnv command.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;However there is a nice Python hack that lets you get at the compiling functionality. You need to use the Python Win32 COM extensions to access Visual Stduio  automation from Python. Micheal Graz created this script and tightly integrated it with Vim. I've taken out the vim-specific parts, and added only one Emacs specific part (in dte_get_file) to invoke Emacs when &amp;quot;getting&amp;quot; the current file from Visual Studio. The compilation output now goes to the command line rather than a vim quickfix buffer, so it should be possible to adapt this to your needs.&lt;/p&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;span class="keyword"&gt;import&lt;/span&gt; os, sys, re, time, pywintypes, win32com.client&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;vsWindowKindTaskList&lt;/span&gt;     = &lt;span class="string"&gt;'{4A9B7E51-AA16-11D0-A8C5-00A0C921A4D2}'&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;vsWindowKindFindResults1&lt;/span&gt; = &lt;span class="string"&gt;'{0F887920-C2B6-11D2-9375-0080C747D9A0}'&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;vsWindowKindFindResults2&lt;/span&gt; = &lt;span class="string"&gt;'{0F887921-C2B6-11D2-9375-0080C747D9A0}'&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;vsWindowKindOutput&lt;/span&gt;       = &lt;span class="string"&gt;'{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;vsBuildStateNotStarted&lt;/span&gt; = 1   &lt;span class="comment"&gt;# Build has not yet been started.&lt;br /&gt;&lt;/span&gt;&lt;span class="variable-name"&gt;vsBuildStateInProgress&lt;/span&gt; = 2   &lt;span class="comment"&gt;# Build is currently in progress.&lt;br /&gt;&lt;/span&gt;&lt;span class="variable-name"&gt;vsBuildStateDone&lt;/span&gt; = 3         &lt;span class="comment"&gt;# Build has been completed&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;dte_compile_file&lt;/span&gt; ():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        dte.ExecuteCommand (&lt;span class="string"&gt;'Build.Compile'&lt;/span&gt;)&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt; Exception, e:&lt;br /&gt;        _dte_exception (e)&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="comment"&gt;# ExecuteCommand is not synchronous so we have to wait&lt;br /&gt;&lt;/span&gt;    &lt;span class="keyword"&gt;while&lt;/span&gt; dte.Solution.SolutionBuild.BuildState == vsBuildStateInProgress:&lt;br /&gt;        time.sleep (0.1)&lt;br /&gt;    dte_output (&lt;span class="string"&gt;'output'&lt;/span&gt;)&lt;br /&gt;    _status_msg (&lt;span class="string"&gt;'Compile file complete'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;dte_build_solution&lt;/span&gt;():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; dte.CSharpProjects.Count:&lt;br /&gt;        dte.Documents.CloseAll()&lt;br /&gt;    _dte_raise ()&lt;br /&gt;    _dte_output_activate ()&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        dte.Solution.SolutionBuild.Build (1)&lt;br /&gt;        &lt;span class="comment"&gt;# Build is not synchronous so we have to wait&lt;br /&gt;&lt;/span&gt;        &lt;span class="keyword"&gt;while&lt;/span&gt; dte.Solution.SolutionBuild.BuildState != vsBuildStateDone:&lt;br /&gt;            time.sleep (0.25)&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt; Exception, e:&lt;br /&gt;        _dte_exception (e)&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    dte_output (&lt;span class="string"&gt;'output'&lt;/span&gt;)&lt;br /&gt;    _status_msg (&lt;span class="string"&gt;'Build solution complete'&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;dte_output&lt;/span&gt; (window_kind):&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; window_kind == &lt;span class="string"&gt;'find_results_1'&lt;/span&gt;:&lt;br /&gt;        window_name = &lt;span class="string"&gt;'Find Results 1'&lt;/span&gt;&lt;br /&gt;        window_id = vsWindowKindFindResults1&lt;br /&gt;    &lt;span class="keyword"&gt;elif&lt;/span&gt; window_kind == &lt;span class="string"&gt;'find_results_2'&lt;/span&gt;:&lt;br /&gt;        window_name = &lt;span class="string"&gt;'Find Results 2'&lt;/span&gt;&lt;br /&gt;        window_id = vsWindowKindFindResults2&lt;br /&gt;    &lt;span class="keyword"&gt;elif&lt;/span&gt; window_kind == &lt;span class="string"&gt;'output'&lt;/span&gt;:&lt;br /&gt;        window_name = &lt;span class="string"&gt;'Output'&lt;/span&gt;&lt;br /&gt;        window_id = vsWindowKindOutput&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;:&lt;br /&gt;        _msg (&lt;span class="string"&gt;'Error: unrecognized window (%s)'&lt;/span&gt; % window_kind)&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;br /&gt;        &lt;span class="keyword"&gt;print&lt;/span&gt; &lt;span class="string"&gt;"&amp;gt;&amp;gt; Failed to get dte."&lt;/span&gt;&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; window_id == vsWindowKindOutput:&lt;br /&gt;        owp = dte.Windows.Item(window_id).Object.OutputWindowPanes.Item(&lt;span class="string"&gt;'Build'&lt;/span&gt;)&lt;br /&gt;        sel = owp.TextDocument.Selection&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;:&lt;br /&gt;        sel = dte.Windows.Item(window_id).Selection&lt;br /&gt;    sel.SelectAll()&lt;br /&gt;    _status_msg (&lt;span class="string"&gt;'VS %s'&lt;/span&gt; % window_name)&lt;br /&gt;    &lt;span class="keyword"&gt;print&lt;/span&gt; sel.Text&lt;br /&gt;    sel.Collapse()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;dte_get_file&lt;/span&gt; ():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    doc = dte.ActiveDocument&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; doc:&lt;br /&gt;        _status_msg (&lt;span class="string"&gt;'No VS file!'&lt;/span&gt;)&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    pt = doc.Selection.ActivePoint&lt;br /&gt;    file = os.path.join (doc.Path, doc.Name)&lt;br /&gt;    os.system(&lt;span class="string"&gt;"emacsclientw -n +%d:%d %s "&lt;/span&gt; % (pt.Line, pt.DisplayColumn, file))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;dte_put_file&lt;/span&gt; (filename, line_num, col_num):&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; filename:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    io = dte.ItemOperations&lt;br /&gt;    rc = io.OpenFile (os.path.abspath (filename))&lt;br /&gt;    sel = dte.ActiveDocument.Selection&lt;br /&gt;    sel.MoveToLineAndOffset (line_num, col_num)&lt;br /&gt;    _dte_raise ()&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_get_dte&lt;/span&gt; ():&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; win32com.client.GetActiveObject (&lt;span class="string"&gt;'VisualStudio.DTE'&lt;/span&gt;)&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt; pywintypes.com_error:&lt;br /&gt;        _msg (&lt;span class="string"&gt;'Cannot access VisualStudio. Not running?'&lt;/span&gt;)&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="keyword"&gt;None&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="variable-name"&gt;_wsh&lt;/span&gt; = &lt;span class="keyword"&gt;None&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_get_wsh&lt;/span&gt; ():&lt;br /&gt;    &lt;span class="keyword"&gt;global&lt;/span&gt; _wsh&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; _wsh:&lt;br /&gt;        &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;            _wsh = win32com.client.Dispatch (&lt;span class="string"&gt;'WScript.Shell'&lt;/span&gt;)&lt;br /&gt;        &lt;span class="keyword"&gt;except&lt;/span&gt; pywintypes.com_error:&lt;br /&gt;            _msg (&lt;span class="string"&gt;'Cannot access WScript.Shell'&lt;/span&gt;)&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; _wsh&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_dte_raise&lt;/span&gt; ():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        dte.MainWindow.Activate ()&lt;br /&gt;        _get_wsh().AppActivate (dte.MainWindow.Caption)&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;pass&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_dte_output_activate&lt;/span&gt; ():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    dte.Windows.Item(vsWindowKindOutput).Activate()&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_dte_set_autoload&lt;/span&gt; ():&lt;br /&gt;    dte = _get_dte()&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; dte: &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;    p = dte.Properties (&lt;span class="string"&gt;'Environment'&lt;/span&gt;, &lt;span class="string"&gt;'Documents'&lt;/span&gt;)&lt;br /&gt;    p.Item(&lt;span class="string"&gt;'DetectFileChangesOutsideIDE'&lt;/span&gt;).Value = 1&lt;br /&gt;    p.Item(&lt;span class="string"&gt;'AutoloadExternalChanges'&lt;/span&gt;).Value = 1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_dte_exception&lt;/span&gt; (e):&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; isinstance (e, pywintypes.com_error):&lt;br /&gt;        &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;            msg = e[2][2]&lt;br /&gt;        &lt;span class="keyword"&gt;except&lt;/span&gt;:&lt;br /&gt;            msg = &lt;span class="keyword"&gt;None&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;:&lt;br /&gt;        msg = e&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; msg:&lt;br /&gt;        msg = &lt;span class="string"&gt;'Encountered unknown exception'&lt;/span&gt;&lt;br /&gt;    _status_msg (&lt;span class="string"&gt;'ERROR %s'&lt;/span&gt; % msg)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_status_msg&lt;/span&gt; (msg):&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        caption = _get_dte().MainWindow.Caption.split()[0]&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt;:&lt;br /&gt;        caption = &lt;span class="keyword"&gt;None&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; caption:&lt;br /&gt;        msg = msg + &lt;span class="string"&gt;' ('&lt;/span&gt; + caption + &lt;span class="string"&gt;')'&lt;/span&gt;&lt;br /&gt;    _msg (msg)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;_msg&lt;/span&gt; (msg):&lt;br /&gt;    &lt;span class="keyword"&gt;print&lt;/span&gt; &lt;span class="string"&gt;"&amp;gt;&amp;gt; "&lt;/span&gt; + msg&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;#----------------------------------------------------------------------&lt;br /&gt;# eg vsgo.py dte_compile_file&lt;br /&gt;#    vsgo.py dte_put_file GridToolPanelComponent.cpp 10 5&lt;br /&gt;#    vsgo.py dte_get_file&lt;br /&gt;#    vsgo.py dte_build_solution&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="function-name"&gt;main&lt;/span&gt; ():&lt;br /&gt;    prog = os.path.basename(sys.argv[0])&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; len(sys.argv) == 1:&lt;br /&gt;        &lt;span class="keyword"&gt;print&lt;/span&gt; &lt;span class="string"&gt;'echo "ERROR: not enough args to %s"'&lt;/span&gt; % prog&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    fcn_name = sys.argv[1]&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; globals().has_key(fcn_name):&lt;br /&gt;        &lt;span class="keyword"&gt;print&lt;/span&gt; &lt;span class="string"&gt;'echo "ERROR: no such fcn %s in %s"'&lt;/span&gt; % (fcn_name, prog)&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    fcn = globals()[fcn_name]&lt;br /&gt;    &lt;span class="keyword"&gt;try&lt;/span&gt;:&lt;br /&gt;        apply(fcn, sys.argv[2:])&lt;br /&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;except&lt;/span&gt; TypeError, e:&lt;br /&gt;        &lt;span class="keyword"&gt;print&lt;/span&gt; &lt;span class="string"&gt;'echo "ERROR in %s: %s"'&lt;/span&gt; % (prog, str(e))&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;if&lt;/span&gt; __name__ == &lt;span class="string"&gt;'__main__'&lt;/span&gt;: main()&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-37382324176893598?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/37382324176893598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=37382324176893598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/37382324176893598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/37382324176893598'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/08/automating-developer-studio.html' title='Automating Visual Studio'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-654044094757859921</id><published>2007-06-12T09:49:00.000+01:00</published><updated>2007-06-12T09:56:18.326+01:00</updated><title type='text'>Lisp Array Setter Syntax</title><content type='html'>&lt;p&gt; Not the most inituituve in the world &lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defmethod (setf setter-name) (value (self  class-type) x y z)&lt;br /&gt;  (setf (row-major-aref (array-of self) (* x ... blah... ))))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(setf (setter-name self) x-index y-index z-index value)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The thing to remember is that the value always comes first.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-654044094757859921?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/654044094757859921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=654044094757859921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/654044094757859921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/654044094757859921'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/06/lisp-array-setter-syntax.html' title='Lisp Array Setter Syntax'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-1089922039457927866</id><published>2007-06-09T14:06:00.001+01:00</published><updated>2007-06-09T14:31:51.062+01:00</updated><title type='text'>wxWidgets Documentation in Devhelp format</title><content type='html'>&lt;p&gt;This post is what it says on the tin. I converted the wxWidgets help from htb to devhelp using &lt;a href="http://developer.berlios.de/project/showfiles.php?group_id=918"&gt;this&lt;/a&gt; handy help converter. &lt;a href="http://www.yagc.ndo.co.uk/code/wx.tar.bz2"&gt;Here&lt;/a&gt; is the result. It needs to live somewhere where devhelp can find it: usually /usr/share/devhelp/books or ~/.devhelp/books, although the latter did not work for me&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Why did I want devhelp and not HTB. Partly because devhelp integrates much more nicely with Gnome, but also because it made it trivial to get context - sensitive help out of Emacs with this little gem:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun devhelp-word-at-point ()&lt;br /&gt;  "runs devhelp"&lt;br /&gt;  (interactive)&lt;br /&gt;  (setq w (current-word))&lt;br /&gt;  (start-process-shell-command "devhelp" nil "devhelp" "-s" w))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-1089922039457927866?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/1089922039457927866/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=1089922039457927866' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1089922039457927866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/1089922039457927866'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/06/wxwidgets-documentation-in-devhelp_09.html' title='wxWidgets Documentation in Devhelp format'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-4517342317477858198</id><published>2007-06-04T23:24:00.000+01:00</published><updated>2007-06-04T23:32:18.142+01:00</updated><title type='text'>Save Slime And Die</title><content type='html'>&lt;p&gt;The best way to work with a Lisp is to leave it running all the time and hack on it bit by bit, building up your program bit by bit, doing mini-tests and off-the-cuff code as you go along and shaping it..&lt;p&gt;&lt;br /&gt;&lt;p&gt;Except if you are like me, you might be working on a laptop with a limited battery life and have a strict time limit to your lisp hacking. It's bothered me that when working with SLIME the only way to save a core was to start a lisp in a terminal, load up your systems and your files, then dump and use that with C-u M-x slime, which lets you enter a command line to start your lisp.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It annoys me because if you are like me, your code doesn't necessarily capture the actual state of your core: it also contains half a dozen test variables and functions that you entered in the repl and are useful to have hang around. So I tried to find a way to dump and restore core from within slime. I came up with the following function&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun save-slime-and-die (core-file-name)&lt;br /&gt;           ;; close all &lt;br /&gt;  (mapcar #'(lambda (x) (swank::close-connection x)) swank::*connections*)&lt;br /&gt;  #+sb-thread&lt;br /&gt;  (dolist (thread (remove (swank::current-thread) (swank::all-threads)))&lt;br /&gt;    (swank::kill-thread thread))&lt;br /&gt;  (sleep 1)&lt;br /&gt;  (save-lisp-and-die core-file-name))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;It's obviously for sbcl, and the gotcha is that it has to be executed in the *inferior-lisp* buffer, but it works..C-u M-x sbcl --core test.core brings back core dumped with (save-slime-and-die #P"test.core")&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-4517342317477858198?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/4517342317477858198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=4517342317477858198' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4517342317477858198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/4517342317477858198'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/06/save-slime-and-die.html' title='Save Slime And Die'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2860503751323172709</id><published>2007-05-03T23:47:00.002+01:00</published><updated>2007-05-03T23:51:01.226+01:00</updated><title type='text'>CPP Evil</title><content type='html'>Possibly the most incomprehensible line of code I have ever written.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define ALLOCATE_ENGINE_OBJECT(type) reinterpret_cast&amp;lt;Engine##type##Object*&amp;gt;(\&lt;br /&gt;      world.allocate&amp;lt;Engine##type##Object&amp;gt;()-&gt;init_object(\&lt;br /&gt;         type##Pool.allocate&amp;lt;Engine##type##Data&amp;gt;()))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2860503751323172709?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2860503751323172709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2860503751323172709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2860503751323172709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2860503751323172709'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/05/cpp-evil_03.html' title='CPP Evil'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-2756010229111663260</id><published>2007-03-04T18:33:00.001Z</published><updated>2010-12-01T17:54:29.351Z</updated><title type='text'>Unrealscript mode for Emacs</title><content type='html'>Edit: I've since abandoned this mode and moved to a simpler (but less buggy) version not based on cc-mode that lives &lt;a href="http://badbyteblues.blogspot.com/2010/12/unrealscript-mode-for-emacs-reloaded.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;; &lt;/span&gt;&lt;span class="comment"&gt;unrealscript-mode.el --- unrealscript mode derived from cc-mode&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Author:     2007 John Connors&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Maintainer: John Connors &amp;lt;johnc at yagc dot co dot uk&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Created:    March 2007&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Version:    See cc-mode.el&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Keywords:   unrealscript cc-mode languages oop&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This program is free software; you can redistribute it and/or modify&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;it under the terms of the GNU General Public License as published by&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(at your option) any later version.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This program is distributed in the hope that it will be useful,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;GNU General Public License for more details.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;You should have received a copy of the GNU General Public License&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;along with this program; see the file COPYING.  If not, write to&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;the Free Software Foundation, Inc., 59 Temple Place - Suite 330,&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Boston, MA 02111-1307, USA.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;; &lt;/span&gt;&lt;span class="comment"&gt;Commentary:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Note: The interface used in this file requires CC Mode 5.30 or&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;later.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;; &lt;/span&gt;&lt;span class="comment"&gt;Code:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;require&lt;/span&gt; '&lt;span class="constant"&gt;cc-mode&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;These are only required at compile time to get the sources for the&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;language constants.  (The cc-fonts require and the font-lock&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;related constants could additionally be put inside an&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(eval-after-load "font-lock" ...) but then some trickery is&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;necessary to get them compiled.)&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;eval-when-compile&lt;/span&gt;&lt;br /&gt;  (&lt;span class="keyword"&gt;require&lt;/span&gt; '&lt;span class="constant"&gt;cc-langs&lt;/span&gt;)&lt;br /&gt;  (&lt;span class="keyword"&gt;require&lt;/span&gt; '&lt;span class="constant"&gt;cc-fonts&lt;/span&gt;))&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;eval-and-compile&lt;/span&gt;&lt;br /&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Make our mode known to the language constant system.  Use Java&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;mode as the fallback for the constants we don't change here.&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;This needs to be done also at compile time since the language&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;constants are evaluated then.&lt;br /&gt;&lt;/span&gt;  (c-add-language 'unrealscript-mode 'java-mode))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;unrealscript has no boolean but a string and a vector type.&lt;br /&gt;&lt;/span&gt;(c-lang-defconst c-primitive-type-kwds&lt;br /&gt;  unrealscript &lt;br /&gt;  (append &lt;br /&gt;   '(&lt;span class="string"&gt;"bool"&lt;/span&gt; &lt;span class="string"&gt;"name"&lt;/span&gt; &lt;span class="string"&gt;"object"&lt;/span&gt; &lt;span class="string"&gt;"actor"&lt;/span&gt; &lt;span class="string"&gt;"string"&lt;/span&gt; &lt;span class="string"&gt;"vector"&lt;/span&gt;)&lt;br /&gt;   (delete &lt;span class="string"&gt;"boolean"&lt;/span&gt;&lt;br /&gt;           &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Use append to not be destructive on the&lt;br /&gt;&lt;/span&gt;           &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;return value below.&lt;br /&gt;&lt;/span&gt;           (append&lt;br /&gt;            &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Due to the fallback to Java, we need not give&lt;br /&gt;&lt;/span&gt;            &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;a language to `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-lang-const&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;'.&lt;br /&gt;&lt;/span&gt;            (c-lang-const c-primitive-type-kwds)&lt;br /&gt;            nil))))&lt;br /&gt;&lt;br /&gt;(c-lang-defconst c-type-modifier-keywds&lt;br /&gt;   unrealscript&lt;br /&gt;    (append &lt;br /&gt;      '(&lt;span class="string"&gt;"config"&lt;/span&gt; &lt;span class="string"&gt;"deprecated"&lt;/span&gt; &lt;span class="string"&gt;"edfindable"&lt;/span&gt; &lt;span class="string"&gt;"editconstarray"&lt;/span&gt; &lt;br /&gt;        &lt;span class="string"&gt;"editinline"&lt;/span&gt; &lt;span class="string"&gt;"export"&lt;/span&gt; &lt;span class="string"&gt;"noexport"&lt;/span&gt; &lt;span class="string"&gt;"globalconfig"&lt;/span&gt; &lt;br /&gt;        &lt;span class="string"&gt;"localized"&lt;/span&gt; &lt;span class="string"&gt;"const"&lt;/span&gt; &lt;span class="string"&gt;"editconst"&lt;/span&gt; &lt;span class="string"&gt;"input"&lt;/span&gt; &lt;span class="string"&gt;"travel"&lt;/span&gt; &lt;br /&gt;        &lt;span class="string"&gt;"skip"&lt;/span&gt; &lt;span class="string"&gt;"export"&lt;/span&gt;) &lt;br /&gt;      (c-lang-const c-type-modifier-keywds) &lt;br /&gt;      nil))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;   &lt;/span&gt;&lt;span class="comment"&gt;"Keywords introducing extra declaration specifiers in the region&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;between the header and the body \(i.e. the \"K&amp;amp;R-region\") in&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;declarations."&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(c-lang-defconst c-postfix-decl-spec-kwds&lt;br /&gt;  unrealscript&lt;br /&gt;  (append&lt;br /&gt;   '(&lt;span class="string"&gt;"abstract"&lt;/span&gt; &lt;span class="string"&gt;"native"&lt;/span&gt; &lt;span class="string"&gt;"nativereplication"&lt;/span&gt; &lt;span class="string"&gt;"nousercreate"&lt;/span&gt; &lt;span class="string"&gt;"within"&lt;/span&gt; &lt;br /&gt;     &lt;span class="string"&gt;"perobjectconfig"&lt;/span&gt; &lt;span class="string"&gt;"transient"&lt;/span&gt; &lt;span class="string"&gt;"noexport"&lt;/span&gt; &lt;span class="string"&gt;"dependson"&lt;/span&gt; &lt;span class="string"&gt;"exportstructs"&lt;/span&gt; &lt;br /&gt;     &lt;span class="string"&gt;"cacheexempt"&lt;/span&gt; &lt;span class="string"&gt;"hidedropdown"&lt;/span&gt; &lt;span class="string"&gt;"parseconfig"&lt;/span&gt; &lt;span class="string"&gt;"dontcollapsecategories"&lt;/span&gt;&lt;br /&gt;     &lt;span class="string"&gt;"collapsecategories"&lt;/span&gt; &lt;span class="string"&gt;"hidecategories"&lt;/span&gt; &lt;span class="string"&gt;"showcategories"&lt;/span&gt; &lt;span class="string"&gt;"placeable"&lt;/span&gt;&lt;br /&gt;     &lt;span class="string"&gt;"notplaceable"&lt;/span&gt; &lt;span class="string"&gt;"instanced"&lt;/span&gt;)&lt;br /&gt;   (c-lang-const c-postfix-decl-spec-kwds)&lt;br /&gt;   nil))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;   &lt;/span&gt;&lt;span class="comment"&gt;"Keywords that may be followed by a comma separated list of type&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;identifiers, where each optionally can be prefixed by keywords.  (Can&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;also be used for the special case when the list can contain only one&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;element.)"&lt;br /&gt;&lt;/span&gt;(c-lang-defconst c-type-list-kwds&lt;br /&gt;  unrealscript&lt;br /&gt;  (cons &lt;span class="string"&gt;"within"&lt;/span&gt;&lt;br /&gt;        (c-lang-const c-type-list-kwds)))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Function declarations begin with "function" in this language.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;There's currently no special keyword list for that in CC Mode, but&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;treating it as a modifier works fairly well.&lt;br /&gt;&lt;/span&gt;(c-lang-defconst c-modifier-kwds&lt;br /&gt; unrealscript &lt;br /&gt;  (cons&lt;br /&gt;    &lt;span class="string"&gt;"function"&lt;/span&gt; &lt;br /&gt;   (c-lang-const c-modifier-kwds)))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(c-lang-defconst c-block-decls-with-vars&lt;br /&gt;  unrealscript&lt;br /&gt;  (cons &lt;br /&gt;   &lt;span class="string"&gt;"state"&lt;/span&gt; &lt;br /&gt;        (c-lang-const c-other-block-decl-kwds)))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;"Keywords that may be followed by a parenthesis expression that doesn't&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;contain type identifiers."&lt;br /&gt;&lt;/span&gt;(c-lang-defconst c-paren-nontype-kwds&lt;br /&gt;  unrealscript&lt;br /&gt;  (append &lt;br /&gt;   '(&lt;span class="string"&gt;"state"&lt;/span&gt; &lt;span class="string"&gt;"var"&lt;/span&gt;)&lt;br /&gt;   (c-lang-const c-paren-nontype-kwds)&lt;br /&gt;   nil))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;   &lt;/span&gt;&lt;span class="comment"&gt;"Keywords that may be followed by a parenthesis expression containing&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;type identifiers separated by arbitrary tokens."&lt;br /&gt;&lt;/span&gt;(c-lang-defconst c-paren-type-kwds&lt;br /&gt;  unrealscript&lt;br /&gt;  (append&lt;br /&gt;   '(&lt;span class="string"&gt;"config"&lt;/span&gt; &lt;span class="string"&gt;"dependson"&lt;/span&gt;)&lt;br /&gt;   (c-lang-const c-paren-type-kwds)))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;;; No cpp in this language, but there's still a "#exec" directive to&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;;; fontify.  (The definitions for the extra keywords above are enough&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;;; to incorporate them into the fontification regexps for types and&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;;; keywords, so no additional font-lock patterns are required.)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;(c-lang-defconst c-cpp-matchers&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;   &lt;/span&gt;&lt;span class="comment"&gt;unrealscript &lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;       &lt;/span&gt;&lt;span class="comment"&gt;;; Use the eval form for `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;font-lock-keywords&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' to be able to use&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;       &lt;/span&gt;&lt;span class="comment"&gt;;; the `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-preprocessor-face-name&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' variable that maps to a&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;       &lt;/span&gt;&lt;span class="comment"&gt;;; suitable face depending on the (X)Emacs version.&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;;       &lt;/span&gt;&lt;span class="comment"&gt;'(eval . (list "^\\s *\\(#exec\\)\\&amp;gt;\\(.*\\)"&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;          (list 1 c-preprocessor-face-name)&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;          '(2 font-lock-string-face))))&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defcustom&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-font-lock-extra-types&lt;/span&gt; nil&lt;br /&gt;  &lt;span class="doc"&gt;"*List of extra types (aside from the type keywords) to recognize in Unrealscript mode.&lt;br /&gt;Each list item should be a regexp matching a single identifier."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defconst&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-font-lock-keywords-1&lt;/span&gt; &lt;br /&gt;  (c-lang-const c-matchers-1 unrealscript)&lt;br /&gt;  &lt;span class="doc"&gt;"Minimal highlighting for UNREALSCRIPT mode."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defconst&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-font-lock-keywords-2&lt;/span&gt; &lt;br /&gt;  (c-lang-const c-matchers-2 unrealscript)&lt;br /&gt;  &lt;span class="doc"&gt;"Fast normal highlighting for UNREALSCRIPT mode."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defconst&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-font-lock-keywords-3&lt;/span&gt; &lt;br /&gt;  (c-lang-const c-matchers-3 unrealscript)&lt;br /&gt;  &lt;span class="doc"&gt;"Accurate normal highlighting for UNREALSCRIPT mode."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defvar&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-font-lock-keywords&lt;/span&gt; unrealscript-font-lock-keywords-3&lt;br /&gt;  &lt;span class="doc"&gt;"Default expressions to highlight in UNREALSCRIPT mode."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defvar&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-mode-syntax-table&lt;/span&gt; nil&lt;br /&gt;  &lt;span class="doc"&gt;"Syntax table used in unrealscript-mode buffers."&lt;/span&gt;)&lt;br /&gt;(or unrealscript-mode-syntax-table&lt;br /&gt;    (setq unrealscript-mode-syntax-table&lt;br /&gt;      (funcall (c-lang-const c-make-mode-syntax-table unrealscript))))&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defvar&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-mode-abbrev-table&lt;/span&gt; nil&lt;br /&gt;  &lt;span class="doc"&gt;"Abbreviation table used in unrealscript-mode buffers."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(c-define-abbrev-table 'unrealscript-mode-abbrev-table&lt;br /&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Keywords that if they occur first on a line might alter the&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;syntactic context, and which therefore should trig reindentation&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;when they are completed.&lt;br /&gt;&lt;/span&gt;  '((&lt;span class="string"&gt;"else"&lt;/span&gt; &lt;span class="string"&gt;"else"&lt;/span&gt; c-electric-continued-statement 0)&lt;br /&gt;    (&lt;span class="string"&gt;"while"&lt;/span&gt; &lt;span class="string"&gt;"while"&lt;/span&gt; c-electric-continued-statement 0)))&lt;br /&gt;&lt;br /&gt;(&lt;span class="keyword"&gt;defvar&lt;/span&gt; &lt;span class="variable-name"&gt;unrealscript-mode-map&lt;/span&gt; (&lt;span class="keyword"&gt;let&lt;/span&gt; ((map (c-make-inherited-keymap)))&lt;br /&gt;              &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Add bindings which are only useful for UNREALSCRIPT&lt;br /&gt;&lt;/span&gt;              map)&lt;br /&gt;  &lt;span class="doc"&gt;"Keymap used in unrealscript-mode buffers."&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;(easy-menu-define unrealscript-menu unrealscript-mode-map &lt;span class="string"&gt;"UNREALSCRIPT Mode Commands"&lt;/span&gt;&lt;br /&gt;          &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;Can use `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;unrealscript&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' as the language for `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-mode-menu&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;'&lt;br /&gt;&lt;/span&gt;          &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;since its definition covers any language.  In&lt;br /&gt;&lt;/span&gt;          &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;this case the language is used to adapt to the&lt;br /&gt;&lt;/span&gt;          &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;nonexistence of a cpp pass and thus removing some&lt;br /&gt;&lt;/span&gt;          &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;irrelevant menu alternatives.&lt;br /&gt;&lt;/span&gt;          (cons &lt;span class="string"&gt;"UNREALSCRIPT"&lt;/span&gt; (c-lang-const c-mode-menu unrealscript)))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;;&lt;/span&gt;&lt;span class="comment"&gt;###Autoload&lt;br /&gt;&lt;/span&gt;(add-to-list 'auto-mode-alist '(&lt;span class="string"&gt;"\\.uc\\'"&lt;/span&gt; . unrealscript-mode))&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;;;;&lt;/span&gt;&lt;span class="comment"&gt;###&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="warning"&gt;autoload&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;(&lt;span class="keyword"&gt;defun&lt;/span&gt; &lt;span class="function-name"&gt;unrealscript-mode&lt;/span&gt; ()&lt;br /&gt;  &lt;span class="doc"&gt;"Major mode for editing UNREALSCRIPT UnrealScript is a&lt;br /&gt;Java-like object-orientated programming (OOP) language created by&lt;br /&gt;Epic Games for programming in-game content for the UnrealEngine.&lt;br /&gt; &lt;br /&gt;The hook `&lt;/span&gt;&lt;span class="doc"&gt;&lt;span class="constant"&gt;c-mode-common-hook&lt;/span&gt;&lt;/span&gt;&lt;span class="doc"&gt;' is run with no args at mode&lt;br /&gt;initialization, then `&lt;/span&gt;&lt;span class="doc"&gt;&lt;span class="constant"&gt;unrealscript-mode-hook&lt;/span&gt;&lt;/span&gt;&lt;span class="doc"&gt;'.&lt;br /&gt;&lt;br /&gt;Key bindings:&lt;br /&gt;\\{unrealscript-mode-map}"&lt;/span&gt;&lt;br /&gt;  (interactive)&lt;br /&gt;  (kill-all-local-variables)&lt;br /&gt;  (c-initialize-cc-mode t)&lt;br /&gt;  (set-syntax-table unrealscript-mode-syntax-table)&lt;br /&gt;  (setq major-mode 'unrealscript-mode&lt;br /&gt;    mode-name &lt;span class="string"&gt;"UnrealScript"&lt;/span&gt;&lt;br /&gt;    local-abbrev-table unrealscript-mode-abbrev-table&lt;br /&gt;    abbrev-mode t)&lt;br /&gt;  (use-local-map c-mode-map)&lt;br /&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;`&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-init-language-vars&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' is a macro that is expanded at compile&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;time to a large `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;setq&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' with all the language variables and their&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;customized values for our language.&lt;br /&gt;&lt;/span&gt;  (c-init-language-vars unrealscript-mode)&lt;br /&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;`&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-common-init&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' initializes most of the components of a CC Mode&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;buffer, including setup of the mode menu, font-lock, etc.&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;There's also a lower level routine `&lt;/span&gt;&lt;span class="comment"&gt;&lt;span class="constant"&gt;c-basic-common-init&lt;/span&gt;&lt;/span&gt;&lt;span class="comment"&gt;' that&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;only makes the necessary initialization to get the syntactic&lt;br /&gt;&lt;/span&gt;  &lt;span class="comment-delimiter"&gt;;; &lt;/span&gt;&lt;span class="comment"&gt;analysis and similar things working.&lt;br /&gt;&lt;/span&gt;  (c-common-init 'unrealscript-mode)&lt;br /&gt;  (easy-menu-add unrealscript-menu)&lt;br /&gt;  (run-hooks 'c-mode-common-hook)&lt;br /&gt;  (run-hooks 'unrealscript-mode-hook)&lt;br /&gt;  (setq font-lock-keywords-case-fold-search t)&lt;br /&gt;  (c-update-modeline))&lt;br /&gt;&lt;br /&gt;&amp;#12;&lt;br /&gt;(&lt;span class="keyword"&gt;provide&lt;/span&gt; '&lt;span class="constant"&gt;unrealscript-mode&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-2756010229111663260?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/2756010229111663260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=2756010229111663260' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2756010229111663260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/2756010229111663260'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/03/unrealscript-mode-for-emacs.html' title='Unrealscript mode for Emacs'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-3927160919995533774</id><published>2007-03-01T23:37:00.000Z</published><updated>2007-03-01T23:44:55.711Z</updated><title type='text'>Isometric Projection Matrix</title><content type='html'>&lt;p&gt;One thing that seems to get asked a lot is how to create an isometric style game using a 3d pipline and textured quads, instead of 2d sprite tiles. It is also a question that does not seem to get answered much, so I thought I would whip out a quick demonstration of how to do it with the Irrlicht Engine.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;One thing to note is that this is not a textbook isometric projection which is a form of axonometric projection, but a fudge that makes the width and height of a cube in the viewport equal. This emulates tile based games nicely. Of course, with a &amp;quot;real&amp;quot; projection it might be possible to dynamically change the projection angle, which might be an interesting effect.&lt;/p&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;irrlicht.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;irr&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;core&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;scene&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;video&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;io&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="keyword"&gt;namespace&lt;/span&gt; &lt;span class="constant"&gt;gui&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="function-name"&gt;main&lt;/span&gt;()&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;   &lt;br /&gt;   &lt;span class="type"&gt;IrrlichtDevice&lt;/span&gt; *&lt;span class="variable-name"&gt;device&lt;/span&gt; =&lt;br /&gt;      createDevice( &lt;span class="constant"&gt;video&lt;/span&gt;::EDT_SOFTWARE2, &lt;span class="type"&gt;dimension2d&lt;/span&gt;&amp;lt;s32&amp;gt;(640, 480), 16,&lt;br /&gt;                    &lt;span class="constant"&gt;false&lt;/span&gt;, &lt;span class="constant"&gt;false&lt;/span&gt;, &lt;span class="constant"&gt;false&lt;/span&gt;, 0);&lt;br /&gt;   &lt;br /&gt;   device-&amp;gt;setWindowCaption(L&lt;span class="string"&gt;"Isometric Projection"&lt;/span&gt;);&lt;br /&gt;   &lt;br /&gt;   &lt;span class="type"&gt;IVideoDriver&lt;/span&gt;* &lt;span class="variable-name"&gt;driver&lt;/span&gt; = device-&amp;gt;getVideoDriver();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;while&lt;/span&gt;(device-&amp;gt;run())&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/*&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;        Anything can be drawn between a beginScene() and an endScene()&lt;br /&gt;        call. The beginScene clears the screen with a color and also&lt;br /&gt;        the depth buffer if wanted. Then we let the Scene Manager and&lt;br /&gt;        the GUI Environment draw their content. With the endScene()&lt;br /&gt;        call everything is presented on the screen.&lt;br /&gt;      */&lt;/span&gt;&lt;br /&gt;      driver-&amp;gt;beginScene(&lt;span class="constant"&gt;true&lt;/span&gt;, &lt;span class="constant"&gt;true&lt;/span&gt;, SColor(255,100,101,140));&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * we are not interested in this transform so let us set it to&lt;br /&gt;       * identity&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;      driver-&amp;gt;setTransform(&lt;span class="constant"&gt;video&lt;/span&gt;::ETS_WORLD, &lt;span class="constant"&gt;core&lt;/span&gt;::matrix4());&lt;br /&gt;      driver-&amp;gt;setTransform(&lt;span class="constant"&gt;video&lt;/span&gt;::ETS_VIEW, &lt;span class="constant"&gt;core&lt;/span&gt;::matrix4());&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * first portion of transform - in matrix form&lt;br /&gt;       * x' = (x - z)&lt;br /&gt;       * y' = y + 0.5 * ( x + z )&lt;br /&gt;       * this maps the z to the x and y axes in such a way that &lt;br /&gt;       * the result appears isometric. &lt;br /&gt;       */&lt;/span&gt; &lt;br /&gt;      &lt;span class="type"&gt;matrix4&lt;/span&gt; &lt;span class="variable-name"&gt;projMatrix&lt;/span&gt;;&lt;br /&gt;      projMatrix.makeIdentity();&lt;br /&gt;      projMatrix.M[0] = 1.0f;&lt;br /&gt;      projMatrix.M[8] = -1.0f;&lt;br /&gt;      projMatrix.M[1] = 0.5f;&lt;br /&gt;      projMatrix.M[5] = 1.0f;&lt;br /&gt;      projMatrix.M[9] = 0.5f;&lt;br /&gt;      projMatrix.M[10] = 0.0;&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * second portion of transform -- scale to fit clipping&lt;br /&gt;       * volume. If the scale is 1.0f then the unit vectors fit the&lt;br /&gt;       * clipping volume. The volume is a cuboid, centered in the origin.&lt;br /&gt;       * The scaling will determine the size of this volume which will&lt;br /&gt;       * contain the portion of the world that we can see.&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;      &lt;span class="type"&gt;f32&lt;/span&gt; &lt;span class="variable-name"&gt;scale&lt;/span&gt; = 4.0f;&lt;br /&gt;      &lt;span class="type"&gt;matrix4&lt;/span&gt; &lt;span class="variable-name"&gt;clipMatrix&lt;/span&gt;;&lt;br /&gt;      clipMatrix.buildProjectionMatrixOrthoLH(2 * scale, 2 * scale ,-1 * scale, 2 * scale);&lt;br /&gt;       &lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * concatentate transform - we multiply transforms together in&lt;br /&gt;       * the opposite order to that which we would apply them to a&lt;br /&gt;       * vector because of the law of associativity applies to&lt;br /&gt;       * matrices, but not commutivity and NM != MN fun,&lt;br /&gt;       * eh..matrices..gotta luv em..&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;      projMatrix = clipMatrix * projMatrix;&lt;br /&gt;        &lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * ok we now have our projection matrix&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;      driver-&amp;gt;setTransform(&lt;span class="constant"&gt;video&lt;/span&gt;::ETS_PROJECTION, projMatrix);&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * draw unit x, y, and z vectors in our new space&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;x axis is red&lt;br /&gt;&lt;/span&gt;      driver-&amp;gt;draw3DLine(vector3df(-1.0, 0.0, 0.0),&lt;br /&gt;                         vector3df(1.0, 0.0, 0.0),&lt;br /&gt;                         SColor(255,255,0,0));&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;y axis is green&lt;br /&gt;&lt;/span&gt;      driver-&amp;gt;draw3DLine(vector3df(0.0, -1.0, 0.0),&lt;br /&gt;                         vector3df(0.0, 1.0, 0.0),&lt;br /&gt;                         SColor(255,0,255,0));&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;z axis is blue&lt;br /&gt;&lt;/span&gt;      driver-&amp;gt;draw3DLine(vector3df(0.0, 0.0, -1.0),&lt;br /&gt;                         vector3df(0.0, 0.0, 1.0),&lt;br /&gt;                         SColor(255,0,0,255));&lt;br /&gt;           &lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;       * done&lt;br /&gt;       */&lt;/span&gt;&lt;br /&gt;      driver-&amp;gt;endScene();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   device-&amp;gt;drop();&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;return&lt;/span&gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-3927160919995533774?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/3927160919995533774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=3927160919995533774' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3927160919995533774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/3927160919995533774'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2007/03/isometric-projection-matrix.html' title='Isometric Projection Matrix'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-116756753966960282</id><published>2006-12-31T12:16:00.000Z</published><updated>2006-12-31T12:19:00.753Z</updated><title type='text'>New Year Coding Resolutions</title><content type='html'>&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Finish cl-screen&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finish and post my x86 assembler in Common Lisp to CommonLisp.net&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Write a new software renderer in Lisp&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Finally get the hang of writing setf expanders&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Write an animation testbed in Lisp&lt;/li&gt;&lt;br /&gt;&lt;li&gt;At least make a start at writing a game again.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Learn some Haskell&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Get more famililar with partial differential equations, the nabala operator and the jacobian matrix&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-116756753966960282?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/116756753966960282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=116756753966960282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116756753966960282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116756753966960282'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/12/new-year-coding-resolutions.html' title='New Year Coding Resolutions'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-116750839771046088</id><published>2006-12-30T19:24:00.000Z</published><updated>2006-12-30T19:57:38.793Z</updated><title type='text'>A Games/3d oriented lisp</title><content type='html'>&lt;p&gt;Thoughts about the desirable properties of a Lisp optimised for fast 3d games use.&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Generational and/or incremental garbage collection.&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Incremental means gc collection can be time-bounded; generational will be more effective in culling short lived, small objects, and give us cache wins. Allocation should be trivial as possible.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Native vector, matrix and quaternion types that map to SIMD&lt;/li&gt;&lt;br /&gt;&lt;p&gt;De riguer for fast 3d operations: an inline assembler build into the language, coupled with macro expansion would probably mean that these not be coded&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Hashtables&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Too useful for lots of things&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Property lists&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Ditto: perfect for game AI&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Simple function call syntax&lt;/li&gt;&lt;br /&gt;&lt;p&gt;CL's function call syntax is relatively complicated and makes optimisation harder.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Fast single dimensional arrays&lt;/li&gt;&lt;br /&gt;&lt;p&gt;A neccesity.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Unhygenic macros&lt;/li&gt;&lt;br /&gt;&lt;p&gt;A big system can be build from a relatively small one via CL-style macro-expansion..&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Readtable&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Ideal for rolling gustom syntax. CL's readtable has too many characters reserved. We need to keep ours free&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Optional compile-time type declarations&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Enables an optimiser to do a better job, and keeps more unboxed values arond&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Integrated shader compiler&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Shaders are just too useful not to have: an embedded lisp style shader with macroexpansion facilities would help a great deal.&lt;p&gt;&lt;br /&gt;&lt;li&gt;Sockets&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Needed for multiplayer games, and editors that run alongside the game&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Good FFI - to bind to c/c++ libraries&lt;/li&gt;&lt;br /&gt;&lt;p&gt;A lot of exisiting code is in C - eg OpenGL&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Fast, streamable file I/O library&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Streaming in new data as the game runs is very important for large worlds.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Heaps&lt;/li&gt;&lt;br /&gt;&lt;p&gt;We will need to allocate hunks of memory for talking to 'C' libraries and just because we can? Not sure about this one&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Datatypes /library specifically for geometry - flexible mesh loading/compilation&lt;/li&gt;&lt;br /&gt;&lt;p&gt;We will need acres of geometry, as usual..&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Datatypes / library specifically for texture and image processing&lt;/li&gt;&lt;br /&gt;&lt;p&gt;And acres of texture maps, etc applied to them&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Datatypes / library for spatial structures: quadrees, bsp trees, octtrees, r-trees&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Good Scene management requires these&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Aggressive optimization: register colouring, scheduling, peephole..etc&lt;/li&gt;&lt;br /&gt;&lt;p&gt;Goes without saying&lt;/p&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;That will do for now..;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-116750839771046088?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/116750839771046088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=116750839771046088' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116750839771046088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116750839771046088'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/12/games3d-oriented-lisp.html' title='A Games/3d oriented lisp'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-116567905682753149</id><published>2006-12-09T14:45:00.000Z</published><updated>2006-12-09T15:44:31.466Z</updated><title type='text'>The birth of an assembler.</title><content type='html'>The story so far..It's all surprisingly easy in Lisp...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;; SLIME 2006-10-28&lt;br /&gt;CL-USER&gt; (asdf:oos 'asdf:load-op 'cl-x86-asm)&lt;br /&gt;; loading system definition from /home/johnc/.sbcl/systems/cl-x86-asm.asd&lt;br /&gt;; into #&lt;PACKAGE "ASDF0"&gt;&lt;br /&gt;; registering #&lt;SYSTEM :CL-X86-ASM {A8571F9}&gt; as CL-X86-ASM&lt;br /&gt;; compiling file "/home/johnc/projects/msc/x86instructions.lisp" (written 09 DEC 2006 03:29:02 PM):&lt;br /&gt;; compiling (IN-PACKAGE :CL-X86-ASM)&lt;br /&gt;; compiling (DEFPARAMETER *INSTRUCTION-TABLE* ...)&lt;br /&gt;; compiling (DEFPARAMETER *INSTRUCTION-LOOKUP-TABLE* ...)&lt;br /&gt;; compiling (DEFUN MAKE-INSTRUCTION-HASH-TABLE ...)&lt;br /&gt;; compiling (DEFUN LOOKUP-INSTRUCTION ...)&lt;br /&gt;&lt;br /&gt;; /home/johnc/projects/msc/x86instructions.fasl written&lt;br /&gt;; compilation finished in 0:00:00&lt;br /&gt;; compiling file "/home/johnc/projects/msc/x86-assembler.lisp" (written 09 DEC 2006 03:28:00 PM):&lt;br /&gt;; compiling (IN-PACKAGE :CL-X86-ASM)&lt;br /&gt;; compiling (DEFPARAMETER *CURRENT-BITS-SIZE* ...)&lt;br /&gt;; compiling (DEFUN SWITCH-BITS ...)&lt;br /&gt;; compiling (DEFUN SYMBOL-IS-IN-PACKAGE ...)&lt;br /&gt;; compiling (DEFUN IS-OPERAND-TYPE-P ...)&lt;br /&gt;; compiling (DEFUN FIND-CORRECT-DESCRIPTION ...)&lt;br /&gt;; compiling (DEFUN EXTRACT-ENCODING-FROM-DESCRIPTION ...)&lt;br /&gt;; compiling (DEFUN PROCESS-ENCODING ...)&lt;br /&gt;&lt;br /&gt;; file: /home/johnc/projects/msc/x86-assembler.lisp&lt;br /&gt;; in: DEFUN PROCESS-ENCODING&lt;br /&gt;;     (DEFUN CL-X86-ASM::PROCESS-ENCODING&lt;br /&gt;;          (CL-X86-ASM::INSTRUCTION CL-X86-ASM::OPERANDS&lt;br /&gt;;           CL-X86-ASM::OPERAND-DESCRIPTION)&lt;br /&gt;;     CL-X86-ASM::OPERAND-DESCRIPTION)&lt;br /&gt;; --&gt; PROGN EVAL-WHEN SB-IMPL::%DEFUN SB-INT:NAMED-LAMBDA &lt;br /&gt;; ==&gt;&lt;br /&gt;;   #'(SB-INT:NAMED-LAMBDA CL-X86-ASM::PROCESS-ENCODING&lt;br /&gt;;                          (CL-X86-ASM::INSTRUCTION CL-X86-ASM::OPERANDS&lt;br /&gt;;                           CL-X86-ASM::OPERAND-DESCRIPTION)&lt;br /&gt;;                          (BLOCK CL-X86-ASM::PROCESS-ENCODING&lt;br /&gt;;                            CL-X86-ASM::OPERAND-DESCRIPTION))&lt;br /&gt;; &lt;br /&gt;; caught STYLE-WARNING:&lt;br /&gt;;   The variable INSTRUCTION is defined but never used.&lt;br /&gt;; &lt;br /&gt;; caught STYLE-WARNING:&lt;br /&gt;;   The variable OPERANDS is defined but never used.&lt;br /&gt;&lt;br /&gt;; compiling (DEFUN ASSEMBLE-INSTRUCTION-OR-DIRECTIVE ...)&lt;br /&gt;; compiling (DEFUN ASSEMBLE-FORM ...)&lt;br /&gt;; compiling (DEFUN ASSEMBLE-FORMS ...)&lt;br /&gt;&lt;br /&gt;; /home/johnc/projects/msc/x86-assembler.fasl written&lt;br /&gt;; compilation finished in 0:00:00&lt;br /&gt;WARNING:&lt;br /&gt;   COMPILE-FILE warned while performing #&lt;COMPILE-OP NIL {A872581}&gt; on&lt;br /&gt;   #&lt;CL-SOURCE-FILE "x86-assembler" {A86C899}&gt;.&lt;br /&gt;&lt;br /&gt;; file: /home/johnc/projects/msc/x86-assembler.lisp&lt;br /&gt;; in: DEFUN CL-X86-ASM::IS-OPERAND-TYPE-P&lt;br /&gt;;     (ASSOC CL-X86-ASM::OPERAND-TYPE CL-X86-ASM::*OPERAND-TYPE-CHECKERS*)&lt;br /&gt;; &lt;br /&gt;; caught WARNING:&lt;br /&gt;;   undefined variable: CL-X86-ASM::*OPERAND-TYPE-CHECKERS*&lt;br /&gt;&lt;br /&gt;; in: DEFUN CL-X86-ASM::ASSEMBLE-FORM&lt;br /&gt;;     (FIRST LIST)&lt;br /&gt;; ==&gt;&lt;br /&gt;;   (CAR LIST)&lt;br /&gt;; &lt;br /&gt;; caught WARNING:&lt;br /&gt;;   undefined variable: LIST&lt;br /&gt;&lt;br /&gt;; &lt;br /&gt;; caught WARNING:&lt;br /&gt;;   These variables are undefined:&lt;br /&gt;;     CL-X86-ASM::*OPERAND-TYPE-CHECKERS* LIST&lt;br /&gt;; &lt;br /&gt;; compilation unit finished&lt;br /&gt;;   caught 3 WARNING conditions&lt;br /&gt;;   caught 2 STYLE-WARNING conditions&lt;br /&gt;NIL&lt;br /&gt;CL-USER&gt; (cl-x86-asm::make-instruction-hash-table)&lt;br /&gt;Adding :XORPS to table - ((xmm1 xmm2/m128) (15 87 /r)) &lt;br /&gt;Adding :XORPD to table - ((xmm1 xmm2/m128) (102 15 87 /r)) &lt;br /&gt;Adding :XOR to table - ((EAX imm32) (o32 53 id)) &lt;br /&gt;Adding :XOR to table - ((AX imm16) (o16 53 iw)) &lt;br /&gt;Adding :XOR to table - ((AL imm8) (52 ib)) &lt;br /&gt;Adding :XOR to table - ((r/m32 imm8) (o32 131 /6 ib)) &lt;br /&gt;Adding :XOR to table - ((r/m16 imm8) (o16 131 /6 ib)) &lt;br /&gt;Adding :XOR to table - ((r/m32 imm32) (o32 129 /6 id)) &lt;br /&gt;Adding :XOR to table - ((r/m16 imm16) (o16 129 /6 iw)) &lt;br /&gt;Adding :XOR to table - ((r/m8 imm8) (128 /6 ib)) &lt;br /&gt;Adding :XOR to table - ((reg32 r/m32) (o32 51 /r)) &lt;br /&gt;Adding :XOR to table - ((reg16 r/m16) (o16 51 /r)) &lt;br /&gt;Adding :XOR to table - ((reg8 r/m8) (50 /r)) &lt;br /&gt;Adding :XOR to table - ((r/m32 reg32) (o32 49 /r)) &lt;br /&gt;Adding :XOR to table - ((r/m16 reg16) (o16 49 /r)) &lt;br /&gt;Adding :XOR to table - ((r/m8 reg8) (48 /r)) &lt;br /&gt;Adding :XLATB to table - (NIL (215)) &lt;br /&gt;Adding :XLAT to table - (NIL (215)) &lt;br /&gt;Adding :XCHG to table - ((reg32 EAX) (o32 144 +r)) &lt;br /&gt;Adding :XCHG to table - ((reg16 AX) (o16 144 +r)) &lt;br /&gt;Adding :XCHG to table - ((EAX reg32) (o32 144 +r)) &lt;br /&gt;Adding :XCHG to table - ((AX reg16) (o16 144 +r)) &lt;br /&gt;Adding :XCHG to table - ((r/m32 reg32) (o32 135 /r)) &lt;br /&gt;Adding :XCHG to table - ((r/m16 reg16) (o16 135 /r)) &lt;br /&gt;Adding :XCHG to table - ((r/m8 reg8) (134 /r)) &lt;br /&gt;Adding :XCHG to table - ((reg32 r/m32) (o32 135 /r)) &lt;br /&gt;Adding :XCHG to table - ((reg16 r/m8) (o16 135 /r)) &lt;br /&gt;Adding :XCHG to table - ((reg8 r/m8) (134 /r)) &lt;br /&gt;Adding :XBTS to table - ((reg32 r/m32) (o32 15 166 /r)) &lt;br /&gt;Adding :XBTS to table - ((reg16 r/m16) (o16 15 166 /r)) &lt;br /&gt;Adding :XADD to table - ((r/m32 reg32) (o32 15 193 /r)) &lt;br /&gt;Adding :XADD to table - ((r/m16 reg16) (o16 15 193 /r)) &lt;br /&gt;Adding :XADD to table - ((r/m8 reg8) (15 192 /r)) &lt;br /&gt;Adding :WRSHR to table - ((r/m32) (15 55 /0)) &lt;br /&gt;Adding :WRMSR to table - (NIL (15 48)) &lt;br /&gt;Adding :WBINVD to table - (NIL (15 9)) &lt;br /&gt;Adding :FWAIT to table - (NIL (155)) &lt;br /&gt;Adding :WAIT to table - (NIL (155)) &lt;br /&gt;Adding :VERW to table - ((r/m16) (15 0 /5)) &lt;br /&gt;Adding :VERR to table - ((r/m16) (15 0 /4)) &lt;br /&gt;Adding :UNPCKLPS to table - ((xmm1 xmm2/m128) (15 20 /r)) &lt;br /&gt;Adding :UNPCKLPD to table - ((xmm1 xmm2/m128) (102 15 20 /r)) &lt;br /&gt;Adding :UNPCKHPS to table - ((xmm1 xmm2/m128) (15 21 /r)) &lt;br /&gt;Adding :UNPCKHPD to table - ((xmm1 xmm2/m128) (102 15 21 /r)) &lt;br /&gt;Adding :UMOV to table - ((reg32 r/m32) (o32 15 19 /r)) &lt;br /&gt;Adding :UMOV to table - ((reg16 r/m16) (o16 15 19 /r)) &lt;br /&gt;Adding :UMOV to table - ((reg8 r/m8) (15 18 /r)) &lt;br /&gt;Adding :UMOV to table - ((r/m32 reg32) (o32 15 17 /r)) &lt;br /&gt;Adding :UMOV to table - ((r/m16 reg16) (o16 15 17 /r)) &lt;br /&gt;Adding :UMOV to table - ((r/m8 reg8) (15 16 /r)) &lt;br /&gt;Adding :UD2 to table - (NIL (15 11)) &lt;br /&gt;Adding :UD1 to table - (NIL (15 185)) &lt;br /&gt;Adding :UD0 to table - (NIL (15 255)) &lt;br /&gt;Adding :UCOMISS to table - ((xmm1 xmm2/m128) (15 46 /r)) &lt;br /&gt;Adding :UCOMISD to table - ((xmm1 xmm2/m128) (102 15 46 /r)) &lt;br /&gt;Adding :TEST to table - ((EAX imm32) (o32 169 id)) &lt;br /&gt;Adding :TEST to table - ((AX imm16) (o16 169 iw)) &lt;br /&gt;Adding :TEST to table - ((AL imm8) (168 ib)) &lt;br /&gt;Adding :TEST to table - ((r/m32 imm32) (o32 247 /0 id)) &lt;br /&gt;Adding :TEST to table - ((r/m16 imm16) (o16 247 /0 iw)) &lt;br /&gt;Adding :TEST to table - ((r/m8 imm8) (246 /0 ib)) &lt;br /&gt;Adding :TEST to table - ((r/m32 reg32) (o32 133 /r)) &lt;br /&gt;Adding :TEST to table - ((r/m16 reg16) (o16 133 /r)) &lt;br /&gt;Adding :TEST to table - ((r/m8 reg8) (132 /r)) &lt;br /&gt;Adding :SYSRET to table - (NIL (15 7)) &lt;br /&gt;Adding :SYSEXIT to table - (NIL (15 53)) &lt;br /&gt;Adding :SYSENTER to table - (NIL (15 52)) &lt;br /&gt;Adding :SYSCALL to table - (NIL (15 5)) &lt;br /&gt;Adding :SVTS to table - ((m80) (15 124 /0)) &lt;br /&gt;Adding :SVLDT to table - ((m80) (15 122 /0)) &lt;br /&gt;Adding :SVDC to table - ((m80 segreg) (15 120 /r)) &lt;br /&gt;Adding :SUBSS to table - ((xmm1 xmm2/m128) (243 15 92 /r)) &lt;br /&gt;Adding :SUBSD to table - ((xmm1 xmm2/m128) (242 15 92 /r)) &lt;br /&gt;Adding :SUBPS to table - ((xmm1 xmm2/m128) (15 92 /r)) &lt;br /&gt;Adding :SUBPD to table - ((xmm1 xmm2/m128) (102 15 92 /r)) &lt;br /&gt;Adding :SUB to table - ((EAX imm32) (o32 45 id)) &lt;br /&gt;Adding :SUB to table - ((AX imm16) (o16 45 iw)) &lt;br /&gt;Adding :SUB to table - ((AL imm8) (44 ib)) &lt;br /&gt;Adding :SUB to table - ((r/m32 imm8) (o32 131 /5 ib)) &lt;br /&gt;Adding :SUB to table - ((r/m16 imm8) (o16 131 /5 ib)) &lt;br /&gt;Adding :SUB to table - ((r/m32 imm32) (o32 129 /5 id)) &lt;br /&gt;Adding :SUB to table - ((r/m16 imm16) (o16 129 /5 iw)) &lt;br /&gt;Adding :SUB to table - ((r/m8 imm8) (128 /5 ib)) &lt;br /&gt;Adding :SUB to table - ((reg32 r/m32) (o32 43 /r)) &lt;br /&gt;Adding :SUB to table - ((reg16 r/m16) (o16 43 /r)) &lt;br /&gt;Adding :SUB to table - ((reg8 r/m8) (42 /r)) &lt;br /&gt;Adding :SUB to table - ((r/m32 reg32) (o32 41 /r)) &lt;br /&gt;Adding :SUB to table - ((r/m16 reg16) (o16 41 /r)) &lt;br /&gt;Adding :SUB to table - ((r/m8 reg8) (40 /r)) &lt;br /&gt;Adding :STR to table - ((r/m16) (15 0 /1)) &lt;br /&gt;Adding :STOSD to table - (NIL (o32 171)) &lt;br /&gt;Adding :STOSW to table - (NIL (o16 171)) &lt;br /&gt;Adding :STOSB to table - (NIL (170)) &lt;br /&gt;Adding :STMXCSR to table - ((m32) (15 174 /3)) &lt;br /&gt;Adding :STI to table - (NIL (251)) &lt;br /&gt;Adding :STD to table - (NIL (253)) &lt;br /&gt;Adding :STC to table - (NIL (249)) &lt;br /&gt;Adding :SQRTSS to table - ((xmm1 xmm2/m128) (243 15 81 /r)) &lt;br /&gt;Adding :SQRTSD to table - ((xmm1 xmm2/m128) (242 15 81 /r)) &lt;br /&gt;Adding :SQRTPS to table - ((xmm1 xmm2/m128) (15 81 /r)) &lt;br /&gt;Adding :SQRTPD to table - ((xmm1 xmm2/m128) (102 15 81 /r)) &lt;br /&gt;Adding :SMSW to table - ((r/m16) (15 1 /4)) &lt;br /&gt;Adding :SMINTOLD to table - (NIL (15 126)) &lt;br /&gt;Adding :SMINT to table - (NIL (15 56)) &lt;br /&gt;Adding :SMI to table - (NIL (241)) &lt;br /&gt;Adding :SHUFPS to table - ((xmm1 xmm2/m128 imm8) (15 198 /r ib)) &lt;br /&gt;Adding :SHUFPD to table - ((xmm1 xmm2/m128 imm8) (102 15 198 /r ib)) &lt;br /&gt;Adding :SHRD to table - ((r/m32 reg32 CL) (o32 15 173 /r)) &lt;br /&gt;Adding :SHRD to table - ((r/m16 reg16 CL) (o16 15 173 /r)) &lt;br /&gt;Adding :SHRD to table - ((r/m32 reg32 imm8) (o32 15 172 /r ib)) &lt;br /&gt;Adding :SHRD to table - ((r/m16 reg16 imm8) (o16 15 172 /r ib)) &lt;br /&gt;Adding :SHLD to table - ((r/m16 reg32 CL) (o32 15 165 /r)) &lt;br /&gt;Adding :SHLD to table - ((r/m16 reg16 CL) (o16 15 165 /r)) &lt;br /&gt;Adding :SHLD to table - ((r/m16 reg32 imm8) (o32 15 164 /r ib)) &lt;br /&gt;Adding :SHLD to table - ((r/m16 reg16 imm8) (o16 15 164 /r ib)) &lt;br /&gt;Adding :SHR to table - ((r/m32 imm8) (o32 193 /5 ib)) &lt;br /&gt;Adding :SHR to table - ((r/m32 CL) (o32 211 /5)) &lt;br /&gt;Adding :SHR to table - ((r/m32 1) (o32 209 /5)) &lt;br /&gt;Adding :SHR to table - ((r/m16 imm8) (o16 193 /5 ib)) &lt;br /&gt;Adding :SHR to table - ((r/m16 CL) (o16 211 /5)) &lt;br /&gt;Adding :SHR to table - ((r/m16 1) (o16 209 /5)) &lt;br /&gt;Adding :SHR to table - ((r/m8 imm8) (192 /5 ib)) &lt;br /&gt;Adding :SHR to table - ((r/m8 CL) (210 /5)) &lt;br /&gt;Adding :SHR to table - ((r/m8 1) (208 /5)) &lt;br /&gt;Adding :SHL to table - ((r/m32 imm8) (o32 193 /4 ib)) &lt;br /&gt;Adding :SHL to table - ((r/m32 CL) (o32 211 /4)) &lt;br /&gt;Adding :SHL to table - ((r/m32 1) (o32 209 /4)) &lt;br /&gt;Adding :SHL to table - ((r/m16 imm8) (o16 193 /4 ib)) &lt;br /&gt;Adding :SHL to table - ((r/m16 CL) (o16 211 /4)) &lt;br /&gt;Adding :SHL to table - ((r/m16 1) (o16 209 /4)) &lt;br /&gt;Adding :SHL to table - ((r/m8 imm8) (192 /4 ib)) &lt;br /&gt;Adding :SHL to table - ((r/m8 CL) (210 /4)) &lt;br /&gt;Adding :SHL to table - ((r/m8 1) (208 /4)) &lt;br /&gt;Adding :SLDT to table - ((r/m16) (15 0 /0)) &lt;br /&gt;Adding :SIDT to table - ((mem) (15 1 /1)) &lt;br /&gt;Adding :SGDT to table - ((mem) (15 1 /0)) &lt;br /&gt;Adding :SFENCE to table - (NIL (15 174 /7)) &lt;br /&gt;Adding :SCASD to table - (NIL (o32 175)) &lt;br /&gt;Adding :SCASW to table - (NIL (o16 175)) &lt;br /&gt;Adding :SCASB to table - (NIL (174)) &lt;br /&gt;Adding :SBB to table - ((EAX imm32) (o32 29 id)) &lt;br /&gt;Adding :SBB to table - ((AX imm16) (o16 29 iw)) &lt;br /&gt;Adding :SBB to table - ((AL imm8) (28 ib)) &lt;br /&gt;Adding :SBB to table - ((r/m32 imm8) (o32 131 /3 ib)) &lt;br /&gt;Adding :SBB to table - ((r/m16 imm8) (o16 131 /3 ib)) &lt;br /&gt;Adding :SBB to table - ((r/m32 imm32) (o32 129 /3 id)) &lt;br /&gt;Adding :SBB to table - ((r/m16 imm16) (o16 129 /3 iw)) &lt;br /&gt;Adding :SBB to table - ((r/m8 imm8) (128 /3 ib)) &lt;br /&gt;Adding :SBB to table - ((reg32 r/m32) (o32 27 /r)) &lt;br /&gt;Adding :SBB to table - ((reg16 r/m16) (o16 27 /r)) &lt;br /&gt;Adding :SBB to table - ((reg8 r/m8) (26 /r)) &lt;br /&gt;Adding :SBB to table - ((r/m32 reg32) (o32 25 /r)) &lt;br /&gt;Adding :SBB to table - ((r/m16 reg16) (o16 25 /r)) &lt;br /&gt;Adding :SBB to table - ((r/m8 reg8) (24 /r)) &lt;br /&gt;Adding :SALC to table - (NIL (214)) &lt;br /&gt;Adding :SAR to table - ((r/m32 imm8) (o32 193 /7 ib)) &lt;br /&gt;Adding :SAR to table - ((r/m32 CL) (o32 211 /7)) &lt;br /&gt;Adding :SAR to table - ((r/m32 1) (o32 209 /7)) &lt;br /&gt;Adding :SAR to table - ((r/m16 imm8) (o16 193 /7 ib)) &lt;br /&gt;Adding :SAR to table - ((r/m16 CL) (o16 211 /7)) &lt;br /&gt;Adding :SAR to table - ((r/m16 1) (o16 209 /7)) &lt;br /&gt;Adding :SAR to table - ((r/m8 imm8) (192 /7 ib)) &lt;br /&gt;Adding :SAR to table - ((r/m8 CL) (210 /7)) &lt;br /&gt;Adding :SAR to table - ((r/m8 1) (208 /7)) &lt;br /&gt;Adding :SAL to table - ((r/m32 imm8) (o32 193 /4 ib)) &lt;br /&gt;Adding :SAL to table - ((r/m32 CL) (o32 211 /4)) &lt;br /&gt;Adding :SAL to table - ((r/m32 1) (o32 209 /4)) &lt;br /&gt;Adding :SAL to table - ((r/m16 imm8) (o16 193 /4 ib)) &lt;br /&gt;Adding :SAL to table - ((r/m16 CL) (o16 211 /4)) &lt;br /&gt;Adding :SAL to table - ((r/m16 1) (o16 209 /4)) &lt;br /&gt;Adding :SAL to table - ((r/m8 imm8) (192 /4 ib)) &lt;br /&gt;Adding :SAL to table - ((r/m8 CL) (210 /4)) &lt;br /&gt;Adding :SAL to table - ((r/m8 1) (208 /4)) &lt;br /&gt;Adding :SAHF to table - (NIL (158)) &lt;br /&gt;Adding :RSTS to table - ((m80) (15 125 /0)) &lt;br /&gt;Adding :RSQRTSS to table - ((xmm1 xmm2/m128) (243 15 82 /r)) &lt;br /&gt;Adding :RSQRTPS to table - ((xmm1 xmm2/m128) (15 82 /r)) &lt;br /&gt;Adding :RSM to table - (NIL (15 170)) &lt;br /&gt;Adding :RSLDT to table - ((m80) (15 123 /0)) &lt;br /&gt;Adding :RSDC to table - ((segreg m80) (15 121 /r)) &lt;br /&gt;Adding :ROR to table - ((r/m32 imm8) (o32 193 /1 ib)) &lt;br /&gt;Adding :ROR to table - ((r/m32 CL) (o32 211 /1)) &lt;br /&gt;Adding :ROR to table - ((r/m32 1) (o32 209 /1)) &lt;br /&gt;Adding :ROR to table - ((r/m16 imm8) (o16 193 /1 ib)) &lt;br /&gt;Adding :ROR to table - ((r/m16 CL) (o16 211 /1)) &lt;br /&gt;Adding :ROR to table - ((r/m16 1) (o16 209 /1)) &lt;br /&gt;Adding :ROR to table - ((r/m8 imm8) (192 /1 ib)) &lt;br /&gt;Adding :ROR to table - ((r/m8 CL) (210 /1)) &lt;br /&gt;Adding :ROR to table - ((r/m8 1) (208 /1)) &lt;br /&gt;Adding :ROL to table - ((r/m32 imm8) (o32 193 /0 ib)) &lt;br /&gt;Adding :ROL to table - ((r/m32 CL) (o32 211 /0)) &lt;br /&gt;Adding :ROL to table - ((r/m32 1) (o32 209 /0)) &lt;br /&gt;Adding :ROL to table - ((r/m16 imm8) (o16 193 /0 ib)) &lt;br /&gt;Adding :ROL to table - ((r/m16 CL) (o16 211 /0)) &lt;br /&gt;Adding :ROL to table - ((r/m16 1) (o16 209 /0)) &lt;br /&gt;Adding :ROL to table - ((r/m8 imm8) (192 /0 ib)) &lt;br /&gt;Adding :ROL to table - ((r/m8 CL) (210 /0)) &lt;br /&gt;Adding :ROL to table - ((r/m8 1) (208 /0)) &lt;br /&gt;Adding :RETN to table - ((imm16) (194 iw)) &lt;br /&gt;Adding :RETN to table - (NIL (195)) &lt;br /&gt;Adding :RETF to table - ((imm16) (202 iw)) &lt;br /&gt;Adding :RETF to table - (NIL (203)) &lt;br /&gt;Adding :RET to table - ((imm16) (194 iw)) &lt;br /&gt;Adding :RET to table - (NIL (195)) &lt;br /&gt;Adding :RDTSC to table - (NIL (15 49)) &lt;br /&gt;Adding :RDSHR to table - ((r/m32) (15 54 /0)) &lt;br /&gt;Adding :RDPMC to table - (NIL (15 51)) &lt;br /&gt;Adding :RDMSR to table - (NIL (15 50)) &lt;br /&gt;Adding :RCPSS to table - ((xmm1 xmm2/m128) (243 15 83 /r)) &lt;br /&gt;Adding :RCPPS to table - ((xmm1 xmm2/m128) (15 83 /r)) &lt;br /&gt;Adding :RCR to table - ((r/m32 imm8) (o32 193 /3 ib)) &lt;br /&gt;Adding :RCR to table - ((r/m32 CL) (o32 211 /3)) &lt;br /&gt;Adding :RCR to table - ((r/m32 1) (o32 209 /3)) &lt;br /&gt;Adding :RCR to table - ((r/m16 imm8) (o16 193 /3 ib)) &lt;br /&gt;Adding :RCR to table - ((r/m16 CL) (o16 211 /3)) &lt;br /&gt;Adding :RCR to table - ((r/m16 1) (o16 209 /3)) &lt;br /&gt;Adding :RCR to table - ((r/m8 imm8) (192 /3 ib)) &lt;br /&gt;Adding :RCR to table - ((r/m8 CL) (210 /3)) &lt;br /&gt;Adding :RCR to table - ((r/m8 1) (208 /3)) &lt;br /&gt;Adding :RCL to table - ((r/m32 imm8) (o32 193 /2 ib)) &lt;br /&gt;Adding :RCL to table - ((r/m32 CL) (o32 211 /2)) &lt;br /&gt;Adding :RCL to table - ((r/m32 1) (o32 209 /2)) &lt;br /&gt;Adding :RCL to table - ((r/m16 imm8) (o16 193 /2 ib)) &lt;br /&gt;Adding :RCL to table - ((r/m16 CL) (o16 211 /2)) &lt;br /&gt;Adding :RCL to table - ((r/m16 1) (o16 209 /2)) &lt;br /&gt;Adding :RCL to table - ((r/m8 imm8) (192 /2 ib)) &lt;br /&gt;Adding :RCL to table - ((r/m8 CL) (210 /2)) &lt;br /&gt;Adding :RCL to table - ((r/m8 1) (208 /2)) &lt;br /&gt;Adding :PXOR to table - ((xmm1 xmm2/m128) (102 15 239 /r)) &lt;br /&gt;Adding :PXOR to table - ((mm1 mm2/m64) (15 239 /r)) &lt;br /&gt;Adding :PUSHFW to table - (NIL (o16 156)) &lt;br /&gt;Adding :PUSHFD to table - (NIL (o32 156)) &lt;br /&gt;Adding :PUSHF to table - (NIL (156)) &lt;br /&gt;Adding :PUSHAW to table - (NIL (o16 96)) &lt;br /&gt;Adding :PUSHAD to table - (NIL (o32 96)) &lt;br /&gt;Adding :PUSHA to table - (NIL (96)) &lt;br /&gt;Adding :PUSH to table - ((imm32) (o32 104 id)) &lt;br /&gt;Adding :PUSH to table - ((imm16) (o16 104 iw)) &lt;br /&gt;Adding :PUSH to table - ((imm8) (106 ib)) &lt;br /&gt;Adding :PUSH to table - ((GS) (15 168)) &lt;br /&gt;Adding :PUSH to table - ((FS) (15 160)) &lt;br /&gt;Adding :PUSH to table - ((SS) (22)) &lt;br /&gt;Adding :PUSH to table - ((ES) (6)) &lt;br /&gt;Adding :PUSH to table - ((DS) (30)) &lt;br /&gt;Adding :PUSH to table - ((CS) (14)) &lt;br /&gt;Adding :PUSH to table - ((r/m32) (o32 255 /6)) &lt;br /&gt;Adding :PUSH to table - ((r/m16) (o16 255 /6)) &lt;br /&gt;Adding :PUSH to table - ((reg32) (o32 80 +r)) &lt;br /&gt;Adding :PUSH to table - ((reg16) (o16 80 +r)) &lt;br /&gt;Adding :PUNPCKLQDQ to table - ((xmm1 xmm2/m128) (102 15 108 /r)) &lt;br /&gt;Adding :PUNPCKLDQ to table - ((xmm1 xmm2/m128) (102 15 98 /r)) &lt;br /&gt;Adding :PUNPCKLWD to table - ((xmm1 xmm2/m128) (102 15 97 /r)) &lt;br /&gt;Adding :PUNPCKLBW to table - ((xmm1 xmm2/m128) (102 15 96 /r)) &lt;br /&gt;Adding :PUNPCKLDQ to table - ((mm1 mm2/m32) (15 98 /r)) &lt;br /&gt;Adding :PUNPCKLWD to table - ((mm1 mm2/m32) (15 97 /r)) &lt;br /&gt;Adding :PUNPCKLBW to table - ((mm1 mm2/m32) (15 96 /r)) &lt;br /&gt;Adding :PUNPCKHQDQ to table - ((xmm1 xmm2/m128) (102 15 109 /r)) &lt;br /&gt;Adding :PUNPCKHDQ to table - ((xmm1 xmm2/m128) (102 15 106 /r)) &lt;br /&gt;Adding :PUNPCKHWD to table - ((xmm1 xmm2/m128) (102 15 105 /r)) &lt;br /&gt;Adding :PUNPCKHBW to table - ((xmm1 xmm2/m128) (102 15 104 /r)) &lt;br /&gt;Adding :PUNPCKHDQ to table - ((mm1 mm2/m64) (15 106 /r)) &lt;br /&gt;Adding :PUNPCKHWD to table - ((mm1 mm2/m64) (15 105 /r)) &lt;br /&gt;Adding :PUNPCKHBW to table - ((mm1 mm2/m64) (15 104 /r)) &lt;br /&gt;Adding :PSWAPD to table - ((mm1 mm2/m64) (15 15 /r 187)) &lt;br /&gt;Adding :PSUBSIW to table - ((mm1 mm2/m64) (15 85 /r)) &lt;br /&gt;Adding :PSUBUSW to table - ((xmm1 xmm2/m128) (102 15 217 /r)) &lt;br /&gt;Adding :PSUBUSB to table - ((xmm1 xmm2/m128) (102 15 216 /r)) &lt;br /&gt;Adding :PSUBUSW to table - ((mm1 mm2/m64) (15 217 /r)) &lt;br /&gt;Adding :PSUBUSB to table - ((mm1 mm2/m64) (15 216 /r)) &lt;br /&gt;Adding :PSUBSW to table - ((xmm1 xmm2/m128) (102 15 233 /r)) &lt;br /&gt;Adding :PSUBSB to table - ((xmm1 xmm2/m128) (102 15 232 /r)) &lt;br /&gt;Adding :PSUBSW to table - ((mm1 mm2/m64) (15 233 /r)) &lt;br /&gt;Adding :PSUBSB to table - ((mm1 mm2/m64) (15 232 /r)) &lt;br /&gt;Adding :PSUBQ to table - ((xmm1 xmm2/m128) (102 15 251 /r)) &lt;br /&gt;Adding :PSUBD to table - ((xmm1 xmm2/m128) (102 15 250 /r)) &lt;br /&gt;Adding :PSUBW to table - ((xmm1 xmm2/m128) (102 15 249 /r)) &lt;br /&gt;Adding :PSUBB to table - ((xmm1 xmm2/m128) (102 15 248 /r)) &lt;br /&gt;Adding :PSUBQ to table - ((mm1 mm2/m64) (15 251 /r)) &lt;br /&gt;Adding :PSUBD to table - ((mm1 mm2/m64) (15 250 /r)) &lt;br /&gt;Adding :PSUBW to table - ((mm1 mm2/m64) (15 249 /r)) &lt;br /&gt;Adding :PSUBB to table - ((mm1 mm2/m64) (15 248 /r)) &lt;br /&gt;Adding :PSRLDQ to table - ((xmm1 imm8) (102 15 115 /3 ib)) &lt;br /&gt;Adding :PSRLQ to table - ((xmm imm8) (102 15 115 /2 ib)) &lt;br /&gt;Adding :PSRLQ to table - ((xmm1 xmm2/m128) (102 15 211 /r)) &lt;br /&gt;Adding :PSRLQ to table - ((mm imm8) (15 115 /2 ib)) &lt;br /&gt;Adding :PSRLQ to table - ((mm1 mm2/m64) (15 211 /r)) &lt;br /&gt;Adding :PSRLD to table - ((xmm imm8) (102 15 114 /2 ib)) &lt;br /&gt;Adding :PSRLD to table - ((xmm1 xmm2/m128) (102 15 210 /r)) &lt;br /&gt;Adding :PSRLD to table - ((mm imm8) (15 114 /2 ib)) &lt;br /&gt;Adding :PSRLD to table - ((mm1 mm2/m64) (15 210 /r)) &lt;br /&gt;Adding :PSRLW to table - ((xmm imm8) (102 15 113 /2 ib)) &lt;br /&gt;Adding :PSRLW to table - ((xmm1 xmm2/m128) (102 15 209 /r)) &lt;br /&gt;Adding :PSRLW to table - ((mm imm8) (15 113 /2 ib)) &lt;br /&gt;Adding :PSRLW to table - ((mm1 mm2/m64) (15 209 /r)) &lt;br /&gt;Adding :PSRAD to table - ((xmm imm8) (102 15 114 /4 ib)) &lt;br /&gt;Adding :PSRAD to table - ((xmm1 xmm2/m128) (102 15 226 /r)) &lt;br /&gt;Adding :PSRAD to table - ((mm imm8) (15 114 /4 ib)) &lt;br /&gt;Adding :PSRAD to table - ((mm1 mm2/m64) (15 226 /r)) &lt;br /&gt;Adding :PSRAW to table - ((xmm imm8) (102 15 113 /4 ib)) &lt;br /&gt;Adding :PSRAW to table - ((xmm1 xmm2/m128) (102 15 225 /r)) &lt;br /&gt;Adding :PSRAW to table - ((mm imm8) (15 113 /4 ib)) &lt;br /&gt;Adding :PSRAW to table - ((mm1 mm2/m64) (15 225 /r)) &lt;br /&gt;Adding :PSLLDQ to table - ((xmm1 imm8) (102 15 115 /7 ib)) &lt;br /&gt;Adding :PSLLQ to table - ((xmm imm8) (102 15 115 /6 ib)) &lt;br /&gt;Adding :PSLLQ to table - ((xmm1 xmm2/m128) (102 15 243 /r)) &lt;br /&gt;Adding :PSLLQ to table - ((mm imm8) (15 115 /6 ib)) &lt;br /&gt;Adding :PSLLQ to table - ((mm1 mm2/m64) (15 243 /r)) &lt;br /&gt;Adding :PSLLD to table - ((xmm imm8) (102 15 114 /6 ib)) &lt;br /&gt;Adding :PSLLD to table - ((xmm1 xmm2/m128) (102 15 242 /r)) &lt;br /&gt;Adding :PSLLD to table - ((mm imm8) (15 114 /6 ib)) &lt;br /&gt;Adding :PSLLD to table - ((mm1 mm2/m64) (15 242 /r)) &lt;br /&gt;Adding :PSLLW to table - ((xmm imm8) (102 15 113 /6 ib)) &lt;br /&gt;Adding :PSLLW to table - ((xmm1 xmm2/m128) (102 15 241 /r)) &lt;br /&gt;Adding :PSLLW to table - ((mm imm8) (15 113 /6 ib)) &lt;br /&gt;Adding :PSLLW to table - ((mm1 mm2/m64) (15 241 /r)) &lt;br /&gt;Adding :PSHUFW to table - ((mm1 mm2/m64 imm8) (15 112 /r ib)) &lt;br /&gt;Adding :PSHUFLW to table - ((xmm1 xmm2/m128 imm8) (242 15 112 /r ib)) &lt;br /&gt;Adding :PSHUFHW to table - ((xmm1 xmm2/m128 imm8) (243 15 112 /r ib)) &lt;br /&gt;Adding :PSHUFD to table - ((xmm1 xmm2/m128 imm8) (102 15 112 /r ib)) &lt;br /&gt;Adding :PSADBW to table - ((xmm1 xmm2/m128) (102 15 246 /r)) &lt;br /&gt;Adding :PSADBW to table - ((mm1 mm2/m64) (15 246 /r)) &lt;br /&gt;Adding :PREFETCHT2 to table - ((m8) (15 24 /3)) &lt;br /&gt;Adding :PREFETCHT1 to table - ((m8) (15 24 /2)) &lt;br /&gt;Adding :PREFETCHT0 to table - ((m8) (15 24 /1)) &lt;br /&gt;Adding :PREFETCHNTA to table - ((m8) (15 24 /0)) &lt;br /&gt;Adding :PREFETCHW to table - ((mem8) (15 13 /1)) &lt;br /&gt;Adding :PREFETCH to table - ((mem8) (15 13 /0)) &lt;br /&gt;Adding :POR to table - ((xmm1 xmm2/m128) (102 15 235 /r)) &lt;br /&gt;Adding :POR to table - ((mm1 mm2/m64) (15 235 /r)) &lt;br /&gt;Adding :POPFD to table - (NIL (o32 157)) &lt;br /&gt;Adding :POPFW to table - (NIL (o16 157)) &lt;br /&gt;Adding :POPF to table - (NIL (157)) &lt;br /&gt;Adding :POPAD to table - (NIL (o32 97)) &lt;br /&gt;Adding :POPAW to table - (NIL (o16 97)) &lt;br /&gt;Adding :POPA to table - (NIL (97)) &lt;br /&gt;Adding :POP to table - ((GS) (15 169)) &lt;br /&gt;Adding :POP to table - ((FS) (15 161)) &lt;br /&gt;Adding :POP to table - ((SS) (23)) &lt;br /&gt;Adding :POP to table - ((ES) (7)) &lt;br /&gt;Adding :POP to table - ((DS) (31)) &lt;br /&gt;Adding :POP to table - ((CS) (15)) &lt;br /&gt;Adding :POP to table - ((r/m32) (o32 143 /0)) &lt;br /&gt;Adding :POP to table - ((r/m16) (o16 143 /0)) &lt;br /&gt;Adding :POP to table - ((reg32) (o32 88 +r)) &lt;br /&gt;Adding :POP to table - ((reg16) (o16 88 +r)) &lt;br /&gt;Adding :PMVGEZB to table - ((mmxreg mem64) (15 92 /r)) &lt;br /&gt;Adding :PMVLZB to table - ((mmxreg mem64) (15 91 /r)) &lt;br /&gt;Adding :PMVNZB to table - ((mmxreg mem64) (15 90 /r)) &lt;br /&gt;Adding :PMVZB to table - ((mmxreg mem64) (15 88 /r)) &lt;br /&gt;Adding :PMULUDQ to table - ((xmm1 xmm2/m128) (102 15 244 /r)) &lt;br /&gt;Adding :PMULUDQ to table - ((mm1 mm2/m64) (15 244 /r)) &lt;br /&gt;Adding :PMULLW to table - ((xmm1 xmm2/m128) (102 15 213 /r)) &lt;br /&gt;Adding :PMULHW to table - ((xmm1 xmm2/m128) (102 15 229 /r)) &lt;br /&gt;Adding :PMULLW to table - ((mm1 mm2/m64) (15 213 /r)) &lt;br /&gt;Adding :PMULHW to table - ((mm1 mm2/m64) (15 229 /r)) &lt;br /&gt;Adding :PMULHUW to table - ((xmm1 xmm2/m128) (102 15 228 /r)) &lt;br /&gt;Adding :PMULHUW to table - ((mm1 mm2/m64) (15 228 /r)) &lt;br /&gt;Adding :PMULHRWA to table - ((mm1 mm2/m64) (15 15 /r 183)) &lt;br /&gt;Adding :PMULHRIW to table - ((mm1 mm2/m64) (15 93 /r)) &lt;br /&gt;Adding :PMULHRWC to table - ((mm1 mm2/m64) (15 89 /r)) &lt;br /&gt;Adding :PMOVMSKB to table - ((reg32 xmm) (102 15 215 /r)) &lt;br /&gt;Adding :PMOVMSKB to table - ((reg32 mm) (15 215 /r)) &lt;br /&gt;Adding :PMINUB to table - ((xmm1 xmm2/m128) (102 15 218 /r)) &lt;br /&gt;Adding :PMINUB to table - ((mm1 mm2/m64) (15 218 /r)) &lt;br /&gt;Adding :PMINSW to table - ((xmm1 xmm2/m128) (102 15 234 /r)) &lt;br /&gt;Adding :PMINSW to table - ((mm1 mm2/m64) (15 234 /r)) &lt;br /&gt;Adding :PMAXUB to table - ((xmm1 xmm2/m128) (102 15 222 /r)) &lt;br /&gt;Adding :PMAXUB to table - ((mm1 mm2/m64) (15 222 /r)) &lt;br /&gt;Adding :PMAXSW to table - ((xmm1 xmm2/m128) (102 15 238 /r)) &lt;br /&gt;Adding :PMAXSW to table - ((mm1 mm2/m64) (15 238 /r)) &lt;br /&gt;Adding :PMAGW to table - ((mm1 mm2/m64) (15 82 /r)) &lt;br /&gt;Adding :PMADDWD to table - ((xmm1 xmm2/m128) (102 15 245 /r)) &lt;br /&gt;Adding :PMADDWD to table - ((mm1 mm2/m64) (15 245 /r)) &lt;br /&gt;Adding :PMACHRIW to table - ((mm m64) (15 94 /r)) &lt;br /&gt;Adding :PINSRW to table - ((xmm r16/r32/m16 imm8) (102 15 196 /r ib)) &lt;br /&gt;Adding :PINSRW to table - ((mm r16/r32/m16 imm8) (15 196 /r ib)) &lt;br /&gt;Adding :PI2FW to table - ((mm1 mm2/m64) (15 15 /r 12)) &lt;br /&gt;Adding :PI2FD to table - ((mm1 mm2/m64) (15 15 /r 13)) &lt;br /&gt;Adding :PFSUBR to table - ((mm1 mm2/m64) (15 15 /r 170)) &lt;br /&gt;Adding :PFSUB to table - ((mm1 mm2/m64) (15 15 /r 154)) &lt;br /&gt;Adding :PFRSQRT to table - ((mm1 mm2/m64) (15 15 /r 151)) &lt;br /&gt;Adding :PFRSQIT1 to table - ((mm1 mm2/m64) (15 15 /r 167)) &lt;br /&gt;Adding :PFRCPIT2 to table - ((mm1 mm2/m64) (15 15 /r 182)) &lt;br /&gt;Adding :PFRCPIT1 to table - ((mm1 mm2/m64) (15 15 /r 166)) &lt;br /&gt;Adding :PFRCP to table - ((mm1 mm2/m64) (15 15 /r 150)) &lt;br /&gt;Adding :PFPNACC to table - ((mm1 mm2/m64) (15 15 /r 142)) &lt;br /&gt;Adding :PFNACC to table - ((mm1 mm2/m64) (15 15 /r 138)) &lt;br /&gt;Adding :PFMUL to table - ((mm1 mm2/m64) (15 15 /r 180)) &lt;br /&gt;Adding :PFMIN to table - ((mm1 mm2/m64) (15 15 /r 148)) &lt;br /&gt;Adding :PFMAX to table - ((mm1 mm2/m64) (15 15 /r 164)) &lt;br /&gt;Adding :PFCMPGT to table - ((mm1 mm2/m64) (15 15 /r 160)) &lt;br /&gt;Adding :PFCMPGE to table - ((mm1 mm2/m64) (15 15 /r 144)) &lt;br /&gt;Adding :PFCMPEQ to table - ((mm1 mm2/m64) (15 15 /r 176)) &lt;br /&gt;Adding :PFADD to table - ((mm1 mm2/m64) (15 15 /r 158)) &lt;br /&gt;Adding :PFACC to table - ((mm1 mm2/m64) (15 15 /r 174)) &lt;br /&gt;Adding :PF2IW to table - ((mm1 mm2/m64) (15 15 /r 28)) &lt;br /&gt;Adding :PF2ID to table - ((mm1 mm2/m64) (15 15 /r 29)) &lt;br /&gt;Adding :PEXTRW to table - ((reg32 xmm imm8) (102 15 197 /r ib)) &lt;br /&gt;Adding :PEXTRW to table - ((reg32 mm imm8) (15 197 /r ib)) &lt;br /&gt;Adding :PDISTIB to table - ((mm m64) (15 84 /r)) &lt;br /&gt;Adding :PCMPGTD to table - ((xmm1 xmm2/m128) (102 15 102 /r)) &lt;br /&gt;Adding :PCMPGTW to table - ((xmm1 xmm2/m128) (102 15 101 /r)) &lt;br /&gt;Adding :PCMPGTB to table - ((xmm1 xmm2/m128) (102 15 100 /r)) &lt;br /&gt;Adding :PCMPEQD to table - ((xmm1 xmm2/m128) (102 15 118 /r)) &lt;br /&gt;Adding :PCMPEQW to table - ((xmm1 xmm2/m128) (102 15 117 /r)) &lt;br /&gt;Adding :PCMPEQB to table - ((xmm1 xmm2/m128) (102 15 116 /r)) &lt;br /&gt;Adding :PCMPGTD to table - ((mm1 mm2/m64) (15 102 /r)) &lt;br /&gt;Adding :PCMPGTW to table - ((mm1 mm2/m64) (15 101 /r)) &lt;br /&gt;Adding :PCMPGTB to table - ((mm1 mm2/m64) (15 100 /r)) &lt;br /&gt;Adding :PCMPEQD to table - ((mm1 mm2/m64) (15 118 /r)) &lt;br /&gt;Adding :PCMPEQW to table - ((mm1 mm2/m64) (15 117 /r)) &lt;br /&gt;Adding :PCMPEQB to table - ((mm1 mm2/m64) (15 116 /r)) &lt;br /&gt;Adding :PAVGUSB to table - ((mm1 mm2/m64) (15 15 /r 191)) &lt;br /&gt;Adding :PAVGW to table - ((xmm1 xmm2/m128) (102 15 227 /r)) &lt;br /&gt;Adding :PAVGB to table - ((xmm1 xmm2/m128) (102 15 224 /r)) &lt;br /&gt;Adding :PAVGW to table - ((mm1 mm2/m64) (15 227 /r)) &lt;br /&gt;Adding :PAVGB to table - ((mm1 mm2/m64) (15 224 /r)) &lt;br /&gt;Adding :PAVEB to table - ((mmxreg r/m64) (15 80 /r)) &lt;br /&gt;Adding :PAUSE to table - (NIL (243 144)) &lt;br /&gt;Adding :PANDN to table - ((xmm1 xmm2/m128) (102 15 223 /r)) &lt;br /&gt;Adding :PAND to table - ((xmm1 xmm2/m128) (102 15 219 /r)) &lt;br /&gt;Adding :PANDN to table - ((mm1 mm2/m64) (15 223 /r)) &lt;br /&gt;Adding :PAND to table - ((mm1 mm2/m64) (15 219 /r)) &lt;br /&gt;Adding :PADDUSW to table - ((xmm1 xmm2/m128) (102 15 221 /r)) &lt;br /&gt;Adding :PADDUSB to table - ((xmm1 xmm2/m128) (102 15 220 /r)) &lt;br /&gt;Adding :PADDUSW to table - ((mm1 mm2/m64) (15 221 /r)) &lt;br /&gt;Adding :PADDUSB to table - ((mm1 mm2/m64) (15 220 /r)) &lt;br /&gt;Adding :PADDSIW to table - ((mmxreg r/m64) (15 81 /r)) &lt;br /&gt;Adding :PADDSW to table - ((xmm1 xmm2/m128) (102 15 237 /r)) &lt;br /&gt;Adding :PADDSB to table - ((xmm1 xmm2/m128) (102 15 236 /r)) &lt;br /&gt;Adding :PADDSW to table - ((mm1 mm2/m64) (15 237 /r)) &lt;br /&gt;Adding :PADDSB to table - ((mm1 mm2/m64) (15 236 /r)) &lt;br /&gt;Adding :PADDQ to table - ((xmm1 xmm2/m128) (102 15 212 /r)) &lt;br /&gt;Adding :PADDQ to table - ((mm1 mm2/m64) (15 212 /r)) &lt;br /&gt;Adding :PADDD to table - ((xmm1 xmm2/m128) (102 15 254 /r)) &lt;br /&gt;Adding :PADDW to table - ((xmm1 xmm2/m128) (102 15 253 /r)) &lt;br /&gt;Adding :PADDB to table - ((xmm1 xmm2/m128) (102 15 252 /r)) &lt;br /&gt;Adding :PADDD to table - ((mm1 mm2/m64) (15 254 /r)) &lt;br /&gt;Adding :PADDW to table - ((mm1 mm2/m64) (15 253 /r)) &lt;br /&gt;Adding :PADDB to table - ((mm1 mm2/m64) (15 252 /r)) &lt;br /&gt;Adding :PACKUSWB to table - ((xmm1 xmm2/m128) (102 15 103 /r)) &lt;br /&gt;Adding :PACKSSWB to table - ((xmm1 xmm2/m128) (102 15 99 /r)) &lt;br /&gt;Adding :PACKSSDW to table - ((xmm1 xmm2/m128) (102 15 107 /r)) &lt;br /&gt;Adding :PACKUSWB to table - ((mm1 mm2/m64) (15 103 /r)) &lt;br /&gt;Adding :PACKSSWB to table - ((mm1 mm2/m64) (15 99 /r)) &lt;br /&gt;Adding :PACKSSDW to table - ((mm1 mm2/m64) (15 107 /r)) &lt;br /&gt;Adding :OUTSD to table - (NIL (o32 111)) &lt;br /&gt;Adding :OUTSW to table - (NIL (o16 111)) &lt;br /&gt;Adding :OUTSB to table - (NIL (110)) &lt;br /&gt;Adding :OUT to table - ((DX EAX) (o32 239)) &lt;br /&gt;Adding :OUT to table - ((DX AX) (o16 239)) &lt;br /&gt;Adding :OUT to table - ((DX AL) (238)) &lt;br /&gt;Adding :OUT to table - ((imm8 EAX) (o32 231 ib)) &lt;br /&gt;Adding :OUT to table - ((imm8 AX) (o16 231 ib)) &lt;br /&gt;Adding :OUT to table - ((imm8 AL) (230 ib)) &lt;br /&gt;Adding :ORPS to table - ((xmm1 xmm2/m128) (15 86 /r)) &lt;br /&gt;Adding :ORPD to table - ((xmm1 xmm2/m128) (102 15 86 /r)) &lt;br /&gt;Adding :OR to table - ((EAX imm32) (o32 13 id)) &lt;br /&gt;Adding :OR to table - ((AX imm16) (o16 13 iw)) &lt;br /&gt;Adding :OR to table - ((AL imm8) (12 ib)) &lt;br /&gt;Adding :OR to table - ((r/m32 imm8) (o32 131 /1 ib)) &lt;br /&gt;Adding :OR to table - ((r/m16 imm8) (o16 131 /1 ib)) &lt;br /&gt;Adding :OR to table - ((r/m32 imm32) (o32 129 /1 id)) &lt;br /&gt;Adding :OR to table - ((r/m16 imm16) (o16 129 /1 iw)) &lt;br /&gt;Adding :OR to table - ((r/m8 imm8) (128 /1 ib)) &lt;br /&gt;Adding :OR to table - ((reg32 r/m32) (o32 11 /r)) &lt;br /&gt;Adding :OR to table - ((reg16 r/m16) (o16 11 /r)) &lt;br /&gt;Adding :OR to table - ((reg8 r/m8) (10 /r)) &lt;br /&gt;Adding :OR to table - ((r/m32 reg32) (o32 9 /r)) &lt;br /&gt;Adding :OR to table - ((r/m16 reg16) (o16 9 /r)) &lt;br /&gt;Adding :OR to table - ((r/m8 reg8) (8 /r)) &lt;br /&gt;Adding :NOP to table - (NIL (144)) &lt;br /&gt;Adding :NOT to table - ((r/m32) (o32 247 /2)) &lt;br /&gt;Adding :NOT to table - ((r/m16) (o16 247 /2)) &lt;br /&gt;Adding :NOT to table - ((r/m8) (246 /2)) &lt;br /&gt;Adding :NEG to table - ((r/m32) (o32 247 /3)) &lt;br /&gt;Adding :NEG to table - ((r/m16) (o16 247 /3)) &lt;br /&gt;Adding :NEG to table - ((r/m8) (246 /3)) &lt;br /&gt;Adding :MULSS to table - ((xmm1 xmm2/mem32) (243 15 89 /r)) &lt;br /&gt;Adding :MULSD to table - ((xmm1 xmm2/mem32) (242 15 89 /r)) &lt;br /&gt;Adding :MULPS to table - ((xmm1 xmm2/mem128) (15 89 /r)) &lt;br /&gt;Adding :MULPD to table - ((xmm1 xmm2/mem128) (102 15 89 /r)) &lt;br /&gt;Adding :MUL to table - ((r/m32) (o32 247 /4)) &lt;br /&gt;Adding :MUL to table - ((r/m16) (o16 247 /4)) &lt;br /&gt;Adding :MUL to table - ((r/m8) (246 /4)) &lt;br /&gt;Adding :MOVUPS to table - ((xmm1/mem128 xmm2) (15 17 /r)) &lt;br /&gt;Adding :MOVUPS to table - ((xmm1 xmm2/mem128) (15 16 /r)) &lt;br /&gt;Adding :MOVUPD to table - ((xmm1/mem128 xmm2) (102 15 17 /r)) &lt;br /&gt;Adding :MOVUPD to table - ((xmm1 xmm2/mem128) (102 15 16 /r)) &lt;br /&gt;Adding :MOVZX to table - ((reg32 r/m16) (o32 15 183 /r)) &lt;br /&gt;Adding :MOVZX to table - ((reg32 r/m8) (o32 15 182 /r)) &lt;br /&gt;Adding :MOVZX to table - ((reg16 r/m8) (o16 15 182 /r)) &lt;br /&gt;Adding :MOVSX to table - ((reg32 r/m16) (o32 15 191 /r)) &lt;br /&gt;Adding :MOVSX to table - ((reg32 r/m8) (o32 15 190 /r)) &lt;br /&gt;Adding :MOVSX to table - ((reg16 r/m8) (o16 15 190 /r)) &lt;br /&gt;Adding :MOVSS to table - ((xmm1/m32 xmm2) (243 15 17 /r)) &lt;br /&gt;Adding :MOVSS to table - ((xmm1 xmm2/m32) (243 15 16 /r)) &lt;br /&gt;Adding :MOVSD to table - ((xmm1/m64 xmm2) (242 15 17 /r)) &lt;br /&gt;Adding :MOVSD to table - ((xmm1 xmm2/m64) (242 15 16 /r)) &lt;br /&gt;Adding :MOVSD to table - (NIL (o32 165)) &lt;br /&gt;Adding :MOVSW to table - (NIL (o16 165)) &lt;br /&gt;Adding :MOVSB to table - (NIL (164)) &lt;br /&gt;Adding :MOVQ2DQ to table - ((xmm mm) (243 OF 214 /r)) &lt;br /&gt;Adding :MOVQ to table - ((xmm1/m64 xmm2) (102 15 214 /r)) &lt;br /&gt;Adding :MOVQ to table - ((xmm1 xmm2/m64) (243 15 126 /r)) &lt;br /&gt;Adding :MOVQ to table - ((mm1/m64 mm2) (15 127 /r)) &lt;br /&gt;Adding :MOVQ to table - ((mm1 mm2/m64) (15 111 /r)) &lt;br /&gt;Adding :MOVNTQ to table - ((m64 mm) (15 231 /r)) &lt;br /&gt;Adding :MOVNTPS to table - ((m128 xmm) (15 43 /r)) &lt;br /&gt;Adding :MOVNTPD to table - ((m128 xmm) (102 15 43 /r)) &lt;br /&gt;Adding :MOVNTI to table - ((m32 reg32) (15 195 /r)) &lt;br /&gt;Adding :MOVNTDQ to table - ((m128 xmm) (102 15 231 /r)) &lt;br /&gt;Adding :MOVMSKPS to table - ((reg32 xmm) (15 80 /r)) &lt;br /&gt;Adding :MOVMSKPD to table - ((reg32 xmm) (102 15 80 /r)) &lt;br /&gt;Adding :MOVLPS to table - ((m64 xmm) (OF 19 /r)) &lt;br /&gt;Adding :MOVLPS to table - ((xmm m64) (OF 18 /r)) &lt;br /&gt;Adding :MOVLPD to table - ((m64 xmm) (102 OF 19 /r)) &lt;br /&gt;Adding :MOVLPD to table - ((xmm m64) (102 OF 18 /r)) &lt;br /&gt;Adding :MOVLHPS to table - ((xmm1 xmm2) (OF 22 /r)) &lt;br /&gt;Adding :MOVHPS to table - ((m64 xmm) (15 23 /r)) &lt;br /&gt;Adding :MOVHPS to table - ((xmm m64) (15 22 /r)) &lt;br /&gt;Adding :MOVHPD to table - ((m64 xmm) (102 OF 23 /r)) &lt;br /&gt;Adding :MOVHPD to table - ((xmm m64) (102 OF 22 /r)) &lt;br /&gt;Adding :MOVHLPS to table - ((xmm1 xmm2) (OF 18 /r)) &lt;br /&gt;Adding :MOVDQU to table - ((xmm1/m128 xmm2) (243 OF 127 /r)) &lt;br /&gt;Adding :MOVDQU to table - ((xmm1 xmm2/m128) (243 OF 111 /r)) &lt;br /&gt;Adding :MOVDQA to table - ((xmm1/m128 xmm2) (102 OF 127 /r)) &lt;br /&gt;Adding :MOVDQA to table - ((xmm1 xmm2/m128) (102 OF 111 /r)) &lt;br /&gt;Adding :MOVDQ2Q to table - ((mm xmm) (242 OF 214 /r)) &lt;br /&gt;Adding :MOVD to table - ((r/m32 xmm) (102 15 126 /r)) &lt;br /&gt;Adding :MOVD to table - ((xmm r/m32) (102 15 110 /r)) &lt;br /&gt;Adding :MOVD to table - ((r/m32 mm) (15 126 /r)) &lt;br /&gt;Adding :MOVD to table - ((mm r/m32) (15 110 /r)) &lt;br /&gt;Adding :MOVAPS to table - ((xmm1/mem128 xmm2) (15 41 /r)) &lt;br /&gt;Adding :MOVAPS to table - ((xmm1 xmm2/mem128) (15 40 /r)) &lt;br /&gt;Adding :MOVAPD to table - ((xmm1/mem128 xmm2) (102 15 41 /r)) &lt;br /&gt;Adding :MOVAPD to table - ((xmm1 xmm2/mem128) (102 15 40 /r)) &lt;br /&gt;Adding :MOV to table - ((TR3/4/5/6/7 reg32) (15 38 /r)) &lt;br /&gt;Adding :MOV to table - ((DR0/1/2/3/6/7 reg32) (15 35 /r)) &lt;br /&gt;Adding :MOV to table - ((CR0/2/3/4 reg32) (15 34 /r)) &lt;br /&gt;Adding :MOV to table - ((reg32 TR3/4/5/6/7) (15 36 /r)) &lt;br /&gt;Adding :MOV to table - ((reg32 DR0/1/2/3/6/7) (15 33 /r)) &lt;br /&gt;Adding :MOV to table - ((reg32 CR0/2/3/4) (15 32 /r)) &lt;br /&gt;Adding :MOV to table - ((segreg r/m32) (o32 142 /r)) &lt;br /&gt;Adding :MOV to table - ((segreg r/m16) (o16 142 /r)) &lt;br /&gt;Adding :MOV to table - ((r/m32 segreg) (o32 140 /r)) &lt;br /&gt;Adding :MOV to table - ((r/m16 segreg) (o16 140 /r)) &lt;br /&gt;Adding :MOV to table - ((memoffs32 EAX) (o32 163 ow/od)) &lt;br /&gt;Adding :MOV to table - ((memoffs16 AX) (o16 163 ow/od)) &lt;br /&gt;Adding :MOV to table - ((memoffs8 AL) (162 ow/od)) &lt;br /&gt;Adding :MOV to table - ((EAX memoffs32) (o32 161 ow/od)) &lt;br /&gt;Adding :MOV to table - ((AX memoffs16) (o16 161 ow/od)) &lt;br /&gt;Adding :MOV to table - ((AL memoffs8) (160 ow/od)) &lt;br /&gt;Adding :MOV to table - ((r/m32 imm32) (o32 199 /0 id)) &lt;br /&gt;Adding :MOV to table - ((r/m16 imm16) (o16 199 /0 iw)) &lt;br /&gt;Adding :MOV to table - ((r/m8 imm8) (198 /0 ib)) &lt;br /&gt;Adding :MOV to table - ((reg32 imm32) (o32 184 +r id)) &lt;br /&gt;Adding :MOV to table - ((reg16 imm16) (o16 184 +r iw)) &lt;br /&gt;Adding :MOV to table - ((reg8 imm8) (176 +r ib)) &lt;br /&gt;Adding :MOV to table - ((reg32 r/m32) (o32 139 /r)) &lt;br /&gt;Adding :MOV to table - ((reg16 r/m16) (o16 139 /r)) &lt;br /&gt;Adding :MOV to table - ((reg8 r/m8) (138 /r)) &lt;br /&gt;Adding :MOV to table - ((r/m32 reg32) (o32 137 /r)) &lt;br /&gt;Adding :MOV to table - ((r/m16 reg16) (o16 137 /r)) &lt;br /&gt;Adding :MOV to table - ((r/m8 reg8) (136 /r)) &lt;br /&gt;Adding :MINSS to table - ((xmm1 xmm2/m32) (243 15 93 /r)) &lt;br /&gt;Adding :MINSD to table - ((xmm1 xmm2/m64) (242 15 93 /r)) &lt;br /&gt;Adding :MINPS to table - ((xmm1 xmm2/m128) (15 93 /r)) &lt;br /&gt;Adding :MINPD to table - ((xmm1 xmm2/m128) (102 15 93 /r)) &lt;br /&gt;Adding :MFENCE to table - (NIL (15 174 /6)) &lt;br /&gt;Adding :MAXSS to table - ((xmm1 xmm2/m32) (243 15 95 /r)) &lt;br /&gt;Adding :MAXSD to table - ((xmm1 xmm2/m64) (242 15 95 /r)) &lt;br /&gt;Adding :MAXPS to table - ((xmm1 xmm2/m128) (15 95 /r)) &lt;br /&gt;Adding :MAXPD to table - ((xmm1 xmm2/m128) (102 15 95 /r)) &lt;br /&gt;Adding :MASKMOVQ to table - ((mm1 mm2) (15 247 /r)) &lt;br /&gt;Adding :MASKMOVDQU to table - ((xmm1 xmm2) (102 15 247 /r)) &lt;br /&gt;Adding :LTR to table - ((r/m16) (15 0 /3)) &lt;br /&gt;Adding :LSL to table - ((reg32 r/m32) (o32 15 3 /r)) &lt;br /&gt;Adding :LSL to table - ((reg16 r/m16) (o16 15 3 /r)) &lt;br /&gt;Adding :LOOPNZ to table - ((imm ECX) (2610 224 rb)) &lt;br /&gt;Adding :LOOPNZ to table - ((imm CX) (2582 224 rb)) &lt;br /&gt;Adding :LOOPNZ to table - ((imm) (224 rb)) &lt;br /&gt;Adding :LOOPNE to table - ((imm ECX) (2610 224 rb)) &lt;br /&gt;Adding :LOOPNE to table - ((imm CX) (2582 224 rb)) &lt;br /&gt;Adding :LOOPNE to table - ((imm) (224 rb)) &lt;br /&gt;Adding :LOOPZ to table - ((imm ECX) (2610 225 rb)) &lt;br /&gt;Adding :LOOPZ to table - ((imm CX) (2582 225 rb)) &lt;br /&gt;Adding :LOOPZ to table - ((imm) (225 rb)) &lt;br /&gt;Adding :LOOPE to table - ((imm ECX) (2610 225 rb)) &lt;br /&gt;Adding :LOOPE to table - ((imm CX) (2582 225 rb)) &lt;br /&gt;Adding :LOOPE to table - ((imm) (225 rb)) &lt;br /&gt;Adding :LOOP to table - ((imm ECX) (2610 226 rb)) &lt;br /&gt;Adding :LOOP to table - ((imm CX) (2582 226 rb)) &lt;br /&gt;Adding :LOOP to table - ((imm) (226 rb)) &lt;br /&gt;Adding :LODSD to table - (NIL (o32 173)) &lt;br /&gt;Adding :LODSW to table - (NIL (o16 173)) &lt;br /&gt;Adding :LODSB to table - (NIL (172)) &lt;br /&gt;Adding :LOADALL286 to table - (NIL (15 5)) &lt;br /&gt;Adding :LOADALL to table - (NIL (15 7)) &lt;br /&gt;Adding :LMSW to table - ((r/m16) (15 1 /6)) &lt;br /&gt;Adding :LLDT to table - ((r/m16) (15 0 /2)) &lt;br /&gt;Adding :LIDT to table - ((mem) (15 1 /3)) &lt;br /&gt;Adding :LGDT to table - ((mem) (15 1 /2)) &lt;br /&gt;Adding :LFENCE to table - (NIL (15 174 /5)) &lt;br /&gt;Adding :LEAVE to table - (NIL (201)) &lt;br /&gt;Adding :LEA to table - ((reg32 mem) (o32 141 /r)) &lt;br /&gt;Adding :LEA to table - ((reg16 mem) (o16 141 /r)) &lt;br /&gt;Adding :LSS to table - ((reg32 mem) (o32 15 178 /r)) &lt;br /&gt;Adding :LSS to table - ((reg16 mem) (o16 15 178 /r)) &lt;br /&gt;Adding :LGS to table - ((reg32 mem) (o32 15 181 /r)) &lt;br /&gt;Adding :LGS to table - ((reg16 mem) (o16 15 181 /r)) &lt;br /&gt;Adding :LFS to table - ((reg32 mem) (o32 15 180 /r)) &lt;br /&gt;Adding :LFS to table - ((reg16 mem) (o16 15 180 /r)) &lt;br /&gt;Adding :LES to table - ((reg32 mem) (o32 196 /r)) &lt;br /&gt;Adding :LES to table - ((reg16 mem) (o16 196 /r)) &lt;br /&gt;Adding :LDS to table - ((reg32 mem) (o32 197 /r)) &lt;br /&gt;Adding :LDS to table - ((reg16 mem) (o16 197 /r)) &lt;br /&gt;Adding :LDMXCSR to table - ((mem32) (15 174 /2)) &lt;br /&gt;Adding :LAR to table - ((reg32 r/m32) (o32 15 2 /r)) &lt;br /&gt;Adding :LAR to table - ((reg16 r/m16) (o16 15 2 /r)) &lt;br /&gt;Adding :LAHF to table - (NIL (159)) &lt;br /&gt;Adding :JMP to table - ((r/m32) (o32 255 /4)) &lt;br /&gt;Adding :JMP to table - ((r/m16) (o16 255 /4)) &lt;br /&gt;Adding :JMP to table - ((mem32) (o32 255 /5)) &lt;br /&gt;Adding :JMP to table - ((mem) (o16 255 /5)) &lt;br /&gt;Adding :JMP to table - ((imm:imm32) (o32 234 id iw)) &lt;br /&gt;Adding :JMP to table - ((imm:imm16) (o16 234 iw iw)) &lt;br /&gt;Adding :JMP to table - ((imm) (235 rb)) &lt;br /&gt;Adding :JMP to table - ((imm) (233 rw/rd)) &lt;br /&gt;Adding :JECXZ to table - ((imm) (2610 227 rb)) &lt;br /&gt;Adding :JCXZ to table - ((imm) (2582 227 rb)) &lt;br /&gt;Adding :IRETD to table - (NIL (o32 207)) &lt;br /&gt;Adding :IRETW to table - (NIL (o16 207)) &lt;br /&gt;Adding :IRET to table - (NIL (207)) &lt;br /&gt;Adding :INVLPG to table - ((mem) (15 1 /7)) &lt;br /&gt;Adding :INVD to table - (NIL (15 8)) &lt;br /&gt;Adding :INTO to table - (NIL (206)) &lt;br /&gt;Adding :INT03 to table - (NIL (204)) &lt;br /&gt;Adding :INT3 to table - (NIL (204)) &lt;br /&gt;Adding :INT01 to table - (NIL (241)) &lt;br /&gt;Adding :ICEBP to table - (NIL (241)) &lt;br /&gt;Adding :INT1 to table - (NIL (241)) &lt;br /&gt;Adding :INT to table - ((imm8) (205 ib)) &lt;br /&gt;Adding :INSD to table - (NIL (o32 109)) &lt;br /&gt;Adding :INSW to table - (NIL (o16 109)) &lt;br /&gt;Adding :INSB to table - (NIL (108)) &lt;br /&gt;Adding :INC to table - ((r/m32) (o32 255 /0)) &lt;br /&gt;Adding :INC to table - ((r/m16) (o16 255 /0)) &lt;br /&gt;Adding :INC to table - ((r/m8) (254 /0)) &lt;br /&gt;Adding :INC to table - ((reg32) (o32 64 +r)) &lt;br /&gt;Adding :INC to table - ((reg16) (o16 64 +r)) &lt;br /&gt;Adding :IN to table - ((EAX DX) (o32 237)) &lt;br /&gt;Adding :IN to table - ((AX DX) (o16 237)) &lt;br /&gt;Adding :IN to table - ((AL DX) (236)) &lt;br /&gt;Adding :IN to table - ((EAX imm8) (o32 229 ib)) &lt;br /&gt;Adding :IN to table - ((AX imm8) (o16 229 ib)) &lt;br /&gt;Adding :IN to table - ((AL imm8) (228 ib)) &lt;br /&gt;Adding :IMUL to table - ((reg32 r/m32 imm32) (o32 105 /r id)) &lt;br /&gt;Adding :IMUL to table - ((reg32 r/m32 imm8) (o32 107 /r ib)) &lt;br /&gt;Adding :IMUL to table - ((reg16 r/m16 imm16) (o16 105 /r iw)) &lt;br /&gt;Adding :IMUL to table - ((reg16 r/m16 imm8) (o16 107 /r ib)) &lt;br /&gt;Adding :IMUL to table - ((reg32 imm32) (o32 105 /r id)) &lt;br /&gt;Adding :IMUL to table - ((reg32 imm8) (o32 107 /r ib)) &lt;br /&gt;Adding :IMUL to table - ((reg16 imm16) (o16 105 /r iw)) &lt;br /&gt;Adding :IMUL to table - ((reg16 imm8) (o16 107 /r ib)) &lt;br /&gt;Adding :IMUL to table - ((reg32 r/m32) (o32 15 175 /r)) &lt;br /&gt;Adding :IMUL to table - ((reg16 r/m16) (o16 15 175 /r)) &lt;br /&gt;Adding :IMUL to table - ((r/m32) (o32 247 /5)) &lt;br /&gt;Adding :IMUL to table - ((r/m16) (o16 247 /5)) &lt;br /&gt;Adding :IMUL to table - ((r/m8) (246 /5)) &lt;br /&gt;Adding :IDIV to table - ((r/m32) (o32 247 /7)) &lt;br /&gt;Adding :IDIV to table - ((r/m16) (o16 247 /7)) &lt;br /&gt;Adding :IDIV to table - ((r/m8) (246 /7)) &lt;br /&gt;Adding :IBTS to table - ((r/m32 reg32) (o32 15 167 /r)) &lt;br /&gt;Adding :IBTS to table - ((r/m16 reg16) (o16 15 167 /r)) &lt;br /&gt;Adding :HLT to table - (NIL (244)) &lt;br /&gt;Adding :FYL2XP1 to table - (NIL (217 249)) &lt;br /&gt;Adding :FYL2X to table - (NIL (217 241)) &lt;br /&gt;Adding :FXTRACT to table - (NIL (217 244)) &lt;br /&gt;Adding :FXSAVE to table - ((memory) (15 174 /0)) &lt;br /&gt;Adding :FXRSTOR to table - ((memory) (15 174 /1)) &lt;br /&gt;Adding :FXCH to table - ((ST0 fpureg) (217 200 +r)) &lt;br /&gt;Adding :FXCH to table - ((fpureg ST0) (217 200 +r)) &lt;br /&gt;Adding :FXCH to table - ((fpureg) (217 200 +r)) &lt;br /&gt;Adding :FXCH to table - (NIL (217 201)) &lt;br /&gt;Adding :FXAM to table - (NIL (217 229)) &lt;br /&gt;Adding :FUCOMIP to table - ((ST0 fpureg) (223 232 +r)) &lt;br /&gt;Adding :FUCOMIP to table - ((fpureg) (223 232 +r)) &lt;br /&gt;Adding :FUCOMI to table - ((ST0 fpureg) (219 232 +r)) &lt;br /&gt;Adding :FUCOMI to table - ((fpureg) (219 232 +r)) &lt;br /&gt;Adding :FUCOMPP to table - (NIL (218 233)) &lt;br /&gt;Adding :FUCOMP to table - ((ST0 fpureg) (221 232 +r)) &lt;br /&gt;Adding :FUCOMP to table - ((fpureg) (221 232 +r)) &lt;br /&gt;Adding :FUCOM to table - ((ST0 fpureg) (221 224 +r)) &lt;br /&gt;Adding :FUCOM to table - ((fpureg) (221 224 +r)) &lt;br /&gt;Adding :FTST to table - (NIL (217 228)) &lt;br /&gt;Adding :FSUBRP to table - ((fpureg ST0) (222 224 +r)) &lt;br /&gt;Adding :FSUBRP to table - ((fpureg) (222 224 +r)) &lt;br /&gt;Adding :FSUBP to table - ((fpureg ST0) (222 232 +r)) &lt;br /&gt;Adding :FSUBP to table - ((fpureg) (222 232 +r)) &lt;br /&gt;Adding :FSUBR to table - ((fpureg ST0) (220 224 +r)) &lt;br /&gt;Adding :FSUBR to table - ((fpureg) (220 224 +r)) &lt;br /&gt;Adding :FSUBR to table - ((ST0 fpureg) (216 232 +r)) &lt;br /&gt;Adding :FSUBR to table - ((fpureg) (216 232 +r)) &lt;br /&gt;Adding :FSUBR to table - ((mem64) (220 /5)) &lt;br /&gt;Adding :FSUBR to table - ((mem32) (216 /5)) &lt;br /&gt;Adding :FSUB to table - ((fpureg ST0) (220 232 +r)) &lt;br /&gt;Adding :FSUB to table - ((fpureg) (220 232 +r)) &lt;br /&gt;Adding :FSUB to table - ((ST0 fpureg) (216 224 +r)) &lt;br /&gt;Adding :FSUB to table - ((fpureg) (216 224 +r)) &lt;br /&gt;Adding :FSUB to table - ((mem64) (220 /4)) &lt;br /&gt;Adding :FSUB to table - ((mem32) (216 /4)) &lt;br /&gt;Adding :FNSTSW to table - ((AX) (223 224)) &lt;br /&gt;Adding :FNSTSW to table - ((mem16) (221 /7)) &lt;br /&gt;Adding :FSTSW to table - ((AX) (155 223 224)) &lt;br /&gt;Adding :FSTSW to table - ((mem16) (155 221 /7)) &lt;br /&gt;Adding :FNSTENV to table - ((mem) (217 /6)) &lt;br /&gt;Adding :FSTENV to table - ((mem) (155 217 /6)) &lt;br /&gt;Adding :FNSTCW to table - ((mem16) (217 /7)) &lt;br /&gt;Adding :FSTCW to table - ((mem16) (155 217 /7)) &lt;br /&gt;Adding :FSTP to table - ((fpureg) (221 216 +r)) &lt;br /&gt;Adding :FSTP to table - ((mem80) (219 /7)) &lt;br /&gt;Adding :FSTP to table - ((mem64) (221 /3)) &lt;br /&gt;Adding :FSTP to table - ((mem32) (217 /3)) &lt;br /&gt;Adding :FST to table - ((fpureg) (221 208 +r)) &lt;br /&gt;Adding :FST to table - ((mem64) (221 /2)) &lt;br /&gt;Adding :FST to table - ((mem32) (217 /2)) &lt;br /&gt;Adding :FSQRT to table - (NIL (217 250)) &lt;br /&gt;Adding :FSINCOS to table - (NIL (217 251)) &lt;br /&gt;Adding :FSIN to table - (NIL (217 254)) &lt;br /&gt;Adding :FSETPM to table - (NIL (219 228)) &lt;br /&gt;Adding :FSCALE to table - (NIL (217 253)) &lt;br /&gt;Adding :FRSTOR to table - ((mem) (221 /4)) &lt;br /&gt;Adding :FNSAVE to table - ((mem) (221 /6)) &lt;br /&gt;Adding :FSAVE to table - ((mem) (155 221 /6)) &lt;br /&gt;Adding :FRNDINT to table - (NIL (217 252)) &lt;br /&gt;Adding :FPREM1 to table - (NIL (217 245)) &lt;br /&gt;Adding :FPREM to table - (NIL (217 248)) &lt;br /&gt;Adding :FPTAN to table - (NIL (217 242)) &lt;br /&gt;Adding :FPATAN to table - (NIL (217 243)) &lt;br /&gt;Adding :FNOP to table - (NIL (217 208)) &lt;br /&gt;Adding :FMULP to table - ((fpureg ST0) (222 200 +r)) &lt;br /&gt;Adding :FMULP to table - ((fpureg) (222 200 +r)) &lt;br /&gt;Adding :FMUL to table - ((fpureg ST0) (220 200 +r)) &lt;br /&gt;Adding :FMUL to table - ((fpureg) (220 200 +r)) &lt;br /&gt;Adding :FMUL to table - ((ST0 fpureg) (216 200 +r)) &lt;br /&gt;Adding :FMUL to table - ((fpureg) (216 200 +r)) &lt;br /&gt;Adding :FMUL to table - ((mem64) (220 /1)) &lt;br /&gt;Adding :FMUL to table - ((mem32) (216 /1)) &lt;br /&gt;Adding :FLDENV to table - ((mem) (217 /4)) &lt;br /&gt;Adding :FLDCW to table - ((mem16) (217 /5)) &lt;br /&gt;Adding :FLDZ to table - (NIL (217 238)) &lt;br /&gt;Adding :FLDPI to table - (NIL (217 235)) &lt;br /&gt;Adding :FLDLN2 to table - (NIL (217 237)) &lt;br /&gt;Adding :FLDLG2 to table - (NIL (217 236)) &lt;br /&gt;Adding :FLDL2T to table - (NIL (217 233)) &lt;br /&gt;Adding :FLDL2E to table - (NIL (217 234)) &lt;br /&gt;Adding :FLD1 to table - (NIL (217 232)) &lt;br /&gt;Adding :FLD to table - ((fpureg) (217 192 +r)) &lt;br /&gt;Adding :FLD to table - ((mem80) (219 /5)) &lt;br /&gt;Adding :FLD to table - ((mem64) (221 /0)) &lt;br /&gt;Adding :FLD to table - ((mem32) (217 /0)) &lt;br /&gt;Adding :FISUBR to table - ((mem32) (218 /5)) &lt;br /&gt;Adding :FISUBR to table - ((mem16) (222 /5)) &lt;br /&gt;Adding :FISUB to table - ((mem32) (218 /4)) &lt;br /&gt;Adding :FISUB to table - ((mem16) (222 /4)) &lt;br /&gt;Adding :FNINIT to table - (NIL (219 227)) &lt;br /&gt;Adding :FINIT to table - (NIL (155 219 227)) &lt;br /&gt;Adding :FINCSTP to table - (NIL (217 247)) &lt;br /&gt;Adding :FIMUL to table - ((mem32) (218 /1)) &lt;br /&gt;Adding :FIMUL to table - ((mem16) (222 /1)) &lt;br /&gt;Adding :FISTP to table - ((mem64) (223 /7)) &lt;br /&gt;Adding :FISTP to table - ((mem32) (219 /3)) &lt;br /&gt;Adding :FISTP to table - ((mem16) (223 /3)) &lt;br /&gt;Adding :FIST to table - ((mem32) (219 /2)) &lt;br /&gt;Adding :FIST to table - ((mem16) (223 /2)) &lt;br /&gt;Adding :FILD to table - ((mem64) (223 /5)) &lt;br /&gt;Adding :FILD to table - ((mem32) (219 /0)) &lt;br /&gt;Adding :FILD to table - ((mem16) (223 /0)) &lt;br /&gt;Adding :FIDIVR to table - ((mem32) (218 /7)) &lt;br /&gt;Adding :FIDIVR to table - ((mem16) (222 /7)) &lt;br /&gt;Adding :FIDIV to table - ((mem32) (218 /6)) &lt;br /&gt;Adding :FIDIV to table - ((mem16) (222 /6)) &lt;br /&gt;Adding :FICOMP to table - ((mem32) (218 /3)) &lt;br /&gt;Adding :FICOMP to table - ((mem16) (222 /3)) &lt;br /&gt;Adding :FICOM to table - ((mem32) (218 /2)) &lt;br /&gt;Adding :FICOM to table - ((mem16) (222 /2)) &lt;br /&gt;Adding :FIADD to table - ((mem32) (218 /0)) &lt;br /&gt;Adding :FIADD to table - ((mem16) (222 /0)) &lt;br /&gt;Adding :FFREEP to table - ((fpureg) (223 192 +r)) &lt;br /&gt;Adding :FFREE to table - ((fpureg) (221 192 +r)) &lt;br /&gt;Adding :FEMMS to table - (NIL (15 14)) &lt;br /&gt;Adding :FDIVRP to table - ((fpureg ST0) (222 240 +r)) &lt;br /&gt;Adding :FDIVRP to table - ((fpureg) (222 240 +r)) &lt;br /&gt;Adding :FDIVP to table - ((fpureg ST0) (222 248 +r)) &lt;br /&gt;Adding :FDIVP to table - ((fpureg) (222 248 +r)) &lt;br /&gt;Adding :FDIVR to table - ((fpureg ST0) (220 240 +r)) &lt;br /&gt;Adding :FDIVR to table - ((fpureg) (220 240 +r)) &lt;br /&gt;Adding :FDIVR to table - ((ST0 fpureg) (216 248 +r)) &lt;br /&gt;Adding :FDIVR to table - ((fpureg) (216 248 +r)) &lt;br /&gt;Adding :FDIVR to table - ((mem64) (220 /0)) &lt;br /&gt;Adding :FDIVR to table - ((mem32) (216 /0)) &lt;br /&gt;Adding :FDIV to table - ((fpureg ST0) (220 248 +r)) &lt;br /&gt;Adding :FDIV to table - ((fpureg) (220 248 +r)) &lt;br /&gt;Adding :FDIV to table - ((ST0 fpureg) (216 240 +r)) &lt;br /&gt;Adding :FDIV to table - ((fpureg) (216 240 +r)) &lt;br /&gt;Adding :FDIV to table - ((mem64) (220 /6)) &lt;br /&gt;Adding :FDIV to table - ((mem32) (216 /6)) &lt;br /&gt;Adding :FNENI to table - (NIL (219 224)) &lt;br /&gt;Adding :FENI to table - (NIL (155 219 224)) &lt;br /&gt;Adding :FNDISI to table - (NIL (219 225)) &lt;br /&gt;Adding :FDISI to table - (NIL (155 219 225)) &lt;br /&gt;Adding :FDECSTP to table - (NIL (217 246)) &lt;br /&gt;Adding :FCOS to table - (NIL (217 255)) &lt;br /&gt;Adding :FCOMIP to table - ((ST0 fpureg) (223 240 +r)) &lt;br /&gt;Adding :FCOMIP to table - ((fpureg) (223 240 +r)) &lt;br /&gt;Adding :FCOMI to table - ((ST0 fpureg) (219 240 +r)) &lt;br /&gt;Adding :FCOMI to table - ((fpureg) (219 240 +r)) &lt;br /&gt;Adding :FCOMPP to table - (NIL (222 217)) &lt;br /&gt;Adding :FCOMP to table - ((ST0 fpureg) (216 216 +r)) &lt;br /&gt;Adding :FCOMP to table - ((fpureg) (216 216 +r)) &lt;br /&gt;Adding :FCOMP to table - ((mem64) (220 /3)) &lt;br /&gt;Adding :FCOMP to table - ((mem32) (216 /3)) &lt;br /&gt;Adding :FCOM to table - ((ST0 fpureg) (216 208 +r)) &lt;br /&gt;Adding :FCOM to table - ((fpureg) (216 208 +r)) &lt;br /&gt;Adding :FCOM to table - ((mem64) (220 /2)) &lt;br /&gt;Adding :FCOM to table - ((mem32) (216 /2)) &lt;br /&gt;Adding :FCMOVNU to table - ((ST0 fpureg) (219 216 +r)) &lt;br /&gt;Adding :FCMOVNU to table - ((fpureg) (219 216 +r)) &lt;br /&gt;Adding :FCMOVNBE to table - ((ST0 fpureg) (219 208 +r)) &lt;br /&gt;Adding :FCMOVNBE to table - ((fpureg) (219 208 +r)) &lt;br /&gt;Adding :FCMOVNE to table - ((ST0 fpureg) (219 200 +r)) &lt;br /&gt;Adding :FCMOVNE to table - ((fpureg) (219 200 +r)) &lt;br /&gt;Adding :FCMOVNB to table - ((ST0 fpureg) (219 192 +r)) &lt;br /&gt;Adding :FCMOVNB to table - ((fpureg) (219 192 +r)) &lt;br /&gt;Adding :FCMOVU to table - ((ST0 fpureg) (218 216 +r)) &lt;br /&gt;Adding :FCMOVU to table - ((fpureg) (218 216 +r)) &lt;br /&gt;Adding :FCMOVBE to table - ((ST0 fpureg) (218 208 +r)) &lt;br /&gt;Adding :FCMOVBE to table - ((fpureg) (218 208 +r)) &lt;br /&gt;Adding :FCMOVE to table - ((ST0 fpureg) (218 200 +r)) &lt;br /&gt;Adding :FCMOVE to table - ((fpureg) (218 200 +r)) &lt;br /&gt;Adding :FCMOVB to table - ((ST0 fpureg) (218 192 +r)) &lt;br /&gt;Adding :FCMOVB to table - ((fpureg) (218 192 +r)) &lt;br /&gt;Adding :FNCLEX to table - (NIL (219 226)) &lt;br /&gt;Adding :FCLEX to table - (NIL (155 219 226)) &lt;br /&gt;Adding :FCHS to table - (NIL (217 224)) &lt;br /&gt;Adding :FBSTP to table - ((mem80) (223 /6)) &lt;br /&gt;Adding :FBLD to table - ((mem80) (223 /4)) &lt;br /&gt;Adding :FADDP to table - ((fpureg ST0) (222 192 +r)) &lt;br /&gt;Adding :FADDP to table - ((fpureg) (222 192 +r)) &lt;br /&gt;Adding :FADD to table - ((fpureg ST0) (220 192 +r)) &lt;br /&gt;Adding :FADD to table - ((fpureg) (220 192 +r)) &lt;br /&gt;Adding :FADD to table - ((ST0 fpureg) (216 192 +r)) &lt;br /&gt;Adding :FADD to table - ((fpureg) (216 192 +r)) &lt;br /&gt;Adding :FADD to table - ((mem64) (220 /0)) &lt;br /&gt;Adding :FADD to table - ((mem32) (216 /0)) &lt;br /&gt;Adding :FABS to table - (NIL (217 225)) &lt;br /&gt;Adding :F2XM1 to table - (NIL (217 240)) &lt;br /&gt;Adding :ENTER to table - ((imm imm) (200 iw ib)) &lt;br /&gt;Adding :EMMS to table - (NIL (15 119)) &lt;br /&gt;Adding :DIVSS to table - ((xmm1 xmm2/mem32) (243 15 94 /r)) &lt;br /&gt;Adding :DIVSD to table - ((xmm1 xmm2/mem64) (242 15 94 /r)) &lt;br /&gt;Adding :DIVPS to table - ((xmm1 xmm2/mem128) (15 94 /r)) &lt;br /&gt;Adding :DIVPD to table - ((xmm1 xmm2/mem128) (102 15 94 /r)) &lt;br /&gt;Adding :DIV to table - ((r/m32) (o32 247 /6)) &lt;br /&gt;Adding :DIV to table - ((r/m16) (o16 247 /6)) &lt;br /&gt;Adding :DIV to table - ((r/m8) (246 /6)) &lt;br /&gt;Adding :DEC to table - ((r/m32) (o32 255 /1)) &lt;br /&gt;Adding :DEC to table - ((r/m16) (o16 255 /1)) &lt;br /&gt;Adding :DEC to table - ((r/m8) (254 /1)) &lt;br /&gt;Adding :DEC to table - ((reg32) (o32 72 +r)) &lt;br /&gt;Adding :DEC to table - ((reg16) (o16 72 +r)) &lt;br /&gt;Adding :DAS to table - (NIL (47)) &lt;br /&gt;Adding :DAA to table - (NIL (39)) &lt;br /&gt;Adding :CVTTSD2SI to table - ((reg32 xmm/mem32) (243 15 44 /r)) &lt;br /&gt;Adding :CVTTSD2SI to table - ((reg32 xmm/mem64) (242 15 44 /r)) &lt;br /&gt;Adding :CVTTPS2PI to table - ((mm xmm/mem64) (15 44 /r)) &lt;br /&gt;Adding :CVTTPS2DQ to table - ((xmm1 xmm2/mem128) (243 15 91 /r)) &lt;br /&gt;Adding :CVTTPD2PI to table - ((mm xmm/mem128) (102 15 44 /r)) &lt;br /&gt;Adding :CVTTPD2DQ to table - ((xmm1 xmm2/mem128) (102 15 230 /r)) &lt;br /&gt;Adding :CVTSS2SI to table - ((reg32 xmm/mem32) (243 15 45 /r)) &lt;br /&gt;Adding :CVTSS2SD to table - ((xmm1 xmm2/mem32) (243 15 90 /r)) &lt;br /&gt;Adding :CVTSI2SS to table - ((xmm r/m32) (243 15 42 /r)) &lt;br /&gt;Adding :CVTSI2SD to table - ((xmm r/m32) (242 15 42 /r)) &lt;br /&gt;Adding :CVTSD2SS to table - ((xmm1 xmm2/mem64) (242 15 90 /r)) &lt;br /&gt;Adding :CVTSD2SI to table - ((reg32 xmm/mem64) (242 15 45 /r)) &lt;br /&gt;Adding :CVTPS2PI to table - ((mm xmm/mem64) (15 45 /r)) &lt;br /&gt;Adding :CVTPS2PD to table - ((xmm1 xmm2/mem64) (15 90 /r)) &lt;br /&gt;Adding :CVTPS2DQ to table - ((xmm1 xmm2/mem128) (102 15 91 /r)) &lt;br /&gt;Adding :CVTPI2PS to table - ((xmm mm/mem64) (15 42 /r)) &lt;br /&gt;Adding :CVTPI2PD to table - ((xmm mm/mem64) (102 15 42 /r)) &lt;br /&gt;Adding :CVTPD2PS to table - ((xmm1 xmm2/mem128) (102 15 90 /r)) &lt;br /&gt;Adding :CVTPD2PI to table - ((mm xmm/mem128) (102 15 45 /r)) &lt;br /&gt;Adding :CVTPD2DQ to table - ((xmm1 xmm2/mem128) (242 15 230 /r)) &lt;br /&gt;Adding :CVTDQ2PS to table - ((xmm1 xmm2/mem128) (15 91 /r)) &lt;br /&gt;Adding :CVTDQ2PD to table - ((xmm1 xmm2/mem64) (243 15 230 /r)) &lt;br /&gt;Adding :CPUID to table - (NIL (15 162)) &lt;br /&gt;Adding :COMISS to table - ((xmm1 xmm2/mem32) (102 15 47 /r)) &lt;br /&gt;Adding :COMISD to table - ((xmm1 xmm2/mem64) (102 15 47 /r)) &lt;br /&gt;Adding :CMPXCHG8B to table - ((mem) (15 199 /1)) &lt;br /&gt;Adding :CMPXCHG486 to table - ((r/m32 reg32) (o32 15 167 /r)) &lt;br /&gt;Adding :CMPXCHG486 to table - ((r/m16 reg16) (o16 15 167 /r)) &lt;br /&gt;Adding :CMPXCHG486 to table - ((r/m8 reg8) (15 166 /r)) &lt;br /&gt;Adding :CMPXCHG to table - ((r/m32 reg32) (o32 15 177 /r)) &lt;br /&gt;Adding :CMPXCHG to table - ((r/m16 reg16) (o16 15 177 /r)) &lt;br /&gt;Adding :CMPXCHG to table - ((r/m8 reg8) (15 176 /r)) &lt;br /&gt;Adding :CMPORDSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 7)) &lt;br /&gt;Adding :CMPNLESS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 6)) &lt;br /&gt;Adding :CMPNLTSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 5)) &lt;br /&gt;Adding :CMPNEQSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 4)) &lt;br /&gt;Adding :CMPUNORDSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 3)) &lt;br /&gt;Adding :CMPLESS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 2)) &lt;br /&gt;Adding :CMPLTSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 1)) &lt;br /&gt;Adding :CMPEQSS to table - ((xmm1 xmm2/mem32) (243 15 194 /r 0)) &lt;br /&gt;Adding :CMPSS to table - ((xmm1 xmm2/mem32 imm8) (243 15 194 /r ib)) &lt;br /&gt;Adding :CMPORDSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 7)) &lt;br /&gt;Adding :CMPNLESD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 6)) &lt;br /&gt;Adding :CMPNLTSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 5)) &lt;br /&gt;Adding :CMPNEQSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 4)) &lt;br /&gt;Adding :CMPUNORDSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 3)) &lt;br /&gt;Adding :CMPLESD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 2)) &lt;br /&gt;Adding :CMPLTSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 1)) &lt;br /&gt;Adding :CMPEQSD to table - ((xmm1 xmm2/mem64) (242 15 194 /r 0)) &lt;br /&gt;Adding :CMPSD to table - ((xmm1 xmm2/mem64 imm8) (242 15 194 /r ib)) &lt;br /&gt;Adding :CMPSD to table - (NIL (o32 167)) &lt;br /&gt;Adding :CMPSW to table - (NIL (o16 167)) &lt;br /&gt;Adding :CMPSB to table - (NIL (166)) &lt;br /&gt;Adding :CMPORDPS to table - ((xmm1 xmm2/mem128) (15 194 /r 7)) &lt;br /&gt;Adding :CMPNLEPS to table - ((xmm1 xmm2/mem128) (15 194 /r 6)) &lt;br /&gt;Adding :CMPNLTPS to table - ((xmm1 xmm2/mem128) (15 194 /r 5)) &lt;br /&gt;Adding :CMPNEQPS to table - ((xmm1 xmm2/mem128) (15 194 /r 4)) &lt;br /&gt;Adding :CMPUNORDPS to table - ((xmm1 xmm2/mem128) (15 194 /r 3)) &lt;br /&gt;Adding :CMPLEPS to table - ((xmm1 xmm2/mem128) (15 194 /r 2)) &lt;br /&gt;Adding :CMPLTPS to table - ((xmm1 xmm2/mem128) (15 194 /r 1)) &lt;br /&gt;Adding :CMPEQPS to table - ((xmm1 xmm2/mem128) (15 194 /r 0)) &lt;br /&gt;Adding :CMPPS to table - ((xmm1 xmm2/mem128 imm8) (15 194 /r ib)) &lt;br /&gt;Adding :CMPORDPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 7)) &lt;br /&gt;Adding :CMPNLEPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 6)) &lt;br /&gt;Adding :CMPNLTPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 5)) &lt;br /&gt;Adding :CMPNEQPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 4)) &lt;br /&gt;Adding :CMPUNORDPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 3)) &lt;br /&gt;Adding :CMPLEPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 2)) &lt;br /&gt;Adding :CMPLTPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 1)) &lt;br /&gt;Adding :CMPEQPD to table - ((xmm1 xmm2/mem128) (102 15 194 /r 0)) &lt;br /&gt;Adding :CMPPD to table - ((xmm1 xmm2/mem128 imm8) (102 15 194 /r ib)) &lt;br /&gt;Adding :CMP to table - ((EAX imm32) (o32 61 id)) &lt;br /&gt;Adding :CMP to table - ((AX imm16) (o16 61 iw)) &lt;br /&gt;Adding :CMP to table - ((AL imm8) (60 ib)) &lt;br /&gt;Adding :CMP to table - ((r/m32 imm8) (o32 131 /0 ib)) &lt;br /&gt;Adding :CMP to table - ((r/m16 imm8) (o16 131 /0 ib)) &lt;br /&gt;Adding :CMP to table - ((r/m32 imm32) (o32 129 /0 id)) &lt;br /&gt;Adding :CMP to table - ((r/m16 imm16) (o16 129 /0 iw)) &lt;br /&gt;Adding :CMP to table - ((r/m8 imm8) (128 /0 ib)) &lt;br /&gt;Adding :CMP to table - ((reg32 r/m32) (o32 59 /r)) &lt;br /&gt;Adding :CMP to table - ((reg16 r/m16) (o16 59 /r)) &lt;br /&gt;Adding :CMP to table - ((reg8 r/m8) (58 /r)) &lt;br /&gt;Adding :CMP to table - ((r/m32 reg32) (o32 57 /r)) &lt;br /&gt;Adding :CMP to table - ((r/m16 reg16) (o16 57 /r)) &lt;br /&gt;Adding :CMP to table - ((r/m8 reg8) (56 /r)) &lt;br /&gt;Adding :CMC to table - (NIL (245)) &lt;br /&gt;Adding :CLFLUSH to table - ((mem) (15 174 /7)) &lt;br /&gt;Adding :CLTS to table - (NIL (15 6)) &lt;br /&gt;Adding :CLI to table - (NIL (250)) &lt;br /&gt;Adding :CLD to table - (NIL (252)) &lt;br /&gt;Adding :CLC to table - (NIL (248)) &lt;br /&gt;Adding :CDQ to table - (NIL (o32 153)) &lt;br /&gt;Adding :CWD to table - (NIL (o16 153)) &lt;br /&gt;Adding :CWDE to table - (NIL (o32 152)) &lt;br /&gt;Adding :CBW to table - (NIL (o16 152)) &lt;br /&gt;Adding :CALL to table - ((r/m32) (o32 255 /2)) &lt;br /&gt;Adding :CALL to table - ((r/m16) (o16 255 /2)) &lt;br /&gt;Adding :CALL to table - ((mem32) (o32 255 /3)) &lt;br /&gt;Adding :CALL to table - ((mem16) (o16 255 /3)) &lt;br /&gt;Adding :CALL to table - ((imm:imm32) (o32 154 id iw)) &lt;br /&gt;Adding :CALL to table - ((imm:imm16) (o16 154 iw iw)) &lt;br /&gt;Adding :CALL to table - ((imm) (232 rw/rd)) &lt;br /&gt;Adding :BTS to table - ((r/m32 imm) (o32 15 186 /5 ib)) &lt;br /&gt;Adding :BTS to table - ((r/m16 imm) (o16 15 186 /5 ib)) &lt;br /&gt;Adding :BTS to table - ((r/m32 reg32) (o32 15 171 /r)) &lt;br /&gt;Adding :BTS to table - ((r/m16 reg16) (o16 15 171 /r)) &lt;br /&gt;Adding :BTR to table - ((r/m32 imm8) (o32 15 186 /6 ib)) &lt;br /&gt;Adding :BTR to table - ((r/m16 imm8) (o16 15 186 /6 ib)) &lt;br /&gt;Adding :BTR to table - ((r/m32 reg32) (o32 15 179 /r)) &lt;br /&gt;Adding :BTR to table - ((r/m16 reg16) (o16 15 179 /r)) &lt;br /&gt;Adding :BTC to table - ((r/m32 imm8) (o32 15 186 /7 ib)) &lt;br /&gt;Adding :BTC to table - ((r/m16 imm8) (o16 15 186 /7 ib)) &lt;br /&gt;Adding :BTC to table - ((r/m32 reg32) (o32 15 187 /r)) &lt;br /&gt;Adding :BTC to table - ((r/m16 reg16) (o16 15 187 /r)) &lt;br /&gt;Adding :BT to table - ((r/m32 imm8) (o32 15 186 /4 ib)) &lt;br /&gt;Adding :BT to table - ((r/m16 imm8) (o16 15 186 /4 ib)) &lt;br /&gt;Adding :BT to table - ((r/m32 reg32) (o32 15 163 /r)) &lt;br /&gt;Adding :BT to table - ((r/m16 reg16) (o16 15 163 /r)) &lt;br /&gt;Adding :BSWAP to table - ((reg32) (o32 15 200 +r)) &lt;br /&gt;Adding :BSR to table - ((reg32 r/m32) (o32 15 189 /r)) &lt;br /&gt;Adding :BSR to table - ((reg16 r/m16) (o16 15 189 /r)) &lt;br /&gt;Adding :BSF to table - ((reg32 r/m32) (o32 15 188 /r)) &lt;br /&gt;Adding :BSF to table - ((reg16 r/m16) (o16 15 188 /r)) &lt;br /&gt;Adding :BOUND to table - ((reg32 mem) (o32 98 /r)) &lt;br /&gt;Adding :BOUND to table - ((reg16 mem) (o16 98 /r)) &lt;br /&gt;Adding :ARPL to table - ((r/m16 reg16) (99 /r)) &lt;br /&gt;Adding :ANDPS to table - ((xmm1 xmm2/mem128) (15 84 /r)) &lt;br /&gt;Adding :ANDPD to table - ((xmm1 xmm2/mem128) (102 15 84 /r)) &lt;br /&gt;Adding :ANDNPS to table - ((xmm1 xmm2/mem128) (15 85 /r)) &lt;br /&gt;Adding :ANDNPD to table - ((xmm1 xmm2/mem128) (102 15 85 /r)) &lt;br /&gt;Adding :AND to table - ((EAX imm32) (o32 37 id)) &lt;br /&gt;Adding :AND to table - ((AX imm16) (o16 37 iw)) &lt;br /&gt;Adding :AND to table - ((AL imm8) (36 ib)) &lt;br /&gt;Adding :AND to table - ((r/m32 imm8) (o32 131 /4 ib)) &lt;br /&gt;Adding :AND to table - ((r/m16 imm8) (o16 131 /4 ib)) &lt;br /&gt;Adding :AND to table - ((r/m32 imm32) (o32 129 /4 id)) &lt;br /&gt;Adding :AND to table - ((r/m16 imm16) (o16 129 /4 iw)) &lt;br /&gt;Adding :AND to table - ((r/m8 imm8) (128 /4 ib)) &lt;br /&gt;Adding :AND to table - ((reg32 r/m32) (o32 35 /r)) &lt;br /&gt;Adding :AND to table - ((reg16 r/m16) (o16 35 /r)) &lt;br /&gt;Adding :AND to table - ((reg8 r/m8) (34 /r)) &lt;br /&gt;Adding :AND to table - ((r/m32 reg32) (o32 33 /r)) &lt;br /&gt;Adding :AND to table - ((r/m16 reg16) (o16 33 /r)) &lt;br /&gt;Adding :AND to table - ((r/m8 reg8) (32 /r)) &lt;br /&gt;Adding :ADDSS to table - ((xmm1 xmm2/mem32) (243 15 88 /r)) &lt;br /&gt;Adding :ADDSD to table - ((xmm1 xmm2/mem64) (242 15 88 /r)) &lt;br /&gt;Adding :ADDPS to table - ((xmm1 xmm2/mem128) (15 88 /r)) &lt;br /&gt;Adding :ADDPD to table - ((xmm1 xmm2/mem128) (102 15 88 /r)) &lt;br /&gt;Adding :ADD to table - ((EAX imm32) (o32 5 id)) &lt;br /&gt;Adding :ADD to table - ((AX imm16) (o16 5 iw)) &lt;br /&gt;Adding :ADD to table - ((AL imm8) (4 ib)) &lt;br /&gt;Adding :ADD to table - ((r/m32 imm8) (o32 131 /0 ib)) &lt;br /&gt;Adding :ADD to table - ((r/m16 imm8) (o16 131 /0 ib)) &lt;br /&gt;Adding :ADD to table - ((r/m32 imm32) (o32 129 /0 id)) &lt;br /&gt;Adding :ADD to table - ((r/m16 imm16) (o16 129 /0 iw)) &lt;br /&gt;Adding :ADD to table - ((r/m8 imm8) (128 /0 ib)) &lt;br /&gt;Adding :ADD to table - ((reg32 r/m32) (o32 3 /r)) &lt;br /&gt;Adding :ADD to table - ((reg16 r/m16) (o16 3 /r)) &lt;br /&gt;Adding :ADD to table - ((reg8 r/m8) (2 /r)) &lt;br /&gt;Adding :ADD to table - ((r/m32 reg32) (o32 1 /r)) &lt;br /&gt;Adding :ADD to table - ((r/m16 reg16) (o16 1 /r)) &lt;br /&gt;Adding :ADD to table - ((r/m8 reg8) (0 /r)) &lt;br /&gt;Adding :ADC to table - ((EAX imm32) (o32 21 id)) &lt;br /&gt;Adding :ADC to table - ((AX imm16) (o16 21 iw)) &lt;br /&gt;Adding :ADC to table - ((AL imm8) (20 ib)) &lt;br /&gt;Adding :ADC to table - ((r/m32 imm8) (o32 131 /2 ib)) &lt;br /&gt;Adding :ADC to table - ((r/m16 imm8) (o16 131 /2 ib)) &lt;br /&gt;Adding :ADC to table - ((r/m32 imm32) (o32 129 /2 id)) &lt;br /&gt;Adding :ADC to table - ((r/m16 imm16) (o16 129 /2 iw)) &lt;br /&gt;Adding :ADC to table - ((r/m8 imm8) (128 /2 ib)) &lt;br /&gt;Adding :ADC to table - ((reg32 r/m32) (o32 19 /r)) &lt;br /&gt;Adding :ADC to table - ((reg16 r/m16) (o16 19 /r)) &lt;br /&gt;Adding :ADC to table - ((reg8 r/m8) (18 /r)) &lt;br /&gt;Adding :ADC to table - ((r/m32 reg32) (o32 17 /r)) &lt;br /&gt;Adding :ADC to table - ((r/m16 reg16) (o16 17 /r)) &lt;br /&gt;Adding :ADC to table - ((r/m8 reg8) (16 /r)) &lt;br /&gt;Adding :AAM to table - ((imm) (212 ib)) &lt;br /&gt;Adding :AAM to table - (NIL (212 10)) &lt;br /&gt;Adding :AAD to table - ((imm) (213 ib)) &lt;br /&gt;Adding :AAD to table - (NIL (213 10)) &lt;br /&gt;Adding :AAS to table - (NIL (63)) &lt;br /&gt;Adding :AAA to table - (NIL (55)) &lt;br /&gt;Adding :|J0 NEAR| to table - ((imm) (15 128 rw/rd)) &lt;br /&gt;Adding :|JNO NEAR| to table - ((imm) (15 129 rw/rd)) &lt;br /&gt;Adding :|JB NEAR| to table - ((imm) (15 130 rw/rd)) &lt;br /&gt;Adding :|JC NEAR| to table - ((imm) (15 130 rw/rd)) &lt;br /&gt;Adding :|JNAE NEAR| to table - ((imm) (15 130 rw/rd)) &lt;br /&gt;Adding :|JAE NEAR| to table - ((imm) (15 131 rw/rd)) &lt;br /&gt;Adding :|JNB NEAR| to table - ((imm) (15 131 rw/rd)) &lt;br /&gt;Adding :|JNC NEAR| to table - ((imm) (15 131 rw/rd)) &lt;br /&gt;Adding :|JE NEAR| to table - ((imm) (15 132 rw/rd)) &lt;br /&gt;Adding :|JZ NEAR| to table - ((imm) (15 132 rw/rd)) &lt;br /&gt;Adding :|JNE NEAR| to table - ((imm) (15 133 rw/rd)) &lt;br /&gt;Adding :|JNZ NEAR| to table - ((imm) (15 133 rw/rd)) &lt;br /&gt;Adding :|JBE NEAR| to table - ((imm) (15 134 rw/rd)) &lt;br /&gt;Adding :|JNA NEAR| to table - ((imm) (15 134 rw/rd)) &lt;br /&gt;Adding :|JA NEAR| to table - ((imm) (15 135 rw/rd)) &lt;br /&gt;Adding :|JNBE NEAR| to table - ((imm) (15 135 rw/rd)) &lt;br /&gt;Adding :|JS NEAR| to table - ((imm) (15 136 rw/rd)) &lt;br /&gt;Adding :|JNS NEAR| to table - ((imm) (15 137 rw/rd)) &lt;br /&gt;Adding :|JP NEAR| to table - ((imm) (15 138 rw/rd)) &lt;br /&gt;Adding :|JPE NEAR| to table - ((imm) (15 138 rw/rd)) &lt;br /&gt;Adding :|JNP NEAR| to table - ((imm) (15 139 rw/rd)) &lt;br /&gt;Adding :|JPO NEAR| to table - ((imm) (15 139 rw/rd)) &lt;br /&gt;Adding :|JL NEAR| to table - ((imm) (15 140 rw/rd)) &lt;br /&gt;Adding :|JNGE NEAR| to table - ((imm) (15 140 rw/rd)) &lt;br /&gt;Adding :|JGE NEAR| to table - ((imm) (15 141 rw/rd)) &lt;br /&gt;Adding :|JNL NEAR| to table - ((imm) (15 141 rw/rd)) &lt;br /&gt;Adding :|JLE NEAR| to table - ((imm) (15 142 rw/rd)) &lt;br /&gt;Adding :|JNG NEAR| to table - ((imm) (15 142 rw/rd)) &lt;br /&gt;Adding :|JG NEAR| to table - ((imm) (15 143 rw/rd)) &lt;br /&gt;Adding :|JNLE NEAR| to table - ((imm) (15 143 rw/rd)) &lt;br /&gt;Adding :J0 to table - ((imm) (112 rb)) &lt;br /&gt;Adding :JNO to table - ((imm) (113 rb)) &lt;br /&gt;Adding :JB to table - ((imm) (114 rb)) &lt;br /&gt;Adding :JC to table - ((imm) (114 rb)) &lt;br /&gt;Adding :JNAE to table - ((imm) (114 rb)) &lt;br /&gt;Adding :JAE to table - ((imm) (115 rb)) &lt;br /&gt;Adding :JNB to table - ((imm) (115 rb)) &lt;br /&gt;Adding :JNC to table - ((imm) (115 rb)) &lt;br /&gt;Adding :JE to table - ((imm) (116 rb)) &lt;br /&gt;Adding :JZ to table - ((imm) (116 rb)) &lt;br /&gt;Adding :JNE to table - ((imm) (117 rb)) &lt;br /&gt;Adding :JNZ to table - ((imm) (117 rb)) &lt;br /&gt;Adding :JBE to table - ((imm) (118 rb)) &lt;br /&gt;Adding :JNA to table - ((imm) (118 rb)) &lt;br /&gt;Adding :JA to table - ((imm) (119 rb)) &lt;br /&gt;Adding :JNBE to table - ((imm) (119 rb)) &lt;br /&gt;Adding :JS to table - ((imm) (120 rb)) &lt;br /&gt;Adding :JNS to table - ((imm) (121 rb)) &lt;br /&gt;Adding :JP to table - ((imm) (122 rb)) &lt;br /&gt;Adding :JPE to table - ((imm) (122 rb)) &lt;br /&gt;Adding :JNP to table - ((imm) (123 rb)) &lt;br /&gt;Adding :JPO to table - ((imm) (123 rb)) &lt;br /&gt;Adding :JL to table - ((imm) (124 rb)) &lt;br /&gt;Adding :JNGE to table - ((imm) (124 rb)) &lt;br /&gt;Adding :JGE to table - ((imm) (125 rb)) &lt;br /&gt;Adding :JNL to table - ((imm) (125 rb)) &lt;br /&gt;Adding :JLE to table - ((imm) (126 rb)) &lt;br /&gt;Adding :JNG to table - ((imm) (126 rb)) &lt;br /&gt;Adding :JG to table - ((imm) (127 rb)) &lt;br /&gt;Adding :JNLE to table - ((imm) (127 rb)) &lt;br /&gt;Adding :SET0 to table - ((r/m8) (15 144 /2)) &lt;br /&gt;Adding :SETNO to table - ((r/m8) (15 145 /2)) &lt;br /&gt;Adding :SETB to table - ((r/m8) (15 146 /2)) &lt;br /&gt;Adding :SETC to table - ((r/m8) (15 146 /2)) &lt;br /&gt;Adding :SETNAE to table - ((r/m8) (15 146 /2)) &lt;br /&gt;Adding :SETAE to table - ((r/m8) (15 147 /2)) &lt;br /&gt;Adding :SETNB to table - ((r/m8) (15 147 /2)) &lt;br /&gt;Adding :SETNC to table - ((r/m8) (15 147 /2)) &lt;br /&gt;Adding :SETE to table - ((r/m8) (15 148 /2)) &lt;br /&gt;Adding :SETZ to table - ((r/m8) (15 148 /2)) &lt;br /&gt;Adding :SETNE to table - ((r/m8) (15 149 /2)) &lt;br /&gt;Adding :SETNZ to table - ((r/m8) (15 149 /2)) &lt;br /&gt;Adding :SETBE to table - ((r/m8) (15 150 /2)) &lt;br /&gt;Adding :SETNA to table - ((r/m8) (15 150 /2)) &lt;br /&gt;Adding :SETA to table - ((r/m8) (15 151 /2)) &lt;br /&gt;Adding :SETNBE to table - ((r/m8) (15 151 /2)) &lt;br /&gt;Adding :SETS to table - ((r/m8) (15 152 /2)) &lt;br /&gt;Adding :SETNS to table - ((r/m8) (15 153 /2)) &lt;br /&gt;Adding :SETP to table - ((r/m8) (15 154 /2)) &lt;br /&gt;Adding :SETPE to table - ((r/m8) (15 154 /2)) &lt;br /&gt;Adding :SETNP to table - ((r/m8) (15 155 /2)) &lt;br /&gt;Adding :SETPO to table - ((r/m8) (15 155 /2)) &lt;br /&gt;Adding :SETL to table - ((r/m8) (15 156 /2)) &lt;br /&gt;Adding :SETNGE to table - ((r/m8) (15 156 /2)) &lt;br /&gt;Adding :SETGE to table - ((r/m8) (15 157 /2)) &lt;br /&gt;Adding :SETNL to table - ((r/m8) (15 157 /2)) &lt;br /&gt;Adding :SETLE to table - ((r/m8) (15 158 /2)) &lt;br /&gt;Adding :SETNG to table - ((r/m8) (15 158 /2)) &lt;br /&gt;Adding :SETG to table - ((r/m8) (15 159 /2)) &lt;br /&gt;Adding :SETNLE to table - ((r/m8) (15 159 /2)) &lt;br /&gt;Adding :CMOV0 to table - ((reg32 r/m32) (o32 15 64 /r)) &lt;br /&gt;Adding :CMOVNO to table - ((reg32 r/m32) (o32 15 65 /r)) &lt;br /&gt;Adding :CMOVB to table - ((reg32 r/m32) (o32 15 66 /r)) &lt;br /&gt;Adding :CMOVC to table - ((reg32 r/m32) (o32 15 66 /r)) &lt;br /&gt;Adding :CMOVNAE to table - ((reg32 r/m32) (o32 15 66 /r)) &lt;br /&gt;Adding :CMOVAE to table - ((reg32 r/m32) (o32 15 67 /r)) &lt;br /&gt;Adding :CMOVNB to table - ((reg32 r/m32) (o32 15 67 /r)) &lt;br /&gt;Adding :CMOVNC to table - ((reg32 r/m32) (o32 15 67 /r)) &lt;br /&gt;Adding :CMOVE to table - ((reg32 r/m32) (o32 15 68 /r)) &lt;br /&gt;Adding :CMOVZ to table - ((reg32 r/m32) (o32 15 68 /r)) &lt;br /&gt;Adding :CMOVNE to table - ((reg32 r/m32) (o32 15 69 /r)) &lt;br /&gt;Adding :CMOVNZ to table - ((reg32 r/m32) (o32 15 69 /r)) &lt;br /&gt;Adding :CMOVBE to table - ((reg32 r/m32) (o32 15 70 /r)) &lt;br /&gt;Adding :CMOVNA to table - ((reg32 r/m32) (o32 15 70 /r)) &lt;br /&gt;Adding :CMOVA to table - ((reg32 r/m32) (o32 15 71 /r)) &lt;br /&gt;Adding :CMOVNBE to table - ((reg32 r/m32) (o32 15 71 /r)) &lt;br /&gt;Adding :CMOVS to table - ((reg32 r/m32) (o32 15 72 /r)) &lt;br /&gt;Adding :CMOVNS to table - ((reg32 r/m32) (o32 15 73 /r)) &lt;br /&gt;Adding :CMOVP to table - ((reg32 r/m32) (o32 15 74 /r)) &lt;br /&gt;Adding :CMOVPE to table - ((reg32 r/m32) (o32 15 74 /r)) &lt;br /&gt;Adding :CMOVNP to table - ((reg32 r/m32) (o32 15 75 /r)) &lt;br /&gt;Adding :CMOVPO to table - ((reg32 r/m32) (o32 15 75 /r)) &lt;br /&gt;Adding :CMOVL to table - ((reg32 r/m32) (o32 15 76 /r)) &lt;br /&gt;Adding :CMOVNGE to table - ((reg32 r/m32) (o32 15 76 /r)) &lt;br /&gt;Adding :CMOVGE to table - ((reg32 r/m32) (o32 15 77 /r)) &lt;br /&gt;Adding :CMOVNL to table - ((reg32 r/m32) (o32 15 77 /r)) &lt;br /&gt;Adding :CMOVLE to table - ((reg32 r/m32) (o32 15 78 /r)) &lt;br /&gt;Adding :CMOVNG to table - ((reg32 r/m32) (o32 15 78 /r)) &lt;br /&gt;Adding :CMOVG to table - ((reg32 r/m32) (o32 15 79 /r)) &lt;br /&gt;Adding :CMOVNLE to table - ((reg32 r/m32) (o32 15 79 /r)) &lt;br /&gt;Adding :CMOV0 to table - ((reg16 r/m16) (o16 15 64 /r)) &lt;br /&gt;Adding :CMOVNO to table - ((reg16 r/m16) (o16 15 65 /r)) &lt;br /&gt;Adding :CMOVB to table - ((reg16 r/m16) (o16 15 66 /r)) &lt;br /&gt;Adding :CMOVC to table - ((reg16 r/m16) (o16 15 66 /r)) &lt;br /&gt;Adding :CMOVNAE to table - ((reg16 r/m16) (o16 15 66 /r)) &lt;br /&gt;Adding :CMOVAE to table - ((reg16 r/m16) (o16 15 67 /r)) &lt;br /&gt;Adding :CMOVNB to table - ((reg16 r/m16) (o16 15 67 /r)) &lt;br /&gt;Adding :CMOVNC to table - ((reg16 r/m16) (o16 15 67 /r)) &lt;br /&gt;Adding :CMOVE to table - ((reg16 r/m16) (o16 15 68 /r)) &lt;br /&gt;Adding :CMOVZ to table - ((reg16 r/m16) (o16 15 68 /r)) &lt;br /&gt;Adding :CMOVNE to table - ((reg16 r/m16) (o16 15 69 /r)) &lt;br /&gt;Adding :CMOVNZ to table - ((reg16 r/m16) (o16 15 69 /r)) &lt;br /&gt;Adding :CMOVBE to table - ((reg16 r/m16) (o16 15 70 /r)) &lt;br /&gt;Adding :CMOVNA to table - ((reg16 r/m16) (o16 15 70 /r)) &lt;br /&gt;Adding :CMOVA to table - ((reg16 r/m16) (o16 15 71 /r)) &lt;br /&gt;Adding :CMOVNBE to table - ((reg16 r/m16) (o16 15 71 /r)) &lt;br /&gt;Adding :CMOVS to table - ((reg16 r/m16) (o16 15 72 /r)) &lt;br /&gt;Adding :CMOVNS to table - ((reg16 r/m16) (o16 15 73 /r)) &lt;br /&gt;Adding :CMOVP to table - ((reg16 r/m16) (o16 15 74 /r)) &lt;br /&gt;Adding :CMOVPE to table - ((reg16 r/m16) (o16 15 74 /r)) &lt;br /&gt;Adding :CMOVNP to table - ((reg16 r/m16) (o16 15 75 /r)) &lt;br /&gt;Adding :CMOVPO to table - ((reg16 r/m16) (o16 15 75 /r)) &lt;br /&gt;Adding :CMOVL to table - ((reg16 r/m16) (o16 15 76 /r)) &lt;br /&gt;Adding :CMOVNGE to table - ((reg16 r/m16) (o16 15 76 /r)) &lt;br /&gt;Adding :CMOVGE to table - ((reg16 r/m16) (o16 15 77 /r)) &lt;br /&gt;Adding :CMOVNL to table - ((reg16 r/m16) (o16 15 77 /r)) &lt;br /&gt;Adding :CMOVLE to table - ((reg16 r/m16) (o16 15 78 /r)) &lt;br /&gt;Adding :CMOVNG to table - ((reg16 r/m16) (o16 15 78 /r)) &lt;br /&gt;Adding :CMOVG to table - ((reg16 r/m16) (o16 15 79 /r)) &lt;br /&gt;Adding :CMOVNLE to table - ((reg16 r/m16) (o16 15 79 /r)) &lt;br /&gt;NIL&lt;br /&gt;CL-USER&gt; (cl-x86-asm::make-segment "text" :segment-type 'data-segment :set-to-current t)&lt;br /&gt;; Evaluation aborted&lt;br /&gt;CL-USER&gt; (cl-x86-asm::make-segment "text" :segment-type 'cl-x86-asm::data-segment :set-to-current t)&lt;br /&gt;#&lt;PACKAGE "text-x86-symbol-package"&gt;&lt;br /&gt;CL-USER&gt; (cl-x86-asm::assemble-forms :AAD :RET)&lt;br /&gt;Looking up instruction AAD&lt;br /&gt;Found instruction AAD&lt;br /&gt;Looking up instruction RET&lt;br /&gt;Found instruction RET&lt;br /&gt;(NIL NIL)&lt;br /&gt;CL-USER&gt; &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-116567905682753149?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/116567905682753149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=116567905682753149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116567905682753149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116567905682753149'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/12/birth-of-assembler.html' title='The birth of an assembler.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-116567542919332580</id><published>2006-12-09T14:33:00.000Z</published><updated>2006-12-09T14:44:05.006Z</updated><title type='text'>meta-meta-programming</title><content type='html'>Strictly for laughs, and partly for performance: a bit of meta-meta-programming.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;;; make #{ .. } notation become a short hand for (values ...)&lt;br /&gt;(defun |#{-reader| (stream char arg)&lt;br /&gt;   (declare (ignore char arg))&lt;br /&gt;    `(values ,@(read-delimited-list #\} stream t)))&lt;br /&gt;&lt;br /&gt;(set-dispatch-macro-character #\# #\{ #'|#{-reader|) &lt;br /&gt;(set-macro-character #\} (get-macro-character #\) nil))&lt;br /&gt;&lt;br /&gt;(defmacro make-tuple-struct (&amp;key type-name  tuple-type tuple-default-value elements)&lt;br /&gt;  "Create a structure in the form needed for tuple / packing&lt;br /&gt;unpacking. All fields should have the same type and default value."&lt;br /&gt;  `(defstruct ,type-name &lt;br /&gt;     ,@(loop&lt;br /&gt;     for element in elements&lt;br /&gt;     collect (list element tuple-default-value :type tuple-type))))&lt;br /&gt;&lt;br /&gt;;; test code&lt;br /&gt;(make-tuple-struct :type-name vector2d   :tuple-type single-float :tuple-default-value 0.0 :elements (x y))&lt;br /&gt;(make-tuple-struct :type-name vector3d   :tuple-type single-float :tuple-default-value 0.0 :elements (x y z))&lt;br /&gt;(make-tuple-struct :type-name vector4d   :tuple-type single-float :tuple-default-value 0.0 :elements (x y z w))&lt;br /&gt;(make-tuple-struct :type-name quaternion :tuple-type single-float :tuple-default-value 0.0 :elements (x y z w))&lt;br /&gt;(make-tuple-struct :type-name color      :tuple-type single-float :tuple-default-value 0.0 :elements (r g b a))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defmacro with-gensyms (syms &amp;body body)&lt;br /&gt;  `(let ,(mapcar #'(lambda (s) `(,s (gensym)))&lt;br /&gt;   syms)&lt;br /&gt;     ,@body))&lt;br /&gt;&lt;br /&gt;(defmacro make-tuple-unpacker (&amp;key type-name elements)&lt;br /&gt;  "Create an unpacker function such as (vector? vector4d) that takes an instance&lt;br /&gt;of a struct and unpacks it to tuples (aka multiple values)"&lt;br /&gt;  (labels&lt;br /&gt;      ((make-macro-name (type-name)&lt;br /&gt;  (intern (concatenate 'string &lt;br /&gt;         (symbol-name type-name)&lt;br /&gt;         "?")))&lt;br /&gt;       (make-element-names (elements)&lt;br /&gt;  (mapcar #'(lambda (x) &lt;br /&gt;       (find-symbol  &lt;br /&gt;        (concatenate 'string &lt;br /&gt;       (symbol-name type-name) "-" &lt;br /&gt;       (symbol-name x))))&lt;br /&gt;   elements)))&lt;br /&gt;    `(defmacro ,(make-macro-name type-name) (packed-tuple)&lt;br /&gt;      (let ((packed-tuple-sym (gensym)))&lt;br /&gt; `(let&lt;br /&gt;     ((,packed-tuple-sym ,packed-tuple))&lt;br /&gt;    (values ,@(loop &lt;br /&gt;   for element-name in (quote ,(make-element-names elements))&lt;br /&gt;   collect (list element-name packed-tuple-sym))))))))&lt;br /&gt;&lt;br /&gt;       &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(make-tuple-unpacker :type-name vector2d :elements (x y))&lt;br /&gt;(make-tuple-unpacker :type-name vector3d :elements (x y z))&lt;br /&gt;(make-tuple-unpacker :type-name vector4d :elements (x y z w))&lt;br /&gt;(make-tuple-unpacker :type-name quaternion :elements (x y z w))&lt;br /&gt;(make-tuple-unpacker :type-name color  :elements (r g b a))&lt;br /&gt;&lt;br /&gt;;; to do - not entirely sure if this is wise/neeed&lt;br /&gt;;; is anything evaluated more than once? I lost track&lt;br /&gt;(defmacro make-with-tuple (&amp;key type-name)&lt;br /&gt;  "Create a macro that can be used to bind members of the tuples struct to symbols&lt;br /&gt;   to symbols e-g (with-vector thing-vec (x y z w) &amp;body forms)"&lt;br /&gt;  (labels &lt;br /&gt;      ((make-unpacker-name (type-name)&lt;br /&gt;  (intern (concatenate 'string &lt;br /&gt;         (symbol-name type-name)&lt;br /&gt;         "?")))&lt;br /&gt;       (make-macro-name (type-name)&lt;br /&gt;  (intern (concatenate 'string &lt;br /&gt;         "WITH-"&lt;br /&gt;         (symbol-name type-name)))))&lt;br /&gt;       `(defmacro ,(make-macro-name type-name) (tuple element-syms &amp;body forms)&lt;br /&gt;   `(multiple-value-bind&lt;br /&gt;   ,(loop &lt;br /&gt;       for element-sym in element-syms &lt;br /&gt;       collect element-sym)&lt;br /&gt;        (,',(make-unpacker-name type-name) ,tuple)&lt;br /&gt;      ,@forms))))&lt;br /&gt;&lt;br /&gt;(make-with-tuple :type-name vector2d)&lt;br /&gt;(make-with-tuple :type-name vector3d)&lt;br /&gt;(make-with-tuple :type-name vector4d)&lt;br /&gt;(make-with-tuple :type-name quarternion)&lt;br /&gt;(make-with-tuple :type-name color)&lt;br /&gt;&lt;br /&gt;(defmacro make-tuple-packer (&amp;key type-name elements)&lt;br /&gt;  "Create a tuple-name! macro for packing multiple values into &lt;br /&gt;   a tuple struct. eg (vector! up #{ 0.0 1.0 0.0 })"&lt;br /&gt;  (labels &lt;br /&gt;      ((make-packer-name (type-name)&lt;br /&gt;  (intern (concatenate 'string &lt;br /&gt;         (symbol-name type-name)&lt;br /&gt;         "!")))&lt;br /&gt;       (make-element-names (elements)&lt;br /&gt;  (mapcar #'(lambda (x) &lt;br /&gt;       (find-symbol  &lt;br /&gt;        (concatenate 'string &lt;br /&gt;       (symbol-name type-name) "-" &lt;br /&gt;       (symbol-name x))))&lt;br /&gt;   elements)))&lt;br /&gt;    `(defmacro ,(make-packer-name type-name) (target-sym tuple-values)&lt;br /&gt;       (let* ((element-name-list ',(make-element-names elements))     &lt;br /&gt;       (varlist (mapcar #'(lambda (x) (gensym (symbol-name x))) element-name-list)))&lt;br /&gt;  `(multiple-value-bind  &lt;br /&gt;  ,(mapcar #'(lambda (x) x) varlist)&lt;br /&gt;       ,tuple-values&lt;br /&gt;   (progn  ,@(mapcar #'(lambda (p v) `(setf (,p ,target-sym) ,v)) element-name-list varlist)))))))&lt;br /&gt;&lt;br /&gt;(make-tuple-packer :type-name vector2d   :elements (x y))&lt;br /&gt;(make-tuple-packer :type-name vector3d   :elements (x y z))&lt;br /&gt;(make-tuple-packer :type-name vector4d   :elements (x y z w))&lt;br /&gt;(make-tuple-packer :type-name quaternion :elements (x y z w))&lt;br /&gt;(make-tuple-packer :type-name color      :elements (r g b a))&lt;br /&gt;&lt;br /&gt;(defparameter *blue* (make-color  :b 1.0))&lt;br /&gt;(defparameter *transparent-blue* (make-color :b 1.0 :a 0.5))&lt;br /&gt;(defparameter *red* (make-color  :r 1.0))&lt;br /&gt;(defparameter *yellow* (make-color :r 1.0 :g 1.0))&lt;br /&gt;(with-color *yellow* (yr yg yb ya) (format t "Yellow ~A ~A ~A ~A " yr yg yb ya))&lt;br /&gt;&lt;br /&gt;;; change yellow to white&lt;br /&gt;(color! *yellow*  #{ 1.0 1.0 1.0 0.0 })&lt;br /&gt;&lt;br /&gt;(with-color *yellow* (yr yg yb ya) (format t "Yellow ~A ~A ~A ~A " yr yg yb ya))&lt;br /&gt;&lt;br /&gt;;; confirm change&lt;br /&gt;(color? *yellow*)&lt;br /&gt;&lt;br /&gt;(defmacro make-tuple-type (tuple-name &amp;key tuple-element-type tuple-default-value elements)&lt;br /&gt;  "Create a tuple type in one swoosh with all the support macros for it"&lt;br /&gt;  `(progn&lt;br /&gt;    (make-tuple-struct :type-name ,tuple-name&lt;br /&gt;        :tuple-type ,tuple-element-type &lt;br /&gt;        :tuple-default-value ,tuple-default-value&lt;br /&gt;        :elements  ,elements )&lt;br /&gt;    (make-tuple-unpacker :type-name ,tuple-name :elements ,elements)&lt;br /&gt;    (make-with-tuple :type-name ,tuple-name)&lt;br /&gt;    (make-tuple-packer :type-name ,tuple-name :elements ,elements)))&lt;br /&gt;&lt;br /&gt;(make-tuple-type pixel :tuple-element-type (unsigned-byte 8) :tuple-default-value 0 :elements (b r g a)) &lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;make-tuple-type is a macro that invokes a set of macros that invoke macros. I hope to be able to build on this to get together a decent 3d-game/spatial-math collection of lisp code. Now I have to think about how exactly I want transforms to work. I'm tempted to code them as scale-rotate-translate rather than a straight matrix.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-116567542919332580?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/116567542919332580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=116567542919332580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116567542919332580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/116567542919332580'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/12/meta-meta-programming.html' title='meta-meta-programming'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-115672162400393581</id><published>2006-08-28T00:23:00.000+01:00</published><updated>2006-08-28T00:33:44.023+01:00</updated><title type='text'>A POD polymorphic object</title><content type='html'>&lt;p&gt;Impossible, you cry: POD is POD and virtual functions are virtual functions and nary the twain shall meet! More sophisticated readers among you might assume this is a rehash of static polymorphism, but this is not so. I have a POD struct that can be used nonhomegenously in a container,  and support run-time polymorphism. Without further ado, here is the code..&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;simple.h&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;enum&lt;/span&gt; &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;   eMeshObject = 0,&lt;br /&gt;   eSkeletonObject,&lt;br /&gt;   nEngineObjectKinds&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;typedef&lt;/span&gt; &lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="type"&gt;t_TRANSFORM&lt;/span&gt;[16];&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;typedef&lt;/span&gt; &lt;span class="type"&gt;void&lt;/span&gt; (*&lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt;)(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;extern&lt;/span&gt; &lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="variable-name"&gt;update_jump_table&lt;/span&gt;[nEngineObjectKinds];&lt;br /&gt;&lt;br /&gt;template &amp;lt;typename T&amp;gt; class EngineObject&lt;br /&gt;{&lt;br /&gt;   &lt;span class="constant"&gt;private&lt;/span&gt;:&lt;br /&gt;      &lt;span class="type"&gt;T&lt;/span&gt;* &lt;span class="variable-name"&gt;object_data&lt;/span&gt;;&lt;br /&gt;      &lt;span class="keyword"&gt;enum&lt;/span&gt; &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="variable-name"&gt;kind&lt;/span&gt;;&lt;br /&gt;      &lt;br /&gt;   &lt;span class="constant"&gt;public&lt;/span&gt;:&lt;br /&gt;      &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="function-name"&gt;init_object&lt;/span&gt;()&lt;br /&gt;      {&lt;br /&gt;         kind = T::object_kind;  &lt;br /&gt;         update_jump_table[kind] = T::object_update_fn;&lt;br /&gt;         object_data = new T(); &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;or T::allocate_object&lt;br /&gt;&lt;/span&gt;      };&lt;br /&gt;      &lt;br /&gt;      &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="function-name"&gt;update_object&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;)&lt;br /&gt;      {&lt;br /&gt;         update_jump_table[kind](time_delta);&lt;br /&gt;      }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt;&amp;gt; class EngineObject&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;&amp;gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="constant"&gt;private&lt;/span&gt;:&lt;br /&gt;   &lt;span class="type"&gt;void&lt;/span&gt; *&lt;span class="variable-name"&gt;object_data&lt;/span&gt;;&lt;br /&gt;   &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="variable-name"&gt;kind&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;public&lt;/span&gt;:&lt;br /&gt;   &lt;span class="type"&gt;void&lt;/span&gt; *&lt;span class="function-name"&gt;getData&lt;/span&gt;() &lt;br /&gt;   {&lt;br /&gt;      &lt;span class="keyword"&gt;return&lt;/span&gt; object_data;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="function-name"&gt;getKind&lt;/span&gt;()&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="keyword"&gt;return&lt;/span&gt; kind;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="function-name"&gt;update_object&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;)&lt;br /&gt;   {&lt;br /&gt;      update_jump_table[kind](time_delta);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;class&lt;/span&gt; &lt;span class="variable-name"&gt;EngineMeshData&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="constant"&gt;public&lt;/span&gt;:&lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt;  &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="variable-name"&gt;object_kind&lt;/span&gt;; &lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt;  &lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="variable-name"&gt;object_update_fn&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="function-name"&gt;UpdateMesh&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;class&lt;/span&gt; &lt;span class="variable-name"&gt;EngineSkeletonData&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="constant"&gt;public&lt;/span&gt;:&lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt;  &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="variable-name"&gt;object_kind&lt;/span&gt;; &lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt;  &lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="variable-name"&gt;object_update_fn&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;span class="keyword"&gt;static&lt;/span&gt; &lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="function-name"&gt;UpdateSkeleton&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;typedef&lt;/span&gt; &lt;span class="type"&gt;EngineObject&lt;/span&gt;&amp;lt;EngineMeshData&amp;gt; EngineMeshObject;&lt;br /&gt;&lt;span class="keyword"&gt;typedef&lt;/span&gt; &lt;span class="type"&gt;EngineObject&lt;/span&gt;&amp;lt;EngineSkeletonData&amp;gt; EngineSkeletonObject;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;simple.cpp&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#include&lt;/span&gt; &lt;span class="string"&gt;"simple.h"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt; * pseudo - vtable !&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="variable-name"&gt;update_jump_table&lt;/span&gt;[nEngineObjectKinds];&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt; * skeleton defintions&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;enum&lt;/span&gt; &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="constant"&gt;EngineSkeletonData&lt;/span&gt;::&lt;span class="variable-name"&gt;object_kind&lt;/span&gt; = eSkeletonObject;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="constant"&gt;EngineSkeletonData&lt;/span&gt;::&lt;span class="function-name"&gt;UpdateSkeleton&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="constant"&gt;std&lt;/span&gt;::cout &amp;lt;&amp;lt; &lt;span class="string"&gt;"Update Skeleton\n"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="constant"&gt;EngineSkeletonData&lt;/span&gt;::&lt;span class="variable-name"&gt;object_update_fn&lt;/span&gt; = &lt;span class="constant"&gt;EngineSkeletonData&lt;/span&gt;::UpdateSkeleton;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/**&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt; * mesh defintions&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;enum&lt;/span&gt; &lt;span class="type"&gt;eEngineObjectKind&lt;/span&gt; &lt;span class="constant"&gt;EngineMeshData&lt;/span&gt;::&lt;span class="variable-name"&gt;object_kind&lt;/span&gt; = eMeshObject;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;void&lt;/span&gt; &lt;span class="constant"&gt;EngineMeshData&lt;/span&gt;::&lt;span class="function-name"&gt;UpdateMesh&lt;/span&gt;(&lt;span class="type"&gt;float&lt;/span&gt; &lt;span class="variable-name"&gt;time_delta&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="constant"&gt;std&lt;/span&gt;::cout &amp;lt;&amp;lt; &lt;span class="string"&gt;"Update Mesh\n"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;UpdateFunctionPtr&lt;/span&gt; &lt;span class="constant"&gt;EngineMeshData&lt;/span&gt;::&lt;span class="variable-name"&gt;object_update_fn&lt;/span&gt; = &lt;span class="constant"&gt;EngineMeshData&lt;/span&gt;::UpdateMesh;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;EngineObject&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;&amp;gt; &lt;span class="variable-name"&gt;world&lt;/span&gt;[2];&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="function-name"&gt;main&lt;/span&gt; (&lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;argc&lt;/span&gt;, &lt;span class="type"&gt;char&lt;/span&gt; *&lt;span class="variable-name"&gt;argv&lt;/span&gt;[])&lt;br /&gt;{&lt;br /&gt;   &lt;span class="type"&gt;EngineSkeletonObject&lt;/span&gt; *&lt;span class="variable-name"&gt;skeleton&lt;/span&gt; = &lt;span class="keyword"&gt;new&lt;/span&gt;(world) &lt;span class="type"&gt;EngineSkeletonObject&lt;/span&gt;();&lt;br /&gt;   skeleton-&amp;gt;init_object();&lt;br /&gt;&lt;br /&gt;   &lt;span class="type"&gt;EngineMeshObject&lt;/span&gt; *&lt;span class="variable-name"&gt;mesh&lt;/span&gt; = &lt;span class="keyword"&gt;new&lt;/span&gt;(world+1) &lt;span class="type"&gt;EngineMeshObject&lt;/span&gt;();&lt;br /&gt;   mesh-&amp;gt;init_object();&lt;br /&gt;&lt;br /&gt;   world[0].update_object(1.0f);&lt;br /&gt;   world[1].update_object(1.0f);&lt;br /&gt;   &lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-115672162400393581?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/115672162400393581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=115672162400393581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115672162400393581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115672162400393581'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/08/pod-polymorphic-object.html' title='A POD polymorphic object'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-115615061368986275</id><published>2006-08-21T09:54:00.000+01:00</published><updated>2006-08-21T09:56:53.700+01:00</updated><title type='text'>The autoconf dance..</title><content type='html'>It goes like this: .in and out....&lt;br /&gt;&lt;br /&gt;aclocal -&gt; aclocal.m4&lt;br /&gt;autoheader -&gt; config.h&lt;br /&gt;autoconf -&gt; configure&lt;br /&gt;automake -&gt; Makefile.ac -&gt; Makefile.in&lt;br /&gt;configure -&gt; Makefile.in -&gt; Makefile&lt;br /&gt;&lt;br /&gt;Then make finally builds it....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-115615061368986275?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/115615061368986275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=115615061368986275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115615061368986275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115615061368986275'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/08/autoconf-dance.html' title='The autoconf dance..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-115404761759003817</id><published>2006-07-28T01:40:00.000+01:00</published><updated>2006-07-28T01:46:57.606+01:00</updated><title type='text'>Etags</title><content type='html'>Nice as Emacs is for editing languages like Lisp, Lua or Python, I've never been 100% happy with it for C/C++ until now. I finally got my etags setup right. The trick is to do:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: courier new;"&gt;find /usr/include -name '*.h' | etags --declarations    --no-globals&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;in your home directory and use the --include option of etags to include the generated TAG file in your home directory in your project TAG files.&lt;br /&gt;&lt;br /&gt;This means you have a handy dictinonary you can use up to look up the function prototypes and macros in your system includes, which is something I have been missing a lot. Just looking at the function prototype itself is much better for jogging memory while in the zone, rather than having to hunt it down in a manual..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-115404761759003817?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/115404761759003817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=115404761759003817' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115404761759003817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/115404761759003817'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/07/etags.html' title='Etags'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114702279732023374</id><published>2006-05-07T18:20:00.000+01:00</published><updated>2006-05-07T18:26:37.330+01:00</updated><title type='text'>Python style tuples in Lisp</title><content type='html'>It's easy to extend Lisp to handle python-style tuples.  This is all it takes:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defun |#{-reader| (stream char arg)&lt;br /&gt;   (declare (ignore char arg))&lt;br /&gt;    `(values ,@(read-delimited-list #\} stream t)))&lt;br /&gt;&lt;br /&gt;(set-dispatch-macro-character #\# #\{ #'|#{-reader|)&lt;br /&gt;(set-macro-character #\} (get-macro-character #\) nil))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;It installs a despatching macro in the readtable - so that when the reader encounters the #{ sequence it reads it up to the } terminating character, then  splices it into  a (values  ...) form.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;You can do neat things like (setf #{x y z} #{ 1.2 3.0 3.0 }) to do tuple assignment with no further work - it all falls out of the standard behaviour of Common Lisp.&lt;br /&gt;&lt;br/&gt;&lt;br /&gt;What I'm wondering, now  is if it's possible to combine readtable hacks with regular expressions to implement a lexical parser for an entirely different language without leaving Lisp. I guess it is, but I haven't got a project with a use for it. Yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114702279732023374?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114702279732023374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114702279732023374' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114702279732023374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114702279732023374'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/05/python-style-tuples-in-lisp.html' title='Python style tuples in Lisp'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114649890168662359</id><published>2006-05-01T16:35:00.000+01:00</published><updated>2006-05-01T16:55:01.696+01:00</updated><title type='text'>Ludum Dare</title><content type='html'>Things I learnt on the &lt;a href="http://www.ludumdare.com/"&gt;Ludum Dare.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;Even on a 48 hour schedule, after you have done 90% of your game, you still have the other 90% to do - gameplay tweaking.&lt;/li&gt;   &lt;li&gt;There are some things I need to learn more about - pixel art, and audio coding. My finished game had no audio.&lt;/li&gt;   &lt;li&gt;You can't mix 2D SDL content (menus) and 3D opengl content easily. Although the SDL does let you flip between the modes easily.&lt;/li&gt;   &lt;li&gt;Steel Bank Common Lisp is not ready for prime-time application delivery on Win32. Although it is very close.&lt;/li&gt;   &lt;li&gt;I can code about 2x as fast in Lisp with SLIME vs C++.&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;I can still write games.&lt;/li&gt; &lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114649890168662359?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114649890168662359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114649890168662359' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114649890168662359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114649890168662359'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/05/ludum-dare.html' title='Ludum Dare'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114604702043954697</id><published>2006-04-26T11:19:00.000+01:00</published><updated>2006-07-28T01:56:27.186+01:00</updated><title type='text'>Microsoft</title><content type='html'>&lt;p&gt;Since Microsoft are currently telling the world what a nice monster they are and how evil and arbitary the EU Competition supremos are, I think it's time to look back to when there actually was some freedom and choice in the software world - just before the appearance of Win 3.1, when you could choose between DR-DOS or MS-DOS, and how Microsoft &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://www.ddj.com/article/printableArticle.jhtml?articleID=184409070&amp;amp;dept_url=/"&gt;killed&lt;/a&gt;&lt;/span&gt; that competition.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;EDIT: The link mysteriously died. There don't seem to be too many copies of this doc floating on the web for some reason. Minds more paranoid than I may speculate&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The rest, as they say, is history. There is just one thing I'd like to know: Who WAS AARD?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114604702043954697?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114604702043954697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114604702043954697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114604702043954697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114604702043954697'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/04/microsoft.html' title='Microsoft'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114430605052775399</id><published>2006-04-06T07:44:00.000+01:00</published><updated>2006-04-06T07:49:23.723+01:00</updated><title type='text'>Frame zero is a mythical creature.</title><content type='html'>I've decided that the entire last post was a result of semantic confusion. Keyframes and frames are different things; a frame is a measure of elapsed time, and a keyframe is a sample of animation at an instant in time, so it makes perfect sense to say an animation with four sampled keyframes actually has three frames; because frames are just seconds in disguise, just another way of expressing the elapsed time. The trick is to keep t accurate and all you have left is interpolation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114430605052775399?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114430605052775399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114430605052775399' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114430605052775399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114430605052775399'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/04/frame-zero-is-mythical-creature.html' title='Frame zero is a mythical creature.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114424834523060179</id><published>2006-04-05T15:44:00.000+01:00</published><updated>2006-04-05T15:46:33.680+01:00</updated><title type='text'>Frame zero. It drives me nuts.</title><content type='html'>What am I talking about? Well, for the sake of argument, lets suppose I have a 4 - frame, keyframed animation, with the simulation and the renderer stepped at 1/30sec per frame. The artist sees 4 frames in Maya/Max/Blender/WhizzosAtomicModeller&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;t&lt;br /&gt;+-----------+-----------+-----------+------------+&lt;br /&gt;|           |           |           |            |&lt;br /&gt;+-----------+-----------+-----------+------------+&lt;br /&gt;0           1           2           3            4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To play a complete animation, we have to render at 5 intervals, starting with t=0 and ending with t=4. Great, so thats what you do, after all, the artists want to see *all* of their lovely animation, right?&lt;br /&gt;&lt;br /&gt;So along comes someone else, actually observing the behavior of the animation and says "hey, our x frame animation is playing over x+1 frames", and the guy/thing/car is overshooting their turn/cutscene spot/fov&lt;br /&gt;&lt;br /&gt;At this point a number of things can happen.&lt;br /&gt;&lt;br /&gt;1&gt; We rejig the logic/calling order so that animation_update() always gets called before animation_render() and we never see the t=0 frame. Everything seems right. There's no "unstated state", the animation is always playing - that has to be right, no? Er..as along as none of the more bright artists realize and get upset (rightly) that they are losing a frame of their lovingly hand-crafted animation every time.&lt;br /&gt;&lt;br /&gt;2&gt; We add one to the number of frames of animation every time the AI asks what the frame count is going to be. Velocities, etc get scaled accordingly. This can annoy AI people, if things take a frame longer than they think they will, especially when doing things like cornering. The API/Interface has to be bulletproof.&lt;br /&gt;&lt;br /&gt;3&gt; The opposite of 1&gt;. Have every animation signal its desire to terminate a frame before the end and never play t=4 except either to hold a pose, or blended in with another animation that is transitioning in.&lt;br /&gt;&lt;br /&gt;I've worked in shops that have used each. My personal preference is probably 3, but I've met people quite vehement about 1. I have never had the chutzpah to pull 2, myself, but I've seen people do it successfully.&lt;br /&gt;&lt;br /&gt;Before I write yet another animation engine (properly, this time, I always tell myself!) I'd like to sound out the opinions of the crowd. Anyone have any strong arguments pro and con for any of these three?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114424834523060179?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114424834523060179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114424834523060179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114424834523060179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114424834523060179'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/04/frame-zero-it-drives-me-nuts.html' title='Frame zero. It drives me nuts.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114392811139203349</id><published>2006-04-01T22:44:00.000+01:00</published><updated>2006-04-02T09:10:21.236+01:00</updated><title type='text'>Amazon Web Services With Lisp</title><content type='html'>&lt;p&gt;I've just had a nice day banging my head on the wall trying to figure out why I can't talk to amazon web services with &lt;a href="http://www.cliki.net/Trivial-HTTP"&gt;cl-trivial-http&lt;/a&gt;. Turns out that trivial-http doesn't actually implement HTTP to the letter. GET is supposed to send the local path and not the full URL to the server. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;When you send Amazon the local path instead of the full URL, it wants to play. Just for reference, here is my test code. Hope it helps someone...&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;;; load up requirements&lt;br /&gt;(asdf:oos 'asdf:load-op 'trivial-sockets)&lt;br /&gt;(asdf:oos 'asdf:load-op 'trivial-http)&lt;br /&gt;(asdf:oos 'asdf:load-op 's-xml)&lt;br /&gt;&lt;br /&gt;;; Define parts of the REST request.&lt;br /&gt;(defparameter *baseurl* "http://webservices.amazon.com/onca/xml")&lt;br /&gt;(defparameter *service* "AWSECommerceService")&lt;br /&gt;(defparameter *accesskeyid* "098CMPJ4AGZ7C6T1DHG2") &lt;br /&gt;(defparameter *operation* "ItemSearch")&lt;br /&gt;(defparameter *searchindex* "Books")&lt;br /&gt;(defparameter *default-response-group* "Request,Small")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defparameter *search-indexes* '( "Apparel" "Automotive"  "Baby"  "Beauty"  "Blended"  "Books"  "Classical"  "DigitalMusic"  "DVD"  "Electronics"  "ForeignBooks"  "GourmetFood"  "HealthPersonalCare"  "Hobbies"  "HomeGarden"  "Jewelry"  "Kitchen"  "Magazines"  "Merchants"  "Miscellaneous"  "Music"  "MusicalInstruments"  "MusicTracks"  "OfficeProducts"  "OutdoorLiving"  "PCHardware"  "PetSupplies"  "Photo"  "Restaurants"  "Software"  "SoftwareVideoGames"  "SportingGoods"  "Tools"  "Toys"  "VHS"  "Video"  "VideoGames"  "Wireless"  "WirelessAccessories" ) )&lt;br /&gt;&lt;br /&gt;(defparameter *response-groups* '( "Accessories" "BrowseNodeInfo" "BrowseNodes" "Cart" "CartNewReleases" "CartTopSellers" "CartSimilarities" "CustomerFull" "CustomerInfo" "CustomerLists" "CustomerReviews" "EditorialReview" "Help" "Images" "ItemAttributes" "ItemIds" "Large" "ListFull" "ListInfo" "ListItems" "ListmaniaLists" "ListMinimum" "Medium" "NewReleases" "OfferFull" "Offers" "OfferSummary" "Request" "Reviews" "SalesRank" "SearchBins" "Seller" "SellerListing" "Similarities" "Small" "Subjects" "TopSellers" "Tracks" "TransactionDetails" "VariationMinimum" "Variations" "VariationImages" "VariationSummary" ))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defun append-parameter-to-url (url name value)&lt;br /&gt;  (let ((result &lt;br /&gt;  (concatenate 'string url "&amp;" name "=" (trivial-http:escape-url-query value)))) &lt;br /&gt;    result))&lt;br /&gt;&lt;br /&gt;(defun make-amazon-item-search-url (search-index &amp;key keywords power title author item-page (response-group *default-response-group*))&lt;br /&gt;  (if (not (member search-index *search-indexes* :test #'string=))&lt;br /&gt;      (error "~A is not a valid search index" search-index)&lt;br /&gt;      (let ((result &lt;br /&gt;      (concatenate 'string &lt;br /&gt;     *baseurl* "?Service=" *service* "&amp;AWSAccessKeyId=" *accesskeyid* &lt;br /&gt;     "&amp;Operation=ItemSearch&amp;SearchIndex="  search-index "&amp;ResponseGroup=" response-group&lt;br /&gt;     "&amp;ContentType=text%2Fxml&amp;Version=2005-03-23")))&lt;br /&gt; (if keywords &lt;br /&gt;     (setf result (append-parameter-to-url result "Keywords" keywords)))&lt;br /&gt; (if author &lt;br /&gt;     (setf result (append-parameter-to-url result "Author" author)))&lt;br /&gt; (if title  &lt;br /&gt;     (setf result (append-parameter-to-url result "Title" author)))&lt;br /&gt; (if power &lt;br /&gt;     (setf result (append-parameter-to-url result "Power" power)))&lt;br /&gt; (if item-page &lt;br /&gt;     (setf result (append-parameter-to-url result "ItemPage" item-page))) &lt;br /&gt; result))) &lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(defun url-path (url)&lt;br /&gt;  (assert (string-equal url "http://" :end1 7))&lt;br /&gt;  (let ((path-start (or (position #\/ url :start 7) (length url))))&lt;br /&gt;    (subseq url path-start (length url))))&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;(defun amazon-http-get (url)&lt;br /&gt;  (let* ((host (thttp::url-host url))&lt;br /&gt;         (port (thttp::url-port url))&lt;br /&gt;         (stream (trivial-sockets:open-stream host port)))&lt;br /&gt;    (format stream "GET ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~A~A"&lt;br /&gt;     (url-path url) thttp::+crlf+ host thttp::+crlf+ thttp::+crlf+ thttp::+crlf+)&lt;br /&gt;    (force-output stream)&lt;br /&gt;    (list&lt;br /&gt;     (thttp::response-read-code stream)&lt;br /&gt;     (thttp::response-read-headers stream)&lt;br /&gt;     stream)))&lt;br /&gt;&lt;br /&gt;(defun test-amazon ()&lt;br /&gt;  (destructuring-bind (response headers http-stream)&lt;br /&gt;      (amazon-http-get (make-amazon-item-search-url "Books" :keywords "Lisp" :item-page "25"))&lt;br /&gt;    (if (not (= response 200))&lt;br /&gt; (error  "response ~A  from server" response)&lt;br /&gt; (progn &lt;br /&gt;   (format t "response ~A~%" response)&lt;br /&gt;   (format t "headers ~A~%" headers)&lt;br /&gt;   (loop for line = (read-line http-stream nil nil)&lt;br /&gt;  while line do (format t "~A%" line))))))&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114392811139203349?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114392811139203349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114392811139203349' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114392811139203349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114392811139203349'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/04/amazon-web-services-with-lisp.html' title='Amazon Web Services With Lisp'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114297937129085604</id><published>2006-03-21T22:10:00.000Z</published><updated>2006-03-21T22:21:14.390Z</updated><title type='text'>SDL and curses</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/7103/28/1600/omega_sdl.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/7103/28/400/omega_sdl.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dickey.his.com/ncurses/ncurses-intro.html"&gt;Curses&lt;/a&gt; is an ancient API for doing terminal I/O. &lt;a href="http://www.libsdl.org"&gt;SDL&lt;/a&gt; is a modern graphics library, nice and platform independent for talking to framebuffers, keyboards and other devices used in games. &lt;a href="http://www.libsdl.org/projects/SDL_ttf/"&gt;SDL_ttf&lt;/a&gt; is an extra library that lets you render TTF characters on an SDL framebuffer.&lt;br /&gt;&lt;br /&gt;I've combined the three into one. I have a the beginnings of a curses-compatible library that renders to an SDL frambebuffer. It works well enough now for you to be able to play the Omega Roguelike in a window - see the screenshot. Hopefully it will become a way to rescue and make platform - independent old curses bound - apps. Expect it to hit Sourceforge in a few days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114297937129085604?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114297937129085604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114297937129085604' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114297937129085604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114297937129085604'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/03/sdl-and-curses.html' title='SDL and curses'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114241186675825605</id><published>2006-03-15T08:05:00.001Z</published><updated>2006-03-15T08:40:44.390Z</updated><title type='text'>Why my Java is lukewarm</title><content type='html'>I loved this recent post from Bill Clementsons &lt;a href="http://bc.tech.coop/blog/060304.html"&gt;blog&lt;/a&gt;. It finally made me realise why Java drives me nuts. It's simple: the observation is made that C is ideal for programming a von-Neumann machine - it's a light abstraction of it's capabilities into human readable language - flow of control keywords, and a strong set of arithmetic operators take care of the CPU and ALU. It interfaces well with the host O/S because the host O/S is itself written in C, and it just treats memory as a huge flat, address space. Indirection is achieved via function pointers, so we can treat functions as first-class objects, sort of.&lt;br /&gt;&lt;br /&gt;Lisp is at the other end, it's deeply emmeshed in the Lambda calculus wich appears to be an elegant model of computation - don't quote me on that, though, I'm only just beginning to learn this. However, the upshot is that it has powers of abstraction that leave other languages panting.&lt;br /&gt;&lt;br /&gt;And Java. Well, Java. Java seems to be all about the notion of the object; at it's root, the absract data type. We lose the ease of interaction with the von-Neumann architecture that we gain with C, in return for this object abstraction and a huge class library. It almost pulls it off. Guy Steele called it "halfway to Lisp" but I think that was being generous. It's more like a third of the way to Lisp, given the lack of flexibility in constructing abstractions. Generics might even the balance a bit, I'm not yet sure: however, as they are not a compile - time construct, I doubt it.&lt;br /&gt;&lt;br /&gt;Sometimes it's good to be freed from the von-Neumann architecture: but I'm not convinced that the object abstraction, on its own is enough. Interfaces are a poor substitute for first class functions and closures. It must be said that a disciplined programmer can do the bookkeeping needed by C without thinking, too much. All pointers need to be set to NULL in debug after being free'd(). Pointers that are going to point to something dynamically allocated must be initalised to NULL: usually this is enclosed in a suitable macro. There are perfectly good tools like&lt;a href="http://valgrind.org/"&gt;Valgrind&lt;/a&gt; and &lt;a href="http://www.compuware.com/products/devpartner/"&gt;Dev-Partner&lt;/a&gt; for tracking memory usage. Modern architectures make the dangling pointer/memory issue a thing of the past. If the tools availble are properly used.&lt;br /&gt;&lt;br /&gt;I find Java excels where objects excel: constructing models of real-world processes where objects map nicely to concrete entities: GUI's are a good example. When you are dealing with a more amorphous problem, Java is suicide. There is a reason why the OO 101 courses always tend to show students GUI code as an example, or simple simulations. Those are the problems that classically, objects were designed to solve, and they solve them well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In short, Java reminds me of Pascal; a language with training wheels that give you just enough power to write a decent program, but not enough to give you the rope to tie yourself in knots. In some environments, this would be an excellent thing, but I've been ruined forever by Lisp. Java will always be my fourth choice, after Lisp, C++ and C.&lt;br /&gt;&lt;br /&gt;I know what I'm missing. Sniff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114241186675825605?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114241186675825605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114241186675825605' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114241186675825605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114241186675825605'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/03/why-my-java-is-lukewarm_15.html' title='Why my Java is lukewarm'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114222087145974439</id><published>2006-03-13T03:28:00.000Z</published><updated>2006-03-13T03:34:31.470Z</updated><title type='text'>Microsoft Out - Surreals Dali</title><content type='html'>I've just been coding a small C++ Windows Forms app in Visual Studio Express .NET. It was the most surreal experience I've had for some time, let me tell you! Firstly, VSE 2005 emulates emacs, secondly C++ was my choice of language for coding a .NET app.&lt;br /&gt;&lt;br /&gt;Editing using Emacs keystrokes in such a familiar environment, using a language that was almost, but not really C++ gave me a situation where I was seeing old habits and patterns appear in completely unfamiliar places. Every 5 mins I just had to pause and let the "&lt;span style="font-style: italic;"&gt;what the hell?" &lt;/span&gt;feeling wash over me.&lt;br /&gt;&lt;br /&gt;Still, I did get that app coded eventually, and it *was* easier than MFC.  It only took Redmond eight (or was it 12?) years to improve on that..although to be fair, comparing the result of this exercise to a MFC 1.0 app is like comparing a light saber to a rusty tin-opener.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114222087145974439?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114222087145974439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114222087145974439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114222087145974439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114222087145974439'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/03/microsoft-out-surreals-dali.html' title='Microsoft Out - Surreals Dali'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114219436934799498</id><published>2006-03-12T20:10:00.000Z</published><updated>2006-03-12T20:12:49.356Z</updated><title type='text'>Quietness</title><content type='html'>Yes, it's been quiet, here recently, but that's because I have been actually, you know, coding. Mostly I've been concentrating on the simple but useful: a mud client in Common Lisp that's stood as a good introduction to Common Lisp streams, and have been once more attempthing to rescue a few long abandoned but fairly amusing roguelike games by writing a version of curses that targets an SDL window. Nearly there. Just one more horrible implementation detail to work out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114219436934799498?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114219436934799498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114219436934799498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114219436934799498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114219436934799498'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/03/quietness.html' title='Quietness'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114106335840818278</id><published>2006-02-27T17:36:00.000Z</published><updated>2006-02-27T18:11:14.173Z</updated><title type='text'>Genetic Programming</title><content type='html'>&lt;a href="http://www.genetic-programming.com/johnkoza.html"&gt;John Koza&lt;/a&gt;formalized the use of LISP S-Expressions as the representation of Choice for Genetic Programming. Lisp S-expressions map directly onto a parse tree, which can be manipulated via the usual methods of tree modification. Functions that accept zero arguments or constants (quoted or otherwise are terminals) and other functions are non-terminals.&lt;br /&gt;&lt;br /&gt;The standard GP algorithm takes five inputs.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;a set of terminal functions, T&lt;/li&gt;&lt;li&gt;a set of non-terminal functions, NT&lt;/li&gt;&lt;li&gt;a set of control parameters P&lt;/li&gt;&lt;li&gt;a fitness funtion, f(x)&lt;/li&gt;&lt;li&gt;a termination criterion t&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Contained in the set of control parameters are &lt;/p&gt;&lt;ul&gt;&lt;li&gt;n - the initial number of S-expressions&lt;/li&gt;&lt;li&gt;Di - the initial maximum depth of nesting of an S-Expression&lt;/li&gt;&lt;li&gt;Pr - probability of reproduction of a fit individual&lt;/li&gt;&lt;li&gt;Pc - probablility of recombination of a fit individual&lt;/li&gt;&lt;li&gt;Pm - probabiliy of mutation of a fit indivudual&lt;/li&gt;&lt;li&gt;Dc - maximum depth of nesting of an S-Expression during a run&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The standard algorithm runs a follows&lt;/p&gt;&lt;ol&gt;&lt;li&gt;(setf *generation-count* 0)&lt;/li&gt;&lt;li&gt;(setf *current-population* (random-experssions :count n :nesting Di :terminals T :non-terminals TF))&lt;/li&gt;&lt;li&gt;(set *current-fitness* (loop for individial in *current-population* collect (fitness individual))&lt;/li&gt;&lt;li&gt;Filter the current population by fitness, producing a new individual by a randomly chosen method.&lt;/li&gt;&lt;li&gt;(setf *current-population* *new-population*)&lt;/li&gt;&lt;li&gt;(until t)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Fitness is usually measured by standardzed fitness where the fittest indvidiual has a fitness of zero. Reproduction is a asexual copy, mutation is asxual copying with reandom errors, and crosover is splicing together two infvidials from one half of each individial, the splice point being arbitarily chosen. It is important that the union of T and NT (called C) is sufficent to solve the target problem, and that all the functions accept and return arguments of the same type. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114106335840818278?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114106335840818278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114106335840818278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114106335840818278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114106335840818278'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/02/genetic-programming.html' title='Genetic Programming'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114077108815049087</id><published>2006-02-24T08:49:00.000Z</published><updated>2006-02-24T08:51:28.160Z</updated><title type='text'>Intresting Lisp Factoid of the Day</title><content type='html'>&lt;p&gt;You can put docstrings in Lambda expressions. Whee, just what I always wanted!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;((lambda (x) "This is documented" (format t "~A" x)) &lt;br /&gt;1&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114077108815049087?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114077108815049087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114077108815049087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114077108815049087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114077108815049087'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/02/intresting-lisp-factoid-of-day.html' title='Intresting Lisp Factoid of the Day'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-114053469325139166</id><published>2006-02-21T15:09:00.000Z</published><updated>2006-02-21T15:11:33.263Z</updated><title type='text'>More on Cooperatives</title><content type='html'>&lt;p&gt;Of course, my recent ramblings on co-operatives only echo a train of thought someone , somewhere else has had and put into action: take a look at the &lt;a href="http://www.selectparks.net/"&gt;SelectParks&lt;/a&gt; co-operative. At least I know I'm not going crazy, now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-114053469325139166?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/114053469325139166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=114053469325139166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114053469325139166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/114053469325139166'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/02/more-on-cooperatives.html' title='More on Cooperatives'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113915970615668155</id><published>2006-02-05T17:01:00.000Z</published><updated>2006-02-05T17:49:15.023Z</updated><title type='text'>More Lisp on Gentoo</title><content type='html'>&lt;p&gt;The sbcl-cvs ebuild turned out to be a good example of the pitfalls awaiting the CVS ebuilder. Recently the contrib/systems directory was removed from sbcl cvs as Win32 doesn't do symlinks. Unfortunately, the plain-vanilla Gentoo asdf ebuild still wanted them, so when you loaded up Slime it complained it couldn't find SB-BSD-SOCKETS.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The solution was to create the symlinks as part of the ebuild. Slime now works with it..Here's the new &lt;a href="http://www.yagc.ndo.co.uk/code/sbcl-cvs.tar.bz2"&gt;ebuild&lt;/a&gt;. It needs to live in /usr/local/portage/dev-lisp and you need PORTDIR_OVERLAY="/usr/local/portage" in your make.conf.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Edit: perhaps I should also warn you that this ebuild uses cmucl to compile sbcl and will pull that in, too.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113915970615668155?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113915970615668155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113915970615668155' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113915970615668155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113915970615668155'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/02/more-lisp-on-gentoo.html' title='More Lisp on Gentoo'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113886647013666248</id><published>2006-02-02T07:04:00.000Z</published><updated>2006-02-02T08:03:06.590Z</updated><title type='text'>Lisp on Gentoo</title><content type='html'>One thing about Lisp is that releases of packages tend to be infrequent: for instance Gentoo's cl-mcclim is ancient, and doesn't compile with the *unmasked* sbcl (.94) in portage. Advice on #lisp is that many asdf packages should be pulled from CVS rather than messing about with distro packages. One nice thing about Gentoo is that you can write ebuild scripts that pull distro packages straight from CVS, so I'm going to write a few ebuilds for myself and publish them here to save a few people time. First off is the SBCL CVS &lt;a href="http://www.yagc.ndo.co.uk/code/sbcl-cvs.tar.gz"&gt;ebuild&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113886647013666248?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113886647013666248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113886647013666248' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113886647013666248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113886647013666248'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/02/lisp-on-gentoo.html' title='Lisp on Gentoo'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113835276272096092</id><published>2006-01-27T08:40:00.000Z</published><updated>2006-01-27T09:06:03.440Z</updated><title type='text'>The Independent Game Developers Co-operative</title><content type='html'>Many developers are fond of excorciating the current state of the games industry, bemoaning how broken the current publisher - developer model is, and are looking for a more sane alternative that concentrates on the quality of the games themselves. At least three times in my career I've experienced the tension between the need for a publically owned company to maximise profit for its shareholders and the desire of game developers just to keep working on a game, until it reaches the quality threshold they are comfortable with putting their name to. Realistically, there is no way that this is going to get resolved in favour of the developers. I've accepted that as part of working in the industry; if you need the results for this quarter, you need the results for this quarter and that's how it is.&lt;br /&gt;&lt;br /&gt;However, there *is* a positive alternative if there are enough people brave enough, out there. A co-operative. The whole essence of a co-operative is the opposite of a company. Members own shares, and the co-operative exists to provide services or goods to the members in the most effective possible way. For an up-to date example, see the &lt;a href="http://tech.coop/index"&gt;Tech Co-op&lt;/a&gt; in Canada.&lt;br /&gt;&lt;br /&gt;Off the top of my head, this is how I see it working:&lt;br /&gt;&lt;br /&gt;I'd envisage a game developers co-op working as two-coperatives: first there would be a gamers service co-op and secondly there would be a smaller game developers workers co-op, the membership of the first driving the second. The reaons for this are that the membership of the gamers co-op would be open to anyone on the internet. Membership would get you regular mailed game CD's for at least a year, then these would be provided thereafter for a small subscription fee. The gamer as a member of the co-operative would be able to pitch ideas and designs to the developers-cooperative, get technical support, game server hosting, and other services to be identified.&lt;br /&gt;&lt;br /&gt;The game developers co-operative would provide or sell services to the gamers co-op at a preferential rate, but would also engage in marketing and distribution efforts on behalf of it's members. This would enable an otherwise less affluent group of developers to talk directly to publishers and get access to platforms it would otherwise not have access to. Revenue would be ploughed back into the memebers projects.&lt;br /&gt;&lt;br /&gt;These are only tentative back of the envelope thoughts; the main point is that with the reach of the internet, a co-operative has the potential be a much larger, more effective organisation than before. The inherent problems with such a proposal - no one reaching any agreement - have to be dealt with by careful sturcturing of the co-operative.&lt;br /&gt;&lt;br /&gt;It's time for me to do more research..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113835276272096092?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113835276272096092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113835276272096092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113835276272096092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113835276272096092'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/01/independent-game-developers-co.html' title='The Independent Game Developers Co-operative'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113673070833576219</id><published>2006-01-08T14:22:00.000Z</published><updated>2006-01-08T14:32:04.710Z</updated><title type='text'>Oracle XE on Gentoo</title><content type='html'>&lt;p&gt;Installing Oracle Express Edition on Gentoo Linux was both easy and hard. It's the usual case of synthesising bits and peices off the web: the system tweaking you have to do pre-install is well documented &lt;a href="http://gentoo-wiki.com/HOWTO_Install_Oracle_10g"&gt;here&lt;/a&gt;; then you need a &lt;a href="http://gentoo-wiki.com/HOWTO_Installing_3rd_Party_Ebuilds"&gt;portage overlay&lt;/a&gt;, as documented here, and then you can use &lt;a href=http://forums.gentoo.org/viewtopic-t-397836-start-0-postdays-0-postorder-asc-highlight-oracle.html&gt;the ebuild from this thread&lt;/a&gt; to install it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Once it's up and running getting emacs to talk to it is a peice of cake. You need to customise the oracle-sql program to point to the installed sqlplus binary, and you need to source oracle_env.sh from the config directory..then launch emacs and connect.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It took some work, but it's *much* better than using a bare sql plus instance and notepad in Windows. I can develop my SQL in a similar style to my Lisp, sending fragments to a running instance via C-c C-r, which is the absolute minimum I am coming to expect of any language.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113673070833576219?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113673070833576219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113673070833576219' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113673070833576219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113673070833576219'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2006/01/oracle-xe-on-gentoo.html' title='Oracle XE on Gentoo'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113491002125799850</id><published>2005-12-18T12:41:00.000Z</published><updated>2005-12-18T12:47:01.260Z</updated><title type='text'>Lets try plugging this into this...</title><content type='html'>My last two assignments (Java, Web coding) were very straightforward and boring, so I've decided to make my life interesting by using a combination of &lt;a href="http://www.oracle.com/technology/products/database/xe/index.html"&gt;Oracle 10g Express&lt;/a&gt;, &lt;a href="http://clsql.b9.com/"&gt;CLSQL&lt;/a&gt;, and &lt;a href="http://clsql.b9.com/"&gt;Gentoo Linux&lt;/a&gt; for my database assignment. Neither officially supports any of the others, but they &lt;a href="http://www.dbazine.com/blogs/blog-cf/chrisfoot/oracleonlinux"&gt;should&lt;/a&gt; fit together. Let's see...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113491002125799850?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113491002125799850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113491002125799850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113491002125799850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113491002125799850'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/12/lets-try-plugging-this-into-this.html' title='Lets try plugging this into this...'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113490970356898160</id><published>2005-12-18T12:38:00.000Z</published><updated>2005-12-18T12:41:43.580Z</updated><title type='text'>Lisp software renderer</title><content type='html'>My pet Lisp project has been languishing on my laptop recently; I've had a fiddle with the Linux Framebuffer Device interface, and it's occured to me I might more usefully bind to that than the PTC library. Potentially it could be a non X based graphical backend to the McCLIM. Someone is already working on an Open GL backend and that code could map over quite nicely...the fonts would be some kind of awful hack, though...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113490970356898160?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113490970356898160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113490970356898160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113490970356898160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113490970356898160'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/12/lisp-software-renderer.html' title='Lisp software renderer'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113311100114950635</id><published>2005-11-27T16:58:00.000Z</published><updated>2005-11-27T17:07:25.466Z</updated><title type='text'>Bitmap Fonts, Java, Wingdings and Unicode</title><content type='html'>&lt;img width="320" height="200" alt="Bitmap Font Builder App" src="http://www.yagc.ndo.co.uk/images/bitmapfontbuilder.png"&gt;&lt;br /&gt;&lt;p&gt;After my brush with the script-fu I thought I'd go back to basics and do the bitmap font creator as a Java app. I have whipped up this app for knocking up old school bitmap fonts. The gradient fills haven't really surrvived Pay attention to the picture, as it shows at what code points to find the Wingdings glyphs in the Unicode set. It's not 0..255, as has puzzled many Java coders before!&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113311100114950635?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113311100114950635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113311100114950635' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113311100114950635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113311100114950635'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/bitmap-fonts-java-wingdings-and.html' title='Bitmap Fonts, Java, Wingdings and Unicode'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113224147957510976</id><published>2005-11-17T15:14:00.000Z</published><updated>2005-11-17T15:31:43.406Z</updated><title type='text'>Bitmap fonts and the script-fu.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.yagc.ndo.co.uk/images/neon_font.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px;" src="http://www.yagc.ndo.co.uk/images/neon_font.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Despite my rant against script-fu, it must be acknowlgeded it's highly useful for getting game art knocked out in double quick time for example, bitmap fonts. &lt;a href="http://www.yagc.ndo.co.uk/code/neon-logo.scm.html"&gt;Here's&lt;/a&gt; a script that can knock one up in a jiffy - it's just a sligtly modified version of a standard script. I'm somewhat dismayed by the size of the .png file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113224147957510976?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113224147957510976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113224147957510976' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113224147957510976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113224147957510976'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/bitmap-fonts-and-script-fu.html' title='Bitmap fonts and the script-fu.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113213716186905667</id><published>2005-11-16T10:21:00.000Z</published><updated>2005-11-16T10:32:41.880Z</updated><title type='text'>Script-fu</title><content type='html'>&lt;p&gt;Today I delved into the realm of &lt;a href="www.gimp.org"&gt;Gimp&lt;/a&gt;, SIOD, &lt;a href="http://www.xcf.berkeley.edu/~gimp/script-fu/script-fu.html"&gt;Script-fu&lt;/a&gt;; and let me tell you it's the least productive environment I've hit since the ZX81. I mean &lt;span style="font-weight:bold;"&gt;(set! variable value)&lt;/span&gt; is your assignment operator, so like a good lisp monkey I try &lt;span style="font-weight:bold;"&gt;(set! (aref string 1) "A")&lt;/span&gt;. Does that work? No. You use something called &lt;span style="font-weight:bold;"&gt;(aset string 1 65)&lt;/span&gt; why doesn't it have a bang, eh? &lt;/p&gt;&lt;br /&gt;&lt;p&gt;So, I want to create an array. Now I created a list with &lt;span style="font-weight:bold;"&gt;make-list&lt;/span&gt;, so, of course, I want to use &lt;span style="font-weight:bold;"&gt;make-array&lt;/span&gt;. No? Gotcha again! It's &lt;span style="font-weight:bold;"&gt;cons-array&lt;/span&gt;. Arrgh!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Add that to the fact that pressing the escape key closes the script-fu console window; which is something I do quite a lot, as it's hardwired into me that Escape means &amp;quot;clear the input&amp;quot; and that the &lt;a href="http://www.cs.indiana.edu/scheme-repository/imp/siod.html#builtin"&gt;documentation &lt;/a&gt; is just a scrappy list of functions that makes it hard to find what you need, that's a recipie for a very frustrating morning. The tragedy is that this is going to be some peoples first exposure to a lisp-like language..it could be so much better; the scintilla component could have been embedded in, there could be a much better tutorial and reference; but I guess someone would have to be paid for that..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113213716186905667?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113213716186905667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113213716186905667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113213716186905667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113213716186905667'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/script-fu.html' title='Script-fu'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113196172624556509</id><published>2005-11-14T09:46:00.000Z</published><updated>2005-11-14T09:48:46.256Z</updated><title type='text'>Sony are in so much trouble..</title><content type='html'>&lt;p&gt;This story just runs and runs. Not only do Sony release a rootkit that installs itself onto Windows PC's without telling people, and get discovered, it turns out that the rootkit is a &lt;a href="http://dewinter.com/modules.php?name=News&amp;file=article&amp;sid=215"&gt;GPL violation&lt;/a&gt;! This one is going to run and run...are Sony trying to replace Microsoft as the Evil Empire? They seem to be taking a pretty good shot at it!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113196172624556509?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113196172624556509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113196172624556509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113196172624556509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113196172624556509'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/sony-are-in-so-much-trouble.html' title='Sony are in &lt;b&gt;&lt;i&gt;so&lt;/i&gt;&lt;/b&gt; much trouble..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113139439644603423</id><published>2005-11-07T20:07:00.000Z</published><updated>2005-11-07T20:13:16.460Z</updated><title type='text'>Package du Jour: Dia</title><content type='html'>&lt;p&gt;I've been playing with &lt;a href="http://www.gnome.org/projects/dia/"&gt;Dia&lt;/a&gt; and been moderately impressed with what I've found. I've been using it as part of my course; being able to export to .pngs is good. It's happy with a wide range of diagrams: mostly I am using it for entity relationship diagrams and UML. There's even a &lt;a href="http://dia2code.sourceforge.net/"&gt;uml to code&lt;/a&gt; generator for it which I intend to try using for my Java assignment. While I can't say it's as good as Visio (when did &lt;i&gt;that&lt;/i&gt; become part of Microsoft Office), it's a cheap way for students to explore UML and &amp;quot;good enough&amp;quot; for most small projects, and it has an interesting quirky diagram set: isometric game tiles - houses, railways, fields - which can be used to layout a small toy town. It might even be a game prototyping tool one day; with the right tileset..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113139439644603423?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113139439644603423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113139439644603423' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113139439644603423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113139439644603423'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/package-du-jour-dia.html' title='Package du Jour: Dia'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-113135533730983125</id><published>2005-11-07T08:55:00.000Z</published><updated>2005-11-07T09:22:17.380Z</updated><title type='text'>Change of Direction</title><content type='html'>&lt;p&gt;It might seem strange to some people that I have recently left &lt;a href ="http://en.wikipedia.org/wiki/Reflections_Interactive"&gt;Reflections&lt;/a&gt; and decided to enroll on a &lt;a href="http://online.northumbria.ac.uk/prospectus/coursedetail.asp?CourseID=255"&gt;Masters&lt;/a&gt; degree course; it's a strange thing to do at 38 years of age. Even stranger, the Masters course is not strictly games-oriented. Well it's not as big a jump into the unknown as it looks: many of the new mobile platforms use Java, databases are increasingly important - both as repositories for the huge number of assets used in game development, and for the backend of MMPORG's as well as their more humble play-by-web cousins.&lt;/p&gt; &lt;br /&gt;&lt;p&gt;The web itself is probably the most interesting platform around today: it's a mass medium based on a mishmash of standards and technologies that can be bent to do almost everything; a giant laboratory free from the restrictions of proprietary console platform development. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;I'm beginning to suspect a much better (as in scalable, among other things) platform for games development can be assembled out of some of the emergent technologies available now; a distributed, social system capable of handling vast amounts of assets, and large numbers of distributed collaborators. It's my intention to try and assemble a platform capable of this, and offer it as a model for further research.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;It's also my intention to learn as much as possible in a short time whithout my brain exploding; as this is the most challenging course my local university has to offer, that might be hard. Still, onwards...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-113135533730983125?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/113135533730983125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=113135533730983125' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113135533730983125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/113135533730983125'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/11/change-of-direction.html' title='Change of Direction'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-112921066471861739</id><published>2005-10-13T14:29:00.000+01:00</published><updated>2005-10-13T14:37:44.726+01:00</updated><title type='text'>More newbie thoughts on Lisp</title><content type='html'>It's become obvious with the code I've been writing recently that Lisp's strength and weaknesses are all tied to it's lack of syntax. The fact it has very little in the way of syntax leads to a combinatorial explosion - there are an almost infinite number of ways to do simple things: it makes me wonder if the whole purpose of strong syntax in languages isn't simply to prevent this, and guide the energies of programmers into productive channels. It certainly was the case in C and Fortran where syntax was carefully constructed to enable mapping high level language to machine instructions a straightforward transformation.&lt;br /&gt;&lt;br /&gt;However the lack of syntax has to be an achilles heel: the huge number of idioms that could be applied to simple programs means no two coders are going to write anything neccesarily similar. I'm assming the full set of coders of all levels of competence here. I expect a smaller set of seasoned coders would converge on similar solutions given similar problems. Which makes it a devastating weapon in the hands of a sesoned coder, but probably in a team of mixed abilities it would lead to much higher communication oveheads.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-112921066471861739?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/112921066471861739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=112921066471861739' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112921066471861739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112921066471861739'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/10/more-newbie-thoughts-on-lisp.html' title='More newbie thoughts on Lisp'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-112860767145549226</id><published>2005-10-06T15:01:00.000+01:00</published><updated>2005-10-06T15:07:51.460+01:00</updated><title type='text'>Project Madness</title><content type='html'>&lt;p&gt;I simply have to back off, I'm trying to do too many bloody things at once.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here's my long list&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;Get deeply enought into web/database tech to get a small play-by-web game running.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Update the Omega rougelike game for the SDL &amp; modern multiplatform code.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Update Blah, a roguelike skeleton that fell off the net many moons ago, with SDL graphics and Lua scripting.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Finish the LISP software renderer.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Create a tool for parsing C into sexp's with an eye to auto-generating UFFI or CFFI bindings.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Some unspecified Java app, just to keep my hand in : possibly a Blogger to Live-Journal migration tool.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Some more games that have been bubbling under the radar for what seems like years.&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;Lunch with Laura - a graphic novel. Nothing to do with coding, but it competes for time.&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Clearly, something has to give, somewhere..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-112860767145549226?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/112860767145549226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=112860767145549226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112860767145549226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112860767145549226'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/10/project-madness.html' title='Project Madness'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-112619557265138164</id><published>2005-09-08T16:59:00.000+01:00</published><updated>2005-09-08T17:06:12.656+01:00</updated><title type='text'>XEmacs Wins</title><content type='html'>&lt;p&gt;Mostly because you can configure it seven hundred ways to Sunday, and after lots of fiddling I arrived at an &lt;a href="http://www.yagc.ndo.co.uk/code/init.el.html"&gt;init.el&lt;/a&gt; I kind of liked. It has room for improvement. It probably shouldn't rely on &lt;a href="http://cscope.sourceforge.net"&gt;cscope&lt;/a&gt; for tagging, becasue that's platform specific. It probably should fall back on plain old tags. Onwards to do some actual coding then: programmers are the only people who can get so preoccupied with sharpening an axe they forget about the damn tree.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-112619557265138164?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/112619557265138164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=112619557265138164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112619557265138164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112619557265138164'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/09/xemacs-wins.html' title='XEmacs Wins'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-112609029981968845</id><published>2005-09-07T11:23:00.000+01:00</published><updated>2005-09-07T11:51:39.826+01:00</updated><title type='text'>Grand Text Editor</title><content type='html'>&lt;p&gt;I find myself prevaricating between editors. I know I have to pick one and stick to it, but I can't make up my mind which. I've narrowed it down to a few promising candidates, all cross-platform.&lt;p&gt;&lt;br /&gt;&lt;li&gt;Emacs.&lt;/li&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.xemacs.org"&gt;XEmacs&lt;/a&gt; is pretty much *the* editor if I want to code in Lisp, as it has &lt;a href="http://common-lisp.net/project/slime/"&gt;Slime&lt;/a&gt;, one of the most interactive and potentially productive programming environments I've ever seen. The &lt;a href="http://ecb.sourceforge.net/"&gt;Emacs Code Browser&lt;/a&gt; gives me IDE-like organisation and navigation. It integrates nicely with gdb and the shell. The con side is that the tagging is poor, and requiring more than three keystrokes to do anything useful makes it difficult and &amp;quot;slow;&amp;quot feeling to work with. It's so configurable it's difficult to zero in on a single working style with it. The learning curve seems endless.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Gvim.&lt;/li&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.vim.org"&gt;Vi - Improved&lt;/a&gt;. Another editing heavyweight, and the keystrokes are both brief and seared into my brain as I've been exposed to it on and off throughout my career. Frankly, if it wasn't for the amount of Lisp I do, it'd be my editor of choice. It doesn't have anything like ECB - but it does have &lt;a href="http://www.vim.org/tips/tip.php?tip_id=450"&gt;sessions&lt;/a&gt; - a collection of settings that can be quickly saved and restarted. Which is fine for keeping track of different projects. It also as a huge collection of scripts and customisations, like Emacs..The keyword completion is wicked, but it's not context sensitive like Intellisence.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;JEdit.&lt;/li&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://www.jedit.org"&gt;JEdit&lt;/a&gt; is another contender. It handles sessions and tags pretty much as well as Vi and XEmacs do. It's set of plugins are not as comprehensive as vim or XEmacs, but there's enough for the job. It's main benefit is a more modern gui and a slicker feel. Comfort is an important factor. The plugins are very Java-centric, and I suspect this editor would be a powerhouse for a Java coder, but I'm not so sure about how it would pan out for a C++/Lisp coder.&lt;/p&gt;&lt;br /&gt;&lt;li&gt;Visual Slick Edit.&lt;/li&gt;&lt;br /&gt;&lt;p&gt;The only &lt;a href="http://www.slickedit.com/"&gt;commercial&lt;/a&gt; editor of the bunch, and the slickest. It intelligently does completion of structure and class members, parameter lists, and does incremental tagging in the background: as a result I'm more productive when coding in C/C++ with this editor. It gave me a real competitive advantage over my Visual Studio bound colleagues back in the days of Visual Studio 6. Although they have since caguht up. It can handle Python and there is a script for Lisp support on the website, which I haven't tried.Lack of Lisp is a major minus, otherwise this would ne a no-brainer. Although, perhaps I could use this in conjunction with the &lt;a href="http://www.lispworks.com/products/ide.html"&gt;LispWorks IDE&lt;/a&gt;.&lt;br /&gt;&lt;p&gt;So which one do I pick? They all have something I want, and they all miss something else. Can anyone spot anything I've missed? Some plugin or mode that would give one an advantage over the other? Shorter XEmacs keystrokes? Intellisense for vim or JEdit? A good Lisp mode for Visual Slick Edit?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-112609029981968845?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/112609029981968845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=112609029981968845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112609029981968845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112609029981968845'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/09/grand-text-editor.html' title='Grand Text Editor'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-112594810688444450</id><published>2005-09-05T20:21:00.000+01:00</published><updated>2005-09-05T20:25:55.683+01:00</updated><title type='text'>Goodbye Slackware</title><content type='html'>&lt;p&gt;One of the first things I've done with my newfound freedom since leaving Reflections is to review all my Linux installs. For a long time I've been soldiering on with the redoubtable Slackware. However, I resolved to give Debian a try, and frankly I'm amazed by what I've seen. Compared to Slackware install was fast, friendly and trouble-free: network, video, and sound were all auto-detected, and the graphical login came up first time. &lt;/p&gt;&lt;p&gt;&lt;br /&gt;Gnome is gorgeous, too, all point and click and "just works". Even this post came straight from the desktop blogging tool, rather than via Firefox.&lt;/p&gt; &lt;p&gt; Every time I revisit a mainstream distro, I'm amazed by the progress. Frankly, if something like this came pre-installed, damn few people would touch a Windows PC. Mind you, Steve Jobs has probably recently come to the same conclusion, so there maybe hope, yet...meanwhile, it's back to my Lisp rendering follies, I guess.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-112594810688444450?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/112594810688444450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=112594810688444450' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112594810688444450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/112594810688444450'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/09/goodbye-slackware.html' title='Goodbye Slackware'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111908984251605620</id><published>2005-06-18T10:40:00.000+01:00</published><updated>2005-06-18T11:35:17.613+01:00</updated><title type='text'>Lisp, the language that does your coding for you..</title><content type='html'>&lt;p&gt;Well, not quite - but almost. After reading &lt;a href="http://www.ptarmigangames.com/malcontent/"&gt;Rogue Malcontents&lt;/a&gt; nifty &lt;a href="http://www.ptarmigangames.com/malcontent/archives/26"&gt;post&lt;/a&gt; where he uses macros to wrap simple-arrays with structure - like syntax (very handy for interacting with APIs like OpenGL), I went back and looked at my code with a fresh eye. I found I was writing lots of forms like this :-&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;(red (get-red p0) (funcall red-interpolator))&lt;br /&gt;(blue (get-blue p0) (funcall blue-interpolator))&lt;br /&gt;(green (get-green p0) (funcall green-interpolator))&lt;br /&gt;(alpha (get-alpha p0) (funcall alpha-interpolator))&lt;/blockquote&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;..where the same form was wrapped around each colour channel of a pixel. So I thought "Hmm, time for a macro". My first attempt was something like this:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;(defmacro with-pixel-colour-list (body)&lt;br /&gt;  (list &lt;br /&gt;     `list &lt;br /&gt;   (replace-symbol 'get-pixel 'get-red body)&lt;br /&gt;   (replace-symbol 'get-pixel 'get-blue body)&lt;br /&gt;   (replace-symbol 'get-pixel 'get-green body)&lt;br /&gt;   (replace-symbol 'get-pixel 'get-alpha body)))&lt;/blockquote&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Where replace-symbol was a utility function of my own devising which car'd its way through a form, replacing a matching symbol as it went - given here for completeness. So the form fed to with-pixel-colour list gets replicated four times - the first time with the get-pixel call replaced with a get-red call, the second time get-pixel replaced by a get-green call, and so forth. So I only have to write one form once, rathte than four times, and the compiler does the rest of the work for me, macro-expanding the code before compiling it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;(eval-when (:compile-toplevel :load-toplevel :execute)&lt;br /&gt;  (defun replace-symbol (sym1 sym2 list)&lt;br /&gt; (cond &lt;br /&gt;   ((null list)&lt;br /&gt;    nil)&lt;br /&gt;   ((null (car list))&lt;br /&gt;    (replace-symbol sym1 sym2 (cdr list)))&lt;br /&gt;   ((symbolp (car list)) &lt;br /&gt;    (if (string= (symbol-name sym1) (symbol-name (car list)))&lt;br /&gt;     (cons sym2 (replace-symbol sym1 sym2 (cdr list)))&lt;br /&gt;     (cons (car list) (replace-symbol sym1 sym2 (cdr list)))))&lt;br /&gt;   ((listp (car list))&lt;br /&gt;    (cons (replace-symbol sym1 sym2 (car list))&lt;br /&gt;    (replace-symbol sym1 sym2 (cdr list))))&lt;br /&gt;   (t (cons&lt;br /&gt;    (car list)&lt;br /&gt;    (replace-symbol sym1 sym2 (cdr list)))))))&lt;/blockquote&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So, (with-pixel-colours *my-pixel*) expands nicely to (LIST (GET-RED *MY-PIXEL*) (GET-BLUE *MY-PIXEL*) (GET-GREEN *MY-PIXEL*) (GET-ALPHA *MY-PIXEL*)) and I can write things like: &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;code&gt;(defun sum-colours (pixel)&lt;br /&gt;  (apply #'+ (with-pixel-colours (get-pixel pixel))))&lt;/blockquote&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;(setf *my-pixel* (make-pixel 1 1 1 0))&lt;/blockquote&gt;&lt;/p&gt;&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;(sum-colours *my-pixel*)&lt;/blockquote&gt;&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;3&lt;/code&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Fantastic - but there has to be a wider application than this - so my next task was to generalise it a bit. More in the next post. :) &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I do get the feeling I'm re-inventing a well known technique, as I'm a newbie, and this kind of thing is just too useful. Any experienced Lisp coders care to comment?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111908984251605620?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111908984251605620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111908984251605620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111908984251605620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111908984251605620'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/06/lisp-language-that-does-your-coding.html' title='Lisp, the language that does your coding for you..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111749506906515816</id><published>2005-05-31T00:06:00.000+01:00</published><updated>2005-06-18T11:32:33.226+01:00</updated><title type='text'>Ion Drive</title><content type='html'>&lt;p&gt;I've never found a window manager I've been 100% happy with - &lt;a href="http://www.kde.org"&gt;KDE&lt;/a&gt; and &lt;a href="http://www.gnome.org"&gt;Gnome&lt;/a&gt; are far to slow to live on my old P600 Laptop, &lt;a href="http://www.afterstep.org"&gt;Afterstep&lt;/a&gt;, while asethetically pleasing, had too many menus, too many different feels and options and and I never could settle on a consistent set. &lt;a href="http://www.nongnu.org/ratpoison/"&gt;Ratpoison&lt;/a&gt; was my most recent discovery, and while I liked it for it's simplicity, it was a bit too simple - it handled modal dialogs like mozillas download manager dialog badly - putting them in a whole window. At last I've discovered &lt;a href="http://modeemi.cs.tut.fi/~tuomov/ion/"&gt;Ion&lt;/a&gt; - a tad more sophisticated than Ratpoison, but not much, so it still responds instantly on a clapped out laptop. It just handles dialogs much better, and works on the same principe - you should be able to treat your window manager in exactly the same way as you treat your text editor window - by having multiple windows and frames you can split, delete, create, and traverse between via simple keystrokes. If you dislike mice, it's worth giving it a try..&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The only problem is -- there will never be a Windows version. It'd be interesting to see what a Mac user would make of it, though..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111749506906515816?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111749506906515816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111749506906515816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111749506906515816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111749506906515816'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/05/ion-drive.html' title='Ion Drive'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111618855601041259</id><published>2005-05-15T21:19:00.000+01:00</published><updated>2005-05-15T21:22:36.016+01:00</updated><title type='text'>And now colour it in..</title><content type='html'>&lt;p&gt;Added &lt;a href="http://www.yagc.ndo.co.uk/images/colour_tri.png"&gt;coloured&lt;/a&gt; tris to my renderer yesterday - it's coming along nicely. Started out as a  &amp;quot;learn lisp&amp;quot; exercise, but now it's taking on a life of it's own.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111618855601041259?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111618855601041259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111618855601041259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111618855601041259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111618855601041259'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/05/and-now-colour-it-in.html' title='And now colour it in..'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111503854672290804</id><published>2005-05-02T13:52:00.000+01:00</published><updated>2005-05-02T13:57:57.233+01:00</updated><title type='text'>Dynamic game difficulty adjustment.</title><content type='html'>Some thoughts after reading  &lt;a href="http://www.gamasutra.com/"&gt;The Psychology Behind Games&lt;/a&gt; by Anders Hejdenberg.&lt;br /&gt;&lt;br /&gt;Should a game adjust it's difficulty level based on the players observed ability in the game? Possibly, but it's an artificial device.  Response to changes in the players ability should probably err on the cautious side when making the game easy and on the converse side when making the game harder. It's important to have player profiles, too. Visual feedback of the current setting and a manual override would be nice, too. Some people don't want things to be too easy and for the game to "surrender", but other people would use such a mechanism to cheat, or just plain want to go through the game quickly.&lt;br /&gt;&lt;br /&gt;Feedback and control are the watchwords, as ever.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111503854672290804?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111503854672290804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111503854672290804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111503854672290804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111503854672290804'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/05/dynamic-game-difficulty-adjustment.html' title='Dynamic game difficulty adjustment.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111435957444045060</id><published>2005-04-24T17:13:00.000+01:00</published><updated>2005-04-24T17:19:34.440+01:00</updated><title type='text'>Brand new Baby Bouncing Triangle</title><content type='html'>At last cl-ptc (the Lisp software renderer) plots a nice, clean triangle, after weeks of fiddling around with interpolator functions, it's a relief. It's my first ever time as a lisp, so I'm proud to present my first ever bit of &lt;a href="http://www.yagc.ndo.co.uk/images/cl-ptc-first-ever-triangle.png"&gt;Lisp porn&lt;/a&gt;..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111435957444045060?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111435957444045060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111435957444045060' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111435957444045060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111435957444045060'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/04/brand-new-baby-bouncing-triangle.html' title='Brand new Baby Bouncing Triangle'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111434975592821889</id><published>2005-04-24T14:28:00.000+01:00</published><updated>2005-04-24T14:35:55.930+01:00</updated><title type='text'>Lisp gets it right</title><content type='html'>&lt;p&gt;After playing with lots of different methods of linearly interpolating the edges of triangles (well, 3 - DDA, MAI, &amp; Bressenham) in Lisp, I settled for the straight add the gradient to the minor axis. Madness, I hear you say - not really, because Lisp doesn't represent the result of integer division as a float, but as a pair of integers that represent a ratio, so even doing it this way means I can reserve the FPU for perspective - correct texture mapping the way Intel intended. Obviously, the representation of this ratio is implementation dependent, but I'd really hope that in an implemenation  with 32 bit fixnums, the ratio is expressed as a 64 bit fixed point integer..of course it's also probably possible to get LISP to use 16 bit integers for coordinates and 32 bit integers for the ratios, but I haven't got that far into the type sysetem, yet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111434975592821889?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111434975592821889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111434975592821889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111434975592821889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111434975592821889'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/04/lisp-gets-it-right.html' title='Lisp gets it right'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-111359598457115849</id><published>2005-04-15T21:02:00.000+01:00</published><updated>2005-04-15T21:13:04.573+01:00</updated><title type='text'>Lisp Software Renderer, Redux</title><content type='html'>&lt;p&gt; Of course, it's impossible to leave a challenge I got so close to completing, and so I dust off the Lisp software renderer and return to the fray. I've had to grapple a bit with ASDF and learnt the hard way why upper case file names and lower case package names don't mix. Also, trying to write a tail-recursive Bressenham was interesting..only a few more bugs to wrinkle out and it can hit common-lisp.net. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Then I can go onto the freenode #lisp channel and get a critique, I hope. 123 notes at an (optimize (speed 3)) sounds like there's still a lot of work ahead..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-111359598457115849?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/111359598457115849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=111359598457115849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111359598457115849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/111359598457115849'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/04/lisp-software-renderer-redux.html' title='Lisp Software Renderer, Redux'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110898731339706244</id><published>2005-02-21T11:58:00.000Z</published><updated>2005-02-21T12:01:53.476Z</updated><title type='text'>CL-Ncurses</title><content type='html'>I was playing with this at the weekend. And it's a nice solution for whipping up testbeds for simulations that can get away with a simple text interface. The trouble is it needs a bit of work, and the maintainer has dissapeared...&lt;br /&gt;&lt;br /&gt;I'd really like to submit a patch but there doesn't seem to be any point. I wish there was some kind of policy on common-lisp.net for dealing with such orphaned projects. The same as with sourceforge, I guess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110898731339706244?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110898731339706244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110898731339706244' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110898731339706244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110898731339706244'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/02/cl-ncurses.html' title='CL-Ncurses'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110838920175302958</id><published>2005-02-14T13:52:00.000Z</published><updated>2005-02-14T13:53:21.756Z</updated><title type='text'>LISP Software Renderer RIP</title><content type='html'>&lt;p&gt;I gave up on my quest to write a software renderer in Lisp - I got as far as creating nice antialiased clipped lines, but was driven to the conclusion that the only sane language for such a beast is assembler...even C doesn't get quite close enough to the metal without generous helpings of inline assembler - which kind of misses the point..&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I did discover that a LISP compiler with a decent static type system, vectorisation, SSE/SIMD support, and inline assembler could do just about as good a job as C. Trouble is, there's no LISP system like that in existence. There's at least two good open source Lisps that could be persuaded to do it, though..&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110838920175302958?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110838920175302958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110838920175302958' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110838920175302958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110838920175302958'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/02/lisp-software-renderer-rip.html' title='LISP Software Renderer RIP'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110717743055092654</id><published>2005-01-31T13:11:00.000Z</published><updated>2005-01-31T13:17:10.550Z</updated><title type='text'>Debug versus Release builds</title><content type='html'>This applies to fairly strongly and/or statically typed languages only, obviously:&lt;br /&gt;&lt;br /&gt;The way I think of it, the difference between release and debug is the difference between trying to fly a plane with no instruments at all, and a possibly dodgy engine that won't neccessarily give you any warning that it's about to burn, versus a nice modern jet with thoroughly checked over engines and wiring, a full array of instrumentation and autopilots for everything you could possibly need.&lt;br /&gt;&lt;br /&gt;Now - it's your backside in the plane - which do you want to fly?&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110717743055092654?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110717743055092654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110717743055092654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110717743055092654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110717743055092654'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/01/debug-versus-release-builds.html' title='Debug versus Release builds'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110676652828583514</id><published>2005-01-26T18:58:00.000Z</published><updated>2005-05-02T14:04:10.453+01:00</updated><title type='text'>Visual Studio and Standard Environments.</title><content type='html'>&lt;p&gt;Just what is it that people see in it? Working with it as an editor is like swimming through treacle. Without the Visual Assist plugin it's auto completion is limited and without lengthy compile times, it can't manage to tag a project well. You can only really edit three languages with it, and use only the hand full of source code control systems that implement a Microsoft API. It's scripting facilities are ripe for viral attack, and poor tools for automation.&lt;/p&gt; &lt;p&gt;The wizards to help programmers who don't know how to do basic things ignore their ignorance, though. I'm just a little pissed off about this "standard environment" that' s been imposed on everybody at work. The a component of the last "standard environment" was the slowest and most broken source control system I've ever worked with.&lt;/p&gt;&lt;p&gt;When carrying 500kilo weights is the standard environment for the Olympic High Jump, then all this will make sense. I think. Standard environments might be great for managers as they reduce programmers to the lowest common interchangable denominaters, but for programmers looking for an edge and a chance to develop great software, they are a positive handicap.&lt;/p&gt;&lt;p&gt;Somewhere there is a cutoff point where staying within the standard environment becomes ultimately more punishing than the leap forward out of it. I just hope I can recognise that point.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110676652828583514?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110676652828583514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110676652828583514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110676652828583514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110676652828583514'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/01/visual-studio-and-standard.html' title='Visual Studio and Standard Environments.'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110661592313949934</id><published>2005-01-25T01:08:00.000Z</published><updated>2005-01-25T01:18:43.140Z</updated><title type='text'>Progress with Lisp</title><content type='html'>&lt;p&gt;So far my initial enthusiasm for LISP is wearing off a bit. I can see it's practical potential,  but the main upshot of my learning it, so far is that I've switched to Emacs from Vi.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Perhaps my problem is that I'm just put off by the constant fiddling needed with free Linux implementations and the unavailabilty of a good free as in beer Win32 implementation. I miss the ease of integration with a lot of useful libraries I'm used to working with in both Python &amp;amp; C++, as well as all the new idioms I have to absorb.&lt;/p&gt;&lt;br /&gt;&lt;p&gt; I can see the language can do things that Python only vaguely aspires to, though. I'm just not sure that in the cases when I don't need the extra grunt of Lisp that I'll be able to prototype as rapidly as I could in Python.&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110661592313949934?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110661592313949934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110661592313949934' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110661592313949934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110661592313949934'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/01/progress-with-lisp.html' title='Progress with Lisp'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110606662906707193</id><published>2005-01-18T16:40:00.000Z</published><updated>2005-01-18T16:43:49.066Z</updated><title type='text'>More Fun With Dungeon Generation</title><content type='html'>Much improved. Doesn't guarantee interconnection, though,&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;############               ####       ## ###  ##################&lt;br /&gt;############               ####        # ##   ##################&lt;br /&gt;                          ####                   ##############&lt;br /&gt;### ##                 #   ####        #          ##############&lt;br /&gt;### ########           #   #######  #             ##############&lt;br /&gt;   ########          ##  ######                  ##############&lt;br /&gt;############# #          ####      ###           ##############&lt;br /&gt;  ########### #      #   ####          ##        ##############&lt;br /&gt;# ###########    # ###   ################        ##############&lt;br /&gt;#                #       ################        ##############&lt;br /&gt;#  #########     #####   ######################################&lt;br /&gt;   #########     ##      ######################################&lt;br /&gt;#   #########    ##  #  ########################################&lt;br /&gt;#   ###########  ## ##       ###################################&lt;br /&gt;# # ###########          ### ###################################&lt;br /&gt;    ##########     ######## ###################################&lt;br /&gt;####  ###################### ###################################&lt;br /&gt;##### ###################### ###################################&lt;br /&gt;##### ###################### ###################################&lt;br /&gt;##### ###################### ###################################&lt;br /&gt;     ###################### ###################################&lt;br /&gt;# ########################## ###################################&lt;br /&gt;# #####################      ###################################&lt;br /&gt;# #####################    #####################################&lt;br /&gt;# ######################## #####################################&lt;br /&gt;# #####      ############# #####################################&lt;br /&gt;# #####      ####            ###################################&lt;br /&gt;# #####      #### # ######## ###################################&lt;br /&gt;#                            ###################################&lt;br /&gt;            ####     ##########################################&lt;br /&gt;            ######## #                   ######################&lt;br /&gt;# #### #### #########   ################# ######################&lt;br /&gt;      #### ############################# ######################&lt;br /&gt;#           ######    ################### ######################&lt;br /&gt;# ################ ## ################### ######################&lt;br /&gt; ################ ## ################### ######################&lt;br /&gt;################# ## ################### ######################&lt;br /&gt;   ############## ## ################### ######################&lt;br /&gt;### ##############    ###################   ####################&lt;br /&gt;### ################  ##################### ####################&lt;br /&gt;### ################  ##################### ####################&lt;br /&gt;### ################  ##################### ####################&lt;br /&gt;### ################  ####  ############### ####################&lt;br /&gt;### ################  ####  ############### ####################&lt;br /&gt;### ################  ##    ############### ####################&lt;br /&gt;### #################    ## #########       ####################&lt;br /&gt;### ################# ##### ######### ##########################&lt;br /&gt;### #################           ##### ##########################&lt;br /&gt;### ###################### ###    ### ##########################&lt;br /&gt;### ###################### ###    ### ##########################&lt;br /&gt;#   ###################### ###        ##########################&lt;br /&gt; ######################## ###              ####################&lt;br /&gt;    ##################### ### ############ #######  ###########&lt;br /&gt; ## ##################### ### ############          ###########&lt;br /&gt;#  # ##################### ### ############    ## ##  ##########&lt;br /&gt;## # #####################     ############ ## ## ### ##########&lt;br /&gt;##   #####################  ############### ## ## ### ##########&lt;br /&gt;################                ########### ## ## ### ##########&lt;br /&gt;#########    ### #######        ########### ## #      ##########&lt;br /&gt;#########    ### #######        ########### ##    ##  ##########&lt;br /&gt;#########    #   #######        ########### ##    ##    ########&lt;br /&gt;#########       ##########  #  ##########         ## ## ########&lt;br /&gt;#########    ##             #  ##########  ######    ## ########&lt;br /&gt;#########    ## #############  #################################&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 255, 0);"&gt;import&lt;/span&gt; Numeric&lt;br /&gt;&lt;span style="color: rgb(0, 255, 0);"&gt;import&lt;/span&gt; whrandom&lt;br /&gt;&lt;span style="color: rgb(0, 255, 0);"&gt;import&lt;/span&gt; math&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 0);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;Burrower&lt;/span&gt;:&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;__init__&lt;/span&gt;(self, x, y, lifetime = 0, dx = 0, dy = 0):&lt;br /&gt;       self.data = [ x, y, lifetime, dx, dy ]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;burrower_is_dead&lt;/span&gt;(self):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; self.data[2] == -1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;kill_burrower&lt;/span&gt;(self):&lt;br /&gt;       self.data[2] = -1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;tick_burrower&lt;/span&gt;(self,b):&lt;br /&gt;       self.data[2] = self.data[2] + 1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;pick_random_motion&lt;/span&gt;(self, allow_diagonals):&lt;br /&gt;       motion = whrandom.randrange(0,3)&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; motion == 0:&lt;br /&gt;           dx =    - 1&lt;br /&gt;           dy = self.data[4]&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               dy = 0&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;elif&lt;/span&gt; motion == 1:&lt;br /&gt;           dx = 1&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;              dy = 0&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;elif&lt;/span&gt; motion == 2:&lt;br /&gt;           dy = -1&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               dx = 0&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;elif&lt;/span&gt; motion == 3:&lt;br /&gt;           dy = 1&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               dx = 0&lt;br /&gt;       &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# don't double back on yourself&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; dx == -self.data[3] &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; dy == self.data[4]:&lt;br /&gt;           dy = dx&lt;br /&gt;           dx = self.data[4]&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; dy == -self.data[4] &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; dx == self.data[3]:&lt;br /&gt;           dx = dy&lt;br /&gt;           dy = self.data[3]&lt;br /&gt;       self.data[3] = dx&lt;br /&gt;       self.data[4] = dy&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;clip_burrower&lt;/span&gt;(self, minx, miny, maxx, maxy):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[0] &amp;lt; minx:&lt;br /&gt;           self.data[0] = minx&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[0] &amp;gt; maxx:&lt;br /&gt;           self.data[0] = maxx&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[1] &amp;lt; miny:&lt;br /&gt;           self.data[1] = miny&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[1] &amp;gt; maxy:&lt;br /&gt;           self.data[1] = miny&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;un_move_burrower&lt;/span&gt;(self, minx, miny, maxx, maxy, allow_diagonals):&lt;br /&gt;       self.data[0] = self.data[0] - self.data[3]&lt;br /&gt;       self.data[1] = self.data[1] - self.data[4]&lt;br /&gt;       self.clip_burrower(minx, miny, maxx, maxy)&lt;br /&gt;       self.pick_random_motion(allow_diagonals)&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# move the burrower one cell, carving as you go along&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# to do  rather than randomly pick a direction, randomly *change* a direction (more control of twistiness, etc)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;move_burrower&lt;/span&gt;(self, minx, miny, maxx, maxy, changeprob, allow_diagonals):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; whrandom.random() &amp;lt; changeprob:&lt;br /&gt;           self.pick_random_motion(allow_diagonals)&lt;br /&gt;       &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# am i dead ? if so I should be concenrating on a nice firm rigor mortis&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.burrower_is_dead():&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt;&lt;br /&gt;       self.data[0] = self.data[0] + self.data[3]&lt;br /&gt;       self.data[1] = self.data[1] + self.data[4]&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[0] &amp;lt; minx:&lt;br /&gt;           self.data[0] = 0&lt;br /&gt;           self.data[3] = 1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[1] &amp;lt; miny:&lt;br /&gt;           self.data[1] = 0&lt;br /&gt;           self.data[4] = 1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[0] &amp;gt; maxx:&lt;br /&gt;           self.data[0] = maxx&lt;br /&gt;           self.data[3] = -1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.data[1] &amp;gt; maxy:&lt;br /&gt;           self.data[1] = maxy&lt;br /&gt;           self.data[4] = -1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 0);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;Dungeon&lt;/span&gt;:&lt;br /&gt;   TileIdNumber = { &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;granite&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt; : 0 , &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;room&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt; : 1, &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;corridor&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt; : 2 }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;__init__&lt;/span&gt;(self,  width, depth):&lt;br /&gt;       self.tiles = Numeric.zeros((width, depth))&lt;br /&gt;       self.width = width&lt;br /&gt;       self.depth = depth&lt;br /&gt;       self.room_centres = [ ]&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;room_too_close&lt;/span&gt;(self, x, y, min_room_distance):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; r &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; self.room_centres:&lt;br /&gt;           dx = r[0] - x&lt;br /&gt;           dy = r[1] - y&lt;br /&gt;           dist = math.sqrt(x * x + y * y)&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; (dist &amp;lt; min_room_distance):&lt;br /&gt;               &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; True&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; False&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;burrower_room_create&lt;/span&gt;(self, b, broom_prob, max_room_width, max_room_depth, min_room_distance, burrower_index):&lt;br /&gt;       &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# we have a room&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; whrandom.random() &amp;gt; broom_prob:&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; 0&lt;br /&gt;       room_width = whrandom.randrange(max_room_width / 2) + 1&lt;br /&gt;       room_depth = whrandom.randrange(max_room_depth / 2) + 1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.room_too_close(b.data[0], b.data[1], min_room_distance):&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; 0&lt;br /&gt;       self.room_centres.append((b.data[0], b.data[1]))&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; x &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range (b.data[0] - room_width, b.data[0] + room_width):&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; y &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range (b.data[1] - room_depth, b.data[1] + room_depth):&lt;br /&gt;               &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; (x &amp;gt;= 0) &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (x &amp;lt; self.width) &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (y &amp;gt;= 0) &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (y &amp;lt; self.depth):&lt;br /&gt;                   self.tiles[x][y] = burrower_index&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; 1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;burrower_birth&lt;/span&gt;(self,bbirth_prob):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; whrandom.random() &amp;lt; bbirth_prob&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;baby_burrower&lt;/span&gt;(self, b):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt; Burrower(b.data[0] + whrandom.randrange(2), b.data[1] + whrandom.randrange(2), 0, 0, 0)&lt;br /&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;print_dungeon&lt;/span&gt;(self):&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; y &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,self.depth):&lt;br /&gt;           s = &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;""&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; x &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,self.width):&lt;br /&gt;               &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.tiles[x][y] == Dungeon.TileIdNumber[&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;granite&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;]:&lt;br /&gt;                   s = s + &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;#&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;               &lt;span style="color: rgb(255, 255, 0);"&gt;else&lt;/span&gt;:&lt;br /&gt;                   s = s + &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt; &lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;print&lt;/span&gt; s&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# burrowers start on one side of the level, on each turn they can either split (birth prob),&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# create a room (die), have a max lifetime, and the algo terminates when room_count is reached&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;#&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color: rgb(255, 255, 0);"&gt;def&lt;/span&gt; &lt;span style="color: rgb(192, 192, 192);"&gt;generate&lt;/span&gt;(self, burrower_total, room_total, birth_prob, turn_prob, room_prob, lifetime, max_room_width, max_room_depth, min_room_distance, allow_diagonals):&lt;br /&gt;       &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# set up burrowers&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;       burrowers = []&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; i &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,burrower_total):&lt;br /&gt;           side = whrandom.randrange(0,4)&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; side == 0:&lt;br /&gt;               burrower = Burrower( 0, whrandom.randrange(0, self.depth) , 0, 1, 0 )&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;elif&lt;/span&gt; side == 1:&lt;br /&gt;               burrower = Burrower( self.width-1, whrandom.randrange(0, self.depth) , -1, 0, 0 )&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;elif&lt;/span&gt; side == 2:&lt;br /&gt;               burrower = Burrower( whrandom.randrange(0,self.width), 0, 0, 0, 1 )&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;else&lt;/span&gt;:&lt;br /&gt;               burrower = Burrower( whrandom.randrange(0,self.width), self.depth-1 , 0, 0, -1 )&lt;br /&gt;           burrowers.append(burrower)&lt;br /&gt;       room_count = 0&lt;br /&gt;       burrower_alive = True&lt;br /&gt;       i = 0&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;while&lt;/span&gt; burrower_alive:&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;print&lt;/span&gt; &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;Generation &lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt; , i&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;print&lt;/span&gt; &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;Rooms # &lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;, room_count&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;print&lt;/span&gt; &lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;Burrowers &lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;, len(burrowers)&lt;br /&gt;           self.print_dungeon()&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;print&lt;/span&gt;&lt;br /&gt;           burrower_alive = False&lt;br /&gt;           birth_list = []&lt;br /&gt;           burrower_index = 1&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;for&lt;/span&gt; b &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; burrowers:&lt;br /&gt;               &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; b.burrower_is_dead():&lt;br /&gt;                   burrower_alive = True&lt;br /&gt;                   b.move_burrower(0, 0, self.width-1, self.depth-1, turn_prob, allow_diagonals)&lt;br /&gt;                   &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# if the burrower reaches another corridor, kill it&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                   burrower_tile = self.tiles[b.data[0]][b.data[1]]&lt;br /&gt;                   &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; (burrower_tile != Dungeon.TileIdNumber[&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;granite&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;]) &lt;span style="color: rgb(255, 165, 0);"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (burrower_tile != burrower_index):&lt;br /&gt;                       b.un_move_burrower(0,0, self.width-1, self.depth-1, allow_diagonals)&lt;br /&gt;                       b.data[2] = b.data[2] + 1&lt;br /&gt;                       &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; b.data[2] &amp;gt; lifetime:&lt;br /&gt;                           b.kill_burrower()&lt;br /&gt;                   self.tiles[b.data[0]][b.data[1]] = burrower_index&lt;br /&gt;                   &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; self.burrower_birth(birth_prob):&lt;br /&gt;                       birth_list.append(self.baby_burrower(b))&lt;br /&gt;                   room_count = room_count + self.burrower_room_create(b, room_prob, max_room_width, max_room_depth, min_room_distance, burrower_index)&lt;br /&gt;               burrower_index = burrower_index + 1&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; birth_list:&lt;br /&gt;               burrowers.extend(birth_list)&lt;br /&gt;           &lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; room_count &amp;gt;= room_total:&lt;br /&gt;               birth_prob = 0.0&lt;br /&gt;               room_prob = 0.0&lt;br /&gt;           i = i + 1&lt;br /&gt;       &lt;span style="color: rgb(255, 255, 0);"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 0);"&gt;if&lt;/span&gt; __name__==&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 255, 255);"&gt;__main__&lt;/span&gt;&lt;span style="background-color: rgb(0, 0, 128);"&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;"&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;   dungeon = Dungeon(64,64)&lt;br /&gt;   dungeon.generate(16, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# burrower total&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    12, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# room total&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    0.009, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# birth probability&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    0.25, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# turn probability&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    0.03, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# room probability&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    2, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# lifetime (max non self - hits allowwd)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    9,  &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# max_room_depth&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    9, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# max room width&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    6, &lt;span style="color: rgb(192, 192, 192);"&gt;&lt;b&gt;# min room distance&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;                    False)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110606662906707193?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110606662906707193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110606662906707193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110606662906707193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110606662906707193'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/01/more-fun-with-dungeon-generation.html' title='More Fun With Dungeon Generation'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-110562381098640039</id><published>2005-01-13T13:39:00.000Z</published><updated>2005-01-13T13:43:30.986Z</updated><title type='text'>Fun With Dungeon Generation</title><content type='html'>&lt;p&gt;One of the more preinnal topics of &lt;a href="http://www.hut.fi/%7Eeye/roguelike/rogue.html"&gt;roguelike&lt;/a&gt; game design, or general dungeon cralws is "How do I generate that funky dungeon procedurally?". There's an unbelievable number of algorithms, but this one is my favourite...&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:#a020f0;"&gt;import&lt;/span&gt; Numeric&lt;br /&gt;&lt;span style="color:#a020f0;"&gt;import&lt;/span&gt; whrandom&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#804040;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;Burrower&lt;/span&gt;:&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;__init__&lt;/span&gt;(self, x, y, lifetime = 0, dx = 0, dy = 0):&lt;br /&gt;       self.data = [ x, y, lifetime, dx, dy ]&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;burrower_is_dead&lt;/span&gt;(self):&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; self.data[2] == -1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;kill_burrower&lt;/span&gt;(self):&lt;br /&gt;       self.data[2] = -1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;tick_burrower&lt;/span&gt;(self,b):&lt;br /&gt;       self.data[2] = self.data[2] + 1&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;pick_random_motion&lt;/span&gt;(self, allow_diagonals):&lt;br /&gt;       motion = whrandom.randrange(0,3)&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; motion == 0:&lt;br /&gt;           self.data[3] =  - 1&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#804040;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               self.data[4] = 0&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt; motion == 1:&lt;br /&gt;           self.data[3] = 1&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#804040;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               self.data[4] = 0&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt; motion == 2:&lt;br /&gt;           self.data[4] = -1&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#804040;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               self.data[3] = 0&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt; motion == 3:&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#804040;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; allow_diagonals:&lt;br /&gt;               self.data[3] = 0&lt;br /&gt;           self.data[4] = 1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# move the burrower one cell, carving as you go along&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# to do  rather than randomly pick a direction, randomly *change* a direction (more control of twistiness, etc)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;move_burrower&lt;/span&gt;(self, minx, miny, maxx, maxy, changeprob, allow_diagonals):&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; whrandom.random() &amp;lt; changeprob:&lt;br /&gt;           self.pick_random_motion(allow_diagonals)&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;# am i dead ? if so I should be concenrating on a nice firm rigor mortis&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.burrower_is_dead():&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;       self.data[0] = self.data[0] + self.data[3]&lt;br /&gt;       self.data[1] = self.data[1] + self.data[4]&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.data[0] &amp;lt; minx:&lt;br /&gt;           self.data[0] = 0&lt;br /&gt;           self.data[3] = 1&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.data[1] &amp;lt; miny:&lt;br /&gt;           self.data[1] = 0&lt;br /&gt;           self.data[4] = 1&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.data[0] &amp;gt; maxx:&lt;br /&gt;           self.data[0] = maxx&lt;br /&gt;           self.data[3] = -1&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.data[1] &amp;gt; maxy:&lt;br /&gt;           self.data[1] = maxy&lt;br /&gt;           self.data[4] = -1&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;# up lifetime count&lt;/span&gt;&lt;br /&gt;       self.data[2] = self.data[2] + 1&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#804040;"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;Dungeon&lt;/span&gt;:&lt;br /&gt;   TileIdNumber = { "&lt;span style="color:#ff00ff;"&gt;granite&lt;/span&gt;" : 0 , "&lt;span style="color:#ff00ff;"&gt;empty&lt;/span&gt;" : 1, "&lt;span style="color:#ff00ff;"&gt;corridor&lt;/span&gt;" : 2 }&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;__init__&lt;/span&gt;(self,  width, depth):&lt;br /&gt;       self.tiles = Numeric.zeros((width, depth))&lt;br /&gt;       self.width = width&lt;br /&gt;       self.depth = depth&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# die, maybe, if lifetime expired, die with a whimper,&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# else die with a bang and create a room&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# returns count of rooms created so we can track them&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# to do : probability of generating "special" rooms?&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;#&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;burrower_death&lt;/span&gt;(self, b, bdeath_prob, lifetime, max_room_width, max_room_depth):&lt;br /&gt;       result = 0&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;# if out of time, just die quietly&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; b.data[2] &amp;gt; lifetime:&lt;br /&gt;           b.kill_burrower()&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;# if random chance of death turns up, burst into a room&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; whrandom.random() &amp;lt; bdeath_prob:&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;# we have a room&lt;/span&gt;&lt;br /&gt;           room_width = whrandom.randrange(max_room_width / 2) + 1&lt;br /&gt;           room_depth = whrandom.randrange(max_room_depth / 2) + 1&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; x &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range (b.data[0] - room_width, b.data[0] + room_width):&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; y &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range (b.data[1] - room_depth, b.data[1] + room_depth):&lt;br /&gt;                   &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; (x &amp;gt;= 1) &lt;span style="color:#804040;"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (x &amp;lt; self.width-1) &lt;span style="color:#804040;"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (y &amp;gt;= 1) &lt;span style="color:#804040;"&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt; (y &amp;lt; self.depth-1):&lt;br /&gt;                       self.tiles[x][y] = Dungeon.TileIdNumber["&lt;span style="color:#ff00ff;"&gt;empty&lt;/span&gt;"]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;#           b.kill_burrower()&lt;/span&gt;&lt;br /&gt;           result = 1&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; result&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;burrower_birth&lt;/span&gt;(self,bbirth_prob):&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; whrandom.random() &amp;lt; bbirth_prob&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;baby_burrower&lt;/span&gt;(self, b):&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt; Burrower(b.data[0] + whrandom.randrange(2), b.data[1] + whrandom.randrange(2), 0, 0, 0)&lt;br /&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;print_dungeon&lt;/span&gt;(self):&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; y &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,self.depth):&lt;br /&gt;           s = ""&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; x &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,self.width):&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.tiles[x][y] == Dungeon.TileIdNumber["&lt;span style="color:#ff00ff;"&gt;granite&lt;/span&gt;"]:&lt;br /&gt;                   s = s + "&lt;span style="color:#ff00ff;"&gt;#&lt;/span&gt;"&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;:&lt;br /&gt;                   s = s + "&lt;span style="color:#ff00ff;"&gt; &lt;/span&gt;"&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt; s&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;#&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# burrowers start on one side of the level, on each turn they can either split (birth prob),&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;# create a room (die), have a max lifetime, and the algo terminates when room_count is reached&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;#&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#804040;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#008080;"&gt;generate&lt;/span&gt;(self, burrower_total, room_total, birth_prob, death_prob, turn_prob, lifetime, max_room_width, max_room_depth, allow_diagonals):&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;# set up burrowers&lt;/span&gt;&lt;br /&gt;       burrowers = []&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; i &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; range(0,burrower_total):&lt;br /&gt;           side = whrandom.randrange(0,4)&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; side == 0:&lt;br /&gt;               burrower = Burrower( 0, whrandom.randrange(0, self.depth) , 0, 1, 0 )&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt; side == 1:&lt;br /&gt;               burrower = Burrower( self.width-1, whrandom.randrange(0, self.depth) , -1, 0, 0 )&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;elif&lt;/b&gt;&lt;/span&gt; side == 2:&lt;br /&gt;               burrower = Burrower( whrandom.randrange(0,self.width), 0, 0, 0, 1 )&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;else&lt;/b&gt;&lt;/span&gt;:&lt;br /&gt;               burrower = Burrower( whrandom.randrange(0,self.width), self.depth-1 , 0, 0, -1 )&lt;br /&gt;           burrowers.append(burrower)&lt;br /&gt;       room_count = 0&lt;br /&gt;       burrower_alive = True&lt;br /&gt;       i = 0&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;while&lt;/b&gt;&lt;/span&gt; burrower_alive:&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt; "&lt;span style="color:#ff00ff;"&gt;Generation &lt;/span&gt;" , i&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt; "&lt;span style="color:#ff00ff;"&gt;Rooms # &lt;/span&gt;", room_count&lt;br /&gt;           self.print_dungeon()&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;print&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;           burrower_alive = False&lt;br /&gt;           birth_list = []&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;for&lt;/b&gt;&lt;/span&gt; b &lt;span style="color:#804040;"&gt;&lt;b&gt;in&lt;/b&gt;&lt;/span&gt; burrowers:&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; &lt;span style="color:#804040;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt; b.burrower_is_dead():&lt;br /&gt;                   burrower_alive = True&lt;br /&gt;               b.move_burrower(0, 0, self.width-1, self.depth-1, turn_prob, allow_diagonals)&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; (self.tiles[b.data[0]][b.data[1]] == Dungeon.TileIdNumber["&lt;span style="color:#ff00ff;"&gt;corridor&lt;/span&gt;"]):&lt;br /&gt;                   b.kill_burrower()&lt;br /&gt;               self.tiles[b.data[0]][b.data[1]] = Dungeon.TileIdNumber["&lt;span style="color:#ff00ff;"&gt;corridor&lt;/span&gt;"]&lt;br /&gt;               &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; self.burrower_birth(birth_prob):&lt;br /&gt;                   birth_list.append(self.baby_burrower(b))&lt;br /&gt;               room_count = room_count + self.burrower_death(b, death_prob, lifetime, max_room_width, max_room_depth)&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; birth_list:&lt;br /&gt;               burrowers.extend(birth_list)&lt;br /&gt;           &lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; room_count == room_total:&lt;br /&gt;               birth_prob = 0&lt;br /&gt;               death_prob = 0&lt;br /&gt;       &lt;span style="color:#804040;"&gt;&lt;b&gt;return&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#804040;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt; __name__=="&lt;span style="color:#ff00ff;"&gt;__main__&lt;/span&gt;":&lt;br /&gt;   dungeon = Dungeon(64,32)&lt;br /&gt;   dungeon.generate(16, 32, 0.01, 0.005, 0.05, 1024, 16, 16, False)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7235819-110562381098640039?l=badbyteblues.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://badbyteblues.blogspot.com/feeds/110562381098640039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7235819&amp;postID=110562381098640039' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110562381098640039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7235819/posts/default/110562381098640039'/><link rel='alternate' type='text/html' href='http://badbyteblues.blogspot.com/2005/01/fun-with-dungeon-generation.html' title='Fun With Dungeon Generation'/><author><name>John Connors</name><uri>http://www.blogger.com/profile/01102954516659291106</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://1.bp.blogspot.com/-4m2_TGiupEE/TX9f-I7Lo3I/AAAAAAAAAD8/AOymlCmzOQU/s220/100_2356.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7235819.post-109890509993102109</id><published>2004-10-27T20:18:00.000+01:00</published><updated>2004-10-27T20:24:59.930+01:00</updated><title type='text'>UML, OO models and Abstraction</title><content type='html'>There's a hierarchy of sorts of abstraction away from machine hardware - you start with assembler - working with resigsters, raw memory, I/O ports, interrupts etc, but it gets more wooly and disintegrates into something resembling a spaghetti ATN the further you work your way up.&lt;br /&gt;&lt;br /&gt;C takes you one layer from that - it gives you functions, typing and normal maths notation, but you are still working with raw lumps of memory (structs) and there's a pretty much one to one mapping between expressions and machine instructions - the size assembler output is going to be roughly proportional to source input.&lt;br /&gt;&lt;br /&gt;"C with classes" C++ gives you some more layers - You can take a hunk of raw memory and associate it
