Archived

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

omegasyphon

assembly conversion for graphics

Recommended Posts

does anyone know what the following assembly code would look like in c++?
  

	lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
	// get video pointer to primary surfce

	USHORT *image_buffer = (USHORT *)ddsd.lpSurface;       
	for (int y=0;y<WHEIGHT;y++)
	{
		DWORD color = rgb16bit(0,( y >> 3),0);
		color = (color) | (color <<16);
     _asm
         {
         CLD                        ; clear direction of copy to forward
         MOV EAX, color             ; color goes here
         MOV ECX, (WWIDTH/2)  ; number of DWORDS goes here
         MOV EDI, image_buffer      ; address of line to move data
         REP STOSD                  ; send the pentium X on its way
         } // end asm

         

   	//memcpy(&image_buffer[y*ddsd.lPitch],&bitmap.buffer[y*WWIDTH*2],WWIDTH*2);

	image_buffer +=(ddsd.lPitch>>1);
	}
	if (FAILED(offsurface->Unlock(NULL)))
	return 0;
  

Share this post


Link to post
Share on other sites
Hi, sorry for the late reply.

It is just a simple copy. In an unopimized way, it would go like this:

for (int i = 0; i < WWIDTH/2; i++)
{
((DWORD *)image_buffer) = color;
}

Let me describe the asm commands to make it clearer:
CLD (forgit it... just to make forward writes..)
MOV EAX, color (loads color into EAX register, a register is some sort of variable in CPU)
MOV ECX, WWIDTH/2 (just like eax)
MOV EDI, image_buffer (like eax, ecx, but here, a pointer is loaded...)
REP STOSD (this is a complex comand, it stores the content of register EAX at the position EDI points to, then increases EDI by 4 (4 BYTES, one DWORD) and stores EAX at the new position of EDI, and does this as often as the number in ECX).
So its something like a loop which only stores DWORDS.

This assembler code should be faster then the c++ code, as it doesnt require a conditional jump (like in a loop). But if you have a good compiler, it might optimize your above loop to what is written in the assembler code (or even to something faster). There is also a C comand I think that does the same, something like zeromemory() or memcpy() or something, I dont know...

Hope this cleared it.
See you,
Chock

PS: all in all, the code does nothing more than creating a fade from black to darkgreen on a 16Bit surface by simply drawing lines with increasing green components at every 8th scanline. Nothing special so.

Share this post


Link to post
Share on other sites
well when i lock the back buffer im not sure how to use lpsurface and lpitch to copy the screen width and height to the back buffer
also does it matter if i lock the back buffer in function game_init or functio game_main?

Share this post


Link to post
Share on other sites
I don´t quite know what you mean...

Let me try to start at the beginning. The screen is stored in an array of Bytes (or words or dwords). Each Byte (word, dword) contains one Pixel. The pixels are stored topdownleftright. That means the first byte represents the topmost left pixel, the next is the pixel one to the right, if you arrived at the right part of the screen, then the next line starts.

So, the first pixel is stored at position lpSurface (it is a pointer). The pixel one to the right is at lpSurface+1. And so on.
The pixel one below is lpSurface+lpitch, if you have the pixel at position x, y, it is stored at position lpSurface[x + y*lpitch]. I hope this clears it. In your example you have 16Bit pixels. That means one pixel has two bytes. The pixels are stored 565, that means the highest 5 bits represent the amount of red color, the next 6 bits the green and the last five bits the blue color. This is what the function rgb16bit does. Well, there is no more to say about. You must lock the backbuffer as often as you want to change its content. And I don´t think you only want to change it at init, or you will get a constant picture. So you lock it whenever you want to draw. That is, every frame. Is that what you asked? If not, please explain more closely.

Share this post


Link to post
Share on other sites
ok look this is my game main function. when i run the program it starts and then quits shortly after changing the display mode.
i dont know why it does this and i cant seem to find the answer in lamoths book.


    
int Game_Main(void *parms, int num_parms)
{
// make sure this isn't executed again

if (window_closed)
return(0);

// for now test if user is hitting ESC and send WM_CLOSE

if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
} // end if

DD_INIT_STRUCT(ddsd);
lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
// get video pointer to primary surfce

DWORD *image_buffer = (DWORD *)ddsd.lpSurface;

for (int y=0;y<WHEIGHT;y++)
{
memcpy(&image_buffer[y*ddsd.lPitch],&bitmap.buffer[y*WWIDTH*2],WWIDTH*2);
image_buffer += WWIDTH;
}
if (FAILED(offsurface->Unlock(NULL)))
return 0;

drawmap();
lpddsprimary->Flip(NULL, DDFLIP_WAIT);
return 1;
} // end Game_Main




Edited by - omegasyphon on February 11, 2001 6:00:13 PM

Share this post


Link to post
Share on other sites