aboutsummaryrefslogtreecommitdiff
path: root/engines/macventure
diff options
context:
space:
mode:
authorBorja Lorente2016-06-30 08:41:25 +0200
committerBorja Lorente2016-08-14 18:43:13 +0200
commit517aceefcb397ccda476dc7e2b02d6da5595e4fd (patch)
treee0430870cb341ba64f903d3042bffecfc744ea19 /engines/macventure
parent246fec28f55ca646a77985cd7b95a33b2cae994d (diff)
downloadscummvm-rg350-517aceefcb397ccda476dc7e2b02d6da5595e4fd.tar.gz
scummvm-rg350-517aceefcb397ccda476dc7e2b02d6da5595e4fd.tar.bz2
scummvm-rg350-517aceefcb397ccda476dc7e2b02d6da5595e4fd.zip
MACVENTURE: Add scene transition
Diffstat (limited to 'engines/macventure')
-rw-r--r--engines/macventure/gui.cpp280
-rw-r--r--engines/macventure/gui.h32
-rw-r--r--engines/macventure/image.cpp8
-rw-r--r--engines/macventure/macventure.cpp44
-rw-r--r--engines/macventure/macventure.h5
-rw-r--r--engines/macventure/world.cpp14
6 files changed, 246 insertions, 137 deletions
diff --git a/engines/macventure/gui.cpp b/engines/macventure/gui.cpp
index 7cae246ab1..15d573b6a8 100644
--- a/engines/macventure/gui.cpp
+++ b/engines/macventure/gui.cpp
@@ -110,12 +110,42 @@ Gui::~Gui() {
if (_controlData)
delete _controlData;
+ if (_exitsData)
+ delete _exitsData;
+
Common::HashMap<ObjID, ImageAsset*>::const_iterator it = _assets.begin();
for (; it != _assets.end(); it++) {
delete it->_value;
}
}
+void Gui::initGUI() {
+ _screen.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
+ _wm.setScreen(&_screen);
+
+ // Menu
+ _menu = _wm.addMenu();
+ if (!loadMenus())
+ error("Could not load menus");
+ _menu->setCommandsCallback(menuCommandsCallback, this);
+ _menu->calcDimensions();
+
+ loadGraphics();
+
+ if (!loadWindows())
+ error("Could not load windows");
+
+ initWindows();
+
+ assignObjReferences();
+
+ if (!loadControls())
+ error("Could not load controls");
+
+ draw();
+
+}
+
void Gui::draw() {
// Will be performance-improved after the milestone
@@ -138,15 +168,11 @@ void Gui::drawTitle() {
warning("drawTitle hasn't been tested yet");
}
-void Gui::drawExit(ObjID id) {
- findWindowData(kExitsWindow).children.push_back(DrawableObject(id, kBlitDirect));
-}
-
void Gui::clearControls() {
if (!_controlData)
return;
- Common::List<CommandButton>::iterator it = _controlData->begin();
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
for (; it != _controlData->end(); ++it) {
it->unselect();
}
@@ -228,33 +254,6 @@ void Gui::removeChild(WindowReference target, ObjID child) {
data.children.remove_at(index);
}
-void Gui::initGUI() {
- _screen.create(kScreenWidth, kScreenHeight, Graphics::PixelFormat::createFormatCLUT8());
- _wm.setScreen(&_screen);
-
- // Menu
- _menu = _wm.addMenu();
- if (!loadMenus())
- error("Could not load menus");
- _menu->setCommandsCallback(menuCommandsCallback, this);
- _menu->calcDimensions();
-
- loadGraphics();
-
- if (!loadWindows())
- error("Could not load windows");
-
- initWindows();
-
- assignObjReferences();
-
- if (!loadControls())
- error("Could not load controls");
-
- draw();
-
-}
-
void Gui::initWindows() {
// Game Controls Window
@@ -282,7 +281,7 @@ void Gui::initWindows() {
loadBorder(_outConsoleWindow, "border_left_scroll_inac.bmp", true);
// Self Window
- _selfWindow = _wm.addWindow(false, true, true);
+ _selfWindow = _wm.addWindow(false, true, false);
_selfWindow->setDimensions(getWindowData(kSelfWindow).bounds);
_selfWindow->setActive(false);
_selfWindow->setCallback(selfWindowCallback, this);
@@ -290,7 +289,7 @@ void Gui::initWindows() {
loadBorder(_selfWindow, "border_no_scroll_inac.bmp", true);
// Exits Window
- _exitsWindow = _wm.addWindow(false, true, true);
+ _exitsWindow = _wm.addWindow(false, false, false);
_exitsWindow->setDimensions(getWindowData(kExitsWindow).bounds);
_exitsWindow->setActive(false);
_exitsWindow->setCallback(exitsWindowCallback, this);
@@ -475,7 +474,8 @@ bool Gui::loadControls() {
Common::SeekableReadStream *res;
Common::MacResIDArray::const_iterator iter;
- _controlData = new Common::List<CommandButton>();
+ _controlData = new Common::Array<CommandButton>();
+ _exitsData = new Common::Array<CommandButton>();
if ((resArray = _resourceManager->getResIDArray(MKTAG('C', 'N', 'T', 'L'))).size() == 0)
return false;
@@ -541,7 +541,7 @@ void Gui::drawCommandsWindow() {
kColorBlack,
Graphics::kTextAlignCenter);
} else {
- Common::List<CommandButton>::const_iterator it = _controlData->begin();
+ Common::Array<CommandButton>::const_iterator it = _controlData->begin();
for (; it != _controlData->end(); ++it) {
CommandButton button = *it;
if (button.getData().refcon != kControlExitBox)
@@ -553,22 +553,22 @@ void Gui::drawCommandsWindow() {
void Gui::drawMainGameWindow() {
const WindowData &data = getWindowData(kMainGameWindow);
BorderBounds border = borderBounds(data.type);
+ ObjID objRef = data.objRef;
_mainGameWindow->setDirty(true);
- //if (data.titleLength > 0)
- // drawWindowTitle(kMainGameWindow, srf);
-
- if (!_assets.contains(3)) {
- _assets[3] = new ImageAsset(3, _graphics);
- }
+ if (data.objRef > 0 && data.objRef < 2000) {
+ if (!_assets.contains(objRef)) {
+ _assets[objRef] = new ImageAsset(objRef, _graphics);
+ }
- _assets[3]->blitInto(
- _mainGameWindow->getSurface(),
- border.leftOffset,
- border.topOffset,
- kBlitDirect);
+ _assets[objRef]->blitInto(
+ _mainGameWindow->getSurface(),
+ border.leftOffset,
+ border.topOffset,
+ kBlitDirect);
+ }
drawObjectsInWindow(kMainGameWindow, _mainGameWindow->getSurface());
findWindow(kMainGameWindow)->setDirty(true);
@@ -603,34 +603,20 @@ void Gui::drawInventories() {
}
void Gui::drawExitsWindow() {
- WindowData &data = findWindowData(kExitsWindow);
- BorderBounds border = borderBounds(data.type);
+
Graphics::ManagedSurface *srf = _exitsWindow->getSurface();
+ BorderBounds border = borderBounds(getWindowData(kExitsWindow).type);
+
srf->fillRect(Common::Rect(
border.leftOffset,
border.topOffset,
srf->w + border.rightOffset,
srf->h + border.bottomOffset), kColorWhite);
- // For each obj in the main window, if it is an exit, we draw it
- WindowData &objData = findWindowData(kMainGameWindow);
- Common::Point pos;
- ObjID child;
- //BlitMode mode;
- Common::Rect exit;
- for (uint i = 0; i < objData.children.size(); i++) {
- child = objData.children[i].obj;
- //mode = (BlitMode)objData.children[i].mode;
- pos = _engine->getObjExitPosition(child);
- pos.x += border.leftOffset;
- pos.y += border.topOffset;
- exit = Common::Rect(pos.x, pos.y, pos.x + kExitButtonWidth, pos.y + kExitButtonHeight);
- if (_engine->isObjExit(child)) {
- if (_engine->isObjSelected(child))
- srf->fillRect(exit, kColorGreen);
-
- srf->fillRect(exit, kColorGreen);
- }
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ CommandButton button = *it;
+ button.draw(*_exitsWindow->getSurface());
}
findWindow(kExitsWindow)->setDirty(true);
@@ -719,6 +705,92 @@ void Gui::drawDraggedObject() {
}
}
+
+void Gui::updateWindow(WindowReference winID, bool containerOpen) {
+ if (winID == kSelfWindow || containerOpen) {
+ WindowData &data = findWindowData(winID);
+ if (winID == kCommandsWindow) {
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
+ for (; it != _controlData->end(); ++it) {
+ it->unselect();
+ }
+ }
+ Common::Array<DrawableObject> &children = data.children;
+ for (uint i = 0; i < children.size(); i++) {
+ uint flag = 0;
+ ObjID child = children[i].obj;
+ BlitMode mode = kBlitDirect;
+ bool off = !_engine->isObjVisible(child);
+ if (flag || !off || !_engine->isObjClickable(child)) {
+ mode = kBlitBIC;
+ if (off || flag) {
+ mode = kBlitXOR;
+ }
+ else if (_engine->isObjSelected(child)) {
+ mode = kBlitOR;
+ }
+ children[i] = DrawableObject(child, mode);
+ }
+ else {
+ children[i] = DrawableObject(child, kBlitXOR);
+ }
+ }
+ if (winID == kMainGameWindow) {
+ drawMainGameWindow();
+ }
+ else {
+ Graphics::MacWindow *winRef = findWindow(winID);
+ winRef->getSurface()->fillRect(data.bounds, kColorGray);
+ }
+ if (data.type == kZoomDoc && data.updateScroll) {
+ warning("Unimplemented: update scroll");
+ }
+ }
+}
+
+void Gui::unselectExits() {
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ CommandButton button = *it;
+ button.unselect();
+ }
+}
+
+void Gui::updateExit(ObjID obj) {
+ if (!_engine->isObjExit(obj)) return;
+
+ BorderBounds border = borderBounds(getWindowData(kExitsWindow).type);
+
+ int ctl = -1;
+ int i = 0;
+ Common::Array<CommandButton>::const_iterator it = _exitsData->begin();
+ for (;it != _exitsData->end(); it++) {
+ if (it->getData().refcon == obj)
+ ctl = i;
+ else
+ i++;
+ }
+
+ if (ctl != -1)
+ _exitsData->remove_at(ctl);
+
+ if (!_engine->isHiddenExit(obj) &&
+ _engine->getParent(obj) == _engine->getParent(1))
+ {
+ ControlData data;
+ data.titleLength = 0;
+ data.refcon = obj;
+ Common::Point pos = _engine->getObjExitPosition(obj);
+ pos.x = border.leftOffset;
+ pos.y = border.topOffset;
+ data.bounds = Common::Rect(pos.x, pos.y, pos.x + kExitButtonWidth, pos.y + kExitButtonHeight);
+ data.visible = true;
+
+ _exitsData->push_back(CommandButton(data, this));
+ }
+}
+
+
WindowData & Gui::findWindowData(WindowReference reference) {
assert(_windowData);
@@ -894,46 +966,6 @@ void menuCommandsCallback(int action, Common::String &text, void *data) {
g->handleMenuAction((MenuAction)action);
}
-void Gui::updateWindow(WindowReference winID, bool containerOpen) {
- if (winID == kNoWindow) return;
- if (winID == kSelfWindow || containerOpen) {
- WindowData &data = findWindowData(winID);
- if (winID == kCommandsWindow) {
- Common::List<CommandButton>::iterator it = _controlData->begin();
- for (; it != _controlData->end(); ++it) {
- it->unselect();
- }
- }
- Common::Array<DrawableObject> &children = data.children;
- for (uint i = 0; i < children.size(); i++) {
- uint flag = 0;
- ObjID child = children[i].obj;
- BlitMode mode = kBlitDirect;
- bool off = !_engine->isObjVisible(child);
- if (flag || !off || !_engine->isObjClickable(child)) {
- mode = kBlitBIC;
- if (off || flag) {
- mode = kBlitXOR;
- } else if (_engine->isObjSelected(child)) {
- mode = kBlitOR;
- }
- children[i] = DrawableObject(child, mode);
- } else {
- children[i] = DrawableObject(child, kBlitXOR);
- }
- }
- if (winID == kMainGameWindow) {
- drawMainGameWindow();
- }
- else {
- Graphics::MacWindow *winRef = findWindow(winID);
- winRef->getSurface()->fillRect(data.bounds, kColorGray);
- }
- if (data.type == kZoomDoc && data.updateScroll) {
- warning("Unimplemented: update scroll");
- }
- }
-}
void Gui::invertWindowColors(WindowReference winID) {
Graphics::ManagedSurface *srf = findWindow(winID)->getSurface();
@@ -1006,7 +1038,7 @@ bool Gui::processCommandEvents(WindowClick click, Common::Event &event) {
if (!_controlData)
return false;
- Common::List<CommandButton>::iterator it = _controlData->begin();
+ Common::Array<CommandButton>::iterator it = _controlData->begin();
for (; it != _controlData->end(); ++it) {
if (it->isInsideBounds(position)) {
it->select();
@@ -1064,8 +1096,32 @@ bool MacVenture::Gui::processSelfEvents(WindowClick click, Common::Event & event
}
bool MacVenture::Gui::processExitsEvents(WindowClick click, Common::Event & event) {
- if (_engine->needsClickToContinue())
- return true;
+ if (event.type == Common::EVENT_LBUTTONUP) {
+ if (_engine->needsClickToContinue()) {
+ return true;
+ }
+
+ Common::Point position(
+ event.mouse.x - _exitsWindow->getDimensions().left,
+ event.mouse.y - _exitsWindow->getDimensions().top);
+
+ CommandButton data;
+ if (!_exitsData)
+ return false;
+
+ Common::Array<CommandButton>::iterator it = _exitsData->begin();
+ for (; it != _exitsData->end(); ++it) {
+ if (it->isInsideBounds(position)) {
+ it->select();
+ data = *it;
+ }
+ else {
+ it->unselect();
+ }
+ }
+
+ _engine->handleObjectSelect(data.getData().refcon, kExitsWindow, event);
+ }
return getWindowData(kExitsWindow).visible;
}
@@ -1118,7 +1174,7 @@ BorderBounds Gui::borderBounds(MVWindowType type) {
case MacVenture::kPlainDBox:
return BorderBounds(6, 6, 6, 6);
case MacVenture::kAltBox:
- //return BorderBounds(8, 9, 11, 10); // For now, I'll stick to the original bmp, it's gorgeous
+ return BorderBounds(8, 9, 11, 10); // For now, I'll stick to the original bmp, it's gorgeous
break;
case MacVenture::kNoGrowDoc:
return BorderBounds(1, 17, 1, 1);
diff --git a/engines/macventure/gui.h b/engines/macventure/gui.h
index 73c4318408..dd08173d3c 100644
--- a/engines/macventure/gui.h
+++ b/engines/macventure/gui.h
@@ -129,7 +129,7 @@ struct ControlData {
uint16 scrollMax;
uint16 scrollMin;
uint16 cdef;
- uint32 refcon;
+ uint32 refcon; // If exits window, then the obj id. Otherwise, the control type
uint8 titleLength;
char* title;
uint16 border;
@@ -159,7 +159,7 @@ public:
void draw();
void drawMenu();
void drawTitle();
- void drawExit(ObjID id);
+
void clearControls();
bool processEvent(Common::Event &event);
void handleMenuAction(MenuAction action);
@@ -195,6 +195,9 @@ public:
void addChild(WindowReference target, ObjID child);
void removeChild(WindowReference target, ObjID child);
+ void unselectExits();
+ void updateExit(ObjID id);
+
// Ugly switches
BorderBounds borderBounds(MVWindowType type);
@@ -207,7 +210,8 @@ private: // Attributes
Graphics::MacWindowManager _wm;
Common::List<WindowData> *_windowData;
- Common::List<CommandButton> *_controlData;
+ Common::Array<CommandButton> *_controlData;
+ Common::Array<CommandButton> *_exitsData;
Graphics::MacWindow *_controlsWindow;
Graphics::MacWindow *_mainGameWindow;
@@ -290,16 +294,18 @@ public:
surface.fillRect(_data.bounds, colorFill);
surface.frameRect(_data.bounds, kColorBlack);
- const Graphics::Font &font = _gui->getCurrentFont();
- Common::String title(_data.title);
- font.drawString(
- &surface,
- title,
- _data.bounds.left,
- _data.bounds.top,
- _data.bounds.right - _data.bounds.left,
- colorText,
- Graphics::kTextAlignCenter);
+ if (_data.titleLength > 0) {
+ const Graphics::Font &font = _gui->getCurrentFont();
+ Common::String title(_data.title);
+ font.drawString(
+ &surface,
+ title,
+ _data.bounds.left,
+ _data.bounds.top,
+ _data.bounds.right - _data.bounds.left,
+ colorText,
+ Graphics::kTextAlignCenter);
+ }
}
bool isInsideBounds(const Common::Point point) const {
diff --git a/engines/macventure/image.cpp b/engines/macventure/image.cpp
index d880e142bb..1aae1727ef 100644
--- a/engines/macventure/image.cpp
+++ b/engines/macventure/image.cpp
@@ -77,7 +77,13 @@ ImageAsset::~ImageAsset() {
void ImageAsset::decodePPIC(ObjID id, Common::Array<byte> &data) {
ObjID realID = id;
uint32 size = _container->getItemByteSize(id);
- if (size == 2 || size == 0) {
+ if (size < 2) {
+ _rowBytes = 0;
+ _bitHeight = 0;
+ _bitHeight = 0;
+ return;
+ }
+ if (size == 2) {
realID = _container->getItem(id)->readUint16BE();
}
Common::BitStream32BEMSB stream(_container->getItem(realID), true);
diff --git a/engines/macventure/macventure.cpp b/engines/macventure/macventure.cpp
index 8624159a95..08b5ec90c1 100644
--- a/engines/macventure/macventure.cpp
+++ b/engines/macventure/macventure.cpp
@@ -174,7 +174,7 @@ void MacVentureEngine::requestUnpause() {
void MacVentureEngine::selectControl(ControlReference id) {
ControlAction action = referenceToAction(id);
- debug(4, "Select control %x", action);
+ debug(2, "Select control %x", action);
_selectedControl = action;
}
@@ -190,7 +190,7 @@ void MacVentureEngine::activateCommand(ControlReference id) {
_activeControl = kNoCommand;
_activeControl = action;
}
- debug(4, "Activating Command %x... Command %x is active", action, _activeControl);
+ debug(2, "Activating Command %x... Command %x is active", action, _activeControl);
refreshReady();
}
@@ -520,6 +520,17 @@ void MacVentureEngine::unselectObject(ObjID objID) {
}
}
+
+void MacVentureEngine::updateExits() {
+ // exitWin.killControls();
+ _gui->unselectExits();
+
+ Common::Array<ObjID> exits = _world->getChildren(_world->getObjAttr(1, kAttrParentObject), true);
+ for (uint i = 0; i < exits.size(); i++)
+ _gui->updateExit(exits[i]);
+
+}
+
int MacVentureEngine::findObjectInArray(ObjID objID, const Common::Array<ObjID> &list) {
// Find the object in the current selection
bool found = false;
@@ -542,7 +553,7 @@ Common::String MacVentureEngine::getPrefixString(uint flag, ObjID obj) {
if (ndx) {
return _decodingNamingArticles->getString(ndx);
} else {
- return Common::String("missigno ");
+ return Common::String("m1551gn0 ");
}
}
@@ -551,7 +562,20 @@ Common::String MacVentureEngine::getNoun(ObjID ndx) {
}
void MacVentureEngine::highlightExit(ObjID objID) {
- warning("highlightExit: unimplemented");
+ //ObjID ctl = _gui->getWinChild(obj);
+ /*if (ctl) {
+ if (findObjectInArray(obj, _selectedObjs) != -1)
+ _gui->selectExit(ctl);
+ else
+ _gui->unselectExit(ctl);
+ }
+ if (obj == _world->getObjAttr(1, kAttrParentObject)) {
+ if (findObjectInArray(obj, _selectedObjs) != -1)
+ _gui->selectExit(obj);
+ else
+ _gui->unselectExit(obj);
+ }*/
+ //updateWindow(findParentWindow(obj));
}
void MacVentureEngine::selectPrimaryObject(ObjID objID) {
@@ -587,7 +611,7 @@ void MacVentureEngine::openObject(ObjID objID) {
if (objID == _world->getObjAttr(1, kAttrParentObject)) {
_gui->updateWindowInfo(kMainGameWindow, objID, _world->getChildren(objID, true));
_gui->updateWindow(kMainGameWindow, _world->getObjAttr(objID, kAttrContainerOpen));
- //_gui->drawExits();
+ updateExits();
_gui->setWindowTitle(kMainGameWindow, _world->getText(objID, objID, objID)); // it ignores source and target in the original
} else { // Open inventory window
Common::Point p(_world->getObjAttr(objID, kAttrPosX), _world->getObjAttr(objID, kAttrPosY));
@@ -649,7 +673,7 @@ void MacVentureEngine::checkObject(QueuedObject old) {
old.hidden != _world->getObjAttr(id, kAttrHiddenExit) ||
old.exitx != _world->getObjAttr(id, kAttrExitX) ||
old.exity != _world->getObjAttr(id, kAttrExitY))
- _gui->drawExit(id);
+ _gui->updateExit(id);
}
WindowReference win = getObjWindow(id);
ObjID cur = id;
@@ -787,12 +811,20 @@ bool MacVentureEngine::isObjExit(ObjID objID) {
return _world->getObjAttr(objID, kAttrIsExit);
}
+bool MacVentureEngine::isHiddenExit(ObjID objID) {
+ return _world->getObjAttr(objID, kAttrHiddenExit);
+}
+
Common::Point MacVentureEngine::getObjExitPosition(ObjID objID) {
uint x = _world->getObjAttr(objID, kAttrExitX);
uint y = _world->getObjAttr(objID, kAttrExitY);
return Common::Point(x, y);
}
+ObjID MacVentureEngine::getParent(ObjID objID) {
+ return _world->getObjAttr(objID, kAttrParentObject);
+}
+
Common::Rect MacVentureEngine::getObjBounds(ObjID objID) {
Common::Point pos = getObjPosition(objID);
uint w = _gui->getObjWidth(objID); // This shouldn't go here
diff --git a/engines/macventure/macventure.h b/engines/macventure/macventure.h
index 28c3bf9ad3..9ecfbc0fd7 100644
--- a/engines/macventure/macventure.h
+++ b/engines/macventure/macventure.h
@@ -205,7 +205,10 @@ public:
bool isObjClickable(ObjID objID);
bool isObjSelected(ObjID objID);
bool isObjExit(ObjID objID);
+ bool isHiddenExit(ObjID objID);
Common::Point getObjExitPosition(ObjID objID);
+ ObjID getParent(ObjID objID);
+
// Encapsulation HACK
Common::Rect getObjBounds(ObjID objID);
@@ -232,7 +235,7 @@ private:
void unselectObject(ObjID objID);
void highlightExit(ObjID objID);
void selectPrimaryObject(ObjID objID);
-
+ void updateExits();
// Object queue methods
void focusObjectWindow(ObjID objID);
diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp
index 8e83f91057..670f39902c 100644
--- a/engines/macventure/world.cpp
+++ b/engines/macventure/world.cpp
@@ -43,17 +43,23 @@ World::~World() {
uint32 World::getObjAttr(ObjID objID, uint32 attrID) {
uint32 res;
uint32 index = _engine->getGlobalSettings().attrIndices[attrID];
+ // HACK, but if I try to initialize it in the else clause, it goes out of scope and segfaults
+ Common::SeekableReadStream *objStream = _objectConstants->getItem(objID);
if (!(index & 0x80)) { // It's not a constant
res = _saveGame->getAttr(objID, index);
} else {
- Common::SeekableReadStream *objStream = _objectConstants->getItem(objID);
index &= 0x7F;
- objStream->skip((index * 2) - 1);
- res = objStream->readUint16BE();
+ if (objStream->size() == 0) return 0;
+ // Look for the right attribute inside the object
+ objStream->skip(index * 2);
+ res = objStream->readByte() << 8;
+ res |= objStream->readByte();
}
res &= _engine->getGlobalSettings().attrMasks[attrID];
res >>= _engine->getGlobalSettings().attrShifts[attrID];
- debug(11, "Attribute %x from object %x is %x", attrID, objID, res);
+ if (res & 0x8000)
+ res = -((res ^ 0xffff) + 1);
+ debug(3, "Attribute %x from object %x is %x", attrID, objID, res);
return res;
}