Commits

blipi committed a5c2418

v0.5
Recuperada versión vieja
Añadidas clases importantes para el funcionamiento
Añadido código "packet"
Corregidos varios bugs
Adaptado HTTP de win a unix
Adaptados nombres de variables unsigned win a unix
Otros

Comments (0)

Files changed (35)

+/*
+ 
+  CSocket Class by OneWhoSighs
+  www.b0ts.org
+ 
+  This class was inspired by Waryas's original library. I was bored.
+ 
+*/
+ 
+#include "HTTP.h"
+
+//-------------------------------------------------------------------
+// Constructor / Destructor
+//-------------------------------------------------------------------
+ 
+CSocket::CSocket()
+{
+       netInitialize();
+       m_cRecievePacket = (char*)malloc(4096);
+}
+ 
+CSocket::~CSocket()
+{
+       netDeinitialize();
+       free(m_cRecievePacket);
+}
+ 
+int CSocket::disconnectSocket(int m_sConnection)
+{
+    int ret = shutdown(m_sConnection, SHUT_RDWR);
+	if (ret < 0) 
+		return -1;
+	
+	ret = close(m_sConnection);
+	if (ret < 0) 
+		return -1;
+
+	return 0;
+}
+
+int CSocket::disconnect(){
+	int ret = shutdown(list_s, SHUT_RDWR);
+	if (ret < 0) 
+		return -1;
+	
+	ret = close(list_s);
+	if (ret < 0) 
+		return -1;
+
+    m_bServerOnline = false;
+
+	return 1;
+}
+//-------------------------------------------------------------------
+// Server functions
+//-------------------------------------------------------------------
+ 
+bool CSocket::initializeServer(int m_iPort)
+{
+       list_s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
+ 
+       m_siServerInfo.sin_family = AF_INET;
+       m_siServerInfo.sin_addr.s_addr = INADDR_ANY; 
+       m_siServerInfo.sin_port = htons(m_iPort);
+
+	   if(bind(list_s, (sockaddr*)&m_siServerInfo, sizeof(struct sockaddr)) == 0)
+       {
+              m_bServerOnline = true;
+              return true;
+       }
+ 
+       return false;
+}
+ 
+int CSocket::acceptClient()
+{
+       if(m_bServerOnline)
+       {
+              if(listen( list_s, 256 ) != 0)
+                     return NULL;
+ 
+              int m_sClient;
+              int m_iLength;
+ 
+              m_iLength = sizeof m_siServerInfo;
+ 
+              m_sClient = accept( list_s, (sockaddr*)&m_siServerInfo, (socklen_t*)&m_iLength );
+ 
+              if(m_sClient != 0)
+                     return m_sClient;
+ 
+              return NULL;
+       }
+       else
+       {
+              return NULL;
+       }
+}
+ 
+char* CSocket::clientRecieve(int m_sClient, int *size)
+{
+       if(m_bServerOnline)
+       {
+              memset(m_cRecievePacket,0,4096);
+ 
+              int m_iReturn = recv(m_sClient,m_cRecievePacket,4096,0);
+              
+              if(m_iReturn > 0){
+					 if(size)
+						 *size = m_iReturn;
+
+                     return m_cRecievePacket;
+			  }
+
+              if(m_iReturn != 0)
+                     return NULL;
+
+              return NULL;
+       }
+       else
+       {
+              return NULL;
+       }
+}
+ 
+int CSocket::clientSend(int m_sClient, char* m_cPacket)
+{
+       return send(m_sClient,m_cPacket,strlen(m_cPacket),0);
+}
+int CSocket::clientSend(int m_sClient, u8* m_cPacket, int len){
+	return send(m_sClient,(char*)m_cPacket,len,0);
+}
+ 
+//-------------------------------------------------------------------
+// Remote connections functions
+//-------------------------------------------------------------------
+ 
+int CSocket::remoteConnect(char* m_IP, int m_iPort)
+{
+    int m_sConnection = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
+     
+	memset(&m_siServerInfo, 0, sizeof(m_siServerInfo));
+	m_siServerInfo.sin_len = sizeof(m_siServerInfo);
+	m_siServerInfo.sin_family = AF_INET;
+	inet_pton(AF_INET, m_IP, &m_siServerInfo.sin_addr);
+	m_siServerInfo.sin_port = htons(m_iPort);
+
+	int ret = connect(m_sConnection, (struct sockaddr*)&m_siServerInfo, sizeof(m_siServerInfo));
+	if (ret)
+		return -1;
+
+	return m_sConnection;
+}
+
+int CSocket::remoteRecieve(int m_sConnection, char* m_cRemoteBuffer, int m_iLength)
+{
+       memset(m_cRemoteBuffer,0,m_iLength);
+       int m_iReturn = recv(m_sConnection,m_cRemoteBuffer,m_iLength,0);
+ 
+       return m_iReturn;
+}
+ 
+char* CSocket::remoteRetrieveCookies(char* m_cRemoteBuffer)
+{
+       char* m_cCookies = strstr(m_cRemoteBuffer,"Set-Cookie:");
+ 
+       if(m_cCookies)
+       {
+              char* m_cCookie = (char*)malloc(1024);
+              memset(m_cCookie,0,1024);
+              
+              while(strstr(m_cCookies,"Set-Cookie:"))
+              {
+                     m_cCookies = strstr(m_cCookies,"Set-Cookie:");
+                     m_cCookies += strlen("Set-Cookie:");
+                     *m_cCookies++;
+                     
+                     strncat(m_cCookie,m_cCookies,strstr(m_cCookies,";")-m_cCookies);
+ 
+                     if(strstr(m_cCookies,"Set-Cookie:"))
+                            strcat(m_cCookie,"; ");
+              }
+ 
+              return m_cCookie;
+       }
+       else
+       {
+              return NULL;
+       }
+ 
+       return NULL;
+}
+ 
+int CSocket::remoteGET(int m_sConnection, char* m_cHost, char* m_cPath, char* m_cReferer, char* m_cCookies)
+{
+       char* m_cCompleteBuffer = (char*)malloc(2096);
+ 
+       sprintf(m_cCompleteBuffer,
+              "GET %s " 
+              "HTTP/1.1\r\n"
+              "Host: %s\r\n"
+              "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3\r\n"
+              "Keep-Alive: 300\r\n"
+              "Connection: keep-alive\r\n"
+              ,m_cPath
+              ,m_cHost);
+
+       if(m_cReferer)
+       {
+              strcat(m_cCompleteBuffer,"Referer: ");
+              strcat(m_cCompleteBuffer,m_cReferer);
+              if(m_cCookies)
+                     strcat(m_cCompleteBuffer,"\r\n");
+              else
+                     strcat(m_cCompleteBuffer,"\r\n\r\n");
+       }
+ 
+       if(m_cCookies)
+       {
+              strcat(m_cCompleteBuffer,"Cookie: ");
+              strcat(m_cCompleteBuffer,m_cCookies);
+              strcat(m_cCompleteBuffer,"\r\n\r\n");
+       }
+ 
+       int m_iReturn = send(m_sConnection,m_cCompleteBuffer,strlen(m_cCompleteBuffer),0);
+       
+       free(m_cCompleteBuffer);
+ 
+       return m_iReturn;
+}
+ 
+int CSocket::remotePOST(int m_sConnection, char* m_cHost, char* m_cPath, char* m_cData, char* m_cReferer, char* m_cCookies)
+{
+       char* m_cCompleteBuffer = (char*)malloc(2096);
+ 
+       if(m_cCookies)
+       {
+              sprintf(m_cCompleteBuffer,
+                     "POST %s "
+                     "HTTP/1.1\r\n"
+                     "Host: %s\r\n"
+                     "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3\r\n"
+                     "Referer: %s\r\n"
+                     "Keep-Alive: 300\r\n"
+                     "Connection: keep-alive\r\n"
+                     "Cookie: %s\r\n"
+                     ,m_cPath
+                     ,m_cHost
+                     ,m_cReferer
+                     ,m_cCookies);
+       }
+       else
+       {
+              sprintf(m_cCompleteBuffer,
+                     "POST %s "
+                     "HTTP/1.1\r\n"
+                     "Host: %s\r\n"
+                     "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3\r\n"
+                     "Referer: %s\r\n"
+                     "Keep-Alive: 300\r\n"
+                     "Connection: keep-alive\r\n"
+                     ,m_cPath
+                     ,m_cHost
+                     ,m_cReferer);
+       }
+ 
+       char* m_cDummy  = "Content-Type: application/x-www-form-urlencoded\r\n";
+       char* m_cDummy2 = (char*)malloc(128);
+ 
+       int m_iLength = strlen(m_cData);
+ 
+       sprintf(m_cDummy2,"Content-Length: %i\r\n\r\n",m_iLength);
+ 
+       int m_iReturn = send(m_sConnection,m_cCompleteBuffer,strlen(m_cCompleteBuffer),0);
+       
+       if(m_iReturn)
+       {
+              m_iReturn = send(m_sConnection,m_cDummy,strlen(m_cDummy),0);
+              
+              if(m_iReturn)
+              {
+                     m_iReturn = send(m_sConnection,m_cDummy2,strlen(m_cDummy2),0);
+                            
+                            if(m_iReturn)
+                            {
+                                   m_iReturn = send(m_sConnection,m_cData,strlen(m_cData),0);
+ 
+                                   if(m_iReturn)
+                                   {
+                                          free(m_cDummy2);
+                                          free(m_cCompleteBuffer);
+                                          return m_iReturn;
+                                   }
+                            }
+              }
+       }
+ 
+       free(m_cDummy2);
+       free(m_cCompleteBuffer);
+ 
+       return m_iReturn;
+}
+
+//Deletes HTTP headers
+char* CSocket::clearBuffer(char* buffer){
+	bool end = false;
+	bool old = false;
+	while(!end){
+		if(*buffer == '\0')
+			break;
+		else if(*buffer == '\n'){
+			if(!old)
+				old = true;
+			else
+				end = true;
+		}else if(*buffer == '\r'){}
+		else
+			old = false;	
+		
+		buffer++;
+	}
+
+	return buffer;
+}
+#include <psl1ght/lv2/net.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#pragma once
+ 
+class CSocket
+{
+private:
+
+    //-------------------------------------------------------------------
+    // Variable declarations
+    //-------------------------------------------------------------------
+	int conn_s;
+	int list_s;
+
+	sockaddr_in m_siServerInfo; // server information
+    bool m_bServerOnline; // is server online
+	char *m_cRecievePacket; // buffer that the recv from any client will be put into
+ 
+public: 
+	//-------------------------------------------------------------------
+	// Constructor / Destructor
+	//-------------------------------------------------------------------
+	CSocket(); // constructor
+	~CSocket(); // destructor
+       
+	int disconnectSocket(int m_sConnection); // close connection
+	int disconnect(); // close connection
+ 
+    //-------------------------------------------------------------------
+    // Server functions
+    //-------------------------------------------------------------------
+    bool initializeServer(int m_iPort); // initialize a server
+    int acceptClient(); // accept client - this should be looped as it is the listener for clients
+	char *clientRecieve(int m_sClient, int *size); // recieve from a client - buffer will be moved to m_cRecievePacket
+	int clientSend(int m_sClient, char* m_cPacket); // send packet/buffer to client / socket
+	int clientSend(int m_sClient, u8* m_cPacket, int len); // send packet/buffer to client / socket
+
+    //-------------------------------------------------------------------
+    // Remote connections functions
+    //-------------------------------------------------------------------
+	int remoteConnect(char* m_IP, int m_iPort); // connect to ip / host
+	int remoteRecieve(int m_sConnection, char* m_cRemoteBuffer, int m_iLength); // recieve buffer
+	char *remoteRetrieveCookies(char* m_cRemoteBuffer); // retrieve cookies from buffer
+       
+	int remoteGET(int m_sConnection, char* m_cHost, char* m_cPath, char* m_cReferer, char* m_cCookies); // GET a page, basically visit a website
+	int remotePOST(int m_sConnection, char* m_cHost, char* m_cPath, char* m_cData, char* m_cReferer, char* m_cCookies); // POST a form, for posting forms on a web-site
+
+	char *clearBuffer(char* buffer);
+};

bin/DEL.PNG

Added
New image

bin/DEL.psd

Added
New image

bin/MASK2.PNG

Old
Old image
New
New image
+#include "blowfish.h"
+
+#define S(x,i)			(SBoxes[i][x.w.byte##i])
+#define bf_F(x)			(((S(x,0) + S(x,1)) ^ S(x,2)) + S(x,3))
+#define ROUND(a,b,n)	(a.dword ^= bf_F(b) ^ PArray[n])
+
+#define MAXKEYBYTES 	56		// 448 bits max
+#define NPASS           16		// SBox passes
+
+//-------------------------------------------------------------------------
+
+union aword
+{
+	u32 dword;
+	u8 byte[4];
+	struct
+	{
+		unsigned int byte3 : 8;
+		unsigned int byte2 : 8;
+		unsigned int byte1 : 8;
+		unsigned int byte0 : 8;
+	} w;
+};
+
+//-------------------------------------------------------------------------
+
+static u32 bf_P[NPASS + 2] =
+{
+	0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+	0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+	0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+	0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+	0x9216d5d9, 0x8979fb1b,
+};
+
+static u32 bf_S[4][256] =
+{
+	0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+	0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+	0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+	0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+	0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+	0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+	0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+	0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+	0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+	0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+	0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+	0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+	0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+	0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+	0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+	0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+	0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+	0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+	0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+	0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+	0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+	0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+	0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+	0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+	0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+	0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+	0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+	0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+	0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+	0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+	0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+	0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
+
+	0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+	0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+	0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+	0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+	0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+	0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+	0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+	0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+	0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+	0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+	0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+	0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+	0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+	0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+	0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+	0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+	0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+	0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+	0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+	0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+	0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+	0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+	0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+	0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+	0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+	0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+	0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+	0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+	0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+	0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+	0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+	0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
+
+	0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+	0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+	0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+	0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+	0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+	0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+	0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+	0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+	0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+	0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+	0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+	0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+	0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+	0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+	0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+	0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+	0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+	0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+	0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+	0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+	0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+	0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+	0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+	0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+	0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+	0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+	0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+	0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+	0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+	0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+	0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+	0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+
+	0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+	0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+	0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+	0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+	0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+	0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+	0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+	0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+	0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+	0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+	0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+	0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+	0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+	0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+	0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+	0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+	0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+	0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+	0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+	0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+	0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+	0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+	0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+	0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+	0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+	0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+	0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+	0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+	0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+	0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+	0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+	0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
+};
+
+//-------------------------------------------------------------------------
+
+cBlowFish::cBlowFish()
+{
+}
+
+//-------------------------------------------------------------------------
+
+cBlowFish::~cBlowFish()
+{
+}
+
+//-------------------------------------------------------------------------
+
+// the low level(private) encryption function
+void cBlowFish::Blowfish_encipher(u32 *xl, u32 *xr)
+{
+	union aword Xl, Xr;
+
+	Xl.dword = *xl;
+	Xr.dword = *xr;
+
+	Xl.dword ^= PArray [0];
+	ROUND(Xr, Xl, 1);  ROUND(Xl, Xr, 2);
+	ROUND(Xr, Xl, 3);  ROUND(Xl, Xr, 4);
+	ROUND(Xr, Xl, 5);  ROUND(Xl, Xr, 6);
+	ROUND(Xr, Xl, 7);  ROUND(Xl, Xr, 8);
+	ROUND(Xr, Xl, 9);  ROUND(Xl, Xr, 10);
+	ROUND(Xr, Xl, 11); ROUND(Xl, Xr, 12);
+	ROUND(Xr, Xl, 13); ROUND(Xl, Xr, 14);
+	ROUND(Xr, Xl, 15); ROUND(Xl, Xr, 16);
+	Xr.dword ^= PArray [17];
+	
+	*xr = Xl.dword;
+	*xl = Xr.dword;
+}
+
+//-------------------------------------------------------------------------
+
+// the low level(private) decryption function
+void cBlowFish::Blowfish_decipher(u32 *xl, u32 *xr)
+{
+   union aword  Xl;
+   union aword  Xr;
+
+   Xl.dword = *xl;
+   Xr.dword = *xr;
+
+   Xl.dword ^= PArray [17];
+   ROUND(Xr, Xl, 16);  ROUND(Xl, Xr, 15);
+   ROUND(Xr, Xl, 14);  ROUND(Xl, Xr, 13);
+   ROUND(Xr, Xl, 12);  ROUND(Xl, Xr, 11);
+   ROUND(Xr, Xl, 10);  ROUND(Xl, Xr, 9);
+   ROUND(Xr, Xl, 8);   ROUND(Xl, Xr, 7);
+   ROUND(Xr, Xl, 6);   ROUND(Xl, Xr, 5);
+   ROUND(Xr, Xl, 4);   ROUND(Xl, Xr, 3);
+   ROUND(Xr, Xl, 2);   ROUND(Xl, Xr, 1);
+   Xr.dword ^= PArray[0];
+
+   *xl = Xr.dword;
+   *xr = Xl.dword;
+}
+
+//-------------------------------------------------------------------------
+
+// constructs the enctryption sieve
+void cBlowFish::Initialize(u8 key[], int keybytes)
+{
+	int  		i, j;
+	u32  		data, datal, datar;
+	union aword temp;
+
+	// first fill arrays from data tables
+	for(i = 0; i < 18; i++)
+		PArray [i] = bf_P [i];
+
+	for(i = 0; i < 4; i++)
+	{
+	 	for(j = 0; j < 256; j++)
+	 		SBoxes [i][j] = bf_S [i][j];
+	}
+
+	j = 0;
+	for(i = 0; i < NPASS + 2; ++i)
+	{
+		temp.dword = 0;
+		temp.w.byte0 = key[j];
+		temp.w.byte1 = key[(j+1) % keybytes];
+		temp.w.byte2 = key[(j+2) % keybytes];
+		temp.w.byte3 = key[(j+3) % keybytes];
+		data = temp.dword;
+		
+		PArray [i] ^= data;
+		
+		j =(j + 4) % keybytes;
+	}
+
+	datal = 0;
+	datar = 0;
+
+	for(i = 0; i < NPASS + 2; i += 2)
+	{
+		Blowfish_encipher(&datal, &datar);
+		PArray [i] = datal;
+		PArray [i + 1] = datar;
+	}
+
+	for(i = 0; i < 4; ++i)
+	{
+		for(j = 0; j < 256; j += 2)
+		{
+		  Blowfish_encipher(&datal, &datar);
+		  SBoxes[i][j] = datal;
+		  SBoxes[i][j + 1] = datar;
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+
+// get output length, which must be even MOD 8
+u32 cBlowFish::GetOutputLength(u32 lInputLong)
+{
+	u32 lVal = 0;
+	lVal = lInputLong % 8;	// find out if uneven number of bytes at the end
+	if(lVal != 0)
+		return lInputLong + 8 - lVal;
+	else
+		return lInputLong;
+}
+
+//-------------------------------------------------------------------------
+
+// Encode pIntput into pOutput.  Input length in lSize.  Returned value
+// is length of output which will be even MOD 8 bytes.  Input buffer and
+// output buffer can be the same, but be sure buffer length is even MOD 8.
+u32 cBlowFish::Encode(u8 * pInput, u8 * pOutput, u32 lSize)
+{
+	u32 	lCount, lOutSize, lGoodBytes;
+	u8	*pi, *po;
+	int		i, j;
+	int		SameDest =(pInput == pOutput ? 1 : 0);
+
+	lOutSize = GetOutputLength(lSize);
+	for(lCount = 0; lCount < lOutSize; lCount += 8)
+	{
+		if(SameDest)	// if encoded data is being written into input buffer
+		{
+		 	if(lCount < lSize - 7)	// if not dealing with uneven bytes at end
+		 	{
+		 	 	Blowfish_encipher((u32 *) pInput, (u32 *)(pInput + 4));
+		 	}
+		 	else		// pad end of data with null bytes to complete encryption
+		 	{
+				po = pInput + lSize;	// point at byte past the end of actual data
+				j =(int)(lOutSize - lSize);	// number of bytes to set to null
+				for(i = 0; i < j; i++)
+					*po++ = 0;
+		 	 	Blowfish_encipher((u32 *) pInput, (u32 *)(pInput + 4));
+		 	}
+		 	pInput += 8;
+		}
+		else 			// output buffer not equal to input buffer, so must copy
+		{               // input to output buffer prior to encrypting
+		 	if(lCount < lSize - 7)	// if not dealing with uneven bytes at end
+		 	{
+		 		pi = pInput;
+		 		po = pOutput;
+		 		for(i = 0; i < 8; i++)
+					// copy bytes to output
+		 			*po++ = *pi++;
+		 	 	// now encrypt them
+				Blowfish_encipher((u32 *) pOutput, (u32 *)(pOutput + 4));
+		 	}
+		 	else		// pad end of data with null bytes to complete encryption
+		 	{
+		 		lGoodBytes = lSize - lCount;	// number of remaining data bytes
+		 		po = pOutput;
+		 		for(i = 0; i <(int) lGoodBytes; i++)
+		 			*po++ = *pInput++;
+		 		for(j = i; j < 8; j++)
+		 			*po++ = 0;
+		 	 	Blowfish_encipher((u32 *) pOutput, (u32 *)(pOutput + 4));
+		 	}
+		 	pInput += 8;
+		 	pOutput += 8;
+		}
+	}
+	return lOutSize;
+}
+
+//-------------------------------------------------------------------------
+
+// Decode pIntput into pOutput.  Input length in lSize.  Input buffer and
+// output buffer can be the same, but be sure buffer length is even MOD 8.
+void cBlowFish::Decode(u8 * pInput, u8 * pOutput, u32 lSize)
+{
+	u32 	lCount;
+	u8	*pi, *po;
+	int		i;
+	int		SameDest =(pInput == pOutput ? 1 : 0);
+
+	for(lCount = 0; lCount < lSize; lCount += 8)
+	{
+		if(SameDest)	// if encoded data is being written into input buffer
+		{
+	 	 	Blowfish_decipher((u32 *) pInput, (u32 *)(pInput + 4));
+		 	pInput += 8;
+		}
+		else 			// output buffer not equal to input buffer
+		{               // so copy input to output before decoding
+	 		pi = pInput;
+	 		po = pOutput;
+	 		for(i = 0; i < 8; i++)
+	 			*po++ = *pi++;
+	 	 	Blowfish_decipher((u32 *) pOutput, (u32 *)(pOutput + 4));
+		 	pInput += 8;
+		 	pOutput += 8;
+		}
+	}
+}
+
+//-------------------------------------------------------------------------
+#ifndef BLOWFISH_H
+#define BLOWFISH_H
+
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <errno.h>
+#include <psl1ght/types.h>
+
+class cBlowFish
+{
+private:
+	u32 		PArray[18];
+	u32		SBoxes[4][256];
+	void 		Blowfish_encipher(u32 *xl, u32 *xr);
+	void 		Blowfish_decipher(u32 *xl, u32 *xr);
+
+public:
+	cBlowFish();
+	~cBlowFish();
+	void 		Initialize(u8 key[], int keybytes);
+	u32		GetOutputLength(u32 lInputLong);
+	u32		Encode(u8 * pInput, u8 * pOutput, u32 lSize);
+	void		Decode(u8 * pInput, u8 * pOutput, u32 lSize);
+};
+
+#endif
+/* Crc - 32 BIT ANSI X3.66 CRC checksum files */
+
+#include "crc32.h"
+
+#ifdef __TURBOC__
+ #pragma warn -cln
+#endif
+
+/**********************************************************************\
+|* Demonstration program to compute the 32-bit CRC used as the frame  *|
+|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71     *|
+|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level     *|
+|* protocol).  The 32-bit FCS was added via the Federal Register,     *|
+|* 1 June 1982, p.23798.  I presume but don't know for certain that   *|
+|* this polynomial is or will be included in CCITT V.41, which        *|
+|* defines the 16-bit CRC (often called CRC-CCITT) polynomial.  FIPS  *|
+|* PUB 78 says that the 32-bit FCS reduces otherwise undetected       *|
+|* errors by a factor of 10^-5 over 16-bit FCS.                       *|
+\**********************************************************************/
+
+/* Need an unsigned type capable of holding 32 bits; */
+
+typedef u32 UNS_32_BITS;
+
+/* Copyright (C) 1986 Gary S. Brown.  You may use this program, or
+   code or tables extracted from it, as desired without restriction.*/
+
+/* First, the polynomial itself and its table of feedback terms.  The  */
+/* polynomial is                                                       */
+/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
+/* Note that we take it "backwards" and put the highest-order term in  */
+/* the lowest-order bit.  The X^32 term is "implied"; the LSB is the   */
+/* X^31 term, etc.  The X^0 term (usually shown as "+1") results in    */
+/* the MSB being 1.                                                    */
+
+/* Note that the usual hardware shift register implementation, which   */
+/* is what we're using (we're merely optimizing it by doing eight-bit  */
+/* chunks at a time) shifts bits into the lowest-order term.  In our   */
+/* implementation, that means shifting towards the right.  Why do we   */
+/* do it this way?  Because the calculated CRC must be transmitted in  */
+/* order from highest-order term to lowest-order term.  UARTs transmit */
+/* characters in order from LSB to MSB.  By storing the CRC this way,  */
+/* we hand it to the UART in the order low-byte to high-byte; the UART */
+/* sends each low-bit to hight-bit; and the result is transmission bit */
+/* by bit from highest- to lowest-order term without requiring any bit */
+/* shuffling on our part.  Reception works similarly.                  */
+
+/* The feedback terms table consists of 256, 32-bit entries.  Notes:   */
+/*                                                                     */
+/*  1. The table can be generated at runtime if desired; code to do so */
+/*     is shown later.  It might not be obvious, but the feedback      */
+/*     terms simply represent the results of eight shift/xor opera-    */
+/*     tions for all combinations of data and CRC register values.     */
+/*                                                                     */
+/*  2. The CRC accumulation logic is the same for all CRC polynomials, */
+/*     be they sixteen or thirty-two bits wide.  You simply choose the */
+/*     appropriate table.  Alternatively, because the table can be     */
+/*     generated at runtime, you can start by generating the table for */
+/*     the polynomial in question and use exactly the same "updcrc",   */
+/*     if your application needn't simultaneously handle two CRC       */
+/*     polynomials.  (Note, however, that XMODEM is strange.)          */
+/*                                                                     */
+/*  3. For 16-bit CRCs, the table entries need be only 16 bits wide;   */
+/*     of course, 32-bit entries work OK if the high 16 bits are zero. */
+/*                                                                     */
+/*  4. The values must be right-shifted by eight bits by the "updcrc"  */
+/*     logic; the shift must be unsigned (bring in zeroes).  On some   */
+/*     hardware you could probably optimize the shift in assembler by  */
+/*     using byte-swap instructions.                                   */
+
+static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
+0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+u32 updateCRC32(unsigned char ch, u32 crc)
+{
+      return crc_32_tab[((int)crc ^ ch) & 0xff] ^ ((crc >> 8) & 0x00FFFFFF);
+}
+
+bool crc32file(char *name, u32 *crc, long *charcnt)
+{
+      register FILE *fin;
+      register u32 oldcrc32;
+      register int c;
+
+      oldcrc32 = 0xFFFFFFFF; *charcnt = 0;
+#ifdef MSDOS
+      if ((fin=fopen(name, "rb"))==NULL)
+#else
+      if ((fin=fopen(name, "r"))==NULL)
+#endif
+      {
+            perror(name);
+            return -1;
+      }
+      while ((c=getc(fin))!=EOF)
+      {
+            ++*charcnt;
+			oldcrc32 = crc_32_tab[((int)oldcrc32 ^ c) & 0xff] ^ ((oldcrc32 >> 8) & 0x00FFFFFF);
+      }
+
+      if (ferror(fin))
+      {
+            perror(name);
+            *charcnt = -1;
+      }
+      fclose(fin);
+
+      *crc = oldcrc32 = ~oldcrc32;
+
+      return 1;
+}
+
+u32 crc32buf(char *buf, size_t len)
+{
+      register u32 oldcrc32;
+
+      oldcrc32 = 0xFFFFFFFF;
+
+      for ( ; len; --len, ++buf)
+      {
+            oldcrc32 = crc_32_tab[((int)oldcrc32 ^ *buf) & 0xff] ^ ((oldcrc32 >> 8) & 0x00FFFFFF);
+      }
+
+      return ~oldcrc32;
+      
+}
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <errno.h>
+#include <psl1ght/types.h>
+
+u32 crc32buf(char *buf, size_t len);
+#include "font.h"
+
+int ttf_inited;
+FT_Library f_freetype;
+FT_Face f_face;
+
+int TTFLoadFont(char * path, void * from_memory, int size_from_memory)
+{
+   
+    if(!ttf_inited)
+        FT_Init_FreeType(&f_freetype);
+    ttf_inited = 1;
+
+    if(path) {
+        if(FT_New_Face(f_freetype, path, 0, &f_face)) return -1;
+    } else {
+        if(FT_New_Memory_Face(f_freetype, (const FT_Byte*)from_memory, size_from_memory, 0, &f_face)) return -1;
+    }
+
+    return 0;
+}
+
+void TTFUnloadFont()
+{
+   FT_Done_FreeType(f_freetype);
+   ttf_inited = 0;
+}
+
+void TTF_toBitmap(u8 chr, u8 * bitmap, short *w, short *h, short *y_correction)
+{
+    FT_Set_Pixel_Sizes(f_face, (*w), (*h));
+    
+    FT_GlyphSlot slot = f_face->glyph;
+
+    memset(bitmap, 0, (*w) * (*h));
+
+    if(FT_Load_Char(f_face, (char) chr, FT_LOAD_RENDER )) {(*w) = 0; return;}
+
+    int n, m, ww;
+
+    *y_correction = (*h) - 1 - slot->bitmap_top;
+    
+    ww = 0;
+
+    for(n = 0; n < slot->bitmap.rows; n++) {
+        for (m = 0; m < slot->bitmap.width; m++) {
+
+            if(m >= (*w) || n >= (*h)) continue;
+            
+            bitmap[m] = (u8) slot->bitmap.buffer[ww + m];
+        }
+    
+    bitmap += *w;
+
+    ww += slot->bitmap.width;
+    }
+
+    *w = ((slot->advance.x + 31) >> 6) + ((slot->bitmap_left < 0) ? -slot->bitmap_left : 0);
+    *h = slot->bitmap.rows;
+}
+#ifndef FONT_H
+#define FONT_H
+
+#include <libfont.h>
+#include <ft2build.h>
+#include <freetype/freetype.h> 
+#include <freetype/ftglyph.h>
+
+int TTFLoadFont(char * path, void * from_memory, int size_from_memory);
+void TTFUnloadFont();
+void TTF_toBitmap(u8 chr, u8 * bitmap, short *w, short *h, short *y_correction);
+
+#endif
+#include "graphics.h"
+
+void DrawTexture2d(float x, float y, float dx, float dy, u32 texture_offset, PngDatas texture)
+{
+    tiny3d_SetTexture(0, texture_offset, texture.width, texture.height, texture.wpitch, TINY3D_TEX_FORMAT_A8R8G8B8, 1);
+    tiny3d_SetPolygon(TINY3D_QUADS);
+	
+    tiny3d_VertexPos(x  , y  , 1);   
+    tiny3d_VertexColor(0xFFFFFFFF);
+    tiny3d_VertexTexture(0.0f, 0.0f);
+
+    tiny3d_VertexPos(x + dx, y  , 1);
+    tiny3d_VertexTexture(0.99f, 0.0f);
+
+    tiny3d_VertexPos(x + dx, y + dy, 1);
+    tiny3d_VertexTexture(0.99f, 0.99f);
+
+    tiny3d_VertexPos(x  , y + dy, 1);
+    tiny3d_VertexTexture(0.0f, 0.99f);
+    tiny3d_End();
+}
+
+void DrawTextureRect2d(int x, int y, int w, int h, RECT rect, u32 texture_offset, PngDatas texture)
+{
+    tiny3d_SetTexture(0, texture_offset, texture.width, texture.height, texture.wpitch, TINY3D_TEX_FORMAT_A8R8G8B8, 1);
+    tiny3d_SetPolygon(TINY3D_QUADS);
+
+    tiny3d_VertexPos(x  , y  , 1);   
+    tiny3d_VertexColor(0xFFFFFFFF);
+    tiny3d_VertexTexture(rect.x / w, rect.y / h);
+	
+	tiny3d_VertexPos(rect.x2, y  , 1);
+	tiny3d_VertexTexture(rect.x / w, rect.y / h);
+
+	tiny3d_VertexPos(rect.x2, rect.y2, 1);
+	tiny3d_VertexTexture(rect.x2 / w, rect.y2 / h);
+
+	tiny3d_VertexPos(x  , rect.y2, 1);
+    tiny3d_VertexTexture(0.0f, rect.y2 / h);
+    tiny3d_End();
+}
+
+void DrawBackground2D(u32 rgba)
+{
+    tiny3d_SetPolygon(TINY3D_QUADS);
+
+    tiny3d_VertexPos(0  , 0  , 65535);
+    tiny3d_VertexColor(rgba);
+
+    tiny3d_VertexPos(847, 0  , 65535);
+
+    tiny3d_VertexPos(847, 511, 65535);
+
+    tiny3d_VertexPos(0  , 511, 65535);
+    tiny3d_End();
+}
+
+
+struct _SIZE GetTextSize(int sx, int sy, const char* str){
+
+	u8 *buf = (u8 *) str;
+
+	long width = 0;
+	long height = 0;
+	struct _SIZE rSize = {0};
+
+	while(*buf) {
+
+		if(*buf == '\n') {width = 0; height += sy;}
+		else if(*buf == 9) width+=sx;
+		else if(*buf >= sy) {
+			width+=sx;
+		}
+
+		buf++;
+		
+		if(width > rSize.width) rSize.width = width;
+
+		if(width < 0) width= 0;
+		if(width > (848-sx)) {width= 0; height+= sy;}
+		if(height < 0) height= 0;
+		if(height > (512-sy)) { rSize.height = -1; }
+	
+		if(rSize.height != -1) rSize.height = height;
+
+	}
+
+	if( rSize.height == 0 )
+		 rSize.height = sy;
+
+	return rSize;
+}
+
+void AdjustViewport( float x, float y )
+{
+	double sx = (double) Video_Resolution.width;
+	double sy = (double) Video_Resolution.height;
+	double px = (double) (1000 + x)/1000.0;
+	double py = (double) (1000 + y)/1000.0;
+
+	tiny3d_UserViewport( 1,
+						(float) ((sx - sx * px) / 2.0), // 2D position
+						(float) ((sy - sy * py) / 2.0),
+						(float) ((sx * px) / 848.0),    // 2D scale
+						(float) ((sy * py) / 512.0),
+						(((float) Video_Resolution.width) / 1920.0f) * (float) (1000 + x)/1000.0f,  // 3D scale
+						(((float) Video_Resolution.height) / 1080.0f) * (float) (1000 + y)/1000.0f);
+
+
+
+}
+#include "headers.h"
+
+typedef struct RECT{
+	float x;
+	float y;
+	float x2;
+	float y2;
+}RECT;
+
+void DrawTexture2d(float x, float y, float dx, float dy, u32 texture_offset, PngDatas texture);
+void DrawTextureRect2d(int x, int y, int w, int h, RECT rect, u32 texture_offset, PngDatas texture);
+void DrawBackground2D(u32 rgba);
+struct _SIZE GetTextSize(int sx, int sy, const char* str);
+void AdjustViewport( float x, float y );
+#ifndef HEADERS_H
+#define HEADERS_H
+
+// ----- GLOBAL INCLUDES ----- //
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+#include <math.h>
+#include <string.h>
+
+#include <lv2/process.h>
+#include <psl1ght/lv2/thread.h>
+#include <sysmodule/sysmodule.h>
+#include <sysutil/events.h>
+
+#include <sys/stat.h>
+#include <io/msg.h>
+#include <io/pad.h>
+#include <sysmodule/sysmodule.h>
+
+#include <tiny3d.h>
+#include <libfont.h>
+#include <pngdec/loadpng.h>
+
+typedef struct _SIZE{
+	u32 width;
+	u32 height;
+}_SIZE;
+
+#endif
 #include <sys/stat.h>
 #include <sysutil/events.h>
 #include <io/msg.h>
-#include <io/pad.h> 
+#include <io/pad.h> 
 #include <io/mouse.h> 
 #include <sysmodule/sysmodule.h>
 
 
 #include "types.h"
 #include "oskdialog.h"
+#include "graphics.h"
+#include "font.h"
+#include "HTTP.h"
+#include "packet.h"
 
 
+// ----- DEFINES ----- //
+#define N_IMAGES                9       
+#define COOLDOWN_TIME			200
+
+// ----- STRUCTS ----- //
+typedef struct PAD_BLOCK{
+        u8 UP_BLOCKED;
+        u8 DOWN_BLOCKED;
+        u8 LEFT_BLOCKED;
+        u8 RIGHT_BLOCKED;
+        
+        struct timeval UP_COOLDOWN;
+        struct timeval DOWN_COOLDOWN;
+        struct timeval LEFT_COOLDOWN;
+        struct timeval RIGHT_COOLDOWN;
+}PAD_BLOCK;
+
+enum userAction{
+        ACTION_MENU = 0,
+        ACTION_TROPHY_LOAD,
+        ACTION_TROHPY,
+}uAction = ACTION_MENU;
+
+
+
+// ----- VARIABLES ----- //
+static char hdd_folder_installed[64] = "RNA000001"; // folder for program
+
 //Tiny3D Resources
 u32 *texture_mem;
 u32 * texture_pointer;
+PngDatas IMAGES[N_IMAGES]; // PNG container of texture3
+u32 IMAGES_offset[N_IMAGES] = {0}; // offset for texture3 (used to pass the texture)
 
 //SDK modules
 u32 module_flag;
 
+//Store Status
 volatile u8 running = 1;
+u32 menu_sel = 0;
+u8 fade = 0xFF;
+u32 fade_anim = 0;
+PAD_BLOCK pad_block = {0};
+
+struct timeval menu_fade1 = {0};
+struct timeval menu_fade2 = {0};
+
+
+//Inner vars
+OSK *cOSK = NULL;
+char *username = NULL;
+char *md5_pass = NULL;
+s8 login_process = -1;
+
+//Packet referent
+CSocket *csocket = NULL;
+int sock = NULL;
+
+
+// ----- PROTOTYPES ----- //
+void Debug( char *format, ... );
+void drawScene( void );
+void releaseAll( void );
+int loadModules( void );
+void customLoadPNG( void );
+void loadTexture( void );
+void drawScene( void );
+static void sys_callback(uint64_t status, uint64_t param, void* userdata);
+void login_result(unsigned char result);
+
+// ----- CODE ----- //
+
+void Debug(char *format, ...){
+    char str[1024];
+    char filename[1024];
+
+    va_list argp;        
+    va_start(argp, format);
+    vsprintf(str, format, argp);
+    va_end(argp);
+
+    FILE *fDebug;
+    sprintf(filename, "/dev_hdd0/game/%s/USRDIR/log.txt",hdd_folder_installed);
+    fDebug = fopen(filename, "a+");
+
+    fputs(str, fDebug);
+
+    fclose(fDebug);
+}
+
 
 void releaseAll() {
 	
 	sysUnregisterCallback(EVENT_SLOT0);
 	//sys_ppu_thread_join(thread1_id, &retval);
 	
+	delete csocket;
+
 	if(module_flag & 2)
 		SysUnloadModule(SYSMODULE_PNGDEC);
 
 	return 1;
 }
 
-void loadTexture()
-{
-
-    texture_mem = (u32*)tiny3d_AllocTexture(64*1024*1024); // alloc 64MB of space for textures (this pointer can be global)    
-
-    if(!texture_mem) return; // fail!
-
-    texture_pointer = texture_mem;
-}
-
 static void sys_callback(uint64_t status, uint64_t param, void* userdata) {
 
      switch (status) {
 	}
 }
 
+extern void login_result(unsigned char result){
+	login_process = result;
+}
+
+void drawScene(){
+        
+    tiny3d_Project2D();
+        
+    DrawTexture2d(0, 0, 741.5583, 511.0518, IMAGES_offset[0], IMAGES[0]); //MASK 1
+    DrawTexture2d(0, 0, 848, 512, IMAGES_offset[1], IMAGES[1]); //MASK 2
+
+    //MENU FADE (FLECHAS HORIZONTALES)
+    if(fade_anim > 0){
+        gettimeofday(&menu_fade2, NULL);
+
+        u32 d1 = (menu_fade1.tv_sec * 1000) + (menu_fade1.tv_usec / 1000);
+        u32 d2 = (menu_fade2.tv_sec * 1000) + (menu_fade2.tv_usec / 1000);
+
+        u32 at = ((d2 > d1)?d2-d1:d1-d2);
+                
+        if(at > 0){             
+            if(fade_anim == 1){
+                fade = 0xFF - (at * 0xFF / 1000); 
+                if(fade == 0 || (255 - (at * 255 / 1000)) <= 0 ){
+                    gettimeofday(&menu_fade1, NULL);
+                    fade_anim = 2;
+                }
+            }else if(fade_anim == 2){
+                fade = (at * 0xFF / 1000);
+                if(fade == 0xFF || (at * 255 / 1000) >= 255)
+                    fade_anim = 0;
+            }
+        }
+    }
+        
+    //MENU DRAW
+    SetCurrentFont(1);
+    SetFontColor(0xFFFFFF00 + fade, 0x0);
+    SetFontSize(22, 28);
+
+    float x = 625.4, y = 294.4;
+    for(int i = 0; i < 4; i++){
+        if(menu_sel == i)
+            DrawTexture2d(x, y, 34.45, 41.2444, IMAGES_offset[3], IMAGES[3]);
+        else
+            DrawTexture2d(x, y, 34.45, 41.2444, IMAGES_offset[2], IMAGES[2]);
+
+        if(i == 0)
+            DrawString(x + 40, y + 41.2444/2 - 28/2 - 5, "AMIGOS");
+        else if(i == 1)
+            DrawString(x + 40, y + 41.2444/2 - 28/2 - 5, "TROFEOS");
+        else if(i == 2)
+            DrawString(x + 40, y + 41.2444/2 - 28/2 - 5, "SAVES");
+        else if(i == 3)
+            DrawString(x + 40, y + 41.2444/2 - 28/2 - 5, "NETWORK");
+
+        y += 38.8740;
+    }
+
+    x = 632.9083;
+    y = 215.9703;
+        
+	SetFontSize(32, 28);
+    SetFontColor(0xFFFFFFFF, 0x0);  
+    DrawString(x, y, "Bienvenido,\n");
+
+    SetFontColor(0xFFFD00FF, 0x0);
+    DrawString(632.9083 + 30, GetFontY(), username);
+
+
+    switch(uAction){
+        case ACTION_TROPHY_LOAD:{
+			/*
+            sys_ppu_thread_t id;
+            u64 priority = 1500;
+            size_t stack_size = 0x1000;
+            
+			sys_ppu_thread_create(  &id, trophie_sync, (u64)NULL, priority, stack_size, THREAD_JOINABLE, "TROPHY_SYNC");
+
+            msgType mdialogprogress = MSGDIALOG_SINGLE_PROGRESSBAR;
+    
+            msgDialogOpen2(mdialogprogress, "Sincronizando trofeos", my_dialog, (void *) 0x33330001, NULL);
+            msgDialogProgressBarMessage(PROGRESSBAR_INDEX0, "Espere");
+            msgDialogResetProgressBar(PROGRESSBAR_INDEX0);
+   
+            dialog_action = 0;
+            while(!dialog_action){
+                    sysCheckCallback();
+                    tiny3d_Flip();
+            }
+
+            msgDialogClose();
+			*/
+        }break;
+        default:
+            break;
+    }
+}
+
+void customLoadPNG(){
+
+    for(int i = 0; i < N_IMAGES; i++){
+        char filename[1024] = {0};
+
+        if(i==0) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/MASK1.PNG",hdd_folder_installed);
+        if(i==1) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/MASK2.PNG",hdd_folder_installed);
+        if(i==2) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/MENU.PNG",hdd_folder_installed);
+        if(i==3) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/MENUSEL.PNG",hdd_folder_installed);
+        if(i==4) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/LOGO.PNG",hdd_folder_installed);
+        if(i==5) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/CRUCETA.PNG",hdd_folder_installed);
+        if(i==6) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/X.PNG",hdd_folder_installed);
+        if(i==7) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/O.PNG",hdd_folder_installed);
+        if(i==8) sprintf(filename, "/dev_hdd0/game/%s/USRDIR/SQ.PNG",hdd_folder_installed);
+                        
+        memset(&IMAGES[i], 0, sizeof(PngDatas));
+
+        LoadPNG(&(IMAGES[i]), filename);
+    }
+}
+
+void loadTexture()
+{
+    texture_mem = (u32*)tiny3d_AllocTexture(64*1024*1024); // alloc 64MB of space for textures (this pointer can be global)    
+
+    if(!texture_mem) return; // fail!
+
+    texture_pointer = texture_mem;
+   
+    customLoadPNG();
+        
+    for(int i = 0; i < N_IMAGES; i++){
+        IMAGES_offset[i] = 0;
+        if(IMAGES[i].bmp_out){
+            memcpy(texture_pointer, IMAGES[i].bmp_out, IMAGES[i].wpitch * IMAGES[i].height);
+            
+            free(IMAGES[i].bmp_out);
+            IMAGES[i].bmp_out = texture_pointer;
+            texture_pointer += (IMAGES[i].wpitch/4 * IMAGES[i].height + 3) & ~3; 
+            IMAGES_offset[i] = tiny3d_TextureOffset(IMAGES[i].bmp_out);      // get the offset (RSX use offset instead address)
+        }
+    }
+	        
+	cOSK = new OSK(texture_pointer, "/dev_hdd0/game/RNA000001/USRDIR");
+	texture_pointer = cOSK->getTexturePointer();
+
+	ResetFont();
+    char filename[1024] = {0};
+
+    sprintf(filename, "/dev_hdd0/game/%s/USRDIR/Base02.ttf",hdd_folder_installed);
+    TTFLoadFont(filename, (void*)NULL, 0);
+    texture_pointer = (u32 *) AddFontFromTTF((u8 *) texture_pointer, 32, 255, 32, 32, TTF_toBitmap);
+    TTFUnloadFont();    
+                
+    sprintf(filename, "/dev_hdd0/game/%s/USRDIR/Decibel_2.ttf",hdd_folder_installed);
+    TTFLoadFont(filename, (void*)NULL, 0);
+    texture_pointer = (u32 *) AddFontFromTTF((u8 *) texture_pointer, 32, 255, 32, 32, TTF_toBitmap);
+    TTFUnloadFont();    
+	
+	texture_pointer = cOSK->loadFont(2, "/dev_hdd0/game/RNA000001/USRDIR", texture_pointer);	
+}
+
 int main(int argc, const char* argv[], const char* envp[])
 {
 	tiny3d_Init(1024*1024);
 	tiny3d_Project2D();
 
+	AdjustViewport( -70.0f, -50.0f );
+
 	loadModules();
 		
 	ioPadInit(7);
 	
 	sysRegisterCallback(EVENT_SLOT0, sys_callback, NULL);
 
-
-	OSK *cOSK = new OSK(texture_pointer, "/dev_hdd0/game/RNA000001/USRDIR");
-	texture_pointer = cOSK->getTexturePointer();
-
-	texture_pointer = cOSK->loadFont(0, "/dev_hdd0/game/RNA000001/USRDIR", texture_pointer);
-
-	osk_point point = {300, 200};
+	csocket = new CSocket();
+	sock = csocket->remoteConnect("192.168.1.103", 80);
+	
+	osk_point point = {250, 100};
 	cOSK->setPos(point);
 
-	char *buffer = NULL;
+login:
+
+	for(int i = 0; i < 2; i++){
+		cOSK->open();
+
+		while(cOSK->getStatus() != OSK_RETURN){
+			tiny3d_Clear(0xff000000, TINY3D_CLEAR_ALL);
+
+			// Enable alpha Test
+			tiny3d_AlphaTest(1, 0x10, TINY3D_ALPHA_FUNC_GEQUAL);
+
+			// Enable alpha blending.
+			tiny3d_BlendFunc(1, (blend_src_func)(TINY3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | TINY3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA),
+				(blend_dst_func)(NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO),
+				(blend_func)(TINY3D_BLEND_RGB_FUNC_ADD | TINY3D_BLEND_ALPHA_FUNC_ADD));
+
+			tiny3d_Project2D();
+
+			cOSK->draw();
+			cOSK->handlePad();
+
+			SetCurrentFont(2);
+			SetFontSize(32, 38);
+			SetFontColor(0xFFFFFFFF, 0x0);
+			
+			if(i == 0)
+				DrawString(250, 80, "Input username...");
+			else if(i == 1)
+				DrawString(250, 80, "Input password...");
+
+			tiny3d_Flip();
+			sysCheckCallback();
+		}
+
+		if(i == 0){
+			username = cOSK->getBuffer();
+			usleep(500000);
+		}else if(i == 1)
+			md5_pass = cOSK->getBuffer();
+	}
+
+	char *temp_md5_pass = send_login(username, md5_pass);
+
+	login_process = -1;
+	while(login_process == -1){
+		tiny3d_Clear(0xff000000, TINY3D_CLEAR_ALL);
+		// Enable alpha Test
+		tiny3d_AlphaTest(1, 0x10, TINY3D_ALPHA_FUNC_GEQUAL);
+		// Enable alpha blending.
+		tiny3d_BlendFunc(1, (blend_src_func)(TINY3D_BLEND_FUNC_SRC_RGB_SRC_ALPHA | TINY3D_BLEND_FUNC_SRC_ALPHA_SRC_ALPHA),
+			(blend_dst_func)(NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO),
+			(blend_func)(TINY3D_BLEND_RGB_FUNC_ADD | TINY3D_BLEND_ALPHA_FUNC_ADD));
+
+		tiny3d_Project2D();
+
+		DrawString(250, 80, "Wait...");
+
+		tiny3d_Flip();
+		sysCheckCallback();
+	}
+	
+	//free(md5_pass);
+
+	if(login_process == 0){
+		//free(username);
+		goto login;
+	}else
+		md5_pass = temp_md5_pass;
+	
 
 	/*** - MAIN LOOP - ***/
 	while( running ){
-		
-		tiny3d_Clear(0xff555555, TINY3D_CLEAR_ALL);
+		//CLEAR = BG
+		tiny3d_Clear(0xff000000, TINY3D_CLEAR_ALL);
 
         // Enable alpha Test
         tiny3d_AlphaTest(1, 0x10, TINY3D_ALPHA_FUNC_GEQUAL);
             (blend_dst_func)(NV30_3D_BLEND_FUNC_DST_RGB_ONE_MINUS_SRC_ALPHA | NV30_3D_BLEND_FUNC_DST_ALPHA_ZERO),
             (blend_func)(TINY3D_BLEND_RGB_FUNC_ADD | TINY3D_BLEND_ALPHA_FUNC_ADD));
 
-		tiny3d_Project2D();
+		
+		struct timeval tnow;
+        gettimeofday(&tnow, NULL);
+        long cur_time = (tnow.tv_sec * 1000 + tnow.tv_usec/1000);
 
-		if(cOSK->getStatus() == OSK_INITIALIZED)
-			cOSK->open();
-		else if(cOSK->getStatus() == OSK_RUNNING){
-			cOSK->draw();
-			cOSK->handlePad();
-		}else if(cOSK->getStatus() == OSK_RETURN)
-			buffer = cOSK->getBuffer();
-		else if(cOSK->getStatus() == OSK_END)
-			DrawString(200, 200, buffer);
+        //EVITAR USO CONTINUO DEL PAD, BLOQUEAR DURANTE 500 MILISEC
+        //RUTINA DE DESBLOQUEO:
+        if(pad_block.UP_BLOCKED){
+            if( (cur_time - (pad_block.UP_COOLDOWN.tv_sec * 1000 + pad_block.UP_COOLDOWN.tv_usec/1000) >= COOLDOWN_TIME) ||
+                    ((pad_block.UP_COOLDOWN.tv_sec * 1000 + pad_block.UP_COOLDOWN.tv_usec/1000) - cur_time >= COOLDOWN_TIME))
+				pad_block.UP_BLOCKED = false;
+        }
+        if(pad_block.DOWN_BLOCKED){
+            if( (cur_time - (pad_block.DOWN_COOLDOWN.tv_sec * 1000 + pad_block.DOWN_COOLDOWN.tv_usec/1000) >= COOLDOWN_TIME) ||
+                    ((pad_block.DOWN_COOLDOWN.tv_sec * 1000 + pad_block.DOWN_COOLDOWN.tv_usec/1000) - cur_time >= COOLDOWN_TIME))
+                pad_block.DOWN_BLOCKED = false;
+        }
+        if(pad_block.LEFT_BLOCKED){
+            if( (cur_time - (pad_block.LEFT_COOLDOWN.tv_sec * 1000 + pad_block.LEFT_COOLDOWN.tv_usec/1000) >= COOLDOWN_TIME) ||
+                    ((pad_block.LEFT_COOLDOWN.tv_sec * 1000 + pad_block.LEFT_COOLDOWN.tv_usec/1000) - cur_time >= COOLDOWN_TIME))
+                 pad_block.LEFT_BLOCKED = false;
+        }
+        if(pad_block.RIGHT_BLOCKED){
+            if( (cur_time - (pad_block.RIGHT_COOLDOWN.tv_sec * 1000 + pad_block.RIGHT_COOLDOWN.tv_usec/1000) >= COOLDOWN_TIME) ||
+                    ((pad_block.RIGHT_COOLDOWN.tv_sec * 1000 + pad_block.RIGHT_COOLDOWN.tv_usec/1000) - cur_time >= COOLDOWN_TIME))
+                pad_block.RIGHT_BLOCKED = false;
+        }
+
+		drawScene();
+                                
+        PadInfo padinfo;
+        PadData paddata;
+        ioPadGetInfo(&padinfo);
+
+        for(int i = 0; i < MAX_PADS; i++){
+            if(padinfo.status[i]){
+                ioPadGetData(i, &paddata);
+                                
+                if(paddata.BTN_DOWN && !pad_block.DOWN_BLOCKED){
+                    if(menu_sel < 4)
+                        menu_sel++;
+
+                    pad_block.DOWN_BLOCKED = 1;
+                    gettimeofday(&pad_block.DOWN_COOLDOWN, NULL);
+                }
+                if(paddata.BTN_UP && !pad_block.UP_BLOCKED){
+                    if(menu_sel > 0)
+                        menu_sel--;
+
+                    pad_block.UP_BLOCKED = 1;
+                    gettimeofday(&pad_block.UP_COOLDOWN, NULL);
+                }
+
+                if(paddata.BTN_LEFT && !pad_block.LEFT_BLOCKED){
+                    fade_anim = 1;
+                    gettimeofday(&menu_fade1, NULL);
+
+                    pad_block.LEFT_BLOCKED = 1;
+                    gettimeofday(&pad_block.LEFT_COOLDOWN, NULL);
+                }
+                if(paddata.BTN_RIGHT && !pad_block.RIGHT_BLOCKED){
+                    fade_anim = 1;
+                    gettimeofday(&menu_fade1, NULL);
+
+                    pad_block.RIGHT_BLOCKED = 1;
+                    gettimeofday(&pad_block.RIGHT_COOLDOWN, NULL);
+                }
+            }
+        }
 				
         tiny3d_Flip();
-
 		sysCheckCallback();
 
 	}
+#include "md5.h"
+
+/* typedef a 32 bit type */
+typedef unsigned long int UINT4;
+
+/* Data structure for MD5 (Message Digest) computation */
+struct MD5_CTX{
+  UINT4 i[2];                   /* number of _bits_ handled mod 2^64 */
+  UINT4 buf[4];                                    /* scratch buffer */
+  unsigned char in[64];                              /* input buffer */
+  unsigned char digest[16];     /* actual digest after MD5Final call */
+} ;
+
+void MD5Init (MD5_CTX *mdContext);
+void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
+void MD5Final (MD5_CTX *mdContext);
+
+/* forward declaration */
+static void Transform (UINT4* buf, UINT4* in);
+
+static unsigned char PADDING[64] = {
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/* F, G and H are basic MD5 functions: selection, majority, parity */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z))) 
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
+/* Rotation is separate from addition to prevent recomputation */
+#define FF(a, b, c, d, x, s, ac) \
+  {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) \
+  {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) \
+  {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) \
+  {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+   (a) = ROTATE_LEFT ((a), (s)); \
+   (a) += (b); \
+  }
+
+void MD5Init (MD5_CTX *mdContext)
+{
+  mdContext->i[0] = mdContext->i[1] = (UINT4)0;
+
+  /* Load magic initialization constants.
+   */
+  mdContext->buf[0] = (UINT4)0x67452301;
+  mdContext->buf[1] = (UINT4)0xefcdab89;
+  mdContext->buf[2] = (UINT4)0x98badcfe;
+  mdContext->buf[3] = (UINT4)0x10325476;
+}
+
+void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* update number of bits */
+  if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
+    mdContext->i[1]++;
+  mdContext->i[0] += ((UINT4)inLen << 3);
+  mdContext->i[1] += ((UINT4)inLen >> 29);
+
+  while (inLen--) {
+    /* add new character to buffer, increment mdi */
+    mdContext->in[mdi++] = *inBuf++;
+
+    /* transform if necessary */
+    if (mdi == 0x40) {
+      for (i = 0, ii = 0; i < 16; i++, ii += 4)
+        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+                (((UINT4)mdContext->in[ii+2]) << 16) |
+                (((UINT4)mdContext->in[ii+1]) << 8) |
+                ((UINT4)mdContext->in[ii]);
+      Transform ((UINT4*)mdContext->buf, (UINT4*)in);
+      mdi = 0;
+    }
+  }
+}
+
+void MD5Final (MD5_CTX *mdContext)
+{
+  UINT4 in[16];
+  int mdi;
+  unsigned int i, ii;
+  unsigned int padLen;
+
+  /* save number of bits */
+  in[14] = mdContext->i[0];
+  in[15] = mdContext->i[1];
+
+  /* compute number of bytes mod 64 */
+  mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
+
+  /* pad out to 56 mod 64 */
+  padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
+  MD5Update (mdContext, PADDING, padLen);
+
+  /* append length in bits and transform */
+  for (i = 0, ii = 0; i < 14; i++, ii += 4)
+    in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
+            (((UINT4)mdContext->in[ii+2]) << 16) |
+            (((UINT4)mdContext->in[ii+1]) << 8) |
+            ((UINT4)mdContext->in[ii]);
+  Transform (mdContext->buf, in);
+
+  /* store buffer in digest */
+  for (i = 0, ii = 0; i < 4; i++, ii += 4) {
+    mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
+    mdContext->digest[ii+1] =
+      (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
+    mdContext->digest[ii+2] =
+      (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
+    mdContext->digest[ii+3] =
+      (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
+  }
+}
+
+/* Basic MD5 step. Transform buf based on in.
+ */
+static void Transform (UINT4* buf, UINT4* in)
+{
+  UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
+
+  /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+  FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */
+  FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */
+  FF ( c, d, a, b, in[ 2], S13,  606105819); /* 3 */
+  FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */
+  FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */
+  FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */
+  FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */
+  FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */
+  FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */
+  FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */
+  FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */
+  FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */
+  FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */
+  FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */
+  FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */
+  FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */
+
+  /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+  GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */
+  GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */
+  GG ( c, d, a, b, in[11], S23,  643717713); /* 19 */
+  GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */
+  GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */
+  GG ( d, a, b, c, in[10], S22,   38016083); /* 22 */
+  GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */
+  GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */
+  GG ( a, b, c, d, in[ 9], S21,  568446438); /* 25 */
+  GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */
+  GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */
+  GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */
+  GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */
+  GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */
+  GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */
+  GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */
+
+  /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+  HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */
+  HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */
+  HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */
+  HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */
+  HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */
+  HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */
+  HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */
+  HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */
+  HH ( a, b, c, d, in[13], S31,  681279174); /* 41 */
+  HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */
+  HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */
+  HH ( b, c, d, a, in[ 6], S34,   76029189); /* 44 */
+  HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */
+  HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */
+  HH ( c, d, a, b, in[15], S33,  530742520); /* 47 */
+  HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */
+
+  /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+  II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */
+  II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */
+  II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */
+  II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */
+  II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */
+  II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */
+  II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */
+  II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */
+  II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */
+  II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */
+  II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */
+  II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */
+  II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */
+  II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */
+  II ( c, d, a, b, in[ 2], S43,  718787259); /* 63 */
+  II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+}
+
+/*
+ **********************************************************************
+ ** End of md5.c                                                     **
+ ******************************* (cut) ********************************
+ */
+
+/*
+ **********************************************************************
+ ** md5driver.c -- sample routines to test                           **
+ ** RSA Data Security, Inc. MD5 message digest algorithm.            **
+ ** Created: 2/16/90 RLR                                             **
+ ** Updated: 1/91 SRD                                                **
+ **********************************************************************
+ */
+
+/*
+ **********************************************************************
+ ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
+ **                                                                  **
+ ** RSA Data Security, Inc. makes no representations concerning      **
+ ** either the merchantability of this software or the suitability   **
+ ** of this software for any particular purpose.  It is provided "as **
+ ** is" without express or implied warranty of any kind.             **
+ **                                                                  **
+ ** These notices must be retained in any copies of any part of this **
+ ** documentation and/or software.                                   **
+ **********************************************************************
+ */
+
+/* -- include the following file if the file md5.h is separate -- */
+/* #include "md5.h" */
+
+/* Prints message digest buffer in mdContext as 32 hexadecimal digits.
+   Order is from low-order byte to high-order byte of digest.
+   Each byte is printed with high-order hexadecimal digit first.
+ */
+static void MDPrint (MD5_CTX *mdContext)
+{
+  int i;
+
+  for (i = 0; i < 16; i++)
+    printf ("%02x", mdContext->digest[i]);
+}
+
+char *MDPrint2 (MD5_CTX *mdContext)
+{
+  int i;
+
+  char *buff = new char[16*2];
+  memset(buff, 0, 16*2);
+
+  for (i = 0; i < 16; i++){
+	char buff2[3];
+	sprintf(buff2, "%.2X", mdContext->digest[i]);
+    strcat(buff, buff2);
+  }
+
+  return buff;
+}
+
+/* size of test block */
+#define TEST_BLOCK_SIZE 1000
+
+/* number of blocks to process */
+#define TEST_BLOCKS 10000
+
+/* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
+static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
+
+/* A time trial routine, to measure the speed of MD5.
+   Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
+   characters.
+ */
+static void MDTimeTrial ()
+{
+  MD5_CTX mdContext;
+  time_t endTime, startTime;
+  unsigned char data[TEST_BLOCK_SIZE];
+  unsigned int i;
+
+  /* initialize test data */
+  for (i = 0; i < TEST_BLOCK_SIZE; i++)
+    data[i] = (unsigned char)(i & 0xFF);
+
+  /* start timer */
+  printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
+  time (&startTime);
+
+  /* digest data in TEST_BLOCK_SIZE byte blocks */
+  MD5Init (&mdContext);
+  for (i = TEST_BLOCKS; i > 0; i--)
+    MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
+  MD5Final (&mdContext);
+
+  /* stop timer, get time difference */
+  time (&endTime);
+  MDPrint (&mdContext);
+  printf (" is digest of test input.\n");
+  printf
+    ("Seconds to process test input: %ld\n", (long)(endTime-startTime));
+  printf
+    ("Characters processed per second: %ld\n",
+     TEST_BYTES/(endTime-startTime));
+}
+
+/* Computes the message digest for string inString.
+   Prints out message digest, a space, the string (in quotes) and a
+   carriage return.
+ */
+char *MDString (char *inString)
+{
+  MD5_CTX mdContext;
+  unsigned int len = strlen (inString);
+
+  MD5Init (&mdContext);
+  MD5Update (&mdContext, (unsigned char*)inString, len);
+  MD5Final (&mdContext);
+  return MDPrint2 (&mdContext);
+
+}
+
+/* Computes the message digest for a specified file.
+   Prints out message digest, a space, the file name, and a carriage
+   return.
+ */
+static void MDFile (char *filename)
+{
+  FILE *inFile = fopen (filename, "rb");
+  MD5_CTX mdContext;
+  int bytes;
+  unsigned char data[1024];
+
+  if (inFile == NULL) {
+    printf ("%s can't be opened.\n", filename);
+    return;
+  }
+
+  MD5Init (&mdContext);
+  while ((bytes = fread (data, 1, 1024, inFile)) != 0)
+    MD5Update (&mdContext, data, bytes);
+  MD5Final (&mdContext);
+  MDPrint (&mdContext);
+  printf (" %s\n", filename);
+  fclose (inFile);
+}
+
+/* Writes the message digest of the data from stdin onto stdout,
+   followed by a carriage return.
+ */
+static void MDFilter ()
+{
+  MD5_CTX mdContext;
+  int bytes;
+  unsigned char data[16];
+
+  MD5Init (&mdContext);
+  while ((bytes = fread (data, 1, 16, stdin)) != 0)
+    MD5Update (&mdContext, data, bytes);
+  MD5Final (&mdContext);
+  MDPrint (&mdContext);
+  printf ("\n");
+}
+
+/*
+ **********************************************************************
+ ** End of md5driver.c                                               **
+ ******************************* (cut) ********************************
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+#include <string.h>
+
+char *MDString (char *inString);
 };
 
 block_data lblock = {0}, rblock = {0}, ublock = {0}, dblock = {0};
-block_data xblock = {0};
-
-
+block_data l1block = {0}, r1block = {0}, r2block = {0};
+block_data xblock = {0}, tblock = {0};
 
 void TTF_to_Bitmap(u8 chr, u8 * bitmap, short *w, short *h, short *y_correction){
 	FT_Set_Pixel_Sizes(face, (*w), (*h));
 	*h = slot->bitmap.rows;
 }
 
-void Debug(char *format, ...){
-	char str[1024];
-	char filename[1024];
+void TTF_get_Size(u8 chr, u8 *w, u8 *h){    
+	if(!face)
+		return;
 
-    va_list argp;        
-    va_start(argp, format);
-	vsprintf(str, format, argp);
-	va_end(argp);
+	FT_GlyphSlot slot = face->glyph;
+	if(!slot)
+		return;
 
-	FILE *fDebug;
-	sprintf(filename, "/dev_hdd0/game/%s/USRDIR/log.txt", "RNA000001");
-	fDebug = fopen(filename, "a+");
+	if(FT_Load_Char(face, (char) chr, FT_LOAD_RENDER ))
+		return;
 
-	fputs(str, fDebug);
-
-	fclose(fDebug);
+	*w = (slot->advance.x >> 6) + slot->bitmap_left;
+	*h = (slot->advance.x >> 6) + ((slot->bitmap_left < 0) ? -slot->bitmap_left : 0);
 }