/* parsing lists {{{*/ if(service) { xmlNodePtr memberships = findNode(service->children, "Memberships", 1); xmlNodePtr ms; xmlNodePtr role; xmlNodePtr members, member; xmlNodePtr pname; xmlNodePtr type; xmlNodePtr lastchange; xmlChar *content; int flag = 0; lastchange = findNode(service->children, "LastChange", 1); content = xmlNodeGetContent(lastchange); cl->lastchange = strdup((char*)content); DMSG(stderr, "Contact: lastchange = %s\n", cl->lastchange); if(!memberships) { fprintf(stderr, "NULL membership\n"); count = 0; goto cleanup; } for(ms=memberships->children;ms;ms=ms->next) { int ctype = 1; if(!ms->children) continue; role = findNode(ms->children, "MemberRole", 1); if(!role) { fprintf(stderr, "Null role\n"); count = 0; goto cleanup; } members = findNode(role, "Members", 1); if(!members) continue; if(xmlStrEqual(role->children->content, (xmlChar*)"Allow")) flag = 3; else if(xmlStrEqual(role->children->content, (xmlChar*)"Block")) flag = 4; else continue; for(member=members->children;member;member=member->next) { Contact *c; type = findNode(member->children, "Type", 1); content = xmlNodeGetContent(type); if(!content) { fprintf(stderr, "NULL Type\n"); continue; } if(xmlStrEqual(content, (xmlChar*)"Passport")) { pname = findNode(member->children, "PassportName", 1); ctype = 1; } else if(xmlStrEqual(content, (xmlChar*)"Email")) { pname = findNode(member->children, "Email", 1); ctype = 32; } else continue; xmlFree(content); if(!pname) { fprintf(stderr, "NULL PassportName or Email\n"); continue; } content = xmlNodeGetContent(pname); if(content) { char name[32]; char domain[32]; if(sscanf((char*)content, "%[^@]@%s", name, domain) != 2) { fprintf(stderr, "parse contact: malformed email: %s\n", content); continue; } c = contact_new((char*)content); c->name = strdup(name); c->type = ctype; c->status = NA; c->inlist |= flag; c->domain = NULL; /* should be filled during sort */ cl_append_contact(cl, c, name, domain); xmlFree(content); count++; } } } }/*}}}*/ DMSG(stderr, "parsed contact count: %d\n", count); cleanup: cl->flag &= ~CL_INITLIST; return count; }/*}}}*/ int _cl_do_soapreq_ab(CL *cl)/*{{{*/ { TCPClient *client; char *req = NULL; char *header; char buf[512]; int ret, len; char *ptr = NULL; client = tcpclient_new("contacts.msn.com", 80); ret = _cl_load_soapreq_ab(cl, cl->ablastchange, &req, TRUE); if(ret) { tcpclient_connect(client); header = (char*)xmalloc(strlen(ab_request_header) + 32); DMSG(stderr, "sending ab request\n"); len = sprintf(header, "%s%d\r\n\r\n", ab_request_header, ret); if(tcpclient_send(client, header, len) <= 0) goto cleanup; if(tcpclient_send(client, req, ret) <= 0) goto cleanup; len = tcpclient_recv_header(client, &ptr); /* header */ if(ptr) { HTTPHeader *header; xmlDocPtr doc; xmlParserCtxtPtr ctxt; FILE *fp; DMSG(stderr, "AB response header:\n%s", ptr); header = http_parse_header(ptr); len = header->content_length; DMSG(stderr, "Length: %d\n", len); http_header_destroy(header); memset(buf, 0, sizeof(buf)); fp = fopen("addressbook.xml", "w"); fprintf(fp, buf); len -= (ret = tcpclient_recv(client, buf, sizeof(buf)-1)); ctxt = xmlCreatePushParserCtxt(NULL, NULL, buf, ret, "addressbook.xml"); fprintf(fp, buf); if(ctxt == NULL) { fprintf(stderr, "failed to create parser context"); return 0; } while(len > 0) { memset(buf, 0, sizeof(buf)); len -= (ret=tcpclient_recv(client, buf, sizeof(buf)-1)); fprintf(fp, buf); xmlParseChunk(ctxt, buf, ret, 0); } fclose(fp); xmlParseChunk(ctxt, buf, 0, 1); tcpclient_destroy(client); client = NULL; doc = ctxt->myDoc; len = ctxt->wellFormed; xmlFreeParserCtxt(ctxt); //count += _cl_parse_contacts(cl, doc); xmlFreeDoc(doc); xmlCleanupParser(); DMSG(stderr, "addressbook xml parsing done: %s\n", len?"good":"malformed"); xfree(ptr); } else { DMSG(stderr, "ab: no header found\n\r"); } } else { fprintf(stderr, "failed to load abreq\n"); } cleanup: xfree(header); return 0; }/*}}}*/ int cl_load_contacts(CL *cl, const char* file)/*{{{*/ { int ret; xmlDocPtr doc; xmlNodePtr root; xmlNodePtr contact; xmlNodePtr node; xmlChar *content; doc = xmlReadFile(file, NULL, 0); if (doc == NULL) { fprintf(stderr, "Failed to parse %s\n", file); return 0; } ret = 0; root = xmlDocGetRootElement(doc); contact = findNode(root->children, "contact", 3); #define READSTR(dst,elem) node = findNode(contact->children, elem, 1); \ content = xmlNodeGetContent(node); \ dst = strdup((char*)content); \ xmlFree(content) #define READINT(dst, elem) node = findNode(contact->children, elem, 1); \ content = xmlNodeGetContent(node); \ dst = atoi((char*)content); \ xmlFree(content) for(;contact;contact=contact->next) { Contact *c; node = findNode(contact->children, "nick", 1); content = xmlNodeGetContent(node); c = contact_new((char*)content); xmlFree(content); READSTR(c->name, "name"); READSTR(c->PSM, "PSM"); READINT(c->inlist, "inlist"); READINT(c->type, "type"); c->status = NA; node = findNode(contact->children, "domain", 1); content = xmlNodeGetContent(node); c->domain = NULL; /* should be filled during sort */ cl_append_contact(cl, c, c->name, (char*)content); xmlFree(content); ret++; } node = findNode(root->children, "lastchange", 3); if(node) { content = xmlNodeGetContent(node); cl->lastchange = strdup((char*)content); xmlFree(content); } xmlFreeDoc(doc); return ret; }/*}}}*/
static void load_sample_names(int size, SFInfo *sf, FILE *fd) { int i, nsamples; if (sf->version > 1) { fprintf(stderr, "*** version 2 has obsolete format??\n"); FSKIP(size, fd); return; } /* each sample name has a fixed lentgh (20 bytes) */ nsamples = size / 20; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { fprintf(stderr, "*** different # of samples ?? (%d : %d)\n", sf->nsamples, nsamples); FSKIP(size, fd); return; } /* read each name from file */ for (i = 0; i < sf->nsamples; i++) { READSTR(sf->sample[i].name, fd); } }
void Instruments::load_sample_names(int size, SFInfo *sf, struct timidity_file *fd) { int i, nsamples; if (sf->version > 1) { ctl_cmsg(CMSG_WARNING, VERB_NORMAL, "%s: *** version 2 has obsolete format??",fd->filename.c_str()); FSKIP(size, fd); return; } /* each sample name has a fixed lentgh (20 bytes) */ nsamples = size / 20; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { ctl_cmsg(CMSG_WARNING, VERB_NORMAL, "%s: *** different # of samples ?? (%d : %d)\n",fd->filename.c_str(), sf->nsamples, nsamples); FSKIP(size, fd); return; } /* read each name from file */ for (i = 0; i < sf->nsamples; i++) { READSTR(sf->sample[i].name, fd); } }
static void load_sample_info(int size, SFInfo *sf, FILE *fd) { int i; int in_rom; /* the record size depends on the soundfont version */ if (sf->version > 1) { /* SF2 includes sample name and other infos */ sf->nsamples = size / 46; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else { /* SBK; sample name may be read already */ int nsamples = size / 16; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { #if 0 fprintf(stderr, "*** different # of infos ?? (%d : %d)\n", sf->nsamples, nsamples); FSKIP(size, fd); return; #endif /* overwrite it */ sf->nsamples = nsamples; } } in_rom = 1; /* data may start from ROM samples */ for (i = 0; i < sf->nsamples; i++) { if (sf->version > 1) /* SF2 only */ READSTR(sf->sample[i].name, fd); READDW(sf->sample[i].startsample, fd); READDW(sf->sample[i].endsample, fd); READDW(sf->sample[i].startloop, fd); READDW(sf->sample[i].endloop, fd); if (sf->version > 1) { /* SF2 only */ READDW(sf->sample[i].samplerate, fd); READB(sf->sample[i].originalPitch, fd); READB(sf->sample[i].pitchCorrection, fd); READW(sf->sample[i].samplelink, fd); READW(sf->sample[i].sampletype, fd); } else { /* for SBK; set missing infos */ sf->sample[i].samplerate = 44100; sf->sample[i].originalPitch = 60; sf->sample[i].pitchCorrection = 0; sf->sample[i].samplelink = 0; /* the first RAM data starts from address 0 */ if (sf->sample[i].startsample == 0) in_rom = 0; if (in_rom) sf->sample[i].sampletype = 0x8001; else sf->sample[i].sampletype = 1; } } }
void Instruments::load_sample_info(int size, SFInfo *sf, struct timidity_file *fd) { int i; int in_rom; /* the record size depends on the soundfont version */ if (sf->version > 1) { /* SF2 includes sample name and other infos */ sf->nsamples = size / 46; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else { /* SBK; sample name may be read already */ int nsamples = size / 16; if (sf->sample == NULL) { sf->nsamples = nsamples; sf->sample = NEW(SFSampleInfo, sf->nsamples); } else if (sf->nsamples != nsamples) { /* overwrite it */ sf->nsamples = nsamples; } } in_rom = 1; /* data may start from ROM samples */ for (i = 0; i < sf->nsamples; i++) { if (sf->version > 1) /* SF2 only */ READSTR(sf->sample[i].name, fd); READDW((uint32_t *)&sf->sample[i].startsample, fd); READDW((uint32_t *)&sf->sample[i].endsample, fd); READDW((uint32_t *)&sf->sample[i].startloop, fd); READDW((uint32_t *)&sf->sample[i].endloop, fd); if (sf->version > 1) { /* SF2 only */ READDW((uint32_t *)&sf->sample[i].samplerate, fd); READB(sf->sample[i].originalPitch, fd); READB(sf->sample[i].pitchCorrection, fd); READW(&sf->sample[i].samplelink, fd); READW(&sf->sample[i].sampletype, fd); } else { /* for SBK; set missing infos */ sf->sample[i].samplerate = 44100; sf->sample[i].originalPitch = 60; sf->sample[i].pitchCorrection = 0; sf->sample[i].samplelink = 0; /* the first RAM data starts from address 0 */ if (sf->sample[i].startsample == 0) in_rom = 0; if (in_rom) sf->sample[i].sampletype = 0x8001; else sf->sample[i].sampletype = 1; } } }
static void load_inst_header(int size, SFInfo *sf, FILE *fd) { int i; sf->ninsts = size / 22; sf->inst = NEW(SFInstHdr, sf->ninsts); for (i = 0; i < sf->ninsts; i++) { READSTR(sf->inst[i].hdr.name, fd); READW(sf->inst[i].hdr.bagNdx, fd); /* iniitialize layer table; it'll be parsed later */ sf->inst[i].hdr.nlayers = 0; sf->inst[i].hdr.layer = NULL; } }
void Instruments::load_inst_header(int size, SFInfo *sf, struct timidity_file *fd) { int i; sf->ninsts = size / 22; sf->inst = NEW(SFInstHdr, sf->ninsts); for (i = 0; i < sf->ninsts; i++) { READSTR(sf->inst[i].hdr.name, fd); READW(&sf->inst[i].hdr.bagNdx, fd); /* iniitialize layer table; it'll be parsed later */ sf->inst[i].hdr.nlayers = 0; sf->inst[i].hdr.layer = NULL; ctl_cmsg(CMSG_INFO, VERB_DEBUG, " InstHdr %d (%s) bagNdx=%d", i, sf->inst[i].hdr.name, sf->inst[i].hdr.bagNdx); } }
static void load_preset_header(int size, SFInfo *sf, FILE *fd) { int i; sf->npresets = size / 38; sf->preset = NEW(SFPresetHdr, sf->npresets); for (i = 0; i < sf->npresets; i++) { READSTR(sf->preset[i].hdr.name, fd); READW(sf->preset[i].preset, fd); READW(sf->preset[i].bank, fd); READW(sf->preset[i].hdr.bagNdx, fd); SKIPDW(fd); /* lib; ignored*/ SKIPDW(fd); /* genre; ignored */ SKIPDW(fd); /* morph; ignored */ /* initialize layer table; it'll be parsed later */ sf->preset[i].hdr.nlayers = 0; sf->preset[i].hdr.layer = NULL; } }
void CReplay :: ParseReplay( bool parseBlocks ) { m_HostPID = 0; m_HostName.clear( ); m_GameName.clear( ); m_StatString.clear( ); m_PlayerCount = 0; m_MapGameType = 0; m_Players.clear( ); m_Slots.clear( ); m_RandomSeed = 0; m_SelectMode = 0; m_StartSpotCount = 0; m_LoadingBlocks = queue<BYTEARRAY>( ); m_Blocks = queue<BYTEARRAY>( ); m_CheckSums = queue<uint32_t>( ); if( m_Flags != 32768 ) { CONSOLE_Print( "[REPLAY] invalid replay (flags mismatch)" ); m_Valid = false; return; } istringstream ISS( m_Decompressed ); unsigned char Garbage1; uint32_t Garbage4; string GarbageString; unsigned char GarbageData[65535]; READB( ISS, &Garbage4, 4 ); // Unknown (4.0) if( Garbage4 != 272 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.0 Unknown mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Host RecordID (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host RecordID mismatch)" ); m_Valid = false; return; } READB( ISS, &m_HostPID, 1 ); if( m_HostPID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host PlayerID is invalid)" ); m_Valid = false; return; } READSTR( ISS, m_HostName ); // Host PlayerName (4.1) READB( ISS, &Garbage1, 1 ); // Host AdditionalSize (4.1) if( Garbage1 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalSize mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Host AdditionalData (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.1 Host AdditionalData mismatch)" ); m_Valid = false; return; } AddPlayer( m_HostPID, m_HostName ); READSTR( ISS, m_GameName ); // GameName (4.2) READSTR( ISS, GarbageString ); // Null (4.0) READSTR( ISS, m_StatString ); // StatString (4.3) READB( ISS, &m_PlayerCount, 4 ); // PlayerCount (4.6) if( m_PlayerCount > 12 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.6 PlayerCount is invalid)" ); m_Valid = false; return; } READB( ISS, &m_MapGameType, 4 ); // GameType (4.7) READB( ISS, &Garbage4, 4 ); // LanguageID (4.8) while( 1 ) { READB( ISS, &Garbage1, 1 ); // Player RecordID (4.1) if( Garbage1 == 22 ) { unsigned char PlayerID; string PlayerName; READB( ISS, &PlayerID, 1 ); // Player PlayerID (4.1) if( PlayerID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player PlayerID is invalid)" ); m_Valid = false; return; } READSTR( ISS, PlayerName ); // Player PlayerName (4.1) READB( ISS, &Garbage1, 1 ); // Player AdditionalSize (4.1) if( Garbage1 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalSize mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // Player AdditionalData (4.1) if( Garbage1 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player AdditionalData mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // Unknown if( Garbage4 != 0 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Unknown mismatch)" ); m_Valid = false; return; } AddPlayer( PlayerID, PlayerName ); } else if( Garbage1 == 25 ) break; else { CONSOLE_Print( "[REPLAY] invalid replay (4.9 Player RecordID mismatch)" ); m_Valid = false; return; } } uint16_t Size; unsigned char NumSlots; READB( ISS, &Size, 2 ); // Size (4.10) READB( ISS, &NumSlots, 1 ); // NumSlots (4.10) if( Size != 7 + NumSlots * 9 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.10 Size is invalid)" ); m_Valid = false; return; } if( NumSlots == 0 || NumSlots > 12 ) { CONSOLE_Print( "[REPLAY] invalid replay (4.10 NumSlots is invalid)" ); m_Valid = false; return; } for( int i = 0; i < NumSlots; ++i ) { unsigned char SlotData[9]; READB( ISS, SlotData, 9 ); BYTEARRAY SlotDataBA = UTIL_CreateByteArray( SlotData, 9 ); m_Slots.push_back( CGameSlot( SlotDataBA ) ); } READB( ISS, &m_RandomSeed, 4 ); // RandomSeed (4.10) READB( ISS, &m_SelectMode, 1 ); // SelectMode (4.10) READB( ISS, &m_StartSpotCount, 1 ); // StartSpotCount (4.10) if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse replay header" ); m_Valid = false; return; } if( !parseBlocks ) return; READB( ISS, &Garbage1, 1 ); // first start block ID (5.0) if( Garbage1 != CReplay :: REPLAY_FIRSTSTARTBLOCK ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block ID mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // first start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 first start block data mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage1, 1 ); // second start block ID (5.0) if( Garbage1 != CReplay :: REPLAY_SECONDSTARTBLOCK ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block ID mismatch)" ); m_Valid = false; return; } READB( ISS, &Garbage4, 4 ); // second start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 second start block data mismatch)" ); m_Valid = false; return; } while( 1 ) { READB( ISS, &Garbage1, 1 ); // third start block ID *or* loading block ID (5.0) if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block unexpected end of file found)" ); m_Valid = false; return; } if( Garbage1 == CReplay :: REPLAY_LEAVEGAME ) { READB( ISS, GarbageData, 13 ); BYTEARRAY LoadingBlock; LoadingBlock.push_back( Garbage1 ); UTIL_AppendByteArray( LoadingBlock, GarbageData, 13 ); m_LoadingBlocks.push( LoadingBlock ); } else if( Garbage1 == CReplay :: REPLAY_THIRDSTARTBLOCK ) break; else { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block ID mismatch)" ); m_Valid = false; return; } } READB( ISS, &Garbage4, 4 ); // third start block data (5.0) if( Garbage4 != 1 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 third start block data mismatch)" ); m_Valid = false; return; } if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse replay start blocks" ); m_Valid = false; return; } uint32_t ActualReplayLength = 0; while( 1 ) { READB( ISS, &Garbage1, 1 ); // block ID (5.0) if( ISS.eof( ) || ISS.fail( ) ) break; else if( Garbage1 == CReplay :: REPLAY_LEAVEGAME ) { READB( ISS, GarbageData, 13 ); // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_LEAVEGAME ); UTIL_AppendByteArray( Block, GarbageData, 13 ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_TIMESLOT ) { uint16_t BlockSize; READB( ISS, &BlockSize, 2 ); READB( ISS, GarbageData, BlockSize ); if( BlockSize >= 2 ) ActualReplayLength += GarbageData[0] | GarbageData[1] << 8; // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_TIMESLOT ); UTIL_AppendByteArray( Block, BlockSize, false ); UTIL_AppendByteArray( Block, GarbageData, BlockSize ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_CHATMESSAGE ) { unsigned char PID; uint16_t BlockSize; READB( ISS, &PID, 1 ); if( PID > 15 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 chatmessage pid is invalid)" ); m_Valid = false; return; } READB( ISS, &BlockSize, 2 ); READB( ISS, GarbageData, BlockSize ); // reconstruct the block BYTEARRAY Block; Block.push_back( CReplay :: REPLAY_CHATMESSAGE ); Block.push_back( PID ); UTIL_AppendByteArray( Block, BlockSize, false ); UTIL_AppendByteArray( Block, GarbageData, BlockSize ); m_Blocks.push( Block ); } else if( Garbage1 == CReplay :: REPLAY_CHECKSUM ) { READB( ISS, &Garbage1, 1 ); if( Garbage1 != 4 ) { CONSOLE_Print( "[REPLAY] invalid replay (5.0 checksum unknown mismatch)" ); m_Valid = false; return; } uint32_t CheckSum; READB( ISS, &CheckSum, 4 ); m_CheckSums.push( CheckSum ); } else { // it's not necessarily an error if we encounter an unknown block ID since replays can contain extra data break; } } if( m_ReplayLength != ActualReplayLength ) CONSOLE_Print( "[REPLAY] warning - replay length mismatch (" + UTIL_ToString( m_ReplayLength ) + "ms/" + UTIL_ToString( ActualReplayLength ) + "ms)" ); m_Valid = true; }
void CSaveGame :: ParseSaveGame( ) { m_MapPath.clear( ); m_GameName.clear( ); m_NumSlots = 0; m_Slots.clear( ); m_RandomSeed = 0; m_MagicNumber.clear( ); if( m_Flags != 0 ) { CONSOLE_Print( "[SAVEGAME] invalid replay (flags mismatch)" ); m_Valid = false; return; } istringstream ISS( m_Decompressed ); // savegame format figured out by Varlock: // string -> map path // 0 (string?) -> ??? (no idea what this is) // string -> game name // 0 (string?) -> ??? (maybe original game password) // string -> stat string // 4 bytes -> ??? (seems to be # of slots) // 4 bytes -> ??? (seems to be 0x01 0x28 0x49 0x00 on both of the savegames examined) // 2 bytes -> ??? (no idea what this is) // slot structure // 4 bytes -> magic number unsigned char Garbage1; uint16_t Garbage2; uint32_t Garbage4; string GarbageString; uint32_t MagicNumber; READSTR( ISS, m_MapPath ); // map path READSTR( ISS, GarbageString ); // ??? READSTR( ISS, m_GameName ); // game name READSTR( ISS, GarbageString ); // ??? READSTR( ISS, GarbageString ); // stat string READB( ISS, &Garbage4, 4 ); // ??? READB( ISS, &Garbage4, 4 ); // ??? READB( ISS, &Garbage2, 2 ); // ??? READB( ISS, &m_NumSlots, 1 ); // number of slots if( m_NumSlots > 12 ) { CONSOLE_Print( "[SAVEGAME] invalid savegame (too many slots)" ); m_Valid = false; return; } for( unsigned char i = 0; i < m_NumSlots; i++ ) { unsigned char SlotData[9]; READB( ISS, SlotData, 9 ); // slot data m_Slots.push_back( CGameSlot( SlotData[0], SlotData[1], SlotData[2], SlotData[3], SlotData[4], SlotData[5], SlotData[6], SlotData[7], SlotData[8] ) ); } READB( ISS, &m_RandomSeed, 4 ); // random seed READB( ISS, &Garbage1, 1 ); // GameType READB( ISS, &Garbage1, 1 ); // number of player slots (non observer) READB( ISS, &MagicNumber, 4 ); // magic number if( ISS.eof( ) || ISS.fail( ) ) { CONSOLE_Print( "[SAVEGAME] failed to parse savegame header" ); m_Valid = false; return; } m_MagicNumber = UTIL_CreateByteArray( MagicNumber, false ); m_Valid = true; }
/* read and load font, return incore font structure*/ static PMWCFONT fnt_load_font(const char *path) { FILEP ifp; PMWCFONT pf = NULL; int i; unsigned short maxwidth, height, ascent, pad; unsigned long firstchar, defaultchar, size; unsigned long nbits, noffset, nwidth; char version[4+1]; char name[64+1]; char copyright[256+1]; char fname[256]; ifp = FOPEN(path, "rb"); if (!ifp) { strcpy(fname, FNT_FONT_DIR "/"); strcpy(fname + sizeof(FNT_FONT_DIR), path); ifp = FOPEN(fname, "rb"); /* Try to grab it from the MWFONTDIR directory */ if (!ifp) { char *env = getenv("MWFONTDIR"); if (env) { sprintf(fname, "%s/%s", env, path); printf("Trying to get font from %s\n", fname); ifp = FOPEN(fname, "rb"); } } } if (!ifp) return NULL; /* read magic and version #*/ memset(version, 0, sizeof(version)); if (READSTR(ifp, version, 4) != 4) goto errout; if (strcmp(version, VERSION) != 0) goto errout; pf = (PMWCFONT)calloc(1, sizeof(MWCFONT)); if (!pf) goto errout; /* internal font name*/ if (READSTRPAD(ifp, name, 64) != 64) goto errout; pf->name = (char *)malloc(strlen(name)+1); if (!pf->name) goto errout; strcpy(pf->name, name); /* copyright, not currently stored*/ if (READSTRPAD(ifp, copyright, 256) != 256) goto errout; /* font info*/ if (!READSHORT(ifp, &maxwidth)) goto errout; pf->maxwidth = maxwidth; if (!READSHORT(ifp, &height)) goto errout; pf->height = height; if (!READSHORT(ifp, &ascent)) goto errout; pf->ascent = ascent; if (!READSHORT(ifp, &pad)) goto errout; if (!READLONG(ifp, &firstchar)) goto errout; pf->firstchar = firstchar; if (!READLONG(ifp, &defaultchar)) goto errout; pf->defaultchar = defaultchar; if (!READLONG(ifp, &size)) goto errout; pf->size = size; /* variable font data sizes*/ /* # words of MWIMAGEBITS*/ if (!READLONG(ifp, &nbits)) goto errout; pf->bits = (MWIMAGEBITS *)malloc(nbits * sizeof(MWIMAGEBITS)); if (!pf->bits) goto errout; pf->bits_size = nbits; /* # longs of offset*/ if (!READLONG(ifp, &noffset)) goto errout; if (noffset) { pf->offset = (unsigned long *)malloc(noffset * sizeof(unsigned long)); if (!pf->offset) goto errout; } /* # bytes of width*/ if (!READLONG(ifp, &nwidth)) goto errout; if (nwidth) { pf->width = (unsigned char *)malloc(nwidth * sizeof(unsigned char)); if (!pf->width) goto errout; } /* variable font data*/ for (i=0; i<nbits; ++i) if (!READSHORT(ifp, &pf->bits[i])) goto errout; /* pad to longword boundary*/ if (ftell(ifp) & 02) if (!READSHORT(ifp, &pf->bits[i])) goto errout; if (noffset) for (i=0; i<pf->size; ++i) if (!READLONG(ifp, &pf->offset[i])) goto errout; if (nwidth) for (i=0; i<pf->size; ++i) if (!READBYTE(ifp, &pf->width[i])) goto errout; FCLOSE(ifp); return pf; /* success!*/ errout: FCLOSE(ifp); if (!pf) return NULL; if (pf->name) free(pf->name); if (pf->bits) free(pf->bits); if (pf->offset) free(pf->offset); if (pf->width) free(pf->width); free(pf); return NULL; }