Calculating memory address
1: void __fastcall fastpixel(long* surface)
2: {
3: int iCount = 1152*864;
4: __asm
5: {
6: // Assign pointers to register
7: push edi;
8: push ecx;
9: push eax;
10: mov edi, [surface] ; //put dest addr to edi reg
11: mov ecx, [iCount] ;// put count to ecx reg
12:
13: codeloop:
14: mov eax, [edi] ; //mov a byte of src data to low
15: xor eax, 0x00ffffff ;
16: mov [edi], eax ;
17: add edi,4;
18: dec ecx ; //decrement count by 1
19: jnz codeloop ; //jump to codeloop if not 0
20: pop edi;
21: pop ecx;
22: pop eax;
23: }
24: }
Ok so I've got this lovely bit of code that I've constructed and I need a few clerifications:
in theory I should have been able to replace lines 14 to 16 with this:
first:
xor [edi], 0x00FFFFFF
how ever this just turns my screen blue :\
second:
I seem to need to use add edi,4 instead of just inc because inc only seems to move it 1 byte forward, is there a way to fix this?
third:
This is in the help docs for MASM32 but I have no clue what idex, scale, and displacement are reffering to.
[ Base Address + Index * Scale + Displacement ]
[ebx + ecx * 4 + 8]
ebx is the base address.
ecx is the index.
4 is the scale based on the data size.
8 is the displacement in BYTES.
[1517 byte] By [
barrensoul] at [2007-11-19 7:33:02]

# 7 Re: Calculating memory address
#include <windows.h>
#include <ddraw.h>
HINSTANCE ghinst = 0;
HDC hdc;
HWND mainwindow = 0;
static DDSCAPS ddscaps;
static LPDIRECTDRAW lpDD = 0;
static LPDIRECTDRAWSURFACE lpDDSPrimary;
static LPDIRECTDRAWSURFACE lpDDSBack;
static DDSURFACEDESC ddsd;
static PAINTSTRUCT ps;
static HDC whdc;
static DDSURFACEDESC DDSurfDesc;
static BYTE on_off[999364];
static BYTE off_on[999364];
bool drawnow = 0;
bool CreatePrimarySurface();
bool DirectDrawInit();
void __forceinline updateFrame( void );
void suicide ();
long FAR PASCAL WndProc (HWND myhwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CHAR:
if (wParam == VK_ESCAPE) // VK key code for exit key
PostQuitMessage(0);
else if (wParam == VK_SPACE)
drawnow = 1;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return(DefWindowProc(myhwnd,message,wParam,lParam));
}
int FAR PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
char buffer[10];
WNDCLASS wc;
HWND myhwnd=0;
MSG msg;
ghinst = hInst;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.hInstance = ghinst;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hIcon = 0;
wc.lpszMenuName = 0;
wc.hCursor = LoadCursor(0,IDC_ARROW);
wc.hbrBackground = (HBRUSH__ *)GetStockObject(BLACK_BRUSH);
wc.lpszClassName = "DDClass";
if (!RegisterClass(&wc)){MessageBox(mainwindow,"RegisterClass","error",MB_OK); return(1);}
bool mainloop = 1;
if (!DirectDrawInit())
{
suicide();
MessageBox(mainwindow,"DDinit","error",MB_OK);
exit(0);
}
CreatePrimarySurface();
long* colour = 0;
BYTE setpixel = 1;
BYTE neighbour = 0;
unsigned int index = 0;
unsigned int Y = 0; // x
unsigned int X = 0; // xxxooo
ZeroMemory(on_off,sizeof(on_off)); // xx
//on_off[576+(432*1154)] = 1;
on_off[577+(433*1154)] = 1; //x rabit
on_off[576+(433*1154)] = 1; //xxx
on_off[578+(433*1154)] = 1; // x
on_off[577+(434*1154)] = 1;
on_off[576+(432*1154)] = 1;
on_off[580+(432*1154)] = 1; //xxx
on_off[581+(432*1154)] = 1; // x
on_off[582+(432*1154)] = 1;
on_off[581+(433*1154)] = 1;
/*switchen
on_off[566+(431*1154)] = 1; //575 is middle 431 is middle
on_off[565+(431*1154)] = 1;
on_off[564+(431*1154)] = 1;
on_off[565+(430*1154)] = 1;
on_off[564+(428*1154)] = 1;
on_off[562+(430*1154)] = 1;
on_off[561+(429*1154)] = 1;
on_off[562+(428*1154)] = 1;
on_off[587+(433*1154)] = 1;
on_off[588+(433*1154)] = 1;
on_off[587+(434*1154)] = 1;
*/
unsigned long counter = 0;
ZeroMemory(buffer,10);
DDBLTFX ddbltfx;
/*------- MAIN LOOP --------*/
while (mainloop)
{
while (PeekMessage(&msg,0,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
{mainloop = 0;}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ZeroMemory( &DDSurfDesc, sizeof( DDSurfDesc ));
DDSurfDesc.dwSize = sizeof( DDSurfDesc );
lpDDSBack->Lock( 0, &DDSurfDesc, DDLOCK_WAIT, 0 );
long* surface = reinterpret_cast<long*>(DDSurfDesc.lpSurface);
for(Y = 1; Y<865; ++Y)
{
for(X= 1; X<1153; ++X)
{
neighbour += on_off[(X-1)+((Y-1)*1154)];
neighbour += on_off[(X+1)+((Y-1)*1154)];
neighbour += on_off[(X-1)+((Y+1)*1154)];
neighbour += on_off[(X+1)+((Y+1)*1154)];
neighbour += on_off[(X-1)+(Y*1154)];
neighbour += on_off[(X+1)+(Y*1154)];
neighbour += on_off[X+((Y+1)*1154)];
neighbour += on_off[X+((Y-1)*1154)];
if(neighbour)
{
if(((neighbour == 2)&&(on_off[X+(Y*1154)]))||((neighbour == 3)))
{
//index = (X-1+((Y-1)*1152));
__asm
{
mov eax,DWORD PTR [X];
dec eax;
mov ecx,DWORD PTR [Y];
dec ecx;
imul ecx, 1152; //integer multiplication
add ecx,eax;
xor eax,eax;
//mov ecx, [index]; //index
mov edi, [surface]; //put dest addr to edi reg
mov al, BYTE PTR [edi+ecx]; //mov a byte of src data to low
xor al,BYTE PTR 255;
mov BYTE PTR [edi+ecx], al;
//off_on[X+(Y*1154)] = 1;
mov ecx, [Y];
imul ecx, 1154;
lea edi, off_on;
add ecx,[X];
mov [edi+ecx], 1;
}
}
}
neighbour = 0;
}
}
lpDDSBack->GetDC(&hdc);
itoa(++counter,buffer,10);
SetBkColor(hdc, RGB(0, 0, 0));
SetTextColor(hdc, RGB(255, 255, 255));
TextOut(hdc, 500, 0, buffer, lstrlen(buffer));
lpDDSBack->ReleaseDC(hdc);
lpDDSBack->Unlock(DDSurfDesc.lpSurface);
lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
for(X = 0; X<1154; ++X)
{
off_on[X] = 0;
off_on[X+(865*1154)] = 0;
}
for(Y = 0; Y<866; ++Y)
{
off_on[Y*1154] = 0;
off_on[1153+(Y*1154)] = 0;
}
CopyMemory(on_off,off_on,sizeof(off_on));
ZeroMemory(off_on,sizeof(off_on));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = 0x00;
lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL, &ddbltfx);
}
suicide();
return(1);
}
void suicide ()
{
if (lpDD)
{
if (lpDDSPrimary)
{
lpDDSPrimary->Release();
lpDDSPrimary = 0;
}
lpDD->Release(); lpDD = 0;
}
if (mainwindow)
{
DestroyWindow(mainwindow);
mainwindow = 0;
}
}
bool DirectDrawInit()
{
HDC hdc = GetDC(0);
mainwindow = CreateWindow("DDClass","Escapetoexit",WS_VISIBLE | WS_POPUP,0,0,GetDeviceCaps(hdc,HORZRES),GetDeviceCaps(hdc,VERTRES),0,0,ghinst,0);
ReleaseDC(0,hdc);
ShowCursor(0);
HRESULT ddrval;
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
if( ddrval != DD_OK )
{
MessageBox(mainwindow,"Direct Draw Creation","error",MB_OK);
return(false);
}
ddrval = lpDD->SetCooperativeLevel( mainwindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
if( ddrval != DD_OK )
{
lpDD->Release();
MessageBox(mainwindow,"Coop Level","error",MB_OK);
return(false);
}
ddrval = lpDD->SetDisplayMode( 1152, 864, 8);
if( ddrval != DD_OK )
{
lpDD->Release();
MessageBox(mainwindow,"Display Mode","error",MB_OK);
return(false);
}
return(true);
}
bool CreatePrimarySurface()
{
HRESULT ddrval;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if( ddrval != DD_OK )
{
MessageBox(mainwindow,"Creat Surface","error",MB_OK);
lpDD->Release();
return(false);
}
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if( ddrval != DD_OK )
{
MessageBox(mainwindow,"Get Attached Surface","error",MB_OK);
lpDDSPrimary->Release();
lpDD->Release();
return(false);
}
return true;
}
well here it is, you'll need the directX SDK so you can link the directx libs n stuff (don't get the most recent one if your using VC++6.0 because it dosn't support VC++6.0 any more, you'll need to find last months)
link: user32.lib ddraw.lib gdi32.lib