Note: I just updated my simpledisplay.d. My color constructor said b = c when I meant this.b = c... hence everything was yellow! You can download again from the same place.
Nick Sabalausky wrote: > I haven't benchmarked or even tested this, and heck, maybe I'm just > a dinosaur, but for better speed and flexibility I'd recommend > something more like what I've attached. Yea, that does sound better. Though I have a few comments... > The width is statically-known, so the compiler can optimize the > index calculation from multiplication to shifts when appropriate. One concern I have here is will it be an incompatible type with dynamic widths? i.e. an image loaded from a file? (I'll be hopefully cleaning up my png and bmp loaders in the near future to use with this.) Maybe it could use an interface to smooth that over. I actually had a similar fight with myself over Indexed vs TrueColor when writing the original thing. They really don't have compatible interfaces. Sure, you could do some kind of putpixel(uint data) for each of them, but it's not really the same. So I think they should be separate types, with functions to convert back and forth. (both conversions being lossy in their own way.. just because two palette entries have the same rgb values doesn't mean the two colors are semantically the same.) But, I'm getting off the point. Indexed images can be played with later. > The alpha channel opens the door for, well, mixing images using alpha. Definitely. > A major improvement, of course, would be to replace the GDI > stuff with Direct3D 7 or 8 (there's no real need to require > anything beyond those versions). Now, I don't want to get too fancy.. especially since I've never used directx, not even for hello world, and I don't think performance will be too big of a deal. But, I did do something similar with my D1 game lib. It uses SDL for most its stuff, but I found that to be dreadfully slow with anything beyond the simple, so I changed the output to use OpenGL, set up to do 2d output. Only difference client code wise was I had was I had to stop using putPixel - it was even slower! But sprite rotation and blitting, lines, shapes, all that stuff was sped up by huge, huge amounts. And I got free alpha blending and gradients! It was a huge benefit, ultimately very worth it. So yeah, I think I would like to do something similar here too, but since I have no experience with D3D it'll have to be low on my own priority list. But I like the idea! Now, the next thing I want to write up in here is some kind of event handling. The idea is: image.display(); // does what it does now - just make it work, and // wait for the user to close the window. This keeps it dead simple for a reporting use case. But, let's think about some interactivity too. In DOS, the pattern I used was something like this: // initialize the program and the screen while(still_going) { if(kbhit()) { char c = getch(); // handle c } // draw your frame wait_for_next_frame(); } // clean up My D1 game code did something similar, but the loop was replaced by a virtual class method and the wait was done by a system timer. (And something too cool: instead of checking the keyboard, it checked a joystick or keyboard, pretending it always had a Playstation controller. if(buttonWasPressed(triangle, 1)) // the 1 is player #1 // react if(buttonIsDown(square)) // react Then, if you had a controller plugged into the computer, it'd just work, or you could be boring and use the keyboard, with the keys mapped to the playstation names. One of the IMO best parts was that the controller interface was also network transparent, so any game that stuck to it could be played online too. The way that'd work is the server sends out state to everyone, random number seeds, etc. Then, all controls were lagged a frame or two. If you pressed a button, it'd transmit your action to the other players along with a timestamp. Frame 20, you hit circle. It sends down the network "on frame 22, send the event that player #2 pressed circle". Then, since everyone has the same program and the same initial state, everyone sees the same thing, without the game itself needing to know anything about the network. Of course, the lag could be slightly annoying, but meh, didn't bother me. Besides, I can't complain too much about free networking! Man, I wish I had more time to make games. Of course, there were also keyIsDown, etc, too if you couldn't use the controller interface, but it didn't get the automatic networking or different players. Wow, I'm off topic again. Anyway, for the event loop here, I'm thinking something similar to how std.concurrency does it might be a good approach: a bunch of delegates, matched to events by their signature. Simple signatures could be accepted as well as fancier ones. // need to make a simple window separately here so it is persistent auto win = new DrawableWindow(width, height); // still use an image the same way. Alternatively, DrawableWindow // could implement the same interface as Image, probably double // buffering internally anyway, so pretty much same implementation. auto image = new Image(width, height); window.eventLoop( 50, // first parameter is the timeout. can be 0 to only react // to events, but putting one in gives you an easy to use // frame pulse for drawing (int keyPressed) { // might be a struct KeyEvent rather than int // react to the key }, (int x, int y, int mouseButton) { // react to a mouse click }, () { // no params means your timeout happened, time to draw // draw your frame... image.display(win); // this overload uses the existing // window and returns immediately // rather than making and waiting } // might also offer a platform specific msg, wParam, lParam // so you could in theory do all of Win32 based on this same // framework ); This way, you could whip something up right there and have a simple little game all inside a couple dozen lines of main() without needing any monster libraries in your project. Wow, I think I really like this...