<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: regband.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 18:04:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SV_REGBAND_HXX
#define _SV_REGBAND_HXX

#ifndef _SV_SV_H
#include <vcl/sv.h>
#endif
#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif

/* =======================================================================

class ImplRegionBand

This class handles one y-band of the region. In this band may contain one
or more seprarations in x-direction. The y-Band do not contain any
separation after creation.

The separations are modified with basic clipping functions like Union and
Intersection - the Class will process the clipping for the actual band.

The actual separations may be checked by functions like IsInside or
IsOver.

======================================================================= */

// ------------------------
// - ImplRegionBand-Types -
// ------------------------

// element for the list with x-separations
struct ImplRegionBandSep
{
    ImplRegionBandSep*          mpNextSep;
    long                        mnXLeft;
    long                        mnXRight;
    BOOL                        mbRemoved;
};

enum LineType { LINE_ASCENDING, LINE_DESCENDING, LINE_HORIZONTAL };

// element for the list with x-separations
struct ImplRegionBandPoint
{
    ImplRegionBandPoint*        mpNextBandPoint;
    long                        mnX;
    long                        mnLineId;
    BOOL                        mbEndPoint;
    LineType                    meLineType;
};

// ------------------
// - ImplRegionBand -
// ------------------

class ImplRegionBand
{
public:
    ImplRegionBand*             mpNextBand;         // pointer to the next element of the list
    ImplRegionBand*             mpPrevBand;         // pointer to the previous element of the list (only used temporaery)
    ImplRegionBandSep*          mpFirstSep;         // root of the list with x-separations
    ImplRegionBandPoint*        mpFirstBandPoint;   // root of the list with lines
    long                        mnYTop;             // actual boundary of the band
    long                        mnYBottom;
    BOOL                        mbTouched;

                                // create y-band with boundaries
                                ImplRegionBand( long nYTop, long nYBottom );
                                // copy y-band with with all data
                                ImplRegionBand( const ImplRegionBand & theSourceBand );
                                ~ImplRegionBand();

    long                        GetXLeftBoundary() const;
    long                        GetXRightBoundary() const;

                                // combine overlapping bands
    BOOL                        OptimizeBand();

                                // generate separations from lines and process
                                // union with existing separations
    void                        ProcessPoints();
                                // insert point in the list for later processing
    BOOL                        InsertPoint( long nX, long nLineID,
                                             BOOL bEndPoint, LineType eLineType );

    void                        Union( long nXLeft, long nXRight );
    void                        Intersect( long nXLeft, long nXRight );
    void                        Exclude( long nXLeft, long nXRight );
    void                        XOr( long nXLeft, long nXRight );

    void                        MoveX( long nHorzMove );
    void                        ScaleX( double fHorzScale );

    BOOL                        IsInside( long nX );
    BOOL                        IsInside( long nLeft, long nRight );
    BOOL                        IsOver( long nLeft, long nRight );

    BOOL                        IsEmpty() const { return ((!mpFirstSep) && (!mpFirstBandPoint)); }

    BOOL                        operator==( const ImplRegionBand& rRegionBand ) const;
};

#endif  // _SV_REGBAND_HXX
<commit_msg>INTEGRATION: CWS changefileheader (1.2.320); FILE MERGED 2008/04/01 16:05:21 thb 1.2.320.3: #i85898# Stripping all external header guards 2008/04/01 13:01:13 thb 1.2.320.2: #i85898# Stripping all external header guards 2008/03/28 15:44:16 rt 1.2.320.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: regband.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SV_REGBAND_HXX
#define _SV_REGBAND_HXX

#include <vcl/sv.h>
#include <tools/poly.hxx>

/* =======================================================================

class ImplRegionBand

This class handles one y-band of the region. In this band may contain one
or more seprarations in x-direction. The y-Band do not contain any
separation after creation.

The separations are modified with basic clipping functions like Union and
Intersection - the Class will process the clipping for the actual band.

The actual separations may be checked by functions like IsInside or
IsOver.

======================================================================= */

// ------------------------
// - ImplRegionBand-Types -
// ------------------------

// element for the list with x-separations
struct ImplRegionBandSep
{
    ImplRegionBandSep*          mpNextSep;
    long                        mnXLeft;
    long                        mnXRight;
    BOOL                        mbRemoved;
};

enum LineType { LINE_ASCENDING, LINE_DESCENDING, LINE_HORIZONTAL };

// element for the list with x-separations
struct ImplRegionBandPoint
{
    ImplRegionBandPoint*        mpNextBandPoint;
    long                        mnX;
    long                        mnLineId;
    BOOL                        mbEndPoint;
    LineType                    meLineType;
};

// ------------------
// - ImplRegionBand -
// ------------------

class ImplRegionBand
{
public:
    ImplRegionBand*             mpNextBand;         // pointer to the next element of the list
    ImplRegionBand*             mpPrevBand;         // pointer to the previous element of the list (only used temporaery)
    ImplRegionBandSep*          mpFirstSep;         // root of the list with x-separations
    ImplRegionBandPoint*        mpFirstBandPoint;   // root of the list with lines
    long                        mnYTop;             // actual boundary of the band
    long                        mnYBottom;
    BOOL                        mbTouched;

                                // create y-band with boundaries
                                ImplRegionBand( long nYTop, long nYBottom );
                                // copy y-band with with all data
                                ImplRegionBand( const ImplRegionBand & theSourceBand );
                                ~ImplRegionBand();

    long                        GetXLeftBoundary() const;
    long                        GetXRightBoundary() const;

                                // combine overlapping bands
    BOOL                        OptimizeBand();

                                // generate separations from lines and process
                                // union with existing separations
    void                        ProcessPoints();
                                // insert point in the list for later processing
    BOOL                        InsertPoint( long nX, long nLineID,
                                             BOOL bEndPoint, LineType eLineType );

    void                        Union( long nXLeft, long nXRight );
    void                        Intersect( long nXLeft, long nXRight );
    void                        Exclude( long nXLeft, long nXRight );
    void                        XOr( long nXLeft, long nXRight );

    void                        MoveX( long nHorzMove );
    void                        ScaleX( double fHorzScale );

    BOOL                        IsInside( long nX );
    BOOL                        IsInside( long nLeft, long nRight );
    BOOL                        IsOver( long nLeft, long nRight );

    BOOL                        IsEmpty() const { return ((!mpFirstSep) && (!mpFirstBandPoint)); }

    BOOL                        operator==( const ImplRegionBand& rRegionBand ) const;
};

#endif  // _SV_REGBAND_HXX
<|endoftext|>


<commit_before><commit_msg>vcldemo: render more small scaled page-border alikes<commit_after><|endoftext|>


<commit_before>#include <iostream>
using namespace std;

double mile;
double kilometer;

int main()
{
	cout<<"Bitte geben sie die Distanz in Meilen ein:"<<endl;
	cin>>mile;
	cout<<"Vielen Dank! Ihre Eingabe wird verarbeitet..."<<endl;
	kilometer = mile*1.60934;
	cout<<mile<<" Meilen sind umgerechnet "<<kilometer<<" Kilometer."<<endl;
	return 0;
}
<commit_msg>Update mileToKilometer.cpp<commit_after>#include <iostream>
using namespace std;

double mile;
double kilometer;

double mileToKilometer(double)
{
	kilometer = mile*1.60934;
	return mile;
}

int main()
{
	cout<<"Bitte geben sie die Distanz in Meilen ein:"<<endl;
	cin>>mile;
	mileToKilometer(mile);
	cout<<mile<<" Meilen sind umgerechnet "<<kilometer<<" Kilometer."<<endl;

}
<|endoftext|>


<commit_before>#pragma once

#include <cstdlib>
#include "anyode/anyode_parallel.hpp"
#include "cvodes_anyode.hpp"

namespace cvodes_anyode_parallel {

    using cvodes_cxx::LMM;
    using cvodes_cxx::IterType;
    using cvodes_anyode::simple_adaptive;
    using cvodes_anyode::simple_predefined;

    using sa_t = std::pair<std::vector<realtype>, std::vector<realtype> >;

    template <class OdeSys>
    std::vector<std::pair<sa_t, std::vector<int>>>
    multi_adaptive(std::vector<OdeSys *> odesys, // vectorized
                   const std::vector<realtype> atol,
                   const realtype rtol,
                   const LMM lmm,
                   const realtype * const y0,  // vectorized
                   const realtype * t0,  // vectorized
                   const realtype * tend,  // vectorized
                   const long int mxsteps,
                   const realtype * dx0,  // vectorized
                   const realtype * dx_min,  // vectorized
                   const realtype * dx_max,  // vectorized
                   const bool with_jacobian=false,
                   IterType iter_type=IterType::Undecided,
                   int linear_solver=0,
                   const int maxl=0,
                   const realtype eps_lin=0.0,
                   const unsigned nderiv=0,
                   bool return_on_root=false,
                   int autorestart=0, // must be autonomous!
                   bool return_on_error=false
                   ){
        const int ny = odesys[0]->get_ny();
        const int nsys = odesys.size();
        auto results = std::vector<std::pair<sa_t, std::vector<int>>>(nsys);
        anyode_parallel::ThreadException te;
        char * num_threads_var = std::getenv("ANYODE_NUM_THREADS");
        int nt = (num_threads_var) ? std::atoi(num_threads_var) : 1;
        if (nt < 0)
            nt = 1;
        #pragma omp parallel for num_threads(nt) // OMP_NUM_THREADS should be 1 for openblas LU (small matrices)
        for (int idx=0; idx<nsys; ++idx){
            std::pair<sa_t, std::vector<int>> local_result;
            te.run([&]{
                local_result.first = simple_adaptive<OdeSys>(
                    odesys[idx], atol, rtol, lmm, y0 + idx*ny, t0[idx], tend[idx],
                    local_result.second, mxsteps, dx0[idx], dx_min[idx], dx_max[idx], with_jacobian,
                    iter_type, linear_solver, maxl, eps_lin, nderiv, return_on_root,
                    autorestart, return_on_error);
            });
            results[idx] = local_result;
        }
        te.rethrow();

        return results;
    }

    template <class OdeSys>
    std::vector<std::pair<std::vector<int>, std::vector<double>>>
    multi_predefined(std::vector<OdeSys *> odesys,  // vectorized
                     const std::vector<realtype> atol,
                     const realtype rtol,
                     const LMM lmm,
                     const realtype * const y0, // vectorized
                     const std::size_t nout,
                     const realtype * const tout, // vectorized
                     realtype * const yout,  // vectorized
                     const long int mxsteps,
                     const realtype * dx0,  // vectorized
                     const realtype * dx_min,  // vectorized
                     const realtype * dx_max,  // vectorized
                     const bool with_jacobian=false,
                     IterType iter_type=IterType::Undecided,
                     int linear_solver=0,
                     const int maxl=0,
                     const realtype eps_lin=0.0,
                     const unsigned nderiv=0,
                     int autorestart=0 // must be autonomous!
                     ){
        const int ny = odesys[0]->get_ny();
        const int nsys = odesys.size();

        auto roots = std::vector<std::pair<std::vector<int>, std::vector<double>>>(nsys);

        anyode_parallel::ThreadException te;
        #pragma omp parallel for
        for (int idx=0; idx<nsys; ++idx){
            te.run([&]{
               simple_predefined<OdeSys>(odesys[idx], atol, rtol, lmm, y0 + idx*ny,
                                         nout, tout + idx*nout, yout + idx*ny*nout*(nderiv+1),
                                         roots[idx].first, roots[idx].second,
                                         mxsteps, dx0[idx], dx_min[idx], dx_max[idx], with_jacobian,
                                         iter_type, linear_solver, maxl, eps_lin, nderiv,
                                         autorestart);
            });
        }
        te.rethrow();

        return roots;
    }

}
<commit_msg>Add return_on_error to cvodes_anyode_parallel<commit_after>#pragma once

#include <cstdlib>
#include "anyode/anyode_parallel.hpp"
#include "cvodes_anyode.hpp"

namespace cvodes_anyode_parallel {

    using cvodes_cxx::LMM;
    using cvodes_cxx::IterType;
    using cvodes_anyode::simple_adaptive;
    using cvodes_anyode::simple_predefined;

    using sa_t = std::pair<std::vector<realtype>, std::vector<realtype> >;

    template <class OdeSys>
    std::vector<std::pair<sa_t, std::vector<int>>>
    multi_adaptive(std::vector<OdeSys *> odesys, // vectorized
                   const std::vector<realtype> atol,
                   const realtype rtol,
                   const LMM lmm,
                   const realtype * const y0,  // vectorized
                   const realtype * t0,  // vectorized
                   const realtype * tend,  // vectorized
                   const long int mxsteps,
                   const realtype * dx0,  // vectorized
                   const realtype * dx_min,  // vectorized
                   const realtype * dx_max,  // vectorized
                   const bool with_jacobian=false,
                   IterType iter_type=IterType::Undecided,
                   int linear_solver=0,
                   const int maxl=0,
                   const realtype eps_lin=0.0,
                   const unsigned nderiv=0,
                   bool return_on_root=false,
                   int autorestart=0, // must be autonomous!
                   bool return_on_error=false
                   ){
        const int ny = odesys[0]->get_ny();
        const int nsys = odesys.size();
        auto results = std::vector<std::pair<sa_t, std::vector<int>>>(nsys);
        anyode_parallel::ThreadException te;
        char * num_threads_var = std::getenv("ANYODE_NUM_THREADS");
        int nt = (num_threads_var) ? std::atoi(num_threads_var) : 1;
        if (nt < 0)
            nt = 1;
        #pragma omp parallel for num_threads(nt) // OMP_NUM_THREADS should be 1 for openblas LU (small matrices)
        for (int idx=0; idx<nsys; ++idx){
            std::pair<sa_t, std::vector<int>> local_result;
            te.run([&]{
                local_result.first = simple_adaptive<OdeSys>(
                    odesys[idx], atol, rtol, lmm, y0 + idx*ny, t0[idx], tend[idx],
                    local_result.second, mxsteps, dx0[idx], dx_min[idx], dx_max[idx], with_jacobian,
                    iter_type, linear_solver, maxl, eps_lin, nderiv, return_on_root,
                    autorestart, return_on_error);
            });
            results[idx] = local_result;
        }
        te.rethrow();

        return results;
    }

    template <class OdeSys>
    std::vector<std::pair<std::vector<int>, std::vector<double>>>
    multi_predefined(std::vector<OdeSys *> odesys,  // vectorized
                     const std::vector<realtype> atol,
                     const realtype rtol,
                     const LMM lmm,
                     const realtype * const y0, // vectorized
                     const std::size_t nout,
                     const realtype * const tout, // vectorized
                     realtype * const yout,  // vectorized
                     const long int mxsteps,
                     const realtype * dx0,  // vectorized
                     const realtype * dx_min,  // vectorized
                     const realtype * dx_max,  // vectorized
                     const bool with_jacobian=false,
                     IterType iter_type=IterType::Undecided,
                     int linear_solver=0,
                     const int maxl=0,
                     const realtype eps_lin=0.0,
                     const unsigned nderiv=0,
                     int autorestart=0, // must be autonomous!
                     bool return_on_error=false
                     ){
        const int ny = odesys[0]->get_ny();
        const int nsys = odesys.size();

        auto roots = std::vector<std::pair<std::vector<int>, std::vector<double>>>(nsys);

        anyode_parallel::ThreadException te;
        #pragma omp parallel for
        for (int idx=0; idx<nsys; ++idx){
            te.run([&]{
               simple_predefined<OdeSys>(odesys[idx], atol, rtol, lmm, y0 + idx*ny,
                                         nout, tout + idx*nout, yout + idx*ny*nout*(nderiv+1),
                                         roots[idx].first, roots[idx].second,
                                         mxsteps, dx0[idx], dx_min[idx], dx_max[idx], with_jacobian,
                                         iter_type, linear_solver, maxl, eps_lin, nderiv,
                                         autorestart, return_on_error);
            });
        }
        te.rethrow();

        return roots;
    }

}
<|endoftext|>


<commit_before>#include "lelantus_verifier.h"
#include "../amount.h"
#include "chainparams.h"
#include "util.h"

namespace lelantus {

LelantusVerifier::LelantusVerifier(const Params* p, unsigned int v) : params(p), version(v) {
}

bool LelantusVerifier::verify(
        const std::map<uint32_t, std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<uint32_t>& groupIds,
        const Scalar& Vin,
        uint64_t Vout,
        uint64_t fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        const SchnorrProof& qkSchnorrProof) {
    Scalar x;
    bool fSkipVerification = 0;
    return verify(anonymity_sets, anonymity_set_hashes, serialNumbers, ecdsaPubkeys, groupIds, Vin, Vout, fee, Cout, proof, qkSchnorrProof, x, fSkipVerification);
}

bool LelantusVerifier::verify(
        const std::map<uint32_t, std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<uint32_t>& groupIds,
        const Scalar& Vin,
        uint64_t Vout,
        uint64_t fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        const SchnorrProof& qkSchnorrProof,
        Scalar& x,
        bool fSkipVerification) {
    //check the overflow of Vout and fee
    if (!(Vout <= uint64_t(::Params().GetConsensus().nMaxValueLelantusSpendPerTransaction) && fee < (1000 * CENT))) { // 1000 * CENT is the value of max fee defined at validation.h
        LogPrintf("Lelantus verification failed due to transparent values check failed.");
        return false;
    }

    // number of serials should be equal to number of sigma proofs, we need one proof for each serial
    if (serialNumbers.size() != proof.sigma_proofs.size()) {
        LogPrintf("Lelantus verification failed due to sizes of serials  and sigma proofs are not equal.");
        return false;
    }

    // max possible number of output coins is 8,
    if (Cout.size() > (params->get_bulletproofs_max_m() / 2)) {
        LogPrintf("Number of output coins are more than allowed.");
        return false;
    }

    std::vector<std::vector<PublicCoin>> vAnonymity_sets;
    std::vector<std::vector<Scalar>> vSin;
    vAnonymity_sets.reserve(anonymity_sets.size());
    vSin.resize(anonymity_sets.size());

    size_t i = 0;
    auto itr = vSin.begin();
    for (const auto& set : anonymity_sets) {
        vAnonymity_sets.emplace_back(set.second);

        while (i < groupIds.size() && groupIds[i] == set.first) {
            itr->push_back(serialNumbers[i++]);
        }
        itr++;
    }

    Scalar zV, zR;
    unique_ptr<ChallengeGenerator> challengeGenerator;
    try {
        // we are passing challengeGenerator ptr here, as after LELANTUS_TX_VERSION_4_5 we need  it back, with filled data, to use in schnorr proof,
        if (!(verify_sigma(vAnonymity_sets, anonymity_set_hashes, vSin, serialNumbers, ecdsaPubkeys, Cout, proof.sigma_proofs, qkSchnorrProof, x, challengeGenerator, zV, zR, fSkipVerification) &&
             verify_rangeproof(Cout, proof.bulletproofs) &&
             verify_schnorrproof(x, zV, zR, Vin, Vout, fee, Cout, proof, challengeGenerator)))
            return false;
    } catch (std::invalid_argument&) {
        return false;
    }

    return true;
}

bool LelantusVerifier::verify_sigma(
        const std::vector<std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<std::vector<Scalar>>& Sin,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<PublicCoin>& Cout,
        const std::vector<SigmaExtendedProof> &sigma_proofs,
        const SchnorrProof& qkSchnorrProof,
        Scalar& x,
        unique_ptr<ChallengeGenerator>& challengeGenerator,
        Scalar& zV,
        Scalar& zR,
        bool fSkipVerification) {
    std::vector<GroupElement> PubcoinsOut;
    PubcoinsOut.reserve(Cout.size());
    for (auto coin : Cout)
        PubcoinsOut.emplace_back(coin.getValue());

    LelantusPrimitives::generate_Lelantus_challenge(
            sigma_proofs,
            anonymity_set_hashes,
            serialNumbers,
            ecdsaPubkeys,
            PubcoinsOut,
            version,
            challengeGenerator,
            x);

    SigmaExtendedVerifier sigmaVerifier(params->get_g(), params->get_sigma_h(), params->get_sigma_n(),
                                                          params->get_sigma_m());

    if (Sin.size() != anonymity_sets.size())
        throw std::invalid_argument("Number of anonymity sets and number of vectors containing serial numbers must be equal");

    int t = 0;
    for (std::size_t k = 0; k < Sin.size(); k++) {

        std::vector<SigmaExtendedProof> sigma_proofs_k;
        for (std::size_t i = 0; i < Sin[k].size(); ++i, ++t) {
            zV += sigma_proofs[t].zV_;
            zR += sigma_proofs[t].zR_;
            sigma_proofs_k.emplace_back(sigma_proofs[t]);
        }

        //skip verification if we are collecting proofs for later batch verification
        if (fSkipVerification)
            continue;

        std::vector<GroupElement> C_;
        C_.reserve(anonymity_sets[k].size());
        for (std::size_t j = 0; j < anonymity_sets[k].size(); ++j)
            C_.emplace_back(anonymity_sets[k][j].getValue());

        if (!sigmaVerifier.batchverify(C_, x, Sin[k], sigma_proofs_k)) {
            LogPrintf("Lelantus verification failed due sigma verification failed.");
            return false;
        }
    }

    // verify schnorr proof to verify that Q_k is generated honestly;
    if (version >= LELANTUS_TX_VERSION_4_5) {
        Scalar q_k_x;
        challengeGenerator->get_challenge(q_k_x);

        NthPower qK_x_n(q_k_x);
        GroupElement Gk_sum;
        std::vector<GroupElement> Qks;
        Qks.reserve(sigma_proofs.size() * params->get_sigma_m());
        for (std::size_t t = 0; t < sigma_proofs.size(); ++t)
        {
            const std::vector<GroupElement>& Qk = sigma_proofs[t].Qk;
            for (std::size_t k = 0; k < Qk.size(); ++k)
            {
                Gk_sum += (Qk[k]) * qK_x_n.pow;
                qK_x_n.go_next();

                Qks.emplace_back(Qk[k]);
            }
        }

        SchnorrVerifier schnorrVerifier(params->get_h1(), params->get_h0(), version >= LELANTUS_TX_VERSION_4_5);
        if (!schnorrVerifier.verify(Gk_sum, Qks, qkSchnorrProof)) {
            LogPrintf("Lelantus verification failed due to Qk schnorr proof verification failed.");
            return false;
        }
    }

    return true;
}

bool LelantusVerifier::verify_rangeproof(
        const std::vector<PublicCoin>& Cout,
        const RangeProof& bulletproofs) {
    if (Cout.empty())
        return true;

    std::size_t n = params->get_bulletproofs_n();
    std::size_t m = Cout.size() * 2;

    while (m & (m - 1))
        m++;

    std::vector<GroupElement> g_, h_;
    g_.reserve(n * m);
    h_.reserve(n * m);
    g_.insert(g_.end(), params->get_bulletproofs_g().begin(), params->get_bulletproofs_g().begin() + (n * m));
    h_.insert(h_.end(), params->get_bulletproofs_h().begin(), params->get_bulletproofs_h().begin() + (n * m));

    std::vector<GroupElement> V;
    V.reserve(m);
    std::vector<GroupElement> commitments(Cout.size());
    for (std::size_t i = 0; i < Cout.size(); ++i) {
        V.push_back(Cout[i].getValue());
        V.push_back(Cout[i].getValue() + params->get_h1_limit_range());
        commitments.emplace_back(Cout[i].getValue());
    }

    for (std::size_t i = Cout.size() * 2; i < m; ++i)
        V.push_back(GroupElement());

    RangeVerifier  rangeVerifier(params->get_h1(), params->get_h0(), params->get_g(), g_, h_, n, version);
    if (!rangeVerifier.verify_batch(V, commitments, bulletproofs)) {
        LogPrintf("Lelantus verification failed due range proof verification failed.");
        return false;
    }
    return true;
}

bool LelantusVerifier::verify_schnorrproof(
        const Scalar& x,
        const Scalar& zV,
        const Scalar& zR,
        const Scalar& Vin,
        const Scalar& Vout,
        const Scalar fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        unique_ptr<ChallengeGenerator>& challengeGenerator) {
    GroupElement A;
    for (std::size_t i = 0; i < Cout.size(); ++i)
        A += Cout[i].getValue();
    if (Cout.size() > 0)
        A *= x.exponent(params->get_sigma_m());
    A += params->get_h1() * ((Vout + fee) * x.exponent(params->get_sigma_m()));

    GroupElement B = (params->get_h1() * (Vin * x.exponent(params->get_sigma_m())))
                     + LelantusPrimitives::double_commit(params->get_g(), uint64_t(0), params->get_h1(), zV, params->get_h0(), zR);

    NthPower x_k(x);
    std::vector<Scalar> x_ks;
    x_ks.reserve(params->get_sigma_m());
    for (int k = 0; k < params->get_sigma_m(); ++k)
    {
        x_ks.emplace_back(x_k.pow);
        x_k.go_next();
    }

    GroupElement Comm;
    for (std::size_t t = 0; t < proof.sigma_proofs.size(); ++t)
    {
        GroupElement Comm_t;
        const std::vector<GroupElement>& Qk = proof.sigma_proofs[t].Qk;
        for (std::size_t k = 0; k < Qk.size(); ++k)
        {
            Comm_t += (Qk[k]) * x_ks[k];
        }
        Comm += Comm_t;
    }
    B += Comm;
    SchnorrVerifier schnorrVerifier(params->get_g(), params->get_h0(), version >= LELANTUS_TX_VERSION_4_5);
    const SchnorrProof& schnorrProof = proof.schnorrProof;
    GroupElement Y = A + B * (Scalar(uint64_t(1)).negate());
    // after LELANTUS_TX_VERSION_4_5 we are getting challengeGenerator with filled data from sigma,
    if (!schnorrVerifier.verify(Y, A, B, schnorrProof, challengeGenerator)) {
        LogPrintf("Lelantus verification failed due schnorr proof verification failed.");
        return false;
    }
    return true;
}

}//namespace lelantus<commit_msg>Use multiscalar multiplication in balance verification (#1037)<commit_after>#include "lelantus_verifier.h"
#include "../amount.h"
#include "chainparams.h"
#include "util.h"

namespace lelantus {

LelantusVerifier::LelantusVerifier(const Params* p, unsigned int v) : params(p), version(v) {
}

bool LelantusVerifier::verify(
        const std::map<uint32_t, std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<uint32_t>& groupIds,
        const Scalar& Vin,
        uint64_t Vout,
        uint64_t fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        const SchnorrProof& qkSchnorrProof) {
    Scalar x;
    bool fSkipVerification = 0;
    return verify(anonymity_sets, anonymity_set_hashes, serialNumbers, ecdsaPubkeys, groupIds, Vin, Vout, fee, Cout, proof, qkSchnorrProof, x, fSkipVerification);
}

bool LelantusVerifier::verify(
        const std::map<uint32_t, std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<uint32_t>& groupIds,
        const Scalar& Vin,
        uint64_t Vout,
        uint64_t fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        const SchnorrProof& qkSchnorrProof,
        Scalar& x,
        bool fSkipVerification) {
    //check the overflow of Vout and fee
    if (!(Vout <= uint64_t(::Params().GetConsensus().nMaxValueLelantusSpendPerTransaction) && fee < (1000 * CENT))) { // 1000 * CENT is the value of max fee defined at validation.h
        LogPrintf("Lelantus verification failed due to transparent values check failed.");
        return false;
    }

    // number of serials should be equal to number of sigma proofs, we need one proof for each serial
    if (serialNumbers.size() != proof.sigma_proofs.size()) {
        LogPrintf("Lelantus verification failed due to sizes of serials  and sigma proofs are not equal.");
        return false;
    }

    // max possible number of output coins is 8,
    if (Cout.size() > (params->get_bulletproofs_max_m() / 2)) {
        LogPrintf("Number of output coins are more than allowed.");
        return false;
    }

    std::vector<std::vector<PublicCoin>> vAnonymity_sets;
    std::vector<std::vector<Scalar>> vSin;
    vAnonymity_sets.reserve(anonymity_sets.size());
    vSin.resize(anonymity_sets.size());

    size_t i = 0;
    auto itr = vSin.begin();
    for (const auto& set : anonymity_sets) {
        vAnonymity_sets.emplace_back(set.second);

        while (i < groupIds.size() && groupIds[i] == set.first) {
            itr->push_back(serialNumbers[i++]);
        }
        itr++;
    }

    Scalar zV, zR;
    unique_ptr<ChallengeGenerator> challengeGenerator;
    try {
        // we are passing challengeGenerator ptr here, as after LELANTUS_TX_VERSION_4_5 we need  it back, with filled data, to use in schnorr proof,
        if (!(verify_sigma(vAnonymity_sets, anonymity_set_hashes, vSin, serialNumbers, ecdsaPubkeys, Cout, proof.sigma_proofs, qkSchnorrProof, x, challengeGenerator, zV, zR, fSkipVerification) &&
             verify_rangeproof(Cout, proof.bulletproofs) &&
             verify_schnorrproof(x, zV, zR, Vin, Vout, fee, Cout, proof, challengeGenerator)))
            return false;
    } catch (std::invalid_argument&) {
        return false;
    }

    return true;
}

bool LelantusVerifier::verify_sigma(
        const std::vector<std::vector<PublicCoin>>& anonymity_sets,
        const std::vector<std::vector<unsigned char>>& anonymity_set_hashes,
        const std::vector<std::vector<Scalar>>& Sin,
        const std::vector<Scalar>& serialNumbers,
        const std::vector<std::vector<unsigned char>>& ecdsaPubkeys,
        const std::vector<PublicCoin>& Cout,
        const std::vector<SigmaExtendedProof> &sigma_proofs,
        const SchnorrProof& qkSchnorrProof,
        Scalar& x,
        unique_ptr<ChallengeGenerator>& challengeGenerator,
        Scalar& zV,
        Scalar& zR,
        bool fSkipVerification) {
    std::vector<GroupElement> PubcoinsOut;
    PubcoinsOut.reserve(Cout.size());
    for (auto coin : Cout)
        PubcoinsOut.emplace_back(coin.getValue());

    LelantusPrimitives::generate_Lelantus_challenge(
            sigma_proofs,
            anonymity_set_hashes,
            serialNumbers,
            ecdsaPubkeys,
            PubcoinsOut,
            version,
            challengeGenerator,
            x);

    SigmaExtendedVerifier sigmaVerifier(params->get_g(), params->get_sigma_h(), params->get_sigma_n(),
                                                          params->get_sigma_m());

    if (Sin.size() != anonymity_sets.size())
        throw std::invalid_argument("Number of anonymity sets and number of vectors containing serial numbers must be equal");

    int t = 0;
    for (std::size_t k = 0; k < Sin.size(); k++) {

        std::vector<SigmaExtendedProof> sigma_proofs_k;
        for (std::size_t i = 0; i < Sin[k].size(); ++i, ++t) {
            zV += sigma_proofs[t].zV_;
            zR += sigma_proofs[t].zR_;
            sigma_proofs_k.emplace_back(sigma_proofs[t]);
        }

        //skip verification if we are collecting proofs for later batch verification
        if (fSkipVerification)
            continue;

        std::vector<GroupElement> C_;
        C_.reserve(anonymity_sets[k].size());
        for (std::size_t j = 0; j < anonymity_sets[k].size(); ++j)
            C_.emplace_back(anonymity_sets[k][j].getValue());

        if (!sigmaVerifier.batchverify(C_, x, Sin[k], sigma_proofs_k)) {
            LogPrintf("Lelantus verification failed due sigma verification failed.");
            return false;
        }
    }

    // verify schnorr proof to verify that Q_k is generated honestly;
    if (version >= LELANTUS_TX_VERSION_4_5) {
        Scalar q_k_x;
        challengeGenerator->get_challenge(q_k_x);

        NthPower qK_x_n(q_k_x);
        GroupElement Gk_sum;
        std::vector<GroupElement> Qks;
        Qks.reserve(sigma_proofs.size() * params->get_sigma_m());
        for (std::size_t t = 0; t < sigma_proofs.size(); ++t)
        {
            const std::vector<GroupElement>& Qk = sigma_proofs[t].Qk;
            for (std::size_t k = 0; k < Qk.size(); ++k)
            {
                Gk_sum += (Qk[k]) * qK_x_n.pow;
                qK_x_n.go_next();

                Qks.emplace_back(Qk[k]);
            }
        }

        SchnorrVerifier schnorrVerifier(params->get_h1(), params->get_h0(), version >= LELANTUS_TX_VERSION_4_5);
        if (!schnorrVerifier.verify(Gk_sum, Qks, qkSchnorrProof)) {
            LogPrintf("Lelantus verification failed due to Qk schnorr proof verification failed.");
            return false;
        }
    }

    return true;
}

bool LelantusVerifier::verify_rangeproof(
        const std::vector<PublicCoin>& Cout,
        const RangeProof& bulletproofs) {
    if (Cout.empty())
        return true;

    std::size_t n = params->get_bulletproofs_n();
    std::size_t m = Cout.size() * 2;

    while (m & (m - 1))
        m++;

    std::vector<GroupElement> g_, h_;
    g_.reserve(n * m);
    h_.reserve(n * m);
    g_.insert(g_.end(), params->get_bulletproofs_g().begin(), params->get_bulletproofs_g().begin() + (n * m));
    h_.insert(h_.end(), params->get_bulletproofs_h().begin(), params->get_bulletproofs_h().begin() + (n * m));

    std::vector<GroupElement> V;
    V.reserve(m);
    std::vector<GroupElement> commitments(Cout.size());
    for (std::size_t i = 0; i < Cout.size(); ++i) {
        V.push_back(Cout[i].getValue());
        V.push_back(Cout[i].getValue() + params->get_h1_limit_range());
        commitments.emplace_back(Cout[i].getValue());
    }

    for (std::size_t i = Cout.size() * 2; i < m; ++i)
        V.push_back(GroupElement());

    RangeVerifier  rangeVerifier(params->get_h1(), params->get_h0(), params->get_g(), g_, h_, n, version);
    if (!rangeVerifier.verify_batch(V, commitments, bulletproofs)) {
        LogPrintf("Lelantus verification failed due range proof verification failed.");
        return false;
    }
    return true;
}

bool LelantusVerifier::verify_schnorrproof(
        const Scalar& x,
        const Scalar& zV,
        const Scalar& zR,
        const Scalar& Vin,
        const Scalar& Vout,
        const Scalar fee,
        const std::vector<PublicCoin>& Cout,
        const LelantusProof& proof,
        unique_ptr<ChallengeGenerator>& challengeGenerator) {
    // x^m
    Scalar x_m = x.exponent(params->get_sigma_m());

    // A is computed directly, to take advantage of point addition
    GroupElement A;
    for (std::size_t j = 0; j < Cout.size(); ++j) {
        A += Cout[j].getValue();
    }
    A += params->get_h1() * (Vout + fee);
    A *= x_m;

    // B is computed via multiscalar multiplication
    std::vector<GroupElement> B_points;
    std::vector<Scalar> B_scalars;
    B_points.emplace_back(params->get_h1());
    B_scalars.emplace_back(Vin*x_m + zV);
    B_points.emplace_back(params->get_h0());
    B_scalars.emplace_back(zR);

    NthPower x_k(x);
    std::vector<Scalar> x_ks;
    x_ks.reserve(params->get_sigma_m());
    for (int k = 0; k < params->get_sigma_m(); ++k)
    {
        x_ks.emplace_back(x_k.pow);
        x_k.go_next();
    }

    for (std::size_t t = 0; t < proof.sigma_proofs.size(); ++t)
    {
        const std::vector<GroupElement>& Qk = proof.sigma_proofs[t].Qk;
        for (std::size_t k = 0; k < Qk.size(); ++k)
        {
            B_points.emplace_back(Qk[k]);
            B_scalars.emplace_back(x_ks[k]);
        }
    }

    GroupElement B = secp_primitives::MultiExponent(B_points, B_scalars).get_multiple();

    SchnorrVerifier schnorrVerifier(params->get_g(), params->get_h0(), version >= LELANTUS_TX_VERSION_4_5);
    const SchnorrProof& schnorrProof = proof.schnorrProof;
    GroupElement Y = A + B * (Scalar(uint64_t(1)).negate());
    // after LELANTUS_TX_VERSION_4_5 we are getting challengeGenerator with filled data from sigma,
    if (!schnorrVerifier.verify(Y, A, B, schnorrProof, challengeGenerator)) {
        LogPrintf("Lelantus verification failed due schnorr proof verification failed.");
        return false;
    }
    return true;
}

}//namespace lelantus<|endoftext|>


<commit_before>#ifndef Renderer_HPP
#define Renderer_HPP

#include "FBO.hpp"
#include "BeatDetect.hpp"
#include "Common.hpp"
#include <string>
#include <set>

#ifdef USE_GLES1
#include <GLES/gl.h>
#else
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#endif

#ifdef USE_FTGL
#ifdef WIN32
#include <ftgl.h>
#include <FTGLPixmapFont.h>
#include <FTGLExtrdFont.h>
#else
#include <FTGL/FTFont.h>
#include <FTGL/FTGLPixmapFont.h>
#include <FTGL/FTGLExtrdFont.h>
#endif
#endif /** USE_FTGL */

#include "Pipeline.hpp"
#include "PerPixelMesh.hpp"
#include "Transformation.hpp"
#include "ShaderEngine.hpp"

class UserTexture;
class BeatDetect;
class TextureManager;

class Renderer
{

public:

  bool showfps;
  bool showtitle;
  bool showpreset;
  bool showhelp;
  bool showstats;

  bool studio;
  bool correction;

  bool noSwitch;

  int totalframes;
  float realfps;

  std::string title;
  int drawtitle;
  int texsize;

  Renderer( int width, int height, int gx, int gy, int texsize,  BeatDetect *beatDetect, std::string presetURL, std::string title_fontURL, std::string menu_fontURL);
  ~Renderer();

  void RenderFrame(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void ResetTextures();
  void reset(int w, int h);
  GLuint initRenderToTexture();

  void SetPipeline(Pipeline &pipeline);

  void setPresetName(const std::string& theValue)
  {
    m_presetName = theValue;
  }

  std::string presetName() const
  {
    return m_presetName;
  }

private:

	PerPixelMesh mesh;
  RenderTarget *renderTarget;
  BeatDetect *beatDetect;
  TextureManager *textureManager;
  static Pipeline* currentPipe;
  RenderContext renderContext;
  //per pixel equation variables
#ifdef USE_CG
  ShaderEngine shaderEngine;
#endif
  std::string m_presetName;

  float* p;

  int vw;
  int vh;

  float aspect;

  std::string title_fontURL;
  std::string menu_fontURL;
  std::string presetURL;

#ifdef USE_FTGL
  FTGLPixmapFont *title_font;
  FTGLPixmapFont *other_font;
  FTGLExtrdFont *poly_font;
#endif /** USE_FTGL */

  void SetupPass1(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void Interpolation(const Pipeline &pipeline);
  void RenderItems(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void FinishPass1();
  void Pass2 (const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void CompositeOutput(const Pipeline &pipeline, const PipelineContext &pipelineContext);

  inline static Point PerPixel(Point p, PerPixelContext &context)
  {
	  return currentPipe->PerPixel(p,context);
  }

  void rescale_per_pixel_matrices();

  void draw_fps( float realfps );
  void draw_stats();
  void draw_help();
  void draw_preset();
  void draw_title();
  void draw_title_to_screen(bool flip);
  void draw_title_to_texture();

};

#endif
<commit_msg>FTGL header update<commit_after>#ifndef Renderer_HPP
#define Renderer_HPP

#include "FBO.hpp"
#include "BeatDetect.hpp"
#include "Common.hpp"
#include <string>
#include <set>

#ifdef USE_GLES1
#include <GLES/gl.h>
#else
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#endif

#ifdef USE_FTGL
#ifdef WIN32
#include <ftgl.h>
#include <FTGLPixmapFont.h>
#include <FTGLExtrdFont.h>
#else
#include <FTGL/ftgl.h>
#endif
#endif /** USE_FTGL */

#include "Pipeline.hpp"
#include "PerPixelMesh.hpp"
#include "Transformation.hpp"
#include "ShaderEngine.hpp"

class UserTexture;
class BeatDetect;
class TextureManager;

class Renderer
{

public:

  bool showfps;
  bool showtitle;
  bool showpreset;
  bool showhelp;
  bool showstats;

  bool studio;
  bool correction;

  bool noSwitch;

  int totalframes;
  float realfps;

  std::string title;
  int drawtitle;
  int texsize;

  Renderer( int width, int height, int gx, int gy, int texsize,  BeatDetect *beatDetect, std::string presetURL, std::string title_fontURL, std::string menu_fontURL);
  ~Renderer();

  void RenderFrame(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void ResetTextures();
  void reset(int w, int h);
  GLuint initRenderToTexture();

  void SetPipeline(Pipeline &pipeline);

  void setPresetName(const std::string& theValue)
  {
    m_presetName = theValue;
  }

  std::string presetName() const
  {
    return m_presetName;
  }

private:

	PerPixelMesh mesh;
  RenderTarget *renderTarget;
  BeatDetect *beatDetect;
  TextureManager *textureManager;
  static Pipeline* currentPipe;
  RenderContext renderContext;
  //per pixel equation variables
#ifdef USE_CG
  ShaderEngine shaderEngine;
#endif
  std::string m_presetName;

  float* p;

  int vw;
  int vh;

  float aspect;

  std::string title_fontURL;
  std::string menu_fontURL;
  std::string presetURL;

#ifdef USE_FTGL
  FTGLPixmapFont *title_font;
  FTGLPixmapFont *other_font;
  FTGLExtrdFont *poly_font;
#endif /** USE_FTGL */

  void SetupPass1(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void Interpolation(const Pipeline &pipeline);
  void RenderItems(const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void FinishPass1();
  void Pass2 (const Pipeline &pipeline, const PipelineContext &pipelineContext);
  void CompositeOutput(const Pipeline &pipeline, const PipelineContext &pipelineContext);

  inline static Point PerPixel(Point p, PerPixelContext &context)
  {
	  return currentPipe->PerPixel(p,context);
  }

  void rescale_per_pixel_matrices();

  void draw_fps( float realfps );
  void draw_stats();
  void draw_help();
  void draw_preset();
  void draw_title();
  void draw_title_to_screen(bool flip);
  void draw_title_to_texture();

};

#endif
<|endoftext|>


<commit_before>//===--- TypeCheckProtocol.cpp - Protocol Checking ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for protocols, in particular, checking
// whether a given type conforms to a given protocol.
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "NameLookup.h"
using namespace swift;

static Type getInstanceUsageType(ValueDecl *Value, ASTContext &Context) {
  Type Ty = Value->getType();
  if (FuncDecl *Func = dyn_cast<FuncDecl>(Value)) {
    // FIXME: Revisit when we add 'this' to static functions.
    if (!Func->isStatic()) {
      if (auto FuncTy = dyn_cast<FunctionType>(Func->getType()))
        return FuncTy->getResult()->getUnlabeledType(Context);
    }
  }

  return Ty->getUnlabeledType(Context);
}

/// \brief Retrieve the kind of requirement described by the given declaration,
/// for use in some diagnostics.
/// FIXME: Enumify this.
int getRequirementKind(ValueDecl *VD) {
  if (isa<FuncDecl>(VD))
    return 0;

  if (isa<VarDecl>(VD))
    return 1;

  assert(isa<SubscriptDecl>(VD) && "Unhandled requirement kind");
  return 2;
}

static std::unique_ptr<ProtocolConformance>
checkConformsToProtocol(TypeChecker &TC, Type T, ProtocolDecl *Proto,
                        SourceLoc ComplainLoc) {
  llvm::DenseMap<ValueDecl *, ValueDecl *> Mapping;
  llvm::DenseMap<ArchetypeType *, Type> TypeMapping;
  llvm::DenseMap<ProtocolDecl *, ProtocolConformance *> InheritedMapping;

  // Check that T conforms to all inherited protocols.
  for (auto Inherited : Proto->getInherited()) {
    ProtocolType *InheritedProto = Inherited->getAs<ProtocolType>();
    if (!InheritedProto)
      return nullptr;

    if (auto Conformance = TC.conformsToProtocol(T, InheritedProto->getDecl(),
                                                 ComplainLoc))
      InheritedMapping[InheritedProto->getDecl()] = Conformance;
    else {
      // Recursive call already diagnosed this problem, but tack on a note
      // to establish the relationship.
      if (ComplainLoc.isValid()) {
        TC.diagnose(Proto->getLocStart(),
                    diag::inherited_protocol_does_not_conform, T, Inherited);
      }
      return nullptr;
    }
  }

  bool Complained = false;

  // First, resolve any associated type members. They'll be used for checking
  // other members.

  // FIXME: This algorithm is totally busted. We want to allow deduction of
  // associated type witnesses from the parameter/return types of other
  // witnesses, or to figure out an associated type based on one of its other
  // names, which means we need a rather more sophisticated algorithm.
  for (auto Member : Proto->getMembers()) {
    auto AssociatedType = dyn_cast<TypeAliasDecl>(Member);
    if (!AssociatedType)
      continue;

    // Bind the implicit 'This' type to the type T.
    // FIXME: Should have some kind of 'implicit' bit to detect this.
    if (AssociatedType->getName().str().equals("This")) {
      TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
        = T;
      continue;
    }

    MemberLookup Lookup(T, AssociatedType->getName(), TC.TU);
    if (Lookup.isSuccess()) {
      SmallVector<TypeDecl *, 2> Viable;

      for (auto Candidate : Lookup.Results) {
        switch (Candidate.Kind) {
        case MemberLookupResult::MetatypeMember:
          // FIXME: Check this type against the protocol requirements.
          if (auto Type = dyn_cast<TypeDecl>(Candidate.D))
            Viable.push_back(Type);
          break;

        case MemberLookupResult::MemberProperty:
        case MemberLookupResult::MemberFunction:
          // Fall-through

        case MemberLookupResult::TupleElement:
          // Tuple elements cannot satisfy requirements.
          break;
        }
      }

      if (Viable.size() == 1) {
        TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
          = Viable.front()->getDeclaredType();
        continue;
      }

      if (ComplainLoc.isInvalid())
        return nullptr;

      if (!Viable.empty()) {
        if (!Complained) {
          TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                      T, Proto->getDeclaredType());
          Complained = true;
        }

        TC.diagnose(AssociatedType->getLocStart(),
                    diag::ambiguous_witnesses_type,
                    AssociatedType->getName());

        for (auto Candidate : Viable)
          TC.diagnose(Candidate->getLocStart(), diag::protocol_witness_type);
      }
    }

    if (ComplainLoc.isValid()) {
      if (!Complained) {
        TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                    T, Proto->getDeclaredType());
        Complained = true;
      }

      TC.diagnose(AssociatedType->getLocStart(), diag::no_witnesses_type,
                  AssociatedType->getName());
      for (auto Candidate : Lookup.Results) {
        if (Candidate.hasDecl())
          TC.diagnose(Candidate.D->getLocStart(), diag::protocol_witness_type);
      }
    } else {
      return nullptr;
    }

  }

  // Check that T provides all of the required func/variable/subscript members.
  for (auto Member : Proto->getMembers()) {
    auto Requirement = dyn_cast<ValueDecl>(Member);
    if (!Requirement)
      continue;

    // Associated type requirements handled above.
    if (isa<TypeAliasDecl>(Requirement))
      continue;

    // Variable/function/subscript requirements.
    MemberLookup Lookup(T, Requirement->getName(), TC.TU);

    if (Lookup.isSuccess()) {
      SmallVector<ValueDecl *, 2> Viable;
      // Determine the type that we require the witness to have, substituting
      // in the witnesses we've collected for our archetypes.
      Type RequiredTy = TC.substType(getInstanceUsageType(Requirement,
                                                          TC.Context),
                                     TypeMapping);

      for (auto Candidate : Lookup.Results) {
        switch (Candidate.Kind) {
        case MemberLookupResult::MetatypeMember:
          // Static members are ignored.
          // FIXME: Diagnose if static members happen to match?
          break;

        case MemberLookupResult::MemberProperty:
        case MemberLookupResult::MemberFunction:
          if (Candidate.D->getKind() == Requirement->getKind() &&
              RequiredTy->isEqual(getInstanceUsageType(Candidate.D,
                                                       TC.Context)))
            Viable.push_back(Candidate.D);
          break;

        case MemberLookupResult::TupleElement:
          // Tuple elements cannot satisfy requirements.
          break;
        }
      }

      if (Viable.size() == 1) {
        Mapping[Requirement] = Viable.front();
        continue;
      }

      if (ComplainLoc.isInvalid())
        return nullptr;

      if (!Viable.empty()) {
        if (!Complained) {
          TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                      T, Proto->getDeclaredType());
          Complained = true;
        }

        TC.diagnose(Requirement->getLocStart(), diag::ambiguous_witnesses,
                    getRequirementKind(Requirement),
                    Requirement->getName(),
                    RequiredTy);

        for (auto Candidate : Viable)
          TC.diagnose(Candidate->getLocStart(), diag::protocol_witness,
                      getInstanceUsageType(Candidate, TC.Context));
      }
    }

    if (ComplainLoc.isValid()) {
      if (!Complained) {
        TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                    T, Proto->getDeclaredType());
        Complained = true;
      }

      TC.diagnose(Requirement->getLocStart(), diag::no_witnesses,
                  getRequirementKind(Requirement),
                  Requirement->getName(),
                  getInstanceUsageType(Requirement, TC.Context));
      for (auto Candidate : Lookup.Results) {
        if (Candidate.hasDecl())
          TC.diagnose(Candidate.D->getLocStart(), diag::protocol_witness,
                      getInstanceUsageType(Candidate.D, TC.Context));
      }
    } else {
      return nullptr;
    }
  }

  if (Complained)
    return nullptr;

  std::unique_ptr<ProtocolConformance> Result(new ProtocolConformance);
  // FIXME: Make DenseMap movable to make this efficient.
  Result->Mapping = std::move(Mapping);
  Result->TypeMapping = std::move(TypeMapping);
  Result->InheritedMapping = std::move(InheritedMapping);
  return Result;
}

ProtocolConformance *
TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto,
                                SourceLoc ComplainLoc) {
  ASTContext::ConformsToMap::key_type Key(T->getCanonicalType(), Proto);
  ASTContext::ConformsToMap::iterator Known = Context.ConformsTo.find(Key);
  if (Known != Context.ConformsTo.end())
    return Known->second;

  // Assume that the type does not conform to this protocol while checking
  // whether it does in fact conform. This eliminates both infinite recursion
  // (if the protocol hierarchies are circular) as well as tautologies.
  Context.ConformsTo[Key] = nullptr;
  if (std::unique_ptr<ProtocolConformance> Conformance
        = checkConformsToProtocol(*this, T, Proto, ComplainLoc)) {
    auto result = Conformance.release();
    Context.ConformsTo[Key] = result;
    return result;
  }
  return nullptr;
}
<commit_msg>Make explicit protocol conformance checking more robust against unsatisfied associated type requirements. Otherwise, we would assert because substitution did not have a binding for the unsatisfied archetypes. This whole conforms-to matching stuff will eventually be rewritten, so it doesn't bother me that we don't continue checking very far after failing to satisfy an associated type requirement.<commit_after>//===--- TypeCheckProtocol.cpp - Protocol Checking ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for protocols, in particular, checking
// whether a given type conforms to a given protocol.
//===----------------------------------------------------------------------===//
#include "TypeChecker.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "NameLookup.h"
using namespace swift;

static Type getInstanceUsageType(ValueDecl *Value, ASTContext &Context) {
  Type Ty = Value->getType();
  if (FuncDecl *Func = dyn_cast<FuncDecl>(Value)) {
    // FIXME: Revisit when we add 'this' to static functions.
    if (!Func->isStatic()) {
      if (auto FuncTy = dyn_cast<FunctionType>(Func->getType()))
        return FuncTy->getResult()->getUnlabeledType(Context);
    }
  }

  return Ty->getUnlabeledType(Context);
}

/// \brief Retrieve the kind of requirement described by the given declaration,
/// for use in some diagnostics.
/// FIXME: Enumify this.
int getRequirementKind(ValueDecl *VD) {
  if (isa<FuncDecl>(VD))
    return 0;

  if (isa<VarDecl>(VD))
    return 1;

  assert(isa<SubscriptDecl>(VD) && "Unhandled requirement kind");
  return 2;
}

static std::unique_ptr<ProtocolConformance>
checkConformsToProtocol(TypeChecker &TC, Type T, ProtocolDecl *Proto,
                        SourceLoc ComplainLoc) {
  llvm::DenseMap<ValueDecl *, ValueDecl *> Mapping;
  llvm::DenseMap<ArchetypeType *, Type> TypeMapping;
  llvm::DenseMap<ProtocolDecl *, ProtocolConformance *> InheritedMapping;

  // Check that T conforms to all inherited protocols.
  for (auto Inherited : Proto->getInherited()) {
    ProtocolType *InheritedProto = Inherited->getAs<ProtocolType>();
    if (!InheritedProto)
      return nullptr;

    if (auto Conformance = TC.conformsToProtocol(T, InheritedProto->getDecl(),
                                                 ComplainLoc))
      InheritedMapping[InheritedProto->getDecl()] = Conformance;
    else {
      // Recursive call already diagnosed this problem, but tack on a note
      // to establish the relationship.
      if (ComplainLoc.isValid()) {
        TC.diagnose(Proto->getLocStart(),
                    diag::inherited_protocol_does_not_conform, T, Inherited);
      }
      return nullptr;
    }
  }

  bool Complained = false;

  // First, resolve any associated type members. They'll be used for checking
  // other members.

  // FIXME: This algorithm is totally busted. We want to allow deduction of
  // associated type witnesses from the parameter/return types of other
  // witnesses, or to figure out an associated type based on one of its other
  // names, which means we need a rather more sophisticated algorithm.
  for (auto Member : Proto->getMembers()) {
    auto AssociatedType = dyn_cast<TypeAliasDecl>(Member);
    if (!AssociatedType)
      continue;

    // Bind the implicit 'This' type to the type T.
    // FIXME: Should have some kind of 'implicit' bit to detect this.
    if (AssociatedType->getName().str().equals("This")) {
      TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
        = T;
      continue;
    }

    MemberLookup Lookup(T, AssociatedType->getName(), TC.TU);
    if (Lookup.isSuccess()) {
      SmallVector<TypeDecl *, 2> Viable;

      for (auto Candidate : Lookup.Results) {
        switch (Candidate.Kind) {
        case MemberLookupResult::MetatypeMember:
          // FIXME: Check this type against the protocol requirements.
          if (auto Type = dyn_cast<TypeDecl>(Candidate.D))
            Viable.push_back(Type);
          break;

        case MemberLookupResult::MemberProperty:
        case MemberLookupResult::MemberFunction:
          // Fall-through

        case MemberLookupResult::TupleElement:
          // Tuple elements cannot satisfy requirements.
          break;
        }
      }

      if (Viable.size() == 1) {
        TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
          = Viable.front()->getDeclaredType();
        continue;
      }

      if (ComplainLoc.isInvalid())
        return nullptr;

      if (!Viable.empty()) {
        if (!Complained) {
          TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                      T, Proto->getDeclaredType());
          Complained = true;
        }

        TC.diagnose(AssociatedType->getLocStart(),
                    diag::ambiguous_witnesses_type,
                    AssociatedType->getName());

        for (auto Candidate : Viable)
          TC.diagnose(Candidate->getLocStart(), diag::protocol_witness_type);

        TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
          = ErrorType::get(TC.Context);
        continue;
      }
    }

    if (ComplainLoc.isValid()) {
      if (!Complained) {
        TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                    T, Proto->getDeclaredType());
        Complained = true;
      }

      TC.diagnose(AssociatedType->getLocStart(), diag::no_witnesses_type,
                  AssociatedType->getName());
      for (auto Candidate : Lookup.Results) {
        if (Candidate.hasDecl())
          TC.diagnose(Candidate.D->getLocStart(), diag::protocol_witness_type);
      }

      TypeMapping[AssociatedType->getUnderlyingType()->getAs<ArchetypeType>()]
        = ErrorType::get(TC.Context);
    } else {
      return nullptr;
    }
  }

  // Check that T provides all of the required func/variable/subscript members.
  for (auto Member : Proto->getMembers()) {
    auto Requirement = dyn_cast<ValueDecl>(Member);
    if (!Requirement)
      continue;

    // Associated type requirements handled above.
    if (isa<TypeAliasDecl>(Requirement))
      continue;

    // Variable/function/subscript requirements.
    MemberLookup Lookup(T, Requirement->getName(), TC.TU);

    if (Lookup.isSuccess()) {
      SmallVector<ValueDecl *, 2> Viable;
      // Determine the type that we require the witness to have, substituting
      // in the witnesses we've collected for our archetypes.
      Type RequiredTy = TC.substType(getInstanceUsageType(Requirement,
                                                          TC.Context),
                                     TypeMapping);

      for (auto Candidate : Lookup.Results) {
        switch (Candidate.Kind) {
        case MemberLookupResult::MetatypeMember:
          // Static members are ignored.
          // FIXME: Diagnose if static members happen to match?
          break;

        case MemberLookupResult::MemberProperty:
        case MemberLookupResult::MemberFunction:
          if (Candidate.D->getKind() == Requirement->getKind() &&
              RequiredTy->isEqual(getInstanceUsageType(Candidate.D,
                                                       TC.Context)))
            Viable.push_back(Candidate.D);
          break;

        case MemberLookupResult::TupleElement:
          // Tuple elements cannot satisfy requirements.
          break;
        }
      }

      if (Viable.size() == 1) {
        Mapping[Requirement] = Viable.front();
        continue;
      }

      if (ComplainLoc.isInvalid())
        return nullptr;

      if (!Viable.empty()) {
        if (!Complained) {
          TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                      T, Proto->getDeclaredType());
          Complained = true;
        }

        TC.diagnose(Requirement->getLocStart(), diag::ambiguous_witnesses,
                    getRequirementKind(Requirement),
                    Requirement->getName(),
                    RequiredTy);

        for (auto Candidate : Viable)
          TC.diagnose(Candidate->getLocStart(), diag::protocol_witness,
                      getInstanceUsageType(Candidate, TC.Context));

        continue;
      }
    }

    if (ComplainLoc.isValid()) {
      if (!Complained) {
        TC.diagnose(ComplainLoc, diag::type_does_not_conform,
                    T, Proto->getDeclaredType());
        Complained = true;
      }

      TC.diagnose(Requirement->getLocStart(), diag::no_witnesses,
                  getRequirementKind(Requirement),
                  Requirement->getName(),
                  getInstanceUsageType(Requirement, TC.Context));
      for (auto Candidate : Lookup.Results) {
        if (Candidate.hasDecl())
          TC.diagnose(Candidate.D->getLocStart(), diag::protocol_witness,
                      getInstanceUsageType(Candidate.D, TC.Context));
      }
    } else {
      return nullptr;
    }
  }

  if (Complained)
    return nullptr;

  std::unique_ptr<ProtocolConformance> Result(new ProtocolConformance);
  // FIXME: Make DenseMap movable to make this efficient.
  Result->Mapping = std::move(Mapping);
  Result->TypeMapping = std::move(TypeMapping);
  Result->InheritedMapping = std::move(InheritedMapping);
  return Result;
}

ProtocolConformance *
TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto,
                                SourceLoc ComplainLoc) {
  ASTContext::ConformsToMap::key_type Key(T->getCanonicalType(), Proto);
  ASTContext::ConformsToMap::iterator Known = Context.ConformsTo.find(Key);
  if (Known != Context.ConformsTo.end())
    return Known->second;

  // Assume that the type does not conform to this protocol while checking
  // whether it does in fact conform. This eliminates both infinite recursion
  // (if the protocol hierarchies are circular) as well as tautologies.
  Context.ConformsTo[Key] = nullptr;
  if (std::unique_ptr<ProtocolConformance> Conformance
        = checkConformsToProtocol(*this, T, Proto, ComplainLoc)) {
    auto result = Conformance.release();
    Context.ConformsTo[Key] = result;
    return result;
  }
  return nullptr;
}
<|endoftext|>


<commit_before>#include "stdafx.h"

#include "config.h"
#include "graphics.h"
#include "movies.h"
#include "tig_startup.h"
#include "tig_msg.h"
#include "tig_mouse.h"

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam);

/*
	Indicates that incoming events are due to window creation.
*/
static bool creatingWindow = false;

struct WindowFuncs : AddressTable {
	void (__cdecl *WindowActivationChanged)(bool active);

	WindowFuncs() {
		rebase(WindowActivationChanged, 0x101DF4E0);
	}
} windowFuncs;

GlobalPrimitive<uint32_t, 0x10D25C38> globalWwndproc;

bool CreateMainWindow(TigConfig* settings) {
	bool windowed = config.windowed;
	bool unknownFlag = (settings->flags & 0x100) != 0;

	video->hinstance = settings->hinstance;

	// Is not actually used anymore, but messages.c checks for it being != 0
	globalWwndproc = 1;

	WNDCLASSA wndClass;
	ZeroMemory(&wndClass, sizeof(WNDCLASSA));
	wndClass.style = CS_DBLCLKS;
	wndClass.lpfnWndProc = MainWindowProc;
	wndClass.hInstance = video->hinstance;
	wndClass.hIcon = LoadIconA(video->hinstance, "icon");
	wndClass.hCursor = LoadCursorA(0, MAKEINTRESOURCEA(IDC_ARROW));
	wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndClass.lpszClassName = "TIGClass";

	if (!RegisterClassA(&wndClass)) {
		return false;
	}

	auto screenWidth = GetSystemMetrics(SM_CXSCREEN);
	auto screenHeight = GetSystemMetrics(SM_CYSCREEN);

	RECT windowRect;
	HMENU menu;
	DWORD dwStyle;
	DWORD dwExStyle;

	if (!windowed) {
		settings->width = screenWidth;
		settings->height = screenHeight;

		windowRect.left = 0;
		windowRect.top = 0;
		windowRect.right = screenWidth;
		windowRect.bottom = screenHeight;
		menu = 0;
		dwStyle = WS_POPUP;
		// This is bad for debugging
		if (!IsDebuggerPresent()) {
			dwExStyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
		} else {
			dwExStyle = 0;
		}
		memcpy(&video->screenSizeRect, &windowRect, sizeof(RECT));
	} else {
		// Apparently this flag controls whether x,y are preset from the outside
		if (unknownFlag) {
			windowRect.left = settings->x;
			windowRect.top = settings->y;
			windowRect.right = settings->x + settings->width;
			windowRect.bottom = settings->y + settings->height;
		} else {
			windowRect.left = (screenWidth - settings->width) / 2;
			windowRect.top = (screenHeight - settings->height) / 2;
			windowRect.right = windowRect.left + settings->width;
			windowRect.bottom = windowRect.top + settings->height;
		}

		menu = NULL;
		dwStyle = WS_OVERLAPPEDWINDOW; //  WS_CAPTION | WS_CLIPCHILDREN | WS_SYSMENU | WS_GROUP;
		dwExStyle = 0;

  		AdjustWindowRect(&windowRect, dwStyle, FALSE);
		int extraWidth = (windowRect.right - windowRect.left) - settings->width;
		int extraHeight = (windowRect.bottom - windowRect.top) - settings->height;
		windowRect.left = (screenWidth - settings->width) / 2 - (extraWidth / 2);
		windowRect.top = (screenHeight - settings->height) / 2 - (extraHeight / 2);
		windowRect.right = windowRect.left + settings->width + extraWidth;
		windowRect.bottom = windowRect.top + settings->height + extraHeight;
	}

	dwStyle |= WS_VISIBLE;
	video->width = settings->width;
	video->height = settings->height;

	temple_set<0x10D24E0C>(0);
	temple_set<0x10D24E10>(0);
	temple_set<0x10D24E14>(settings->width);

	const char* windowTitle;
	// Apparently is a flag that indicates a custom window title
	if (settings->flags & 0x40) {
		windowTitle = settings->windowTitle;
	} else {
		windowTitle = "Temple of Elemental Evil - Cirlce of Eight";
	}

	DWORD windowWidth = windowRect.right - windowRect.left;
	DWORD windowHeight = windowRect.bottom - windowRect.top;
	logger->info("Creating window with dimensions {}x{}", windowWidth, windowHeight);
	video->hwnd = CreateWindowExA(
		dwExStyle,
		"TIGClass",
		windowTitle,
		dwStyle,
		windowRect.left,
		windowRect.top,
		windowWidth,
		windowHeight,
		0,
		menu,
		settings->hinstance,
		0);

	if (video->hwnd) {
		RECT clientRect;
		GetClientRect(video->hwnd, &clientRect);
		video->current_width = clientRect.right - clientRect.left;
		video->current_height = clientRect.bottom - clientRect.top;

		// Scratchbuffer size sometimes doesn't seem to be set by ToEE itself
		temple_set<0x10307284>(video->current_width);
		temple_set<0x10307288>(video->current_height);

		return true;
	}

	return false;
}

static LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam) {

	static int mousePosX = 0; // Replaces memory @ 10D25CEC
	static int mousePosY = 0; // Replaces memory @ 10D25CF0
	RECT rect;
	TigMsg tigMsg;

	switch (msg) {
	case WM_SETCURSOR:
		SetCursor(nullptr); // Disables default cursor
		if (!movieFuncs.MovieIsPlaying) {
			video->d3dDevice->delegate->ShowCursor(TRUE);
		}
		return TRUE; // This prevents windows from setting the default cursor for us
	case WM_LBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::LEFT, true);
		break;
	case WM_LBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::LEFT, false);
		break;
	case WM_RBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::RIGHT, true);
		break;
	case WM_RBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::RIGHT, false);
		break;
	case WM_MBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::MIDDLE, true);
		break;
	case WM_MBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::MIDDLE, false);
		break;
	case WM_MOUSEWHEEL:
		GetWindowRect(hWnd, &rect);
		mouseFuncs.SetPos(
			GET_X_LPARAM(lparam) - rect.left,
			                    GET_Y_LPARAM(lparam) - rect.top,
			                    GET_WHEEL_DELTA_WPARAM(wparam)
		);
		break;
	case WM_KEYDOWN:
		if (wparam >= VK_HOME && wparam <= VK_DOWN || wparam == VK_DELETE) {
			tigMsg.createdMs = timeGetTime();
			tigMsg.type = TigMsgType::KEYDOWN;
			tigMsg.arg1 = wparam;
			msgFuncs.Enqueue(&tigMsg);
		}
		break;
	case WM_CHAR:
		tigMsg.createdMs = timeGetTime();
		tigMsg.type = TigMsgType::CHAR;
		tigMsg.arg1 = wparam;
		msgFuncs.Enqueue(&tigMsg);
		break;
	case WM_SYSCOMMAND:
		if (wparam == SC_KEYMENU || wparam == SC_SCREENSAVE || wparam == SC_MONITORPOWER) {
			return 0;
		}
		break;
	case WM_ACTIVATEAPP:
		windowFuncs.WindowActivationChanged(wparam == 1);
		break;
	case WM_CLOSE:
		tigMsg.createdMs = timeGetTime();
		tigMsg.type = TigMsgType::EXIT;
		tigMsg.arg1 = 1;
		msgFuncs.Enqueue(&tigMsg);
		return 0;
		// Does not seem to be used:
		/*case WM_CREATE:
			GetClientRect(hWnd, &rect);
			ClientToScreen(hWnd, (LPPOINT)&rect);
			ClientToScreen(hWnd, (LPPOINT)&rect.right);
			refresh_screen_rect(&rect);
			break;
		case WM_MOVE:
			GetClientRect(hWnd, &rect);
			ClientToScreen(hWnd, (LPPOINT)&rect);
			ClientToScreen(hWnd, (LPPOINT)&rect.right);
			refresh_screen_rect(&rect);
			get_window_rect(&rect);
			nullsub_1();
			goto LABEL_40;*/
	case WM_ERASEBKGND:
		return 0;
	case WM_MOUSEMOVE:
		mousePosX = GET_X_LPARAM(lparam);
		mousePosY = GET_Y_LPARAM(lparam);
		mouseFuncs.SetPos(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), 0);
		break;
	default:
		break;
	}

	if (msg != WM_KEYDOWN) {
		mouseFuncs.SetPos(mousePosX, mousePosY, 0);
	}

	// Previously, ToEE called a global window proc here but it did nothing useful.
	return DefWindowProcA(hWnd, msg, wparam, lparam);
}
<commit_msg>Disable resizing of main window.<commit_after>#include "stdafx.h"

#include "config.h"
#include "graphics.h"
#include "movies.h"
#include "tig_startup.h"
#include "tig_msg.h"
#include "tig_mouse.h"

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam);

/*
	Indicates that incoming events are due to window creation.
*/
static bool creatingWindow = false;

struct WindowFuncs : AddressTable {
	void (__cdecl *WindowActivationChanged)(bool active);

	WindowFuncs() {
		rebase(WindowActivationChanged, 0x101DF4E0);
	}
} windowFuncs;

GlobalPrimitive<uint32_t, 0x10D25C38> globalWwndproc;

bool CreateMainWindow(TigConfig* settings) {
	bool windowed = config.windowed;
	bool unknownFlag = (settings->flags & 0x100) != 0;

	video->hinstance = settings->hinstance;

	// Is not actually used anymore, but messages.c checks for it being != 0
	globalWwndproc = 1;

	WNDCLASSA wndClass;
	ZeroMemory(&wndClass, sizeof(WNDCLASSA));
	wndClass.style = CS_DBLCLKS;
	wndClass.lpfnWndProc = MainWindowProc;
	wndClass.hInstance = video->hinstance;
	wndClass.hIcon = LoadIconA(video->hinstance, "icon");
	wndClass.hCursor = LoadCursorA(0, MAKEINTRESOURCEA(IDC_ARROW));
	wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndClass.lpszClassName = "TIGClass";

	if (!RegisterClassA(&wndClass)) {
		return false;
	}

	auto screenWidth = GetSystemMetrics(SM_CXSCREEN);
	auto screenHeight = GetSystemMetrics(SM_CYSCREEN);

	RECT windowRect;
	HMENU menu;
	DWORD dwStyle;
	DWORD dwExStyle;

	if (!windowed) {
		settings->width = screenWidth;
		settings->height = screenHeight;

		windowRect.left = 0;
		windowRect.top = 0;
		windowRect.right = screenWidth;
		windowRect.bottom = screenHeight;
		menu = 0;
		dwStyle = WS_POPUP;
		// This is bad for debugging
		if (!IsDebuggerPresent()) {
			dwExStyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
		} else {
			dwExStyle = 0;
		}
		memcpy(&video->screenSizeRect, &windowRect, sizeof(RECT));
	} else {
		// Apparently this flag controls whether x,y are preset from the outside
		if (unknownFlag) {
			windowRect.left = settings->x;
			windowRect.top = settings->y;
			windowRect.right = settings->x + settings->width;
			windowRect.bottom = settings->y + settings->height;
		} else {
			windowRect.left = (screenWidth - settings->width) / 2;
			windowRect.top = (screenHeight - settings->height) / 2;
			windowRect.right = windowRect.left + settings->width;
			windowRect.bottom = windowRect.top + settings->height;
		}

		menu = NULL;
		dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
		dwExStyle = 0;

  		AdjustWindowRect(&windowRect, dwStyle, FALSE);
		int extraWidth = (windowRect.right - windowRect.left) - settings->width;
		int extraHeight = (windowRect.bottom - windowRect.top) - settings->height;
		windowRect.left = (screenWidth - settings->width) / 2 - (extraWidth / 2);
		windowRect.top = (screenHeight - settings->height) / 2 - (extraHeight / 2);
		windowRect.right = windowRect.left + settings->width + extraWidth;
		windowRect.bottom = windowRect.top + settings->height + extraHeight;
	}

	dwStyle |= WS_VISIBLE;
	video->width = settings->width;
	video->height = settings->height;

	temple_set<0x10D24E0C>(0);
	temple_set<0x10D24E10>(0);
	temple_set<0x10D24E14>(settings->width);

	const char* windowTitle;
	// Apparently is a flag that indicates a custom window title
	if (settings->flags & 0x40) {
		windowTitle = settings->windowTitle;
	} else {
		windowTitle = "Temple of Elemental Evil - Cirlce of Eight";
	}

	DWORD windowWidth = windowRect.right - windowRect.left;
	DWORD windowHeight = windowRect.bottom - windowRect.top;
	logger->info("Creating window with dimensions {}x{}", windowWidth, windowHeight);
	video->hwnd = CreateWindowExA(
		dwExStyle,
		"TIGClass",
		windowTitle,
		dwStyle,
		windowRect.left,
		windowRect.top,
		windowWidth,
		windowHeight,
		0,
		menu,
		settings->hinstance,
		0);

	if (video->hwnd) {
		RECT clientRect;
		GetClientRect(video->hwnd, &clientRect);
		video->current_width = clientRect.right - clientRect.left;
		video->current_height = clientRect.bottom - clientRect.top;

		// Scratchbuffer size sometimes doesn't seem to be set by ToEE itself
		temple_set<0x10307284>(video->current_width);
		temple_set<0x10307288>(video->current_height);

		return true;
	}

	return false;
}

static LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam) {

	static int mousePosX = 0; // Replaces memory @ 10D25CEC
	static int mousePosY = 0; // Replaces memory @ 10D25CF0
	RECT rect;
	TigMsg tigMsg;

	switch (msg) {
	case WM_SETCURSOR:
		SetCursor(nullptr); // Disables default cursor
		if (!movieFuncs.MovieIsPlaying) {
			video->d3dDevice->delegate->ShowCursor(TRUE);
		}
		return TRUE; // This prevents windows from setting the default cursor for us
	case WM_LBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::LEFT, true);
		break;
	case WM_LBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::LEFT, false);
		break;
	case WM_RBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::RIGHT, true);
		break;
	case WM_RBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::RIGHT, false);
		break;
	case WM_MBUTTONDOWN:
		mouseFuncs.SetButtonState(MouseButton::MIDDLE, true);
		break;
	case WM_MBUTTONUP:
		mouseFuncs.SetButtonState(MouseButton::MIDDLE, false);
		break;
	case WM_MOUSEWHEEL:
		GetWindowRect(hWnd, &rect);
		mouseFuncs.SetPos(
			GET_X_LPARAM(lparam) - rect.left,
			                    GET_Y_LPARAM(lparam) - rect.top,
			                    GET_WHEEL_DELTA_WPARAM(wparam)
		);
		break;
	case WM_KEYDOWN:
		if (wparam >= VK_HOME && wparam <= VK_DOWN || wparam == VK_DELETE) {
			tigMsg.createdMs = timeGetTime();
			tigMsg.type = TigMsgType::KEYDOWN;
			tigMsg.arg1 = wparam;
			msgFuncs.Enqueue(&tigMsg);
		}
		break;
	case WM_CHAR:
		tigMsg.createdMs = timeGetTime();
		tigMsg.type = TigMsgType::CHAR;
		tigMsg.arg1 = wparam;
		msgFuncs.Enqueue(&tigMsg);
		break;
	case WM_SYSCOMMAND:
		if (wparam == SC_KEYMENU || wparam == SC_SCREENSAVE || wparam == SC_MONITORPOWER) {
			return 0;
		}
		break;
	case WM_ACTIVATEAPP:
		windowFuncs.WindowActivationChanged(wparam == 1);
		break;
	case WM_CLOSE:
		tigMsg.createdMs = timeGetTime();
		tigMsg.type = TigMsgType::EXIT;
		tigMsg.arg1 = 1;
		msgFuncs.Enqueue(&tigMsg);
		return 0;
		// Does not seem to be used:
		/*case WM_CREATE:
			GetClientRect(hWnd, &rect);
			ClientToScreen(hWnd, (LPPOINT)&rect);
			ClientToScreen(hWnd, (LPPOINT)&rect.right);
			refresh_screen_rect(&rect);
			break;
		case WM_MOVE:
			GetClientRect(hWnd, &rect);
			ClientToScreen(hWnd, (LPPOINT)&rect);
			ClientToScreen(hWnd, (LPPOINT)&rect.right);
			refresh_screen_rect(&rect);
			get_window_rect(&rect);
			nullsub_1();
			goto LABEL_40;*/
	case WM_ERASEBKGND:
		return 0;
	case WM_MOUSEMOVE:
		mousePosX = GET_X_LPARAM(lparam);
		mousePosY = GET_Y_LPARAM(lparam);
		mouseFuncs.SetPos(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam), 0);
		break;
	default:
		break;
	}

	if (msg != WM_KEYDOWN) {
		mouseFuncs.SetPos(mousePosX, mousePosY, 0);
	}

	// Previously, ToEE called a global window proc here but it did nothing useful.
	return DefWindowProcA(hWnd, msg, wparam, lparam);
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "lsystemview.h"
#include <QtGui>
#include <QFileDialog>
#include <QFile>
#include <QXmlStreamReader>
#include <QMessageBox>
#include <QFileSystemModel>
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->startXDoubleSpinBox, SIGNAL(valueChanged(double)),
            ui->lSystemView, SLOT(valueStartXChanged(double)));
    connect(ui->startYDoubleSpinBox, SIGNAL(valueChanged(double)),
            ui->lSystemView, SLOT(valueStartYChanged(double)));
    connect(ui->startRotationSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueStartRotChanged(int)));
    connect(ui->iterationsSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueIterationsChanged(int)));
    connect(ui->stepSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueStepLengthChanged(int)));

    connect(ui->backgroundWidget, SIGNAL(colorChanged(QColor)),
            ui->lSystemView, SLOT(setBackgroundColor(QColor)));
    connect(ui->foregroundWidget, SIGNAL(colorChanged(QColor)),
            ui->lSystemView, SLOT(setForegroundColor(QColor)));

    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(onOpenClicked()));
    connect(ui->actionShowHideBrowser, SIGNAL(triggered()), this, SLOT(onShowHideBrowserClicked()));
    connect(ui->actionShowHideProperties, SIGNAL(triggered()), this, SLOT(onShowHidePropertiesClicked()));

    connect(ui->randomizeButton, SIGNAL(clicked()), this, SLOT(onRandomizeColorsClicked()));

    updateControls();

    // l-system directory browser

    fileSystemModel = new QFileSystemModel;
    fileSystemModel->setRootPath(QDir::homePath());

    QStringList nameFilters;

    nameFilters.append("*.lsys");

    fileSystemModel->setNameFilters(nameFilters);

    ui->treeView->setModel(fileSystemModel);

    connect(ui->treeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
            this, SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onOpenClicked()
{
    QString s = QFileDialog::getOpenFileName(this,
                                               tr("Open L-System File"), "", tr("L-System Files (*.lsys)"));
    QFile *f = new QFile(s);

    openFile(f);
}

void MainWindow::onShowHideBrowserClicked()
{
    ui->treeView->setVisible(!ui->treeView->isVisible());
}

void MainWindow::onShowHidePropertiesClicked()
{
    ui->parameters->setVisible(!ui->parameters->isVisible());
}

void MainWindow::onRandomizeColorsClicked()
{
    ui->lSystemView->lsystem.setRandomColors();
    updateControls();
    update();
}

void MainWindow::openFile(QFile *f)
{
    ui->lSystemView->lsystem.load(f);
    updateControls();
    update();
}

void MainWindow::onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
    QString path = fileSystemModel->filePath(ui->treeView->selectionModel()->currentIndex());

    QFile *f = new QFile(path);

    openFile(f);
}

void MainWindow::updateControls()
{
    ui->startXDoubleSpinBox->setValue(ui->lSystemView->lsystem.startX);
    ui->startYDoubleSpinBox->setValue(ui->lSystemView->lsystem.startY);
    ui->startRotationSpinBox->setValue(ui->lSystemView->lsystem.startRot);
    ui->iterationsSpinBox->setValue(ui->lSystemView->lsystem.iterations);
    ui->stepSpinBox->setValue(ui->lSystemView->lsystem.stepLength);
    ui->backgroundWidget->setValue(ui->lSystemView->lsystem.backgroundColor);
    ui->foregroundWidget->setValue(ui->lSystemView->lsystem.foregroundColor);
}
<commit_msg>File browser shows only file name, hidden its header.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "lsystemview.h"
#include <QtGui>
#include <QFileDialog>
#include <QFile>
#include <QXmlStreamReader>
#include <QMessageBox>
#include <QFileSystemModel>
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->startXDoubleSpinBox, SIGNAL(valueChanged(double)),
            ui->lSystemView, SLOT(valueStartXChanged(double)));
    connect(ui->startYDoubleSpinBox, SIGNAL(valueChanged(double)),
            ui->lSystemView, SLOT(valueStartYChanged(double)));
    connect(ui->startRotationSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueStartRotChanged(int)));
    connect(ui->iterationsSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueIterationsChanged(int)));
    connect(ui->stepSpinBox, SIGNAL(valueChanged(int)),
            ui->lSystemView, SLOT(valueStepLengthChanged(int)));

    connect(ui->backgroundWidget, SIGNAL(colorChanged(QColor)),
            ui->lSystemView, SLOT(setBackgroundColor(QColor)));
    connect(ui->foregroundWidget, SIGNAL(colorChanged(QColor)),
            ui->lSystemView, SLOT(setForegroundColor(QColor)));

    connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(onOpenClicked()));
    connect(ui->actionShowHideBrowser, SIGNAL(triggered()), this, SLOT(onShowHideBrowserClicked()));
    connect(ui->actionShowHideProperties, SIGNAL(triggered()), this, SLOT(onShowHidePropertiesClicked()));

    connect(ui->randomizeButton, SIGNAL(clicked()), this, SLOT(onRandomizeColorsClicked()));

    updateControls();

    // l-system directory browser

    fileSystemModel = new QFileSystemModel;
    fileSystemModel->setRootPath(QDir::homePath());

    QStringList nameFilters;

    nameFilters.append("*.lsys");

    fileSystemModel->setNameFilters(nameFilters);

    ui->treeView->setModel(fileSystemModel);
    ui->treeView->hideColumn(3);
    ui->treeView->hideColumn(2);
    ui->treeView->hideColumn(1);
    ui->treeView->setHeaderHidden(true);

    connect(ui->treeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
            this, SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onOpenClicked()
{
    QString s = QFileDialog::getOpenFileName(this,
                                               tr("Open L-System File"), "", tr("L-System Files (*.lsys)"));
    QFile *f = new QFile(s);

    openFile(f);
}

void MainWindow::onShowHideBrowserClicked()
{
    ui->treeView->setVisible(!ui->treeView->isVisible());
}

void MainWindow::onShowHidePropertiesClicked()
{
    ui->parameters->setVisible(!ui->parameters->isVisible());
}

void MainWindow::onRandomizeColorsClicked()
{
    ui->lSystemView->lsystem.setRandomColors();
    updateControls();
    update();
}

void MainWindow::openFile(QFile *f)
{
    ui->lSystemView->lsystem.load(f);
    updateControls();
    update();
}

void MainWindow::onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
    QString path = fileSystemModel->filePath(ui->treeView->selectionModel()->currentIndex());

    QFile *f = new QFile(path);

    openFile(f);
}

void MainWindow::updateControls()
{
    ui->startXDoubleSpinBox->setValue(ui->lSystemView->lsystem.startX);
    ui->startYDoubleSpinBox->setValue(ui->lSystemView->lsystem.startY);
    ui->startRotationSpinBox->setValue(ui->lSystemView->lsystem.startRot);
    ui->iterationsSpinBox->setValue(ui->lSystemView->lsystem.iterations);
    ui->stepSpinBox->setValue(ui->lSystemView->lsystem.stepLength);
    ui->backgroundWidget->setValue(ui->lSystemView->lsystem.backgroundColor);
    ui->foregroundWidget->setValue(ui->lSystemView->lsystem.foregroundColor);
}
<|endoftext|>