Scrolling tiles question

Started by
12 comments, last by Zorbfish 21 years, 10 months ago

  

#define WIN32_LEAN_AND_MEAN
#define WORLDX 40
#define WORLDY 40

#include <stdio.h>
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>

LPDIRECTDRAW lpDD=NULL;
LPDIRECTDRAWSURFACE lpPrimary=NULL;
LPDIRECTDRAWSURFACE lpBackBuffer=NULL;
LPDIRECTDRAWSURFACE lpSecondary=NULL;
LPDIRECTDRAWCLIPPER lpClipper=NULL;
HINSTANCE hInstance;
RECT src,dest;
DDBLTFX ddbltfx;
HDC hdc;
RECT Tiles[]={
	{0,0,32,32},
	{32,0,64,32},
	{64,0,96,32}
};
int x=0,y=0,start_x,start_y,end_x,end_y,camerax,cameray;

int map[WORLDX][WORLDY] = {
     {2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,2, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,2, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
	 {2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
     {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}};

long CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);

BOOL DirectDraw(HWND hwnd){
	if(FAILED(DirectDrawCreate(NULL,&lpDD,NULL)))
		return FALSE;
	if(FAILED(lpDD->SetCooperativeLevel(hwnd,DDSCL_ALLOWREBOOT|DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)))
		return FALSE;
	if(FAILED(lpDD->SetDisplayMode(640,480,32)))
		return FALSE;
	DDSURFACEDESC ddsd;
	ddsd.dwSize=sizeof(DDSURFACEDESC);
	ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
	ddsd.ddsCaps.dwCaps=DDSCAPS_COMPLEX|DDSCAPS_FLIP|DDSCAPS_PRIMARYSURFACE;
	ddsd.dwBackBufferCount=1;
	if(FAILED(lpDD->CreateSurface(&ddsd,&lpPrimary,NULL)))
		return FALSE;
	ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
	if(FAILED(lpPrimary->GetAttachedSurface(&ddsd.ddsCaps,&lpBackBuffer)))
		return FALSE;

	ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_CKSRCBLT; 
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; 
    ddsd.dwHeight=32; 
    ddsd.dwWidth=96;
    ddsd.ddckCKSrcBlt.dwColorSpaceLowValue=RGB(255,255,255);
    ddsd.ddckCKSrcBlt.dwColorSpaceHighValue=RGB(255,255,255);

	if(FAILED(lpDD->CreateSurface(&ddsd,&lpSecondary,NULL)))
		return FALSE;
	if(FAILED(lpDD->CreateClipper(NULL,&lpClipper,NULL)))
		return FALSE;

	LPRGNDATA lpClipList = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER) +
										     sizeof(RECT));
	RECT rcBoundary = {0, 0, 640, 480};
	memcpy(lpClipList->Buffer, &rcBoundary, sizeof(RECT));
	lpClipList->rdh.dwSize = sizeof(RGNDATAHEADER);
	lpClipList->rdh.iType = RDH_RECTANGLES;
	lpClipList->rdh.nCount = 1;
	lpClipList->rdh.nRgnSize = sizeof(RECT);
	lpClipList->rdh.rcBound = rcBoundary;
	if (FAILED(lpClipper->SetClipList(lpClipList, 0)))
	{
		free(lpClipList);
		return(FALSE);
	}

	if (FAILED(lpBackBuffer->SetClipper(lpClipper)))
	{
		free(lpClipList);
		return(FALSE);
	}
	
	free(lpClipList);

	return TRUE;
}

bool LoadImage(LPDIRECTDRAWSURFACE lpDDS, LPSTR szImage){
	
	HBITMAP hbm;
	HDC hdcImage=NULL,hdcSurf=NULL;
	DDSURFACEDESC ddsd;

	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);

	if(FAILED(lpDDS->GetSurfaceDesc(&ddsd)))
		return FALSE;

	hbm=(HBITMAP)LoadImage(NULL,szImage,IMAGE_BITMAP,ddsd.dwWidth,ddsd.dwHeight,LR_LOADFROMFILE|LR_CREATEDIBSECTION);

	if(hbm==NULL)
		return FALSE;

	hdcImage=CreateCompatibleDC(NULL);
	SelectObject(hdcImage,hbm);

	if(FAILED(lpDDS->GetDC(&hdcSurf)))
		return FALSE;

	if(BitBlt(hdcSurf,0,0,ddsd.dwWidth,ddsd.dwHeight,hdcImage,0,0,SRCCOPY)==FALSE)
		return FALSE;

	if(hdcSurf)
		lpDDS->ReleaseDC(hdcSurf);
	if(hdcImage)
		DeleteDC(hdcImage);
	if(hbm)
		DeleteObject(hbm);

	return TRUE;
};

bool UpdateFrame(){
	SetRect(&dest,0,0,32,32);

	start_x=camerax/32;
	end_x=start_x+20;
	start_y=cameray/32;
	end_y=start_y+15;

	if(camerax%32==0){
		end_x--;
	}
	else{
		dest.left-=x;
		dest.right-=x;
	}
	if(cameray%32==0){
		end_y--;
	}
	else{
		dest.top-=y;
		dest.bottom-=y;
	}
	for(int i=start_y;i<end_y;i++){
		for(int j=start_x;j<end_x;j++){
			int tile=map[i][j];
			lpBackBuffer->Blt(&dest,lpSecondary,&Tiles[tile],DDBLT_WAIT,NULL);
			dest.left+=32;dest.right+=32;
		}
		dest.top+=32;
		dest.bottom+=32;
		dest.left=0;dest.right=32;


	}
	return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
	MSG msg;
	HWND hwnd;

	WNDCLASS wc;
	wc.style= CS_HREDRAW|CS_VREDRAW;
	wc.hInstance=hInstance;
	wc.lpfnWndProc=WindowProc;
	wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor=LoadCursor(hInstance,IDC_ARROW);
	wc.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
	wc.cbClsExtra=0;
	wc.cbWndExtra=0;
	wc.lpszClassName="Window";
	wc.lpszMenuName=NULL;

	RegisterClass(&wc);
	hwnd=CreateWindowEx(WS_EX_TOPMOST,"Window","Test",WS_POPUP,0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);
	ShowWindow(hwnd,nShowCmd);
	UpdateWindow(hwnd);
	ShowCursor(FALSE);

	if(FAILED(DirectDraw(hwnd)))
		return FALSE;
	if(FAILED(LoadImage(lpSecondary,"grass.bmp")))
		return FALSE;/*
	if(FAILED(LoadImage(lpHero,"sprite.bmp")))
		return FALSE;*/

	ddbltfx.dwSize=sizeof(DDBLTFX);
	ddbltfx.dwFillColor=0;
	int maxx=WORLDX;
	int maxy=WORLDY;
	int maxcamerax=(maxx-19)*32;
	int maxcameray=(maxy-15)*32;
	camerax=maxcamerax/2;
	cameray=maxcameray/2;

	while(TRUE){
		DWORD dwStart=GetTickCount();
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
			if(msg.message == WM_QUIT){
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else{

			UpdateFrame();
			lpPrimary->Flip(NULL,DDFLIP_WAIT);
			while(GetTickCount()-dwStart<33);
		}
	};
	return msg.wParam;
};

long CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
	PAINTSTRUCT ps;

	switch(message){
	case WM_ACTIVATEAPP:
		break;
	case WM_PAINT:
		BeginPaint(hwnd,&ps);
		EndPaint(hwnd,&ps);
		break;
	case WM_KEYDOWN:
		switch(wParam){
		case VK_ESCAPE:
			DestroyWindow(hwnd);
			break;
		case VK_UP:
			cameray-=5;
			break;
		case VK_DOWN:
			cameray+=5;
			break;
		case VK_LEFT:
			camerax-=5;
			break;
		case VK_RIGHT:
			camerax+=5;
			break;

		};
		break;
	case WM_DESTROY:
		if(lpDD!=NULL){
			if(lpPrimary!=NULL){
				if(lpBackBuffer!=NULL)
					lpBackBuffer->Release();
				if(lpClipper!=NULL)
					lpClipper->Release();
				if(lpSecondary!=NULL)
					lpSecondary->Release();
				lpPrimary->Release();
			};
			lpDD->Release();
			lpBackBuffer=NULL;
			lpClipper=NULL;
			lpSecondary=NULL;
			lpPrimary=NULL;
			lpDD=NULL;

		};
		ShowCursor(TRUE);
		PostQuitMessage(0);
		break;
	default:
		break;
	};
	return DefWindowProc(hwnd,message,wParam,lParam);
};
  
OK, I''ve read the Game Programming Genesis tutorial many times and I understand the theory behind scrolling the screen. I tried simplifying the code (i.e. removing bitwise ops for now,and i/o) and unfortunately the code does not smooth scroll as it should. Can anyone provide some insight into what I''m doing wrong? Also I''ve tried to find an article on exactly what the difference is with the clipper syntax above... For instance isn''t it easier just to declare the clipper to the whole window? lpClipper->SetHwnd(NULL,hwnd) Or does the clip list play a more significant role I do not understand? Anyways thanks for reading and hopefully someone out here can help me out... Zorb
Advertisement
Your VK Keypresses increase/decrease the camera position by 5 each time, thats not smooth scrolling, try 1.

(This is the main problem)
Also after each row you set dest.left/right to 0/32 it should be

dest.left=-x; //0 - offset
dest.right=32-x; // 32 (tilesize) - offset

the same as the inital code set it to (I''m assuming X/Y is your offset, its not in the code displayed).

,Jay

Edit: X/Y should be position modulus tilesize giving the offset.
The problem is that you only move your scrolling when you receive the KEYDOWN message. You must keep track of pressed keys. Here''s a quick and dirty example :


  bool keys[256];long CALLBACK WindowProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){	  switch(message)  {  case WM_KEYDOWN:    keys[wParam] = true;    break;  case WM_KEYUP:    keys[wParam] = false;    break;  // Stuff...  }}// in the update functionif ( keys[VK_UP])  cameray -= 5;if ( keys[VK_DOWN])  cameray += 5;// And so on  
I tried both suggested solutions and neither worked...
Jason''s suggestion didn''t seem to do anything different, the screen just scrolled 32 pixels each time, so it still moved tile by tile with no smooth scroll.
Prosper''s suggestion just froze my program altogether and nothing happens Maybe I didn''t put it in the right place...
I think my problem must be in my blit code... it must either not run correctly or not efficiently and that''s why it runs crappy. But of course I don''t know for sure that''s why Im here
Perhaps you could post a link to a zip file containing the code and an executable. I would then have a look at it because I can`t find any obvious errors right now .

Im Anfang war die Tat...
Faust
Im Anfang war die Tat...Faust
You say you understand the principle, with all due respect you don''t ().

for Y= ColMax //tiles round up to offscreen
for X= 0 to RowMax
blit(Offscreen,todest(x,y)) //blah
next
next

Blit (OffsetX,OffsetY,Offscreen-OffsetX,Offscreen-OffsetY)

you draw a offscreen surface tileX+1/tileY+1 (round up), you then blit offscreenX to ScreenWidth-OffscreenX etc.

Not to be offensive but this is the basic principle behind each and every tile based game, If you need additional explaination post (Jim Adams did a very good tut, on this site I think).

,Jay
Sorry, that sounded very patronising. Basicly you blit N tiles across the screen (and down), the offset is the distance from 0 to the next tile (0-31 eg), added to the offscreen surface to get the proper blit (screen width etc). Obviously the offscreen surface will be too short in most circumstances, so add a single tile to the width/height of the offscreen surface to allow for the offset.


for X= Tileposy to TilePosY+1
for TileX = TilePosX to TilePosX+1
Blit //blah
next
next

blit (as before);

With me ??

,Jay
I modified it a bit... it kinda smooth scrolls now but all I think I did was introduce more problems...
here''s a link to the zip for everyone interested.
http://www21.brinkster.com/leopold/scroll.zip
Alright, I will try and work that a bit... And I do understand the principle... just I guess I can''t put what I know into code :|

This topic is closed to new replies.

Advertisement