You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
442 lines
14 KiB
442 lines
14 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
//#include "plClothingMtl.h" |
|
#include "../../AssetMan/PublicInterface/AssManBaseTypes.h" |
|
#include "max.h" |
|
|
|
class plClothingEditBox |
|
{ |
|
protected: |
|
int fCtrlID; |
|
int fPBEditID; |
|
|
|
plClothingEditBox() {}; |
|
|
|
void IGetText(IParamBlock2 *pb, HWND hCtrl) |
|
{ |
|
// Get the previous value |
|
const char *oldVal = pb->GetStr(fPBEditID); |
|
if (!oldVal) |
|
oldVal = ""; |
|
|
|
// Get the text from the edit and store it in the paramblock |
|
int len = GetWindowTextLength(hCtrl)+1; |
|
if (len > 1) |
|
{ |
|
char *buf = TRACKED_NEW char[len]; |
|
GetWindowText(hCtrl, buf, len); |
|
|
|
// If the old value is different from the current one, update |
|
if (strcmp(oldVal, buf)) |
|
pb->SetValue(fPBEditID, 0, buf); |
|
|
|
delete [] buf; |
|
} |
|
else |
|
{ |
|
// If the old value wasn't empty, update |
|
if (*oldVal != '\0') |
|
pb->SetValue(fPBEditID, 0, ""); |
|
} |
|
} |
|
|
|
public: |
|
plClothingEditBox(int ctrlID, int pbEditID) : fCtrlID(ctrlID), fPBEditID(pbEditID) {} |
|
|
|
void UpdateText(IParamBlock2 *pb, HWND hWnd) |
|
{ |
|
const char *str = pb->GetStr(fPBEditID); |
|
SetDlgItemText(hWnd, fCtrlID, (str != nil ? str : "")); |
|
} |
|
|
|
BOOL ProcessMsg(IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
// If this isn't a message we process, return |
|
if (!(msg == WM_INITDIALOG || msg == WM_DESTROY || |
|
(msg == WM_COMMAND && LOWORD(wParam) == fCtrlID))) |
|
return FALSE; |
|
|
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
|
|
// Initializing the dialog, set the text box |
|
if (msg == WM_INITDIALOG) |
|
{ |
|
UpdateText(pb, hWnd); |
|
return FALSE; |
|
} |
|
|
|
// Being destroyed, but we may not have gotten the text from the edit box |
|
// (EN_KILLFOCUS seems to be sent after the window isn't recieving any more messages) |
|
if (msg == WM_DESTROY) |
|
{ |
|
IGetText(pb, GetDlgItem(hWnd, fCtrlID)); |
|
return FALSE; |
|
} |
|
|
|
int notification = HIWORD(wParam); |
|
HWND hCtrl = (HWND)lParam; |
|
|
|
// Disable Max accelerators when the edit box gets focus |
|
if (notification == EN_SETFOCUS) |
|
{ |
|
//plMaxAccelerators::Disable(); |
|
DisableAccelerators(); |
|
return TRUE; |
|
} |
|
// The edit control is losing focus, get it's contents |
|
else if (notification == EN_KILLFOCUS) |
|
{ |
|
IGetText(pb, hCtrl); |
|
//plMaxAccelerators::Enable(); |
|
EnableAccelerators(); |
|
return TRUE; |
|
} |
|
|
|
return FALSE; |
|
} |
|
}; |
|
|
|
class ClothingBasicDlgProc; |
|
extern ClothingBasicDlgProc gClothingBasicDlgProc; |
|
|
|
static ParamBlockDesc2 gClothingMtlPB |
|
( |
|
plClothingMtl::kBlkBasic, _T("Clothing"), IDS_PASS_BASIC, GetClothingMtlDesc(), |
|
P_AUTO_CONSTRUCT + P_AUTO_UI + P_CALLSETS_ON_LOAD, plClothingMtl::kRefBasic, |
|
|
|
// UI |
|
IDD_CLOTHING, IDS_PASS_BASIC, 0, 0, &gClothingBasicDlgProc, |
|
|
|
plClothingMtl::kTileset, _T("tileset"), TYPE_INT, 0, 0, |
|
p_default, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmap, _T("texmap"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kDescription, _T("ItemDescription"), TYPE_STRING, 0, 0, |
|
p_ui, TYPE_EDITBOX, IDC_CLOTHING_DESCRIPTION, |
|
end, |
|
|
|
plClothingMtl::kThumbnail, _T("Thumbnail"), TYPE_TEXMAP, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kLayer, _T("Layer"), TYPE_INT, 0, 0, |
|
p_default, plClothingElement::kLayerTint1, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkin, _T("SkinLayer"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmap2, _T("TintLayer2"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kDefault, _T("Default"), TYPE_BOOL, 0, 0, |
|
p_ui, TYPE_SINGLECHEKBOX, IDC_CLOTHING_DEFAULT, |
|
p_default, 0, |
|
end, |
|
|
|
plClothingMtl::kCustomTextSpecs, _T("TextSpecs"), TYPE_STRING, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapBase, _T("BaseLayer"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend1, _T("SkinBlend(1)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend2, _T("SkinBlend(2)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend3, _T("SkinBlend(3)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend4, _T("SkinBlend(4)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend5, _T("SkinBlend(5)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kTexmapSkinBlend6, _T("SkinBlend(6)"), TYPE_TEXMAP_TAB, plClothingMtl::kMaxTiles, 0, 0, |
|
end, |
|
|
|
plClothingMtl::kDefaultTint1, _T("DefaultTint1"), TYPE_RGBA, 0, 0, |
|
p_ui, TYPE_COLORSWATCH, IDC_CLOTHING_TINT1, |
|
p_default, Color(1,1,1), |
|
end, |
|
|
|
plClothingMtl::kDefaultTint2, _T("DefaultTint2"), TYPE_RGBA, 0, 0, |
|
p_ui, TYPE_COLORSWATCH, IDC_CLOTHING_TINT2, |
|
p_default, Color(1,1,1), |
|
end, |
|
|
|
plClothingMtl::kForcedAcc, _T("ForcedAcc"), TYPE_STRING, 0, 0, |
|
p_ui, TYPE_EDITBOX, IDC_CLOTHING_FORCED_ACC, |
|
end, |
|
|
|
end |
|
); |
|
|
|
class ClothingBasicDlgProc : public ParamMap2UserDlgProc |
|
{ |
|
protected: |
|
plClothingEditBox fCustomText; |
|
|
|
public: |
|
ClothingBasicDlgProc() : fCustomText(IDC_CLOTHING_CUSTOM_TEXT_SPECS, plClothingMtl::kCustomTextSpecs) {} |
|
~ClothingBasicDlgProc() {} |
|
|
|
void UpdateDisplay(IParamMap2 *pmap) |
|
{ |
|
HWND hWnd = pmap->GetHWnd(); |
|
IParamBlock2 *pb = pmap->GetParamBlock(); |
|
|
|
plClothingMtl *mtl = (plClothingMtl *)pb->GetOwner(); |
|
HWND cbox = NULL; |
|
plPlasmaMAXLayer *layer; |
|
PBBitmap *pbbm; |
|
ICustButton *bmSelectBtn; |
|
char buff[256]; |
|
|
|
// Setup the tiles |
|
int i, j; |
|
int layerSet = pb->GetInt(ParamID(plClothingMtl::kLayer)); |
|
int layerIdx = plClothingMtl::LayerToPBIdx[layerSet]; |
|
for (j = 0; j < plClothingMtl::kMaxTiles; j++) |
|
{ |
|
layer = (plPlasmaMAXLayer *)pb->GetTexmap(ParamID(layerIdx), 0, j); |
|
pbbm = (layer == nil ? nil : layer->GetPBBitmap()); |
|
|
|
bmSelectBtn = GetICustButton(GetDlgItem(hWnd, plClothingMtl::ButtonConstants[j])); |
|
bmSelectBtn->SetText(pbbm ? (TCHAR*)pbbm->bi.Filename() : "(none)"); |
|
ReleaseICustButton(bmSelectBtn); |
|
} |
|
|
|
// And the thumbnail... |
|
layer = (plPlasmaMAXLayer *)pb->GetTexmap(ParamID(plClothingMtl::kThumbnail)); |
|
if (layer == nil) |
|
{ |
|
layer = TRACKED_NEW plLayerTex; |
|
pb->SetValue(ParamID(plClothingMtl::kThumbnail), 0, layer); |
|
} |
|
pbbm = layer->GetPBBitmap(); |
|
if (pbbm) |
|
{ |
|
bmSelectBtn = GetICustButton(GetDlgItem(hWnd, IDC_CLOTHING_THUMBNAIL)); |
|
bmSelectBtn->SetText((TCHAR*)pbbm->bi.Filename()); |
|
ReleaseICustButton(bmSelectBtn); |
|
} |
|
|
|
int setIdx = pb->GetInt(ParamID(plClothingMtl::kTileset)); |
|
ComboBox_SetCurSel(GetDlgItem(hWnd, IDC_CLOTHING_TILESET), setIdx); |
|
ComboBox_SetCurSel(GetDlgItem(hWnd, IDC_CLOTHING_LAYER), pb->GetInt(ParamID(plClothingMtl::kLayer))); |
|
mtl->InitTilesets(); |
|
plClothingTileset *tileset = mtl->fTilesets.Get(setIdx); |
|
for (i = 0; i < tileset->fElements.GetCount(); i++) |
|
{ |
|
plClothingElement *element = tileset->fElements.Get(i); |
|
SendMessage(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i]), |
|
WM_SETTEXT, NULL, (LPARAM)element->fName); |
|
sprintf(buff, "(%d, %d)", element->fWidth, element->fHeight); |
|
SendMessage(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i + 1]), |
|
WM_SETTEXT, NULL, (LPARAM)buff); |
|
|
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i]), SW_SHOW); |
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i + 1]), SW_SHOW); |
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::ButtonConstants[i]), SW_SHOW); |
|
} |
|
for (i = tileset->fElements.GetCount(); i < plClothingMtl::kMaxTiles; i++) |
|
{ |
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i]), SW_HIDE); |
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::TextConstants[2 * i + 1]), SW_HIDE); |
|
ShowWindow(GetDlgItem(hWnd, plClothingMtl::ButtonConstants[i]), SW_HIDE); |
|
} |
|
mtl->ReleaseTilesets(); |
|
|
|
fCustomText.UpdateText(pb, hWnd); |
|
} |
|
|
|
virtual void Update(TimeValue t, Interval& valid, IParamMap2* pmap) { UpdateDisplay(pmap); } |
|
|
|
BOOL DlgProc(TimeValue t, IParamMap2 *map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
|
{ |
|
// Check if it is for our edit box |
|
if (fCustomText.ProcessMsg(map, hWnd, msg, wParam, lParam)) |
|
return TRUE; |
|
|
|
int id = LOWORD(wParam); |
|
int code = HIWORD(wParam); |
|
|
|
IParamBlock2 *pb = map->GetParamBlock(); |
|
plClothingMtl *mtl = (plClothingMtl *)pb->GetOwner(); |
|
HWND cbox = NULL; |
|
plPlasmaMAXLayer *layer; |
|
PBBitmap *pbbm; |
|
ICustButton *bmSelectBtn; |
|
int layerIdx = plClothingMtl::LayerToPBIdx[pb->GetInt(ParamID(plClothingMtl::kLayer))]; |
|
|
|
switch (msg) |
|
{ |
|
case WM_INITDIALOG: |
|
int j; |
|
mtl->InitTilesets(); |
|
cbox = GetDlgItem(hWnd, IDC_CLOTHING_TILESET); |
|
for (j = 0; j < mtl->fTilesets.GetCount(); j++) |
|
SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM)mtl->fTilesets.Get(j)->fName); |
|
|
|
mtl->ReleaseTilesets(); |
|
|
|
cbox = GetDlgItem(hWnd, IDC_CLOTHING_LAYER); |
|
for (j = 0; j < plClothingElement::kLayerMax; j++) |
|
ComboBox_AddString(cbox, plClothingMtl::LayerStrings[j]); |
|
|
|
return TRUE; |
|
|
|
case WM_COMMAND: |
|
if (id == IDC_CLOTHING_TILESET) |
|
{ |
|
int setIdx = SendMessage(GetDlgItem(hWnd, id), CB_GETCURSEL, 0, 0); |
|
pb->SetValue(plClothingMtl::kTileset, t, setIdx); |
|
return TRUE; |
|
} |
|
|
|
if (id == IDC_CLOTHING_LAYER) |
|
{ |
|
|
|
pb->SetValue(plClothingMtl::kLayer, t, ComboBox_GetCurSel(GetDlgItem(hWnd, id))); |
|
return TRUE; |
|
} |
|
|
|
if (id == IDC_CLOTHING_THUMBNAIL) |
|
{ |
|
layer = (plPlasmaMAXLayer *)pb->GetTexmap(ParamID(plClothingMtl::kThumbnail)); |
|
if (layer == nil) |
|
return FALSE; |
|
|
|
BitmapInfo bi; |
|
bi.SetName(layer->GetPBBitmap() == nil ? "" : layer->GetPBBitmap()->bi.Name()); |
|
|
|
BOOL selectedNewBitmap = layer->HandleBitmapSelection(); |
|
if (selectedNewBitmap) |
|
{ |
|
pbbm = layer->GetPBBitmap(); |
|
bmSelectBtn = GetICustButton(GetDlgItem(hWnd, IDC_CLOTHING_THUMBNAIL)); |
|
bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : "(none)"); |
|
ReleaseICustButton(bmSelectBtn); |
|
} |
|
return TRUE; |
|
} |
|
|
|
int buttonIdx = -1; |
|
if (id == IDC_CLOTHING_TEXTURE1) buttonIdx = 0; |
|
else if (id == IDC_CLOTHING_TEXTURE2) buttonIdx = 1; |
|
else if (id == IDC_CLOTHING_TEXTURE3) buttonIdx = 2; |
|
else if (id == IDC_CLOTHING_TEXTURE4) buttonIdx = 3; |
|
|
|
if (buttonIdx != -1) |
|
{ |
|
layer = (plPlasmaMAXLayer *)pb->GetTexmap(ParamID(layerIdx), 0, buttonIdx); |
|
if (layer == nil) |
|
{ // First time we've set a layer on this spot |
|
layer = TRACKED_NEW plLayerTex; |
|
pb->SetValue(ParamID(layerIdx), 0, layer, buttonIdx); |
|
} |
|
|
|
jvUniqueId oldId; |
|
layer->GetBitmapAssetId(oldId); |
|
|
|
BitmapInfo bi; |
|
bi.SetName(layer->GetPBBitmap() == nil ? "" : layer->GetPBBitmap()->bi.Name()); |
|
|
|
BOOL selectedNewBitmap = layer->HandleBitmapSelection(); |
|
if (selectedNewBitmap) |
|
{ |
|
// Check if it's ok, and undo if not. |
|
hsBool choiceOk = true; |
|
|
|
pbbm = layer->GetPBBitmap(); |
|
if (pbbm != nil) |
|
{ |
|
mtl->InitTilesets(); |
|
|
|
plClothingTileset *tileset = mtl->fTilesets.Get(pb->GetInt(plClothingMtl::kTileset)); |
|
plClothingElement *element = tileset->fElements.Get(buttonIdx); |
|
float targRatio = (float)element->fWidth / (float)element->fHeight; |
|
float ratio = (float)pbbm->bi.Width() / (float)pbbm->bi.Height(); |
|
|
|
if (targRatio != ratio) |
|
{ |
|
choiceOk = false; |
|
hsMessageBox("That image's width/height ratio does not match the one for this tile. " |
|
"Restoring the old selection.", "Invalid image", hsMessageBoxNormal); |
|
} |
|
else if (pbbm->bi.Width() < element->fWidth) |
|
{ |
|
choiceOk = false; |
|
hsMessageBox("The chosen image is too small for that tile slot. " |
|
"Restoring the old selection.", "Invalid image", hsMessageBoxNormal); |
|
} |
|
|
|
mtl->ReleaseTilesets(); |
|
} |
|
if (!choiceOk) |
|
{ |
|
layer->SetBitmapAssetId(oldId); |
|
layer->SetBitmap(&bi); |
|
} |
|
else |
|
{ |
|
bmSelectBtn = GetICustButton(GetDlgItem(hWnd, plClothingMtl::ButtonConstants[buttonIdx])); |
|
bmSelectBtn->SetText(pbbm != nil ? (TCHAR*)pbbm->bi.Filename() : "(none)"); |
|
ReleaseICustButton(bmSelectBtn); |
|
} |
|
} |
|
} |
|
return TRUE; |
|
} |
|
|
|
return FALSE; |
|
} |
|
|
|
void DeleteThis() {} |
|
}; |
|
static ClothingBasicDlgProc gClothingBasicDlgProc;
|
|
|