void RenderEditorItemsInfo() { UINT8 *pDestBuf, *pSrcBuf; UINT32 uiSrcPitchBYTES, uiDestPitchBYTES; INVTYPE *item; HVOBJECT hVObject; UINT32 uiVideoObjectIndex; INT16 i; INT16 minIndex, maxIndex; INT16 sWidth, sOffset, sStart, x, y; UINT16 usNumItems; UINT16 usQuantity; if(!eInfo.fActive) { return; } if( gusMouseXPos < (iScreenWidthOffset + 110) || gusMouseXPos > (iScreenWidthOffset + 480) || gusMouseYPos < (2 * iScreenHeightOffset + 360) || gusMouseYPos > (2 * iScreenHeightOffset + 440) ) { //Mouse has moved out of the items display region -- so nothing can be highlighted. eInfo.sHilitedItemIndex = -1; } pDestBuf = LockVideoSurface(FRAME_BUFFER, &uiDestPitchBYTES); pSrcBuf = LockVideoSurface(eInfo.uiBuffer, &uiSrcPitchBYTES); Blt16BPPTo16BPP((UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, iScreenWidthOffset + 110, 2 * iScreenHeightOffset + 360, 60*eInfo.sScrollIndex, 0, 360, 80 ); UnLockVideoSurface(eInfo.uiBuffer); UnLockVideoSurface(FRAME_BUFFER); //calculate the min and max index that is currently shown. This determines //if the highlighted and/or selected items are drawn with the outlines. minIndex = eInfo.sScrollIndex * 2; maxIndex = minIndex + 11; //draw the hilighted item if applicable. if( eInfo.sHilitedItemIndex >= minIndex && eInfo.sHilitedItemIndex <= maxIndex ) { if( eInfo.pusItemIndex ) { item = &Item[eInfo.pusItemIndex[eInfo.sHilitedItemIndex]]; uiVideoObjectIndex = GetInterfaceGraphicForItem( item ); GetVideoObject( &hVObject, uiVideoObjectIndex ); x = iScreenWidthOffset + (eInfo.sHilitedItemIndex/2 - eInfo.sScrollIndex)*60 + 110; y = 2 * iScreenHeightOffset + 360 + (eInfo.sHilitedItemIndex % 2) * 40; UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : item->ubGraphicNum; sWidth = hVObject->pETRLEObject[usGraphicNum].usWidth; sOffset = hVObject->pETRLEObject[usGraphicNum].sOffsetX; sStart = x + (60 - sWidth - sOffset*2) / 2; if( sWidth ) { BltVideoObjectOutlineFromIndex( FRAME_BUFFER, uiVideoObjectIndex, usGraphicNum, sStart, y+2, Get16BPPColor(FROMRGB(250, 250, 0)), TRUE ); } } } //draw the selected item if( eInfo.sSelItemIndex >= minIndex && eInfo.sSelItemIndex <= maxIndex ) { if( eInfo.pusItemIndex ) { item = &Item[eInfo.pusItemIndex[eInfo.sSelItemIndex]]; uiVideoObjectIndex = GetInterfaceGraphicForItem( item ); GetVideoObject( &hVObject, uiVideoObjectIndex ); x = iScreenWidthOffset + (eInfo.sSelItemIndex/2 - eInfo.sScrollIndex)*60 + 110; y = 2 * iScreenHeightOffset + 360 + (eInfo.sSelItemIndex % 2) * 40; UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : item->ubGraphicNum; sWidth = hVObject->pETRLEObject[usGraphicNum].usWidth; sOffset = hVObject->pETRLEObject[usGraphicNum].sOffsetX; sStart = x + (60 - sWidth - sOffset*2) / 2; if( sWidth ) { BltVideoObjectOutlineFromIndex( FRAME_BUFFER, uiVideoObjectIndex, usGraphicNum, sStart, y+2, Get16BPPColor(FROMRGB(250, 0, 0)), TRUE ); } } } //draw the numbers of each visible item that currently resides in the world. maxIndex = min( maxIndex, eInfo.sNumItems-1 ); for( i = minIndex; i <= maxIndex; i++ ) { usNumItems = CountNumberOfEditorPlacementsInWorld( i, &usQuantity ); if( usNumItems ) { x = iScreenWidthOffset + (i/2 - eInfo.sScrollIndex)*60 + 110; y = 2 * iScreenHeightOffset + 360 + (i % 2) * 40; SetFont( FONT10ARIAL ); SetFontForeground( FONT_YELLOW ); SetFontShadow( FONT_NEARBLACK ); if( usNumItems == usQuantity ) mprintf( x + 12, y + 4, L"%d", usNumItems ); else mprintf( x + 12, y + 4, L"%d(%d)", usNumItems, usQuantity ); } } }
void RenderSelectedItemBlownUp() { UINT32 uiVideoObjectIndex; HVOBJECT hVObject; INT16 sScreenX, sScreenY, xp, yp; ITEM_POOL *pItemPool; UINT16 szItemName[ SIZE_ITEM_NAME ]; INT32 i; INT16 sWidth, sHeight, sOffsetX, sOffsetY; GetGridNoScreenPos( gsItemGridNo, 0, &sScreenX, &sScreenY ); if( sScreenY > 340 ) return; //Display the enlarged item graphic uiVideoObjectIndex = GetInterfaceGraphicForItem( &Item[ gpItem->usItem ] ); GetVideoObject( &hVObject, uiVideoObjectIndex ); sWidth = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].usWidth; sOffsetX = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].sOffsetX; xp = sScreenX + (40 - sWidth - sOffsetX*2) / 2; sHeight = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].usHeight; sOffsetY = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].sOffsetY; yp = sScreenY + (20 - sHeight - sOffsetY*2) / 2; BltVideoObjectOutlineFromIndex( FRAME_BUFFER, uiVideoObjectIndex, Item[ gpItem->usItem ].ubGraphicNum, xp, yp, Get16BPPColor(FROMRGB(0, 140, 170)), TRUE ); //Display the item name above it SetFont( FONT10ARIAL ); SetFontForeground( FONT_YELLOW ); SetFontShadow( FONT_NEARBLACK ); if( gpItem->usItem == ACTION_ITEM || gpItem->usItem == SWITCH ) { BuildTriggerName( gpItem, szItemName ); } else if( Item[ gpItem->usItem ].usItemClass == IC_KEY ) { swprintf( szItemName, L"%S", LockTable[ gpItem->ubKeyID ].ubEditorName ); } else { LoadItemInfo( gpItem->usItem, szItemName, NULL ); } xp = sScreenX - (StringPixLength( szItemName, FONT10ARIAL ) - 40) / 2; yp -= 10; mprintf( xp, yp, szItemName ); if( gpItem->usItem == ACTION_ITEM ) { UINT16 *pStr; pStr = GetActionItemName( gpItem ); xp = sScreenX - (StringPixLength( pStr, FONT10ARIALBOLD ) - 40) / 2; yp += 10; SetFont( FONT10ARIALBOLD ); SetFontForeground( FONT_LTKHAKI ); mprintf( xp, yp, pStr ); SetFontForeground( FONT_YELLOW ); } //Count the number of items in the current pool, and display that. i = 0; GetItemPool( gsItemGridNo, &pItemPool, 0 ); Assert( pItemPool ); while( pItemPool ) { i++; pItemPool = pItemPool->pNext; } xp = sScreenX; yp = sScreenY + 10; mprintf( xp, yp, L"%d", i ); //If the item is hidden, render a blinking H (just like DG) if( gWorldItems[ gpItemPool->iItemIndex ].bVisible == HIDDEN_ITEM || gWorldItems[ gpItemPool->iItemIndex ].bVisible == BURIED ) { SetFont( FONT10ARIALBOLD ); if( GetJA2Clock() % 1000 > 500 ) { SetFontForeground( 249 ); } mprintf( sScreenX + 16, sScreenY + 7, L"H" ); InvalidateRegion( sScreenX + 16, sScreenY + 7, sScreenX + 24, sScreenY + 27 ); } }
void InitEditorItemsInfo(UINT32 uiItemType) { VSURFACE_DESC vs_desc; UINT8 *pDestBuf, *pSrcBuf; UINT32 uiSrcPitchBYTES, uiDestPitchBYTES; INVTYPE *item; SGPRect SaveRect, NewRect; HVOBJECT hVObject; UINT32 uiVideoObjectIndex; UINT16 usUselessWidth, usUselessHeight; INT16 sWidth, sOffset, sStart; INT16 i, x, y; UINT16 usCounter; CHAR16 pStr[ 100 ];//, pStr2[ 100 ]; CHAR16 pItemName[SIZE_ITEM_NAME]; UINT8 ubBitDepth; BOOLEAN fTypeMatch; INT32 iEquipCount = 0; // Check to make sure that there isn't already a valid eInfo if( eInfo.fActive ) { if( eInfo.uiItemType == uiItemType ) { //User clicked on the same item classification -- ignore return; } else { //User selected a different item classification -- delete it first. ClearEditorItemsInfo(); ClearTaskbarRegion( iScreenWidthOffset + 100, 2 * iScreenHeightOffset + 360, iScreenWidthOffset + 480, 2 * iScreenHeightOffset + 440 ); } } else { //Clear the menu area, so that the buffer doesn't get corrupted. ClearTaskbarRegion( iScreenWidthOffset + 100, 2 * iScreenHeightOffset + 360, iScreenWidthOffset + 480, 2 * iScreenHeightOffset + 440 ); } EnableEditorRegion( ITEM_REGION_ID ); eInfo.uiItemType = uiItemType; eInfo.fActive = TRUE; //Begin initialization of data. switch(uiItemType) { case TBAR_MODE_ITEM_WEAPONS: eInfo.sNumItems = eInfo.sNumWeapons; eInfo.sScrollIndex = eInfo.sSaveWeaponsScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelWeaponsIndex; break; case TBAR_MODE_ITEM_AMMO: eInfo.sNumItems = eInfo.sNumAmmo; eInfo.sScrollIndex = eInfo.sSaveAmmoScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelAmmoIndex; break; case TBAR_MODE_ITEM_ARMOUR: eInfo.sNumItems = eInfo.sNumArmour; eInfo.sScrollIndex = eInfo.sSaveArmourScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelArmourIndex; break; case TBAR_MODE_ITEM_LBEGEAR: eInfo.sNumItems = eInfo.sLBEGear; eInfo.sScrollIndex = eInfo.sSaveLBEScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelLBEIndex; break; case TBAR_MODE_ITEM_EXPLOSIVES: eInfo.sNumItems = eInfo.sNumExplosives; eInfo.sScrollIndex = eInfo.sSaveExplosivesScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelExplosivesIndex; break; case TBAR_MODE_ITEM_EQUIPMENT1: eInfo.sNumItems = eInfo.sNumEquipment1; eInfo.sScrollIndex = eInfo.sSaveEquipment1ScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelEquipment1Index; break; case TBAR_MODE_ITEM_EQUIPMENT2: eInfo.sNumItems = eInfo.sNumEquipment2; eInfo.sScrollIndex = eInfo.sSaveEquipment2ScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelEquipment2Index; break; case TBAR_MODE_ITEM_EQUIPMENT3: eInfo.sNumItems = eInfo.sNumEquipment3; eInfo.sScrollIndex = eInfo.sSaveEquipment3ScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelEquipment3Index; break; case TBAR_MODE_ITEM_TRIGGERS: eInfo.sNumItems = eInfo.sNumTriggers; eInfo.sScrollIndex = eInfo.sSaveTriggersScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelTriggersIndex; break; case TBAR_MODE_ITEM_KEYS: eInfo.sNumItems = eInfo.sNumKeys; eInfo.sScrollIndex = eInfo.sSaveKeysScrollIndex; eInfo.sSelItemIndex = eInfo.sSaveSelKeysIndex; break; default: //error return; } //Allocate memory to store all the item pointers. eInfo.pusItemIndex = (UINT16*)MemAlloc( sizeof(UINT16) * eInfo.sNumItems ); //Disable the appropriate scroll buttons based on the saved scroll index if applicable //Left most scroll position DetermineItemsScrolling(); //calculate the width of the buffer based on the number of items. //every pair of items (odd rounded up) requires 60 pixels for width. //the minimum buffer size is 420. Height is always 80 pixels. eInfo.sWidth = (eInfo.sNumItems > 12) ? ((eInfo.sNumItems+1)/2)*60 : SCREEN_HEIGHT - 120; eInfo.sHeight = 80; // Create item buffer GetCurrentVideoSettings( &usUselessWidth, &usUselessHeight, &ubBitDepth ); vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE; vs_desc.usWidth = eInfo.sWidth; vs_desc.usHeight = eInfo.sHeight; vs_desc.ubBitDepth = ubBitDepth; //!!!Memory check. Create the item buffer if(!AddVideoSurface( &vs_desc, &eInfo.uiBuffer )) { eInfo.fKill = TRUE; eInfo.fActive = FALSE; return; } pDestBuf = LockVideoSurface(eInfo.uiBuffer, &uiDestPitchBYTES); pSrcBuf = LockVideoSurface(FRAME_BUFFER, &uiSrcPitchBYTES); //copy a blank chunk of the editor interface to the new buffer. for( i=0; i<eInfo.sWidth; i+=60 ) { Blt16BPPTo16BPP((UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, 0+i, 0, iScreenWidthOffset + 100, 2 * iScreenHeightOffset + 360, 60, 80 ); } UnLockVideoSurface(eInfo.uiBuffer); UnLockVideoSurface(FRAME_BUFFER); x = 0; y = 0; usCounter = 0; NewRect.iTop = 0; NewRect.iBottom = eInfo.sHeight; NewRect.iLeft = 0; NewRect.iRight = eInfo.sWidth; GetClippingRect(&SaveRect); SetClippingRect(&NewRect); if( eInfo.uiItemType == TBAR_MODE_ITEM_KEYS ) { //Keys use a totally different method for determining for( i = 0; i < eInfo.sNumItems; i++ ) { item = &Item[ KeyTable[ 0 ].usItem + LockTable[ i ].usKeyItem ]; uiVideoObjectIndex = GetInterfaceGraphicForItem( item ); GetVideoObject( &hVObject, uiVideoObjectIndex ); //Store these item pointers for later when rendering selected items. eInfo.pusItemIndex[i] = KeyTable[ 0 ].usItem + LockTable[ i ].usKeyItem; SetFont(SMALLCOMPFONT); SetFontForeground( FONT_MCOLOR_WHITE ); SetFontDestBuffer( eInfo.uiBuffer, 0, 0, eInfo.sWidth, eInfo.sHeight, FALSE ); swprintf( pStr, L"%S", LockTable[ i ].ubEditorName ); DisplayWrappedString(x, (UINT16)(y+25), 60, 2, SMALLCOMPFONT, FONT_WHITE, pStr, FONT_BLACK, TRUE, CENTER_JUSTIFIED ); UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : item->ubGraphicNum; //Calculate the center position of the graphic in a 60 pixel wide area. sWidth = hVObject->pETRLEObject[usGraphicNum].usWidth; sOffset = hVObject->pETRLEObject[usGraphicNum].sOffsetX; sStart = x + (60 - sWidth - sOffset*2) / 2; BltVideoObjectOutlineFromIndex( eInfo.uiBuffer, uiVideoObjectIndex, usGraphicNum, sStart, y+2, 0, FALSE ); //cycle through the various slot positions (0,0), (0,40), (60,0), (60,40), (120,0)... if( y == 0 ) { y = 40; } else { y = 0; x += 60; } } } else for( i = 0; i < eInfo.sNumItems; i++ ) { fTypeMatch = FALSE; while( usCounter<MAXITEMS && !fTypeMatch ) { if ( Item[usCounter].usItemClass == 0 ) break; item = &Item[usCounter]; //if( Item[usCounter].fFlags & ITEM_NOT_EDITOR ) if(item->notineditor) { usCounter++; continue; } if( eInfo.uiItemType == TBAR_MODE_ITEM_TRIGGERS ) { if( i < PRESSURE_ACTION_ID ) usCounter = ( i % 2 ) ? ACTION_ITEM : SWITCH; else usCounter = ACTION_ITEM; fTypeMatch = TRUE; item = &Item[usCounter]; } else switch( item->usItemClass ) { case IC_GUN: case IC_BLADE: case IC_LAUNCHER: case IC_THROWN: case IC_THROWING_KNIFE: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_WEAPONS; break; case IC_PUNCH: if ( i != NOTHING ) { fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_WEAPONS; } else { fTypeMatch = FALSE; } break; case IC_AMMO: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_AMMO; break; case IC_ARMOUR: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_ARMOUR; break; case IC_LBEGEAR: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_LBEGEAR; break; case IC_GRENADE: case IC_BOMB: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_EXPLOSIVES; break; case IC_MEDKIT: case IC_KIT: case IC_FACE: case IC_MONEY: case IC_BELTCLIP: fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_EQUIPMENT1; break; case IC_MISC: if( usCounter == ACTION_ITEM || usCounter == SWITCH ) break; if( iEquipCount < eInfo.sNumEquipment2 ) fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_EQUIPMENT2; else fTypeMatch = eInfo.uiItemType == TBAR_MODE_ITEM_EQUIPMENT3; iEquipCount++; break; } if( fTypeMatch ) { uiVideoObjectIndex = GetInterfaceGraphicForItem( item ); GetVideoObject( &hVObject, uiVideoObjectIndex ); //Store these item pointers for later when rendering selected items. eInfo.pusItemIndex[i] = usCounter; SetFont(SMALLCOMPFONT); SetFontForeground( FONT_MCOLOR_WHITE ); SetFontDestBuffer( eInfo.uiBuffer, 0, 0, eInfo.sWidth, eInfo.sHeight, FALSE ); if( eInfo.uiItemType != TBAR_MODE_ITEM_TRIGGERS ) { LoadItemInfo( usCounter, pItemName, NULL ); swprintf( pStr, L"%s", pItemName ); } else { if( i == PRESSURE_ACTION_ID ) { swprintf( pStr, pInitEditorItemsInfoText[0] ); } else if( i < 2 ) { if( usCounter == SWITCH ) swprintf( pStr, pInitEditorItemsInfoText[5] ); else swprintf( pStr, pInitEditorItemsInfoText[1] ); } else if( i < 4 ) { if( usCounter == SWITCH ) swprintf( pStr, pInitEditorItemsInfoText[6] ); else swprintf( pStr, pInitEditorItemsInfoText[2] ); } else if( i < 6 ) { if( usCounter == SWITCH ) swprintf( pStr, pInitEditorItemsInfoText[7] ); else swprintf( pStr, pInitEditorItemsInfoText[3] ); } else { if( usCounter == SWITCH ) swprintf( pStr, pInitEditorItemsInfoText[8], (i-4)/2 ); else swprintf( pStr, pInitEditorItemsInfoText[4], (i-4)/2 ); } } DisplayWrappedString(x, (UINT16)(y+25), 60, 2, SMALLCOMPFONT, FONT_WHITE, pStr, FONT_BLACK, TRUE, CENTER_JUSTIFIED ); UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : item->ubGraphicNum; if(usGraphicNum < hVObject->usNumberOfObjects) { //Calculate the center position of the graphic in a 60 pixel wide area. sWidth = hVObject->pETRLEObject[usGraphicNum].usWidth; sOffset = hVObject->pETRLEObject[usGraphicNum].sOffsetX; sStart = x + (60 - sWidth - sOffset*2) / 2; if( sWidth && sWidth > 0 ) { BltVideoObjectOutlineFromIndex( eInfo.uiBuffer, uiVideoObjectIndex, usGraphicNum, sStart, y+2, 0, FALSE ); } //cycle through the various slot positions (0,0), (0,40), (60,0), (60,40), (120,0)... if( y == 0 ) { y = 40; } else { y = 0; x += 60; } } else { static vfs::Log& editorLog = *vfs::Log::create(L"EditorItems.log"); editorLog << L"Tried to access item [" << item->ubGraphicNum << L"/" << hVObject->usNumberOfObjects << L"]" << vfs::Log::endl; } } usCounter++; } } SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE ); SetClippingRect(&SaveRect); gfRenderTaskbar = TRUE; }