Message board for the users of flat assembler.
> Windows > DDraw example
Hi! I'm new to both fasm and assembly(and ddraw really).
I wanted to get down and dirty so I took the ddraw example and stripped it of everyting but the skeleton windows and ddraw code, and it works.(except the screen is flashing instead of just black; is this normal?)
I really just want a framebuffer to play with so I tried to edit the paint section like this:
comcall DDSPrimary,LockSurface,0,ddsd,DDLOCK_WAIT or DDLOCK_SURFACEMEMORYPTR, 0
mov eax, ddsd.lpSurface
mov [buffer], eax
mov [buffer+10*640+10], 0FFFFh ; changed to 16-bit colour
Unfortunately this halts the program. It hangs for a couple of seconds and then terminates. I've done almost the exact same thing in C(I'm pretty sure) and it worked.
By the way is this example set up for fast access to the framebuffer, or is it just fast with BitBlt? How else to do it, if it's not suitable? I know in SDL it's best to set up a software surface, but I don't know how to in ddraw..
Edit: Hmm I realize that it should probably be "mov buffer, eax" shouldn't it? But that generates an "invalid operand" error. buffer is defined like this: "buffer dd ?", under "section '.bss'".
|09 Mar 2004, 14:13||
C hides a LOT from the normal structure of an application, sometimes hides even more from a directdraw application. Some things are done behind the scene in C/C++ ... so first concentrate on getting a fully functional win32 application with Directdraw initializations and clean-up.
How are you drawing (main loop) on PeekMessage ? or on WM_PAINT?
Also you have to ::UNLOCK as soon as possible after a ::LOCK... or else other functions like ::Flip will fail .
Is your Primary setup as 16bits 5-6-5?
Are you in exclusive mode (because you can NOT use ::FLIP otherwise)
Also thake care to LPitch member returned after :Lock.
Especially for video located surfaces you CAN NOT assume surface_width==lPitch and when indexing on Y you must use the lPitch and NOT the desired width ...yes they might be the same on some video modes/boards but they are surely different on many...
Any access outside of surfaces limits can have very weird results, sometimes requiering a restart of OS to clear
::Blt method on video surfaces is much more faster than direct access esp for Primary. 1000x faster as it uses the hardware blitter usually...
CPU driven WRITES ONLY to Primary and other video surfaces are DECENT in speed...
NEVER READ from primary and/or any other video memory located surfaces! It is 1000x slow!
You can (sometimes) with well written ASM code outperform Directdraw when doing operations on system memory located surfaces... esp for transparency (color keying) and shadow/blending ... but remember ONLY in system memory...
"Any intelligent fool can make things bigger,
more complex, and more violent.
It takes a touch of genius -- and a lot of courage --
to move in the opposite direction."
|09 Mar 2004, 15:00||
I took the example program that came with fasm, and stripped all image loading/blitting, plus changed from 8 bit to 16.
I guess I'll use 5-6-5 but the ddraw doesnt have to know anything beyond the fact that I'm using 16-bit..?
I know Blt to video surface is much faster than direct access to surfaces, but I wanted to try to make a simple triangle rasterizer. I've done one before in C, but the speed wasn't good enough.
paint is called from the main loop each frame.
Here is the code used to set up DDraw:
As you can see it's in exclusive mode, and it should all be okay there(since I didn't touch anything exept the bits per pixel parameter). I think the problem lies in the code I posted first.
But is this the right way to set up DDraw for direct surface access, such as would be needed for a software rasterizer?
|09 Mar 2004, 15:20||
not bugfix but little note: i think you wanted pixel on [10,10]. In that case you have to address [2*10*640 + 10].
Ha, now i see it (i think). What is 'buffer', yours pointer? If it's pointer then you shouldn't use '[buffer + 2*10*640 + 10]', but something like
mov eax,[buffer] mov [eax + 2*10*640 + 10]
By the way, always await cruel hang on every bug when primary surface is locked, this is quite extreme case. Under XP when it hits GPF or int3 it just exits application without any warning or whatever (but still better than crash )
|09 Mar 2004, 19:15||
Thank you very much! That worked.
Actually it should be "mov [eax + 2*10*640 + 2*10], pixel" shouldn't it?
This of course is much better done with bit shifts?
|09 Mar 2004, 21:47||
if you are using only
[eax + 2*640*10 + 2*10]
then it is better this way, because value of constant expression is evaluated by assembler. But in something real, like plotting at [eax,ebx] it is of course faster with shifts.
But there is another problem i forgot. Not 2*10*640 but 2*10*surfacedesc.lPitch. X size of buffer in memory is in lPitch member of surface description, and isn't always same as X resolution.
|10 Mar 2004, 19:09||
< Last Thread | Next Thread >
Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.