§ Интерфейс
Написал небольшой класс для того, чтобы можно было просто и удобно что-нибудь рисовать. Это просто шаблон. Как пользоваться классом?Скачать!
1#include "screen.cc" 2 3screen* app; 4 5int main(int argc, char** argv) { 6 7 app = new screen(1280, 800, 4); 8 9 while (app->poll()) { 10 11 // Движение мыши 12 if (app->emouse()) { int x = app->mx, y = app->my; } 13 if (app->mdn(1)) { /* Кликнута левая кнопка, 2-правая, 4-средняя */ } 14 if (app->kdn()) { /* Нажата клавиша app->kb_code */ } 15 if (app->etimer()) { /* Сработал таймер */ } 16 } 17}Класс позволяет
- Рисовать точку через pset
- Рисовать линию line
- Очищать экран cls
§ Код класса screen.cc
1#include "SDL.h" 2#include <sys/timeb.h> 3#include <unistd.h> 4#include <fcntl.h> 5#include <stdlib.h> 6#include <stdio.h> 7 8class screen { 9protected: 10 11 int width, height; 12 13 SDL_Event event; 14 SDL_Surface* sdl_screen; 15 struct timeb ms_clock; 16 unsigned int ms_clock_old; 17 unsigned int event_mask; 18 19public: 20 21 int mx; 22 int my; 23 int mk; 24 int kb_code; 25 int kb_mod; 26 int factor; // =1 Увеличение точки 27 unsigned int ms_time_diff; // Скорость срабатывания таймера 28 29 // Конструкторы с параметрами 30 screen(int w, int h) { init(w, h, "BASIC SDL"); } 31 screen(int w, int h, int f) { init(w, h, "BASIC SDL"); factor = f; } 32 ~screen() { } 33 34 // Запуск окна 35 void init(int w, int h, const char* caption) { 36 37 width = w; 38 height = h; 39 mx = my = mk = 0; 40 ms_time_diff = 20; 41 factor = 1; 42 43 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); 44 SDL_EnableUNICODE(1); 45 46 sdl_screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); 47 SDL_WM_SetCaption(caption, 0); 48 SDL_EnableKeyRepeat(500, 30); 49 } 50 51 // Установка большой точки 52 void pset(int x, int y, uint color) { 53 54 for (int i = 0; i < factor; i++) 55 for (int j = 0; j < factor; j++) 56 pixel(factor*x + j, factor*y + i, color); 57 } 58 59 // Установка маленькой точи 60 void pixel(int x, int y, uint color) { 61 62 if (x >= 0 && y >= 0 && x < width && y < height) { 63 ( (Uint32*)sdl_screen->pixels )[ x + width*y ] = color; 64 } 65 } 66 67 // Нарисовать линию 68 void line(int x1, int y1, int x2, int y2, int color) { 69 70 int deltax = abs(x2 - x1); 71 int deltay = abs(y2 - y1); 72 int signx = x1 < x2 ? 1 : -1; 73 int signy = y1 < y2 ? 1 : -1; 74 75 int error = deltax - deltay; 76 int error2; 77 78 pset(x2, y2, color); 79 while (x1 != x2 || y1 != y2) 80 { 81 pset(x1, y1, color); 82 error2 = error * 2; 83 84 if (error2 > -deltay) { 85 error -= deltay; 86 x1 += signx; 87 } 88 89 if (error2 < deltax) { 90 error += deltax; 91 y1 += signy; 92 } 93 } 94 } 95 96 // Очистить весь экран 97 void cls(uint32_t color) { 98 99 for (int i = 0; i < width * height; i++) 100 ( (Uint32*)sdl_screen->pixels )[ i ] = color; 101 } 102 103 // Обмен видео-буфера 104 void flip() { SDL_Flip(sdl_screen); } 105 106 // Получение событий 107 int poll() { 108 109 int tmp; 110 event_mask = 1; // 1=IDLE 111 112 // Регистрация событий 113 while (SDL_PollEvent(& event)) { 114 switch (event.type) { 115 116 case SDL_QUIT: return 0; 117 118 // Перемещение мыши 119 case SDL_MOUSEMOTION: 120 121 event_mask |= 4; 122 mx = event.motion.x; 123 my = event.motion.y; 124 break; 125 126 // Нажата мышь 127 case SDL_MOUSEBUTTONDOWN: 128 129 event_mask |= (4 | 8); 130 mx = event.motion.x; 131 my = event.motion.y; 132 tmp = event.motion.state; 133 134 if (tmp == SDL_BUTTON_LEFT) mk |= 1; 135 else if (tmp == SDL_BUTTON_RIGHT) mk |= 2; 136 else if (tmp == SDL_BUTTON_MIDDLE) mk |= 4; 137 break; 138 139 // Мышь отпущена 140 case SDL_MOUSEBUTTONUP: 141 142 event_mask |= (4 | 16); 143 mx = event.motion.x; 144 my = event.motion.y; 145 tmp = event.motion.state; 146 147 if (tmp == SDL_BUTTON_LEFT) mk &= ~1; 148 else if (tmp == SDL_BUTTON_RIGHT) mk &= ~2; 149 else if (tmp == SDL_BUTTON_MIDDLE) mk &= ~4; 150 break; 151 152 // https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkeysym.html 153 case SDL_KEYDOWN: 154 155 event_mask |= 32; 156 kb_code = event.key.keysym.unicode; 157 kb_mod = event.key.keysym.mod; 158 if (kb_code == 0) kb_code = 0x100 + event.key.keysym.sym; 159 break; 160 161 case SDL_KEYUP: 162 163 event_mask |= 64; 164 kb_code = event.key.keysym.unicode; 165 kb_mod = event.key.keysym.mod; 166 if (kb_code == 0) kb_code = 0x100 + event.key.keysym.sym; 167 break; 168 } 169 } 170 171 // Вычисление разности времени 172 ftime(&ms_clock); 173 int time_curr = ms_clock.millitm; 174 int time_diff = time_curr - ms_clock_old; 175 if (time_diff < 0) time_diff += 1000; 176 177 // Если прошло 20 мс 178 if (time_diff >= ms_time_diff) { 179 180 SDL_Flip(sdl_screen); 181 ms_clock_old = time_curr; 182 event_mask |= 2; // 2=TIMER 183 } 184 185 SDL_Delay(1); 186 return event_mask; 187 } 188 189 // Определение того, какое событие наступило 190 int etimer() { return !!(event_mask & 2); } 191 int emouse() { return !!(event_mask & 4); } 192 193 // Какая клавиша мыши была нажата: id => 1 левая, 2 правая, 3 средняя 194 int mdn(int id) { return ((event_mask & 8) && (mk & id)); } 195 int mup(int id) { return ((event_mask & 16) && (mk & id)); } 196 197 // Обнаружено нажатие клавиши 198 int kdn() { return !!(event_mask & 32); } 199 int kup() { return !!(event_mask & 64); } 200};
§ Makefile
SDL=`sdl-config --cflags --libs` all: g++ $(SDL) -O3 main.cc -lSDL -Wno-unused-result -o main ./main