Results 1 to 10 of 10

Thread: HighScore, getting the users name

  1. #1

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802

    HighScore, getting the users name

    I'm witing a highscore table for a game I'm making, and I've run in to a problem... Whenever I press a key the game quits... I get this error message: "First-chance exception in Game.exe: 0xC0000005: Access Violation." I have no idea what this means...
    Code:
    void HighScores()
    {
    	bool bHSRunning = true;
    	bool bDown = true;
    	bool bChanged = false;
    	char strTemp[2];
    	char strName[50];
    	char strABC[30]("abcdefghijklmnopqrstuvwxyzåäö");
    	char str123[11]("0123456789");
    	int iKey = 0;
    
    	SetTextColor(g_hdc, RGB(255, 0, 0));
    
    	while(bHSRunning)
    	{
    		if(GetAsyncKeyState(VK_ESCAPE))
    		{
    			bHSRunning = false;
    			CleanUpHighScores();
    			g_iMenuState = 4;
    		}
    		for(int i = 0; i < 95; i++)
    		{
    			if(!bDown)
    			{
    				if(HIWORD(GetAsyncKeyState(i)))
    				{
    					if(i >= 48 && i <= 57)
    					{
    						strncpy(strTemp, str123 + (i - 48), 1);
    						bChanged = true;
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    					if(i >= 65 && i <= 90)
    					{
    						strncpy(strTemp, strABC + (i - 65), 1);
    						bChanged = true;
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    					if(i == 8) //8 == BackSpace
    					{
    						chardel(strName, strlen(strName));
    						TextOut(g_hdc, 100, 100, strName, strlen(strName));
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    				}
    			}
    			if(bDown)
    			{
    				if(!HIWORD(GetAsyncKeyState(iKey)))
    				{
    					bDown = false;
    				}
    			}
    		}
    		if(GetAsyncKeyState(VK_SHIFT) || GetAsyncKeyState(VK_LSHIFT) || GetAsyncKeyState(VK_RSHIFT))
    		{
    			strupr(strTemp);
    		}
    		if(bChanged)
    		{
    			strcat(strName, strTemp);
    			TextOut(g_hdc, 100, 100, strName, strlen(strName));
    			bChanged = false;
    		}
    	}
    }
    It's a win32 app written in vc++6.0
    Last edited by McCain; Dec 27th, 2002 at 08:03 PM.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    This means you access memory that doesn't belong to you. Try to narrow the error down as much as possible (placing outputs in the code or better, if you know how, do a debug run).
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    BTW the code looks extremly inefficient to me. Maybe you should restructure it.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    The error seems to be when the program gets to the line: "strcat(strName, strTemp);" (It's near the bottom)
    BTW the code looks extremly inefficient to me. Maybe you should restructure it.
    I'd love to, but I know nothing about how to optimize code...
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  5. #5

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    BTW This code works just fine in a win32 console app (using cout instead of TextOut and calling it void main() instead of void HighScore())...
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  6. #6

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    Ok, this code works:
    Code:
    void HighScores(HWND hwnd)
    {
    	bool bHSRunning = true;
    	bool bDown = true;
    	bool bChanged = false;
    	char strTemp[2];
    	char strName[50];
    	char strABC[30]("abcdefghijklmnopqrstuvwxyzåäö");
    	char str123[11]("0123456789");
    	int iKey = 0;
    
    	GetClientRect(hwnd, &g_rcClient);
    	g_hdc = GetDC(hwnd);
    
    	SetTextColor(g_hdc, RGB(255, 0, 0));
    	SetBkColor(g_hdc, RGB(0, 0, 0));
    	SetTextColor(g_hdcBuffer, RGB(255, 0, 0));
    	SetBkColor(g_hdcBuffer, RGB(0, 0, 0));
    
    	memset(strName, NULL, sizeof(strName));
    	memset(strTemp, NULL, sizeof(strTemp));
    
    	while(bHSRunning)
    	{
    		if(GetAsyncKeyState(VK_ESCAPE))
    		{
    			bHSRunning = false;
    			CleanUpHighScores();
    			g_iMenuState = 4;
    		}
    		for(int i = 0; i < 95; i++)
    		{
    			if(!bDown)
    			{
    				if(HIWORD(GetAsyncKeyState(i)))
    				{
    					if(i >= 48 && i <= 57)
    					{
    						strncpy(strTemp, str123 + (i - 48), 1);
    						bChanged = true;
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    					if(i >= 65 && i <= 90)
    					{
    						strncpy(strTemp, strABC + (i - 65), 1);
    						bChanged = true;
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    					if(i == 8) //8 == BackSpace
    					{
    						chardel(strName, strlen(strName));
    						FillRect(g_hdcBuffer, &g_rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH));
    						TextOut(g_hdcBuffer, 100, 100, strName, strlen(strName));
    						BitBlt(g_hdc, 0, 0, g_rcClient.right, g_rcClient.bottom, g_hdcBuffer, 0, 0, SRCCOPY);
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    					if(i == 32) //32 == Space
    					{
    						strcpy(strTemp, " ");
    						bChanged = true;
    						iKey = i;
    						bDown = true;
    						i = 256;
    					}
    				}
    			}
    			if(bDown)
    			{
    				if(!HIWORD(GetAsyncKeyState(iKey)))
    				{
    					bDown = false;
    				}
    			}
    		}
    		if(GetAsyncKeyState(VK_SHIFT) || GetAsyncKeyState(VK_LSHIFT) || GetAsyncKeyState(VK_RSHIFT))
    		{
    			strupr(strTemp);
    		}
    		if(bChanged)
    		{
    			strcat(strName, strTemp);
    			TextOut(g_hdc, 100, 100, strName, strlen(strName));
    			bChanged = false;
    		}
    	}
    }
    But I still don't know why I needed to fill the strings with NULL or why it worked in the console and not in a regular win app. I've allso added support for the space bar. Now I just want to know how to make this code more efficient and how to add support for holding the backspace key down to erase more than one letter.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  7. #7
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    The reason is quite simple: your use of strcat. strcat searches for the end of the string and adds the characters there. The end of the string is marked by '\0', so if you don't initialize the buffer to all 0 it will search past the end of the buffer and then try to write there, resulting in the access violation.

    But I don't see why you couldn't use strcpy instead of strcat here.

    About the inefficiency: first, is there any specific reason why you're keeping track of the buttons yourself instead of letting the message loop handle it?

    Second: instead of one for-loop and several ifs use several for-loops. This removes many unnecessary - because impossible - if-statements.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  8. #8

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    But why didn't I need to initialize the string when I ran the code in console mode?
    is there any specific reason why you're keeping track of the buttons yourself instead of letting the message loop handle it?
    I don't understand. I'm doing it the only way I could think of... If there is a better way, please let me know. How would I go about letting the message loop handle it?
    I'll remove (most of) the ifs and post the updated code soon.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  9. #9

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    I think this code should be more optimized...
    Code:
    void HighScores(HWND hwnd)
    {
    	bool bHSRunning = true;
    	bool bDown = true;
    	bool bChanged = false;
    	char strTemp[2];
    	char strName[50];
    	char strABC[30]("abcdefghijklmnopqrstuvwxyzåäö");
    	char str123[11]("0123456789");
    	int iKey = 0;
    	int i = 0;
    
    	GetClientRect(hwnd, &g_rcClient);
    	g_hdc = GetDC(hwnd);
    
    	SetTextColor(g_hdc, RGB(255, 0, 0));
    	SetBkColor(g_hdc, RGB(0, 0, 0));
    	SetTextColor(g_hdcBuffer, RGB(255, 0, 0));
    	SetBkColor(g_hdcBuffer, RGB(0, 0, 0));
    
    	memset(strName, NULL, sizeof(strName));
    	memset(strTemp, NULL, sizeof(strTemp));
    
    	while(bHSRunning)
    	{
    		if(GetAsyncKeyState(VK_RETURN))
    		{
    			bHSRunning = false;
    			CleanUpHighScores();
    			g_iMenuState = 4;
    		}
    		if(!bDown)
    		{
    			for(i = 65; i < 91; i++)
    			{
    				if(HIWORD(GetAsyncKeyState(i)))
    				{
    					
    					strncpy(strTemp, strABC + (i - 65), 1);
    					bChanged = true;
    					iKey = i;
    					bDown = true;
    					i = 92;
    				}
    			}
    		}
    		if(!bDown)
    		{
    			for(i = 48; i < 58; i++)
    			{
    				if(HIWORD(GetAsyncKeyState(i)))
    				{
    					strncpy(strTemp, str123 + (i - 48), 1);
    					bChanged = true;
    					iKey = i;
    					bDown = true;
    					i = 60;
    				}
    			}
    		}
    		if(!bDown)
    		{
    			if(HIWORD(GetAsyncKeyState(8))) //8 == BackSpace
    			{
    				chardel(strName, strlen(strName));
    				FillRect(g_hdcBuffer, &g_rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH));
    				TextOut(g_hdcBuffer, 100, 100, strName, strlen(strName));
    				BitBlt(g_hdc, 0, 0, g_rcClient.right, g_rcClient.bottom, g_hdcBuffer, 0, 0, SRCCOPY);
    				iKey = 8;
    				bDown = true;
    				//i = 256;
    			}
    			if(HIWORD(GetAsyncKeyState(32))) //32 == Space
    			{
    				strcpy(strTemp, " ");
    				bChanged = true;
    				iKey = 32;
    				bDown = true;
    				//i = 256;
    			}
    		}
    		if(bDown)
    		{
    			if(!HIWORD(GetAsyncKeyState(iKey)))
    			{
    				bDown = false;
    			}
    		}
    		if(GetAsyncKeyState(VK_SHIFT) || GetAsyncKeyState(VK_LSHIFT) || GetAsyncKeyState(VK_RSHIFT))
    		{
    			strupr(strTemp);
    		}
    		if(bChanged)
    		{
    			strcat(strName, strTemp);
    			TextOut(g_hdc, 100, 100, strName, strlen(strName));
    			bChanged = false;
    		}
    	}
    }
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Yes, that's what I meant.

    As for why it worked in console: the content of uninitialized memory is random. You might have been lucky.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width