Sign in to follow this  
Ipito

RGNDATA struct

Recommended Posts

I'm a little confused about how the _RGNDATA struct works in DirectDraw (I have DX 8.0, which doesn't cover Direct Draw in the documentation). The structure is defined as: typedef struct _RGNDATA { GRNDATAHEADER rdh; // header info char Buffer[1]; // the actual RECT list } I have some example code in a book initializes the structure as follows: LPDIRECTDRAWCLIPPER DDraw_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds, int num_rects, LPRECT clip_list) { // this function creates a clipper from the sent clip list and attaches // it to the sent surface LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper LPRGNDATA region_data; // pointer to the region data that contains // the header and clip list // first create the direct draw clipper if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL))) return(NULL); // now create the clip list from the sent data // first allocate memory for region data region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT)); // now copy the rects into region data memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects); // ... if (FAILED(lpddclipper->SetClipList(region_data, 0))) { // release memory and return error free(region_data); return(NULL); } // end if I'm not very familiar with doing memory allocation the old fashioned C way, and am getting a little confused. The Buffer data member of RGNDATA is an array with a single element storage for one byte; however, the memcpy function appears to be allocating much more than that into Buffer, which I thought would cause the memory to be overrun. In my program, I only have one RECT structure, so would ideally like to allocate the whole RGNDATA struct on the stack, but I got stuck trying to do this: bool GraphicsRenderer::attachClipper() { // this function creates a clipper from the sent clip list and attaches // it to the sent surface int index; // looping var RGNDATA regionData; // pointer to the region data that contains // RECT which is the same size as the screen RECT screenRect = { 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1 }; // first create the direct draw clipper if (FAILED(_lpdd->CreateClipper(0,&_lpddclipper,NULL))) return(NULL); // now copy the rects into region data regionData.Buffer = ???; // ... I'm not sure how to allocate the RECT structure to the region data buffer. If anybody could help me out I'd be v. grateful. Thanks

Share this post


Link to post
Share on other sites
This is C code, featuring an old C hack. The class definition of "char Buffer[1];" really only indicates that there will be a "Buffer" field of the structure; in C (and in C++), arrays are not real "things" and have no idea of their actual lengths, and code is just compiled into a request to look at some particular location in memory (calculated from the location of the array beginning, and the element requested). The malloc() call allocates the memory needed for however many actual objects; thus, that memory "belongs to you" and will be written in as if the structure had specified the appropriate buffer size. What matters is the actual allocated memory, not "what you say it is"; the struct defintion is just used to calculate the offsets (i.e. to say that there is sizeof(RGNDATAHEADER) bytes of stuff at the beginning, so add that to the struct address when accessing Buffer[i]).

That said, it *is* an ugly hack :) The main reason for doing it is to avoid the overhead associated with the "normal" way of doing it, where you would put a pointer in the struct and then have that point at a separate allocation. But this sort of thing causes problems with C++ code, and even in C code - consider what happens if you want to make a _RGNDATA[] array; the compiler would trust the '1' array size when calculating how much memory is needed for the array, and in any case it would have to use *some* constant value, since the whole idea with arrays is that the size of each element is the same, known value. (That lets you find items immediately by calculating their location in memory.)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this