/// default value load routine bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size) { char *pPos; DROID *psCDroid; SDWORD index, members, savedMembers; UDWORD id; LEVEL_DATASET *psLevel; DROID_GROUP *psGroup = NULL; const char *pName; bool bObjectDefined; switch ((unsigned)psVal->type) // Unsigned cast to suppress compiler warnings due to enum abuse. { case ST_INTMESSAGE: if ((size == 1) && (*pBuffer == 0)) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getViewData(pBuffer); if (psVal->v.oval == NULL) { return false; } } break; case ST_BASEOBJECT: case ST_DROID: case ST_STRUCTURE: case ST_FEATURE: id = *((UDWORD *)pBuffer); endian_udword(&id); if (id == UDWORD_MAX) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getBaseObjFromId(id); if (!psVal->v.oval) { debug(LOG_ERROR, "Could not find object id %d", id); } } break; case ST_BASESTATS: case ST_COMPONENT: break; case ST_STRUCTURESTAT: index = getStructStatFromName(pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find structure stat %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_FEATURESTAT: index = getFeatureStatFromName(pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find feature stat %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_BODY: index = getCompFromResName(COMP_BODY, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find body component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_PROPULSION: index = getCompFromResName(COMP_PROPULSION, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find propulsion component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_ECM: index = getCompFromResName(COMP_ECM, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find ECM component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_SENSOR: index = getCompFromResName(COMP_SENSOR, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find sensor component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_CONSTRUCT: index = getCompFromResName(COMP_CONSTRUCT, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find constructor component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_WEAPON: index = getCompFromResName(COMP_WEAPON, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find weapon %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_REPAIR: index = getCompFromResName(COMP_REPAIRUNIT, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find repair component %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_BRAIN: index = getCompFromResName(COMP_BRAIN, pBuffer); if (index == -1) { debug( LOG_FATAL, "scrValDefLoad: couldn't find repair brain %s", pBuffer ); abort(); index = 0; } psVal->v.ival = index; break; case ST_TEMPLATE: id = *((UDWORD *)pBuffer); endian_udword(&id); if (id == UDWORD_MAX) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER); if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find template id %d", id ); abort(); } } break; case ST_TEXTSTRING: { const char* str; char* idStr; uint16_t len; if (size < sizeof(len)) { debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len)), (unsigned int)size); return false; } len = *((uint16_t*)pBuffer); endian_uword(&len); if (size < sizeof(len) + len) { debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len) + len), (unsigned int)size); return false; } if (len == 0) { psVal->v.sval = NULL; return true; } idStr = (char *)malloc(len); if (!idStr) { debug(LOG_ERROR, "Out of memory (tried to allocate %u bytes)", (unsigned int)len); // Don't abort() here, as this might be the result from a bad "len" field in the data return false; } memcpy(idStr, pBuffer + sizeof(len), len); if (idStr[len - 1] != '\0') { debug(LOG_WARNING, "Non-NUL terminated string encountered!"); } idStr[len - 1] = '\0'; str = strresGetString(psStringRes, idStr); if (!str) { debug(LOG_ERROR, "Couldn't find string with id \"%s\"", idStr); free(idStr); return false; } free(idStr); psVal->v.sval = strdup(str); if (!psVal->v.sval) { debug(LOG_FATAL, "Out of memory"); abort(); return false; } } break; case ST_LEVEL: if ((size == 1) && (*pBuffer == 0)) { psVal->v.sval = '\0'; } else { psLevel = levFindDataSet(pBuffer); if (psLevel == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find level dataset %s", pBuffer ); abort(); } psVal->v.sval = psLevel->pName; } break; case ST_RESEARCH: if ((size == 1) && (*pBuffer == 0)) { psVal->v.oval = NULL; } else { psVal->v.oval = (void*)getResearch(pBuffer); if (psVal->v.oval == NULL) { debug( LOG_FATAL, "scrValDefLoad: couldn't find research %s", pBuffer ); abort(); } } break; case ST_GROUP: bObjectDefined = true; if (psVal->v.oval == NULL) { DROID_GROUP *tmp = grpCreate(); tmp->add(NULL); psVal->v.oval = tmp; } pPos = pBuffer; if (version < 2) { members = size / sizeof(UDWORD); } else if (version < 3) { members = (size - sizeof(SDWORD)*4) / sizeof(UDWORD); } else { members = (size - sizeof(SDWORD)*6) / sizeof(UDWORD); // get saved group member count/nullpointer flag endian_sdword((SDWORD*)pPos); bObjectDefined = ( *((SDWORD *)pPos) != UNALLOCATED_OBJECT ); if(bObjectDefined) { savedMembers = *((SDWORD *)pPos); // get number of saved group members ASSERT(savedMembers == members, "scrValDefLoad: calculated and saved group member count did not match." ); } pPos += sizeof(SDWORD); } // make sure group was allocated when it was saved (relevant starting from version 3) if( version < 3 || bObjectDefined ) { if (version >= 2) { // load the retreat data psGroup = (DROID_GROUP*)(psVal->v.oval); endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.x = *((SDWORD *)pPos); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.y = *((SDWORD *)pPos); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); endian_sdword((SDWORD*)pPos); psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } if (version >= 3) { endian_sdword((SDWORD*)pPos); psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } // load the droids while (members > 0) { endian_udword((UDWORD*)pPos); id = *((UDWORD *) pPos); psCDroid = (DROID *)getBaseObjFromId(id); if (!psCDroid) { debug(LOG_ERROR, "Could not find object id %d", id); } else { ((DROID_GROUP*)(psVal->v.oval))->add(psCDroid); } pPos += sizeof(UDWORD); members -= 1; } } else // a group var was unallocated during saving { pPos += sizeof(UWORD); } break; case ST_SOUND: // find audio id // don't use sound if it's disabled if (audio_Disabled()) { psVal->v.ival = NO_SOUND; break; } pName = pBuffer; index = audio_GetTrackID( pName ); if (index == SAMPLE_NOT_FOUND) { // find empty id and set track vals index = audio_SetTrackVals(pName, false, 100, 1800); if (!index) //this is a NON fatal error. { // We can't find filename of the sound for some reason. debug(LOG_ERROR, "Sound ID not available %s not found", pName); break; } } psVal->v.ival = index; break; case ST_STRUCTUREID: case ST_DROIDID: default: // just set the contents directly psVal->v.ival = *((SDWORD *)pBuffer); endian_sdword(&psVal->v.ival); break; } return true; }
// //////////////////////////////////////////////////// static BOOL _addLoadSave(BOOL bLoad,CHAR *sSearchPath,CHAR *sExtension, CHAR *title) { W_FORMINIT sFormInit; W_BUTINIT sButInit; W_LABINIT sLabInit; UDWORD slotCount; static STRING sSlots[10][64]; STRING sTemp[255]; WIN32_FIND_DATA found; HANDLE dir; mode = bLoad; if(GetCurrentDirectory(255,(char*)&sTemp) == 0) { return FALSE; // failed, directory probably didn't exist. } if ((bLoadSaveMode == LOAD_INGAME) || (bLoadSaveMode == SAVE_INGAME)) { if (!bMultiPlayer || (NetPlay.bComms ==0)) { gameTimeStop(); if(GetGameMode() == GS_NORMAL) { BOOL radOnScreen = radarOnScreen; // Only do this in main game. bRender3DOnly = TRUE; radarOnScreen = FALSE; displayWorld(); // Just display the 3d, no interface pie_UploadDisplayBuffer(DisplayBuffer); // Upload the current display back buffer into system memory. iV_ScaleBitmapRGB(DisplayBuffer,iV_GetDisplayWidth(), iV_GetDisplayHeight(),2,2,2); // Make it darker. radarOnScreen = radOnScreen; bRender3DOnly = FALSE; } setGamePauseStatus( TRUE ); setGameUpdatePause(TRUE); setScriptPause(TRUE); setScrollPause(TRUE); setConsolePause(TRUE); } forceHidePowerBar(); intRemoveReticule(); } CreateDirectory(sSearchPath,NULL); // create the directory required... fails if already there, so no problem. widgCreateScreen(&psRequestScreen); // init the screen. widgSetTipFont(psRequestScreen,WFont); /* add a form to place the tabbed form on */ memset(&sFormInit, 0, sizeof(W_FORMINIT)); sFormInit.formID = 0; sFormInit.id = LOADSAVE_FORM; sFormInit.style = WFORM_PLAIN; sFormInit.x = (SWORD)(LOADSAVE_X); sFormInit.y = (SWORD)(LOADSAVE_Y); sFormInit.width = LOADSAVE_W; sFormInit.height = LOADSAVE_H; sFormInit.disableChildren = TRUE; sFormInit.pDisplay = intOpenPlainForm; widgAddForm(psRequestScreen, &sFormInit); // Add Banner sFormInit.formID = LOADSAVE_FORM; sFormInit.id = LOADSAVE_BANNER; sFormInit.x = LOADSAVE_HGAP; sFormInit.y = LOADSAVE_VGAP; sFormInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); sFormInit.height = LOADSAVE_BANNER_DEPTH; sFormInit.disableChildren = FALSE; sFormInit.pDisplay = displayLoadBanner; sFormInit.pUserData = (VOID *)bLoad; widgAddForm(psRequestScreen, &sFormInit); // Add Banner Label memset(&sLabInit, 0, sizeof(W_LABINIT)); sLabInit.formID = LOADSAVE_BANNER; sLabInit.id = LOADSAVE_LABEL; sLabInit.style = WLAB_ALIGNCENTRE; sLabInit.x = 0; sLabInit.y = 4; sLabInit.width = LOADSAVE_W-(2*LOADSAVE_HGAP); //LOADSAVE_W; sLabInit.height = 20; sLabInit.pText = title; sLabInit.FontID = WFont; widgAddLabel(psRequestScreen, &sLabInit); // add cancel. memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = LOADSAVE_BANNER; sButInit.x = 4; sButInit.y = 3; sButInit.width = iV_GetImageWidth(IntImages,IMAGE_NRUTER); sButInit.height = iV_GetImageHeight(IntImages,IMAGE_NRUTER); sButInit.pUserData = (void*)PACKDWORD_TRI(0,IMAGE_NRUTER , IMAGE_NRUTER); sButInit.id = LOADSAVE_CANCEL; sButInit.style = WBUT_PLAIN; sButInit.pTip = strresGetString(psStringRes, STR_MISC_CLOSE); sButInit.FontID = WFont; sButInit.pDisplay = intDisplayImageHilight; widgAddButton(psRequestScreen, &sButInit); // add slots memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = LOADSAVE_FORM; sButInit.style = WBUT_PLAIN; sButInit.width = LOADENTRY_W; sButInit.height = LOADENTRY_H; sButInit.pDisplay = displayLoadSlot; sButInit.FontID = WFont; for(slotCount = 0; slotCount< 10 ; slotCount++) { sButInit.id = slotCount+LOADENTRY_START; if(slotCount<5) { sButInit.x = LOADSAVE_HGAP; sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2*LOADSAVE_VGAP)) + ( slotCount*(LOADSAVE_VGAP+LOADENTRY_H))); } else { sButInit.x = (2*LOADSAVE_HGAP)+LOADENTRY_W; sButInit.y = (SWORD)((LOADSAVE_BANNER_DEPTH +(2* LOADSAVE_VGAP)) + ( (slotCount-5) *(LOADSAVE_VGAP+LOADENTRY_H))); } widgAddButton(psRequestScreen, &sButInit); } // fill slots. slotCount = 0; sprintf(sTemp,"%s*.%s",sSearchPath,sExtension); // form search string. strcpy(sPath,sSearchPath); // setup locals. strcpy(sExt,sExtension); dir =FindFirstFile(sTemp,&found); if(dir != INVALID_HANDLE_VALUE) { while( TRUE ) { /* Set the tip and add the button */ found.cFileName[strlen(found.cFileName) -4 ] = '\0'; // chop extension strcpy(sSlots[slotCount],found.cFileName); //store it! ((W_BUTTON *)widgGetFromID(psRequestScreen,LOADENTRY_START+slotCount))->pTip = sSlots[slotCount]; ((W_BUTTON *)widgGetFromID(psRequestScreen,LOADENTRY_START+slotCount))->pText = sSlots[slotCount]; slotCount++; // goto next but. if(!FindNextFile(dir,&found ) || slotCount == 10 )// only show upto 10 entrys. { break; } } } FindClose(dir); bLoadSaveUp = TRUE; return TRUE; }
// //////////////////////////////////////////////////////////////////////////// BOOL startKeyMapEditor(BOOL first) { W_BUTINIT sButInit; W_FORMINIT sFormInit; KEY_MAPPING *psMapping; UDWORD i,mapcount =0; UDWORD bubbleCount; BOOL bAtEnd,bGotOne; KEY_MAPPING *psPresent,*psNext; char test[255]; addBackdrop(); addSideText (FRONTEND_SIDETEXT ,KM_X-2,KM_Y,strresGetString(psStringRes, STR_KM_KEYMAP_SIDE)); if(first) { loadKeyMap(); // get the current mappings. } memset(&sFormInit, 0, sizeof(W_FORMINIT)); // draw blue form... sFormInit.formID = FRONTEND_BACKDROP; sFormInit.id = KM_FORM; sFormInit.style = WFORM_PLAIN; sFormInit.x = KM_X; sFormInit.y = KM_Y; sFormInit.width = KM_W; sFormInit.height = KM_H; sFormInit.pDisplay = intDisplayPlainForm; widgAddForm(psWScreen, &sFormInit); addMultiBut(psWScreen,KM_FORM,KM_RETURN, // return button. 8,5, iV_GetImageWidth(FrontImages,IMAGE_RETURN), iV_GetImageHeight(FrontImages,IMAGE_RETURN), STR_MUL_CANCEL,IMAGE_RETURN,IMAGE_RETURN_HI,TRUE); addMultiBut(psWScreen,KM_FORM,KM_DEFAULT, 11,45, 56,38, STR_MUL_DEFAULT, IMAGE_KEYMAP_DEFAULT,IMAGE_KEYMAP_DEFAULT,TRUE); // default. /* Better be none that come after this...! */ strcpy(test,"zzzzzzzzzzzzzzzzzzzzz"); psMapping = NULL; //count mappings required. for(psMapping = keyMappings; psMapping; psMapping = psMapping->psNext) { if( (psMapping->status!=KEYMAP__DEBUG)&&(psMapping->status!=KEYMAP___HIDE)) // if it's not a debug mapping.. { mapcount++; if(strcmp(psMapping->pName,test) < 0) { /* Best one found so far */ strcpy(test,psMapping->pName); psPresent = psMapping; } } } // add tab form.. memset(&sFormInit, 0, sizeof(W_FORMINIT)); sFormInit.formID = KM_FORM; sFormInit.id = KM_FORM_TABS; sFormInit.style = WFORM_TABBED; sFormInit.x = 50; sFormInit.y = 10; sFormInit.width = KM_W- 100; sFormInit.height = KM_H- 4; sFormInit.numMajor = numForms(mapcount, BUTTONSPERKEYMAPPAGE); sFormInit.majorPos = WFORM_TABTOP; sFormInit.minorPos = WFORM_TABNONE; sFormInit.majorSize = OBJ_TABWIDTH+3; sFormInit.majorOffset = OBJ_TABOFFSET; sFormInit.tabVertOffset = (OBJ_TABHEIGHT/2); sFormInit.tabMajorThickness = OBJ_TABHEIGHT; sFormInit.pFormDisplay = intDisplayObjectForm; sFormInit.pUserData = (void*)&StandardTab; sFormInit.pTabDisplay = intDisplayTab; for (i=0; i< sFormInit.numMajor; i++) { sFormInit.aNumMinors[i] = 1; } widgAddForm(psWScreen, &sFormInit); //Put the buttons on it memset(&sButInit, 0, sizeof(W_BUTINIT)); sButInit.formID = KM_FORM_TABS; sButInit.style = WFORM_PLAIN; sButInit.width = KM_ENTRYW; sButInit.height = KM_ENTRYH; sButInit.pDisplay = displayKeyMap; sButInit.x = 2; sButInit.y = 16; sButInit.id = KM_START; /* Add our first mapping to the form */ sButInit.pUserData= (VOID*)psPresent; widgAddButton(psWScreen, &sButInit); sButInit.id++; /* Now add the others... */ bubbleCount = 0; bAtEnd = FALSE; /* Stop when the right number or when aphabetically last - not sure...! */ while(bubbleCount<mapcount-1 AND !bAtEnd) { /* Same test as before for upper limit */ strcpy(test,"zzzzzzzzzzzzzzzzzzzzz"); for(psMapping = keyMappings,psNext = NULL,bGotOne = FALSE; psMapping; psMapping = psMapping->psNext) { /* Only certain mappings get displayed */ if( (psMapping->status!=KEYMAP__DEBUG)&&(psMapping->status!=KEYMAP___HIDE)) // if it's not a debug mapping.. { /* If it's alphabetically good but better then next one */ if(strcmp(psMapping->pName,test) < 0 AND strcmp(psMapping->pName,psPresent->pName) > 0) { /* Keep a record of it */ strcpy(test,psMapping->pName); psNext = psMapping; bGotOne = TRUE; } } } /* We found one matching criteria */ if(bGotOne) { psPresent = psNext; bubbleCount++; sButInit.pUserData= (VOID*)psNext; widgAddButton(psWScreen, &sButInit); // move on.. sButInit.id++; /* Might be no more room on the page */ if ( (sButInit.y + KM_ENTRYH+5 ) > (3+ (BUTTONSPERKEYMAPPAGE*(KM_ENTRYH+3)))) { sButInit.y = 16; sButInit.majorID += 1; } else { sButInit.y += KM_ENTRYH +3; } } else { /* The previous one we found was alphabetically last - time to stop */ bAtEnd = TRUE; } } /* Go home... */ return TRUE; }