Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отлов нажатий клавиш, в 'извращённой' SDL перестал работать 
:(
    Опции темы
powerfox
Дата 9.3.2007, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 5
Всего: 97



Привет! Я извращаюсь с freepascal и SDL (сишной). Я для своей паскалевской лабораторки решил написать свою реализацию (частично) модуля graph на Си с SDL. Так как ни в fpc, ни в graph нет нормального graph, то я сейчас хочу полностью его для них написать. В fpc graph работает через svgalib, то есть запуск требуется от рута, выбрасывает "черти куда", дохнет консоль, в которой была вызвана программа (ломается ввод команд (отображение) и куча мусора появляется). 
Я уже часть написал, но упёрся в отлов нажатия клавиш: SDL создаёт окно, там всё рисуется, но (!!!) моя программа ловит нажатие клавиш только когда активна консоль, с которой запустил приложение.
Си код идентичен, а .o я собирал с помощью gcc, слинковано всё верно (иначе бы ничего не рисовалось), то есть проблему может вызывать только код, сгенерированный fpc. Я пробовал расссуждать так: по идее, окно создаётся с помощью нового процесса, но не fork'ается, так как нет в этом особого смысла, по всей видимости, устанавливается канал между процессами, а SDL функции манипулируют им... fpc мог намудрить с каналом. Но это только предположения.

Добавлено @ 12:46 
Вот пример (взято с туториала по SDL):

Чисто Си код:
Код

#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"


void Slock(SDL_Surface *screen);
void Sulock(SDL_Surface *screen);
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B);
void DrawScene(SDL_Surface *screen);

/* ------------------------------------------- */
int main(int argc, char *argv[]){

 if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ){
   printf("Unable to init SDL: %s\n", SDL_GetError());
   exit(1);
 }

 atexit(SDL_Quit);

 SDL_WM_SetCaption("SDL Gfx Example #1","ex1");
 SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"), NULL);

 SDL_Surface *screen;
 screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
 if ( screen == NULL ){
   printf("Unable to set 640x480 video: %s\n", SDL_GetError());
   exit(1);
 }

 int done=0;
 while(done == 0){

   SDL_Event event;

   while ( SDL_PollEvent(&event) ){
     if ( event.type == SDL_QUIT ){
      done = 1;
     }
     if ( event.type == SDL_KEYDOWN ){
       if ( event.key.keysym.sym == SDLK_ESCAPE ){
         done = 1;
       }
     }
   }

   DrawScene(screen);
 }

}


/* ------------------------------------------------------ */
void Slock(SDL_Surface *screen){

 if ( SDL_MUSTLOCK(screen) ){
   if ( SDL_LockSurface(screen) < 0 ){
     return;
   }
 }

}

/* ------------------------------------------------------ */
void Sulock(SDL_Surface *screen){

 if ( SDL_MUSTLOCK(screen) ){
   SDL_UnlockSurface(screen);
 }

}

/* ------------------------------------------------------ */
void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B){

 Uint32 color = SDL_MapRGB(screen->format, R, G, B);
 switch (screen->format->BytesPerPixel){
   case 1:  // Assuming 8-bpp
   {
     Uint8 *bufp;
     bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; *bufp = color;
   } break;
   case 2: // Probably 15-bpp or 16-bpp
   {
     Uint16 *bufp;
     bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color;
   } break;
   case 3: // Slow 24-bpp mode, usually not used
   {
     Uint8 *bufp;
     bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
     if(SDL_BYTEORDER == SDL_LIL_ENDIAN){
       bufp[0] = color;
       bufp[1] = color >> 8;
       bufp[2] = color >> 16;
     }else{
       bufp[2] = color;
       bufp[1] = color >> 8;
       bufp[0] = color >> 16;
     }
   } break;
   case 4: // Probably 32-bpp
   {
     Uint32 *bufp;
     bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
     *bufp = color;
   } break;
 }

}
void line(int x0,int y0,int x1,int y1,SDL_Surface *screen)
{
 int deltax = abs(x1 - x0);
 int deltay = abs(y1 - y0);
 int error = 0;
 int deltaerr = deltay;
 int y = y0;
 if (x0 == x1)
  for (int y = y0;y<=y1;y++)
   DrawPixel(screen,x0,y,150,170,180);

 for(int x = x0; x<=x1; x++)
 {
  DrawPixel(screen,x,y,150,170,180);
  error += deltaerr;
  if (2*error >= deltax)
  {
   y = y + 1;
   error = error - deltax;
  }
 }
}
/* ------------------------------------------------------ */
void DrawScene(SDL_Surface *screen){

 Slock(screen);

 for(int x=15;x<300;x+=5)
  line(x,20,x,300,screen);

 Sulock(screen);
 SDL_Flip(screen);
}



В паскале Си код такой же, но int main заменено на void drawSdl() + из .c убраны заголовки и добавлено #include "draw.h".
draw.h:
Код

#ifndef DRAW_H
#define DRAW_H
 
#include <stdio.h>
#include <stdlib.h> 
#include <SDL/SDL.h>

void drawSdl();
#endif


drawU.pas:
Код

unit drawU;
 
{$link draw.o}
{$linklib c}
{$linklib gcc}
{$linklib SDL}

interface

procedure drawSdl; cdecl; external;

implementation

end.


main.pas:
Код

program sdl_test;
uses drawU;

begin
drawSdl;
readln;
end.


Выполняется одинакоко, но в паскалевском варианте с клавишами проблема (ждёт нажатия Esc и не дождётся smile ).


--------------------
user posted image
PM WWW   Вверх
powerfox
Дата 9.3.2007, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 5
Всего: 97



Если запускать через тыканье из-под konqueror'а, то пашет нормально. В чём же дело?


--------------------
user posted image
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0451 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.