Skip to main content
gamedev.net
🔒 Locked

HELP!!!!!!!!!!

Started by Surg AKA Kunark Dec 2, 2005 at 11:53 PM 12 replies 1.3k views
Original Post
Surg AKA Kunark
Surg AKA Kunark
I desperately need help, been working on this project for two weeks. Hit an error I can't fix so much debugging so I rewrite my code all of it. And now I've hit another error that is unexplainable. From adding some certain code, if someone could please add me to msn so I can send you the program so you can help me debug it. I really need help desperately I thank anyone who helps. tehedra@hotmail.com
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF
Fahrenheit451
Fahrenheit451
I sure don't mind helping you, but you need to let us know what it is that you need help with. It might be that your problem lies outside of my field of knowledge or experience. Anyway, explain a little more about the problem, and maybe even post some code (between [_source_] and [_/source_] tags (remove the _ chars)) and I don't mind taking a look.

F451
Surg AKA Kunark
Surg AKA Kunark
Well I fixed some errors, but everytime I fix an error I get more. What we are doing is creating a small 4 player game over the network.

Right now, this is how it works.

User connects and we perform a handshake. We know the handshake is working as it has gone under some thourough testing. Now we are passing keypresses across the sockets to determine who is doing what. Ill paste my OnTimer code this is on the server side and what it does is sends out the new location to draw our buggies in. The problem is like now with the OnTimer enabled sometimes the client doesn't even render anymore. Sometimes it shows our buggie but it wont move. And sometimes it works. Never is the same.

Anyways, its much easier to talk over msn or chat or something but ill show u what we have.

void CBuggies_DedServDlg::OnTimer(UINT nIDEvent){	static __int64 iTime = 0;	iTime++;	if(iTime % 50){		/*			Okay so, we are running out timer to send out the information.			This is a dual check process to make sure the client has responded.			Is connected and has responded to the last message.			The code will do all the movement on the server side, then 			respond to the clients with the new locations.		*/		int iPlayers2(0);		for(int i(0); i < 4; i++)			if(m_bPlayersActive)				iPlayers2++;		if(iPlayers2>0){			if(((m_bResponse[0] && m_bPlayersActive[0]) || !m_bPlayers[0]) &&				((m_bResponse[1] && m_bPlayersActive[1]) || !m_bPlayers[1]) &&				((m_bResponse[2] && m_bPlayersActive[2]) || !m_bPlayers[2]) &&				((m_bResponse[3] && m_bPlayersActive[3]) || !m_bPlayers[3])){					/*						So, its time to do them movements. Build our						sending packet. Then possible do collission						detection.					*/					for(int i(0); i<4; i++){						/*							Lets do all the movements now.						*/						if(m_cbsBuggies->up)						{							m_cbsBuggies->Accel();							// The car will only turn if it is accelerating							// This is a car not a spaceship							// if the right arrow is pressed then turn right							if(m_cbsBuggies->right)								m_cbsBuggies->TurnRight();							// if the left arrow is pressed then turn left							if(m_cbsBuggies->left)								m_cbsBuggies->TurnLeft();						} else if (m_cbsBuggies->down) {							m_cbsBuggies->Decel();							if(m_cbsBuggies->right)								m_cbsBuggies->TurnRight();							if(m_cbsBuggies->left)								m_cbsBuggies->TurnLeft();						} else {							// Decelerate the car if the gas is not on							m_cbsBuggies->Slow();						}						/*							Now that we have done the movements and set 							all the values required. Its time to							do the move.						*/						m_cbsBuggies->DoMove();						m_bResponse = false;					}					/*						This is time to make our packets and get ready to send						out the car packet to everyone with the correct values.						This is the fun part of this timer.					*/					int iPlayers(0);					for(int i(0); i < 4; i++)						if(m_bPlayersActive)							iPlayers++;					// Number of players minus yourself					SocketPacket* spSend = new SocketPacket[iPlayers];					///////////////////////////////////////////////					///////////////////////////////////////////////					for(int i(0), j(0); i < iPlayers; i++){												/*							Collect the information of all the players and send it							to the new connection. Remember now that we can do this							all at once it makes it much nicer!						*/						// First Determine which is next player						while(!m_bPlayersActive[j] && j < 4)							j++;						/*							Populates array with player names currently playing.							Pointless to send your own name so that name is not							ever sent.						*/						spSend.iFlag = 0;						spSend.data.CarPacket.iPlayer = j;						spSend.data.CarPacket.x = m_cbsBuggies->GetXPos() * 10000;						spSend.data.CarPacket.y = m_cbsBuggies->GetYPos() * 10000;						spSend.data.CarPacket.iDirection = m_cbsBuggies->GetDir() * 10000;					}					//////////////////////////////////////////////					//////////////////////////////////////////////					std::list<CServer*>::iterator scan = m_plConnections.begin();					while(scan != m_plConnections.end()){						if(m_bPlayersActive[(*scan)->m_iPlayer])							(*scan)->Send(spSend, sizeof(SocketPacket) * iPlayers);						scan++;					}					// Clean Memory Up					delete spSend;				} else {					/*						A user is active and connected but not						responding. Count how long its been						if its been over three seconds boot						their ass.					*/				}			}		}	CDialog::OnTimer(nIDEvent);}


That is less complicated then it works. And too me it should work, but then again Im very stubborn and perhaps it shouldn't.

Anyways thanks for the help from anyone who is able to help me.
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF
Fahrenheit451
Fahrenheit451
ah ok. You might get more people looking at this if you posted this in the Multiplayer and Network Programming forum. As it is, this is way over my head! Good luck sorting this out though. Sounds like a cool project you have going there.

F451
Surg AKA Kunark
Surg AKA Kunark
Okay, * looks for a way to switch it over without double posting* lol anyways Ill try there later. Thanks for the help.
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF
hplus0603
hplus0603
Moved to Multiplayer and Networking forum by request.
enum Bool { True, False, FileNotFound };
_winterdyne_
_winterdyne_
Why are you doing this?:
if(iTime % 50){...}


iTime%50 will evaluate to zero the first 50 times this function is called, and will also evaluate to zero every 50th time this is called. % = modulo a.k.a. 'remainder'.

I assume you have a timer of some sort that is checked periodically to call this function.

Is your timer firing appropriately? Are you using a high resolution timer or a windows API timer - these get blocked real easy. You might want to implement a better method (high resolution timer) in your game loop - relying on the windows message pump for timing is not a particularly safe thing to do.



Winterdyne Solutions Ltd is recruiting - this thread for details!
hplus0603
hplus0603
Quote:
if(iTime % 50)


Actually, this will fire the first 49 times through, but not the 50th, and then it will repeat the pattern -- remainder when dividing by 50 is only 0 (false) 1 time out of 50.

However, that's probably not your problem. If I were you, I would put in code that prints various information (time stamp, # bytes received, function you're in, etc) at various important parts of your program, and then inspect that log file. It'll be a lot of data to go through, but that's one of the best ways of knowing what's actually going on.

Other tools that can help are judicious use of assert() to validate assumptions; using Ethereal (the free network sniffer); and your regular debugger -- conditional breakpoints are teh w1n!
enum Bool { True, False, FileNotFound };
Surg AKA Kunark
Surg AKA Kunark
Yes thanks for the help, I never noticed that it was supposed to be !(iTime%10) though that didn't fix my errors. I was able to determine that the harder errors to figure out were the computer themselves. The other ones was once I switched computers I was able to determine that the while loop to move on was incorrect. My sockets and drawing is now working correct. And I ended up sending the information every ms anyways since the network is fast enough to do that.

Now im moving onto collission detection as well as determing an algorithm to draw map tiles onto a screen. Again thanks for the help.
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF
cbenoi1
cbenoi1
It would be interesting to know how you compute acceleration and how the timer is retriggered. If all your computations are based on the WM_TIMER message and you miss one beat, your computations are going to get skewed. You can miss one if the time spent in the OnTimer() routine exceeds the timer delay. By waiting on a blocking Send(), for example.

I think you should review the way you do your game loog and process timer values. Below is what I have in mind:

	//---- Main message loop:	DWORD l_dwTimeBase = timeGetTime();	for (;;)	{		if ( ::PeekMessage( &l_msg, NULL, 0, 0, PM_REMOVE ) )		{			if ( l_msg.message == WM_QUIT )				break;			::TranslateMessage( &l_msg );			::DispatchMessage ( &l_msg );		}		else		{			//---- Update players and execute game simulation			if( timeGetTime() > l_dwTimeBase + 50 )			{				//---- Process all incoming/outgoing messages.				npDPlay_ProcessMessages();				//---- Update the game simulation with latest input				npPlayer_Update( timeGetTime() - l_dwTimeBase );				npGamePlay_Update( timeGetTime() - l_dwTimeBase );				//---- Update the client window				::InvalidateRect( g_hWndMain, NULL, TRUE );				l_dwTimeBase = timeGetTime();			}		}	}


Hope this helps.

-cb
Surg AKA Kunark
Surg AKA Kunark
Im sorry guys, I forgot to mention that Im using MFC here, so there is no game message loop. This timer takes care of almost everything. I've fixed the bugs I had and am now working on drawing problems.

Heres my render function or atleast the part that isn't working perhaps you guys have some ideas. It works the way I thin it should before

		//Get the rect area of the entire screen		CRect rect;		GetClientRect (▭);		//Create a DC for the primary surface		CClientDC dc (this);		// off-screen pixels		CBitmap bmOff;		bmOff.CreateCompatibleBitmap (&dc, rect.Width(), rect.Height());		//create a memory DC compatible with the primary surface		CDC memDC;		memDC.CreateCompatibleDC (&dc);		//make sure to save the old 1x1 Bitmap		CBitmap * pOldOffBM = memDC.SelectObject (&bmOff);		// draw to offscreen DC		//memDC.FillSolidRect (▭, RGB (215, 215, 0)); //desert to buggie on		/*			No more desert to buggie on, its time to buggie on something			more realisitic. Implementing map rendering here.		*/		// Load bitmap		//create an instance of CBitmap		CBitmap bmMap;		// DC		CDC memBitmapDC;		memBitmapDC.CreateCompatibleDC(&dc);		// load the bitmap resource into the bitmap instance		bmMap.LoadBitmap(IDB_DEFAULTMAP);		// select the bitmap into the DC (remember to save the old one!)		CBitmap * pOldddddddy = memBitmapDC.SelectObject(&bmMap);		//		TRACE("[%f,%f]\n", m_cNewBuggie.GetXPos(), m_cNewBuggie.GetYPos());		// This will do the drawing		int iYOffSet(static_cast<int>(m_cNewBuggie.GetYPos())%32);		int iXOffSet(static_cast<int>(m_cNewBuggie.GetXPos())%32);		for(int iWinYPos(-32), iLogicalY((m_cNewBuggie.GetYPos()-(550/2)+64)/32); iWinYPos<576; iWinYPos += 32, iLogicalY++)			for(int iWinXPos(-32), iLogicalX((m_cNewBuggie.GetXPos()-(1000/2)+64)/32); iWinXPos<1028; iWinXPos += 32, iLogicalX++){				// Our window variables for drawing				// We have twenty tiles				switch(m_gmCurrent.iMapTiles[iLogicalY][iLogicalX]){					case 0:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 0, SRCCOPY);						break;					case 1:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 0, SRCCOPY);						break;					case 2:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 0, SRCCOPY);						break;					case 3:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 0, SRCCOPY);					case 4:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 32, SRCCOPY);						break;					case 5:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 32, SRCCOPY);						break;					case 6:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 32, SRCCOPY);						break;					case 7:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 32, SRCCOPY);						break;					case 8:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 64, SRCCOPY);						break;					case 9:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 64, SRCCOPY);						break;					case 10:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 64, SRCCOPY);						break;					case 11:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 64, SRCCOPY);						break;					case 12:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 96, SRCCOPY);						break;					case 13:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 96, SRCCOPY);						break;					case 14:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 96, SRCCOPY);						break;					case 15:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 96, SRCCOPY);						break;					case 16:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 0, 129, SRCCOPY);						break;					case 17:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 32, 129, SRCCOPY);						break;					case 18:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 64, 129, SRCCOPY);						break;					case 19:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 129, SRCCOPY);						break;					default:						memDC.BitBlt(iWinXPos, iWinYPos, 32, 32, &memBitmapDC, 96, 129, SRCCOPY);						break;				}			}		memBitmapDC.SelectObject(pOldddddddy);		m_cNewBuggie.Render (&memDC);				for(int i(0); i < 4; i++)			if(m_cbBuggies)				m_cbBuggies->Render(&memDC);		// flip to primary		dc.BitBlt (0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);		// restore all surfaces/objects		memDC.SelectObject (pOldOffBM);


Thats just all the code, though you only need to pay attention to the for loop with the offset. Im trying to draw a grid of map tiles. But I want it to look smooth as the buggy moves per pixel. Anyways again thanks for any of the help that you can offer.

Okay I fixed some of the code, it now looks like this, runs better but still doesn't run correctly. As well Im having some more troubles, these toubles are with collission detection. If you have any suggestions feel free.

[Edited by - Surg AKA Kunark on December 6, 2005 8:57:44 PM]
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF
cbenoi1
cbenoi1
You will need to bypass the MFC message pump. MFC was not designed for real-time 3D games. Here is an article that shows you how:

http://www.gamedev.net/reference/articles/article2204.asp ( clicky ).

-cb
Surg AKA Kunark
Surg AKA Kunark
Haha yea the game isn't 3D :( Im not that advanced yet. Its just 2D. Ive gotten alittle further and so far nothing is wrong with the timer, if I miss a beat its okay because nothing happens unless its in the timer. So all it does is just doesn't process anything during that round. This doesn't really affect gameplay what so ever so yea. Anyways thanks for the help so far, the socket connections always did work in the end so yea now its just getting the map to scroll right and understand collision detection better.

Yay so thanks to the help of a friend, he was able to tell me what I was doing wrong with my scrolling. Determining the offset alittle off. Thanks for the help guys now all I have left is to optimize my collision detection.

[Edited by - Surg AKA Kunark on December 9, 2005 3:03:20 AM]
~~Johnathan~~LTM my new fad, know it, use it, love it, LAUGHING TO MYSELF

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.