Archived

This topic is now archived and is closed to further replies.

MSW

help an old DOS coder out

Recommended Posts

MSW    151
I''ve been programing sense 1981..first on Apple IIe [basic and pascal]..C-64 [basic]...and sense 1992 on the PC [basic, pascal, C, Assembler]...I''ve done some 2D games and experimented with 3D graphics programing [again only in DOS]..but I''m totaly new to OOP and Direct X...so I''m more then a bit lost anyhow I''m trying to convert some of my old games to Windows useing DX7 [just Pong and Tetris clones...just trying to help me learn this stuff]...anyhow these are in good old screen mode 13h...nothing to write home about..but I still want to use my own graphical routines to "draw" the screen [I know, I know..I should let DX do that...but I''m a control freak, and I feel that I have no control under DX ]...anyhow is there a way in C to axcess the actual pixel raster data from the DX surface...go in and run my own routines on it...then let DX blit the result to video memory?...er...I guess I should also ask if it''s possible to keep the surface in regular memory and not have DX decide to store it in video memory too [I''ve got the book "teach yourself DX7 in 24 hours"..the book doesn''t explain things well enough in this reguard]...and would doing any of this cause a conflict with DX or even Windows? Thanks

Share this post


Link to post
Share on other sites
Ironblayde    130
I'm not sure how much this is going to help since DOS mode 0x13 graphics functions functions certainly won't work unchanged under DirectX, but maybe it'll provide some answers.

First off, you can create your surfaces in system memory rather than video memory by specifying the DDSCAPS_SYSTEMMEMORY flag in the dwCaps member of the DDSCAPS2 structure, which itself is a member of the DDSURFACEDESC2 structure. Here's some code:

// initialize the structure
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

// set relevant fields of the structure
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = SOME_NUMBER;
ddsd.dwHeight = SOME_NUMBER;

// create the surface
lpdd7->CreateSurface(&ddsd, lplpdds, NULL);


This creates an offscreen surface in system memory. You can specify the same flag for the primary surface as well.

Now, to manipulate the surface's pixels directly, all you have to do is to lock the surface. This ensures that you can read the pixel data without it getting changed or moved around on you while you're doing so. To receive a surface memory pointer, you need to specify the DDLOCK_SURFACEMEMORYPTR flag when locking the surface. This goes something like this:

// initialize the structure
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

// lock the surface
lpdds->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL);


Now you've locked the entire surface, and ddsd.lpSurface is a void* that points to the surface memory. The other field you'll want to watch out for is ddsd.lPitch, which is the number of bytes per horizontal line on the surface. Some video cards use more bytes than are required for the surface pixels themselves, so you have to be careful of this. Your book should explain this. If it doesn't... well, then it sucks!

Once you're done messing around with the surface memory, you have to unlock it before you can use the blitter on it. This is done via the Unlock method:

lpdds->Unlock(NULL);

Remember these few things and you should be able to do just about anything with your own routines. One other thing... if you're going to be doing a lot of manual pixel manipulation, be sure to create your surfaces in system memory. Reading from and writing to system memory in this way is several times faster than having to do it with the memory out on the video card.

Good luck!

-Ironblayde
 Aeon Software

The following sentence is true.
The preceding sentence is false.


Edited by - Ironblayde on November 4, 2000 3:25:17 AM

Share this post


Link to post
Share on other sites
Succinct    169
I was right there, too, buddy, albeit i didn''t have mode 0x13 in my blood since eighty-fricking-one! just since like 95 or so..

anyway, here''s how I made my change. the easiest way is to just do everything the same way you do, minus the 13h setup stuff, and then texture map your final VRAM pixture on an orthogonal quad. in other words, just draw your picture in vram, paste it to a rectangle, and then display the rectangle centered on the screen. i''m not sure how to do it in dx, but if you want some info on ogl, you can e-me at furtoman@mailroom.com.

also, if you''re really interested in the whole dos/13h to win32 conversion, you should read a book by one of the forerunners of the pro-dos32/anti-win32 movement. Andre LaMotha wrote tricks of the game-programming gurus back in the day, and he''s recently come out w/ tricks of the -Windows- game programming gurus. he''s really a proponent of good old real mode programming, and he hates windows as much as me (that''s hard). his book shows you how to isolate the windows code in a way you don''t even have to look at it. very nifty stuff, and it''s targeted for dx, too.
have i look, i definitely recommend it.

I have no name that you may call me. I am Succinct, so call me as such.

Share this post


Link to post
Share on other sites
furby100    102
To actually set mode 13h rather than Mode X (which will be used as default) you need to call IDirectDraw7::SetDisplayMode like this:
  
LPDIRECTDRAW7 lpdd; // this is the DirectDraw object you created at the

// beginning of the program, I just put it here to tell you what it is that I am

// using to call the function.


// this is how you set mode 13h:

lpdd->SetDisplayMode(320, 200, 8, 0, DDSDM_STANDARDVGAMODE);

It is vital that you use DDSDM_STANDARDVGAMODE, otherwise it will use ModeX instead of Mode 13h. Also, if you use Mode 13h, using page flipping will be simulated, which slows page flipping to three memory copies and the creation of a temporary buffer, it is better to create a backbuffer in system memory and Blt that to the primary buffer every frame.



Please state the nature of the debugging emergency.


sharewaregames.20m.com

Share this post


Link to post
Share on other sites