3

I have WinQuake.exe game file which I compiled myself from source.

In software mode (without DirectX/OpenGL), what function is used to access video memory?

I know, for example, the DrawDibDraw WinAPI function; but I didn't find it in the code.

7
  • 4
    Guess: direct video RAM access for speed. But since you compiled it from source, why don't you edit your question and put in a link to the source, so we can look?
    – dirkt
    CommentedMay 4, 2024 at 6:43
  • There is too much code to post here, and I did not find the place where direct access to video memory is used. But what if the file is called WinQuake.exe, and that is, used under Windows, and how can direct access to video memory be used under Windows?CommentedMay 4, 2024 at 8:53
  • Run it under a profiler and see where the CPU spends its time.CommentedMay 4, 2024 at 12:47
  • You can see fabiensanglard.net/quakeSource/quakeSourceRendition.php for some looks at rendering in quakeCommentedMay 5, 2024 at 4:37
  • 1
    Guess what it might be and then giving up because you can't validate that particular answer is not a particularly fruitful way to understand someone else's code. And unfortunately, understanding someone else's code is often a large part of programming,
    – dave
    CommentedMay 5, 2024 at 17:05

1 Answer 1

16

When running in software mode, Quake uses SciTech's MGL.

The screen buffer is locked using VID_LockBuffer which calls MGL_beginDirectAccess:

void VID_LockBuffer (void) { ... MGL_beginDirectAccess(); if (memdc) { // Update surface pointer for linear access modes vid.buffer = vid.conbuffer = vid.direct = memdc->surface; vid.rowbytes = vid.conrowbytes = memdc->mi.bytesPerLine; } else if (mgldc) { // Update surface pointer for linear access modes vid.buffer = vid.conbuffer = vid.direct = mgldc->surface; vid.rowbytes = vid.conrowbytes = mgldc->mi.bytesPerLine; } ... } 

Screen state is then available through variable vid:

viddef_t vid; // global video state 

Whose definition is in vid.h:

typedef struct { pixel_t *buffer; // invisible buffer pixel_t *colormap; // 256 * VID_GRADES size unsigned short *colormap16; // 256 * VID_GRADES size int fullbright; // index of first fullbright color unsigned rowbytes; // may be > width if displayed in a window unsigned width; unsigned height; float aspect; // width / height -- < 0 is taller than wide int numpages; int recalc_refdef; // if true, recalc vid-based stuff pixel_t *conbuffer; int conrowbytes; unsigned conwidth; unsigned conheight; int maxwarpwidth; int maxwarpheight; pixel_t *direct; // direct drawing to framebuffer, if not // NULL } viddef_t; 

For instance, the update screen method SCR_UpdateScreen:

void SCR_UpdateScreen (void) { ... D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time VID_LockBuffer (); V_RenderView (); VID_UnlockBuffer (); D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly if (scr_drawdialog) { Sbar_Draw (); Draw_FadeScreen (); SCR_DrawNotifyString (); scr_copyeverything = true; } ... D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time ... } 

If you dig deeper in the above, you will realize that:

3
  • I looked in code and found MGLDC *mgldc = NULL,*memdc = NULL but what is the difference between memdc and mgldc?CommentedMay 5, 2024 at 12:53
  • 3
    @black4 from the names, one would guess memdc is the device context for a regular in-memory back buffer, mgldc is one that’s supposed to go through an OpenGL pipeline.
    – Tommy
    CommentedMay 5, 2024 at 18:57
  • 1
    @black4 memdc allows blitting from a memory buffer: github.com/id-Software/Quake/blob/…
    – aybe
    CommentedMay 6, 2024 at 1:18

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.