Friday, April 22, 2011

HP LaserJet Pro CP1525nw Review

I received the CP1525nw on Thursday, and it turns out this is a really great printer for GNU/Linux (which probably means the other HP network-compatible printers are good, too.)

Basically I unpacked it, plugged in Ethernet and power cables, it fetched an IP address from DHCP and displayed it on the small LCD. You can do some basic configuration through this LCD/few-button interface, but it's not worth the trouble; just note the IP address, enter it into a browser, and setup from there.

You can't setup the wireless via the LCD interface (unless you make use of this silly PIN code system which my router doesn't support anyway.)

Everything is configurable over the web interface, and by default mostly everything is enabled and unsecured. I disabled features I wouldn't use, configured the wireless, assigned a static IP, and secured the interface with a password.

Note that while you can configure the wireless it won't actually become active until the Ethernet cable is disconnected. You can't use both interfaces (Ethernet and WiFi) at the same time.

Everything went very smoothly and you don't need any proprietary software, even for setup, which is wonderful. :-)

Complaints thus far, although I haven't had the chance to use it much due to only having a few sheets of blank paper lying around, are as follows:
  • No duplex printing, although you can of course manually duplex your documents by printing even/odd pages in separate jobs.
  • Paper tray is a bit small: 150 sheets. It would be nice to have a 500 sheet tray which would accomidate an entire ream of paper.
Not big issues, and the print quality is very good, so I would recommend this printer. CUPS configuration was quick and painless, and CUPS has a built-in driver.

Saturday, April 9, 2011

Ultrasonic modem update

I did a little more digging into underwater ultrasonic digital communication. There is a publication from DTIC which looks interesting. It includes some rather boring source code, but provides a lot of good advice in the text.

Available for purchase is An Ultrasonic Sensor Based Low-Power Acoustic Modem for Underwater Communication in Underwater Wireless Sensor Networks by Heungwoo Nam and Sunshin An. It's €25 for the publication, so I'll probably purchase it (unless some anonymous person with access would email me.)

Of course, this is leading to the ultimate conclusion of setting up an EE workbench and buying a bunch of expensive equipment (solder station, oscilloscope, function generator, multimeter, etc.)

I seem to have expensive hobbies. :-( I should really spend some money on a good vacation, which I sorely need.

Thursday, April 7, 2011

Printer for Home Office...

Dear Lazyweb,

I'm currently looking for a printer for my home so that I don't have to wait until I'm at the office and use the printers there... Unfortunately it seems many laser printers (especially Canon, which Verkkokauppa are pushing to sell) either don't have Linux support, or have only proprietary drivers. What ever happened to just accepting a Postscript file?

Canon are especially nasty in that they provide a "source" package, which is really just the source code for some of the utilities, but the core library is still proprietary. Every time I see a shared object or binary inside a source package, I die a little inside...

Besides Xerox printers (very expensive) HP seem to have a couple of good options:
Both accept the following languages:
  • HP PCL 6
  • HP PCL 5c
  • HP Postscript Level 3 Emulation
According to this forum post it looks like it should work out-of-the-box with CUPS, without any proprietary drivers which is a precondition for my purchase...

Verkkokauppa have a rather silly return policy. Maybe this was inaccurate as I only asked one of their sales people, but apparently should you purchase something from their shop in person, then you do not have the option to return it (except if the product is defective.) However, should you purchase online (even to pick-up from the store) you have a 2 week return period...

I am leaning towards the CP1525nw because it seems like it will work with CUPS without proprietary crap, and the wireless network feature means I can put the printer in a walk-in closet or similar and keep it out of the way. Unfortunately it's a 1-2 week order time from the supplier.

It seems a reasonable deal for around the €200 to €300 range.

Sunday, April 3, 2011

Expression parsing and evaluation...

Something which has been annoying for me for a while was the lack of proper expression parsing in libdecl, my engine's declaration parsing library.

This library is responsible for parsing the sound and table/material declarations as defined by id Software, and making them available to the renderer (or other backend: sound engine, etc) in easy to read structures guaranteed to have sane and correct values. libdecl is the component which will complain about your syntax, the backend doesn't have to care about any of this. Really makes the code look a lot nicer. :-)

I was debating the best way to parse expressions, because they can either be very simple, or quite complicated. I realized that I could not rely on line terminators, because it's very common to see an expression span multiple lines with all kinds of tabs and white-space in the file... Of course the lexer ignores white-space, but keeps track of the line count.

After a bit of thinking about this, I decided to rip out the current shunting yard algorithm from the renderer, move it into libdecl, clean it up and rework it quite a bit. Now, it does the following:
  1. Get a token from the lexer,
  2. Check this token matches our expected rules,
    1. the token is an operator or operand, or
    2. the token is a table name. (Detected from 1st-pass.)
  3. If our checks pass, go ahead with the normal algorithm, otherwise,
  4. Push the token back to the lexer, and return the completed expression in Postfix notation.
Here's a hypothetical example that I wrote with more comments than necessary...

/* "material" keyword is optional when inside the material directory */
material textures/screenBlur
{
        sort postProcess

        /* first stage */
        {
                if glslPrograms != 0 &&
                        !isMultiplayer  /* don't blur the screen in multi-player */
                map textures/blur       /* any image format supported */
        }

        /* ... */
}

Obviously simply parsing the "if" expression until the end of the line would fail, furthermore, "if" expressions may be written as if ... or if (...), so matching on parentheses won't work either.

It turns out the easiest thing to do is first a pre-pass which only looks at tables (so that we know "foobarTable" is valid), then a secondary pass which looks at everything (sounds, tables, materials.)

In this example "glslPrograms" and "isMultiplayer" are built-in variables which the parser correctly detects as operands. Therefore we'll only stop parsing after reading the "map" token, realize it's not a valid operator or operand, push it back to the lexer, and return the expression (after some processing.)

This solution seems to be quite elegant, despite the 2-pass algorithm, and handles all the cases correctly.

The next step is to get rid of static stack allocation. Some expressions are very long, so the stack is setup for 64 elements, but this is ridiculous for "time * 0.001" (for example.)