<commit_before>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the Campcaster project.
    http://campcaster.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    Campcaster 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 2 of the License, or
    (at your option) any later version.

    Campcaster 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 Campcaster; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author: fgerlits $
    Version  : $Revision$
    Location : $URL: svn+ssh://fgerlits@code.campware.org/home/svn/repo/livesupport/trunk/livesupport/src/products/gLiveSupport/src/TransportList.cxx $

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif

#include "LiveSupport/Core/TimeConversion.h"
#include "TransportList.h"

using namespace LiveSupport::Core;
using namespace LiveSupport::StorageClient;
using namespace LiveSupport::Widgets;
using namespace LiveSupport::GLiveSupport;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

namespace {

/*------------------------------------------------------------------------------
 *  The localization key for the 'working' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      workingStatusKey    = "workingStatus";

/*------------------------------------------------------------------------------
 *  The localization key for the 'success' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      successStatusKey    = "successStatus";

/*------------------------------------------------------------------------------
 *  The localization key for the 'fault' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      faultStatusKey      = "faultStatus";

/*------------------------------------------------------------------------------
 *  The name of the user preference for storing the list of transports.
 *----------------------------------------------------------------------------*/
const Glib::ustring      userPreferencesKeyName  = "activeTransports";

/*------------------------------------------------------------------------------
 *  The symbol for an upload.
 *----------------------------------------------------------------------------*/
const Glib::ustring      uploadSymbol  = "⇧";

/*------------------------------------------------------------------------------
 *  The symbol for a download.
 *----------------------------------------------------------------------------*/
const Glib::ustring      downloadSymbol  = "⇩";

}

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Constructor.
 *----------------------------------------------------------------------------*/
TransportList :: TransportList (Ptr<GLiveSupport>::Ref    gLiveSupport,
                                Ptr<ResourceBundle>::Ref  bundle)
                                                                    throw ()
          : LocalizedObject(bundle),
            gLiveSupport(gLiveSupport)
{
    Ptr<WidgetFactory>::Ref     widgetFactory = WidgetFactory::getInstance();

    // create the tree view
    treeModel = Gtk::ListStore::create(modelColumns);
    treeView = Gtk::manage(widgetFactory->createTreeView(treeModel));
    treeView->set_enable_search(false);

    // Add the TreeView's view columns:
    try {
        treeView->appendColumn("",
                               modelColumns.directionColumn, 20);
        treeView->appendColumn(*getResourceUstring("titleColumnLabel"),
                               modelColumns.titleColumn, 300);
        treeView->appendColumn(*getResourceUstring("dateColumnLabel"),
                               modelColumns.dateColumn, 180);
        treeView->appendColumn(*getResourceUstring("statusColumnLabel"),
                               modelColumns.statusDisplayColumn, 50);
    } catch (std::invalid_argument &e) {
        std::cerr << e.what() << std::endl;
        std::exit(1);
    }

    // register the signal handler for treeview entries being clicked
    treeView->signal_button_press_event().connect_notify(sigc::mem_fun(*this,
                                        &TransportList::onEntryClicked));

    // create the right-click entry context menu
    uploadMenu      = Gtk::manage(new Gtk::Menu());
    downloadMenu    = Gtk::manage(new Gtk::Menu());
    Gtk::Menu::MenuList&    uploadMenuList      = uploadMenu->items();
    Gtk::Menu::MenuList&    downloadMenuList    = downloadMenu->items();

    try{
        uploadMenuList.push_back(Gtk::Menu_Helpers::MenuElem(
                                *getResourceUstring("cancelUploadMenuItem"),
                                sigc::mem_fun(*this,
                                        &TransportList::onCancelTransport)));
        downloadMenuList.push_back(Gtk::Menu_Helpers::MenuElem(
                                *getResourceUstring("cancelDownloadMenuItem"),
                                sigc::mem_fun(*this,
                                        &TransportList::onCancelTransport)));
    } catch (std::invalid_argument &e) {
        std::cerr << e.what() << std::endl;
        std::exit(1);
    }

    uploadMenu->accelerate(*this);
    downloadMenu->accelerate(*this);

    // add the tree view to this widget
    Gtk::VBox::pack_start(*treeView);

    userPreferencesKey.reset(new const Glib::ustring(userPreferencesKeyName));
}

/*------------------------------------------------------------------------------
 *  Add a new upload task to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: addUpload(Ptr<Playable>::Ref       playable)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     token = storage->uploadToHub(sessionId,
                                                             playable->getId());

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = uploadSymbol;
    row[modelColumns.titleColumn]       = *playable->getTitle();
    row[modelColumns.dateColumn]        = *TimeConversion::nowString();
    row[modelColumns.statusColumn]      = workingStatusKey;
    row[modelColumns.statusDisplayColumn]
                                        = *getResourceUstring(workingStatusKey);
    row[modelColumns.tokenColumn]       = token;
}

/*------------------------------------------------------------------------------
 *  Add a new download task to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: addDownload(Ptr<Playable>::Ref     playable)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     token = storage->downloadFromHub(
                                                            sessionId,
                                                            playable->getId());

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = downloadSymbol;
    row[modelColumns.titleColumn]       = *playable->getTitle();
    row[modelColumns.dateColumn]        = *TimeConversion::nowString();
    row[modelColumns.statusColumn]      = workingStatusKey;
    row[modelColumns.statusDisplayColumn]
                                        = *getResourceUstring(workingStatusKey);
    row[modelColumns.tokenColumn]       = token;
}

/*------------------------------------------------------------------------------
 *  Add an item with an already existing token to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: add(const Glib::ustring &          title,
                     const Glib::ustring &          date,
                     const Glib::ustring &          token,
                     bool                           isUpload)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     tokenPtr(new Glib::ustring(token));
    Ptr<Glib::ustring>::Ref     errorMsg(new Glib::ustring);
    AsyncState                  state = storage->checkTransport(tokenPtr,
                                                                errorMsg);

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = isUpload ? uploadSymbol
                                                   : downloadSymbol;
    row[modelColumns.titleColumn]       = title;
    row[modelColumns.dateColumn]        = date;
    row[modelColumns.tokenColumn]       = tokenPtr;
    setStatus(row, state, errorMsg);
}

/*------------------------------------------------------------------------------
 *  Remove the currently selected item from the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: removeSelected(void)                   throw (XmlRpcException)
{
    Glib::RefPtr<Gtk::TreeSelection>    selection = treeView->get_selection();
    Gtk::TreeIter                       iter = selection->get_selected();
    if (!iter) {
        return;
    }

    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    storage->cancelTransport(sessionId,
                             iter->get_value(modelColumns.tokenColumn));

    treeModel->erase(iter);
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: updateSelected(void)                   throw (XmlRpcException)
{
    Glib::RefPtr<Gtk::TreeSelection>    selection = treeView->get_selection();
    Gtk::TreeIter                       iter = selection->get_selected();
    if (!iter) {
        return false;
    } else {
        return update(iter);
    }
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: update(void)                           throw (XmlRpcException)
{
    bool    didSomething = false;

    for (Gtk::TreeIter  it  = treeModel->children().begin();
                        it != treeModel->children().end(); ++it) {
        didSomething |= update(it);
    }

    return didSomething;
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: updateSilently(void)                               throw ()
{
    bool    didSomething = false;

    for (Gtk::TreeIter  it  = treeModel->children().begin();
                        it != treeModel->children().end(); ++it) {
        try {
            didSomething |= update(it);
        } catch (XmlRpcException &e) {
        }
    }

    return didSomething;
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: update(Gtk::TreeIter   iter)           throw (XmlRpcException)
{
    if (iter->get_value(modelColumns.statusColumn) != workingStatusKey) {
        return false;
    }

    Ptr<StorageClientInterface>::Ref
                                storage = gLiveSupport->getStorageClient();
    Ptr<Glib::ustring>::Ref     errorMsg(new Glib::ustring);
    AsyncState                  status = storage->checkTransport(
                                    iter->get_value(modelColumns.tokenColumn),
                                    errorMsg);

    return setStatus(iter, status, errorMsg);
}

/*------------------------------------------------------------------------------
 *  Set the status of the row pointed to by an iterator.
 *----------------------------------------------------------------------------*/
bool
TransportList :: setStatus(Gtk::TreeIter                        iter,
                           AsyncState                           status,
                           Ptr<const Glib::ustring>::Ref        errorMsg)
                                                                    throw ()
{
    if (status == AsyncState::pendingState) {
        iter->set_value(modelColumns.statusColumn,
                        workingStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *getResourceUstring(workingStatusKey));
        return false;

    } else if (status == AsyncState::finishedState
                    || status == AsyncState::closedState) {
        iter->set_value(modelColumns.statusColumn,
                        successStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *getResourceUstring(successStatusKey));
        return true;

    } else if (status == AsyncState::failedState) {
        iter->set_value(modelColumns.statusColumn,
                        faultStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *formatMessage(faultStatusKey, *errorMsg));
        return false;

    } else {
        std::cerr << "Impossible status: '" << status
                  << "' in TransportList::setStatus()."
                  << std::endl;
    }

    return false;
}

/*------------------------------------------------------------------------------
 *  Return the contents of the transport list.
 *----------------------------------------------------------------------------*/
Ptr<Glib::ustring>::Ref
TransportList :: getContents(void)                                  throw ()
{
    std::ostringstream              contentsStream;
    Gtk::TreeModel::const_iterator  it;
    Ptr<Glib::ustring>::Ref         token;

    for (it = treeModel->children().begin();
                                it != treeModel->children().end(); ++it) {
        Gtk::TreeRow        row = *it;
        if (row[modelColumns.statusColumn] == workingStatusKey) {
            if (row[modelColumns.directionColumn] == uploadSymbol) {
                contentsStream <<  "up\n";
            } else {
                contentsStream <<  "down\n";
            }
            contentsStream << row[modelColumns.titleColumn]     << '\n';
            contentsStream << row[modelColumns.dateColumn]      << '\n';
            token           = row[modelColumns.tokenColumn];
            contentsStream << *token  << '\n';
        }
    }

    Ptr<Glib::ustring>::Ref         contents(new Glib::ustring(
                                                    contentsStream.str() ));
    return contents;
}

/*------------------------------------------------------------------------------
 *  Restore the contents of the transport list.
 *----------------------------------------------------------------------------*/
void
TransportList :: setContents(Ptr<const Glib::ustring>::Ref     contents)
                                                                    throw ()
{
    std::istringstream      contentsStream(contents->raw());

    treeModel->clear();
    while (!contentsStream.eof()) {
        std::string   direction;
        std::string   title;
        std::string   date;
        std::string   token;

        std::getline(contentsStream, direction);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, title);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, date);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, token);
        if (contentsStream.fail()) {
            break;
        }

        try {
            add(title, date, token, (direction == "up"));

        } catch (XmlRpcException &e) {
        }
    }
}

/*------------------------------------------------------------------------------
 *  Event handler for an entry being clicked in the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: onEntryClicked(GdkEventButton *    event)          throw ()
{
    if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
        Gtk::TreePath           currentPath;
        Gtk::TreeViewColumn *   column;
        int     cell_x,
                cell_y;
        bool foundValidRow = treeView->get_path_at_pos(
                                            int(event->x), int(event->y),
                                            currentPath, column,
                                            cell_x, cell_y);

        if (foundValidRow) {
            Gtk::TreeIter   iter = treeModel->get_iter(currentPath);
            if (iter) {
                Gtk::TreeRow    row = *iter;
                if (row[modelColumns.directionColumn] == uploadSymbol) {
                    uploadMenu->popup(event->button, event->time);
                } else {
                    downloadMenu->popup(event->button, event->time);
                }
            }
        }
    }
}

/*------------------------------------------------------------------------------
 *  Event handler for "cancel" selected from the pop-up menu.
 *----------------------------------------------------------------------------*/
void
TransportList :: onCancelTransport(void)                            throw ()
{
    try {
        removeSelected();

    } catch (XmlRpcException &e) {
        gLiveSupport->displayMessageWindow(formatMessage(
                                                "cannotCancelTransportMsg",
                                                e.what() ));
    }
}

<commit_msg>fixing #1871<commit_after>/*------------------------------------------------------------------------------

    Copyright (c) 2004 Media Development Loan Fund

    This file is part of the Campcaster project.
    http://campcaster.campware.org/
    To report bugs, send an e-mail to bugs@campware.org

    Campcaster 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 2 of the License, or
    (at your option) any later version.

    Campcaster 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 Campcaster; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Author   : $Author: fgerlits $
    Version  : $Revision$
    Location : $URL: svn+ssh://fgerlits@code.campware.org/home/svn/repo/livesupport/trunk/livesupport/src/products/gLiveSupport/src/TransportList.cxx $

------------------------------------------------------------------------------*/

/* ============================================================ include files */

#ifdef HAVE_CONFIG_H
#include "configure.h"
#endif

#include "LiveSupport/Core/TimeConversion.h"
#include "TransportList.h"

using namespace LiveSupport::Core;
using namespace LiveSupport::StorageClient;
using namespace LiveSupport::Widgets;
using namespace LiveSupport::GLiveSupport;

/* ===================================================  local data structures */

/* ================================================  local constants & macros */

namespace {

/*------------------------------------------------------------------------------
 *  The localization key for the 'working' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      workingStatusKey    = "workingStatus";

/*------------------------------------------------------------------------------
 *  The localization key for the 'success' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      successStatusKey    = "successStatus";

/*------------------------------------------------------------------------------
 *  The localization key for the 'fault' status.
 *----------------------------------------------------------------------------*/
const Glib::ustring      faultStatusKey      = "faultStatus";

/*------------------------------------------------------------------------------
 *  The name of the user preference for storing the list of transports.
 *----------------------------------------------------------------------------*/
const Glib::ustring      userPreferencesKeyName  = "activeTransports";

/*------------------------------------------------------------------------------
 *  The symbol for an upload.
 *----------------------------------------------------------------------------*/
const Glib::ustring      uploadSymbol  = "⇧";

/*------------------------------------------------------------------------------
 *  The symbol for a download.
 *----------------------------------------------------------------------------*/
const Glib::ustring      downloadSymbol  = "⇩";

}

/* ===============================================  local function prototypes */

/* =============================================================  module code */

/*------------------------------------------------------------------------------
 *  Constructor.
 *----------------------------------------------------------------------------*/
TransportList :: TransportList (Ptr<GLiveSupport>::Ref    gLiveSupport,
                                Ptr<ResourceBundle>::Ref  bundle)
                                                                    throw ()
          : LocalizedObject(bundle),
            gLiveSupport(gLiveSupport)
{
    Ptr<WidgetFactory>::Ref     widgetFactory = WidgetFactory::getInstance();

    // create the tree view
    treeModel = Gtk::ListStore::create(modelColumns);
    treeView = Gtk::manage(widgetFactory->createTreeView(treeModel));
    treeView->set_enable_search(false);

    // Add the TreeView's view columns:
    try {
        treeView->appendColumn("",
                               modelColumns.directionColumn, 20);
        treeView->appendColumn(*getResourceUstring("titleColumnLabel"),
                               modelColumns.titleColumn, 300);
        treeView->appendColumn(*getResourceUstring("dateColumnLabel"),
                               modelColumns.dateColumn, 180);
        treeView->appendColumn(*getResourceUstring("statusColumnLabel"),
                               modelColumns.statusDisplayColumn, 50);
    } catch (std::invalid_argument &e) {
        std::cerr << e.what() << std::endl;
        std::exit(1);
    }

    // register the signal handler for treeview entries being clicked
    treeView->signal_button_press_event().connect_notify(sigc::mem_fun(*this,
                                        &TransportList::onEntryClicked));

    // create the right-click entry context menu
    uploadMenu      = Gtk::manage(new Gtk::Menu());
    downloadMenu    = Gtk::manage(new Gtk::Menu());
    Gtk::Menu::MenuList&    uploadMenuList      = uploadMenu->items();
    Gtk::Menu::MenuList&    downloadMenuList    = downloadMenu->items();

    try{
        uploadMenuList.push_back(Gtk::Menu_Helpers::MenuElem(
                                *getResourceUstring("cancelUploadMenuItem"),
                                sigc::mem_fun(*this,
                                        &TransportList::onCancelTransport)));
        downloadMenuList.push_back(Gtk::Menu_Helpers::MenuElem(
                                *getResourceUstring("cancelDownloadMenuItem"),
                                sigc::mem_fun(*this,
                                        &TransportList::onCancelTransport)));
    } catch (std::invalid_argument &e) {
        std::cerr << e.what() << std::endl;
        std::exit(1);
    }

    uploadMenu->accelerate(*this);
    downloadMenu->accelerate(*this);

    // add the tree view to this widget
    Gtk::VBox::pack_start(*treeView);

    userPreferencesKey.reset(new const Glib::ustring(userPreferencesKeyName));
}

/*------------------------------------------------------------------------------
 *  Add a new upload task to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: addUpload(Ptr<Playable>::Ref       playable)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     token = storage->uploadToHub(sessionId,
                                                             playable->getId());

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = uploadSymbol;
    row[modelColumns.titleColumn]       = *playable->getTitle();
    row[modelColumns.dateColumn]        = *TimeConversion::nowString();
    row[modelColumns.statusColumn]      = workingStatusKey;
    row[modelColumns.statusDisplayColumn]
                                        = *getResourceUstring(workingStatusKey);
    row[modelColumns.tokenColumn]       = token;
}

/*------------------------------------------------------------------------------
 *  Add a new download task to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: addDownload(Ptr<Playable>::Ref     playable)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     token = storage->downloadFromHub(
                                                            sessionId,
                                                            playable->getId());

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = downloadSymbol;
    row[modelColumns.titleColumn]       = *playable->getTitle();
    row[modelColumns.dateColumn]        = *TimeConversion::nowString();
    row[modelColumns.statusColumn]      = workingStatusKey;
    row[modelColumns.statusDisplayColumn]
                                        = *getResourceUstring(workingStatusKey);
    row[modelColumns.tokenColumn]       = token;
}

/*------------------------------------------------------------------------------
 *  Add an item with an already existing token to the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: add(const Glib::ustring &          title,
                     const Glib::ustring &          date,
                     const Glib::ustring &          token,
                     bool                           isUpload)
                                                        throw (XmlRpcException)
{
    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    Ptr<Glib::ustring>::Ref     tokenPtr(new Glib::ustring(token));
    Ptr<Glib::ustring>::Ref     errorMsg(new Glib::ustring);
    AsyncState                  state = storage->checkTransport(tokenPtr,
                                                                errorMsg);

    Gtk::TreeRow    row = *treeModel->append();
    row[modelColumns.directionColumn]   = isUpload ? uploadSymbol
                                                   : downloadSymbol;
    row[modelColumns.titleColumn]       = title;
    row[modelColumns.dateColumn]        = date;
    row[modelColumns.tokenColumn]       = tokenPtr;
    setStatus(row, state, errorMsg);
}

/*------------------------------------------------------------------------------
 *  Remove the currently selected item from the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: removeSelected(void)                   throw (XmlRpcException)
{
    Glib::RefPtr<Gtk::TreeSelection>    selection = treeView->get_selection();
    Gtk::TreeIter                       iter = selection->get_selected();
    if (!iter) {
        return;
    }

    Ptr<StorageClientInterface>::Ref
                                storage     = gLiveSupport->getStorageClient();
    Ptr<SessionId>::Ref         sessionId   = gLiveSupport->getSessionId();

    storage->cancelTransport(sessionId,
                             iter->get_value(modelColumns.tokenColumn));

    treeModel->erase(iter);
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: updateSelected(void)                   throw (XmlRpcException)
{
    Glib::RefPtr<Gtk::TreeSelection>    selection = treeView->get_selection();
    Gtk::TreeIter                       iter = selection->get_selected();
    if (!iter) {
        return false;
    } else {
        return update(iter);
    }
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: update(void)                           throw (XmlRpcException)
{
    bool    didSomething = false;

    for (Gtk::TreeIter  it  = treeModel->children().begin();
                        it != treeModel->children().end(); ++it) {
        didSomething |= update(it);
    }

    return didSomething;
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: updateSilently(void)                               throw ()
{
    bool    didSomething = false;

    for (Gtk::TreeIter  it  = treeModel->children().begin();
                        it != treeModel->children().end(); ++it) {
        try {
            didSomething |= update(it);
        } catch (XmlRpcException &e) {
        }
    }

    return didSomething;
}

/*------------------------------------------------------------------------------
 *  Query the storage server about the status of the pending transport.
 *----------------------------------------------------------------------------*/
bool
TransportList :: update(Gtk::TreeIter   iter)           throw (XmlRpcException)
{
    if (iter->get_value(modelColumns.statusColumn) != workingStatusKey) {
        return false;
    }

    Ptr<StorageClientInterface>::Ref
                                storage = gLiveSupport->getStorageClient();
    Ptr<Glib::ustring>::Ref     errorMsg(new Glib::ustring);
    AsyncState                  status = storage->checkTransport(
                                    iter->get_value(modelColumns.tokenColumn),
                                    errorMsg);

    return setStatus(iter, status, errorMsg);
}

/*------------------------------------------------------------------------------
 *  Set the status of the row pointed to by an iterator.
 *----------------------------------------------------------------------------*/
bool
TransportList :: setStatus(Gtk::TreeIter                        iter,
                           AsyncState                           status,
                           Ptr<const Glib::ustring>::Ref        errorMsg)
                                                                    throw ()
{
    if (status == AsyncState::initState
                    || status == AsyncState::pendingState) {
        iter->set_value(modelColumns.statusColumn,
                        workingStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *getResourceUstring(workingStatusKey));
        return false;

    } else if (status == AsyncState::finishedState
                    || status == AsyncState::closedState) {
        iter->set_value(modelColumns.statusColumn,
                        successStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *getResourceUstring(successStatusKey));
        return true;

    } else if (status == AsyncState::failedState) {
        iter->set_value(modelColumns.statusColumn,
                        faultStatusKey);
        iter->set_value(modelColumns.statusDisplayColumn,
                        *formatMessage(faultStatusKey, *errorMsg));
        return false;

    } else {
        std::cerr << "Impossible status: '" << status
                  << "' in TransportList::setStatus()."
                  << std::endl;
    }

    return false;
}

/*------------------------------------------------------------------------------
 *  Return the contents of the transport list.
 *----------------------------------------------------------------------------*/
Ptr<Glib::ustring>::Ref
TransportList :: getContents(void)                                  throw ()
{
    std::ostringstream              contentsStream;
    Gtk::TreeModel::const_iterator  it;
    Ptr<Glib::ustring>::Ref         token;

    for (it = treeModel->children().begin();
                                it != treeModel->children().end(); ++it) {
        Gtk::TreeRow        row = *it;
        if (row[modelColumns.statusColumn] == workingStatusKey) {
            if (row[modelColumns.directionColumn] == uploadSymbol) {
                contentsStream <<  "up\n";
            } else {
                contentsStream <<  "down\n";
            }
            contentsStream << row[modelColumns.titleColumn]     << '\n';
            contentsStream << row[modelColumns.dateColumn]      << '\n';
            token           = row[modelColumns.tokenColumn];
            contentsStream << *token  << '\n';
        }
    }

    Ptr<Glib::ustring>::Ref         contents(new Glib::ustring(
                                                    contentsStream.str() ));
    return contents;
}

/*------------------------------------------------------------------------------
 *  Restore the contents of the transport list.
 *----------------------------------------------------------------------------*/
void
TransportList :: setContents(Ptr<const Glib::ustring>::Ref     contents)
                                                                    throw ()
{
    std::istringstream      contentsStream(contents->raw());

    treeModel->clear();
    while (!contentsStream.eof()) {
        std::string   direction;
        std::string   title;
        std::string   date;
        std::string   token;

        std::getline(contentsStream, direction);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, title);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, date);
        if (contentsStream.fail()) {
            break;
        }
        std::getline(contentsStream, token);
        if (contentsStream.fail()) {
            break;
        }

        try {
            add(title, date, token, (direction == "up"));

        } catch (XmlRpcException &e) {
        }
    }
}

/*------------------------------------------------------------------------------
 *  Event handler for an entry being clicked in the list.
 *----------------------------------------------------------------------------*/
void
TransportList :: onEntryClicked(GdkEventButton *    event)          throw ()
{
    if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
        Gtk::TreePath           currentPath;
        Gtk::TreeViewColumn *   column;
        int     cell_x,
                cell_y;
        bool foundValidRow = treeView->get_path_at_pos(
                                            int(event->x), int(event->y),
                                            currentPath, column,
                                            cell_x, cell_y);

        if (foundValidRow) {
            Gtk::TreeIter   iter = treeModel->get_iter(currentPath);
            if (iter) {
                Gtk::TreeRow    row = *iter;
                if (row[modelColumns.directionColumn] == uploadSymbol) {
                    uploadMenu->popup(event->button, event->time);
                } else {
                    downloadMenu->popup(event->button, event->time);
                }
            }
        }
    }
}

/*------------------------------------------------------------------------------
 *  Event handler for "cancel" selected from the pop-up menu.
 *----------------------------------------------------------------------------*/
void
TransportList :: onCancelTransport(void)                            throw ()
{
    try {
        removeSelected();

    } catch (XmlRpcException &e) {
        gLiveSupport->displayMessageWindow(formatMessage(
                                                "cannotCancelTransportMsg",
                                                e.what() ));
    }
}

<|endoftext|>


<commit_before><commit_msg>tdf#89381 Revert "vcl: SalGraphics::mirror() - always use GetGraphicsWidth()"<commit_after><|endoftext|>


<commit_before><commit_msg>Signed-off-by: xsmart <xsmart@veyesys.com><commit_after><|endoftext|>


<commit_before>#ifndef VIENNAGRID_ALGORITHM_VOLUME_HPP
#define VIENNAGRID_ALGORITHM_VOLUME_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

#include "viennagrid/forwards.h"
#include "viennagrid/topology/all.hpp"
#include "viennagrid/algorithm/norm.hpp"
#include "viennagrid/algorithm/spanned_volume.hpp"

/** @file volume.hpp
    @brief Computes the volume of different cell types as well as domains and segments
*/

namespace viennagrid
{
  namespace detail
  {

    /** @brief Computes the volume of topologically zero-dimensional elements (vertices). Degenerate case, returns 1 */
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::point_tag)
    {
      return typename ElementType::config_type::numeric_type(1);
    }

    /** @brief Computes the volume of topologically one-dimensional elements (lines, 1-simplex).*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::simplex_tag<1>)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();

      return norm(p0 - p1);
    }

    /** @brief Computes the volume of topologically one-dimensional elements (lines, 1-hypercube).*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::hypercube_tag<1>)
    {
      return volume_impl(cell, viennagrid::simplex_tag<1>());
    }

    //topologically two-dimensional elements
    /** @brief Computes the two-dimensional volume of a triangle.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::triangle_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();

      return spanned_volume(p0, p1, p2);
    }

    /** @brief Computes the two-dimensional volume of a quadrilateral.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::quadrilateral_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();

      return spanned_volume(p0, p1, p3) + spanned_volume(p1, p2, p3); //sum up the two triangular parts
    }

    //topologically three-dimensional elements
    /** @brief Computes the three-dimensional volume of a tetrahedron.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::tetrahedron_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();

      return spanned_volume(p0, p1, p2, p3);
    }

    /** @brief Computes the three-dimensional volume of a hexahedron.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::hexahedron_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();
      PointType const & p4 = ncells<0>(cell)[4].point();
      PointType const & p5 = ncells<0>(cell)[5].point();
      PointType const & p6 = ncells<0>(cell)[6].point();
      PointType const & p7 = ncells<0>(cell)[7].point();

      //decompose hexahedron into six tetrahedra
      return spanned_volume(p0, p1, p3, p4)
             + spanned_volume(p4, p1, p3, p7)
             + spanned_volume(p4, p1, p7, p5)
             + spanned_volume(p1, p2, p3, p7)
             + spanned_volume(p1, p2, p7, p5)
             + spanned_volume(p5, p2, p7, p6);
    }

    //
    /** @brief Dispatched function for computing the volume of a domain or segment.*/
    template <typename ContainerType>
    typename ContainerType::config_type::numeric_type
    volume_domainsegment(ContainerType const & d)
    {
      typedef ContainerType                                      DomainType;
      typedef typename ContainerType::config_type::cell_tag      CellTag;

      typedef typename viennagrid::result_of::const_ncell_range<DomainType, CellTag::dim>::type  CellContainer;
      typedef typename viennagrid::result_of::iterator<CellContainer>::type         CellIterator;

      typename ContainerType::config_type::numeric_type new_volume = 0;
      CellContainer new_cells = viennagrid::ncells<CellTag::dim>(d);
      for (CellIterator new_cit = new_cells.begin();
                        new_cit != new_cells.end();
                      ++new_cit)
      {
        new_volume += volume(*new_cit);
      }
      return new_volume;
    }
  } //namespace detail

  //
  // The public interface functions
  //
  /** @brief Returns the n-dimensional volume of a n-cell */
  template <typename ElementType>
  typename ElementType::config_type::numeric_type
  volume(ElementType const & cell)
  {
    return detail::volume_impl(cell, typename ElementType::tag());
  }

  //special case: domain
  /** @brief Returns the N-dimensional volume of a domain, where the cell type has topological dimension N. */
  template <typename ConfigType>
  typename ConfigType::numeric_type
  volume(domain_t<ConfigType> const & d)
  {
    return detail::volume_domainsegment(d);
  }

  //special case: segment
  /** @brief Returns the N-dimensional volume of a segment, where the cell type has topological dimension N. */
  template <typename ConfigType>
  typename ConfigType::numeric_type
  volume(segment_t<ConfigType> const & d)
  {
    return detail::volume_domainsegment(d);
  }

} //namespace viennagrid
#endif
<commit_msg>added volume algorithm for polygon<commit_after>#ifndef VIENNAGRID_ALGORITHM_VOLUME_HPP
#define VIENNAGRID_ALGORITHM_VOLUME_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>

#include "viennagrid/forwards.h"
#include "viennagrid/topology/all.hpp"
#include "viennagrid/algorithm/norm.hpp"
#include "viennagrid/algorithm/spanned_volume.hpp"

/** @file volume.hpp
    @brief Computes the volume of different cell types as well as domains and segments
*/

namespace viennagrid
{
  namespace detail
  {

    /** @brief Computes the volume of topologically zero-dimensional elements (vertices). Degenerate case, returns 1 */
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::point_tag)
    {
      return typename ElementType::config_type::numeric_type(1);
    }

    /** @brief Computes the volume of topologically one-dimensional elements (lines, 1-simplex).*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::simplex_tag<1>)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();

      return norm(p0 - p1);
    }

    /** @brief Computes the volume of topologically one-dimensional elements (lines, 1-hypercube).*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::hypercube_tag<1>)
    {
      return volume_impl(cell, viennagrid::simplex_tag<1>());
    }

    //topologically two-dimensional elements
    /** @brief Computes the two-dimensional volume of a triangle.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::triangle_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();

      return spanned_volume(p0, p1, p2);
    }

    /** @brief Computes the two-dimensional volume of a quadrilateral.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::quadrilateral_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();

      return spanned_volume(p0, p1, p3) + spanned_volume(p1, p2, p3); //sum up the two triangular parts
    }

    /** @brief Computes the two-dimensional volume of a polygon.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::polygon_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename ElementType::config_type::numeric_type NumericType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;
      typedef typename viennagrid::result_of::iterator<VertexOnCellContainer>::type       VertexOnCellIterator;

      VertexOnCellContainer range = viennagrid::ncells<0>( cell );
      if (range.size() < 3) return 0;
      VertexOnCellIterator it1 = range.begin();
      VertexOnCellIterator it2 = it1; ++it2;

      PointType origin = it1->point();

      NumericType volume = 0;

      for (; it2 != range.end(); ++it1, ++it2)
          volume += signed_spanned_volume(origin, it1->point(), it2->point());

      it1 = range.end(); --it1;
      volume += signed_spanned_volume( origin, it1->point(), range.begin()->point());

      return std::abs(volume);
    }

    //topologically three-dimensional elements
    /** @brief Computes the three-dimensional volume of a tetrahedron.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::tetrahedron_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();

      return spanned_volume(p0, p1, p2, p3);
    }

    /** @brief Computes the three-dimensional volume of a hexahedron.*/
    template <typename ElementType>
    typename ElementType::config_type::numeric_type
    volume_impl(ElementType const & cell, viennagrid::hexahedron_tag)
    {
      typedef typename ElementType::config_type      ConfigType;
      typedef typename viennagrid::result_of::point<ConfigType>::type                 PointType;
      typedef typename viennagrid::result_of::const_ncell_range<ElementType, 0>::type       VertexOnCellContainer;

      PointType const & p0 = ncells<0>(cell)[0].point();
      PointType const & p1 = ncells<0>(cell)[1].point();
      PointType const & p2 = ncells<0>(cell)[2].point();
      PointType const & p3 = ncells<0>(cell)[3].point();
      PointType const & p4 = ncells<0>(cell)[4].point();
      PointType const & p5 = ncells<0>(cell)[5].point();
      PointType const & p6 = ncells<0>(cell)[6].point();
      PointType const & p7 = ncells<0>(cell)[7].point();

      //decompose hexahedron into six tetrahedra
      return spanned_volume(p0, p1, p3, p4)
             + spanned_volume(p4, p1, p3, p7)
             + spanned_volume(p4, p1, p7, p5)
             + spanned_volume(p1, p2, p3, p7)
             + spanned_volume(p1, p2, p7, p5)
             + spanned_volume(p5, p2, p7, p6);
    }

    //
    /** @brief Dispatched function for computing the volume of a domain or segment.*/
    template <typename ContainerType>
    typename ContainerType::config_type::numeric_type
    volume_domainsegment(ContainerType const & d)
    {
      typedef ContainerType                                      DomainType;
      typedef typename ContainerType::config_type::cell_tag      CellTag;

      typedef typename viennagrid::result_of::const_ncell_range<DomainType, CellTag::dim>::type  CellContainer;
      typedef typename viennagrid::result_of::iterator<CellContainer>::type         CellIterator;

      typename ContainerType::config_type::numeric_type new_volume = 0;
      CellContainer new_cells = viennagrid::ncells<CellTag::dim>(d);
      for (CellIterator new_cit = new_cells.begin();
                        new_cit != new_cells.end();
                      ++new_cit)
      {
        new_volume += volume(*new_cit);
      }
      return new_volume;
    }
  } //namespace detail

  //
  // The public interface functions
  //
  /** @brief Returns the n-dimensional volume of a n-cell */
  template <typename ElementType>
  typename ElementType::config_type::numeric_type
  volume(ElementType const & cell)
  {
    return detail::volume_impl(cell, typename ElementType::tag());
  }

  //special case: domain
  /** @brief Returns the N-dimensional volume of a domain, where the cell type has topological dimension N. */
  template <typename ConfigType>
  typename ConfigType::numeric_type
  volume(domain_t<ConfigType> const & d)
  {
    return detail::volume_domainsegment(d);
  }

  //special case: segment
  /** @brief Returns the N-dimensional volume of a segment, where the cell type has topological dimension N. */
  template <typename ConfigType>
  typename ConfigType::numeric_type
  volume(segment_t<ConfigType> const & d)
  {
    return detail::volume_domainsegment(d);
  }

} //namespace viennagrid
#endif
<|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
//#define NO_IMPORT_ARRAY

#include <vigra/numpy_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/nonlineardiffusion.hxx>
#include <vigra/symmetry.hxx>
#include <vigra/tv_filter.hxx>
#include <vigra/shockfilter.hxx>

namespace python = boost::python;

namespace vigra
{

/**
python::tuple
pythonGetAnisotropy2D(
    const NumpyArray<2, double> & image,
    const double alpha_par,
    const double beta_par,
    const double sigma_par,
    const double rho_par,
    const double K_par,
    NumpyArray<2, double> phi,
    NumpyArray<2, double> alpha,
    NumpyArray<2, double> beta
)
{
    res.reshapeIfEmpty(image.taggedShape(),
        "getAnisotropy2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;

    }

    return ;
}
**/

template <class InValue, class OutValue>
NumpyAnyArray
pythonShockFilter(NumpyArray<3, Multiband<InValue> > image,
                  float sigma,
                  float rho,
                  float upwind_factor_h,
                  unsigned int iterations,
                  NumpyArray<3, Multiband<OutValue> > res=NumpyArray<3, Multiband<float> >())
{
    res.reshapeIfEmpty(image.taggedShape(),
        "nonlinearDiffusion2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        for(int k=0; k<image.shape(2); ++k)
        {
            MultiArrayView<2, OutValue, StridedArrayTag> bres   = res.bindOuter(k);
            MultiArrayView<2, InValue,  StridedArrayTag> bimage = image.bindOuter(k);

            shockFilter(bimage,bres, sigma,
                rho, upwind_factor_h, iterations);
        }
    }
    return res;
}

template <class InValue, class OutValue>
NumpyAnyArray
pythonNonlinearDiffusion2D(NumpyArray<3, Multiband<InValue> > image,
                           double edgeThreshold, double scale,
                           NumpyArray<3, Multiband<OutValue> > res=NumpyArray<3, Multiband<float> >())
{
    res.reshapeIfEmpty(image.taggedShape(),
        "nonlinearDiffusion2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        for(int k=0; k<image.shape(2); ++k)
        {
            MultiArrayView<2, OutValue, StridedArrayTag> bres = res.bindOuter(k);
            nonlinearDiffusion(srcImageRange(image.bindOuter(k)),
                               destImage(bres),
                               DiffusivityFunctor< double >(edgeThreshold), scale);
        }
    }
    return res;
}

template <class InValue, class OutValue>
NumpyAnyArray
pythonTotalVariationFilter2D(NumpyArray<2, Singleband<InValue> > image,
                           double alpha, int steps, double eps = 0,
                           NumpyArray<2, Singleband<OutValue> > res = python::object())
{
    std::string description("totalVariationFilter, alpha, steps, eps=");
    description += asString(eps);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "totalVariationFilter(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        totalVariationFilter(image, res, alpha, steps, eps);
    }
    return res;
}

template <class InValue, class InValue2, class OutValue>
NumpyAnyArray
pythonTotalVariationFilter2D(NumpyArray<2, Singleband<InValue> > image,
                             NumpyArray<2, Singleband<InValue2> > weight,
                           double alpha, int steps, double eps = 0,
                           NumpyArray<2, Singleband<OutValue> > res = python::object())
{
    std::string description("totalVariationFilter, weight, alpha, steps, eps=");
    description += asString(eps);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "totalVariationFilter(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        totalVariationFilter(image, weight, res, alpha, steps, eps);
    }
    return res;
}

template < class SrcPixelType >
NumpyAnyArray
pythonRadialSymmetryTransform2D(NumpyArray<2, Singleband<SrcPixelType> > image,
                                double scale = 1.0,
                                NumpyArray<2, Singleband<SrcPixelType> > res = python::object())
{
    std::string description("radial symmetry transform, scale=");
    description += asString(scale);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "radialSymmetryTransform2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        radialSymmetryTransform(srcImageRange(image), destImage(res), scale);
    }
    return res;
}

void defineFilters2D()
{
    using namespace python;

    docstring_options doc_options(true, true, false);

    def("nonlinearDiffusion",
        registerConverters(&pythonNonlinearDiffusion2D<float, float>),
        (arg("image"), arg("edgeThreshold"), arg("scale"), arg("out")=python::object()),
        "Perform edge-preserving smoothing at the given scale."
        "\n\n"
        "For details see nonlinearDiffusion_ in the vigra C++ documentation.\n");

    def("shockFilter",
        registerConverters(&pythonShockFilter<float, float>),
        (
            arg("image"),
            arg("sigma"),
            arg("rho"),
            arg("updwindFactorH") ,
            arg("iterations"),
            arg("out")=python::object()
        ),
        "Perform edge-preserving smoothing at the given scale."
        "\n\n"
        "For details see shockFilter_ in the vigra C++ documentation.\n");

    def("totalVariationFilter",
        registerConverters(&pythonTotalVariationFilter2D<double,double>),
        (arg("image"), arg("alpha"), arg("steps"), arg("eps"), arg("out")=python::object()),
        "Perform total variation filter on 2D single band images."
        "\n\n"
        "For details see totalVariationFilter in the vigra C++ documentation.\n");

    def("totalVariationFilter",
        registerConverters(&pythonTotalVariationFilter2D<double,double,double>),
        (arg("image"), arg("weight"), arg("alpha"), arg("steps"), arg("eps"), arg("out")=python::object()),
        "Perform weighted total variation filter on 2D single band images."
        "\n\n"
        "For details see totalVariationFilter in the vigra C++ documentation.\n");

    def("radialSymmetryTransform2D",
        registerConverters(&pythonRadialSymmetryTransform2D<float>),
        (arg("image"), arg("scale"),arg("out")=python::object()),
        "Find centers of radial symmetry in an 2D image.\n\n"
        "This algorithm implements the Fast Radial Symmetry Transform according to "
        "[G. Loy, A. Zelinsky: \"A Fast Radial Symmetry Transform for Detecting Points of Interest\", "
        "in: A. Heyden et al. (Eds.): Proc. of 7th European Conf. on Computer Vision, Part 1, pp. 358-368, Springer LNCS 2350, 2002]\n\n"
        "For details see radialSymmetryTransform_ in the vigra C++ documentation.\n");
}

void defineKernels();
void defineConvolutionFunctions();
void defineMorphology();
void defineTensor();
void defineNonLocalMean();

} // namespace vigra

using namespace vigra;
using namespace boost::python;

BOOST_PYTHON_MODULE_INIT(filters)
{
    import_vigranumpy();
    defineFilters2D();
    defineKernels();
    defineConvolutionFunctions();
    defineMorphology();
    defineTensor();
    defineNonLocalMean();
}
<commit_msg>formated code<commit_after>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfilters_PyArray_API
//#define NO_IMPORT_ARRAY

#include <vigra/numpy_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/nonlineardiffusion.hxx>
#include <vigra/symmetry.hxx>
#include <vigra/tv_filter.hxx>
#include <vigra/shockfilter.hxx>

namespace python = boost::python;

namespace vigra
{

template <class InValue, class OutValue>
NumpyAnyArray
pythonShockFilter(NumpyArray<3, Multiband<InValue> > image,
                  float sigma,
                  float rho,
                  float upwind_factor_h,
                  unsigned int iterations,
                  NumpyArray<3, Multiband<OutValue> > res=NumpyArray<3, Multiband<float> >())
{
    res.reshapeIfEmpty(image.taggedShape(),
        "nonlinearDiffusion2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        for(int k=0; k<image.shape(2); ++k)
        {
            MultiArrayView<2, OutValue, StridedArrayTag> bres   = res.bindOuter(k);
            MultiArrayView<2, InValue,  StridedArrayTag> bimage = image.bindOuter(k);

            shockFilter(bimage,bres, sigma,
                rho, upwind_factor_h, iterations);
        }
    }
    return res;
}

template <class InValue, class OutValue>
NumpyAnyArray
pythonNonlinearDiffusion2D(NumpyArray<3, Multiband<InValue> > image,
                           double edgeThreshold, double scale,
                           NumpyArray<3, Multiband<OutValue> > res=NumpyArray<3, Multiband<float> >())
{
    res.reshapeIfEmpty(image.taggedShape(),
        "nonlinearDiffusion2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        for(int k=0; k<image.shape(2); ++k)
        {
            MultiArrayView<2, OutValue, StridedArrayTag> bres = res.bindOuter(k);
            nonlinearDiffusion(srcImageRange(image.bindOuter(k)),
                               destImage(bres),
                               DiffusivityFunctor< double >(edgeThreshold), scale);
        }
    }
    return res;
}

template <class InValue, class OutValue>
NumpyAnyArray
pythonTotalVariationFilter2D(NumpyArray<2, Singleband<InValue> > image,
                           double alpha, int steps, double eps = 0,
                           NumpyArray<2, Singleband<OutValue> > res = python::object())
{
    std::string description("totalVariationFilter, alpha, steps, eps=");
    description += asString(eps);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "totalVariationFilter(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        totalVariationFilter(image, res, alpha, steps, eps);
    }
    return res;
}

template <class InValue, class InValue2, class OutValue>
NumpyAnyArray
pythonTotalVariationFilter2D(NumpyArray<2, Singleband<InValue> > image,
                             NumpyArray<2, Singleband<InValue2> > weight,
                           double alpha, int steps, double eps = 0,
                           NumpyArray<2, Singleband<OutValue> > res = python::object())
{
    std::string description("totalVariationFilter, weight, alpha, steps, eps=");
    description += asString(eps);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "totalVariationFilter(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        totalVariationFilter(image, weight, res, alpha, steps, eps);
    }
    return res;
}

template < class SrcPixelType >
NumpyAnyArray
pythonRadialSymmetryTransform2D(NumpyArray<2, Singleband<SrcPixelType> > image,
                                double scale = 1.0,
                                NumpyArray<2, Singleband<SrcPixelType> > res = python::object())
{
    std::string description("radial symmetry transform, scale=");
    description += asString(scale);

    res.reshapeIfEmpty(image.taggedShape().setChannelDescription(description),
            "radialSymmetryTransform2D(): Output array has wrong shape.");

    {
        PyAllowThreads _pythread;
        radialSymmetryTransform(srcImageRange(image), destImage(res), scale);
    }
    return res;
}

void defineFilters2D()
{
    using namespace python;

    docstring_options doc_options(true, true, false);

    def("nonlinearDiffusion",
        registerConverters(&pythonNonlinearDiffusion2D<float, float>),
        (arg("image"), arg("edgeThreshold"), arg("scale"), arg("out")=python::object()),
        "Perform edge-preserving smoothing at the given scale."
        "\n\n"
        "For details see nonlinearDiffusion_ in the vigra C++ documentation.\n");

    def("shockFilter",
        registerConverters(&pythonShockFilter<float, float>),
        (
            arg("image"),
            arg("sigma"),
            arg("rho"),
            arg("updwindFactorH") ,
            arg("iterations"),
            arg("out")=python::object()
        ),
        "Perform edge-preserving smoothing at the given scale."
        "\n\n"
        "For details see shockFilter_ in the vigra C++ documentation.\n");

    def("totalVariationFilter",
        registerConverters(&pythonTotalVariationFilter2D<double,double>),
        (arg("image"), arg("alpha"), arg("steps"), arg("eps"), arg("out")=python::object()),
        "Perform total variation filter on 2D single band images."
        "\n\n"
        "For details see totalVariationFilter in the vigra C++ documentation.\n");

    def("totalVariationFilter",
        registerConverters(&pythonTotalVariationFilter2D<double,double,double>),
        (arg("image"), arg("weight"), arg("alpha"), arg("steps"), arg("eps"), arg("out")=python::object()),
        "Perform weighted total variation filter on 2D single band images."
        "\n\n"
        "For details see totalVariationFilter in the vigra C++ documentation.\n");

    def("radialSymmetryTransform2D",
        registerConverters(&pythonRadialSymmetryTransform2D<float>),
        (arg("image"), arg("scale"),arg("out")=python::object()),
        "Find centers of radial symmetry in an 2D image.\n\n"
        "This algorithm implements the Fast Radial Symmetry Transform according to "
        "[G. Loy, A. Zelinsky: \"A Fast Radial Symmetry Transform for Detecting Points of Interest\", "
        "in: A. Heyden et al. (Eds.): Proc. of 7th European Conf. on Computer Vision, Part 1, pp. 358-368, Springer LNCS 2350, 2002]\n\n"
        "For details see radialSymmetryTransform_ in the vigra C++ documentation.\n");
}

void defineKernels();
void defineConvolutionFunctions();
void defineMorphology();
void defineTensor();
void defineNonLocalMean();

} // namespace vigra

using namespace vigra;
using namespace boost::python;

BOOST_PYTHON_MODULE_INIT(filters)
{
    import_vigranumpy();
    defineFilters2D();
    defineKernels();
    defineConvolutionFunctions();
    defineMorphology();
    defineTensor();
    defineNonLocalMean();
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

#include <osmesa.h>
#include <conio.h>        // For kbhit, getch, textmode (console access)
#include <dpmi.h>         // For __dpmi_int (mouse access)
#include <go32.h>         // For _dos_ds (VRAM access)
#include <sys/movedata.h> // For movedata (VRAM access)
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <GL/glu.h>     // GLU = OpenGL utility library

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <cstdio>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <memory>
#include <iostream>
#include <map>
#include <array>
#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <pc.h>
#include "NativeBitmap.h"

#include "SoundClip.h"
#include "SoundUtils.h"
#include "SoundListener.h"
#include "SoundEmitter.h"

#include "IFileLoaderDelegate.h"

#include "Vec2i.h"
#include "NativeBitmap.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"

#include "NoudarDungeonSnapshot.h"

#include "GameNativeAPI.h"
#include "WindowOperations.h"
#include "Common.h"
#include "LoadPNG.h"

bool inGraphics = true;

namespace PC {
	const unsigned W = 320, H = 200;

	unsigned ImageBuffer[W * H];
	int selector;

	void Init() {
		__dpmi_regs r;

		r.x.ax = 0x13;
		__dpmi_int(0x10, &r);

		outp(0x03c8, 0);

		for ( int r = 0; r < 4; ++r ) {
			for ( int g = 0; g < 4; ++g ) {
				for ( int b = 0; b < 4; ++b ) {
					outp(0x03c9, (r * 85));
					outp(0x03c9, (g * 85));
					outp(0x03c9, (b * 85));
				}
			}
		}
	}

	void renderPalette() {
		_farsetsel(_dos_ds);
		int offset = 0;
		int fullSize = 320 * 200;

		for (int r = 0; r < 255; ++r) {
			for (int x = 0; x < 50; ++x) {
				int shade = 0;

				int origin = r << 16;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + r, shade);
			}
		}

		for (int g = 0; g < 255; ++g) {
			for (int x = 50; x < 100; ++x) {
				int shade = 0;

				int origin = g << 8;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + g, shade);
			}
		}

		for (int b = 0; b < 255; ++b) {
			for (int x = 100; x < 150; ++x) {
				int shade = 0;

				int origin = b;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + b, shade);
			}
		}

		for (int b = 0; b < 255; ++b) {
			for (int x = 150; x < 200; ++x) {
				_farnspokeb(0xA0000 + (320 * x) + b, b);
			}
		}

		std::fill(std::end(ImageBuffer) - (320 * 200), std::end(ImageBuffer), 0x0);

	}

	void Render() {
		_farsetsel(_dos_ds);
		auto pixelData = (*gunState)->getPixelData();
		int offset = 0;
		int fullSize = 320 * 200;

		for (int y = 100; y < 200; ++y) {
			for (int x = 80; x < 240; ++x) {

				offset = (320 * y) + x;
				auto origin = ImageBuffer[offset];
				offset = (320 * (200 - (2 * (y - 100)))) + (((x - 80) * 320) / 160);

				if (pixelData[offset] & 0xFF000000) {
					origin = pixelData[offset];
				}

				int shade = 0;
				shade += (((((origin & 0x0000FF)      )  ) / 85 ) );
				shade += (((((origin & 0x00FF00) >> 8 )  ) / 85 ) ) << 2;
				shade += (((((origin & 0xFF0000) >> 16)  ) / 85 ) ) << 4;

				_farnspokeb( 0xA0000 + 160 + ((200 - (2 * ((y - 100)))) * 320) + ((2 * x)) + 1, shade);
				_farnspokeb( 0xA0000 + 160 + ((199 - (2 * ((y - 100)))) * 320) + ((2 * x)), shade);
				_farnspokeb( 0xA0000 + 160 + ((200 - (2 * ((y - 100)))) * 320) + ((2 * x)), shade);
				_farnspokeb( 0xA0000 + 160 + ((199 - (2 * ((y - 100)))) * 320) + ((2 * x)) + 1, shade);
			}
		}

		std::fill(std::end(ImageBuffer) - (320 * 100), std::end(ImageBuffer), 0x0);
	}

	void Close() // End graphics
	{
		textmode(C80); // Set textmode again.
	}
}

void setGraphics() {
  inGraphics = true;
  PC::Init();
}

void setTextMode() {
  inGraphics = false;

  __dpmi_regs r;

  r.x.ax = 3;
  __dpmi_int(0x10, &r);
}

const int winWidth = 320, winHeight = 200;
bool done = false;
bool isActive = false;

std::vector <std::shared_ptr<odb::NativeBitmap>> loadTextures() {
    std::vector<std::shared_ptr<odb::NativeBitmap>> toReturn;

    toReturn.push_back( loadPNG( "res/grass.ppm") );
    toReturn.push_back( loadPNG( "res/stonef1.ppm") );
    toReturn.push_back( loadPNG( "res/bricks.ppm") );
    toReturn.push_back( loadPNG( "res/arch.ppm") );
    toReturn.push_back( loadPNG( "res/bars.ppm") );
    toReturn.push_back( loadPNG( "res/begin.ppm") );
    toReturn.push_back( loadPNG( "res/exit.ppm") );
    toReturn.push_back( loadPNG( "res/bricks2.ppm") );
    toReturn.push_back( loadPNG( "res/bricks3.ppm") );
    toReturn.push_back( loadPNG( "res/foe0.ppm") );
    toReturn.push_back( loadPNG( "res/foe1.ppm") );
    toReturn.push_back( loadPNG( "res/foe2.ppm") );
    toReturn.push_back( loadPNG( "res/foe3.ppm") );
    toReturn.push_back( loadPNG( "res/foe4.ppm") );
    toReturn.push_back( loadPNG( "res/foe5.ppm") );
    toReturn.push_back( loadPNG( "res/crusad0.ppm") );
    toReturn.push_back( loadPNG( "res/crusad1.ppm") );
    toReturn.push_back( loadPNG( "res/crusad2.ppm") );
    toReturn.push_back( loadPNG( "res/shadow.ppm") );
    toReturn.push_back( loadPNG( "res/ceilin.ppm") );
    toReturn.push_back( loadPNG( "res/ceigdr.ppm") );
    toReturn.push_back( loadPNG( "res/ceigbgn.ppm") );
    toReturn.push_back( loadPNG( "res/ceilend.ppm") );
    toReturn.push_back( loadPNG( "res/splat0.ppm") );
    toReturn.push_back( loadPNG( "res/splat1.ppm") );
    toReturn.push_back( loadPNG( "res/splat2.ppm") );
    toReturn.push_back( loadPNG( "res/ceilbar.ppm") );
    toReturn.push_back( loadPNG( "res/clouds.ppm"));
    toReturn.push_back( loadPNG( "res/stngrsf.ppm"));
    toReturn.push_back( loadPNG( "res/grsstnf.ppm"));
    toReturn.push_back( loadPNG( "res/stngrsn.ppm"));
    toReturn.push_back( loadPNG( "res/grsstnn.ppm"));
    toReturn.push_back( loadPNG( "res/cross.ppm"));

    return toReturn;
}

void initWindow() {

  auto textures = loadTextures();
  OSMesaContext om  = OSMesaCreateContext(OSMESA_RGBA, NULL);
  OSMesaMakeCurrent(om, PC::ImageBuffer, GL_UNSIGNED_BYTE, PC::W, PC::H);

  PC::Init();

  auto gVertexShader = "";
  auto gFragmentShader = "";

  setupGraphics(winWidth, winHeight, gVertexShader, gFragmentShader, textures);

  auto soundListener = std::make_shared<odb::SoundListener>();

  std::vector<std::shared_ptr<odb::SoundEmitter>> sounds;

  std::string filenames[] {
    "res/grasssteps.wav",
      "res/stepsstones.wav",
      "res/bgnoise.wav",
      "res/monsterdamage.wav",
      "res/monsterdead.wav",
      "res/playerdamage.wav",
      "res/playerdead.wav",
      "res/swing.wav"
      };

  for ( auto filename : filenames ) {
    FILE *file = fopen( filename.c_str(), "r");
    auto soundClip = odb::makeSoundClipFrom( file );

    sounds.push_back( std::make_shared<odb::SoundEmitter>(soundClip) );
  }

  setSoundEmitters( sounds, soundListener );
}

void tick() {
  //if I want at least 10fps, I need my rendering and updates to take no more than 100ms, combined
  if ( inGraphics ) {
    gameLoopTick( 250 );
    renderFrame( 250 );
    PC::Render();
  }
}

void setMainLoop() {
  while ( !done ) {
    while(kbhit())
      switch(getch()) {
      case 27: done = true; break;
      case '1':
	setGraphics();
	break;
      case '2':
	setTextMode();
	break;
      case 'w':
	moveUp();
	break;
      case 's':
	moveDown();
	break;
      case 'd':
	moveRight();
	break;
      case 'a':
	moveLeft();
	break;
      case 'h':
	interact();
	break;
      case 'e':
	rotateCameraRight();
	break;
      case 'q':
	rotateCameraLeft();
	break;
      }
    tick();
  }
}

void destroyWindow() {
   shutdown();
}
<commit_msg>Paint the gun of the 3D image, depending on the state of the shooting sequence<commit_after>#include <stdio.h>
#include <stdlib.h>

#include <osmesa.h>
#include <conio.h>        // For kbhit, getch, textmode (console access)
#include <dpmi.h>         // For __dpmi_int (mouse access)
#include <go32.h>         // For _dos_ds (VRAM access)
#include <sys/movedata.h> // For movedata (VRAM access)
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <GL/glu.h>     // GLU = OpenGL utility library

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <cstdio>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <memory>
#include <iostream>
#include <map>
#include <array>
#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <pc.h>
#include "NativeBitmap.h"

#include "SoundClip.h"
#include "SoundUtils.h"
#include "SoundListener.h"
#include "SoundEmitter.h"

#include "IFileLoaderDelegate.h"

#include "Vec2i.h"
#include "NativeBitmap.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"

#include "NoudarDungeonSnapshot.h"

#include "GameNativeAPI.h"
#include "WindowOperations.h"
#include "Common.h"
#include "LoadPNG.h"

bool inGraphics = true;

std::vector<std::shared_ptr<odb::NativeBitmap>> gunStates;
std::vector<std::shared_ptr<odb::NativeBitmap>>::iterator gunState;
namespace PC {
	const unsigned W = 320, H = 200;

	unsigned ImageBuffer[W * H];
	int selector;

	void Init() {
		__dpmi_regs r;

		r.x.ax = 0x13;
		__dpmi_int(0x10, &r);

		outp(0x03c8, 0);

		for ( int r = 0; r < 4; ++r ) {
			for ( int g = 0; g < 4; ++g ) {
				for ( int b = 0; b < 4; ++b ) {
					outp(0x03c9, (r * 85));
					outp(0x03c9, (g * 85));
					outp(0x03c9, (b * 85));
				}
			}
		}
	}

	void renderPalette() {
		_farsetsel(_dos_ds);
		int offset = 0;
		int fullSize = 320 * 200;

		for (int r = 0; r < 255; ++r) {
			for (int x = 0; x < 50; ++x) {
				int shade = 0;

				int origin = r << 16;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + r, shade);
			}
		}

		for (int g = 0; g < 255; ++g) {
			for (int x = 50; x < 100; ++x) {
				int shade = 0;

				int origin = g << 8;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + g, shade);
			}
		}

		for (int b = 0; b < 255; ++b) {
			for (int x = 100; x < 150; ++x) {
				int shade = 0;

				int origin = b;
				shade += (((((origin & 0x0000FF))) / 85));
				shade += (((((origin & 0x00FF00) >> 8)) / 85)) << 2;
				shade += (((((origin & 0xFF0000) >> 16)) / 85)) << 4;

				_farnspokeb(0xA0000 + (320 * x) + b, shade);
			}
		}

		for (int b = 0; b < 255; ++b) {
			for (int x = 150; x < 200; ++x) {
				_farnspokeb(0xA0000 + (320 * x) + b, b);
			}
		}

		std::fill(std::end(ImageBuffer) - (320 * 200), std::end(ImageBuffer), 0x0);

	}

	void Render() {
		_farsetsel(_dos_ds);
		auto pixelData = (*gunState)->getPixelData();
		int offset = 0;
		int fullSize = 320 * 200;

		for (int y = 100; y < 200; ++y) {
			for (int x = 80; x < 240; ++x) {

				offset = (320 * y) + x;
				auto origin = ImageBuffer[offset];
				offset = (320 * (200 - (2 * (y - 100)))) + (((x - 80) * 320) / 160);

				if (pixelData[offset] & 0xFF000000) {
					origin = pixelData[offset];
				}

				int shade = 0;
				shade += (((((origin & 0x0000FF)      )  ) / 85 ) );
				shade += (((((origin & 0x00FF00) >> 8 )  ) / 85 ) ) << 2;
				shade += (((((origin & 0xFF0000) >> 16)  ) / 85 ) ) << 4;

				_farnspokeb( 0xA0000 + 160 + ((200 - (2 * ((y - 100)))) * 320) + ((2 * x)) + 1, shade);
				_farnspokeb( 0xA0000 + 160 + ((199 - (2 * ((y - 100)))) * 320) + ((2 * x)), shade);
				_farnspokeb( 0xA0000 + 160 + ((200 - (2 * ((y - 100)))) * 320) + ((2 * x)), shade);
				_farnspokeb( 0xA0000 + 160 + ((199 - (2 * ((y - 100)))) * 320) + ((2 * x)) + 1, shade);
			}
		}

		std::fill(std::end(ImageBuffer) - (320 * 100), std::end(ImageBuffer), 0x0);
	}

	void Close() // End graphics
	{
		textmode(C80); // Set textmode again.
	}
}

void setGraphics() {
  inGraphics = true;
  PC::Init();
}

void setTextMode() {
  inGraphics = false;

  __dpmi_regs r;

  r.x.ax = 3;
  __dpmi_int(0x10, &r);
}

const int winWidth = 320, winHeight = 200;
bool done = false;
bool isActive = false;

std::vector <std::shared_ptr<odb::NativeBitmap>> loadTextures() {
    std::vector<std::shared_ptr<odb::NativeBitmap>> toReturn;

    toReturn.push_back( loadPNG( "res/grass.ppm") );
    toReturn.push_back( loadPNG( "res/stonef1.ppm") );
    toReturn.push_back( loadPNG( "res/bricks.ppm") );
    toReturn.push_back( loadPNG( "res/arch.ppm") );
    toReturn.push_back( loadPNG( "res/bars.ppm") );
    toReturn.push_back( loadPNG( "res/begin.ppm") );
    toReturn.push_back( loadPNG( "res/exit.ppm") );
    toReturn.push_back( loadPNG( "res/bricks2.ppm") );
    toReturn.push_back( loadPNG( "res/bricks3.ppm") );
    toReturn.push_back( loadPNG( "res/foe0.ppm") );
    toReturn.push_back( loadPNG( "res/foe1.ppm") );
    toReturn.push_back( loadPNG( "res/foe2.ppm") );
    toReturn.push_back( loadPNG( "res/foe3.ppm") );
    toReturn.push_back( loadPNG( "res/foe4.ppm") );
    toReturn.push_back( loadPNG( "res/foe5.ppm") );
    toReturn.push_back( loadPNG( "res/crusad0.ppm") );
    toReturn.push_back( loadPNG( "res/crusad1.ppm") );
    toReturn.push_back( loadPNG( "res/crusad2.ppm") );
    toReturn.push_back( loadPNG( "res/shadow.ppm") );
    toReturn.push_back( loadPNG( "res/ceilin.ppm") );
    toReturn.push_back( loadPNG( "res/ceigdr.ppm") );
    toReturn.push_back( loadPNG( "res/ceigbgn.ppm") );
    toReturn.push_back( loadPNG( "res/ceilend.ppm") );
    toReturn.push_back( loadPNG( "res/splat0.ppm") );
    toReturn.push_back( loadPNG( "res/splat1.ppm") );
    toReturn.push_back( loadPNG( "res/splat2.ppm") );
    toReturn.push_back( loadPNG( "res/ceilbar.ppm") );
    toReturn.push_back( loadPNG( "res/clouds.ppm"));
    toReturn.push_back( loadPNG( "res/stngrsf.ppm"));
    toReturn.push_back( loadPNG( "res/grsstnf.ppm"));
    toReturn.push_back( loadPNG( "res/stngrsn.ppm"));
    toReturn.push_back( loadPNG( "res/grsstnn.ppm"));
    toReturn.push_back( loadPNG( "res/cross.ppm"));

    return toReturn;
}

void initWindow() {

  auto textures = loadTextures();
  gunStates.push_back( loadPNG( "res/shotgun0.ppm", 320, 200) );
  gunStates.push_back( loadPNG( "res/shotgun1.ppm", 320, 200) );
  gunState = std::begin( gunStates );

  OSMesaContext om  = OSMesaCreateContext(OSMESA_RGBA, NULL);
  OSMesaMakeCurrent(om, PC::ImageBuffer, GL_UNSIGNED_BYTE, PC::W, PC::H);

  PC::Init();

  auto gVertexShader = "";
  auto gFragmentShader = "";

  setupGraphics(winWidth, winHeight, gVertexShader, gFragmentShader, textures);

  auto soundListener = std::make_shared<odb::SoundListener>();

  std::vector<std::shared_ptr<odb::SoundEmitter>> sounds;

  std::string filenames[] {
    "res/grasssteps.wav",
      "res/stepsstones.wav",
      "res/bgnoise.wav",
      "res/monsterdamage.wav",
      "res/monsterdead.wav",
      "res/playerdamage.wav",
      "res/playerdead.wav",
      "res/swing.wav"
      };

  for ( auto filename : filenames ) {
    FILE *file = fopen( filename.c_str(), "r");
    auto soundClip = odb::makeSoundClipFrom( file );

    sounds.push_back( std::make_shared<odb::SoundEmitter>(soundClip) );
  }

  setSoundEmitters( sounds, soundListener );
}

void tick() {
  //if I want at least 10fps, I need my rendering and updates to take no more than 100ms, combined
  if ( inGraphics ) {
    gameLoopTick( 250 );
    renderFrame( 250 );
    PC::Render();

    if ( gunState != std::begin( gunStates ) ) {
      gunState = std::prev( gunState );
    }

  }
}

void setMainLoop() {
  while ( !done ) {
    while(kbhit())
      switch(getch()) {
      case 27: done = true; break;
      case '1':
	setGraphics();
	break;
      case '2':
	setTextMode();
	break;
      case 'w':
	moveUp();
	break;
      case 's':
	moveDown();
	break;
      case 'd':
	moveRight();
	break;
      case 'a':
	moveLeft();
	break;
      case 'h':
	interact();
	gunState = std::prev(std::end(gunStates));
	break;
      case 'e':
	rotateCameraRight();
	break;
      case 'q':
	rotateCameraLeft();
	break;
      }
    tick();
  }
}

void destroyWindow() {
   shutdown();
}
<|endoftext|>