<commit_before>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "perfetto/base/string_utils.h"

#include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

bool StartsWith(const std::string& str, const std::string& prefix) {
  return str.compare(0, prefix.length(), prefix) == 0;
}

bool EndsWith(const std::string& str, const std::string& suffix) {
  if (suffix.size() > str.size())
    return false;
  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

bool Contains(const std::string& haystack, const std::string& needle) {
  return haystack.find(needle) != std::string::npos;
}

std::string Join(const std::vector<std::string>& parts,
                 const std::string& delim) {
  std::string acc;
  for (size_t i = 0; i < parts.size(); ++i) {
    acc += parts[i];
    if (i + 1 != parts.size()) {
      acc += delim;
    }
  }
  return acc;
}

std::vector<std::string> SplitString(const std::string& text,
                                     const std::string& delimiter) {
  PERFETTO_CHECK(!delimiter.empty());

  std::vector<std::string> output;
  size_t start = 0;
  size_t next;
  for (;;) {
    next = std::min(text.find(delimiter, start), text.size());
    output.emplace_back(&text[start], next - start);
    start = next + delimiter.size();
    if (start >= text.size())
      break;
  }
  return output;
}

}  // namespace base
}  // namespace perfetto
<commit_msg>base: fix header include for std::min am: e579620e91 am: ddff721725<commit_after>/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "perfetto/base/string_utils.h"

#include <algorithm>

#include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

bool StartsWith(const std::string& str, const std::string& prefix) {
  return str.compare(0, prefix.length(), prefix) == 0;
}

bool EndsWith(const std::string& str, const std::string& suffix) {
  if (suffix.size() > str.size())
    return false;
  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

bool Contains(const std::string& haystack, const std::string& needle) {
  return haystack.find(needle) != std::string::npos;
}

std::string Join(const std::vector<std::string>& parts,
                 const std::string& delim) {
  std::string acc;
  for (size_t i = 0; i < parts.size(); ++i) {
    acc += parts[i];
    if (i + 1 != parts.size()) {
      acc += delim;
    }
  }
  return acc;
}

std::vector<std::string> SplitString(const std::string& text,
                                     const std::string& delimiter) {
  PERFETTO_CHECK(!delimiter.empty());

  std::vector<std::string> output;
  size_t start = 0;
  size_t next;
  for (;;) {
    next = std::min(text.find(delimiter, start), text.size());
    output.emplace_back(&text[start], next - start);
    start = next + delimiter.size();
    if (start >= text.size())
      break;
  }
  return output;
}

}  // namespace base
}  // namespace perfetto
<|endoftext|>


<commit_before>// Copyright 2010-2013 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "base/stringprintf.h"

#include <cstdarg>
#include <cstdio>

#include <string>

namespace operations_research {

void StringAppendV(std::string* const dst, const char* const format, va_list ap) {
  // First try with a small fixed size buffer
  char space[1024];

  // It's possible for methods that use a va_list to invalidate
  // the data in it upon use.  The fix is to make a copy
  // of the structure before using it and use that copy instead.
  va_list backup_ap;
#if defined(_MSC_VER)
  backup_ap = ap;
#else
  va_copy(backup_ap, ap);
#endif
  int result = vsnprintf(space, sizeof(space), format, backup_ap);
  va_end(backup_ap);

  if ((result >= 0) && (result < sizeof(space))) {
    // It fit
    dst->append(space, result);
    return;
  }

  // Repeatedly increase buffer size until it fits
  int length = sizeof(space);
  while (true) {
    if (result < 0) {
      // Older behavior: just try doubling the buffer size
      length *= 2;
    } else {
      // We need exactly "result+1" characters
      length = result + 1;
    }
    char* const buf = new char[length];

// Restore the va_list before we use it again
#if defined(_MSC_VER)
    backup_ap = ap;
#else
    va_copy(backup_ap, ap);
#endif
    result = vsnprintf(buf, length, format, backup_ap);
    va_end(backup_ap);

    if ((result >= 0) && (result < length)) {
      // It fit
      dst->append(buf, result);
      delete[] buf;
      return;
    }
    delete[] buf;
  }
}

std::string StringPrintf(const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  std::string result;
  StringAppendV(&result, format, ap);
  va_end(ap);
  return result;
}

void SStringPrintf(std::string* const dst, const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  dst->clear();
  StringAppendV(dst, format, ap);
  va_end(ap);
}

void StringAppendF(std::string* const dst, const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  StringAppendV(dst, format, ap);
  va_end(ap);
}
}  // namespace operations_research
<commit_msg>backup implementation of va_copy<commit_after>// Copyright 2010-2013 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "base/stringprintf.h"

#include <cstdarg>
#include <cstdio>

#include <string>

#if !defined(_MSC_VER)
#ifndef va_copy
# ifdef __va_copy
# define va_copy(d, s) __va_copy((d), (s))
# else
# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
# endif
#endif
#endif

namespace operations_research {

void StringAppendV(std::string* const dst, const char* const format, va_list ap) {
  // First try with a small fixed size buffer
  char space[1024];

  // It's possible for methods that use a va_list to invalidate
  // the data in it upon use.  The fix is to make a copy
  // of the structure before using it and use that copy instead.
  va_list backup_ap;
#if defined(_MSC_VER)
  backup_ap = ap;
#else
  va_copy(backup_ap, ap);
#endif
  int result = vsnprintf(space, sizeof(space), format, backup_ap);
  va_end(backup_ap);

  if ((result >= 0) && (result < sizeof(space))) {
    // It fit
    dst->append(space, result);
    return;
  }

  // Repeatedly increase buffer size until it fits
  int length = sizeof(space);
  while (true) {
    if (result < 0) {
      // Older behavior: just try doubling the buffer size
      length *= 2;
    } else {
      // We need exactly "result+1" characters
      length = result + 1;
    }
    char* const buf = new char[length];

// Restore the va_list before we use it again
#if defined(_MSC_VER)
    backup_ap = ap;
#else
    va_copy(backup_ap, ap);
#endif
    result = vsnprintf(buf, length, format, backup_ap);
    va_end(backup_ap);

    if ((result >= 0) && (result < length)) {
      // It fit
      dst->append(buf, result);
      delete[] buf;
      return;
    }
    delete[] buf;
  }
}

std::string StringPrintf(const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  std::string result;
  StringAppendV(&result, format, ap);
  va_end(ap);
  return result;
}

void SStringPrintf(std::string* const dst, const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  dst->clear();
  StringAppendV(dst, format, ap);
  va_end(ap);
}

void StringAppendF(std::string* const dst, const char* const format, ...) {
  va_list ap;
  va_start(ap, format);
  StringAppendV(dst, format, ap);
  va_end(ap);
}
}  // namespace operations_research
<|endoftext|>


<commit_before>#include "nanocv/tensor.h"
#include "nanocv/string.h"
#include "nanocv/tabulator.h"
#include "nanocv/measure.hpp"
#include "nanocv/math/conv2d.hpp"
#include <iostream>

using namespace ncv;

const size_t trials = 16;

template
<
        typename top,
        typename tmatrix,
        typename tscalar = typename tmatrix::Scalar
>
static void test_cpu(tabulator_t::row_t& row, top op, const tmatrix& idata, const tmatrix& kdata, tmatrix& odata)
{
        row << ncv::measure_robustly_usec([&] ()
        {
                odata.setZero();
                op(idata, kdata, odata);
        }, trials);
}

void test_conv2d(tabulator_t::row_t& row, int isize, int ksize)
{
        const int osize = isize - ksize + 1;

        matrix_t idata(isize, isize);
        matrix_t kdata(ksize, ksize);
        matrix_t odata(osize, osize);

        idata.setRandom();
        kdata.setRandom();
        odata.setRandom();

        idata /= isize;
        kdata /= ksize;
        odata /= osize;

        test_cpu(row, ncv::math::conv2d_eig<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_cpp<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_dot<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_mad<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_dyn<matrix_t>, idata, kdata, odata);
}

int main(int, char* [])
{
        const int min_isize = 12;
        const int max_isize = 48;
        const int min_ksize = 3;

        tabulator_t table("size\\method");
        table.header() << "eig [us]"
                        << "cpp [us]"
                        << "dot [us]"
                        << "mad [us]"
                        << "dyn [us]"
                        << "toe [us]"
                        << "toe (buff) [us]";

        for (int isize = min_isize; isize <= max_isize; isize += 4)
        {
                table.clear();

                for (int ksize = min_ksize; ksize <= isize - min_ksize; ksize += 2)
                {
                        const string_t header = "(" +
                                text::to_string(isize) + "x" + text::to_string(isize) + "@" +
                                text::to_string(ksize) + "x" + text::to_string(ksize) + ")";

                        tabulator_t::row_t& row = table.append(header);

                        test_conv2d(row, isize, ksize);
                }

                table.print(std::cout);

                std::cout << std::endl;
        }

	return EXIT_SUCCESS;
}

<commit_msg>fix header<commit_after>#include "nanocv/tensor.h"
#include "nanocv/string.h"
#include "nanocv/tabulator.h"
#include "nanocv/measure.hpp"
#include "nanocv/math/conv2d.hpp"
#include <iostream>

using namespace ncv;

const size_t trials = 16;

template
<
        typename top,
        typename tmatrix,
        typename tscalar = typename tmatrix::Scalar
>
static void test_cpu(tabulator_t::row_t& row, top op, const tmatrix& idata, const tmatrix& kdata, tmatrix& odata)
{
        row << ncv::measure_robustly_usec([&] ()
        {
                odata.setZero();
                op(idata, kdata, odata);
        }, trials);
}

void test_conv2d(tabulator_t::row_t& row, int isize, int ksize)
{
        const int osize = isize - ksize + 1;

        matrix_t idata(isize, isize);
        matrix_t kdata(ksize, ksize);
        matrix_t odata(osize, osize);

        idata.setRandom();
        kdata.setRandom();
        odata.setRandom();

        idata /= isize;
        kdata /= ksize;
        odata /= osize;

        test_cpu(row, ncv::math::conv2d_eig<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_cpp<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_dot<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_mad<matrix_t>, idata, kdata, odata);
        test_cpu(row, ncv::math::conv2d_dyn<matrix_t>, idata, kdata, odata);
}

int main(int, char* [])
{
        const int min_isize = 12;
        const int max_isize = 48;
        const int min_ksize = 3;

        tabulator_t table("size\\method");
        table.header() << "eig [us]"
                        << "cpp [us]"
                        << "dot [us]"
                        << "mad [us]"
                        << "dyn [us]";

        for (int isize = min_isize; isize <= max_isize; isize += 4)
        {
                table.clear();

                for (int ksize = min_ksize; ksize <= isize - min_ksize; ksize += 2)
                {
                        const string_t header = "(" +
                                text::to_string(isize) + "x" + text::to_string(isize) + "@" +
                                text::to_string(ksize) + "x" + text::to_string(ksize) + ")";

                        tabulator_t::row_t& row = table.append(header);

                        test_conv2d(row, isize, ksize);
                }

                table.print(std::cout);

                std::cout << std::endl;
        }

	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*

    Graphics File Loader: a test program for csgfxldr library
    Copyright (C) 2000 Andrew Zabolotny <bit@eltech.ru>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#define SYSDEF_PATH
#define SYSDEF_GETOPT
#include "sysdef.h"
#include "csgfxldr/csimage.h"
#include "csgfxldr/pngsave.h"

#include <string.h>

char *programversion = "0.0.1";
char *programname;

/*

  NOTE: If your Losing Operating System {tm} (R) does not have getopt_long,
  please use the one in support/gnu instead. Please don't comment out blocks
  of code, dont #ifdef and so on. It is ugly.

*/

static struct option long_options[] =
{
  {"help", no_argument, 0, 'h'},
  {"display", optional_argument, 0, 'd'},
  {"scale", required_argument, 0, 's'},
  {"mipmap", required_argument, 0, 'm'},
  {"transp", required_argument, 0, 't'},
  {"paletted", no_argument, 0, '8'},
  {"verbose", no_argument, 0, 'v'},
  {"version", no_argument, 0, 'V'},
  {0, no_argument, 0, 0}
};

static struct
{
  bool verbose;
  bool save;
  bool display;
  bool paletted;
  int scaleX, scaleY;
  int displayW, displayH;
  int mipmap;
  bool transp;
  RGBPixel transpcolor;
} opt;

static int display_help ()
{
  printf ("Crystal Space Graphics File Loader test application v%s\n", programversion);
  printf ("Copyright (C) 2000 Andrew Zabolotny\n\n");
  printf ("Usage: %s {option/s} [image file] [...]\n\n", programname);
  printf ("  -d   --display{=#,#} Display the image in ASCII format :-)\n");
  printf ("  -s   --scale=#,#     Re-scale the image to given size #\n");
  printf ("  -m   --mipmap=#      Create mipmap level # (=0,1,2,3) from image\n");
  printf ("  -t   --transp=#,#,#  Treat color (R,G,B) as transparent\n");
  printf ("  -8   --paletted      Load/handle/save image in paletted format\n");
  printf ("  -h   --help          Display this help text\n");
  printf ("  -v   --verbose       Comment on what's happening\n");
  printf ("  -V   --version       Display program version\n");
  return 1;
}

#if 0
// PNM is a very simple format that is handy for quick-and-dirty programs.
// Many image processing programs understands it...
static bool SavePNM (const char *fname, void *image, int w, int h, bool rgb)
{
  FILE *f = fopen (fname, "wb");
  if (!f)
  {
    fprintf (stderr, "%s: cannot open output file %s\n", programname, fname);
    return false;
  }
  char header [100];
  sprintf (header, "P%c\n%d %d\n%d\n", rgb ? '6' : '5', w, h, 255);
  fwrite (header, 1, strlen (header), f);
  if (rgb)
    for (int i = w * h; i > 0; i--)
    {
      fwrite (image, 1, 3, f);
      image = ((RGBPixel *)image) + 1;
    }
  else
    fwrite (image, 1, w * h, f);
  fclose (f);
  return true;
}
#endif

static bool process_file (const char *fname)
{
  printf ("Loading file %s\n", fname);

  FILE *f = fopen (fname, "rb");
  if (!f)
  {
    printf ("%s: cannot open file %s\n", programname, fname);
    return false;
  }

  fseek (f, 0, SEEK_END);
  size_t fsize = ftell (f);
  fseek (f, 0, SEEK_SET);

  if (opt.verbose)
    printf ("Reading %ld bytes from file\n", fsize);

  UByte *buffer = new UByte [fsize];
  if (fread (buffer, 1, fsize, f) < fsize)
  {
    printf ("%s: unexpected EOF while reading file %s\n", programname, fname);
    return false;
  }

  fclose (f);

  iImage *ifile = csImageLoader::Load (buffer, fsize,
    opt.paletted ? CS_IMGFMT_PALETTED8 : CS_IMGFMT_TRUECOLOR);
  delete [] buffer;
  if (!ifile)
  {
    printf ("%s: failed to recognise image format for %s\n", programname, fname);
    return false;
  }

  if (opt.verbose)
  {
    printf ("Image size: %d x %d pixels, %d bytes\n", ifile->GetWidth (),
      ifile->GetHeight (), ifile->GetSize ());
    int fmt = ifile->GetFormat ();
    printf ("Image format: %s, alpha channel: %s\n",
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_NONE ? "none" :
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_PALETTED8 ? "paletted, 256 colors" :
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_TRUECOLOR ? "truecolor" : "unknown",
      (fmt & CS_IMGFMT_ALPHA) ? "present" : "not present");
  }

  char suffix [20];
  suffix [0] = 0;

  if (opt.scaleX > 0 && opt.scaleY > 0)
  {
    printf ("Rescaling image to %d x %d\n", opt.scaleX, opt.scaleY);
    ifile->Resize (opt.scaleX, opt.scaleY);
    sprintf (strchr (suffix, 0), "-s%dx%d", opt.scaleX, opt.scaleY);
  }

  if (opt.mipmap >= 0)
  {
    printf ("Creating mipmap level %d from image\n", opt.mipmap);
    iImage *ifile2 = ifile->MipMap (opt.mipmap,
      opt.transp ? &opt.transpcolor : NULL);
    ifile->DecRef ();
    ifile = ifile2;
    sprintf (strchr (suffix, 0), "-m%d", opt.mipmap);
  }

  if (opt.save)
  {
    char outname [MAXPATHLEN + 1];
    strcpy (outname, fname);
    char *eol = strchr (outname, 0);
    while (eol > outname && *eol != '.') eol--;
    if (eol == outname) eol = strchr (outname, 0);
    strcpy (eol, suffix);
    strcat (eol, ".png");
    printf ("Saving output file %s\n", outname);

#if 1
    if (!csSavePNG (outname, ifile))
      return false;
#else
    if (!SavePNM (outname, ifile->GetImageData (), ifile->GetWidth (), ifile->GetHeight (),
         (ifile->GetFormat () & CS_IMGFMT_MASK) == CS_IMGFMT_TRUECOLOR))
      return false;
#endif
  }

  // Destroy the image object
  ifile->DecRef ();

  return true;
}

static void init_opts()
{
  opt.verbose = false;
  opt.save = true;
  opt.display = false;
  opt.paletted = false;
  opt.scaleX = 0;
  opt.scaleY = 0;
  opt.displayW = 80;
  opt.displayH = 24;
  opt.mipmap = -1;
  opt.transp = false;
}

int main (int argc, char **argv)
{
#if defined (__EMX__)	// Expand wildcards on OS/2+GCC+EMX
  _wildcard (&argc, &argv);
#endif

  init_opts();
  programname = argv [0];

  int c;
  while ((c = getopt_long (argc, argv, "8d::s:m:t:hvV", long_options, NULL)) != EOF)
    switch (c)
    {
      case '?':
        // unknown option
        return -1;
      case '8':
        opt.paletted = true;
        break;
      case 'd':
        opt.save = false;
        opt.display = true;
        if (optarg &&
            sscanf (optarg, "%d,%d", &opt.displayW, &opt.displayH) != 2)
        {
          printf ("%s: expecting <width>,<height> after -d\n", programname);
          return -1;
        }
        break;
      case 's':
        if (sscanf (optarg, "%d,%d", &opt.scaleX, &opt.scaleY) != 2)
        {
          printf ("%s: expecting <width>,<height> after -s\n", programname);
          return -1;
        }
        break;
      case 't':
      {
        opt.transp = true;
        int r,g,b;
        if (sscanf (optarg, "%d,%d,%d", &r, &g, &b) != 3)
        {
          printf ("%s: expecting <R>,<G>,<B> after -t\n", programname);
          return -1;
        }
        opt.transpcolor.red   = r > 255 ? 255 : r < 0 ? 0 : r;
        opt.transpcolor.green = g > 255 ? 255 : g < 0 ? 0 : g;
        opt.transpcolor.blue  = b > 255 ? 255 : b < 0 ? 0 : b;
        break;
      }
      case 'm':
        if (sscanf (optarg, "%d", &opt.mipmap) != 1)
        {
          printf ("%s: expecting <mipmap level> which is one of 0,1,2,3 after -m\n", programname);
          return -1;
        }
        if (opt.mipmap < 0 || opt.mipmap > 3)
        {
          printf ("%s: bad mipmap level (%d): should be one of 0,1,2,3\n", programname, opt.mipmap);
          return -1;
        }
        break;
      case 'h':
        return display_help ();
      case 'v':
        opt.verbose = true;
        break;
      case 'V':
        printf ("%s version %s\n\n", programname, programversion);
        printf ("This program is distributed in the hope that it will be useful,\n");
        printf ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
        printf ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
        printf ("GNU Library General Public License for more details.\n");
        return 0;
    } /* endswitch */

  if (optind >= argc)
    return display_help ();

  for (; optind < argc; ++optind)
    if (!process_file (argv [optind]))
      return -1;

  return 0;
}
<commit_msg>Implemented a cool Ascii-Art {R} {tm} display. -d or --display options. Default size 79x24, you can enlarge for more pleasant results if you use a larger console (with -d79,40 for example)<commit_after>/*

    Graphics File Loader: a test program for csgfxldr library
    Copyright (C) 2000 Andrew Zabolotny <bit@eltech.ru>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#define SYSDEF_PATH
#define SYSDEF_GETOPT
#include "sysdef.h"
#include "csgfxldr/csimage.h"
#include "csgfxldr/pngsave.h"

#include <string.h>

char *programversion = "0.0.1";
char *programname;

/*

  NOTE: If your Losing Operating System {tm} (R) does not have getopt_long,
  please use the one in support/gnu instead. Please don't comment out blocks
  of code, dont #ifdef and so on. It is ugly.

*/

static struct option long_options[] =
{
  {"help", no_argument, 0, 'h'},
  {"display", optional_argument, 0, 'd'},
  {"scale", required_argument, 0, 's'},
  {"mipmap", required_argument, 0, 'm'},
  {"transp", required_argument, 0, 't'},
  {"paletted", no_argument, 0, '8'},
  {"verbose", no_argument, 0, 'v'},
  {"version", no_argument, 0, 'V'},
  {0, no_argument, 0, 0}
};

static struct
{
  bool verbose;
  bool save;
  bool display;
  bool paletted;
  int scaleX, scaleY;
  int displayW, displayH;
  int mipmap;
  bool transp;
} opt =
{
  false,
  true,
  false,
  false,
  0, 0,
  79, 24,
  -1,
  false
};
// Dont move inside the struct!
static RGBPixel transpcolor;

static int display_help ()
{
  printf ("Crystal Space Graphics File Loader test application v%s\n", programversion);
  printf ("Copyright (C) 2000 Andrew Zabolotny\n\n");
  printf ("Usage: %s {option/s} [image file] [...]\n\n", programname);
  printf ("  -d   --display{=#,#} Display the image in ASCII format :-)\n");
  printf ("  -s   --scale=#,#     Re-scale the image to given size #\n");
  printf ("  -m   --mipmap=#      Create mipmap level # (=0,1,2,3) from image\n");
  printf ("  -t   --transp=#,#,#  Treat color (R,G,B) as transparent\n");
  printf ("  -8   --paletted      Load/handle/save image in paletted format\n");
  printf ("  -h   --help          Display this help text\n");
  printf ("  -v   --verbose       Comment on what's happening\n");
  printf ("  -V   --version       Display program version\n");
  return 1;
}

#if 0
// PNM is a very simple format that is handy for quick-and-dirty programs.
// Many image processing programs understands it...
static bool SavePNM (const char *fname, void *image, int w, int h, bool rgb)
{
  FILE *f = fopen (fname, "wb");
  if (!f)
  {
    fprintf (stderr, "%s: cannot open output file %s\n", programname, fname);
    return false;
  }
  char header [100];
  sprintf (header, "P%c\n%d %d\n%d\n", rgb ? '6' : '5', w, h, 255);
  fwrite (header, 1, strlen (header), f);
  if (rgb)
    for (int i = w * h; i > 0; i--)
    {
      fwrite (image, 1, 3, f);
      image = ((RGBPixel *)image) + 1;
    }
  else
    fwrite (image, 1, w * h, f);
  fclose (f);
  return true;
}
#endif

static bool process_file (const char *fname)
{
  printf ("Loading file %s\n", fname);

  FILE *f = fopen (fname, "rb");
  if (!f)
  {
    printf ("%s: cannot open file %s\n", programname, fname);
    return false;
  }

  fseek (f, 0, SEEK_END);
  size_t fsize = ftell (f);
  fseek (f, 0, SEEK_SET);

  if (opt.verbose)
    printf ("Reading %ld bytes from file\n", fsize);

  UByte *buffer = new UByte [fsize];
  if (fread (buffer, 1, fsize, f) < fsize)
  {
    printf ("%s: unexpected EOF while reading file %s\n", programname, fname);
    return false;
  }

  fclose (f);

  iImage *ifile = csImageLoader::Load (buffer, fsize,
    opt.paletted ? CS_IMGFMT_PALETTED8 : CS_IMGFMT_TRUECOLOR);
  delete [] buffer;
  if (!ifile)
  {
    printf ("%s: failed to recognise image format for %s\n", programname, fname);
    return false;
  }

  if (opt.verbose)
  {
    printf ("Image size: %d x %d pixels, %d bytes\n", ifile->GetWidth (),
      ifile->GetHeight (), ifile->GetSize ());
    int fmt = ifile->GetFormat ();
    printf ("Image format: %s, alpha channel: %s\n",
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_NONE ? "none" :
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_PALETTED8 ? "paletted, 256 colors" :
      (fmt & CS_IMGFMT_MASK) == CS_IMGFMT_TRUECOLOR ? "truecolor" : "unknown",
      (fmt & CS_IMGFMT_ALPHA) ? "present" : "not present");
  }

  char suffix [20];
  suffix [0] = 0;

  if (opt.scaleX > 0 && opt.scaleY > 0)
  {
    printf ("Rescaling image to %d x %d\n", opt.scaleX, opt.scaleY);
    ifile->Resize (opt.scaleX, opt.scaleY);
    sprintf (strchr (suffix, 0), "-s%dx%d", opt.scaleX, opt.scaleY);
  }

  if (opt.mipmap >= 0)
  {
    printf ("Creating mipmap level %d from image\n", opt.mipmap);
    iImage *ifile2 = ifile->MipMap (opt.mipmap,
      opt.transp ? &transpcolor : NULL);
    ifile->DecRef ();
    ifile = ifile2;
    sprintf (strchr (suffix, 0), "-m%d", opt.mipmap);
  }

  if (opt.save)
  {
    char outname [MAXPATHLEN + 1];
    strcpy (outname, fname);
    char *eol = strchr (outname, 0);
    while (eol > outname && *eol != '.') eol--;
    if (eol == outname) eol = strchr (outname, 0);
    strcpy (eol, suffix);
    strcat (eol, ".png");
    printf ("Saving output file %s\n", outname);

#if 1
    if (!csSavePNG (outname, ifile))
      return false;
#else
    if (!SavePNM (outname, ifile->GetImageData (), ifile->GetWidth (), ifile->GetHeight (),
         (ifile->GetFormat () & CS_IMGFMT_MASK) == CS_IMGFMT_TRUECOLOR))
      return false;
#endif
  }

  if (opt.display)
  {
    static char imgchr [] = " .,;+*oO";
    ifile->Resize (opt.displayW, opt.displayH);
    RGBPixel *rgb;
    UByte *idx = NULL;
    bool truecolor = (ifile->GetFormat () & CS_IMGFMT_MASK) == CS_IMGFMT_TRUECOLOR;
    if (truecolor)
      rgb = (RGBPixel *)ifile->GetImageData ();
    else
    {
      idx = (UByte *)ifile->GetImageData ();
      rgb = ifile->GetPalette ();
    }
    for (int y = 0; y < opt.displayH; y++)
    {
      for (int x = 0; x < opt.displayW; x++)
      {
        RGBPixel &src = truecolor ? *rgb++ : rgb [*idx++];
        int gray = int (sqrt (src.red * src.red + src.green * src.green +
          src.blue * src.blue) * 8 / 442);
        putc (imgchr [gray], stdout);
      }
      putc ('\n', stdout);
    }
  }

  // Destroy the image object
  ifile->DecRef ();

  return true;
}

int main (int argc, char **argv)
{
#if defined (__EMX__)	// Expand wildcards on OS/2+GCC+EMX
  _wildcard (&argc, &argv);
#endif

  programname = argv [0];

  int c;
  while ((c = getopt_long (argc, argv, "8d::s:m:t:hvV", long_options, NULL)) != EOF)
    switch (c)
    {
      case '?':
        // unknown option
        return -1;
      case '8':
        opt.paletted = true;
        break;
      case 'd':
        opt.save = false;
        opt.display = true;
        if (optarg &&
            sscanf (optarg, "%d,%d", &opt.displayW, &opt.displayH) != 2)
        {
          printf ("%s: expecting <width>,<height> after -d\n", programname);
          return -1;
        }
        break;
      case 's':
        if (sscanf (optarg, "%d,%d", &opt.scaleX, &opt.scaleY) != 2)
        {
          printf ("%s: expecting <width>,<height> after -s\n", programname);
          return -1;
        }
        break;
      case 't':
      {
        opt.transp = true;
        int r,g,b;
        if (sscanf (optarg, "%d,%d,%d", &r, &g, &b) != 3)
        {
          printf ("%s: expecting <R>,<G>,<B> after -t\n", programname);
          return -1;
        }
        transpcolor.red   = r > 255 ? 255 : r < 0 ? 0 : r;
        transpcolor.green = g > 255 ? 255 : g < 0 ? 0 : g;
        transpcolor.blue  = b > 255 ? 255 : b < 0 ? 0 : b;
        break;
      }
      case 'm':
        if (sscanf (optarg, "%d", &opt.mipmap) != 1)
        {
          printf ("%s: expecting <mipmap level> which is one of 0,1,2,3 after -m\n", programname);
          return -1;
        }
        if (opt.mipmap < 0 || opt.mipmap > 3)
        {
          printf ("%s: bad mipmap level (%d): should be one of 0,1,2,3\n", programname, opt.mipmap);
          return -1;
        }
        break;
      case 'h':
        return display_help ();
      case 'v':
        opt.verbose = true;
        break;
      case 'V':
        printf ("%s version %s\n\n", programname, programversion);
        printf ("This program is distributed in the hope that it will be useful,\n");
        printf ("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
        printf ("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
        printf ("GNU Library General Public License for more details.\n");
        return 0;
    } /* endswitch */

  if (optind >= argc)
    return display_help ();

  for (; optind < argc; ++optind)
    if (!process_file (argv [optind]))
      return -1;

  return 0;
}
<|endoftext|>


<commit_before>#include "../lang/lang.h"
#include "../configurator/configurator.h"
#include "../windlg/windlg.h"
#include "../libscreen/libscreen.h"
#include "apps_starter.h"

int app_start(int number_of_app, const char* parametrs) {
	std::string full_path = configurator(APPS_FILE, str(number_of_app) + "_app_path", "", false) + "/" + configurator(APPS_FILE, str(number_of_app) + "_app_launcher", "", false);

	erase();
	endwin();

	int		status;
	pid_t	chpid	= fork();

	if (chpid == 0) {
		if (execl(full_path.c_str(), parametrs, NULL) == -1) // parent process
			exit(0);
	} else {
		waitpid(chpid,&status,WUNTRACED);
		init_display();
	}
	return 0;
}<commit_msg>libscreen->screen<commit_after>#include "../lang/lang.h"
#include "../configurator/configurator.h"
#include "../windlg/windlg.h"
#include "../screen/screen.h"
#include "apps_starter.h"

int app_start(int number_of_app, const char* parametrs) {
	std::string full_path = configurator(APPS_FILE, str(number_of_app) + "_app_path", "", false) + "/" + configurator(APPS_FILE, str(number_of_app) + "_app_launcher", "", false);

	erase();
	endwin();

	int		status;
	pid_t	chpid	= fork();

	if (chpid == 0) {
		if (execl(full_path.c_str(), parametrs, NULL) == -1) // parent process
			exit(0);
	} else {
		waitpid(chpid,&status,WUNTRACED);
		init_display();
	}
	return 0;
}<|endoftext|>


<commit_before>/* bzflag
* Copyright (c) 1993-2010 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "common.h"

/* system headers */
#include <string>
#include <vector>
#include <map>

/* common headers */
#include "bzfio.h"
#include "version.h"
#include "TextUtils.h"
#include "commands.h"
#include "bzfsAPI.h"
#include "DirectoryNames.h"

#include "WorldEventManager.h"

#ifdef _WIN32
std::string extension = ".dll";
std::string globalPluginDir = ".\\plugins\\";
#else
std::string extension = ".so";
std::string globalPluginDir = INSTALL_LIB_DIR;
#endif

typedef std::map<std::string, bz_APIPluginHandler*> tmCustomPluginMap;
tmCustomPluginMap customPluginMap;

typedef struct
{
	std::string name;
	std::string filename;
	bz_Plugin* plugin;
#ifdef _WIN32
	HINSTANCE	handle;
#else
	void*		handle;
#endif
}trPluginRecord;

std::string findPlugin ( std::string pluginName )
{
  // see if we can just open the bloody thing
  FILE	*fp = fopen(pluginName.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return pluginName;
  }

  // now try it with the standard extension
  std::string name = pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  // check the local users plugins dir
  name = getConfigDirName(BZ_CONFIG_DIR_VERSION) + pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  // check the global plugins dir
  name = globalPluginDir + pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  return std::string("");
}

std::vector<trPluginRecord>	vPluginList;

void unload1Plugin ( int iPluginID );

bool PluginExists ( const char* n )
{
  std::string name = n;

  std::vector<trPluginRecord>::iterator itr = vPluginList.begin();
  while ( itr != vPluginList.end())
  {
    if (itr->name == name)
      return true;
    itr++;
  }
  return false;
}

bz_Plugin* getPlugin( const char* n )
{
  std::string name = n;

  std::vector<trPluginRecord>::iterator itr = vPluginList.begin();
  while ( itr != vPluginList.end())
  {
    if (itr->name == name)
      return itr->plugin;
    itr++;
  }
  return NULL;
}

#ifdef _WIN32
#  include <windows.h>

int getPluginVersion ( HINSTANCE hLib )
{
  int (*lpProc)(void);
  lpProc = (int (__cdecl *)(void))GetProcAddress(hLib, "bz_GetMinVersion");
  if (lpProc)
	  return lpProc();
  return 0;
}

bool load1Plugin ( std::string plugin, std::string config )
{
	bz_Plugin* (*lpProc)(void);

	std::string realPluginName = findPlugin(plugin);

	HINSTANCE	hLib = LoadLibrary(realPluginName.c_str());
	if (hLib)
	{
		if (getPluginVersion(hLib) > BZ_API_VERSION)
		{
			logDebugMessage(1,"Plugin: %s found but needs a newer API version (%d), upgrade server\n",plugin.c_str(),getPluginVersion(hLib));
			FreeLibrary(hLib);
			return false;
		}
		else
		{
			lpProc = (bz_Plugin* (__cdecl *)(void))GetProcAddress(hLib, "bz_GetPlugin");
			if (lpProc)
			{
				bz_Plugin* p = lpProc();
				if (!p)
				  return false;

				std::string name  = p->Name();
				if (PluginExists(name.c_str()))
				{
				  FreeLibrary(hLib);
				  return false;
				}

				trPluginRecord pluginRecord;
				pluginRecord.name = name;
				pluginRecord.handle = hLib;
				pluginRecord.plugin = p;
				pluginRecord.filename = plugin;
				vPluginList.push_back(pluginRecord);

				p->Init(config.c_str());

				bz_PluginLoadUnloadEventData_V1 evt;
				evt.plugin = p;
				evt.eventType = bz_ePluginLoaded;
				worldEventManager.callEvents(&evt);

				logDebugMessage(1,"Plugin: %s loaded from %s\n",pluginRecord.name.c_str(),plugin.c_str());
				bz_debugMessagef(4,"%s plugin loaded",pluginRecord.name.c_str());
				return true;
			}
			else
			{
				logDebugMessage(1,"Plugin: %s found but does not contain bz_GetPlugin method\n",plugin.c_str());
				FreeLibrary(hLib);
				return false;
			}
		}
	}
	else
	{
		logDebugMessage(1,"Plugin: %s not found\n",plugin.c_str());
		return false;
	}
}

void unload1Plugin ( int iPluginID )
{
	void (*lpProc)(bz_Plugin*);

	trPluginRecord &plugin = vPluginList[iPluginID];

	bz_PluginLoadUnloadEventData_V1 evt;
	evt.plugin = plugin.plugin;
	evt.eventType = bz_ePluginUnloaded;
	worldEventManager.callEvents(&evt);

	plugin.plugin->Cleanup();
	bz_debugMessagef(4,"%s plugin unloaded",plugin.plugin->Name());

	lpProc = (void (__cdecl *)(bz_Plugin*))GetProcAddress(plugin.handle, "bz_FreePlugin");
	if (lpProc)
	  lpProc(plugin.plugin);
	else
	  logDebugMessage(1,"Plugin: bz_FreePlugin method not used by number %d. Leaking memory.\n",iPluginID);

	FreeLibrary(plugin.handle);
	plugin.handle = NULL;
	plugin.plugin = NULL;
}
#else

#  include <dlfcn.h>
std::vector<void*>	vLibHandles;

int getPluginVersion ( void* hLib )
{
	int (*lpProc)(void);
	*(void**) &lpProc = dlsym(hLib,"bz_GetMinVersion");
	if (lpProc)
		return (*lpProc)();
	return 0;
}

bool load1Plugin ( std::string plugin, std::string config )
{
	bz_Plugin* (*lpProc)();

	std::string realPluginName = findPlugin(plugin);

	void *hLib = dlopen(realPluginName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
	if (hLib)
	{
		if (dlsym(hLib, "bz_GetPlugin") == NULL) {
			logDebugMessage(1,"Plugin: %s found but does not contain bz_Load method, error %s\n",plugin.c_str(),dlerror());
			dlclose(hLib);
			return false;
		}

		int version = getPluginVersion(hLib);
		if (version > BZ_API_VERSION)
		{
			logDebugMessage(1,"Plugin: %s found but needs a newer API version (%d), upgrade server\n",plugin.c_str(), version);
			dlclose(hLib);
			return false;
		}
		else
		{
			*(void**) &lpProc = dlsym(hLib,"bz_GetPlugin");
			if (lpProc)
			{
				bz_Plugin * p = (*lpProc)();
				if (!p)
				  return false;

				std::string name  = p->Name();
				if (PluginExists(name.c_str()))
				  return false;

				trPluginRecord pluginRecord;
				pluginRecord.handle = hLib;
				pluginRecord.name = name;
				pluginRecord.plugin = p;
				pluginRecord.filename = plugin;
				vPluginList.push_back(pluginRecord);
				logDebugMessage(1,"Plugin: %s loaded from %s\n",pluginRecord.name.c_str(),plugin.c_str());
				bz_debugMessagef(4,"%s plugin loaded",pluginRecord.name.c_str());

				p->Init(config.c_str());
				bz_PluginLoadUnloadEventData_V1 evt;
				evt.plugin = p;
				evt.eventType = bz_ePluginLoaded;
				worldEventManager.callEvents(&evt);
				return true;
			}
		}
	}
	else
	{
		logDebugMessage(1,"Plugin: %s not found, error %s\n",plugin.c_str(), dlerror());
		return false;
	}

	logDebugMessage(1,"Plugin: load1Plugin() coding error\n");
	return false;
}

void unload1Plugin ( int iPluginID )
{
	void (*lpProc)(bz_Plugin*);
	trPluginRecord &plugin = vPluginList[iPluginID];

	bz_PluginLoadUnloadEventData_V1 evt;
	evt.plugin = plugin.plugin;
	evt.eventType = bz_ePluginUnloaded;
	worldEventManager.callEvents(&evt);

	plugin.plugin->Cleanup();
	bz_debugMessagef(4,"%s plugin unloaded",plugin.plugin->Name());

	*(void**) &lpProc = dlsym(plugin.handle, "bz_FreePlugin");
	if (lpProc)
	  (*lpProc)(plugin.plugin);
	else
	  logDebugMessage(1,"Plugin: bz_FreePlugin method not used by number %d, error %s. Leaking memory.\n",iPluginID,dlerror());

	dlclose(plugin.handle);
	plugin.handle = NULL;
	plugin.plugin = NULL;
}
#endif

bool loadPlugin ( std::string plugin, std::string config )
{
  // check and see if it's an extension we have a handler for
  std::string ext;

  std::vector<std::string> parts = TextUtils::tokenize(plugin,std::string("."));
  ext = parts[parts.size()-1];

  tmCustomPluginMap::iterator itr = customPluginMap.find(TextUtils::tolower(ext));

  if (itr != customPluginMap.end() && itr->second)
  {
    bz_APIPluginHandler *handler = itr->second;
    return handler->APIPlugin(plugin,config);
  }
  else
  {
    return load1Plugin(plugin,config);
  }
}

bool unloadPlugin ( std::string plugin )
{
	// unload the first one of the name we find
	for (unsigned int i = 0; i < vPluginList.size();i++)
	{
		if ( vPluginList[i].name == plugin || vPluginList[i].filename == plugin )
		{
			unload1Plugin(i);
			vPluginList.erase(vPluginList.begin()+i);
			return true;
		}
	}
	return false;
}

void unloadPlugins ( void )
{
	for (unsigned int i = 0; i < vPluginList.size();i++)
		unload1Plugin(i);
	vPluginList.clear();

	removeCustomSlashCommand("loadplugin");
	removeCustomSlashCommand("unloadplugin");
	removeCustomSlashCommand("listplugins");
}

std::vector<std::string> getPluginList ( void )
{
  std::vector<std::string> plugins;
  for (unsigned int i = 0; i < vPluginList.size();i++)
    plugins.push_back(vPluginList[i].name);

  return plugins;
}

float getPluginMinWaitTime ( void )
{
  float maxTime = 1000.0;

  std::vector<std::string> plugins;
  for (unsigned int i = 0; i < vPluginList.size();i++)
  {
    if (vPluginList[i].plugin && vPluginList[i].plugin->MaxWaitTime < maxTime)
      maxTime = vPluginList[i].plugin->MaxWaitTime;
  }

  return maxTime;
}

void parseServerCommand(const char *message, int dstPlayerId);

class DynamicPluginCommands : public bz_CustomSlashCommandHandler
{
public:
	virtual ~DynamicPluginCommands(){};
	virtual bool SlashCommand ( int playerID, bz_ApiString _command, bz_ApiString _message, bz_APIStringList *params )
	{
		bz_BasePlayerRecord	record;

		std::string command = _command.c_str();
		std::string message = _message.c_str();

		bz_BasePlayerRecord	*p = bz_getPlayerByIndex(playerID);
		if (!p)
			return false;

		record = *p;

		bz_freePlayerRecord(p);

		// list dosn't need admin
		if ( TextUtils::tolower(command) == "listplugins" )
		{
			std::vector<std::string>	plugins = getPluginList();

			if (!plugins.size())
				bz_sendTextMessage(BZ_SERVER,playerID,"No Plug-ins loaded.");
			else
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-ins loaded:");

				for ( unsigned int i = 0; i < plugins.size(); i++)
					bz_sendTextMessage(BZ_SERVER,playerID,plugins[i].c_str());
			}
			return true;
		}

		if (!record.hasPerm("PLUGINS"))
		{
			bz_sendTextMessage(BZ_SERVER,playerID,"You do not have permission to (un)load plug-ins.");
			return true;
		}

		if ( TextUtils::tolower(command) == "loadplugin" )
		{
			if ( !params->size() )
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /loadplugin plug-in");
				return true;
			}

			std::vector<std::string> subparams = TextUtils::tokenize(message,std::string(","));

			std::string config;
			if ( subparams.size() >1)
				config = subparams[1];

			if (loadPlugin(subparams[0],config))
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in loaded.");
			else
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in load failed.");
			return true;
		}

		if ( TextUtils::tolower(command) == "unloadplugin" )
		{
			if ( !params->size() )
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /unloadplugin plug-in");
				return true;
			}

			if ( unloadPlugin(std::string(params->get(0).c_str())) )
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in unloaded.");

			return true;
		}
		return true;
	}
};

DynamicPluginCommands	command;

void initPlugins ( void )
{
	customPluginMap.clear();

	registerCustomSlashCommand("loadplugin",&command);
	registerCustomSlashCommand("unloadplugin",&command);
	registerCustomSlashCommand("listplugins",&command);
}

bool registerCustomPluginHandler ( std::string exte, bz_APIPluginHandler *handler )
{
	std::string ext = TextUtils::tolower(exte);
	customPluginMap[ext] = handler;
	return true;
}

bool removeCustomPluginHandler ( std::string ext, bz_APIPluginHandler *handler )
{
	tmCustomPluginMap::iterator itr = customPluginMap.find(TextUtils::tolower(ext));

	if (itr == customPluginMap.end() || itr->second != handler)
		return false;

	customPluginMap.erase(itr);
	return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>ignore wait times less then 0, we can't go back in time, that would be weird.<commit_after>/* bzflag
* Copyright (c) 1993-2010 Tim Riker
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "common.h"

/* system headers */
#include <string>
#include <vector>
#include <map>

/* common headers */
#include "bzfio.h"
#include "version.h"
#include "TextUtils.h"
#include "commands.h"
#include "bzfsAPI.h"
#include "DirectoryNames.h"

#include "WorldEventManager.h"

#ifdef _WIN32
std::string extension = ".dll";
std::string globalPluginDir = ".\\plugins\\";
#else
std::string extension = ".so";
std::string globalPluginDir = INSTALL_LIB_DIR;
#endif

typedef std::map<std::string, bz_APIPluginHandler*> tmCustomPluginMap;
tmCustomPluginMap customPluginMap;

typedef struct
{
	std::string name;
	std::string filename;
	bz_Plugin* plugin;
#ifdef _WIN32
	HINSTANCE	handle;
#else
	void*		handle;
#endif
}trPluginRecord;

std::string findPlugin ( std::string pluginName )
{
  // see if we can just open the bloody thing
  FILE	*fp = fopen(pluginName.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return pluginName;
  }

  // now try it with the standard extension
  std::string name = pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  // check the local users plugins dir
  name = getConfigDirName(BZ_CONFIG_DIR_VERSION) + pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  // check the global plugins dir
  name = globalPluginDir + pluginName + extension;
  fp = fopen(name.c_str(),"rb");
  if (fp)
  {
	  fclose(fp);
	  return name;
  }

  return std::string("");
}

std::vector<trPluginRecord>	vPluginList;

void unload1Plugin ( int iPluginID );

bool PluginExists ( const char* n )
{
  std::string name = n;

  std::vector<trPluginRecord>::iterator itr = vPluginList.begin();
  while ( itr != vPluginList.end())
  {
    if (itr->name == name)
      return true;
    itr++;
  }
  return false;
}

bz_Plugin* getPlugin( const char* n )
{
  std::string name = n;

  std::vector<trPluginRecord>::iterator itr = vPluginList.begin();
  while ( itr != vPluginList.end())
  {
    if (itr->name == name)
      return itr->plugin;
    itr++;
  }
  return NULL;
}

#ifdef _WIN32
#  include <windows.h>

int getPluginVersion ( HINSTANCE hLib )
{
  int (*lpProc)(void);
  lpProc = (int (__cdecl *)(void))GetProcAddress(hLib, "bz_GetMinVersion");
  if (lpProc)
	  return lpProc();
  return 0;
}

bool load1Plugin ( std::string plugin, std::string config )
{
	bz_Plugin* (*lpProc)(void);

	std::string realPluginName = findPlugin(plugin);

	HINSTANCE	hLib = LoadLibrary(realPluginName.c_str());
	if (hLib)
	{
		if (getPluginVersion(hLib) > BZ_API_VERSION)
		{
			logDebugMessage(1,"Plugin: %s found but needs a newer API version (%d), upgrade server\n",plugin.c_str(),getPluginVersion(hLib));
			FreeLibrary(hLib);
			return false;
		}
		else
		{
			lpProc = (bz_Plugin* (__cdecl *)(void))GetProcAddress(hLib, "bz_GetPlugin");
			if (lpProc)
			{
				bz_Plugin* p = lpProc();
				if (!p)
				  return false;

				std::string name  = p->Name();
				if (PluginExists(name.c_str()))
				{
				  FreeLibrary(hLib);
				  return false;
				}

				trPluginRecord pluginRecord;
				pluginRecord.name = name;
				pluginRecord.handle = hLib;
				pluginRecord.plugin = p;
				pluginRecord.filename = plugin;
				vPluginList.push_back(pluginRecord);

				p->Init(config.c_str());

				bz_PluginLoadUnloadEventData_V1 evt;
				evt.plugin = p;
				evt.eventType = bz_ePluginLoaded;
				worldEventManager.callEvents(&evt);

				logDebugMessage(1,"Plugin: %s loaded from %s\n",pluginRecord.name.c_str(),plugin.c_str());
				bz_debugMessagef(4,"%s plugin loaded",pluginRecord.name.c_str());
				return true;
			}
			else
			{
				logDebugMessage(1,"Plugin: %s found but does not contain bz_GetPlugin method\n",plugin.c_str());
				FreeLibrary(hLib);
				return false;
			}
		}
	}
	else
	{
		logDebugMessage(1,"Plugin: %s not found\n",plugin.c_str());
		return false;
	}
}

void unload1Plugin ( int iPluginID )
{
	void (*lpProc)(bz_Plugin*);

	trPluginRecord &plugin = vPluginList[iPluginID];

	bz_PluginLoadUnloadEventData_V1 evt;
	evt.plugin = plugin.plugin;
	evt.eventType = bz_ePluginUnloaded;
	worldEventManager.callEvents(&evt);

	plugin.plugin->Cleanup();
	bz_debugMessagef(4,"%s plugin unloaded",plugin.plugin->Name());

	lpProc = (void (__cdecl *)(bz_Plugin*))GetProcAddress(plugin.handle, "bz_FreePlugin");
	if (lpProc)
	  lpProc(plugin.plugin);
	else
	  logDebugMessage(1,"Plugin: bz_FreePlugin method not used by number %d. Leaking memory.\n",iPluginID);

	FreeLibrary(plugin.handle);
	plugin.handle = NULL;
	plugin.plugin = NULL;
}
#else

#  include <dlfcn.h>
std::vector<void*>	vLibHandles;

int getPluginVersion ( void* hLib )
{
	int (*lpProc)(void);
	*(void**) &lpProc = dlsym(hLib,"bz_GetMinVersion");
	if (lpProc)
		return (*lpProc)();
	return 0;
}

bool load1Plugin ( std::string plugin, std::string config )
{
	bz_Plugin* (*lpProc)();

	std::string realPluginName = findPlugin(plugin);

	void *hLib = dlopen(realPluginName.c_str(), RTLD_LAZY | RTLD_GLOBAL);
	if (hLib)
	{
		if (dlsym(hLib, "bz_GetPlugin") == NULL) {
			logDebugMessage(1,"Plugin: %s found but does not contain bz_Load method, error %s\n",plugin.c_str(),dlerror());
			dlclose(hLib);
			return false;
		}

		int version = getPluginVersion(hLib);
		if (version > BZ_API_VERSION)
		{
			logDebugMessage(1,"Plugin: %s found but needs a newer API version (%d), upgrade server\n",plugin.c_str(), version);
			dlclose(hLib);
			return false;
		}
		else
		{
			*(void**) &lpProc = dlsym(hLib,"bz_GetPlugin");
			if (lpProc)
			{
				bz_Plugin * p = (*lpProc)();
				if (!p)
				  return false;

				std::string name  = p->Name();
				if (PluginExists(name.c_str()))
				  return false;

				trPluginRecord pluginRecord;
				pluginRecord.handle = hLib;
				pluginRecord.name = name;
				pluginRecord.plugin = p;
				pluginRecord.filename = plugin;
				vPluginList.push_back(pluginRecord);
				logDebugMessage(1,"Plugin: %s loaded from %s\n",pluginRecord.name.c_str(),plugin.c_str());
				bz_debugMessagef(4,"%s plugin loaded",pluginRecord.name.c_str());

				p->Init(config.c_str());
				bz_PluginLoadUnloadEventData_V1 evt;
				evt.plugin = p;
				evt.eventType = bz_ePluginLoaded;
				worldEventManager.callEvents(&evt);
				return true;
			}
		}
	}
	else
	{
		logDebugMessage(1,"Plugin: %s not found, error %s\n",plugin.c_str(), dlerror());
		return false;
	}

	logDebugMessage(1,"Plugin: load1Plugin() coding error\n");
	return false;
}

void unload1Plugin ( int iPluginID )
{
	void (*lpProc)(bz_Plugin*);
	trPluginRecord &plugin = vPluginList[iPluginID];

	bz_PluginLoadUnloadEventData_V1 evt;
	evt.plugin = plugin.plugin;
	evt.eventType = bz_ePluginUnloaded;
	worldEventManager.callEvents(&evt);

	plugin.plugin->Cleanup();
	bz_debugMessagef(4,"%s plugin unloaded",plugin.plugin->Name());

	*(void**) &lpProc = dlsym(plugin.handle, "bz_FreePlugin");
	if (lpProc)
	  (*lpProc)(plugin.plugin);
	else
	  logDebugMessage(1,"Plugin: bz_FreePlugin method not used by number %d, error %s. Leaking memory.\n",iPluginID,dlerror());

	dlclose(plugin.handle);
	plugin.handle = NULL;
	plugin.plugin = NULL;
}
#endif

bool loadPlugin ( std::string plugin, std::string config )
{
  // check and see if it's an extension we have a handler for
  std::string ext;

  std::vector<std::string> parts = TextUtils::tokenize(plugin,std::string("."));
  ext = parts[parts.size()-1];

  tmCustomPluginMap::iterator itr = customPluginMap.find(TextUtils::tolower(ext));

  if (itr != customPluginMap.end() && itr->second)
  {
    bz_APIPluginHandler *handler = itr->second;
    return handler->APIPlugin(plugin,config);
  }
  else
  {
    return load1Plugin(plugin,config);
  }
}

bool unloadPlugin ( std::string plugin )
{
	// unload the first one of the name we find
	for (unsigned int i = 0; i < vPluginList.size();i++)
	{
		if ( vPluginList[i].name == plugin || vPluginList[i].filename == plugin )
		{
			unload1Plugin(i);
			vPluginList.erase(vPluginList.begin()+i);
			return true;
		}
	}
	return false;
}

void unloadPlugins ( void )
{
	for (unsigned int i = 0; i < vPluginList.size();i++)
		unload1Plugin(i);
	vPluginList.clear();

	removeCustomSlashCommand("loadplugin");
	removeCustomSlashCommand("unloadplugin");
	removeCustomSlashCommand("listplugins");
}

std::vector<std::string> getPluginList ( void )
{
  std::vector<std::string> plugins;
  for (unsigned int i = 0; i < vPluginList.size();i++)
    plugins.push_back(vPluginList[i].name);

  return plugins;
}

float getPluginMinWaitTime ( void )
{
  float maxTime = 1000.0;

  std::vector<std::string> plugins;
  for (unsigned int i = 0; i < vPluginList.size();i++)
  {
    if (vPluginList[i].plugin &&  (vPluginList[i].plugin->MaxWaitTime > 0) && (vPluginList[i].plugin->MaxWaitTime < maxTime))
      maxTime = vPluginList[i].plugin->MaxWaitTime;
  }

  return maxTime;
}

void parseServerCommand(const char *message, int dstPlayerId);

class DynamicPluginCommands : public bz_CustomSlashCommandHandler
{
public:
	virtual ~DynamicPluginCommands(){};
	virtual bool SlashCommand ( int playerID, bz_ApiString _command, bz_ApiString _message, bz_APIStringList *params )
	{
		bz_BasePlayerRecord	record;

		std::string command = _command.c_str();
		std::string message = _message.c_str();

		bz_BasePlayerRecord	*p = bz_getPlayerByIndex(playerID);
		if (!p)
			return false;

		record = *p;

		bz_freePlayerRecord(p);

		// list dosn't need admin
		if ( TextUtils::tolower(command) == "listplugins" )
		{
			std::vector<std::string>	plugins = getPluginList();

			if (!plugins.size())
				bz_sendTextMessage(BZ_SERVER,playerID,"No Plug-ins loaded.");
			else
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-ins loaded:");

				for ( unsigned int i = 0; i < plugins.size(); i++)
					bz_sendTextMessage(BZ_SERVER,playerID,plugins[i].c_str());
			}
			return true;
		}

		if (!record.hasPerm("PLUGINS"))
		{
			bz_sendTextMessage(BZ_SERVER,playerID,"You do not have permission to (un)load plug-ins.");
			return true;
		}

		if ( TextUtils::tolower(command) == "loadplugin" )
		{
			if ( !params->size() )
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /loadplugin plug-in");
				return true;
			}

			std::vector<std::string> subparams = TextUtils::tokenize(message,std::string(","));

			std::string config;
			if ( subparams.size() >1)
				config = subparams[1];

			if (loadPlugin(subparams[0],config))
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in loaded.");
			else
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in load failed.");
			return true;
		}

		if ( TextUtils::tolower(command) == "unloadplugin" )
		{
			if ( !params->size() )
			{
				bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /unloadplugin plug-in");
				return true;
			}

			if ( unloadPlugin(std::string(params->get(0).c_str())) )
				bz_sendTextMessage(BZ_SERVER,playerID,"Plug-in unloaded.");

			return true;
		}
		return true;
	}
};

DynamicPluginCommands	command;

void initPlugins ( void )
{
	customPluginMap.clear();

	registerCustomSlashCommand("loadplugin",&command);
	registerCustomSlashCommand("unloadplugin",&command);
	registerCustomSlashCommand("listplugins",&command);
}

bool registerCustomPluginHandler ( std::string exte, bz_APIPluginHandler *handler )
{
	std::string ext = TextUtils::tolower(exte);
	customPluginMap[ext] = handler;
	return true;
}

bool removeCustomPluginHandler ( std::string ext, bz_APIPluginHandler *handler )
{
	tmCustomPluginMap::iterator itr = customPluginMap.find(TextUtils::tolower(ext));

	if (itr == customPluginMap.end() || itr->second != handler)
		return false;

	customPluginMap.erase(itr);
	return true;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: markarr.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 18:27:02 $
 *
 *  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
 *
 ************************************************************************/

#ifdef PCH
#include "core_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------------

#include <tools/debug.hxx>

#include "markarr.hxx"
#include "global.hxx"
#include "address.hxx"

// STATIC DATA -----------------------------------------------------------

//------------------------------------------------------------------------

ScMarkArray::ScMarkArray()
{
    nCount = nLimit = 1;
    pData = new ScMarkEntry[1];
    if (pData)
    {
        pData[0].nRow = MAXROW;
        pData[0].bMarked = FALSE;
    }
}

//------------------------------------------------------------------------

ScMarkArray::~ScMarkArray()
{
    if (pData)
        delete[] pData;
}

//------------------------------------------------------------------------

void ScMarkArray::Reset( BOOL bMarked )
{
    if (pData)
    {
        delete[] pData;

        nCount = nLimit = 1;
        pData = new ScMarkEntry[1];
        if (pData)
        {
            pData[0].nRow = MAXROW;
            pData[0].bMarked = bMarked;
        }
    }
}

//------------------------------------------------------------------------

BOOL ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
{
    long    nLo         = 0;
    long    nHi         = static_cast<long>(nCount) - 1;
    long    nStartRow   = 0;
    long    nEndRow     = 0;
    long    i           = 0;
    BOOL    bFound      = (nCount == 1);
    if (pData)
    {
        while ( !bFound && nLo <= nHi )
        {
            i = (nLo + nHi) / 2;
            if (i > 0)
                nStartRow = (long) pData[i - 1].nRow;
            else
                nStartRow = -1;
            nEndRow = (long) pData[i].nRow;
            if (nEndRow < (long) nRow)
                nLo = ++i;
            else
                if (nStartRow >= (long) nRow)
                    nHi = --i;
                else
                    bFound = TRUE;
        }
    }
    else
        bFound = FALSE;

    if (bFound)
        nIndex=(SCSIZE)i;
    else
        nIndex=0;
    return bFound;
}

BOOL ScMarkArray::GetMark( SCROW nRow ) const
{
    SCSIZE i;
    if (Search( nRow, i ))
        return pData[i].bMarked;
    else
        return FALSE;

}

//------------------------------------------------------------------------

void ScMarkArray::SetMark( SCROW nRow, BOOL bMarked )
{
    SetMarkArea( nRow, nRow, bMarked );
}

void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, BOOL bMarked )
{
    if (ValidRow(nStartRow) && ValidRow(nEndRow))
    {
        if ((nStartRow == 0) && (nEndRow == MAXROW))
        {
            Reset(bMarked);
        }
        else
        {
            SCSIZE nNeeded = nCount + 2;
            if ( nLimit < nNeeded )
            {
                nLimit += SC_MARKARRAY_DELTA;
                if ( nLimit < nNeeded )
                    nLimit = nNeeded;
                ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
                memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
                delete[] pData;
                pData = pNewData;
            }

            SCSIZE ni;          // number of entries in beginning
            SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
            BOOL bCombined = FALSE;
            BOOL bSplit = FALSE;
            if ( nStartRow > 0 )
            {
                // skip beginning
                SCSIZE nIndex;
                Search( nStartRow, nIndex );
                ni = nIndex;

                nInsert = MAXROWCOUNT;
                if ( pData[ni].bMarked != bMarked )
                {
                    if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
                    {   // may be a split or a simple insert or just a shrink,
                        // row adjustment is done further down
                        if ( pData[ni].nRow > nEndRow )
                            bSplit = TRUE;
                        ni++;
                        nInsert = ni;
                    }
                    else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
                        nInsert = ni;
                }
                if ( ni > 0 && pData[ni-1].bMarked == bMarked )
                {   // combine
                    pData[ni-1].nRow = nEndRow;
                    nInsert = MAXROWCOUNT;
                    bCombined = TRUE;
                }
            }
            else
        {
                nInsert = 0;
                ni = 0;
        }

            SCSIZE nj = ni;     // stop position of range to replace
            while ( nj < nCount && pData[nj].nRow <= nEndRow )
                nj++;
            if ( !bSplit )
            {
                if ( nj < nCount && pData[nj].bMarked == bMarked )
                {   // combine
                    if ( ni > 0 )
                    {
                        if ( pData[ni-1].bMarked == bMarked )
                        {   // adjacent entries
                            pData[ni-1].nRow = pData[nj].nRow;
                            nj++;
                        }
                        else if ( ni == nInsert )
                            pData[ni-1].nRow = nStartRow - 1;   // shrink
                    }
                    nInsert = MAXROWCOUNT;
                    bCombined = TRUE;
                }
                else if ( ni > 0 && ni == nInsert )
                    pData[ni-1].nRow = nStartRow - 1;   // shrink
            }
            if ( ni < nj )
            {   // remove middle entries
                if ( !bCombined )
                {   // replace one entry
                    pData[ni].nRow = nEndRow;
                    pData[ni].bMarked = bMarked;
                    ni++;
                    nInsert = MAXROWCOUNT;
                }
                if ( ni < nj )
                {   // remove entries
                    memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
                    nCount -= nj - ni;
                }
            }

            if ( nInsert < MAXROWCOUNT )
            {   // insert or append new entry
                if ( nInsert <= nCount )
                {
                    if ( !bSplit )
                        memmove( pData + nInsert + 1, pData + nInsert,
                            (nCount - nInsert) * sizeof(ScMarkEntry) );
                    else
                    {
                        memmove( pData + nInsert + 2, pData + nInsert,
                            (nCount - nInsert) * sizeof(ScMarkEntry) );
                        pData[nInsert+1] = pData[nInsert-1];
                        nCount++;
                    }
                }
                if ( nInsert )
                    pData[nInsert-1].nRow = nStartRow - 1;
                pData[nInsert].nRow = nEndRow;
                pData[nInsert].bMarked = bMarked;
                nCount++;
            }
        }
    }
//  InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
}

void ScMarkArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
{
    SetMarkArea(nStartRow, nEndRow, FALSE);
}

BOOL ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
{
    SCSIZE nStartIndex;
    SCSIZE nEndIndex;

    if (Search( nStartRow, nStartIndex ))
        if (pData[nStartIndex].bMarked)
            if (Search( nEndRow, nEndIndex ))
                if (nEndIndex==nStartIndex)
                    return TRUE;

    return FALSE;
}

BOOL ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
{
    BOOL bRet = FALSE;
    if ( nCount == 1 )
    {
        if ( pData[0].bMarked )
        {
            rStartRow = 0;
            rEndRow = MAXROW;
            bRet = TRUE;
        }
    }
    else if ( nCount == 2 )
    {
        if ( pData[0].bMarked )
        {
            rStartRow = 0;
            rEndRow = pData[0].nRow;
        }
        else
        {
            rStartRow = pData[0].nRow + 1;
            rEndRow = MAXROW;
        }
        bRet = TRUE;
    }
    else if ( nCount == 3 )
    {
        if ( pData[1].bMarked )
        {
            rStartRow = pData[0].nRow + 1;
            rEndRow = pData[1].nRow;
            bRet = TRUE;
        }
    }
    return bRet;
}

BOOL ScMarkArray::HasMarks() const
{
    return ( nCount > 1 || pData[0].bMarked );
}

void ScMarkArray::SwapCol(ScMarkArray& rMarkArray)
{
    SCSIZE nTemp = rMarkArray.nCount;
    rMarkArray.nCount = nCount;
    nCount = nTemp;

    nTemp = rMarkArray.nLimit;
    rMarkArray.nLimit = nLimit;
    nLimit = nTemp;

    ScMarkEntry* pTemp = rMarkArray.pData;
    rMarkArray.pData = pData;
    pData = pTemp;
}

void ScMarkArray::MoveTo(SCROW nStartRow, SCROW nEndRow, ScMarkArray& rMarkArray)
{
    SCROW nStart = nStartRow;
    for (SCSIZE i = 0; i < nCount; i++)
    {
        if ((pData[i].nRow >= nStartRow) && ((i==0) ? TRUE : pData[i-1].nRow < nEndRow))
        {
            rMarkArray.SetMarkArea(nStart, Min(pData[i].nRow,nEndRow), pData[i].bMarked);
        }
        nStart = Max((SCROW)nStart, (SCROW)(pData[i].nRow + 1) );
    }
    DeleteArea(nStartRow, nEndRow);
}

void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
{
    delete[] rDestMarkArray.pData;

    if (pData)
    {
        rDestMarkArray.pData = new ScMarkEntry[nCount];
        memmove( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
    }
    else
        rDestMarkArray.pData = NULL;

    rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
}

SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, BOOL bUp ) const
{
    SCsROW nRet = nRow;
    if (VALIDROW(nRow))
    {
        SCSIZE nIndex;
        Search(nRow, nIndex);
        if (!pData[nIndex].bMarked)
        {
            if (bUp)
            {
                if (nIndex>0)
                    nRet = pData[nIndex-1].nRow;
                else
                    nRet = -1;
            }
            else
                nRet = pData[nIndex].nRow + 1;
        }
    }
    return nRet;
}

SCROW ScMarkArray::GetMarkEnd( SCROW nRow, BOOL bUp ) const
{
    SCROW nRet;
    SCSIZE nIndex;
    Search(nRow, nIndex);
    DBG_ASSERT( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
    if (bUp)
    {
        if (nIndex>0)
            nRet = pData[nIndex-1].nRow + 1;
        else
            nRet = 0;
    }
    else
        nRet = pData[nIndex].nRow;

    return nRet;
}

//
//  -------------- Iterator ----------------------------------------------
//

ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
    pArray( pNewArray ),
    nPos( 0 )
{
}

ScMarkArrayIter::~ScMarkArrayIter()
{
}

BOOL ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
{
    if ( nPos >= pArray->nCount )
        return FALSE;
    while (!pArray->pData[nPos].bMarked)
    {
        ++nPos;
        if ( nPos >= pArray->nCount )
            return FALSE;
    }
    rBottom = pArray->pData[nPos].nRow;
    if (nPos==0)
        rTop = 0;
    else
        rTop = pArray->pData[nPos-1].nRow + 1;
    ++nPos;
    return TRUE;
}

<commit_msg>INTEGRATION: CWS pchfix01 (1.7.214); FILE MERGED 2006/07/12 10:01:34 kaib 1.7.214.1: #i67080# Converted cxx files in sc, added initial project level pch and stripped old PCH definitions.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: markarr.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 11:06:01 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// INCLUDE ---------------------------------------------------------------

#include <tools/debug.hxx>

#include "markarr.hxx"
#include "global.hxx"
#include "address.hxx"

// STATIC DATA -----------------------------------------------------------

//------------------------------------------------------------------------

ScMarkArray::ScMarkArray()
{
    nCount = nLimit = 1;
    pData = new ScMarkEntry[1];
    if (pData)
    {
        pData[0].nRow = MAXROW;
        pData[0].bMarked = FALSE;
    }
}

//------------------------------------------------------------------------

ScMarkArray::~ScMarkArray()
{
    if (pData)
        delete[] pData;
}

//------------------------------------------------------------------------

void ScMarkArray::Reset( BOOL bMarked )
{
    if (pData)
    {
        delete[] pData;

        nCount = nLimit = 1;
        pData = new ScMarkEntry[1];
        if (pData)
        {
            pData[0].nRow = MAXROW;
            pData[0].bMarked = bMarked;
        }
    }
}

//------------------------------------------------------------------------

BOOL ScMarkArray::Search( SCROW nRow, SCSIZE& nIndex ) const
{
    long    nLo         = 0;
    long    nHi         = static_cast<long>(nCount) - 1;
    long    nStartRow   = 0;
    long    nEndRow     = 0;
    long    i           = 0;
    BOOL    bFound      = (nCount == 1);
    if (pData)
    {
        while ( !bFound && nLo <= nHi )
        {
            i = (nLo + nHi) / 2;
            if (i > 0)
                nStartRow = (long) pData[i - 1].nRow;
            else
                nStartRow = -1;
            nEndRow = (long) pData[i].nRow;
            if (nEndRow < (long) nRow)
                nLo = ++i;
            else
                if (nStartRow >= (long) nRow)
                    nHi = --i;
                else
                    bFound = TRUE;
        }
    }
    else
        bFound = FALSE;

    if (bFound)
        nIndex=(SCSIZE)i;
    else
        nIndex=0;
    return bFound;
}

BOOL ScMarkArray::GetMark( SCROW nRow ) const
{
    SCSIZE i;
    if (Search( nRow, i ))
        return pData[i].bMarked;
    else
        return FALSE;

}

//------------------------------------------------------------------------

void ScMarkArray::SetMark( SCROW nRow, BOOL bMarked )
{
    SetMarkArea( nRow, nRow, bMarked );
}

void ScMarkArray::SetMarkArea( SCROW nStartRow, SCROW nEndRow, BOOL bMarked )
{
    if (ValidRow(nStartRow) && ValidRow(nEndRow))
    {
        if ((nStartRow == 0) && (nEndRow == MAXROW))
        {
            Reset(bMarked);
        }
        else
        {
            SCSIZE nNeeded = nCount + 2;
            if ( nLimit < nNeeded )
            {
                nLimit += SC_MARKARRAY_DELTA;
                if ( nLimit < nNeeded )
                    nLimit = nNeeded;
                ScMarkEntry* pNewData = new ScMarkEntry[nLimit];
                memcpy( pNewData, pData, nCount*sizeof(ScMarkEntry) );
                delete[] pData;
                pData = pNewData;
            }

            SCSIZE ni;          // number of entries in beginning
            SCSIZE nInsert;     // insert position (MAXROW+1 := no insert)
            BOOL bCombined = FALSE;
            BOOL bSplit = FALSE;
            if ( nStartRow > 0 )
            {
                // skip beginning
                SCSIZE nIndex;
                Search( nStartRow, nIndex );
                ni = nIndex;

                nInsert = MAXROWCOUNT;
                if ( pData[ni].bMarked != bMarked )
                {
                    if ( ni == 0 || (pData[ni-1].nRow < nStartRow - 1) )
                    {   // may be a split or a simple insert or just a shrink,
                        // row adjustment is done further down
                        if ( pData[ni].nRow > nEndRow )
                            bSplit = TRUE;
                        ni++;
                        nInsert = ni;
                    }
                    else if ( ni > 0 && pData[ni-1].nRow == nStartRow - 1 )
                        nInsert = ni;
                }
                if ( ni > 0 && pData[ni-1].bMarked == bMarked )
                {   // combine
                    pData[ni-1].nRow = nEndRow;
                    nInsert = MAXROWCOUNT;
                    bCombined = TRUE;
                }
            }
            else
        {
                nInsert = 0;
                ni = 0;
        }

            SCSIZE nj = ni;     // stop position of range to replace
            while ( nj < nCount && pData[nj].nRow <= nEndRow )
                nj++;
            if ( !bSplit )
            {
                if ( nj < nCount && pData[nj].bMarked == bMarked )
                {   // combine
                    if ( ni > 0 )
                    {
                        if ( pData[ni-1].bMarked == bMarked )
                        {   // adjacent entries
                            pData[ni-1].nRow = pData[nj].nRow;
                            nj++;
                        }
                        else if ( ni == nInsert )
                            pData[ni-1].nRow = nStartRow - 1;   // shrink
                    }
                    nInsert = MAXROWCOUNT;
                    bCombined = TRUE;
                }
                else if ( ni > 0 && ni == nInsert )
                    pData[ni-1].nRow = nStartRow - 1;   // shrink
            }
            if ( ni < nj )
            {   // remove middle entries
                if ( !bCombined )
                {   // replace one entry
                    pData[ni].nRow = nEndRow;
                    pData[ni].bMarked = bMarked;
                    ni++;
                    nInsert = MAXROWCOUNT;
                }
                if ( ni < nj )
                {   // remove entries
                    memmove( pData + ni, pData + nj, (nCount - nj) * sizeof(ScMarkEntry) );
                    nCount -= nj - ni;
                }
            }

            if ( nInsert < MAXROWCOUNT )
            {   // insert or append new entry
                if ( nInsert <= nCount )
                {
                    if ( !bSplit )
                        memmove( pData + nInsert + 1, pData + nInsert,
                            (nCount - nInsert) * sizeof(ScMarkEntry) );
                    else
                    {
                        memmove( pData + nInsert + 2, pData + nInsert,
                            (nCount - nInsert) * sizeof(ScMarkEntry) );
                        pData[nInsert+1] = pData[nInsert-1];
                        nCount++;
                    }
                }
                if ( nInsert )
                    pData[nInsert-1].nRow = nStartRow - 1;
                pData[nInsert].nRow = nEndRow;
                pData[nInsert].bMarked = bMarked;
                nCount++;
            }
        }
    }
//  InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
}

void ScMarkArray::DeleteArea(SCROW nStartRow, SCROW nEndRow)
{
    SetMarkArea(nStartRow, nEndRow, FALSE);
}

BOOL ScMarkArray::IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const
{
    SCSIZE nStartIndex;
    SCSIZE nEndIndex;

    if (Search( nStartRow, nStartIndex ))
        if (pData[nStartIndex].bMarked)
            if (Search( nEndRow, nEndIndex ))
                if (nEndIndex==nStartIndex)
                    return TRUE;

    return FALSE;
}

BOOL ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const
{
    BOOL bRet = FALSE;
    if ( nCount == 1 )
    {
        if ( pData[0].bMarked )
        {
            rStartRow = 0;
            rEndRow = MAXROW;
            bRet = TRUE;
        }
    }
    else if ( nCount == 2 )
    {
        if ( pData[0].bMarked )
        {
            rStartRow = 0;
            rEndRow = pData[0].nRow;
        }
        else
        {
            rStartRow = pData[0].nRow + 1;
            rEndRow = MAXROW;
        }
        bRet = TRUE;
    }
    else if ( nCount == 3 )
    {
        if ( pData[1].bMarked )
        {
            rStartRow = pData[0].nRow + 1;
            rEndRow = pData[1].nRow;
            bRet = TRUE;
        }
    }
    return bRet;
}

BOOL ScMarkArray::HasMarks() const
{
    return ( nCount > 1 || pData[0].bMarked );
}

void ScMarkArray::SwapCol(ScMarkArray& rMarkArray)
{
    SCSIZE nTemp = rMarkArray.nCount;
    rMarkArray.nCount = nCount;
    nCount = nTemp;

    nTemp = rMarkArray.nLimit;
    rMarkArray.nLimit = nLimit;
    nLimit = nTemp;

    ScMarkEntry* pTemp = rMarkArray.pData;
    rMarkArray.pData = pData;
    pData = pTemp;
}

void ScMarkArray::MoveTo(SCROW nStartRow, SCROW nEndRow, ScMarkArray& rMarkArray)
{
    SCROW nStart = nStartRow;
    for (SCSIZE i = 0; i < nCount; i++)
    {
        if ((pData[i].nRow >= nStartRow) && ((i==0) ? TRUE : pData[i-1].nRow < nEndRow))
        {
            rMarkArray.SetMarkArea(nStart, Min(pData[i].nRow,nEndRow), pData[i].bMarked);
        }
        nStart = Max((SCROW)nStart, (SCROW)(pData[i].nRow + 1) );
    }
    DeleteArea(nStartRow, nEndRow);
}

void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const
{
    delete[] rDestMarkArray.pData;

    if (pData)
    {
        rDestMarkArray.pData = new ScMarkEntry[nCount];
        memmove( rDestMarkArray.pData, pData, nCount * sizeof(ScMarkEntry) );
    }
    else
        rDestMarkArray.pData = NULL;

    rDestMarkArray.nCount = rDestMarkArray.nLimit = nCount;
}

SCsROW ScMarkArray::GetNextMarked( SCsROW nRow, BOOL bUp ) const
{
    SCsROW nRet = nRow;
    if (VALIDROW(nRow))
    {
        SCSIZE nIndex;
        Search(nRow, nIndex);
        if (!pData[nIndex].bMarked)
        {
            if (bUp)
            {
                if (nIndex>0)
                    nRet = pData[nIndex-1].nRow;
                else
                    nRet = -1;
            }
            else
                nRet = pData[nIndex].nRow + 1;
        }
    }
    return nRet;
}

SCROW ScMarkArray::GetMarkEnd( SCROW nRow, BOOL bUp ) const
{
    SCROW nRet;
    SCSIZE nIndex;
    Search(nRow, nIndex);
    DBG_ASSERT( pData[nIndex].bMarked, "GetMarkEnd ohne bMarked" );
    if (bUp)
    {
        if (nIndex>0)
            nRet = pData[nIndex-1].nRow + 1;
        else
            nRet = 0;
    }
    else
        nRet = pData[nIndex].nRow;

    return nRet;
}

//
//  -------------- Iterator ----------------------------------------------
//

ScMarkArrayIter::ScMarkArrayIter( const ScMarkArray* pNewArray ) :
    pArray( pNewArray ),
    nPos( 0 )
{
}

ScMarkArrayIter::~ScMarkArrayIter()
{
}

BOOL ScMarkArrayIter::Next( SCROW& rTop, SCROW& rBottom )
{
    if ( nPos >= pArray->nCount )
        return FALSE;
    while (!pArray->pData[nPos].bMarked)
    {
        ++nPos;
        if ( nPos >= pArray->nCount )
            return FALSE;
    }
    rBottom = pArray->pData[nPos].nRow;
    if (nPos==0)
        rTop = 0;
    else
        rTop = pArray->pData[nPos-1].nRow + 1;
    ++nPos;
    return TRUE;
}

<|endoftext|>


<commit_before>#include "stdafx.h"
// Microsoft stuff
#include <Windows.h>
#include <direct.h>	// for _getcwd

// Standard library
#include <string>
#include <sstream>	// because

#include "SDL.h"

// Mod loader
#include <SADXModLoader.h>

// Local stuff
#include "typedefs.h"
#include "FileExists.h"
#include "input.h"
#include "rumble.h"

void* RumbleA_ptr				= (void*)0x004BCBC0;
void* RumbleB_ptr				= (void*)0x004BCC10;
void* Rumble_ptr				= (void*)0x004BCB60; // Unused, but here so I don't lose it.
void* UpdateControllers_ptr		= (void*)0x0040F460;
void* AnalogHook_ptr			= (void*)0x0040F343;
void* InitRawControllers_ptr	= (void*)0x0040F451; // End of function (hook)

PointerInfo jumps[] = {
	{ rumble::pdVibMxStop, rumble::pdVibMxStop_hook },
	{ RumbleA_ptr,				rumble::RumbleA },
	{ RumbleB_ptr,				rumble::RumbleB },
	{ AnalogHook_ptr,			input::WriteAnalogs_Hook },
	{ InitRawControllers_ptr,	input::RedirectRawControllers_Hook },
	{ EnableController,			input::EnableController_hook },
	{ DisableController,		input::DisableController_hook }
	// Used to skip over the standard controller update function.
	// This has no effect on the OnInput hook.
	//{ UpdateControllers_ptr, (void*)0x0040FDB3 }
};

std::string BuildModPath(const char* modpath, const char* path)
{
	std::stringstream result;
	char workingdir[FILENAME_MAX];

	result << _getcwd(workingdir, FILENAME_MAX) << "\\" << modpath << "\\" << path;

	return result.str();
}

extern "C"
{
	__declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer };
	__declspec(dllexport) PointerList Jumps[] = { { arrayptrandlength(jumps) } };

	__declspec(dllexport) void OnInput()
	{
		input::PollControllers();
	}

	__declspec(dllexport) void Init(const char* path, const HelperFunctions& helperFunctions)
	{
		int init;
		if ((init = SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC | SDL_INIT_EVENTS)) != 0)
		{
			PrintDebug("Unable to initialize SDL. Error code: %i\n", init);
			MessageBoxA(nullptr, "Error initializing SDL. See debug message for details.",
				"SDL Init Error", MB_OK | MB_ICONERROR);
			return;
		}

		// EnableControl
		WriteData((bool**)0x40EF80, &input::_ControllerEnabled[0]);
		WriteData((bool**)0x40EF86, &input::_ControllerEnabled[1]);
		WriteData((bool**)0x40EF90, input::_ControllerEnabled);

		// DisableControl
		WriteData((bool**)0x40EFB0, &input::_ControllerEnabled[0]);
		WriteData((bool**)0x40EFB6, &input::_ControllerEnabled[1]);
		WriteData((bool**)0x40EFC0, input::_ControllerEnabled);

		// IsControllerEnabled
		WriteData((bool**)0x40EFD8, input::_ControllerEnabled);

		// Control
		WriteData((bool**)0x40FE0D, input::_ControllerEnabled);
		WriteData((bool**)0x40FE2F, &input::_ControllerEnabled[1]);

		// WriteAnalogs
		WriteData((bool**)0x40F30C, input::_ControllerEnabled);

		input::_ControllerEnabled[0] = true;
		input::_ControllerEnabled[1] = true;

		std::string dbpath = BuildModPath(path, "gamecontrollerdb.txt");

		if (FileExists(dbpath))
		{
			int result = SDL_GameControllerAddMappingsFromFile(dbpath.c_str());

			if (result == -1)
				PrintDebug("[Input] Error loading gamecontrollerdb: %s\n", SDL_GetError());
			else
				PrintDebug("[input] Controller mappings loaded: %i\n", result);
		}

		std::string config = BuildModPath(path, "config.ini");

		if (FileExists(config))
		{
			const char* config_cstr = config.c_str();
			input::debug = GetPrivateProfileIntA("Config", "Debug", _DEBUG != 0, config_cstr) != 0;

			for (ushort i = 0; i < GAMEPAD_COUNT; i++)
			{
				std::string section = "Controller " + std::to_string(i + 1);
				const char* section_cstr = section.c_str();

				int deadzoneL = GetPrivateProfileIntA(section_cstr, "DeadzoneL", GAMEPAD_LEFT_THUMB_DEADZONE, config_cstr);
				int deadzoneR = GetPrivateProfileIntA(section_cstr, "DeadzoneR", GAMEPAD_RIGHT_THUMB_DEADZONE, config_cstr);

				bool radialL = GetPrivateProfileIntA(section_cstr, "RadialL", 1, config_cstr) != 0;
				bool radialR = GetPrivateProfileIntA(section_cstr, "RadialR", 0, config_cstr) != 0;

				int triggerThreshold = GetPrivateProfileIntA(section_cstr, "TriggerThreshold", GAMEPAD_TRIGGER_THRESHOLD, config_cstr);

				// TODO: Not this
				char wtf[255];

				GetPrivateProfileStringA(section_cstr, "RumbleFactor", "1.0", wtf, 255, config_cstr);
				float rumbleFactor = min(1.0f, (float)atof(wtf));

				DreamPad::Settings* settings = &DreamPad::Controllers[i].settings;
				settings->apply(deadzoneL, deadzoneR, radialL, radialR, triggerThreshold, rumbleFactor);

				if (input::debug)
				{
					PrintDebug("[Input] Deadzones for P%d (L/R/T): %05d / %05d / %05d\n", (i + 1),
						settings->deadzoneL, settings->deadzoneR, settings->triggerThreshold);
				}
			}
		}

		PrintDebug("[Input] Initialization complete.\n");
	}
}
<commit_msg>aaaaaaaaaa<commit_after>#include "stdafx.h"
// Microsoft stuff
#include <Windows.h>
#include <direct.h>	// for _getcwd

// Standard library
#include <string>
#include <sstream>	// because

#include "SDL.h"

// Mod loader
#include <SADXModLoader.h>

// Local stuff
#include "typedefs.h"
#include "FileExists.h"
#include "input.h"
#include "rumble.h"

void* RumbleA_ptr				= (void*)0x004BCBC0;
void* RumbleB_ptr				= (void*)0x004BCC10;
void* Rumble_ptr				= (void*)0x004BCB60; // Unused, but here so I don't lose it.
void* UpdateControllers_ptr		= (void*)0x0040F460;
void* AnalogHook_ptr			= (void*)0x0040F343;
void* InitRawControllers_ptr	= (void*)0x0040F451; // End of function (hook)

PointerInfo jumps[] = {
	{ rumble::pdVibMxStop, rumble::pdVibMxStop_hook },
	{ RumbleA_ptr,				rumble::RumbleA },
	{ RumbleB_ptr,				rumble::RumbleB },
	{ AnalogHook_ptr,			input::WriteAnalogs_Hook },
	{ InitRawControllers_ptr,	input::RedirectRawControllers_Hook },
	{ EnableController,			input::EnableController_hook },
	{ DisableController,		input::DisableController_hook }
	// Used to skip over the standard controller update function.
	// This has no effect on the OnInput hook.
	//{ UpdateControllers_ptr, (void*)0x0040FDB3 }
};

std::string BuildModPath(const char* modpath, const char* path)
{
	std::stringstream result;
	char workingdir[FILENAME_MAX];

	result << _getcwd(workingdir, FILENAME_MAX) << "\\" << modpath << "\\" << path;

	return result.str();
}

extern "C"
{
	__declspec(dllexport) ModInfo SADXModInfo = { ModLoaderVer };
	__declspec(dllexport) PointerList Jumps[] = { { arrayptrandlength(jumps) } };

	__declspec(dllexport) void OnInput()
	{
		input::PollControllers();
	}

	__declspec(dllexport) void Init(const char* path, const HelperFunctions& helperFunctions)
	{
		int init;
		if ((init = SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC | SDL_INIT_EVENTS)) != 0)
		{
			PrintDebug("Unable to initialize SDL. Error code: %i\n", init);
			MessageBoxA(nullptr, "Error initializing SDL. See debug message for details.",
				"SDL Init Error", MB_OK | MB_ICONERROR);
			return;
		}

		// EnableControl
		WriteData((bool**)0x40EF80, &input::_ControllerEnabled[0]);
		WriteData((bool**)0x40EF86, &input::_ControllerEnabled[1]);
		WriteData((bool**)0x40EF90, input::_ControllerEnabled);

		// DisableControl
		WriteData((bool**)0x40EFB0, &input::_ControllerEnabled[0]);
		WriteData((bool**)0x40EFB6, &input::_ControllerEnabled[1]);
		WriteData((bool**)0x40EFC0, input::_ControllerEnabled);

		// IsControllerEnabled
		WriteData((bool**)0x40EFD8, input::_ControllerEnabled);

		// Control
		WriteData((bool**)0x40FE0D, input::_ControllerEnabled);
		WriteData((bool**)0x40FE2F, &input::_ControllerEnabled[1]);

		// WriteAnalogs
		WriteData((bool**)0x40F30C, input::_ControllerEnabled);

		input::_ControllerEnabled[0] = true;
		input::_ControllerEnabled[1] = true;

		std::string dbpath = BuildModPath(path, "gamecontrollerdb.txt");

		if (FileExists(dbpath))
		{
			int result = SDL_GameControllerAddMappingsFromFile(dbpath.c_str());

			if (result == -1)
				PrintDebug("[Input] Error loading gamecontrollerdb: %s\n", SDL_GetError());
			else
				PrintDebug("[Input] Controller mappings loaded: %i\n", result);
		}

		std::string config = BuildModPath(path, "config.ini");

		if (FileExists(config))
		{
			const char* config_cstr = config.c_str();
			input::debug = GetPrivateProfileIntA("Config", "Debug", _DEBUG != 0, config_cstr) != 0;

			for (ushort i = 0; i < GAMEPAD_COUNT; i++)
			{
				std::string section = "Controller " + std::to_string(i + 1);
				const char* section_cstr = section.c_str();

				int deadzoneL = GetPrivateProfileIntA(section_cstr, "DeadzoneL", GAMEPAD_LEFT_THUMB_DEADZONE, config_cstr);
				int deadzoneR = GetPrivateProfileIntA(section_cstr, "DeadzoneR", GAMEPAD_RIGHT_THUMB_DEADZONE, config_cstr);

				bool radialL = GetPrivateProfileIntA(section_cstr, "RadialL", 1, config_cstr) != 0;
				bool radialR = GetPrivateProfileIntA(section_cstr, "RadialR", 0, config_cstr) != 0;

				int triggerThreshold = GetPrivateProfileIntA(section_cstr, "TriggerThreshold", GAMEPAD_TRIGGER_THRESHOLD, config_cstr);

				// TODO: Not this
				char wtf[255];

				GetPrivateProfileStringA(section_cstr, "RumbleFactor", "1.0", wtf, 255, config_cstr);
				float rumbleFactor = min(1.0f, (float)atof(wtf));

				DreamPad::Settings* settings = &DreamPad::Controllers[i].settings;
				settings->apply(deadzoneL, deadzoneR, radialL, radialR, triggerThreshold, rumbleFactor);

				if (input::debug)
				{
					PrintDebug("[Input] Deadzones for P%d (L/R/T): %05d / %05d / %05d\n", (i + 1),
						settings->deadzoneL, settings->deadzoneR, settings->triggerThreshold);
				}
			}
		}

		PrintDebug("[Input] Initialization complete.\n");
	}
}
<|endoftext|>


<commit_before><commit_msg>tdf#44419 allow A:A and 1:1 references also in Calc A1 and ODF syntax<commit_after><|endoftext|>