RSS LJ

July 28, 2004

Dev cycle ()

by fluffy at 11:34 PM
I will be really happy when the primary dev cycle is finished, because I'm getting pretty sick of 10-hour workdays.

At least I finally got my travel/hotel/etc. reimbursement today so I can actually start buying furniture.

Today I implemented the cache mechanism for loading commonly-used stuff from ROM into RAM, as well as the filesystem. There were also two meetings, one for the entire game team and one for just the developers. The developer one was particularly enlightening, as I found out how little James actually understood about the difference between programming for an embedded system and for a PC, not to mention the right way to make an abstraction layer for multiple targets. (The way he selected was okay if you have multiple targets on a single platform which has a lot of memory. We don't.)

He also showed an almost-cute naivete when it came to how the layered graphics in the DS worked. Unfortunately, it means that there's going to have to be a lot of changes in a lot of his code, because you know what? The layers and multiple screens on the DS are absolutely nothing like pooting textured quads to a single display surface in DirectX. Sorry.

Anyway, some future notes to people who want to develop apps on the DS:

  • The screen is not an ordinary framebuffer, and it has very specific rules for how layers can interact with each other and what can go into which parts of memory
  • virtual methods don't seem like they have an impact on a PC, but that's because PCs have 128MB of RAM and really fast CPUs. vtables are something to avoid on a 66MHz CPU with 4MB, especially when the vtable is being used as a stupid half-assed PImpl mechanism, which in turn is something which probably isn't necessary for what you're trying to do.
  • new and delete have real consequences. You don't want to just wrap every piece of data into a nice big object layer. Further, on the DS you have to actually implement new and delete yourself if you want to use them. (I don't know if he even realized that they're implemented as overloaded operators which usually just call malloc and free.)
  • True OO models are crap, especially when you're incurring lots of overhead just for the convenience of thinking about an image as something which knows how to display itself (by associating a lot of redundant data with it), except that it actually doesn't anyway.
  • Dynamically creating and destroying objects actually wastes more memory than using reasonably-sized tables. Every byte lost due to fragmentation is a byte lost; memory can't just be defragmented or anything. (On modern desktop OSes it kinda-sorta is thanks to the magic of paging, but game consoles don't have a swap file.)
  • Using hardware to scroll an image is way faster than repeatedly blitting it.
  • Some image compression algorithms intermix the decompression and the blitting partially to save memory, but mostly in order to speed it up. So, why the hell would you use the nice blit-accelerating image CODEC to decompress an 8k image to 48k of (precious) memory just so that you can spend about 30x as much time to put it on the screen?
  • The STL is great when you have unbounded memory. 4MB is not unbounded.
  • We're not reading our data from a disk, and no amount of begging is going to get me to implement an fopen()/fread() abstraction layer to what should be done using an iterator paradigm to begin with. There is no such thing as file I/O, and it's easier to thunk files into an array than it is to thunk an array into files.
  • Having an empty class for the purpose of a placeholder "for the sake of having a pointer to something" isn't clever, it's stupid. When I ask you to print out the API to an object class it's because I'm assuming that an object class serves a purpose. Also, don't be a prick about it. You're only allowed to be a prick after you've demonstrated that you know what you're doing.
Aside from that, though, I love this job. :D

Comments

#3216 07/28/2004 08:45 pm Heh
I find this very amusing, because when I got my 25 Mhz 486, I thought to myself "Finally a machine powerful enough to do real C++ programming on".

I'd love to see what some of the young kids today would think of the machine I spent half my career on. 4 Mb of RAM? Try 128k of RAM in a 64k address space, accessed with bank switching.
#3217 07/28/2004 08:50 pm
Hey, I got my start on a C64, and learned many things which still apply to the DS.

It's not just the amount of RAM and CPU. It's the way that the VRAM is accessed, and which parts of the hardware are allowed to do which things with which banks, and what services the operating system and standard library provide, and so on.

Also, 'powerful enough' for applications is far different than 'powerful enough' for games.

Also, if you saw the way he was using virtual methods, you'd probably be ranting too. Smile
#3218 07/28/2004 09:02 pm yeah...
I think every programmer should be required to spend a year or two with an old-school machine.

But remember, I said bank-switching...this was a device that had no memory management. No malloc. No free. All memory was either static, on the stack, or in an 8k bank that had to be manually switched in. It had no standard library...just some bastardized printf workalikes for output. Oh, and some of the banks held code, to, but since both the data and code banks had to be swapped into the same 8k address area.

Heaven help you if your code overflowed the main 40k bank, or any of the smaller banks. Yes, I have experienced days where a victory was making something ten bytes smaller.
#3219 07/28/2004 09:10 pm
Right, I was referring to your DX2/66 DX/25 comment. Smile

Also, how do you think the C128 (a system with a 16-bit address space) worked? Monkeys? Wink Though I never did any low-level developy stuff on the 128. (And it actually did have an MMU, oddly enough.)
#3220 07/28/2004 09:22 pm Oh yeah...
I forgot they had a machine that had more than 64k...
#3221 Skywise (unregistered) 07/28/2004 09:44 pm STL?!
In 4mb? Um.... uh... right. I wonder if your implementation is like ours in that it maintains its own personal heap... and once it takes memory for its own personal use, it never gives it back... it just keeps it for itself the next time.
#3222 07/28/2004 11:31 pm
I was going to ruminate on how the STL isn't supposed to be a hog, but then I remembered how the only template that saw frequent use in a program I worked on was the equivalent of vector<void *>. A game programmer friend and former coworker has described the STL as having "taken [...] the skankiest little tricks the game industry used to optimize code and built [a library] on it." and went on to suggest that the mere fact that game programmers are (at least initially) attracted to the STL indicates that there's something terribly wrong with it.
#3223 07/29/2004 02:15 am
Does James accept your corrections without a fuss or is he one of those people who assumes that his ideas are correct and you just don't "get" it, even when you've provided a full and logical explanation of why it's dumb?
#3224 07/29/2004 02:42 am
4 MB of RAM? LUXURY!
66 MHz processor? SLOTH!
Layered graphics? VANITY!

Seriously, though, with that little memory, using C++ at all sounds like a bad idea to me. Heck, dynamic memory allocation for such a simple system is stupid. Just draw up a big memory map - 0x0000 to 0x1fff is globals, 0x4000 to 0x4fff is for sound mixing, 0x5000 to 0x5fff is the sprite tables... (I'm making up the names as I go along.) Who needs malloc() when you're doing basically the same thing every time?
#3225 07/29/2004 05:27 am
Avalon: Second one.

zetawoof: Yeah. C++ is a great abstraction layer but all of my code uses static and in-stack objects all the time, aside from the ROM cache. There is absolutely no reason for him to dynamically create and destroy these objects, especially since it's basically a vector<Image *>, where Image is, in turn, just a wrapper class for the platform-specific Image type, and on the DS it'll just be another pointer and a size value. Hello, memory fragmentation! I also haven't seen precisely how gimpy his code is, but he says he only does the creation and destruction at the beginning and end of a scene — so what? That just means he's not being totally retarded.
#3226 07/29/2004 09:12 am C++
C++ makes great sense in these situations as a "better C". You just have to avoid the things that cause overhead. Like virtuals.
#3229 07/29/2004 10:15 am
fluffy
Avalon: Second one.


Have you ever had a boss who wasn't an incompetent ass? If the answer is yes, then please remove the incompetent and answer again.
#3230 07/29/2004 12:00 pm
This isn't my boss.