Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Название темы: Игра Ксоникс
Показать сообщение отдельно
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Если не прибегать к библиотекам сторонних производителей, например gdi32.dll от микрософт, не пользоваться алгоритмами стандартной библиотеки c++, то код будет выглядеть примерно так:
Код: Выделить весь код
typedef int surf_bit_t;

struct rect_t
{
   int left, top, right, bottom;
}

struct surface_desc
{
  surf_bit_t *begin; // начало данных
  unsigned width, height, stride; // длина, ширина блока, длина строчки
};

void __blt(surface_desc* from, surface_desc* to)
{
    // копирование без проверки исходых данных.
    // чтобы случайно не попортить память при записи, руководствуемся размерами конечной области
    for(surf_bit_t *row_first1=to->begin,
       *row_last1=to->begin+from->stride*to->width,
       *row_first2=from->from->begin;
        row_first1<row_last1; row_first1+=to->stride, row_first2+=from->stride)
    {
// закомментирован пример кода для копирования,
// можешь поиграться с ним (переделать в закрашивание)
//        for(unsigned col=0; col<to->width; ++col)
//        {
//            row_first1[col] = row_first2[col];
//        }
           memcpy(row_first2, row_first1, to->width*sizeof(surf_bit_t));
    }
}

inline int __constraint(int x, int min, int max)
{
   return x < min ? min : (x < max ? x : max);
}

void blt(surface_desc* from, int x, int y, int width, int height, surface_desc* to, int to_x, int to_y)
{
  // более удобный для пользователя интерфейс
  // с проверкой исходных данных
  // вычисляем перекрывающийся прямоугольник для копирования.

  surface_desc from1, to1;

  {
	// пересечение прямоугольника {0, 0, width, height} с
	// исходным изображением, в координатах копируемого окошка
	rect_t rect_src = {
		__constraint(-x, 0, width),
		__constraint(-y, 0, height),
		__constraint(from->width - x, 0, width),
		__constraint(from->height - y, 0, height)},
	// пересечение  {0, 0, width, height} с
	// конечным изображением и сразу с пересечённым исходным rect_src
	  	rect_dest = {
		__constraint(__constraint(-x_to, 0, width), rect_src.left, rect_src.right),
		__constraint(__constraint(-y_to, 0, height), rect_src.top, rect_src.bottom),
		__constraint(__constraint(to->width - x_to, 0, width), rect_src.left, rect_src.right),
		__constraint(__constraint(to->height - y_to, 0, height), rect_src.top, rect_src.bottom)};
	
	// составляем полётное задание для __blt

	from1.begin  = from->begin + (rect_dest.top + y)*from->stride + rect_dest.left + x;
 	from1.stride = from->stride;
        from1.width  = rect_desc.right - rect_dest.left;
        from1.height = rect_desc.bottom - rect_dest.top;

	to1.begin  = to->begin + (rect_dest.top + to_y)*from->stride + rect_dest.left + to_x;
 	to1.stride = to->stride;
        to1.width  = rect_desc.right - rect_dest.left;
        to1.height = rect_desc.bottom - rect_dest.top;
   }  

   __blt(&from1, &to1);
}

...

// как пользоваться

surf_bit_t screen1_bits[320*200];
surface_desc screen1 = {&screen1_bits, 320, 200, 320};

surf_bit_t screen2_bits[50*100];
surface_desc screen2 = {&screen2_bits, 50, 100, 50};

...

blt(&screen1, 100, 100, 60, 60, &screen2, 10, 10);
если внутри __blt заменить memcpy на memset, то получится "закрашивание". Рекомендую почитать в сторону функции BitBlt от винды. Если surf_bit_t - 8 битный, то можно сделать 8-битные картинки в памяти и смело пользоваться функциями GDI
Это сообщение посчитали полезным следующие участники:

Отправлено: 23:21, 28-12-2008 | #2

Название темы: Игра Ксоникс