Usually I don't mind HTML one bit, but posting the code bits today made me realize something: HTML sucks
for pre-indented text. Apparently there are only three options
for white-space preservation in HTML/CSS: pre
- This value directs user agents to collapse sequences
of whitespace, and break lines as necessary to fill line boxes.
Additional line breaks may be created by occurrences of "\A" in
generated content (e.g., for the BR element in HTML).
- This value prevents user agents from collapsing sequences
of whitespace. Lines are only broken at newlines in the source, or
at occurrences of "\A" in generated content.
- This value collapses whitespace as for 'normal', but suppresses
line breaks within text except for those created by "\A" in generated
content (e.g., for the BR element in HTML).
normal certainly isn't appropriate, because that would not preserve the indentation. pre is almost appropriate, however it disallowes the rendering engine to insert line-breaks, which means the div section the code is in may extend in width arbitrarily. nowrap is obviously inappropriate as well.
What I really need is something close to pre but which allows automatic line-breaks; problem is, to my knowledge there simply isn't anything of the sort!
If anyone has some good advice on how to add indented, syntax-highlit code blocks to my blog painlessly I would be much obliged. I know there are tools out there - I've tried one or two - but none gave me the sort of flexibility I require. I may just break up and write a parser/colorizer with a bit more customizability than what Drazen did (impressive though it is).
I was reading through a bunch of documents I had lying around, and
found one that might be of interest to developers out there. A team in
a previous workplace encountered a strange issue: they were trying to
authenticate against a Windows domain (Active Directory-based domain
server) using ADSI via .NET's System.DirectoryServices, and in some
cases (particular users and particular machines) their login code would
bomb with a "Domain Not Found" error or somesuch.
Turns out they were trying to bind to ldap://domain_name, where domain name was programmatically derived from System.Environment.UserDomainName;
in some cases said property would return, instead of the logged on
user's domain name, the local computer name. Thing is, you would expect
a property in System.Environment to return the value of an evironment variable, presumably USERDOMAIN, which we verified contained the appropriate value.
Digging around in the documentation didn't help, so I turned to ye olde Reflector:
public static string get_UserDomainName()
new EnvironmentPermission(1, "UserDomainName").Demand();
array1 = new byte;
num1 = array1.Length;
builder1 = new StringBuilder(1024);
num2 = builder1.Capacity;
flag1 = Win32Native.LookupAccountName
(null, Environment.UserName, array1, &(num1), builder1, &(num2), &(num3));
num4 = Marshal.GetLastWin32Error();
if (num4 == 120)
throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_Win9x"));
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UserDomainName"));
Note the function call in bold; a quick look in MSDN revealed the following information:
- [in] Pointer to a null-terminated character string that specifies the
name of the system. This string can be the name of a remote computer.
If this string is NULL, the account name translation
begins on the local system. If the name cannot be resolved on the local
system, this function will try to resolve the name using domain controllers
trusted by the local system. Generally, specify a value for
lpSystemName only when the account is in an untrusted domain and the
name of a computer in that domain is known.
- [in] Pointer to a null-terminated string that specifies the account
Use a fully qualified string in the domain_name\user_name format to
ensure that LookupAccountName finds the account in the desired
Note the part marked in red: Environment.UserDomainName does indeed pass null for lpSystemName,
so if the machine contains a local user by the same name as the domain
user, the local machine name will be returned instead of the domain.
This behavior is apparently by design, although I can't figure out how that makes any sense what-so-ever.
There are two easy ways to avoid this issue:
string userDomain = Environment.GetEnvironmentVariable( "USERDOMAIN" );
string userDomain = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split( @'\' )[ 0 ];
I was reading some API documentation and came upon the following sentence: "... and is necessary to successfully login... before envoquing
the other components.".
Damned if I know why, but the GTK+ installation that comes with the Win32 version of GAIM
doesn't handle Hebrew properly (mismatched parentheses, problematic handling of hyphens etc.). I've already mentioned that installing the Glade compilation of GTK+
solves the issue, however I attributed it to a particular broken version of the GAIM installer, which seems not to be the case. I should probably file a bug report about this.
Senthil Kumar found out another interesting bit
of C# trivia: apparently C# does not do compile-time type safetly checks for interface casts! C# is usually very strict in the kind of stuff it allows you to do (unless you use object
s all the time, in which case you deserve to die anyway). This has to be one of the very few cases I've found C++ (as a language) to be superiour to C# - I prefer simplicity and strictness, and while C# certainly provides the former, C++ evidently provides better compile-time checks.
We need to be
able to plan food quantities etc., so it's imperative that we know
who/how many are coming. If you haven't already, please send in
confirmation (preferably along with contact information for yourself
and sceners you know). Also, we still haven't been able to get a hold
of a video projector, so if you can help let us know!
After the flash success of June's IGDA/demo-scene gathering,
we've decided to, er, implement our own: a proper demo-scene gathering,
complete with BBQ, showing of new as well as old demos, and whatever
the hell else we feel like doing! So, without further ado:
Thursday, July 28th 2005 at 20:00, give or take. Being late only means you get to spend less time here
The psuedo-demoparty will be held on the lawn outside Monfort Software
building in Kibbutz Sa'ar. The kibbutz is located just north of
Nahariya and here's how to get here:
- Driving here is easy, though I suggest you use eMap or Walla Maps
for reference: basically just get to Acco junction (the northest
section of road 4), proceed north to Nahariya junction, proceed north
still until you're just north of Nahariya - there'll be a "Sa'ar"
signpost where you turn right to enter the kibbutz. Immediately after
the gate turn left and you'll arrive at a fork; take the right road,
proceed until you see a basketball court on your right. Turn right
immediately after it, right again - we're the second building (the one
with the parking lot). If you have any trouble or need more detailed
instructions get in touch.
- Take a train or bus to Nahariya (the central bus station is located
50 meters from the train station); take bus number 3, 24, 27 or any
number of other busses and just ask the driver to drop you off near
Sa'ar. It's an 8-minute walk from the bus station.
Well we hope most of the oldsk00l demosceners in Israel will show up,
but obviously aspiring Israeli sceners and visiting sceners from abroad
are welcome too! Just get in touch and let us know you're coming so we
can have enough food and drink ready.
The main event is a big-ass BBQ for everyone, cold drinks and beer:
this is a mostly social gathering. However we will have a retromachine
available to play classic demos (P166, 64mb, Tseng E6000/ATi Rage II,
SB AWE64 Gold + GUS GF1 1mb) as well as a copy of the MindCandy demo DVD;
we'll probably have a decent machine to run newer demos on as well. If
anyone intends to make a demo, go for it - it'll definitely be shown!
Other than that, just let us know what you think is good. There are
terrific beaches minutes away from the partyplace; we can have classic
cola-drinking, diskette/disc/hard-drive tossing competitions etc. If
you have any ideas let us know!
We have most of the basics (including food, audio system, demo machine
and general organization covered). We could really use your help in the
- We are in need of a projector. Do you have, or know someone who has, a projector we can have on loan for a couple of days?
- Help us spread the word! Send us any contact information you have
for past and present Israeli sceners, and forward the invite to sceners
you have contact with.
- We're collecting Israeli scene media: pictures, videos,
productions and any other relevant material. All that stuff will be
inserted into an Israeli demo-scene wiki, so if you have anything make
sure to send it out way!
- Good ideas are absolutely welcome!
If any of this applies to you, make sure to get in touch
as soon as possible!
The event is hosted and sponsored by Monfort Software Ltd.
which is where us organizers work; consider this a shameless plug:
we're looking for great programmers to join our team! Want to work in a
dynamic environment with a bunch of other demosceners? Want to work on
realtime 3D engines, .NET applications ranging from enterprise systems
to compilers to a huge variety of software products? Come have a look.
You can contact us in one of many ways. Being the primary contact you can just use my contact page
, or call me directly (0x209E1F5A). If needs be feel free to contact Scroll Lock (0x207994A4, 0x1F38899A). Can't read hex?
The following sceners have confirmed their attendance: Scroll-Lock,
Crunch, MMX, Thalja, Jonny (YOE); Kombat, Rage (Immortals); Dark Spirit
(TTOM); Civax (Moon
Hunters); Borzom, Sticky Baboon (Tatoo); Holograph, Protopad, Vandal
(Pulse, BSP); Nyarlothotep (Kult); Silvatar, Diffuse (Flood); Fizz,
TheMage, Mutant, Blutz. Nyc
Kid (Moon Hunters) will probably be there as well.
Thinking of coming? Let us know!
Been busy doing absolutely nothing of value over the last few days including, but not limited, to: going to the kinneret
for a Saturday afternoon, watching Batman Begins
(seperate post on that later), finishing Half Life 2
again (review coming up), going to a pub, watching Who Framed Roger Rabbit
and almost finishing King Rat
(will probably blog a bit on that at a later date too).
I also blogged practically nothing interesting/useful for the past
couple of weeks, so here's a collection of stuff I have in my "context"
file (sort of a geek's to-do list):
- Apparently I've managed to thoroughly miss the whole Annoying Thing revolution; I've always known the source to be DengDeng but apparently it's evolved and is now officially out of control. Here's an interesting read.
- If you have any inclination towards industrial and/or goth music, check out In Strict Confidence.
Of particular note are Zauberschloss and Engelsstaub (in German) and
the terrific Love Will Never Be The Same (English). I've also given
good listening time to Massive Attack's Mezzanine. On the web radio front I still listen to a lot of Nectarine radio.
- RMS has another thought-provoking artlce
about software patents. RMS's usually extremist opnions aside, I'm
finding what I see around me less and less to my taste, and as a
software developer for a relatively small company I occasionally feel
the results of software patents on my flesh, and it scares me. Patents
are a necessary evil, but leglislators must be extremely careful in
maintaining the balance between protecting innovators and stiffling
innovation. I'll probably write a proper post about this soon.
- Get your own, before they run out!
- Ever had trouble remembering what a toilet in a particular computer game looks like? This site should alleviate your concerns.
- These are really cool. Too bad they probably sound like crap.
- Ho-lee shit.
- Evidently the Israeli customs office does not believe in free software (Hebrew only). Fortunately the story ends happily.
And here are some development-related tidbits:
- A couple of interesting articles on the BCL team blog: this one elaborates on which language features cannot be expressed using CodeDOM (including .NET 2.0), and this one
explains why parsers aren't included with CodeDOM (which would've saved
me a hell of a lot of time on the C# to java source-level compiler I
wrote a few months ago).
- BCL team's libcheck is an immensely useful tool if your team provides public APIs to other teams or customers (via Roy Osherove's ISerializable).
- Balanced matching with regular expressions: apparently the .NET regex implementation allows you to create
"stack"-style expressions (so you can parse, for example, mathematical
expressions with parentheses, C-style comments etc.). The syntax is
somewhat convoluted and tricky to use though (via Roy Osherove's ISerializable).
- I've been asked how to create windows services in .NET on numerous occasions; it is, in fact, incredibly easy. Enter another great post from the BCL team, which will hopefully save me some hours of repeating the same explanations. Thanks, Dave!
- These seem like incredibly useful tools, though (seeing that my
development focus has changed over the last few months) I haven't yet
been able to try out: ComTrace hooks the COM system calls and gives you a filtered view, which is definitely handy for debugging COM issues. Conversely, the PINVOKE.NET add-in is a front-end for the PINVOKE.NET wiki - a respository for unmanaged API P/Invoke signatures and best practices.
- I always thought overhyped, powerful language features can be dangerous in the hands of the uninspired, but this is just ridiculous (thanks, Kuperstein).
If you ever find the need to contact me, here are a few options (prioritized, first is best):
- Send me an e-mail - make sure to change the at/dot text to the appropriate characters
- MSN Messenger alias tomer at tomergabel dot com (same comment applies)
- Leave me a comment on this blogpost
dasBlog's been behaving oddly today. First I find that I have an empty
category (that is, a category with a blank name). Turns out that
dasBlog caches the categories from its content XML files, but has no
category deletion/rename tool (this tool
can only rename categories and is not part of the project itself). I
had to download the files, look up the offending category manually
(another would-be bug: the category list in the XML was personal;music;"
- note the trailing semicolon) and fix it, then touch the config file
to get the site to reload and recache the categories. If I find the
time I'll add this to the source.
The second issue is that my "contact me" entry has disappeared from
the blog entirely, and somehow the links were replaced with links to
another entry. *scratches head* Guess I'll have to rewrite that post...
The vector engine saga
One of the features required by the host application is for the vector engine to create a snapshot of the viewport at a given size. The current API implementation returns an HBITMAP for use by the client app and uses GDI (through MFC) for rendering the viewport. This in itself was OK, but since the viewport size is declared by the host application and the background for the vector engine is usually a bitmap the rendering engine copies the bitmap onto the viewpoint via GDI, which means the bitmap gets rescaled by GDI. This is a big nono because GDI rescaling is both horribly slow and looks like crap (na?ve rescaling, no nearest-neighbor or bicubic).
Bottom line, I had to rewrite the background rendering to utilize DirectDraw; luckily I've already done this for the actual rendering routines in the engine, and the snapshot generation uses that code. I just had to create a DirectDraw off-screen surface, render to its DC instead of the current compatible DC created from the screen surface, create a bitmap from the off-screen surface and return it.
It took very little time to write the rendering code (particularly after finding a couple of tutorials), but the copied bitmap wouldn't save properly; the resulting BMP file had a black rectangle instead of the rendered image, and when I tried to copy the bitmap to the clipboard I couldn't display it (got a "can't copy data from clipboard" error message from mspaint, and clipbrd wouldn't display anything). It took an additional several hours of beating around the proverbial GDI bush to find a solution, and I still can't figure out why it works:
- Create a DirectDraw surface
- Render image
- Create a compatible DC for the surface (bmpDC)
- Create a compatible bitmap for the surface
- Select the compatible bitmap into bmpDC
- Blit the surface DC onto bmpDC
- Here comes the cinch: call ::GetDIBits to fill a BITMAPINFO structure, then to get the bitmap bits (note: make sure to negate the bitmap height, or you'll get an inverted bitmap)
- Delete the original bitmap
- Recreate the bitmap using ::CreateBitmap with the info from the previous step
- Clean up
- Return the newly created bitmap
What really baffles me is that what I'm doing is effectively creating a device-dependant bitmap (DDB) out of the previously created compatible DDB. If that is the case, why is the newly created bitmap functional (that is, I can save from it and copy it to the clipboard properly)? Why was the original bitmap behavior different? And why, when I tried to ::CreateDIBitmap instead, I consistently got an error where the documentation specifically states the only possibly error is an invalid parameter (there were none that I could find)?
I'm completely baffled by this; the solution outlined above is (aside from being ugly) not supposed to work. Has anyone any idea?