Jump to content

Librería GRP, funcion SaveScreenShotToPath | Win XP


fakzo
 Share

Recommended Posts

Hola a todos. Estuve desarrollando un pequeño programa en Python para uso personal. El programa está relacionado a metin2 obviamente y utiliza las librerías que el cliente de metin2 "ofrece". He realizado el programa para un determinado servidor, mientras yo utilizaba Windows 7 64 bits como sistema operativo. El problema sucedió cuando quise probar éste mismo programa en el mismo servidor para el cual se ha creado pero utilizando como sistema operativo Windows XP 32 bits. El problema ocurre con la librería GRP al utilizar una función que ésta ofrece (SaveScreenShotToPath). La función SaveScreenShotToPath perteneciente a la librería GRP se encarga de capturar una imagen de la pantalla y guardarla en una dirección determinada. Espera un parámetro, el cual será la dirección donde se guardará la dicha imagen y devuelve dos valores, un primer valor boolean y un segundo el cual es un string. El boolean devuelve True si se guardó correctamente la imagen o False en caso contrario. La cadena de texto retornada es el nombre que se le ha dado a la imagen. Todo esto funciona perfectamente cuando utilizo el programa en Win 7 64bits, pero al utilizarlo en Win XP 32bits el primer valor boolean retornado es False. Es decir se produjo un fallo al guardar/capturar la imagen. No me explico por qué. Intente cambiando la dirección pensando que quizás el formato de ésta era errónea, pero nada. Probé utilizando otra función de la misma librería llamada SaveScreenShot, esta retorna lo mismo que la anterior pero no espera ningún valor, simplemente guarda la imagen en la carpeta "Documents/Metin2". Obtuve el mismo resultado, fallo al guardar la imagen. No puedo saber porque se produce dicho fallo. Tampoco conozco como están hechas las funciones, para mi son como cajas negras donde yo introduzco valores de entrada y obtengo valores de salidas. La función sirve y se llama correctamente, pero no retorna los valores esperados.

 

Sería de gran ayuda si alguien me podría explicar las posibles causas por la que quizás se produzca el fallo al guardar o capturar la imagen (pongo guardar o capturar ya que no se en que momento se produce el fallo). 

También me serviría mucho si alguien tiene source code de estas funciones, para así verlas y quizás puedo interpretar por qué se produce el fallo.

 

Gracias por su atencion, saludos!

Link to comment
Share on other sites

 

 

PyObject * grpSaveScreenShotToPath(PyObject * poSelf, PyObject * poArgs)
{
	char * szBasePath;
	if (!PyTuple_GetString(poArgs, 0, &szBasePath))
		return Py_BuildException();

	struct tm * tmNow;
	time_t ct;

	ct = time(0);
	tmNow = localtime(&ct);

	char szPath[MAX_PATH + 256];
	snprintf(szPath, sizeof(szPath), "%s%02d%02d_%02d%02d%02d.jpg", 
			szBasePath,
			tmNow->tm_mon + 1,
			tmNow->tm_mday,
			tmNow->tm_hour,
			tmNow->tm_min,
			tmNow->tm_sec);

	BOOL bResult = CPythonGraphic::Instance().SaveScreenShot(szPath);
	return Py_BuildValue("(is)", bResult, szPath);
}

////////////////////////////////////////////////////////////////////////////////

bool CPythonGraphic::SaveScreenShot(const char * c_pszFileName)
{
	HRESULT hr;
	LPDIRECT3DSURFACE8 lpSurface;
	D3DSURFACE_DESC stSurfaceDesc;

	if (FAILED(hr = ms_lpd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &lpSurface)))
	{
		TraceError("Failed to get back buffer (0x%08x)", hr);
		return false;
	}

	if (FAILED(hr = lpSurface->GetDesc(&stSurfaceDesc)))
	{
		TraceError("Failed to get surface desc (0x%08x)", hr);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	UINT uWidth = stSurfaceDesc.Width;
	UINT uHeight = stSurfaceDesc.Height;

	switch( stSurfaceDesc.Format ) {
	case D3DFMT_R8G8B8 :
	case D3DFMT_A8R8G8B8 :
	case D3DFMT_X8R8G8B8 :
	case D3DFMT_R5G6B5 :
	case D3DFMT_X1R5G5B5 :
	case D3DFMT_A1R5G5B5 :
		break;
	case D3DFMT_A4R4G4B4 :
	case D3DFMT_R3G3B2 :
	case D3DFMT_A8R3G3B2 :
	case D3DFMT_X4R4G4B4 :
	case D3DFMT_A2B10G10R10 :
		TraceError("Unsupported BackBuffer Format(%d). Please contact Metin 2 Administrator.", stSurfaceDesc.Format);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	D3DLOCKED_RECT lockRect;
	if (FAILED(hr = lpSurface->LockRect(&lockRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
	{
		TraceError("Failed to lock the surface (0x%08x)", hr);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	BYTE* pbyBuffer = new BYTE[uWidth * uHeight * 3];
	if (pbyBuffer == NULL) {
		lpSurface->UnlockRect();
		lpSurface->Release();
		lpSurface = NULL;
		TraceError("Failed to allocate screenshot buffer");
		return false;
	}
	BYTE* pbySource = (BYTE*) lockRect.pBits;
	BYTE* pbyDestination = (BYTE*) pbyBuffer;
	for(UINT y = 0; y < uHeight; ++y) {
		BYTE *pRow = pbySource;

		switch( stSurfaceDesc.Format ) {
		case D3DFMT_R8G8B8 :
			for(UINT x = 0; x < uWidth; ++x) {
				*pbyDestination++ = pRow[2];	// Blue
				*pbyDestination++ = pRow[1];	// Green
				*pbyDestination++ = pRow[0];	// Red
				pRow += 3;
			}
			break;
		case D3DFMT_A8R8G8B8 :
		case D3DFMT_X8R8G8B8 :
			for(UINT x = 0; x < uWidth; ++x) {
				*pbyDestination++ = pRow[2];	// Blue
				*pbyDestination++ = pRow[1];	// Green
				*pbyDestination++ = pRow[0];	// Red
				pRow += 4;
			}
			break;
		case D3DFMT_R5G6B5 :
			{
				for(UINT x = 0; x < uWidth; ++x) {
					UINT uColor		= *((UINT *) pRow);
					BYTE byBlue		= (uColor >> 11) & 0x1F;
					BYTE byGreen	= (uColor >> 5) & 0x3F;
					BYTE byRed		= uColor & 0x1F;

					*pbyDestination++ = (byBlue << 3)	| (byBlue >> 2);		// Blue
					*pbyDestination++ = (byGreen << 2)	| (byGreen >> 2);		// Green
					*pbyDestination++ = (byRed << 3)	| (byRed >> 2);			// Red
					pRow += 2;
				}
			}
			break;
		case D3DFMT_X1R5G5B5 :
		case D3DFMT_A1R5G5B5 :
			{
				for(UINT x = 0; x < uWidth; ++x) {
					UINT uColor		= *((UINT *) pRow);
					BYTE byBlue		= (uColor >> 10) & 0x1F;
					BYTE byGreen	= (uColor >> 5) & 0x1F;
					BYTE byRed		= uColor & 0x1F;

					*pbyDestination++ = (byBlue << 3)	| (byBlue >> 2);		// Blue
					*pbyDestination++ = (byGreen << 3)	| (byGreen >> 2);		// Green
					*pbyDestination++ = (byRed << 3)	| (byRed >> 2);			// Red
					pRow += 2;
				}
			}
			break;
		}

		// increase by one line
		pbySource += lockRect.Pitch;
	}

	if(lpSurface) {
		lpSurface->UnlockRect();
		lpSurface->Release();
		lpSurface = NULL;
	}

	bool bSaved = SaveJPEG(c_pszFileName, pbyBuffer, uWidth, uHeight);

	if(pbyBuffer) {
		delete [] pbyBuffer;
		pbyBuffer = NULL;
	}

	if(bSaved == false) {
		TraceError("Failed to save JPEG file. (%s, %d, %d)", c_pszFileName, uWidth, uHeight);
		return false;
	}

	if (g_isScreenShotKey)
	{
		FILE* srcFilePtr = fopen(c_pszFileName, "rb");
		if (srcFilePtr)
		{
			fseek(srcFilePtr, 0, SEEK_END);		
			size_t fileSize = ftell(srcFilePtr);
			fseek(srcFilePtr, 0, SEEK_SET);

			char head[21];
			size_t tailSize = fileSize - sizeof(head);
			char* tail = (char*)malloc(tailSize);
			
			fread(head, sizeof(head), 1, srcFilePtr);
			fread(tail, tailSize, 1, srcFilePtr);
			fclose(srcFilePtr);

			char imgDesc[64];
			GenScreenShotTag(c_pszFileName, GetCRC32(tail, tailSize), imgDesc, sizeof(imgDesc));

			int imgDescLen = strlen(imgDesc) + 1;
			
			unsigned char exifHeader[] = {
				0xe1,
				0, // blockLen[1],
				0, // blockLen[0],
				0x45,
				0x78,
				0x69,
				0x66,
				0x0,
				0x0,
				0x49,
				0x49,
				0x2a,
				0x0,
				0x8,
				0x0,
				0x0,
				0x0,
				0x1,
				0x0,
				0xe,
				0x1,
				0x2,
				0x0,
				imgDescLen, // textLen[0],
				0, // textLen[1],
				0, // textLen[2],
				0, // textLen[3],
				0x1a,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
			};

			exifHeader[2] = sizeof(exifHeader) + imgDescLen;

			FILE* dstFilePtr = fopen(c_pszFileName, "wb");
			//FILE* dstFilePtr = fopen("temp.jpg", "wb");
			if (dstFilePtr)
			{
				fwrite(head, sizeof(head), 1, dstFilePtr);
				fwrite(exifHeader, sizeof(exifHeader), 1, dstFilePtr);
				fwrite(imgDesc, imgDescLen, 1, dstFilePtr);
				fputc(0x00, dstFilePtr);
				fputc(0xff, dstFilePtr);
				fwrite(tail, tailSize, 1, dstFilePtr);
				fclose(dstFilePtr);
			}

			free(tail);
		}
	}
	return true;
}

 

 

 

puede que el syserr.txt te diga algo de utilidad.

Link to comment
Share on other sites

 

 

PyObject * grpSaveScreenShotToPath(PyObject * poSelf, PyObject * poArgs)
{
	char * szBasePath;
	if (!PyTuple_GetString(poArgs, 0, &szBasePath))
		return Py_BuildException();

	struct tm * tmNow;
	time_t ct;

	ct = time(0);
	tmNow = localtime(&ct);

	char szPath[MAX_PATH + 256];
	snprintf(szPath, sizeof(szPath), "%s%02d%02d_%02d%02d%02d.jpg", 
			szBasePath,
			tmNow->tm_mon + 1,
			tmNow->tm_mday,
			tmNow->tm_hour,
			tmNow->tm_min,
			tmNow->tm_sec);

	BOOL bResult = CPythonGraphic::Instance().SaveScreenShot(szPath);
	return Py_BuildValue("(is)", bResult, szPath);
}

////////////////////////////////////////////////////////////////////////////////

bool CPythonGraphic::SaveScreenShot(const char * c_pszFileName)
{
	HRESULT hr;
	LPDIRECT3DSURFACE8 lpSurface;
	D3DSURFACE_DESC stSurfaceDesc;

	if (FAILED(hr = ms_lpd3dDevice->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &lpSurface)))
	{
		TraceError("Failed to get back buffer (0x%08x)", hr);
		return false;
	}

	if (FAILED(hr = lpSurface->GetDesc(&stSurfaceDesc)))
	{
		TraceError("Failed to get surface desc (0x%08x)", hr);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	UINT uWidth = stSurfaceDesc.Width;
	UINT uHeight = stSurfaceDesc.Height;

	switch( stSurfaceDesc.Format ) {
	case D3DFMT_R8G8B8 :
	case D3DFMT_A8R8G8B8 :
	case D3DFMT_X8R8G8B8 :
	case D3DFMT_R5G6B5 :
	case D3DFMT_X1R5G5B5 :
	case D3DFMT_A1R5G5B5 :
		break;
	case D3DFMT_A4R4G4B4 :
	case D3DFMT_R3G3B2 :
	case D3DFMT_A8R3G3B2 :
	case D3DFMT_X4R4G4B4 :
	case D3DFMT_A2B10G10R10 :
		TraceError("Unsupported BackBuffer Format(%d). Please contact Metin 2 Administrator.", stSurfaceDesc.Format);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	D3DLOCKED_RECT lockRect;
	if (FAILED(hr = lpSurface->LockRect(&lockRect, NULL, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
	{
		TraceError("Failed to lock the surface (0x%08x)", hr);
		SAFE_RELEASE(lpSurface);
		return false;
	}

	BYTE* pbyBuffer = new BYTE[uWidth * uHeight * 3];
	if (pbyBuffer == NULL) {
		lpSurface->UnlockRect();
		lpSurface->Release();
		lpSurface = NULL;
		TraceError("Failed to allocate screenshot buffer");
		return false;
	}
	BYTE* pbySource = (BYTE*) lockRect.pBits;
	BYTE* pbyDestination = (BYTE*) pbyBuffer;
	for(UINT y = 0; y < uHeight; ++y) {
		BYTE *pRow = pbySource;

		switch( stSurfaceDesc.Format ) {
		case D3DFMT_R8G8B8 :
			for(UINT x = 0; x < uWidth; ++x) {
				*pbyDestination++ = pRow[2];	// Blue
				*pbyDestination++ = pRow[1];	// Green
				*pbyDestination++ = pRow[0];	// Red
				pRow += 3;
			}
			break;
		case D3DFMT_A8R8G8B8 :
		case D3DFMT_X8R8G8B8 :
			for(UINT x = 0; x < uWidth; ++x) {
				*pbyDestination++ = pRow[2];	// Blue
				*pbyDestination++ = pRow[1];	// Green
				*pbyDestination++ = pRow[0];	// Red
				pRow += 4;
			}
			break;
		case D3DFMT_R5G6B5 :
			{
				for(UINT x = 0; x < uWidth; ++x) {
					UINT uColor		= *((UINT *) pRow);
					BYTE byBlue		= (uColor >> 11) & 0x1F;
					BYTE byGreen	= (uColor >> 5) & 0x3F;
					BYTE byRed		= uColor & 0x1F;

					*pbyDestination++ = (byBlue << 3)	| (byBlue >> 2);		// Blue
					*pbyDestination++ = (byGreen << 2)	| (byGreen >> 2);		// Green
					*pbyDestination++ = (byRed << 3)	| (byRed >> 2);			// Red
					pRow += 2;
				}
			}
			break;
		case D3DFMT_X1R5G5B5 :
		case D3DFMT_A1R5G5B5 :
			{
				for(UINT x = 0; x < uWidth; ++x) {
					UINT uColor		= *((UINT *) pRow);
					BYTE byBlue		= (uColor >> 10) & 0x1F;
					BYTE byGreen	= (uColor >> 5) & 0x1F;
					BYTE byRed		= uColor & 0x1F;

					*pbyDestination++ = (byBlue << 3)	| (byBlue >> 2);		// Blue
					*pbyDestination++ = (byGreen << 3)	| (byGreen >> 2);		// Green
					*pbyDestination++ = (byRed << 3)	| (byRed >> 2);			// Red
					pRow += 2;
				}
			}
			break;
		}

		// increase by one line
		pbySource += lockRect.Pitch;
	}

	if(lpSurface) {
		lpSurface->UnlockRect();
		lpSurface->Release();
		lpSurface = NULL;
	}

	bool bSaved = SaveJPEG(c_pszFileName, pbyBuffer, uWidth, uHeight);

	if(pbyBuffer) {
		delete [] pbyBuffer;
		pbyBuffer = NULL;
	}

	if(bSaved == false) {
		TraceError("Failed to save JPEG file. (%s, %d, %d)", c_pszFileName, uWidth, uHeight);
		return false;
	}

	if (g_isScreenShotKey)
	{
		FILE* srcFilePtr = fopen(c_pszFileName, "rb");
		if (srcFilePtr)
		{
			fseek(srcFilePtr, 0, SEEK_END);		
			size_t fileSize = ftell(srcFilePtr);
			fseek(srcFilePtr, 0, SEEK_SET);

			char head[21];
			size_t tailSize = fileSize - sizeof(head);
			char* tail = (char*)malloc(tailSize);
			
			fread(head, sizeof(head), 1, srcFilePtr);
			fread(tail, tailSize, 1, srcFilePtr);
			fclose(srcFilePtr);

			char imgDesc[64];
			GenScreenShotTag(c_pszFileName, GetCRC32(tail, tailSize), imgDesc, sizeof(imgDesc));

			int imgDescLen = strlen(imgDesc) + 1;
			
			unsigned char exifHeader[] = {
				0xe1,
				0, // blockLen[1],
				0, // blockLen[0],
				0x45,
				0x78,
				0x69,
				0x66,
				0x0,
				0x0,
				0x49,
				0x49,
				0x2a,
				0x0,
				0x8,
				0x0,
				0x0,
				0x0,
				0x1,
				0x0,
				0xe,
				0x1,
				0x2,
				0x0,
				imgDescLen, // textLen[0],
				0, // textLen[1],
				0, // textLen[2],
				0, // textLen[3],
				0x1a,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
				0x0,
			};

			exifHeader[2] = sizeof(exifHeader) + imgDescLen;

			FILE* dstFilePtr = fopen(c_pszFileName, "wb");
			//FILE* dstFilePtr = fopen("temp.jpg", "wb");
			if (dstFilePtr)
			{
				fwrite(head, sizeof(head), 1, dstFilePtr);
				fwrite(exifHeader, sizeof(exifHeader), 1, dstFilePtr);
				fwrite(imgDesc, imgDescLen, 1, dstFilePtr);
				fputc(0x00, dstFilePtr);
				fputc(0xff, dstFilePtr);
				fwrite(tail, tailSize, 1, dstFilePtr);
				fclose(dstFilePtr);
			}

			free(tail);
		}
	}
	return true;
}

 

 

 

puede que el syserr.txt te diga algo de utilidad.

 

Muchas gracias, me había fijado en el syrrer.txt pero no había encontrado nada. Por lo tanto ahora procedí a hacer un programa que sólo se encargue de capturar una imagen y ahí noté en el syrrer el error Failed to lock the surface (0x88760827). Este error aparece claramente en en código fuente que me has pasado. Muchas gracias!

 

Intentaré solucionarlo, no se bien a que va el error, pero de como estaba a como estoy es un gran avance jaja. Saludos!

Link to comment
Share on other sites

La verdad es que le he metido ganas pero no he podido solucionarlo, no tengo ni idea que lleva a dicho error. Copio exactamente lo mismos archivos del cliente que tengo en mi pc con win 7 64bits a esta que tiene win XP 32bits y ya salta el dicho error. Por lo tanto deduzco que es algún impedimento del sistema operativo o alguna configuración errónea, lo cual me suena tonto, pero no se me ocurre que más probar.

 

Pensé que quizás el error se producía por falta de permisos o porque algún software externo impedía que se capture o se guarde la imagen. Desactivé y/o desinstalé todo programa que pudiese impedir que se lleve a cabo correctamente la función, pero no obtuve nada. La computadora con win XP 32 bits está formateada y no tiene prácticamente nada, solo librerías y componentes necesarios para que funcione el Metin2.

 

Si alguien me sabe decir las posibles causas por la cual se produce el error Failed to lock the surface (0x88760827), le estaría muy agradecido.

 

Bueno nada mas que decir,

 

Saludos!

Link to comment
Share on other sites

  • 2 weeks later...

Es alguna librería de dirext 3d probablemente.

Gracias por tu ayuda. Reinstalé directx, actualicé todos los drivers, también instalé por las dudas diversos programas como .Net framework, entre otros. Que más puede estar causando el impedimento con la función SaveScreenShot de la librería grp?... Más especificamente el error "Failed to lock the surface". Ya no se me ocurre. Llevo tiempo con esto y no sé que más hacer.

 

Espero que puedas ayudarme o alguien pueda decirme otra posible causa a este error.

 

Gracias, saludos!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...