Friday, October 16, 2009

3D roguelike graphics

I had some trouble sleeping (like a dwarf taken by a fey mood) because I was imagining a roguelike game rendered in 3D graphics with an isometric view which took advantage of the height levels to have little snipers walking on balconies and other similar things.

The graphics would be "traditional" roguelike graphics, but plastered onto 3D primitives which moved around, possibly in real-time, possibly with sub-tile movement accuracy, in a way that could be replaced with expensive 3D graphics later but which would have their own utility and charm to roguelike players.

So I did this little mock up in Blender to get it out of my head and get some sleep. Feedback welcome.

Sunday, September 20, 2009

libfov-1.0.4 released

One bug fixed: The dx and dy values passed to the apply callback were quite wrong. They would work only if you used them in a formula dist_sq = (dx*dx) + (dy*dy). They are now correct (and unit tested).

Get it here: http://code.google.com/p/libfov/

Saturday, May 23, 2009

Xubuntu 9.04 Jaunty Jackelope Package List

I upgraded to Jaunty and in the process I wished that I'd done a dpkg --get-selections > selections.intrepid back when I installed it so that I could diff it with my current selections to see what I had installed in intrepid's lifetime, that I may want to overlay on top of jaunty.

So I remembered to do it this time. If (in the future) you're about to upgrade from jaunty to something else, you may find this useful to compare to the output of dpkg --get-selections.

dpkg --get-selections from my fresh xubuntu 9.04 install

Tuesday, September 23, 2008

My Gnome Trial

I'm a Window Maker user of many years now. It has served me wonderfully. The things I especially like about it are:

  • Smart window placement. When you open a new window, Window Maker finds the area of the screen to put it where it will overlap the least.

  • Alt+LMB Drag moves windows around. You don't have to click the title bar of a window to move it around. Hold Alt and click anywhere on the window with the left mouse button to start moving the window around.

  • Alt+RMB Drag resizes windows. You don't have to click the corner of a window to resize it. Hold Alt and click in any quadrant of a window with the right mouse button and start dragging to resize the window.

  • The dock. The dock is where you put "dockapps". These are 64x64 pixel applications with a range of purposes. My dockapps are: a clock (wmitime), a volume control (wmmixer), a CPU usage meter (wmcpuload), the top 3 processes by CPU usage (wmtop), a memory monitor (wmmemmon), a network traffic monitor (wmnet) and a system tray (docker). The dock is the Window Maker equivalent of applets you might place on a task bar or desktop applets in other window managers. It's compact and it fits into the look of your desktop because there are other 64x64 pixel launchers and icons on it.

  • Disable shortcuts for games. Window Maker permits me to ignore keyboard shortcuts or mouse shortcuts on a per-application basis. This provides an environment in which I can run games in windowed mode and not suffer the loss of important key/mouse combinations such as Alt+RMB.

  • The clip and app icons. These work much like the dock on Mac OS X. Your applications have a dedicated and predictable place to live. When you hide an application, it goes back there. You know where to look for it, whether you've started the application already or not.

  • Hide applications. Left click on the minimise button to hide a window. This is what most window managers let you do. In Window Maker, you can also right click on the minimise button to hide every window the application has opened. Usually the distinction isn't that important but when you're using a multi-window application such as the Gimp, it can be very handy to right click and hide all of the Gimp's windows at once, and double click its app icon to restore them all again.
I noticed that not many of my friends use Window Maker. Almost all of them use Gnome. So I thought maybe it's better. Maybe I should give it a fair trial. So I tried using Gnome. To give it a fair shot, I used it for a couple of months. I set myself the goal of configuring it so that it achieved all the things I like about Window Maker. I also sought new things that would make my life better that I could not previously do with Window Maker. I figured that Compiz 3D accelerated desktop might be good not just for glitz but for visualisation of information and productivity, too.

I found non-3D accelerated Metacity to be pretty basic out of the Ubuntu box. It really didn't satisfy me. I was unable to achieve smart window placement for example. I switched to Compiz pretty quickly so I could use its detailed customisation plugin control panel (ccsm).
  • Smart window placement. Enable the Place Windows plugin.

  • Alt+LMB Drag moves windows around. Enable the Move Window plugin.

  • Alt+RMB Drag resizes windows. Enable the Resize Window plugin. It's the middle mouse button though.

  • The dock. Well... this area is sorely lacking. There are task bar applets but they seemed very ugly, non-standard or limited to me. The system monitor applet is good for memory and CPU but I found the network traffic part of it pretty lacking compared to wmnet. wmnet shows you actual numbers (e.g. "12k/s"), uses colour to differentiate upload and download traffic, and has a logarithmic scale so you can see the small amounts of traffic and the large amounts of traffic all in a very compact area. The Gnome system monitor applet mouse over tells you that your network is "x% in use". What does that even mean? You cannot configure it to tell it what 100% means. Eventually this annoyed me enough that I discovered the gnome-swallow-applet. This baby lets me run Window Maker dock apps in Gnome. Pretty soon I had wmnet running nicely under Gnome and was happy again. Still... it'd be nice if Gnome did it right in the first place.

  • Disable shortcuts for games. I was unable to disable the Alt+RMB context menu. Using gconf-editor to edit Metacity's keyboard settings (/apps/metacity/general/mouse_button_modifier) I was able to prevent the Alt+RMB menu for all windows by binding the menu to Alt+Super+RMB instead. This had the undesirable side-effect of causing the resize window shortcut to change to Alt+Super as well. I couldn't find a perfect solution. I left them both bound to Alt+Super.

  • The clip and app icons. You can put app launchers on the task bar, but minimising a window doesn't hide it in the app launcher. Clicking the app launcher again typically starts a new instance of the application. To get back the one you already started, you have to hunt through the task bar's window list to find what you're after. The place to click to re-open a minimised application or window is not always in the same place since it orders them based on the order you started the applications. So your "finger memory" (or whatever the equivalent is for the mouse) is pretty useless.

  • Hide applications. I couldn't find a way to do this conveniently. Configuring the task bar to always group application windows together helps. Then you can right click on the group and minimise or maximise them all. Not great. I found it easier to minimise the specific window that was in my way but as a result I often had a dangling Gimp window somewhere, cluttering up things.
So that gives you an idea of some of the set backs I faced.

What were the benefits?
  • Drop shadows on windows. I still think 3D window management has the potential for greater productive and visualisation of complex desktops and tasks. It also has the potential to look really nice. I don't think that Gnome, at least the way it comes with Ubuntu, really achieves this though. I didn't especially care for the Vista-like use of translucency on window title bars. It make things look cluttered when you can see through them. I liked window drop shadows though. I thought I would use that "arrange all windows so they're smaller and without overlap temporarily, so i can select which one I want" feature that I see on Mac OS X as well. Turns out I didn't use it that much. I think sloppy focus didn't work well in conjunction with it. So I'd use it to select the window I wanted and then instantly I'd be left focusing some other window. Pretty soon I gave up on it.

  • Zoom. I like the Super+Mouse Wheel zoom plugin. It was handy for web development when you want to examine some pixels close-up and make sure they line up exactly right. But then... Window Maker provides me with wmagnify, so it's really just the convenient shortcut and usage of the zoom plugin that I prefer.

  • Nautilus. I do file browsing and management on the command line but every now and then there are things I prefer to do with a GUI file browser. Browsing through other people's Samba shares is one. I don't want to have to mount and unmount as I go. Transferring stuff to and from a USB flash drive is another. Again, auto-mount and unmount is pretty handy. Nautilus does these things really well. I like it. I even slightly prefer it to konquerer which I used until now. It looks a little cleaner and smoother (I find a lot of KDE apps look cluttered).

  • System tray. I used to keep Pidgin and Skype buddy lists minimised in Window Maker. I must admit though that the system tray is an even more compact and in many ways nicer way to manage them. The biggest benefit for me, however, was that the update-notifier application that tells you when Ubuntu package updates are available, and lets you click to install them, only works via the system tray.
I was reluctantly able to live with the set backs and even label them "differences" and enjoy the benefits. Then one day I noticed how sluggish everything was running. It was bringing my recently purchased monster gaming PC to a grind. Out of curiosity I logged in with Window Maker and everything was snappy and fast again. In fact, so snappy and fast that on that day I decided to end my Gnome trial and go back to Window Maker. The huuuuge difference in responsiveness was the trump card. Ultimately I can live with different keyboard bindings and the odd hack or workaround but taking more than a second to start a terminal will frustrate me to tears.

So I've gone back to Window Maker, and I have incorporated some of what I learned using Gnome. I have hacked away at it to put in a system tray, and Nautilus. I'm extremely happy with it now. I don't feel like I'm missing out on anything.

Given that Window Maker does not work terribly well out of the box on Ubuntu and I had to do some hacking to fill in its deficiencies, I'm going to write up a HOWTO for Window Maker on Ubuntu Hardy, for Gnome users. How to configure it, how to use it, how to understand it when coming from a Gnome world. But that's a story for another time...

Sunday, August 03, 2008

.inputrc

Every now and then I remove one of the customisations I've invented to make my life more convenient and test whether I can still get by as easily. It's a bit like anti-epileptic drugs; you have to take the patient off them every now and then to see if they still have epileptic fits.

.inputrc is not one of them. I needs it. Specifically, I need keys bound to the two best readline functions out there: history-search-forward and history-search-backward. These commands are not bound by default (man readline). They work like old 4DOS and probably several other ancient command prompts. The idea is that most of the commands you want to search for, you search via the start of the line which corresponds to the program you ran. e.g. "What was that sudo command I ran earlier?" So what you do is type 'sudo' and leave the cursor at the end of that word. Now M-p and M-n are like up and down, except they only move through the list of commands in your history that start with 'sudo'. So you can very quickly skip through all the sudo commands in your history. This works so well given Unix command line tools that I almost never need to resort to C-r. "What was that ls command?" 'ls<M-p><M-p><M-p>' "I want to re-run that Capistrano command. What was it?" Type 'cap<M-p><M-p><M-n>Enter'.

# Be quiet.
set bell-style visible

# We are using a UTF terminal.
set convert-meta on

M-n: history-search-forward
M-p: history-search-backward

Sunday, July 27, 2008

ColourfulCapLogger

My eyes find Capistrano's output pretty hard to parse. A guy named Simon Howe at work set up a colour logger at work, I extended it slightly, and I'm going to put it here to share. I find it makes Capistrano much more usable. Drop the script below in lib/capistrano/colour_logger.rb and paste this into Capfile:

Dir['lib/capistrano/*.rb'].each { |extension| load(extension) }

lib/capistrano is a place to keep other Capistrano related things that aren't recipes. I keep Capistrano monkey patches and recipe-wide extensions and helpers there too.

class ColourfulCapLogger < Capistrano::Logger

def log(level, message, line_prefix=nil, ansi='')
if level <= self.level
indent = format("%#{MAX_LEVEL}s", "*" * (MAX_LEVEL - level))
if line_prefix
line_prefix_str = " \e[1;30m[\e[0m#{line_prefix}\e[1;30m]\e[0m"
else
line_prefix_str = ''
end
message.each do |line|
device.puts "#{ansi}#{indent}#{line_prefix_str} #{ansi}#{line.strip}\e[0m\n"
end
end
end

def important(message, line_prefix=nil)
log(IMPORTANT, message, line_prefix, "\e[1;31m") # red
end

def info(message, line_prefix=nil)
log(INFO, message, line_prefix, "\e[0;32m") # green
end

def debug(message, line_prefix=nil)
case message
when /^executing \"/ # shell command
log(DEBUG, message, line_prefix, "\e[0;33m") # brown
when /^executing `/ # task
log(DEBUG, message, line_prefix, "\e[0;36m") # cyan
else
log(DEBUG, message, line_prefix) # default colour
end
end

def trace(message, line_prefix=nil)
log(TRACE, message, line_prefix) # default colour
end
end

# ColourfulCapLogger overriding the existing instance
oldlogger = @logger
@logger = ColourfulCapLogger.new(:output => $stdout) # default is $stderr which is annoying
@logger.level = oldlogger.level

Friday, June 20, 2008

.vimrc

This is my .vimrc, for my own personal reference. In fact, I may come back and update this from time to time.

Here are the important ~/.vim bits and pieces too, in the form of a listing. All these things are generally available on vim.org.

plugin/snippetsEmu.vim (and a whole bunch of language specific files)
plugin/mru.vim
plugin/AlignPlugin.vim
plugin/taglist.vim
plugin/rails.vim
plugin/surround.vim
colors/slate2.vim
scripts/closetag.vim

I have a lot of eRuby files too but I can't recall where they come from.


" Greg McIntyre

" Use Vim settings, rather then Vi settings. This must be first, because it
" changes other options as a side effect.
set nocompatible

set backspace=indent,eol,start " allow backspacing over everything
set wildmode=list:longest " bash-like tab completion
set hidden " let me open multiple unsaved buffers
set incsearch " highlight search matches as I type the search query
set nohlsearch " don't highlight the last sesarh, I find it distracting
set showmatch " parens matching (like Emacs paren blink)
set nojoinspaces " only insert one space when joining sentences
set history=100 " keep this many lines of command line history
set ruler " show the cursor position all the time
set showcmd " display incomplete commands
set noerrorbells " no error bells
set visualbell t_vb= " no beeps or blinks
set tabstop=4 " tab size (how many characters wide tabs are)
set shiftwidth=4 " general purpose indent/unindent size
set autowrite " autowrite, save the file when calling external commands
set scrolloff=1 " number of lines to show above and below the cursor
set guifont=Monospace\ 9 " gvim font
set guioptions-=T " turn off useless toolbar
set guioptions+=c " use console rather than GUI dialog boxes
set guioptions-=m " turn off the menu
set directory=~/.vim/tmp " where temporary files will go
set backupdir=~/.vim/backups " where backup files will go to die
set nobackup " turn off backups, they only ever get in my way
set noswapfile " turn off swapfiles, they're annoying
set number " show line numbers on the left

" Enable file type detection with settings for each mode and auto-indenting
" rules.
filetype plugin indent on

augroup filetypedetect
" Set some modes based on file extension
au BufNewFile,BufRead *.rb,*.rjs,*.rbw,*.gem,*.gemspec setlocal filetype=ruby
au BufNewFile,BufRead *.as setlocal filetype=actionscript
au BufNewFile,BufRead *.mxml setlocal filetype=xml
au BufNewFile,BufRead *.wiki setlocal filetype=Wikipedia
au BufNewFile,BufRead *.json setlocal nowrap sw=4 ts=4 sts=0 noet smartindent number

" Mode specific settings.
au FileType ruby setlocal et ts=2 sw=2 softtabstop=2 omnifunc=rubycomplete#Complete
au FileType eruby setlocal et ts=2 sw=2 softtabstop=2
au FileType css setlocal et ts=2 sw=2 softtabstop=2
au FileType actionscript setlocal nowrap sw=4 ts=4 sts=0 noet smartindent efm=%f(%l):\ col:\ %c\ Error:\ %m
au FileType text setlocal textwidth=78 nonumber
au FileType html,xml setlocal spell nonumber
au FileType html,xml source ~/.vim/scripts/closetag.vim
au FileType cpp,c setlocal makeprg=make
au FileType plaintex setlocal spell

" TextMate style snippets for Actionscript.
au FileType actionscript exec "Snippet for for(var <{i}>:<{uint}> = <{0}>; <{i}> <= <{array}>.length; <{i}>++){\n<{}>\n}"
au FileType actionscript exec "Snippet foreach for each(var <{name}>:<{String}> in <{collection}>){\n<{}>\n}"
au FileType actionscript exec "Snippet if if(<{}>){\n<{}>\n}"
au FileType actionscript exec "Snippet else else{\n<{}>\n}"
au FileType actionscript exec "Snippet new var <{name}>:<{Class}> = new <{Class}>(<{}>);"
au FileType actionscript exec "Snippet var var <{name}>:<{Class}>;\n<{}>"
au FileType actionscript exec "Snippet class var <{name}>:<{Class}>;\n<{}>"
au FileType actionscript exec "Snippet listener <{x}>.addEventListener(<{EventClass}>.<{eventConst}>, handle<{eventType}>, false, 0, true);\n\nfunction handle<{eventType}>(event:<{EventClass}>):void{\n<{}>\n}"
au FileType actionscript exec "Snippet package package <{name}>{\n<{}>\n}"
au FileType actionscript exec "Snippet class public class <{name}>{\npublic function <{name}>(){\n<{}>\n}\n}"
au FileType actionscript exec "Snippet function <{public}> function <{name}>():<{void}>{\n<{}>\n}"
augroup END

" Colour, syntax highlighting.
colorscheme slate2
syntax enable

" Add help searching for user installed packages.
helptags ~/.vim/doc

" Most recently used file list. Alt-R
noremap <M-r> :MRU<CR>
inoremap <M-r> <C-O>:MRU<CR>

" Show diff of current buffer. Alt-M
noremap <M-d> :!tkdiff %<CR>

" Compilation.
nmap <F9> :make<CR><CR><CR>:copen<CR><C-W><C-W>k
nmap <F10> :cnext<CR>
nmap <F11> :cprev<CR>

" Navigation. F12 opens a sidebar with hotlinks to code definitions.
nmap <F12> :TlistToggle<CR>

" I use rake more often than make.
set makeprg=rake

" Allow %/ to be put in :e lines and be expanded to the currently open file's
" directory.
cmap %/ <C-R>=expand("%:p:h")."/"<CR>

" ,e is like :e except it starts with the directory of the file currently
" being edited. Works like Emacs <C-x C-f>.
nmap ,e :e <C-R>=expand("%:p:h")."/"<CR>

" Eclipse style moving of lines - e.g. Vjjj<M-j>
imap <M-j> <Esc>:m+<CR>gi
imap <M-k> <Esc>:m-2<CR>gi
vmap <M-j> :m'>+<CR>gv
vmap <M-k> :m'<-2<CR>gv
vmap <M-h> :<<CR>gv
nmap <M-j> mz:m+<CR>`z
nmap <M-k> mz:m-2<CR>`z
vmap <M-l> :><CR>gv

" Emacs flavoured command line editing.
cnoremap <M-BS> <C-W>
cnoremap <C-A> <Home>

" Rebuild tags file
nmap <M-C> :!ctags -R .

" For putting code in blogs
let html_use_css = 1
let use_xhtml = 1
let html_number_lines = 0
function! HTML(line1, line2) range
exec (a:line1. ',' . a:line2) . 'TOhtml'
exec '0,7d'
exec '/body'
exec 'delete'
exec '/head'
exec 'delete'
exec 'delete'
"exec '14,15d'
exec '%s/<pre>/<pre class="code">/'
exec '$-1,$d'
endfunction
command! -range=% HTML :call HTML(<line1>, <line2>)