int Plus(int a, int b)
{
return a + b;
}
_declspec(naked) int PlusAsm(int a, int b)
{
__asm
{
mov ebx, dword ptr ss:[esp+8]
mov edx, dword ptr ss:[esp+4]
add edx, ebx
mov eax, edx
retn
}
}
int _tmain(int argc, _TCHAR* argv[])
{
for(int nCnt = 0; nCnt < 2; ++nCnt)
{
{
g_Timer.StartFrequency(1);
int nResult = 0;
for(int i = 0; i < 1000000000; ++i)
{
nResult += Plus(1,2);
}
g_Timer.EndFrequency(1);
__int64 n64Time = g_Timer.GetTime(1);
printf( "Normal nResult:%d, Time:%I64d\n\n", nResult, n64Time );
}
{
{
g_Timer.StartFrequency(1);
int nResult = 0;
for(int i = 0; i < 1000000000; ++i)
{
nResult += PlusAsm(1,2);
}
g_Timer.EndFrequency(1);
__int64 n64Time = g_Timer.GetTime(1);
printf( "Assemble nResult:%d, Time:%I64d\n\n", nResult, n64Time );
}
}
}
return 0;
}
프로그래밍
- Assemble 2019.09.10
- 커스텀 타이머 CShsTimer 2017.06.16
- 랭킹 테이블 만들기 2014.12.18
- 문자열에서 숫자, 영어, 특문, 한글 구분하기 (한글 걸러내기) 2014.10.31
- int 에서 INT64 로 자료 변경 문제 2014.07.14
- MsSQL에서 자료형을 8000바이트 이상 사용하는 방법 2014.07.02
- MSSQL 자료형 2014.01.22
- ODBC에서 DB와 서버랑 맵핑하는 자료형 정리 2013.01.10 1
- 맵 이동 2012.12.26 3
- 로비서버 <-> 게임서버, 게임 시작 루틴 2012.10.31 1
Assemble
커스텀 타이머 CShsTimer
ShsTimer.h
#define g_Timer CShsTimer::GetInstance()
/*
#include "ShsTimer.h" //1. 헤더 선언
void main()
{
g_Timer.StartFrequency(1); //2. 시작점 정하기
Sleep(1000);
g_Timer.EndFrequency(1); //3. 종료점 정하기
__int64 n64Time = g_Timer.GetTime(1); //4. 시간 값 리턴 받기
TRACE( "%I64d\n", n64Time ); //5. 결과 값은 1000이 출력 됨
}
※ Sleep(1000); 대신 수행 시간을 알고싶은 코드를 넣으면 됩니다.
void main()
{
g_Timer.Start(3000, 1); // 3초 후 CheckFired에서 true를 리턴하도록 세팅합니다.
for(;;)
{
if( g_Timer.CheckFired(1) ) // 3초 후 true를 리턴합니다.
{
TRACE( "return" );
return;
}
}
}
void main()
{
for(;;)
{
if( g_Timer.SleepEx(1000, 1) ) // 1초 마다 "1"을 출력합니다. Sleep과 동일
{
TRACE( "1" );
}
}
}
※ 주의
- 인덱스 인자를 줄 때 한 묶음 이외에는 사용해서는 안됩니다. SetTimer의 EventID와 동일한 개념입니다.
*/
struct tFrequencyInfo
{
tFrequencyInfo():m_n64SetTime(0)
{
}
LARGE_INTEGER m_start;
LARGE_INTEGER m_end;
__int64 m_n64SetTime;
};
class CShsTimer
{
private:
CShsTimer();
LARGE_INTEGER m_f;
bool m_bCanNotBeUsed; // true면 현재 컴퓨터에서는 사용 불가
map<int, tFrequencyInfo> m_mapFrequencyInfo;
public:
static CShsTimer& GetInstance();
void StartFrequency( int _nIndex ); // 시간을 측정 할 시작 점 지정
void EndFrequency( int _nIndex ); // 시간을 측정 할 종료 점 지정
__int64 GetTime( int _nIndex ); // Start과 End을 지정 후 걸린 시간을 ms단위로 리턴
void Start(__int64 _n64SetTime, int _nIndex ); // 얼마간의 시간을 흐른뒤에 CheckFired 에서 true를 리턴 할지 설정 해줌 ms단위(1000 == 1초)
bool CheckFired( int _nIndex ); // Start으로 세팅 한 시간이 흐를 때 까지 false를 리턴하다가, 세팅한 시간이 되면 true를 계속 리턴
bool SleepEx(__int64 _n64SetTime, int _nIndex); // Sleep()과 동일 한데 false를 리턴하고, 시간 흐르면 true 리턴
// _n64SetTime 세팅 한 시간이 흐르기 전에는 false 리턴, _n64SetTime만큼 시간이 흐르면 딱 한번 true 리턴하고, 처음과 똑같이 반복
};
ShsTimer.cpp
nclude "stdafx.h"
#include "ShsTimer.h"
CShsTimer& CShsTimer::GetInstance()
{
static CShsTimer Instance;
return Instance;
}
CShsTimer::CShsTimer()
{
// 고해상도 타이머의 주파수를 얻는다.
QueryPerformanceFrequency(&m_f);
if( 0 == m_f.QuadPart )
m_bCanNotBeUsed = true;
else
m_bCanNotBeUsed = false;
}
void CShsTimer::StartFrequency( int _nIndex )
{
if( m_bCanNotBeUsed )
return;
// 시작 시점의 CPU 클럭수를 얻는다.
QueryPerformanceCounter(&m_mapFrequencyInfo[_nIndex].m_start);
}
void CShsTimer::EndFrequency( int _nIndex )
{
if( m_bCanNotBeUsed )
return;
// 끝 시점의 클럭수를 얻는다.
QueryPerformanceCounter(&m_mapFrequencyInfo[_nIndex].m_end);
}
__int64 CShsTimer::GetTime( int _nIndex )
{
if( m_bCanNotBeUsed )
return 0;
// 끝 시점의 CPU 클럭수에서 시작 시점의 클럭수를 뺀 후 주파수를 1000으로 나눈 값을 나눈다.
// 1초 기준의 주파수를 1000 으로 나누었기 때문에 1밀리초 동안 발생하는 진동수로 나눈 셈이다.
__int64 ms_interval = (m_mapFrequencyInfo[_nIndex].m_end.QuadPart - m_mapFrequencyInfo[_nIndex].m_start.QuadPart)/(m_f.QuadPart/1000);
return ms_interval;
}
void CShsTimer::Start( __int64 _n64SetTime, int _nIndex )
{
if( m_bCanNotBeUsed )
return;
m_mapFrequencyInfo[_nIndex].m_n64SetTime = _n64SetTime;
StartFrequency(_nIndex);
}
bool CShsTimer::CheckFired( int _nIndex )
{
if( m_bCanNotBeUsed )
return false;
EndFrequency(_nIndex);
if ( GetTime(_nIndex) > m_mapFrequencyInfo[_nIndex].m_n64SetTime )
return true;
return false;
}
bool CShsTimer::SleepEx( __int64 _n64SetTime, int _nIndex )
{
if( m_bCanNotBeUsed )
return false;
if( 0 == m_mapFrequencyInfo[_nIndex].m_n64SetTime )
{
Start(_n64SetTime, _nIndex);
return false;
}
if( CheckFired(_nIndex) )
{
StartFrequency(_nIndex);
return true;
}
return false;
}
랭킹 테이블 만들기
데브피아 SQL Server 에서 퍼왔어요.
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=38&MAEULNo=16&no=37711&ref=37699
|
문자열에서 숫자, 영어, 특문, 한글 구분하기 (한글 걸러내기)
[자문자답] VC++에서 방법알아냈습니다.
http://www.unicode.org/charts/
위의 웹 페이지를 참조해 보시고 아래의 코드를 참조하시면 될듯...
//숫자 |
int 에서 INT64 로 자료 변경 문제
INT64 CreateRaidHistory() 원형에서
int nLineNumber = (int)CreateRaidHistory();
INT64 를 (int)로 자료형 변환을 하니까 컴파일러가 정신 못 차리고 디버깅을 못 한다.
-_-;;
소스 위치를 못 찾음...
MsSQL에서 자료형을 8000바이트 이상 사용하는 방법
DB에서 자료형 선언은
CREATE TABLE UserInformationTbl
(
GiftInventory VARCHAR(MAX) NULL,
)
이렇게 하고,
ODBC를
"SQL Server Native Client 10.0" 으로 만들어야 한다.
그리고 SQLBindParameter 에서 3번째 인자 값과 4번째 인자값을
SQL_C_CHAR , SQL_LONGVARCHAR,
retcode = SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT,
SQL_C_CHAR , SQL_LONGVARCHAR,
nSize, 0, (SQLPOINTER) Data, nSize, &ind);
이상 끝!
MSSQL 자료형
출처: http://blog.naver.com/ballkiss?Redirect=Log&logNo=30025300601
ODBC에서 DB와 서버랑 맵핑하는 자료형 정리
ODBC에서 DB와 서버랑 맵핑하는 자료형 정리
C Type identifier | ODBC C Typedef | C Type |
---|---|---|
SQL_C_CHAR | SQLCHAR | unsigned char |
SQL_C_STINYINT | SCHAR | char |
SQL_C_UTINYINT [i] | UCHAR | unsigned char |
SQL_C_SSHORT [h] | SQLSMALLINT | short int |
SQL_C_USHORT [h] [i] | SQLUSMALLINT | unsigned short int |
SQL_C_SLONG [h] | SQLINTEGER | int |
SQL_C_ULONG [h] [i] | SQLUINTEGER | unsigned int |
SQL_C_SBIGINT | SQLBIGINT | _int64 [g] |
SQL_C_UBIGINT [i] | SQLUBIGINT | unsigned _int64 [g] solidDB does not support unsigned data types such as this. |
SQL_C_FLOAT | SQLREAL | float |
SQL_C_DOUBLE | SQLDOUBLE SQLFLOAT | double |
SQL_C_NUMERIC | SQLNUMERIC | unsigned char [f] |
SQL_C_DECIMAL | SQLDECIMAL | unsigned char [f] |
SQL_C_BINARY | SQLCHAR * | unsigned char * |
SQL_C_TYPE_DATE [c] | SQL_DATE_STRUCT | struct tagDATE_STRUCT{ SQLSMALLINT year; SQLUSMALLINT month; SQLUSMALLINT day; } DATE_STRUCT; [a] |
SQL_C_TYPE_TIME [c] | SQL_TIME_STRUCT | struct tagTIME_STRUCT { SQLUSMALLINT hour; SQLUSMALLINT minute;[d] SQLUSMALLINT second;[e] } |
SQL_C_TYPE_TIMESTAMP [c] | SQL_TIMESTAMP_STRUCT | struct tagTIMESTAMP_STRUCT { SQLSMALLINT year; [a] SQLUSMALLINT month; [b] SQLUSMALLINT day; [c] SQLUSMALLINT hour; SQLUSMALLINT minute; [d] SQLUSMALLINT second;[e] SQLUINTEGER fraction; } |
맵 이동
void 맵이동()
{
if( 맵을 생성해야 하나? )
{
맵 생성;
Npc 생성;
}
기존 맵에 있는 클라가 걸려있는 버프 저장;
기존 맵에 있는 클라에 유닛 제거;
방금 접속한 클라 생성;
방금 접속한 클라에게 이전맵에서 가지고 있었던 버프를 걸어줌;
방금 접속한 클라 정보를 맵안에 모든 클라에게 정보 전송;
방금 접속한 클라 버프정보를 맵안에 모든 클라에게 정보 전송;
Npc 정보 -> 방금 접속한 클라에게 전송;
Npc 버프 정보-> 방금 접속한 클라에게 전송;
기존 맵에 있었던 클라 정보 -> 방금 접속한 클라에게 정보 전송;
기존 맵에 있었던 클라 버프 정보 -> 방금 접속한 클라에게 버프 정보 전송;
}
로비서버 <-> 게임서버, 게임 시작 루틴
1. 로비서버 -> 게임서버
클라 정보 전달
2. 게임서버
클라가 접속하길 기다린다. (10초간)
3. 게임서버
접속이 완료 되면 각 클라 정보를 각 클라에게 보낸다.
4. 클라 -> 게임서버
클라에서 준비가 완료되면 게임서버로 게임을 시작 할 모든 준비가 끝났음을 알린다.
5. 게임서버 -> 클라
모든 클라에게 게임 시작을 알린다.