Older blog entries for ingvar (starting at number 204)

Avid readers cannot have missed the latest little thing (antifuchs, this is all your fault!). And it's now in a "it works, I'll abandon it for the moment" quality. Snag it from here, load ASDF system "clbasic" and then call BASIC:B-R-E-P ("basic-read-eval-print", with an understoop loop).

Code quality varies, I'd not necessarily hold it forth as a shining example of "how to code". The basic dialect itself I'd hold forth as a shining example of how not to design a language, seeing as how "insanely powerful obfuscators" was the leading beacon during the "design".

A bit futher:

0 > list
10 for i=1 to 3
20 for j=1 to 3
30 print "i is "+i
40 print "j is "+j
50 next j
60 next i

NIL > run "i is "1 "j is "1 "i is "1 "j is "2 "i is "1 "j is "3 "i is "2 "j is "1 "i is "2 "j is "2 "i is "2 "j is "3 "i is "3 "j is "1 "i is "3 "j is "2 "i is "3 "j is "3

0 > 50 next i

NIL > 60 next j

NIL > list 10 for i=1 to 3 20 for j=1 to 3 30 print "i is "+i 40 print "j is "+j 50 next i 60 next j

NIL > run "i is "1 "j is "1 "i is "2 "j is "1 "i is "3 "j is "1 "i is "4 "j is "2 "i is "4 "j is "3

0 >

So, for/next loops in place. Naturally without any sort of checking for proper nesting. Improper nesting is seldom useful, but when it is, it's exceedingly useful. Careful application of improper nesting and cmputed come-froms should, hopefully, cause code to look superficially simple but still cause a head-ache. I am beginning to believe I dare package this up now.

Not much games coding lately. Another (old) project sort-of happened. Not quite where it should be, but it's slowly getting there. Next step is having a think about iteration, I think.

So far:

BASIC> (b-r-e-p)
 > list
10 print "Hello"
15 print "World"
20 let nisse=3
22 let nisse=22
23 let nisse=50
25 print nisse
50 come from nisse
55 print line
60 print "The value of nisse is high"
65 goto 0
70 come from nisse
75 print line
80 print "Nisse has a high value here too"

NIL > run "Hello" "World" 51 71 "The value of nisse is high" "Nisse has a high value here too"

0 >

Yep, threaded basic interpreters with a least-surprise computed come from. Well, if there are multiple available come from statements that indicate that the thread of execution should come from the current line, it is (probably) least-surprise to effectively spawn new threads.

This might end up being truly evil, some day. For now, it works. Took a bit longer clearing up a code base that has hovered untouched for more than 6 years, though most of the code worked out of the box. I'd guess about 80% or so. Unfortunately, the code that didn't work was in the essential scaffolding. Also, I wonder why I didn't use hash tables for storing the interpreter's variables instead of knocking up a dictionary tree library (best guess, it looked like an interesting challenge writing the dictionary library and the basic interpreter was, at best, an excuse for having a use for the dictionary library).

Beh. Spending too many hours at work over the weekend meant I forgot i needed to make available a newer Pantzer tar ball. So I will just have to do it now.

So, there's at least one confirmed bug in Pantzer. Unless you have the right font available to our X server, you get a horrible error, telling you so.

There is a patched version, on my disk, not yet released. It needs a little bit of testing, but until then, push an existing font onto PANTZER:*FONT-PREFERENCE* (the fix is, essentially, instead of using the CAR of that list, traverse it until an openable font is found).

Thanks to Athas of #lisp for notifying me of the bug's existence. Once it was pointed out, the fix was, as they say, trivial.

There's a couple of screen-shots up here. Unfortunately, the game is MUCH more appealing in motion.

1 Aug 2006 (updated 1 Aug 2006 at 09:28 UTC) »

Of course, crhodes pointed out that there were some FATAL flaws in my macros. Firstly, I managed to faff decf-if-not-negative (I used > instead of >=). secondly, it suffers from Multiple Evaluation.

(defun decrease-if-positive (base n)
  (if (> base 0)
      (- base n)

(defun decrease-if-not-negative (base n) (if (>= base 0) (- base n) base))

(define-modify-macro decf-if-positive (&optional (delta 1)) decrease-if-positive) (define-modify-macro decf-if-not-negative (&optional (delta 1)) decrease-if-not-negative)

This morning was definitely lacking in the planned book database recovery (sigh). However, there is now "lives", the UI loop terminates as the number of lives spare hit -1, there's a compass rose that seems to behave as it should and there is a visible warning when an enemy tank fires a missile. Still no REAL handling of enemy tank collision (this should I feel, cause s loss-of-life). There is also a handy utility macro or two (hiding in globals.lisp):

(defmacro decf-if-positive (form &optional (step 1))
  (let ((cur (gensym "CUR")))
    `(let ((,cur ,form))
       (if (> ,cur 0)
	   (setf ,form (- ,cur ,step))

(defmacro decf-if-not-negative (form &optional (step 1)) (let ((cur (gensym "CUR"))) `(let ((,cur ,form)) (if (> ,cur 0) (setf ,form (- ,cur ,step)) ,cur))))

Handling of lives is under way.

Tank AI no longer computes FOV as if it was at (0.0; 0.0) but at the actual tank position (this, no messing, improved the aiming and stuff a LOT).

We now handle collisions between missiles and the camera (read "player") by simply deducting a life. Drawing of small tanks in the infobar is in progress (build a list of points off-set from X and Y fed in as parameters, feed to XLIB:DRAW-LINES, with filling).

There might, just might, be a 0.3 ready tomorrow.

So, the AI is somewhat les sstupid, things no longer shoot themselves, annoying "why are enemy tanks not displayed?" bug has been fixed, there is now automatic replenishment of tanks and landscape as it gets shot up.

I think that means "time to link!". So, without further ado, I give you Pantzer, a cheesy wire-frame "shoot tanks" game. NB, at the moment, you can't be killed. That's, admittedly, a bug. But it's a cool bug. It'll be fixed when I've decided on such pesky things as "how many lives".

Oh, to start, load the system, then run (net.hexapodia.pantzer:ui-loop) (if you want an inter-frame delay that's longer than the default 0.1 seconds, give the delay as an optional argument). Oh, yes, make sure to have CLX around, otherwise the display won't work.

195 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!