Модератор: Модераторы
Program kvadrat;
Uses SDL, SDL_Video, crt, keyboard;
Const
width = 720;
height =400;
colordepth = 32 ;
Type
Pixel = LONGWORD; { Must have colordepth bits }
Type
TpixelBuf = Array [0..height-1, 0..width-1] of Pixel ;
Var
screen: PSDL_Surface ;
Q3, W3, E3: BYTE;
Q8, W8: WORD;
BEGIN
ClrScr;
SDL_Init (SDL_INIT_VIDEO) ;
screen := SDL_SetVideoMode (width, height, colordepth, ( SDL_FULLSCREEN + SDL_ANYFORMAT + SDL_SWSURFACE)) ;
if screen = nil then
Begin
Writeln ('Couldn''t initialize video mode at ', width, 'x',
height, 'x', colordepth, 'bpp') ;
Halt(1)
End ;
randomize;
FOR E3:=0 TO 255 DO BEGIN
FOR W3:=0 TO 21 DO
FOR Q3:=0 TO 255 DO BEGIN
Tpixelbuf(screen^.pixels^)[RANDOM(height),RANDOM(width)] :=
SDL_MapRGB(screen^.format,RANDOM(256),RANDOM(256),RANDOM(256));
END;
SDL_UpdateRect (screen, 0, 0, 0, 0) ;
DELAY(80);
FOR Q8:=0 TO HEIGHT-1 DO FOR W8:=0 TO WIDTH-1 DO
Tpixelbuf(screen^.pixels^)[Q8,W8]:=0;
END;
delay(3000);
{InitKeyboard;
GetKeyEvent;
DoneKeyboard;}
SDL_FreeSurface (screen);
SDL_Quit;
END.
Linux Game Programming for PC & Embedded Systems using SDL
Presented by
Fore June
Author of Windows Fan, Linux Fan
Games and SDL
SDL Installation
SDL API
SDL Events SDL Graphics
SDL Events
Programs that operate in a GUI environment are event-driven. An event is an action that takes place within a program when something happens. Part of writing a GUI application is to create event listeners. An event listener is an object or a loop that triggers certain action when a specific event occurs. In the SDL programming environment, an event is produced whenever you move or click the mouse, press a key, or resize the SDL video window. Event handling allows your application to receive input from the user. SDL stores unprocessed events in an internal event queue which allows SDL to collect as many events as possible each time it updates an event. Using functions like SDL_PollEvent, SDL_PeepEvents and SDL_WaitEvent you can observe and handle waiting input events.
There are four main categories of events: keyboard, mouse, window, and system-dependent events. Window events handle gaining and losing focus, as well as exit requests. System-dependent events process raw messages from the windowing system that SDL otherwise would ignore. Information of an event is stored in the structure type SDL_Event. The event queue itself is composed of a series of SDL_Event unions, one for each waiting event. SDL_Event unions are read from the queue with the SDL_PollEvent function and it is then up to the application to process the information stored with them.
Synopsis SDL_Event -- General event structure, which is a union of all possible event types for receiving events from SDL.
Definition typedef union{
Uint8 type;
SDL_ActiveEvent active;
SDL_KeyboardEvent key;
SDL_MouseMotionEvent motion;
SDL_MouseButtonEvent button;
SDL_JoyAxisEvent jaxis;
SDL_JoyBallEvent jball;
SDL_JoyHatEvent jhat;
SDL_JoyButtonEvent jbutton;
SDL_ResizeEvent resize;
SDL_ExposeEvent expose;
SDL_QuitEvent quit;
SDL_UserEvent user;
SDL_SysWMEvent syswm;
} SDL_Event;
Description For reading and placing events on the event queue.
The SDL event subsystem is intertwined with the video subsystem. We basically cannot separate the use of them. Therefore, they are both initialized with SDL_INIT_VIDEO parameter to SDL_Init().
Event Processing To process an event, you need to read the SDL_Event unions from the event queue using the SDL_PollEvent() or SDL_WaitEvent() function. You can also add events onto the event queue using SDL_PushEvent(), which returns 0 on success or -1 on failure. The following are some typical techniques that people use to handle events.
Waiting for events
You can wait for events to occur using the SDL_WaitEvent() function, which waits indefinitely and returns only if an event or an error has occurred.
Synopsis #include "SDL.h"
int SDL_WaitEvent(SDL_Event *event);
Description Waits indefinitely for the next available event.
Returns 0 if there was an error while waiting for events, 1 otherwise. Information of the event detected will be stored in the structure pointed by event and the event is removed from the event queue.
Tip:
SDL has international keyboard support, translating key events and placing the UNICODE equivalents into event.key.keysym.unicode. Since this has some processing overhead involved, it must be enabled using SDL_EnableUNICODE().
Example:
/*
waitevent.cpp
compile by: g++ -o waitevent waitevent.cpp -I/usr/include -L/usr/local/lib -lSDL
executed by: ./waitevent
*/
#include <SDL/SDL.h>
#include <stdlib.h>
bool wait_for_events ()
{
SDL_Event event;
int status;
char *key;
bool quit = false;
printf("waiting for events, press 'q' or 'ESC' to quit\n");
while ( !quit ) {
status = SDL_WaitEvent(&event); //wait indefinitely for an event to occur
//event will be removed from event queue
if ( !status ) { //Error has occurred while waiting
printf("SDL_WaitEvent error: %s\n", SDL_GetError());
return false;
}
switch (event.type) { //check the event type
case SDL_KEYDOWN: //if a key has been pressed
key = SDL_GetKeyName(event.key.keysym.sym);
printf("The %s key was pressed!\n", key );
if ( event.key.keysym.sym == SDLK_ESCAPE ) //quit if 'ESC' pressed
quit = true;
else if ( key[0] == 'q' ) //quit if 'q' pressed
quit = true; //same as "if ( event.key.keysym.sym == SDLK_q )"
break;
case SDL_MOUSEMOTION: //mouse moved
printf("Mouse motion x:%d, y:%d\n", event.motion.x, event.motion.y );
break;
case SDL_MOUSEBUTTONUP: //mouse button pressed
printf("Mouse pressed x:%d, y:%d\n", event.button.x, event.button.y );
break;
case SDL_QUIT: //'x' of Window clicked
exit ( 1 );
break;
}
} //while
return true;
}
int main()
{
SDL_Surface *screen;
//initialize the event subsystem along with video system
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
//ensure SDL_Quit is called when the program exits
atexit(SDL_Quit);
//set video mode of 640 x 480 with 16-bit pixels
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
if ( screen == NULL ) {
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
exit(1);
}
wait_for_events();
return 0;
}
Keyboard and Mouse Events
In the above example, it prints out the key you have pressed and exits if you have pressed 'ESC' or 'q'. The function SDL_GetKeyName() is used to get the name of the key being pressed. SDL assigns a virtual keysym to each key on the keyboard. A preprocessor symbol is used to map to each virtual keysym. For example, Escape key corresponds to the symbol SDLK_ESCAPE; key 'q' corresponds to SDLK_q. Virtual keysyms are of type SDLKey. Virtual keysyms treat the special keys like Ctrl, Alt, and Shift as ordinary keys. You can find their keysyms in the header file SDL_keysym.h. However, those keys are also considered as modifier keys which are represented by ORed bit flags. For example, the flag for a combination of right Ctrl and Alt keys would be ( KMOD_RCTRL | KMOD_RALT ).
A mouse event is generated when you move the move or click on one of its buttons. A mouse reports changes in its position with respect to a fixed unit of measure, called a mickey. For example, a movement 1 inch right and two inches down may correspond to 200 horizontal mouse units and -400 vertical mouse units.
The following are some often used events generated by a mouse or a keyboard. SDL_QUIT - user clicked little x button in the corner of a window mode.
SDL_KEYDOWN - key pressed, stored in the key member of SDL_Event
SDL_KEYUP - key released, stored in the key member of SDL_Event
SDL_MOUSEDOWN - mouse button pressed, stored in button member of SDL_Event
SDL_MOUSEUP - mouse button released, stored in button member of SDL_Event
SDL_MOUSEMOTION - mouse moved, stored in motion member of SDL_Event
For keyboard events, the data are stored in the key event of SDL_Event. A few of the more useful SDLKey's include SDLK_RETURN
SDLK_ESCAPE
SDLK_SPACE
SDLK_0
SDLK_1
...
SDLK_9
SDLK_a
SDLK_b
SDLK_c
...
SDLK_z
The button structure for Mouse up and down is a SDL_MouseButtonEvent structure and has 5 members. The x and y members store the coordinates for the cursor, with ( 0, 0 ) at the upper left corner and the screen is positive. The button member can be SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE, or SDL_BUTTON_RIGHT. The type member stores SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP and state stores SDL_PRESSED and SDL_RELEASED.
The motion member is an SDL_MouseMotionEvent structure. This has the x and y coordinates of the mouse, and xrel and yrel as relative motion in the x and y direction. along with type (always SDL_MOUSEMOTION) Synopsis SDL_MouseButtonEvent -- Mouse button event structure
Definition typedef struct{
Uint8 type; //SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
Uint8 button; //Mouse button index (SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE,
//SDL_BUTTON_RIGHT, SDL_BUTTON_WHEELUP, SDL_BUTTON_WHEELDOWN)
Uint8 state; //SDL_PRESSED or SDL_RELEASED
Uint16 x, y; //The X/Y coordinates of the mouse at press/release time
} SDL_MouseButtonEvent;
Description A member of the SDL_Event union and is used when an event of type SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP is reported.
The following are some useful related functions. SDL_WarpMouse(Uint26 x, Uint16 y) warp the mouse to the given location and generate a SDL_MOUSEMOTION event.
Uint8 *SDL_GetKeyState(int *numkeys) if numkeys is NULL, then all the keys will be returned, otherwise just the first numkeys. The return value is a pointer to an array of keystates, where the SDLKey values are the indexes (SDLK_RETURN, SDLK_p, ...)
For example,
Uint8 *keystate = SDL_GetKeyState(NULL);
if (keystate[SDLK_RETURN]) { printf("Return Key Pressed"); }
SDLMod SDL_GetModState() returns the current state of modifier keys (shift, alt, etc.) where SDLMod is an enum, some values including, KMOD_NONE, KMOD_LSHIFT, KMOD_RSHIFT, KMOD_LALT, KMOD_RALT, KMOD_CAPS. A complete list can be found from SDL_GetModState man page.
char *SDL_GetKeyName ( SDLKey key ) returns a char pointer to the key.
int SDL_EnableKeyRepeat ( int delay, int interval ) sets the key repeat rate. If idelay is 0, repeating is disabled. Two good values for this function are SDL_DEFAULT_REPEAT_DELAY and SDL_DEFAULT_REPEAT_INTERVAL. This returns 0 on success and -1 on failure.
As we mentioned in an earlier chapter, SDL does not support USB devices. If you need to a USB keyboard or mouse for your embedded system, minor modifications of the SDL library are needed; we shall discuss the required modifications in a later chapter.
Polling for events
You can poll for events using the SDL_PollEvent() function. Tip:
You can peek at events in the event queue without removing them by passing the SDL_PEEKEVENT action to SDL_PeepEvents().
Example:
{
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
printf("Mouse moved by %d,%d to (%d,%d)\n",
event.motion.xrel, event.motion.yrel,
event.motion.x, event.motion.y);
break;
case SDL_MOUSEBUTTONDOWN:
printf("Mouse button %d pressed at (%d,%d)\n",
event.button.button, event.button.x, event.button.y);
break;
case SDL_QUIT:
exit(0);
}
}
}
Polling event state
In addition to handling events directly, each type of event has a function which allows you to check the application event state. If you use this exclusively, you should ignore all events with the SDL_EventState() function, and call SDL_PumpEvents() periodically to update the application event state.
Tip:
You can hide or show the system mouse cursor using SDL_ShowCursor().
Example:
{
SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
}
void CheckMouseHover(void)
{
int mouse_x, mouse_y;
SDL_PumpEvents();
SDL_GetMouseState(&mouse_x, &mouse_y);
if ( (mouse_x < 32) && (mouse_y < 32) ) {
printf("Mouse in upper left hand corner!\n");
}
}
Here's a demo I wrote that does something rather similar. It was a test base for my game I'm developing. The ol classic space invaders. (Just starting game development, never done much before, except in asm).
--Begin Code---
program demo;
uses
SDL, SDL_Video, SDL_Events;
const
width = 640;
height = 480;
colordepth = 16;
var
screen: PSDL_Surface;
image: PSDL_Surface;
event: PSDL_Event;
done: Boolean;
filename: String;
begin
SDL_Init(SDL_INIT_VIDEO);
event := new(PSDL_Event);
screen := SDL_SetVideoMode(width, height, colordepth, SDL_SWSURFACE);
if screen = nil then
begin
writeLn ('Couldn''t initialize video mode at ', width, 'x', height, 'x', colordepth, 'bpp');
halt(1);
end;
filename := 'splash.bmp';
image := SDL_loadBMP(@filename[1]);
if (image = nil) then
begin
writeLn('Couldn''t load ' + filename);
halt(1);
end;
if (SDL_BlitSurface(image, nil, screen, nil) < 0) then
begin
writeLn('BlitSurface error:' {+ SDL_GetError()});
end;
SDL_updateRect(screen, 0, 0, image^.w, image^.h);
SDL_freeSurface(image);
done := FALSE;
while (done = FALSE) do
begin
if (SDL_PollEvent(event) > 0) then
begin
if (event^.eventtype = SDL_EventQuit) then
begin
done := TRUE;
end;
end;
end;
SDL_freeSurface(screen);
SDL_Quit ;
end.
--End Code--
cheers
James
-- James Mills, Декабрь 31, 2002 08:07
program demo;
uses
SDL, SDL_Video, SDL_Events;
const
width = 720;
height = 400;
colordepth = 32;
var
screen: PSDL_Surface;
image: PSDL_Surface;
event: PSDL_Event;
done: Boolean;
filename: String;
label 1;
begin
SDL_Init(SDL_INIT_VIDEO);
event := new(PSDL_Event);
screen := SDL_SetVideoMode(width, height, colordepth, (SDL_FULLSCREEN + SDL_SWSURFACE));
if screen = nil then
begin
writeLn ('Couldn''t initialize video mode at ', width, 'x', height, 'x', colordepth, 'bpp');
halt(1);
end;
filename := '0.bmp';
image := SDL_loadBMP(@filename[1]);
if (image = nil) then
begin
writeLn('Couldn''t load ' + filename);
halt(1);
end;
if (SDL_BlitSurface(image, nil, screen, nil) < 0) then
begin
writeLn('BlitSurface error:' {+ SDL_GetError()});
end;
SDL_updateRect(screen, 0, 0, image^.w, image^.h);
SDL_freeSurface(image);
done := FALSE;
while (done = FALSE) do
begin
if (SDL_PollEvent(event) > 0) then
begin
CASE event^.eventtype OF
SDL_KEYDOWN, SDL_MOUSEBUTTONDOWN :done := TRUE;
end;
end;
end;
SDL_freeSurface(screen);
SDL_Quit ;
end.
Вернуться в Free Pascal Compiler
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6