§ Интерфейс

Написал небольшой класс для того, чтобы можно было просто и удобно что-нибудь рисовать. Это просто шаблон. Как пользоваться классом?
Скачать!
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