• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
  • entries
    51
  • comments
    129
  • views
    82329

About this blog

DirectX, Managed DirectX, OS Development. I think.

Entries in this blog

Muhammad Haggag

Damn

I hate PHP. Manual installation isn't working. The windows installer isn't working. Now I have to keep mucking with this **** until I find out why it doesn't do the God-damned job it's supposed to do, and I've wasted all my day already.

And MySQL too. Damn it. The retarded thing doesn't work out of the God-damned virtual box on a God-damned 64-bit Windows. It fails near damn silently. You have to muck around. Always.

And the God-damned MySQL Query browser is one retarded piece of uninspired goo. The son of a gun allows you to open SQL query files, typically containing HUNDREDS AND THOUSANDS of SQL statements, but allows you to execute them only ONE BY ONE. By moving your God-damned cursor over the God-damned statement line till it gets white and pressing the God-damned Execute button. And then it displays some God-damned useless one-line message in the freaking status bar so that it's near damn unreadable. And it doesn't display no God-damned progress dialogs or bars or any damn thing throughout the LONG FREAKING TIMES it takes to do any God-damned thing. I hate it.

And then you have freaking Samsung monitors that are junk and keep flickering like crazy even though they're supposed to be running at 85 damn HZ. I hate Samsung.

So yeah, DAMN.
Muhammad Haggag

VBE fun, #2

I spent the whole day working on the English glyphs. I wasn't happy with the ugly look in the previous entry, so I took a screenshot of an anti-aliased font, zoomed in, and started a pixel-by-pixel struggle of epic proportions, crafting the glyphs by hand, in C. I could've probably written a program to do it, but I sometimes like to brute-force my way through things (especially when I know it's going to take less than a day). Here's how it looks like now:



Each glyph is a 14x8 array of uint8s. Each element takes a value from 0 to 9, where 0 represents the background color and 9 represents the foreground (text) color. The renderer then converts this number to a a floating point value [0, 1] and uses it for blending. The only downside to this so far is that the glyph representations are no longer clear in the code:


[snip]
// 35 - '#'
{
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 8, 5, 4, 9, 0},
{0, 0, 0, 9, 4, 5, 8, 0},
{0, 0, 4, 8, 0, 7, 7, 0},
{4, 9, 9, 9, 9, 9, 9, 9},
{0, 0, 7, 5, 0, 9, 4, 0},
{0, 0, 9, 0, 4, 8, 0, 0},
{9, 9, 9, 9, 9, 9, 9, 5},
{0, 6, 7, 0, 8, 4, 0, 0},
{0, 7, 6, 3, 9, 3, 0, 0},
{0, 9, 4, 5, 8, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
// 36 - '$'
{
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 4, 7, 9, 9, 9, 7, 4},
{0, 8, 5, 0, 9, 0, 4, 8},
{0, 9, 4, 0, 9, 0, 0, 0},
{0, 5, 8, 7, 9, 4, 0, 0},
{0, 0, 4, 5, 9, 5, 8, 5},
{0, 0, 0, 0, 9, 0, 0, 9},
{0, 8, 4, 0, 9, 0, 5, 8},
{0, 4, 7, 9, 9, 9, 7, 4},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 0, 0, 0, 9, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
},
[/snip]



Now, I really have one thing to say before going off to sleep: Rawrrrrrrrrrrrrrrrrrrrrrrrr.
Muhammad Haggag

VBE fun

I was too tired tonight to work on anything serious (e.g. message passing), so I decided to spend some time on VBE (VGA Bios Extensions). I had already downloaded, built and installed VBE GRUB to the disk image, so all that's left was to write the actual graphics code.

VBE exposes 3 functional interfaces, one through BIOS calls (via INT 10), and 2 protected mode interfaces (VBE 2 and 3 interfaces). Unfortunately, the protected mode interfaces are:
1. Lame (e.g. no return values or status codes from VBE calls)
2. Not well-supported on graphics cards
3. Not supported by bochs

So, to properly write a VBE driver one would need to:
1. Keep switching from protected-mode to real-mode and back.
or
2. Run a v8086 task to handle all this.

#1 is obviously not a real option. #2 is possible, except that doing v8086 support isn't really a priority right now. So I just settled down on accepting whatever mode we're booted into, using the information provided by the boot-loader.

The most important info passed by the boot-loader is the linear frame buffer pointer (essentially a pointer to memory-mapped display video memory) and mode information; width, height and bpp among others. With this, I set to create a simple graphics library for bidirectional text rendering (remember: Arabic support is a top priority). And of course, I started with English, since it's much easier.

For now, we're using very basic bitmap fonts. The glyphs are stored statically in the source, until we get the file system and floppy disk drivers complete and stable enough (Don't blame me! I'm not the one working on these). This amounts to the following uber-ugliness:
	uint8 en_glyphs[127 - 32][8][10] =
{
// 32 - ' '
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},

[snip]

// 48 - '0'
{
".........",
"...###...",
"..#...#..",
".#.....#.",
".#.....#.",
".#.....#.",
"..#...#..",
"...###...",
},
// 49 - '1'
{
".........",
"...##....",
"..#.#....",
"....#....",
"....#....",
"....#....",
"....#....",
"....#....",
},
// 50 - '2'
{
".........",
"..####...",
".#....#..",
"......#..",
".....#...",
"...#.....",
"..#......",
"..#####..",
},
// 51 - '3'
{
".........",
"..###....",
".#...#...",
"......#..",
"....##...",
"......#..",
".#...#...",
"..###....",
},
// 52 - '4'
{
".........",
"....#....",
"...##....",
"..#.#....",
".#..#....",
".######..",
"....#....",
"....#....",
},
// 53 - '5'
{
".........",
"..######.",
"..#......",
"..#####..",
".......#.",
".......#.",
".#....#..",
"..####...",
},
// 54 - '6'
{
".........",
"...####..",
"..#......",
"..#......",
"..#.###..",
"..##...#.",
"..#....#.",
"...####..",
},
// 55 - '7'
{
".........",
".#######.",
"......#..",
".....#...",
"....#....",
"...#.....",
"..#......",
".#.......",
},
// 56 - '8'
{
".........",
"..#####..",
".#.....#.",
".#.....#.",
"..#####..",
".#.....#.",
".#.....#.",
"..#####..",
},
// 57 - '9'
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},

[snip]

// 65 - 'A'
{
".........",
"...##....",
"..#..#...",
"..#..#...",
".#....#..",
".######..",
"#......#.",
"#......#.",
},
// 66 - 'B'
{
".........",
".#####...",
".#....#..",
".#....#..",
".#####...",
".#....#..",
".#....#..",
".#####...",
},
// 67 - 'C'
{
".........",
".######..",
"#......#.",
"#........",
"#........",
"#........",
"#......#.",
".######..",
},
// 68 - 'D'
{
".........",
"###......",
"#..##....",
"#....#...",
"#.....#..",
"#....#...",
"#..##....",
"###......",
},
// 69 - 'E'
{
".........",
"########.",
"#........",
"#........",
"########.",
"#........",
"#........",
"########.",
},
// 70 - 'F'
{
".........",
"########.",
"#........",
"#........",
"########.",
"#........",
"#........",
"#........",
},

[snip]

// 90 - 'Z'
{
".........",
".#######.",
"......#..",
".....#...",
"....#....",
"...#.....",
"..#......",
".#######.",
},

[snip]

// 126 - '~'
{
".........",
".........",
".........",
".........",
".........",
".........",
".........",
".........",
},
};




The 'templates' are auto-generated; the comment with the ASCII code and display symbol, and the dot matrix. The generator is a small C++ program. I then fill the parts to be displayed with any non-dot non-zero symbol. As you can see, it's not complete yet - I've just worked on it until I was bored out of my skull, and then ran a simple test:



So yeah, it works, although the font looks so freaking ugly. Ideally, FreeType should be used for the fonts, but that's a bit too much into the future.
Muhammad Haggag
A long time ago, I thought installing InstallShield update manager would be a good idea. For a variety of reasons, it wasn't. I couldn't find a way to uninstall it, though. No start menu entry, no Add/Remove Programs entry, no way to do it from the application itself. In the past, I'd look for a way quickly, not find one, and then forget about it.

Today, I did a little google search on uninstalling the retarded beast. And guess what? Howto: Uninstall update manager. You need to download a freaking uninstaller that's 2.4 MBs.

Wow.

Way to go for a company whose business is the mechanics of user-friendly application installation and uninstallation.

Smacktards.
Muhammad Haggag

French, #1

So, I decided I sould revive my m4d french sk1llz. I've (lightly) studied French in school for approximately 7 years, but - unfortunately - I didn't put that knowledge to good use. The result is that I can now read and understand French if it's not heavy on the vocabulary, but I'm totally unable to write or compose anything in French. And of course, I can't decipher what native French speakers babble at all. Talk about speaking at light speed.

I'm using this WikiBook as a starting refresher. I still haven't set up a schedule for myself, but I'm aiming at writing at least two French journal entries per month. And by French journal entry, I mean something like "Je suis Egyptien". Yeah, I'm taking it easy in the beginning.

And I'm not only writing French journal entries, but I've hunted for some technology oriented French forums and am going to lurk there for a while. My initial attempts at finding such websites were rather unsuccessful. However, once I found the correct keywords, I stumbled upon this. C'est tres formidable!

Unfortunately, not all is well. I'm currently facing 2 issues:

First, being armed with not-so-powerful dictionaries might prove to be troublesome. For example, I wanted to know what the French equivalent of "Fantastic" was, expecting it to be Fantastique (The English word sounds way too French that it must've been borrowed). The dictionary suggested "endiable".

Suspicious.

Consulting a printed French-Arabic dictionary I have, "endiable" is supposed to mean "Satanic", "Diabolic" or "Very fast" (Wha?). Consulting a high-school level French-French dictionary I have (the ultimate source!), it says "Tres rapide". [dead]

If any kind french readers can drop me a link to a good online French-French or French-English dictionary, I'd be very grateful. So grateful, in fact, that I'd dedicate my next French entry entirely to praising you. Think How Washu Is Better style, except in French. And a bit short. As in a couple of lines or something. C'est une offre que tu ne peux pas refuser! (OMG, did I get that right? It took me ages to remember verb pouvoir)

Second, the French keyboard layout is rather weird. At least it is on Ubuntu linux. The 'q' and 'a' are swapped, for some reason. Numbers are now entered via Shift+Key, whereas Key inserts a character or symbol. Is this the way you guys do things normally, or am I missing something?

Anyway, issues aside, let me share with you the astounding knowledge I have gathered so far. Some essential C-related terminolgy:

& -> Esperluette. Frankly, this is way cooler than "ampersand"
* -> Asterisque. I cannot help but adore the cuteness of the way this is pronounced
\ -> Barre oblique inverse. Not cool
[ ] -> Crochets. Easy to remember. Similar to "Crotch", isn't it? Thankfully, it has different pronunciation
: -> Deux points.
; -> Point virgule.
, -> Virgule.
= -> egal. Umm..how do you write an uppercase 'e' with an accent? Is there even such a thing?
! -> Point d'exclamation.
> -> Superieur a.
< -> Inferieur a.
( ) -> Parentheses.
{ } -> Accolades.
% -> Pourcent. modulo?
# -> Diese. Je programme en C diese. Yay!
_ -> Soulignement.

That's it.

PS: What do you know, it looks like the French brain cells in me are waking up. I remembered a part of the following childish song:
Savez-vouz plantez les choux
a la mode a la mode
Savez-vous plantez les choux
a la mode de chez nous
[Don't remember the rest - but it had things to do with arms, elbows and feet I think. A search came up with it, though: here]

French word of the day
Pipi: Guess what this one means.
Example usage: J'ai envie de faire pipi.

Hint: Memorize the above statement, and you know you won't wet your pants if you ever get lost in France.

Exercise: Learn how to secure yourself against soiling your pants.


PS2: Just for Jack's sake. Du lait est superieur a du Cafe.
Muhammad Haggag

Mult-tasking

Since last Thursday, I've been debugging multi-tasking. I had kernel-space threads running fine (which is cool, by the way. Multi-threaded kernels, that is), but I could never do a successful privilege level switch (aka ring switch, from kernel-space to user-space and back). I was always getting bogus SS values when switching back from user-space to kernel-space. This SS value is retrieved from the TSS. I hex-dumped the TSS in my OS and it showed up fine. After lots of reading and re-reading of the Intel manuals, OS-dev tutorials and documents, I couldn't find out what's wrong.

I downloaded the bochs source, and began modifying it - making it print more details when the bogus SS is loaded. I found out that it's loaded with a value that's totally outside the TSS, which means it's looking at a wrong TSS. I inspected the bochs code that loads the SS from the TSS, and from that it was obvious I'd have some retarded bug with my GDT setup.

This was actually one of the very rare occasions I made use of the 'openness' of an open-source software package. Obviously it's a nice thing to have with developer-oriented tools and applications. Thank God bochs builds in under a minute. (Binutils, I'm looking at you! [grin])

Anyway, back to the bug. My TSS setup was like so:

// TSS descriptor
segment_descriptor_t& tss_descriptor = m_gdt_entries[TSS_SEGMENT_DESCRIPTOR_INDEX];
memory_set(&tss_descriptor, 0, sizeof(segment_descriptor_t));
tss_descriptor.limit_0_15 = sizeof(tss_t) - 1;
tss_descriptor.base_address_0_23 = reinterpret_cast(&tss) & 0xFFFF;
tss_descriptor.base_address_24_31= (reinterpret_cast(&tss) >> 24) & 0xFF;
tss_descriptor.segment_type = TSS_SEGMENT_TYPE;
tss_descriptor.ring = 0;
tss_descriptor.is_present = 1;
tss_descriptor.granularity = GRANULARITY_BYTE;




In case you haven't spotted it, the problem is in the base_address. The base_address is split into 2 fields; one is 24-bit wide, the other is 8-bit wide. I was taking only the first 16-bits when filling the first field [dead]. That meant the CPU was reading from a memory address that is significantly lower than the actual TSS address.

So yeah, now I have proper kernel-space to user-space switching and back. Yay!



Throughout this week, I intend to:
- Write thread synchronization objects
- Write basic process management code
- Write a basic system call interface
- Implement separate address spaces for different processes (I'm currently using a flat protected memory model where only accesses to out-of-physical-bounds memory addresses are intercepted).
- Move the keyboard and mouse drivers to user-space
- Write a better user-space test shell (I already have one running in kernel-space)

That's probably too much for one week, but who knows.

This is more of a reminder to myself:
Things that can make it into the next entry:
- Keyboards are not only evil, but retarded too
- I hate to admit it, but gVIM is better than I thought
- Window managers are unnecessarily heavy (e.g. gnome vs xfce)
- Rox filer is cool
- Linux distros still suck at usability and stability
- Color schemes: Black on lightyellow is awesome
- Automake and Autoconf...the day I understand what they're about is the day I die.
- CodeWarrior 9 for the PalmOS is torture
- PalmOS 5 is torture
- Palm devices are torture
- C++ is torture
- So is assembly
- I think I love and hate C++ templates in the same time.
- Long live the 'typename' keyword.
- Writing a correct generic linked list implementation is NOT as easy as one might think
- Testing it isn't easy either
- STLPort std::list tests are not as exhaustive as I thought. In fact, they're more like a joke. Unless I missed something.
- Backward compatibility sucks equally for hardware and software.
- Unit-testing OS components is hard.
- Automating the tests is even harder.
- Debugging OSes is hard too.
- Floppy disks are the most unreliable pieces of junk EVER.
- I bought a new chair.
- And a new keyboard.
- And a new mouse.
- Dual keyboard setups are cool.
- And so is "Little Fighters 2".
- D-Link middle-east routers and switches suck. Probably Ethernet adapters too. A combination of an ethernet adapter, switch, and router is bound to drive you crazy.
- Green tea is way cooler than red tea. Not sure how it compares to coffee, though.
- I think I just had a brain haemorrhage.
- Haemorrhage (also hemorrhage) is such an interesting word. It almost defies correct spelling.
- Must...stop...now...
Muhammad Haggag
Microsoft OneNote is becoming one of the most invaluable programs I have ever used in my life. Since I started using it, it dramatically affected the way I work, the way I surf, and, in general, the way I use my computer.

Even though it provides a lot of nice features, what really hit the sweet spot with me was the ability it gives you to write 'anywhere' on a given page. This lends itself naturally to the process of design as I conceive it. I've always preferred working with pencil and paper whenever creativity or even mere thinking was involved. I've never been able to exactly pinpoint what the main difference between pencil-and-paper and Word-Processor was, until I tried OneNote.

Freedom.

Freedom to write something at the top of the page, leave it and quickly scribble something at the top-right corner of the page, get back to what I was writing, then expanding whatever I've scribbled into a box on the same page, dragging an arrow from this box to that - that sort of thing. Typical word-processor software forces you into a limited top-down flow of words, and consequently, thoughts. And I've always hated that. And I really couldn't work around that inherent limitation, no matter how I tried.

Another fine difference is the definition of what a page is. Word-processors view pages as sequential entities - they come after each other, again, top-to-bottom - and as part of one larger entity, "The Document". Which really is not true at all during the design process, as it applies to me.

When designing, the concept of cards (for lack of a better term - I'm not specifically referring to
Class-Responsibility-Collaborator (CRC) Cards
, even though they might be part of the design process) takes over. Each page is a separate entity of its own, with its own title, and it becomes desirable to have all the pages visible at the same time. And if not possible, one should be able to switch between them quickly.

Another thing that Word-processors don't have is hierarchal organization. A project consists of a number of components. Each components may yet consist of additional sub-components. And each of these has, associated with it, a number of so-called cards. And that's not really a software-specific trait. Generalizing, anything consists of a number of component things. You can choose to break it down to its components or not depending on your desired level of abstraction - and the software program had better provide you with the ability to do just that.

Finally, all this isn't very useful if you don't have the ability to properly search these collections of pages or parts of it, in an information-hunting fashion, like a search engine.

OneNote solves all that through what I consider a very elegant design:



First, the "Projects" dropdown you see is part of a tree. A tree consisting of a number of folders, subfolders, and sections. Each section contains a number of pages. The section pages are tabbed to the right of the page, in a collapsible area. When you collapse it, only the page numbers appear, instead of their titles.

A new page is quickly created by clicking the 'New page' icon (numbered 3). You can quickly switch to other pages simply by clicking their tabs.

Whenever you click on a page, you get a writing area similar to that to the top-right. The one in the top-right has the mouse hovering it, which is why it has the additional rectangular bar on-top. You can resize any such area quickly using the arrows (numbered 2 in the picture). You can move the area around by clicking anywhere in the dotted rectangle (numbered 1) and dragging. Areas resize automatically when you type in them and when there's enough space to resize.

That enough makes it a super-cool tool for me - I now have a centralized place for my design documents, technical designs, journal posts, informative posts and notes. And I can save any of them as Word documents.

But I was pleasantly surprised when I discovered that you don't have an explicit saving mechanism. It saves everything transparently. Yes, that's the closest thing to orthogonal persistence I've seen on today's systems. Mind you, I've not tested ending the Windows session abruptly to check how much information I'd lose, but it's quite enough to me that it saves everything if you switch away or shutdown Windows normally.

So, in conclusion, give it a try. Now, let me get into what I actually started writing the entry for, before going off at a tangent and kissing OneNote's boots.

The following are snippets from my notes, written during the design and implementation phases of the DirectInput hooking component. Microsoft OneNote really shined in this part. It allowed me to easily layout the scenarios before-hand, in English, then fill in the details with the needed API calls and how they were to be used.




When developing the DirectInput hooking component - and before it, the Direct3D one - the only 'real' issue was external world communication. I needed such communication in 2 situations:

Hook application determination
It had to know the name of the application to be hooked. When writing the Direct3D hook, I went with the simple solution of using the registry, and it had worked fine. When writing the input hook, I saw no need to change the way this works.

Keyboard state control
After successfully hooking the target application, we need to be able to receive key-press commands and forward them to the target application.

Therefore, IPC.

After digging for a while in the documentation, the most simple IPC methods I found were:
. Pipes
. Mail slots
. Sockets

Named pipes were the most obvious and simple solution. So I laid out the following scenarios in an English-only pass, then filled it with API references and information in the second pass, using the MSDN documentation.




Named pipes - The server side

First, a named pipe is created by the keyboard device using CreateNamedPipe. The pipe handle is stored within the keyboard device for further use. Pipe creation parameters are:
. Name: \\.\pipe\DInput-Hook
. Open Mode: In-bound
. Pipe mode: PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE
. Max instances: 1
. Out buffer size: 0
. In buffer size: 256
. Default timeout: 200
. Security attributes: null

Whenever the hooked application retrieves the keyboard state, we peek into the pipe to see if we've got any data. A peek is done using PeekNamedPipe, as follows:
. Named pipe: Pipe handle
. Buffer: null
. Buffer size: 0
. Bytes read: 0
. Total bytes available: 0
. Bytes left in this message: messageBytes

The call retrieves the number of bytes available in the message in messageBytes.

If we've got some data, we read them via ReadFile:
. Handle: Pipe handle
. Buffer: A 256 byte buffer
. Num bytes to read: messageBytes
. Num bytes read: numBytesRead
. Overlapped: null

The message consists of a string of numbers, each number representing a scan-code.

Named pipes - The client side

The application should loop endlessly, calling WaitNamedPipe until the pipe is created - this signals the target application's launch and creation of a keyboard device.

It then connects using CreateFile:
. File name: \\.\pipe\DInput-Hook
. Access: GENERIC_WRITE
. Share mode: 0
. Security attributes: null
. Disposition: OPEN_EXISTING
. Attributes: FILE_ATTRIBUTE_NORMAL
. Template file: null

It can keep forwarding messages using WriteFile:
. Handle: Pipe handle
. Buffer: The message buffer
. Num bytes to write: Message size
. Num bytes written: numWritten
. Overlapped: null

When it's done, or an error occurs, it can go ahead and close the pipe using CloseHandle.




Using the above scenarios, I quickly laid out how I want my classes (which was really simple given how simple the scenarios are)

NamedPipeServer


Operations
. Create
. Destroy
. IsDataAvailable
. Read

Attributes
. Pipe handle

NamedPipeClient


Operations
. IsServerAvailable
. Connect
. Write
. Disconnect

Attributes
. Pipe handle




DI7


And the implementation of the above design worked almost right away, hassle-free, and life was good. Until Daphyd The Bard contacted me - he was having trouble to hook a (cool) asteroids game he's been working on. Whenever his launcher loaded the hooking DLL, VB6 would fail with a "File Not Found" error. I tested it on my PC with a VB6 application, and it worked. And when I sent the generated EXE and DLL to him, it didn't.

I had Jack "OMG-FIFTY-REPLIES-PER-SECOND" Hoxely test the same sample and it worked on his PC, promptly popping up a message box saying "LOL", which was the expected behavior. And then it hit me. Both Jack and I use Visual C++ 8, so we both have the runtime installed. And guess what C++ runtime VC8 uses by default? Yep, Multi-threaded DLL runtime. Which David didn't have.

So I switched to the static runtime and the DLL loaded successfully on his computer. But it still didn't work with his game.

After loads of experimentation, debugging and hair-pulling, I discovered that his game was written using DI7. And of course I only hooked DI8 applications.

[lol]

So, I decided to support DI7 too. Initially, I thought it was going to be a minimal amount of work - a copy-n-paste job. Hook DirectInputCreate and there you go. Unfortunately, that didn't work. And Oh God, it didn't work in so many ways.

After a bit of code revision and fiddling to make sure it's not something in my code, I decided it wasn't. The application in question wasn't calling DirectInputCreate - simple as that. So I went looking for alternative ways to create the DirectInput object, and found:
1. DirectInputCreateEx
2. CoCreateInstance

I hooked both of them. And it didn't work - the application wasn't calling them either.
So now I was back at square one. How does the application go about creating a DirectInput object without these?

Then it struck me. DirectInputCreate is actually a macro that resolves to either DirectInputCreateA or DirectInputCreateW, depending on whether the code in question is compiled with the UNICODE flag. So I quickly hooked these two too, and ran the target application.

And it still didn't work.

Another time, I revised the code, did a couple of experiments, but still couldn't get it. Then It Finally Hit Me. We hook functions by simply searching for references to their container DLLs in the EXE headers and replacing their entries in the import tables with entries of our own functions in our DLL. There's no way that's going to work when you're not directly calling the functions in questions, because then you wouldn't have them listed in your headers.

Visual Basic 6 does this. It calls into dx7vb.dll and dx8vb.dll for 7 and 8, respectively. A quick look at dx8vb.dll using the pexports utility that comes with MinGW wasn't very enlightening. The only exported function that looked promising was DllGetClassObject. I hooked that but it wasn't being called.

Unfortunately, I don't have much experience when it comes to COM and all the VB-C++ interaction. I have a couple of ideas, and I might try them out later, but for now I'll move on to something else. I'm currently at a dead-end with VB-based applications.

Not so random link

Hilarious comics by our very own 'boolean'


EDIT: Made the image a clicky.
Muhammad Haggag

MS Word hax0ring

So, today I was contemplating writing a Word-to-BB/Wiki converter; basically, a program that takes a Word document and generates BB or Wiki code that achieves the same formatting. I'm really comfortable with typing and formatting text in Word, and I've never seen something like this, save for Google's blogger plug-in. So I thought it'd be worth it to write something to fill the gap.

Initially I thought I'd have to write a VBScript that iterated through a Word document and converted things on the fly. Fortunately - thank God for Google - it turned out that there's a much easier way - using Word's .NET programmability support, we can import some COM DLLs, automatically generating .NET wrappers on the fly, and Voila!

The reference article I found is this one: Export customized XML from Microsoft Word with VB.NET.

The thing that stumped me at first was that whenever I added the reference to Microsoft Office 11.0 Object Library, it wouldn't find the Word automation DLL. It turns out that .NET programmability isn't installed by default for office components - you have to select it for each Office application manually.

With that out of the way, I thought things would proceed smoothly. Nope.

I hit the first wall when I was trying to call the function that opens a Word document for processing. Here's the generated .NET wrapper function signature:
Document Open(ref object FileName, ref object ConfirmConversions, ref object ReadOnly, ref object AddToRecentFiles, ref object PasswordDocument, ref object PasswordTemplate, ref object Revert, ref object WritePasswordDocument, ref object WritePasswordTemplate, ref object Format, ref object Encoding, ref object Visible, ref object OpenAndRepair, ref object DocumentDirection, ref object NoEncodingDialog, ref object XMLTransform);





Good stuff, huh?

First of all, all but the first parameter are optional - knew that from the documentation. That is, they have default values. However, C# does not support parameters with a default value - it opts for overloading. Unfortunately, the wrapper generated doesn't take that into consideration - i.e. it doesn't generate 15 overloads.

So now I have 2 options:
Call directly, passing all parameters
Use reflection to call the function supplying only the parameters I care for, and using default values for the rest.

The first option didn't look that bad. After all, I'm a self-proclaimed typing ninja. After half an hour of fiddling trying to get this to work, I discovered that not only am I a self-proclaimed typing ninja, but I'm R.E.T.A.R.D.E.D too.

The function takes all its parameters by reference to an object. So, say you want to pass a string for the first parameter. You can't do any of the following:

// Argument '1': cannot convert from 'string' to 'ref object'
wordApplication.Documents.Open(fileName, ...);

// Argument '1': cannot convert rom 'ref string' to 'ref object'
wordApplication.Documents.Open(ref fileName, ...);

// A ref or out argument must be an ssignable variable
wordApplication.Documents.Open(ref ((object)fileName), ...);



So, to the best of my admittedly rather shallow knowledge, you're basically left with:
object name = (object)fileName;
wordApplication.Documents.Open(ref name, ...);




Groan.

Then it struck me that there are fifteen other parameters.

Groan15.

For a single function call, out of many to-be-made function calls.

Thud.

At this point, I decided I'd give reflection a try - maybe it'd look better and be easier to maintain. At least it'd allow me to use the default values. So:

MethodInfo methodInfo = typeof(Word.Documents).GetMethod("Open");
ParameterInfo[] parameterInfo = methodInfo.GetParameters();
object[] parameters = new object[parameterInfo.Length];
parameters[0] = (object)fileName;
for (int i = 1; i < parameterInfo.Length; i++)
parameters = Type.Missing;
Word.Document document = (Word.Document)typeof(Word.Documents).InvokeMember("Open",
BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding,
null, wordApplication.Documents, parameters);





At this point, I was unsure which of the 2 methods is lamer. So I decided I'd implement the first method completely and see how they compare in lameness.

Clickety clickety click, clickety clickety click, and a while later I have this:

object falseObj = (object)false;
object trueObj = (object)true;
object nullObj = null;
object strObj = (object)"";
object formatObj = (object) Word.WdOpenFormat.wdOpenFormatAuto;
object encodingObj = (object) Microsoft.Office.Core.MsoEncoding.msoEncodingAutoDetect;
object directionObj = (object) Word.WdDocumentDirection.wdLeftToRight;

document = wordApplication.Documents.Open(ref name, ref trueObj, ref trueObj, ref falseObj, ref strObj, ref strObj, ref falseObj, ref strObj, ref strObj, ref formatObj, ref encodingObj, ref falseObj, ref falseObj, ref directionObj, ref falseObj, ref nullObj);






"Phew, done! Let's run this baby", thought Retardo. Only to get bombed to death by a type-mismatch COM Exception.

Now, all the events so far almost brought a tear to me eye. In a sad way. Sad, frustrated, and bewildered. There's no information about which parameter it is that is causing the mismatch, and there's nothing wrong as far as I can see. Let the experimentation begin!

Use integers for true and false...Nope.
Pass nullObj instead of empty string objects for all the password stuff...Nope.
Pass strObj instead of nullObj for the last parameter, XMLTransform...OMGLOL!!@@ Works!

So, basically, this parameter is a string. I didn't know that. The documentation says:
Quote:
XMLTransform
Optional Objectt. Specifies a transform to use.


Sigh.

So, now that this method works, I can move on. But now I've learnt my lesson - life is hard. Always. I've not seen the worst yet...

Armed with this honorable spirit, I proceeded with the mucking. As expected, I bumped into more issues, examples of which are:

1. When iterating through the document paragraphs, I first used a foreach loop on the Document.Paragraphs collection. The collection implements IEnumerable, so this worked fine. Later, I needed a one paragraph look-ahead, so I switched to an index-based loop. Only to be greeted by an exception. To let the BOTCHED thing speak for itself:

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in WordToWiki.exe

Additional information: The requested member of the collection does not exist.


By the requested member, it means the indexer. Fo'real, m'nizzle?

2. I rely on style names for formatting. For example, paragraphs with the style named "C#" are converted to C# source tags. To retrieve the style, I used a style property. Only to discover that it's not supported by the C# language - had to use the set_ get_ syntax instead.

Now, not all issues stem from the tools. After working on the thing for a couple of hours more - surprisingly, it was going smoother than I expected - I noticed that there's a lot of swapping going on, and that Windows has slowed down considerably. Additionally, Opera kept crashing. A quick look at the task manager revealed that I had like 30 running instances of Winword.exe, at memory consumption of 1GB+.

Oops!

I forgot to add code to close the word application instance used internally. Took me a couple of minutes to clean this mess up, then I added the code.

I struggled a bit with bold and italics after this - iterating through the document character by character takes ages. Iterating it sentence by sentence is cool, except that I get repeated sentences for some reason - I'll look into that later, God-willing. For now, I've used Word's Search/Replace functionality to do bold and italics. It works, but not neatly. For example, say you have the word "Huzzah" in bold. You'd get tags surrounding each character - i.e. the search/replace isn't greedy.

This journal entry was written in Word then converted using the alpha software. I'll release it when it's done under a non-restrictive license, God-willing - Probably ZLib or something similar.

Muhammad out.
Muhammad Haggag
For the past couple of hours, I've been reading the first 27 entries on this website. It is:
1) Absolutely hilarious
2) Quite enlightening (Get to know lots about the japanese..umm..culture)

Thanks to capn_midnight for this time sucker.

EDIT: A notable quotation...
Quote:
...Still working on Kancho Time, I let go of the two boys hands, and with my right hand guarding the front and the left for the rear, I started to manually parry the attacks. I used my eyes for the front, and relied on Kancho Sense(TM) to help me with the back. Spotting an opening, I broke the Triangle Molest Offense and managed to back myself into a corner, literally saving my ass. I now parried the frontal attacks with both hands, but I wouldn't be able to keep this up for long either.

Just out of curiousity, I looked up to see what the other teacher was doing. She calmly packed away her things at the front and casually talked with some of the girl students, seemingly oblivious to what was going on. Take a moment to think about that, if you will. In a classroom you've got a large black man cornered by three Japanese boys trying to shove fingers up his ass and grab him by the dick, while the teacher, less than 5 meters away, casually talks with the girl students about TV or something. ...That's just how it is here.
Muhammad Haggag

The n00b

Learning an entirely new programming paradigm is surely an extremely refreshing experience. I've been having lots of Prolog fun today.

We've already established that I'm an established slacker. Out of the 17 or so AI lectures we've taken so far, I've only attended the first [lol]. I'm much better when it comes to classes, though, where we actually learn something, so I've attended like 4 out of 6.

Also, I usually only "study" for university 4 times a year: before the midterms and before the finals. Given that the AI mid-term is next Sunday, I had to see what all the fuss is about, so I started reading our course notes and exploring Prolog. And man, what an enjoyable paradigm and language. It's really enlightening to explore problem solving from an entirely different perspective - I encourage you to try it out if you hadn't already.

Given the following very simple rule, "You talk about someone either if you know him or you know someone who talks about him", the exercise asks you to create a prolog representation of it for the following And/Or tree:



So I quickly came up with this:

knows(bill, jane).
knows(jane, pat).
knows(jane, fred).
knows(fred, bill).

talks_about_r(X,Y):- knows(X,Y).
talks_about_r(X,Y):- knows(X,Z), talks_about_r(Z,Y).


It recursed infinitely whenever I queried it with:
?- talks_about_r(X,Y).

Given how inexperienced I am, I couldn't figure out why except by running and tracing it. Can you?
Think about it...

...

Gave up?

Here's a sample run:

X = bill
Y = jane ;

X = jane
Y = pat ;

X = jane
Y = fred ;

X = fred
Y = bill ;

X = bill
Y = pat ;

X = bill
Y = fred ;

X = bill
Y = bill ;

X = bill
Y = jane ;

X = bill
Y = pat ;

X = bill
Y = fred ;

X = bill
Y = bill ;

X = bill
Y = jane ;

X = bill
Y = pat ;

X = bill
Y = fred ;

X = bill
Y = bill ;

X = bill
Y = jane ;

X = bill
Y = pat ;

X = bill
Y = fred ;

X = bill
Y = bill ;

X = bill
Y = jane ;

X = bill
Y = pat ;

X = bill
Y = fred ;

X = bill
Y = bill ;

X = bill
Y = jane ;


Even after taking a look at the above run, I couldn't find out what's going exactly. The derivation tree revealed what's going on:



You can see that the last derived node takes us to "talks_about(bill, Y)", which is going to be broken into 2 branches: "knows(bill, Y)" and "knows(bill, Y), talks_about_r(bill, Y)". Given that bill knows jane, the right branch takes us back to the point: "knows(bill, jane), talks_about_r(jane, Y)" and so on and on and on...[lol]

You can imagine that for a nublet like myself this thingy took quite some time to discover [grin]. I haven't really thought of a simple and elegant solution to prevent this yet, because I'm done for today - perhaps tomorrow. Until then, feel free to tell me your solution if you happen to know one.

So now I've added the 2nd thing to the list of things that bring me back to n00ber zone: Prolog (The first being leetox, of course).

Muhammad out.
Muhammad Haggag

OS Development #1

It's official. This journal's no more titled "Rarely updated". I still don't know what to name it, though, so I'll leave it at '...' temporarily. If you've got any smart suggestions that fulfill the following criteria (yes, you, Jack), feel free to drop me a message:
1.Totally uncool.
2.Totally unoriginal.

I'm basically looking for the journal title equivalent of what "Muhammad Haggag" is in terms of a user name (compared to "Coder"). Something that doesn't imply anything.

NOTE: I felt very strange writing this entry. I usually never speak up my mind, ever, let alone write about it in public. I developed this habit because of a generally high retardation coefficient in my surrounding environment, which taught me to keep my pie-hole shut the hard-way. Hopefully, better minds do exist, and they're going to expose whatever weaknesses there are in my plans to conquer teh univarse!

Now, on the to the meat of the entry. As you may already know, I'm a senior Computer Engineering student at a retarded University. When graduation project proposals were due, I proposed writing an Arabic x86 Operating System. The goals for such a project are not to produce some readily viable alternative to modern OS's (Ha!), but rather:
1) Learn what it takes to make an OS
2) Establish a framework upon which successor students can build and experiment
3) Experiment with various modern OS designs and problem solutions

While point #1 might not seem that big of a deal, it's actually quite important from a local point of view. And by local, I mean the Arab world in general, and Egypt specifically. The majority of programmers here suck, no way around it. Dang, we suck at almost everything, but that's a rather painful subject and I'd rather not open it up now. Back to software. There's no common knowledge base or human expertise in almost all software fields except Enterprise application software, and even there they moderately to genuinely suck. This has lead to a sad situation where people blindly think certain things are impossible, and don't even bother reading up on them, let alone trying creating them.

My colleagues consider writing a simple OS a monumental task. A teaching assistant even said he'd consider it a huge success if we just wrote something that booted and output a single character to the screen! That's downright humiliating. So, hopefully this will break some of the barriers people here have put around themselves.

#2 is an extension of point #1. I hope to provide a modern, micro-kernel based, modular, well-written, easy-to-understand and extend OS.

MINIX3 naturally comes to mind from the previous description, and indeed I use it for reference. My impression of it so far is that it's well-modularized, but kinda falls on the code-clarity part. Why?

C.

Antiquated C, at that.

I know some people swear by C and all, but I don't, and I don't care. I won't try to write a long justification either, because it's useless. Suffice it to say that I don't like being forced to code in a specific paradigm. Options are good.

As for the antiquation part, I mean things like this:

/*===========================================================================*
* deadlock *
*===========================================================================*/

PRIVATE int deadlock(function, cp, src_dst)
int function; /* trap number */
register struct proc *cp; /* pointer to caller */
register int src_dst; /* src or dst process */
{
/* Check for deadlock. This can happen if 'caller_ptr' and 'src_dst' have
* a cyclic dependency of blocking send and receive calls. The only cyclic
* depency that is not fatal is if the caller and target directly SEND(REC)
* and RECEIVE to each other. If a deadlock is found, the group size is
* returned. Otherwise zero is returned.
*/

register struct proc *xp; /* process pointer */
int group_size = 1; /* start with only caller */
int trap_flags;

while (src_dst != ANY) { /* check while process nr */
xp = proc_addr(src_dst); /* follow chain of processes */
group_size ++; /* extra process in group */

/* Check whether the last process in the chain has a depency. If it
* has not, the cycle cannot be closed and we are done.
*/

if (xp->p_rts_flags & RECEIVING) { /* xp has dependency */
src_dst = xp->p_getfrom; /* get xp's source */
} else if (xp->p_rts_flags & SENDING) { /* xp has dependency */
src_dst = xp->p_sendto; /* get xp's destination */
} else {
return(0); /* not a deadlock */
}

/* Now check if there is a cyclic dependency. For group sizes of two,
* a combination of SEND(REC) and RECEIVE is not fatal. Larger groups
* or other combinations indicate a deadlock.
*/

if (src_dst == proc_nr(cp)) { /* possible deadlock */
if (group_size == 2) { /* caller and src_dst */
/* The function number is magically converted to flags. */
if ((xp->p_rts_flags ^ (function << 2)) & SENDING) {
return(0); /* not a deadlock */
}
}
return(group_size); /* deadlock found */
}
}
return(0); /* not a deadlock */
}



Old-style parameter definition, pre-C99 variable definition (at beginning of scope), short header and variable names. Not my cup of tea.

Back to the goals. #3, unfortunately, is more of a "bonus" goal. It's not really a requirement given the limited time we have to create a working OS from the ground-up. I really wanted (and still want) to play with things like Orthogonal persistence, but I don't think we'll have the time to do it. I'd love to experiment with a database-powered, meta-data centered file-system. As someone said, "the possibilities are endless". Unfortunately, time isn't, as far as the faculty's concerned. However, I'm decided on continuing development after graduation. This is already my "pet" project [smile]

One of the core goals, which is kind of a subset of #3, is moving towards full Unicode support. While native English speakers might think already existing OS's do that, they don't do it uniformly or consistently, to the best of my knowledge. In Windows, shells don't support Unicode. They use lame code-pages. On *nix shells, you typically don't get Unicode support UNLESS you're running on an X variant. And even then, you don't get real support (e.g. BiDi).

Luckily, this doesn't involve much work. Building on Unicode from day 1 means you're 90% there. What we're planning to do is simply doing console mode with VBE. i.e. A graphics mode with a BiDi-aware text renderer. I've already written one before for the Palm, and it's not much of a big deal. With Arabic, that is. Rendering languages like Japenese and Chinese is out of scope for now. VBE is supported by all modern hardware, so we shouldn't be getting hardware problems.

During my recent productivity surge, I've been coding all day (Something I haven't done for months!). While most of the time I was working on the DirectX samples, I've spent quite some time on the OS. We use legacy GRUB (0.95) for booting, so we got booting (an otherwise VERY tedious process) out of the way quickly. We currently have a basic functional VGA text-mode driver, a working interrupt handling system, a working PIT (Programmable Interrupt Timer) module, and a working but not full-featured keyboard module.

I was going to write a bit about the problems encountered throughout development so far, but I'd rather do that another time, seeing how large this entry has become. I'd still love to vent off a bit by saying that keyboards are COMPLETELY RETARDED. They are THE SUCK, truly. That, and backwards compatibility is the root of all evil.

Muhammad out.
Muhammad Haggag

MS3D, CodeBlocks

Ah, been a long time since my last update. Following my last update, I got involved in 2 projects in a manner that is best described as crunch mode. During that period, I didn't really get a chance to pursue my other programming interests (e.g. Graphics programming).

About a month ago, the crunch was over. I suddenly had lots of time. Sadly, I was - and, relatively, still am - kind of burnt. I don't have the energy to pour into anything related to programming. Not as I used to.

I've tried a couple of things to get myself back on track. Developing a 100% managed milk-shape 3D model loader and renderer in managed DirectX was my first shot. The project's gone relatively well, and I enjoyed most of it, but I ran out of energy near the end. That said, I started it while in crunch mode, so my work on it can be least described as lame. Over the course of a month, I was able to put, *cough*, 10-15 hours into the thing. It currently loads and displays text ms3d files just fine. The binary loader is also 90% done. I'll release the code under a BSD license or similar license when I'm done with it, though I wonder when that's going to happen.

The second thing I tried, and with which I'm currently busy, is rejoining the CodeBlocks project as a developer. I did some minor contributions when it was first born, then backed out due to lack of time. Now that I have my time back, I checked it to find out it's gained a lot of complexity. Still, it's a fun experience. Wrestling with C++ is - as counter-productive it is sometimes compared to higher-level languages - lots of fun. [grin]

The compiler used by the CodeBlocks developers is MinGW-gcc. The first thing I'm doing is creating a VS.NET solution + projects to be able to build it with VC++ instead. This isn't as straightforward as it seems.

1. The code uses some constructs that aren't supported by VC++.NET. For example, Variadic macros, a feature that was added in C99. Luckily, this isn't that though.

2. The project is built over a plugin-based architecture. CodeBlocks exposes itself to plugins through what is called an SDK. This SDK contains the major components of the system; the code editor, the project manager, etc. The main executable project is merely a driver for these SDK components.

The problem is that the SDK is built as a DLL, for 2 reasons:
A. Each plugin needs to link to the SDK and so does the executable. Making it shared eliminates redundancy and reduces the final package size.
B. Singletonitis.

While point A is clear, point B needs a bit more clarification. We'll get to that after we describe why building the SDK as a DLL is trouble.

The SDK is composed of a multitude of classes. Exporting classes from DLLs, under Visual C++, is a pain. First, you have to mark each with __declspec(dllexport), which is easy. Second, you have to mark EVERY type that's used inside the class (as a data member) with __declspec(dllexport) as well. MinGW-gcc doesn't impose the 2nd constraint, so the developers didn't do the second step while writing CodeBlocks. And with the size of the code base, going through each and every class, tracking the types used internally and marking them is rather unpractical. (Well, more boring than unpractical, but you get the point).

So, my first reaction (back when I joined the project initially) was to simply build the SDK as a static library, not caring about the resulting size overhead of it being linked into multiple plugin DLLs. And I was greeted with a warm crash. Why? This takes us back to point B: Singletonitis.

Singletons are thoroughly (ab)used in the code-base - basically globals under cover. The editor, project manager, application configuration manager, template manager, plugin manager, macros manager, message manager, tools manager and personality manager are all singletons. They're used throughout the SDK, exe and plugin sources. When the SDK was built statically into each plugin, each plugin - being a DLL - got its own instance of the singletons. Thus, each plugin would use un-initialized managers on load/operation, promptly crashing.

The quick solution was to keep the SDK as a static library (for Visual C++ builds), and move the managers to a DLL of their own. The "Managers" DLL simply contains instances of all the singletons, and exposes accessor functions. The already-existing accessor functionality in the SDK was modified to either return directly (for MinGW-gcc builds) or delegate to the DLL (for Visual C++ builds).

Alongside that, I proposed to refactor the whole project, seeing as it wasn't clean enough or well-structured anymore. After all, it's been the work of Yiannis alone till that point, and I doubt he had planned for such a large project when he first started [smile]. Specifically, singletons made the whole project very bulky and inflexible. A single change to one of the singleton managers had diverse effects on the system, and given the hidden dependencies existing due to the use of singletons, such effects were always hard to track and contain. Given that the project back then was far from stable, Yiannis decided to first release a stable version 1.0, and then do a branch where all the refactoring can take place. I left not long after that.

Now that I'm back, it took me a while to wrap my head around these issues and get CodeBlocks to build again, especially since they've removed the VC6 solution due to being obsolete.
Muhammad Haggag
MainForm.cs:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Direct3D = Microsoft.DirectX.Direct3D;

namespace Skeleton
{
public class MainForm : System.Windows.Forms.Form
{
///
/// Clean up any resources being used.
///

protected override void Dispose( bool disposing )
{
...
}

#region Windows Form Designer generated code
...
#endregion

#region Declarations

Direct3D.Device device = null;

#endregion

public MainForm()
{
// Required for Windows Form Designer support
InitializeComponent();

Application.Idle += new EventHandler(OnApplicationIdle);
InitializeGraphics();
}

// The main entry point for the application.
[STAThread]
static void Main()
{
using(MainForm form = new MainForm())
Application.Run(form);
}

void OnApplicationIdle(object sender, EventArgs e)
{
while(IsApplicationIdle)
{
// Render a frame during idle time (no messages are waiting)
device.Clear(Direct3D.ClearFlags.ZBuffer | Direct3D.ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0, null);
device.BeginScene();

device.EndScene();
device.Present();
}
}

bool IsApplicationIdle
{
get
{
NativeMethods.Message msg;
return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}

void InitializeGraphics()
{
device = new Direct3D.Device(GetAdapter(), GetDeviceType(), GetGraphicsWindow(), GetCreateFlags(),
GetPresentParameters());
}

int GetAdapter()
{
return 0;
}

Direct3D.DeviceType GetDeviceType()
{
return Direct3D.DeviceType.Hardware;
}

System.Windows.Forms.Control GetGraphicsWindow()
{
return this;
}

Direct3D.CreateFlags GetCreateFlags()
{
return Direct3D.CreateFlags.SoftwareVertexProcessing;
}

Direct3D.PresentParameters GetPresentParameters()
{
Direct3D.PresentParameters presentParameters = new Direct3D.PresentParameters();
presentParameters.Windowed = true;
presentParameters.EnableAutoDepthStencil = true;
presentParameters.AutoDepthStencilFormat = Direct3D.DepthFormat.D16;
presentParameters.PresentationInterval = Direct3D.PresentInterval.Immediate;
presentParameters.BackBufferFormat = Direct3D.Format.Unknown;
presentParameters.SwapEffect = Direct3D.SwapEffect.Discard;

return presentParameters;
}
}
}




NativeMethods.cs:
using System;
using System.Runtime.InteropServices;

class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
public IntPtr hWnd;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}

[System.Security.SuppressUnmanagedCodeSecurity] // We won't use this maliciously
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);
}
Muhammad Haggag
Finally, I have finished my finals and college projects. It's been a pretty intense semseter - at least for the guys that attended. I, being the pro slacker that I am, have attended about 3 lectures and 4 or 5 classes throughout the semester (out of like 100 lectures and 30 classes or something). They're useless anyway, so I didn't lose much. However, I had to work a wee bit too hard starting from a week before the finals to cover all the stuff they've been teaching the whole semester. I think it worked out Ok, thank God. We'll see when the results are out [smile]

After having stopped working during the finals period (about a month), I returned at fullspeed. To my delight, I was assigned to a .NET-based project; A WinForms application. Given my relatively scarce knowledge of .NET methodology - basically, Syntax-level knowledge, not methodology - (it IS different from developing using, say, C++), I had to do a bit of reading. I found the book Introducing Microsoft .NET to be very good at - well, Duh - introducing .NET. It gives a very nice and brief overview of why they came up with it, and how to use it. The author - David Platt - is just hilarious, and gets the point across rather easily. For example, in Chapter 1, where he talks about common infrastructure problems that led to the development of .NET:
Quote:
Platt's Second Law states that the amount of crap in the universe is conserved.[1] If someone has less crap to deal with, it's because he's managed to dump his ration on someone else's head, but there's no such thing as making it disappear. If hardware and bandwidth are so much easier and cheaper to get, that means writing the software to run that environment must, by the laws of the universe, be harder and more expensive by a corresponding amount

[lol]
And if you check the footnote:
Quote:
[1] Platt's First Law is called "Exponential Estimation Explosion." It states that every software project takes three times as long as your best estimate, even if you apply this law to it.

So true...[smile]

Luckily there was a bucket-load of code in the project already, so I'm kind of learning by example too, by reading the code. My short experience with it so far, and with the VS2003 IDE, is very very enjoyable. Really, I don't find myself hitting the DirectX forum or the lounge every 5 minutes anymore (As a rule, when you see me reply a lot of times in a row, I'm developing something in php). You've got to love how C# is elegantly designed, and how superior the VS2003 Designer is. Things like this make life good!

Anyway, after having finished my first assigned task in the project, I had some free time to start planning the upcoming NeXe update. As you might have known, I released a test release of NeXe a while back. The idea was:
1) To ensure the concept was sound
2) To gather feedback from people
3) To estimate the number of dimwitted, RETARDED, mentally challenged, GOD-DAMNED, freaking stinking MORONIC psychopathic DUMBTARDS. (a.k.a spammers).

The concept is sound. The feedback was awesome (A round of applause to Jack/JollyJeffers, and Georg Rottensteiner). If you see gr4sshopper, IMPALE him for me. NeXe will need spam protection.

Now this update is more of a rebuild, actually. The current release is in classic ASP, which isn't very comfortable to me as a development platform. I've verified that the NeXe server supports ASP.NET. I'm moving to that. In fact, I'm going back to ASP.NET, because that's what I started experimenting with when I set out to revive NeXe.

I'm currently gathering, specifying and refining my requirements. I'm laying down the layout of system, how the stuff will work, what features will be available and how the users will interact with them. Hopefully, I'll be writing about these in upcoming entries and get some feedback. Which means I'll probably break the "Rarely Updated" rule.

Enough for now. If you've read so far, I'd like to say 2 things. First of all, thank you. Second thing:
Sign in to follow this  
Followers 0