flat assembler
Message board for the users of flat assembler.

Index > Windows > DDraw example

Author
Thread Post new topic Reply to topic
Robin



Joined: 09 Mar 2004
Posts: 3
Robin
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:

paint:
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

comcall DDSPrimary,UnlockSurface,0

comcall DDSPrimary,Flip,0,0

jmp main_loop

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'".
Post 09 Mar 2004, 14:13
View user's profile Send private message Reply with quote
bogdanontanu



Joined: 07 Jan 2004
Posts: 403
Location: Sol. Earth. Europe. Romania. Bucuresti
bogdanontanu
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."
Post 09 Mar 2004, 15:00
View user's profile Send private message Visit poster's website Reply with quote
Robin



Joined: 09 Mar 2004
Posts: 3
Robin
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:

invoke DirectDrawCreate,NULL,DDraw,NULL
or eax,eax
jnz ddraw_error

comcall DDraw,SetCooperativeLevel,\
[hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN
or eax,eax
jnz ddraw_error

comcall DDraw,SetDisplayMode,\
640,480,16
or eax,eax
jnz ddraw_error

mov [ddsd.dwSize],sizeof.DDSURFACEDESC
mov [ddsd.dwFlags],DDSD_CAPS+DDSD_BACKBUFFERCOUNT
mov [ddsd.ddsCaps.dwCaps],DDSCAPS_PRIMARYSURFACE+DDSCAPS_FLIP+DDSCAPS_COMPLEX
mov [ddsd.dwBackBufferCount],1
comcall DDraw,CreateSurface,\
ddsd,DDSPrimary,NULL
or eax,eax
jnz ddraw_error

mov [ddscaps.dwCaps],DDSCAPS_BACKBUFFER
comcall DDSPrimary,GetAttachedSurface,\
ddscaps,DDSBack
or eax,eax
jnz ddraw_error


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?
Post 09 Mar 2004, 15:20
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
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
Code:
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 Smile )
Post 09 Mar 2004, 19:15
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Robin



Joined: 09 Mar 2004
Posts: 3
Robin
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?
Post 09 Mar 2004, 21:47
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
if you are using only
Code:
  [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.
Post 10 Mar 2004, 19:09
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.