[Reproduced] SDL Guide Chinese Translation

xiaoxiao2021-03-06  33

SDL Simple DirectMedia Layer, similar to DirectX, is a complete game, multimedia development kit, but different is that it spans almost all platforms, there are various languages, multiple language documents, and this is the majority of volunteers Finished. At present, the extension is not formally document, the following is the wizard portion of the core part of the document.

Preface

About SDL

SDL makes it easy to make Linux, BSD, Macos, Win32 and BEOS platforms, using local high-performance media interfaces, and allow you to design only one source code level API. SDL is a quite low-level API, but use it allows you to write a complete cross-platform program with great flexibility. SDL: http://www.libsdl.org/

About SDL documentation

The SDLDOC project is to rewrite the SDL document and update synchronously. The project group has a volunteer using SDL.

The latest version can be downloaded at http://sdldoc.sourceforge.net

Xie Qi

SAM LANTINGA, SLOUKEN@libsdl.org

Martin Donlon, Akawaka@skynet.ie

Mattias ENGDEG? RD

Julian Peterson

Ken Jordan

Maxim Sobolev

Wesley Poole

Michael Vance

Andreas umbach

Andreas Hofmeister

First chapter foundation

initialization

SDL consists of eight subsystems - audio, CDROM, event processing, file I / O, game rod, thread, memory, and video. SDL_INIT or SDL_INITSUBSYSTEM initialization must be called before use. SDL_INIT must be called earlier than all other SDL calls, which will automatically initialize event processing, file I / O, and thread subsystems, and start other subsystems based on parameter selection. For example, initialization default and video subsystem:

SDL_INIT (SDL_INIT_VIDEO);

Initialization default, video, and time device subsystem:

SDL_INIT (SDL_INIT_VIDEO | SDL_INIT_TIMER);

SDL_INIT corresponds to SDL_QUIT (and SDL_Quitsubsystem). SDL_QUIT off all subsystems must be called before the program is turned off.

In addition, we must also perform errors. Many SDL functions returns a value indicating success or not. Returns -1 when the SDL_INIT fails. Whenever the SDL is wrong, the error message is saved and can be obtained with SDL_Geterror.

Example 1-1 Initialization SDL

#include "sdl.h" / * all SDL App's NEED THIS * /

#include

Int main () {

Printf ("Initializing SDL./N);

/ * Initialize Defaults, Video and Audio * /

IF ((SDL_INIT (SDL_INIT_VIDEO | SDL_INIT_AUDIO) == - 1)) {

Printf ("Could Not Initialize SDL:% s. / N", SDL_GETERROR ());

EXIT (-1);

}

Printf ("SDL Initialized./N");

Printf ("Quiting SDL./N");

/ * Shutdown All Subsystems * /

SDL_QUIT ();

Printf ("Quiting .... / N");

exit (0);

}

Chapter II Image and Video Initialization SDL Video Display Video is the most commonly used part, and is the most complete subsystem of SDL. The following initialization process is done every SDL program, even if some may be different. Example 2-1 Initializing Video SDL_SURFACE * Screen; / * Initialize The SDL Library * /

IF (SDL_INIT (SDL_INIT_VIDEO) <0) {

FPRINTF (stderr,

"Couldn't Initialize SDL:% S / N", SDL_GETERROR ());

Exit (1);

}

/ * Clean Up on exit * /

Atexit (SDL_QUIT);

/ *

* Initialize The Display In A 640x480 8-bit Palettized Mode,

* Requesting a Software Surface

* /

Screen = SDL_SETVIDEOMODE (640, 480, 8, SDL_SWSURFACE);

IF (screen == null) {

FPRINTF (stderr, "couldn't set 640x480x8 video mode:% s / n",

SDL_GETERROR ());

Exit (1);

}

Initializing Best Video Mode If you want some color deep (number of colors) but if the user's display is not supported, you can accept other color depth, using SDL_SetVideomode, plus SDL_AnyFormat parameter. You can also use SDL_VIDEODEOK to find the most closest mode with the request mode. Example 2-2 Initialization Best Video Mode / * Have a Preference for 8-Bit, But Accept Any Depth * /

Screen = SDL_SETVIDEODEODE (640, 480, 8, SDL_SWSURFACE | SDL_AnyFormat);

IF (screen == null) {

FPRINTF (stderr, "couldn't set 640x480x8 video mode:% s / n",

SDL_GETERROR ());

Exit (1);

}

Printf ("SET 640X480 AT% D Bits-Per-Pixel Mode / N",

Screen-> Format-> BitsPerpixel;

Read and display the BMP file When SDL has been initialized, the video mode has been selected, the following function will read and display the specified BMP file. Example 2-3 Read and display BMP file void display_bmp (char * file_name)

{

SDL_SURFACE * image;

/ * Load The BMP File Into a Surface * /

Image = SDL_LOADBMP (file_name);

IF (image == null) {

FPRINTF (stderr, "couldn't load% s:% s / n", file_name, SDL_GETERROR ());

Return;

}

/ *

* Palettized Screen Modes Will Have A Default Palette (A Standard

* 8 * 8 * 4 colour cube), But if the image ispa kettized as well we can

* Use That Palette for a nice color matching

* /

IF (image-> format-> format-> palette) {SDL_SETCOLORS (Screen, Image-> Format-> Palette-> Colors, 0,

Image-> format-> palette-> ncolors;

}

/ * Blit Onto the screen Surface * /

IF (image, null, screen, null <0)

FPRINTF (stderr, "blitsurface error:% s / n", SDL_GETERROR ());

SDL_UPDATERECT (Screen, 0, 0, Image-> W, Image-> H);

/ * Free the allocated bmp surface * /

SDL_FREESURFACE (Image);

}

Draw directly below the two functions of the two functions to read and write in the image plane. They are carefully designed to be used for all colors. Remember to lock the image plane before use, then unlock it. In the pixel value and its red, green, blue value, using SDL_GETRGB () and SDL_MAPRGB (). Example 2-4 getpixel () / *

* Return The Pixel Value At (x, y)

* Note: The Surface Must Be Locked Before Calling this!

* /

Uint32 getpixel (SDL_SURFACE * SURFACE, INT X, INT Y)

{

INT bpp = surface-> format-> bytesperpixel;

/ * Here P is the address to the pixel we want to retrieve * /

UINT8 * P = (uint8 *) Surface-> Pixels Y * Surface-> PITCH X * BPP;

Switch (bpp) {

Case 1:

Return * p;

Case 2:

Return * (uint16 *) p;

Case 3:

IF (SDL_BYTEORDER == SDL_BIG_ENDIAN)

Return P [0] << 16 | P [1] << 8 | P [2];

Else

RETURN P [0] | P [1] << 8 | P [2] << 16;

Case 4:

Return * (uint32 *) p;

DEFAULT:

Return 0; / * shouldn't happen, but avoids warnings * /

}

}

Example 2-5 PUTPIXEL () / *

* Set the pixel at (x, y) to the given value

* Note: The Surface Must Be Locked Before Calling this!

* /

Void Putpixel (SDL_SURFACE * SURFACE, INT X, INT Y, UINT32 PIXEL)

{

INT bpp = surface-> format-> bytesperpixel;

/ * Here P is The Address to the Pixel We Want To set * /

UINT8 * P = (uint8 *) Surface-> Pixels Y * Surface-> PITCH X * BPP;

Switch (bpp) {

Case 1:

* p = pixel;

Break;

Case 2:

* (Uint16 *) p = pixel;

Break;

Case 3:

IF (SDL_BYTEORDER == SDL_BIG_ENDIAN) {

P [0] = (Pixel >> 16) & 0xFF;

P [1] = (Pixel >> 8) & 0xFF;

P [2] = Pixel & 0xFF;

} else {

P [0] = Pixel & 0xFF;

P [1] = (Pixel >> 8) & 0xFF;

P [2] = (Pixel >> 16) & 0xFF;

}

Break;

Case 4:

* (Uint32 *) p = pixel;

Break;

}

}

Example 2-6 Draw a yellow point in the center of PUTPIEL () on the screen / * code to set a yelow pixel at the center of the screen * /

INT X, Y;

Uint32 yellow;

/ * Map the color Yellow to this Display (r = 0xff, g = 0xFF, b = 0x00)

NOTE: IF The Display IS Palettized, You Must Set The Palette First.

* /

YELLOW = SDL_MAPRGB (Screen-> Format, 0xFF, 0xFF, 0x00);

X = Screen-> W / 2;

Y = screen-> h / 2;

/ * Lock The Screen for Direct Access To The Pixels * /

IF (SDL_Mustlock (Screen)) {

IF (SDL_LOCKSURFACE (SCREEN) <0) {

FPRINTF (stderr, "can't lock screen:% s / n", SDL_GETERROR ());

Return;

}

}

PUTPIXEL (Screen, X, Y, YELLOW);

IF (SDL_Mustlock (Screen)) {

SDL_Unlocksurface (screen);

}

/ * Update Just The Part of The Display That We've Changed * /

SDL_UPDATERECT (Screen, X, Y, 1, 1);

Return;

And use the SDL and OpenGLSDL to create and use OpenGL context on a variety of platforms (Linux / X11, Win32, Beos, Macos Classic / Toolbox, Macos, FreeBSD / X11 and Solaris / X11). This allows you to use SDL audio, events, threads, and buses in OpenGL programs, which are usually the task of GLUT. Similar to ordinary initialization, but there are three points: must pass the SDL_opengl parameter to SDL_SETVIDEOMODE; must specify some GL attributes (depth buffer location, frame buffer width, etc.); if you want to use dual buffers, you must specify as GL property Example 2-7 Initialization SDL plus OpenGL / * Information About The Current Video Settings. * /

Const SDL_VideoInfo * info = NULL;

/ * Dimensions of out window. * /

INT width = 0;

INT height = 0;

/ * Color Depth in Bits of Our Window. * /

INT BPP = 0;

/ * Flags We Will Pass Into SDL_SETVIDEOMODE. * /

INT FLAGS = 0;

/ * First, Initialize SDL's Video Subsystem. * /

IF (SDL_INIT (SDL_INIT_VIDEO) <0) {

/ * Failed, exit. * /

FPRINTF (stderr, "Video Initialization Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

/ * Let's get some video information. * /

INFO = SDL_GETVIDEOINFO ();

IF (! info) {

/ * This kind probably never happen. * /

FPRINTF (stderr, "Video Query Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

/ *

* Setur Width / Height To 640/480 (you 10

* of Course Let the User Decide this in a Normal

* app). We get the bpp We Will Request from WE WILL REQUEST

* The Display. on X11, Vidmode Can't change

* Resolution, So this is probably being overly

* Safe. Under Win32, ChangeDisplaySettings

* can change the bpp.

* /

Width = 640;

HEIGHT = 480;

BPP = info-> vfmt-> bitsPerpixel;

/ *

* Now, we want to setup ur request

* Window Attributes for Our OpenGL Window.

* WE WANT * AT Least * 5 Bits of Red, Green

* And Blue. WEALSO WANT AT Least A 16-bit

* Depth buffer.

*

* The Last Thing We do Is Request A Double

* buffered window. '1' Turns on Double

* buffering, '0' Turns IT OFF.

*

* Note That We do not use SDL_DOUBLBUF IN

* The flags to sdl_setvideomode. That Does

* Not affect the gl attribute stat, ONLY

* The Standard 2D Blitting Setup.

* /

SDL_GL_SETATTRIBUTE (SDL_GL_RED_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_GREEN_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_BLUE_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_DEPTH_SIZE, 16);

SDL_GL_SETATTRIBUTE (SDL_GL_DOUBLEBUFFER, 1);

/ *

* WE Want to Request That SDL Provide US * with an OpenGL Window, In A Fullscreen

* Video Mode.

*

* EXERCISE:

* Make Starting Windowed An Option, And

* Handle The Resize Events Properly with

* GLVIEWPORT.

* /

Flags = SDL_OPENGL | SDL_FULLSCREEN

/ *

* Set the video mode

* /

IF (SDL_SETVIDEOMODE (Width, Height, BPP, FLAGS) == 0) {

/ *

* This Could Happen for a Variety of Reasons,

* Including Display Not Being Set, The Specified

* Resolution Not Being Available, ETC.

* /

FPRINTF (stderr, "Video Mode Set Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

OpenGL drawing is the same function and data type in addition to initialization, using OpenGL and other situations in the SDL program. But if you use dual buffers, you must use SDL_GL_SWAPBuffers () to swap the front and rear buffers instead of GLXSWAPBuffers () (GLX) or swapBuffers () (Windows). Example 2-8 SDL and OpenGL / *

* SDL OpenGL TUTORIAL.

* (c) Michael Vance, 2000

* Briareos@lokigames.com

*

* Distributed Under Terms of the LGPL.

* /

#include

#include

#include

#include

#include

Static glboolean shop_rotate = GL_TRUE;

Static void quit_tutorial (int code)

{

/ *

* Quit SDL SO We can Release The Fullscreen

* Mode and restore the previous video settings,

* ETC.

* /

SDL_QUIT ();

/ * EXIT Program. * /

EXIT (CODE);

}

Static void handle_key_down (SDL_Keysym * Keysym)

{

/ *

* WE'R ONLY INTERESTED IF 'ESC' HAS

* Been presssed.

*

* EXERCISE:

* Handle the arrow keys and harness That Change THE

* Viewing Position / Angle.

* /

Switch (Keysym-> SYM) {

Case SDLK_ESCAPE:

Quit_Tutorial (0);

Break;

Case SDLK_SPACE:

Should_Rotate =! Should_Rotate;

Break;

DEFAULT:

Break;

}

}

Static void process_events (void) {

/ * Our SDL Event PlaceHolder. * /

SDL_EVENT EVENT;

/ * Grab all the events off the queue. * /

While (SDL_POLLEVENT (& Event)) {

Switch (Event.Type) {

Case SDL_KeyDown:

/ * Handle Key Presses. * /

Handle_Key_Down (& Event.Key.KeysYM);

Break;

Case SDL_Quit:

/ * Handle Quit Requests (Like Ctrl-C). * /

Quit_Tutorial (0);

Break;

}

}

}

Static void Draw_Screen (Void)

{

/ * Our Angle of rotation. * /

Static float angle = 0.0f;

/ *

* EXERCISE:

* Replace this awful message with Vertex

* Arrays and a call to gldrawelements.

*

* EXERCISE:

* After Completing The Above, Change

* It to use compiled Vertex Arrays.

*

* EXERCISE:

* Verify My WINDINGS Are Correct Here;).

* /

Static GLFLOAT V0 [] = {-1.0F, -1.0F, 1.0F};

Static GLFLOAT V1 [] = {1.0F, -1.0F, 1.0F};

Static GLFLOAT V2 [] = {1.0F, 1.0F, 1.0F};

Static GLFLOAT V3 [] = {-1.0F, 1.0F, 1.0F};

Static GLFLOAT V4 [] = {-1.0F, -1.0F, -1.0F};

Static GLFLOAT V5 [] = {1.0F, -1.0F, -1.0F};

Static GLFLOAT V6 [] = {1.0F, 1.0F, -1.0F};

Static GLFLOAT V7 [] = {-1.0F, 1.0F, -1.0F};

Static glubyte red [] = {255, 0, 0, 255};

Static glubyte green [] = {0, 255, 0, 255};

Static glubyte blue [] = {0, 0, 255, 255};

Static glubyte white [] = {255, 255, 255, 255};

Static glubyte yellow [] = {0, 255, 255, 255};

Static glubyte black [] = {0, 0, 0, 255};

Static glubyte orange [] = {255, 255, 0, 255};

Static glubyte purple [] = {255, 0, 255, 0};

/ * CLEAR THE color and defth buffers. * /

GLCLEAR (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/ * We don't want to modify the project matrix. * /

Glmatrixmode (GL_MODELVIEW); GLLoadIdentity ();

/ * Move Down the z-axis. * /

GltranslateF (0.0, 0.0, -5.0);

/ * Rotate. * /

GLROTATEF (Angle, 0.0, 1.0, 0.0);

IF (shop_rotate) {

IF ( Angle> 360.0F) {

Angle = 0.0f;

}

}

/ * Sendur triangle data to the pipeline. * /

Glbegin (GL_TRIANGLES);

GLCOLOR4UBV (RED);

GLVERTEX3FV (V0);

GLCOLOR4UBV (Green);

GLVERTEX3FV (V1);

Glcolor4ubv (Blue);

GLVERTEX3FV (V2);

GLCOLOR4UBV (RED);

GLVERTEX3FV (V0);

Glcolor4ubv (Blue);

GLVERTEX3FV (V2);

Glcolor4UBV (White);

GlvertEX3FV (V3);

GLCOLOR4UBV (Green);

GLVERTEX3FV (V1);

Glcolor4ubv (Black);

Glvertex3FV (V5);

GLCOLOR4UBV (Orange);

GLVERTEX3FV (V6);

GLCOLOR4UBV (Green);

GLVERTEX3FV (V1);

GLCOLOR4UBV (Orange);

GLVERTEX3FV (V6);

Glcolor4ubv (Blue);

GLVERTEX3FV (V2);

Glcolor4ubv (Black);

Glvertex3FV (V5);

Glcolor4ubv (YELLOW);

Glvertex3FV (V4);

Glcolor4UBV (Purple);

Glvertex3FV (V7);

Glcolor4ubv (Black);

Glvertex3FV (V5);

Glcolor4UBV (Purple);

Glvertex3FV (V7);

GLCOLOR4UBV (Orange);

GLVERTEX3FV (V6);

Glcolor4ubv (YELLOW);

Glvertex3FV (V4);

GLCOLOR4UBV (RED);

GLVERTEX3FV (V0);

Glcolor4UBV (White);

GlvertEX3FV (V3);

Glcolor4ubv (YELLOW);

Glvertex3FV (V4);

Glcolor4UBV (White);

GlvertEX3FV (V3);

Glcolor4UBV (Purple);

Glvertex3FV (V7);

Glcolor4UBV (White);

GlvertEX3FV (V3);

Glcolor4ubv (Blue);

GLVERTEX3FV (V2);

GLCOLOR4UBV (Orange);

GLVERTEX3FV (V6);

Glcolor4UBV (White);

GlvertEX3FV (V3);

GLCOLOR4UBV (Orange);

GLVERTEX3FV (V6);

Glcolor4UBV (Purple);

Glvertex3FV (V7);

GLCOLOR4UBV (Green);

GLVERTEX3FV (V1);

GLCOLOR4UBV (RED);

GLVERTEX3FV (V0);

Glcolor4ubv (YELLOW);

Glvertex3FV (V4);

Glcolor4ubv (Green); GlvertEX3FV (V1);

Glcolor4ubv (YELLOW);

Glvertex3FV (V4);

Glcolor4ubv (Black);

Glvertex3FV (V5);

glend;

/ *

* EXERCISE:

* Draw text telling the user thing 'spc'

* pauses the rotation and 'ESC' Quits.

* Do It usings and textured quads.

* /

/ *

* Swap the buffers. This Tells the driver to

* Render the next frame from the contents of there

* Back-buffer, and to set all rendering Operations

* To Occur On What Was The Front-Buffer.

*

* Double Buffering Prevents Nasty Visual Tearing

* From the application drawing on store of the

* Screen That Are Being Updated At The Same Time.

* /

SDL_GL_SWAPBBUFFERS ();

}

Static void setup_opengl (int width, int hotht)

{

Float ratio = (float) width / (float) Height;

/ * Our Shading Model - Gouraud (Smooth). * /

Glshademodel (GL_SMOOTH);

/ * Culling. * /

GLCULLFACE (GL_BACK);

GLFRONTFACE (GL_CCW);

GLENABLE (GL_CULL_FACE);

/ * SET the CLOR. * /

GlclearColor (0, 0, 0, 0);

/ * Setup company viewport. * /

GLVIEWPORT (0, 0, Width, Height);

/ *

* Change to the Projection Matrix and Set

* Our Viewing Volume.

* /

Glmatrixmode (GL_PROJECTION);

GLLoadIndentity ();

/ *

* EXERCISE:

* Replace this with a call to glfrustum.

* /

Gluperspective (60.0, Ratio, 1.0, 1024.0);

}

Int main (int Argc, char * argv [])

{

/ * Information about the current video settings. * /

Const SDL_VideoInfo * info = NULL;

/ * Dimensions of out window. * /

INT width = 0;

INT height = 0;

/ * Color Depth in Bits of Our Window. * /

INT BPP = 0;

/ * Flags We Will Pass Into SDL_SETVIDEOMODE. * /

INT FLAGS = 0;

/ * First, Initialize SDL's Video Subsystem. * /

IF (SDL_INIT (SDL_INIT_VIDEO) <0) {

/ * Failed, exit. * / Fprintf (stderr, "Video Initialization Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

/ * Let's get some video information. * /

INFO = SDL_GETVIDEOINFO ();

IF (! info) {

/ * This kind probably never happen. * /

FPRINTF (stderr, "Video Query Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

/ *

* Setur Width / Height To 640/480 (you 10

* of Course Let the User Decide this in a Normal

* app). We get the bpp We Will Request from WE WILL REQUEST

* The Display. on X11, Vidmode Can't change

* Resolution, So this is probably being overly

* Safe. Under Win32, ChangeDisplaySettings

* can change the bpp.

* /

Width = 640;

HEIGHT = 480;

BPP = info-> vfmt-> bitsPerpixel;

/ *

* Now, we want to setup ur request

* Window Attributes for Our OpenGL Window.

* WE WANT * AT Least * 5 Bits of Red, Green

* And Blue. WEALSO WANT AT Least A 16-bit

* Depth buffer.

*

* The Last Thing We do Is Request A Double

* buffered window. '1' Turns on Double

* buffering, '0' Turns IT OFF.

*

* Note That We do not use SDL_DOUBLBUF IN

* The flags to sdl_setvideomode. That Does

* Not affect the gl attribute stat, ONLY

* The Standard 2D Blitting Setup.

* /

SDL_GL_SETATTRIBUTE (SDL_GL_RED_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_GREEN_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_BLUE_SIZE, 5);

SDL_GL_SETATTRIBUTE (SDL_GL_DEPTH_SIZE, 16);

SDL_GL_SETATTRIBUTE (SDL_GL_DOUBLEBUFFER, 1);

/ *

* WE Want To Request That SDL Provide US

* with an OpenGL WINDOW, IN A FULLSCREEN

* Video Mode.

*

* EXERCISE:

* Make Starting Windowed An Option, And

* Handle The Resize Events Properly with

* GLVIEWPORT.

* /

Flags = SDL_OPENGL | SDL_FULLSCREEN

/ *

* Set the video mode * /

IF (SDL_SETVIDEOMODE (Width, Height, BPP, FLAGS) == 0) {

/ *

* This Could Happen for a Variety of Reasons,

* Including Display Not Being Set, The Specified

* Resolution Not Being Available, ETC.

* /

FPRINTF (stderr, "Video Mode Set Failed:% S / N",

SDL_GETERROR ());

Quit_Tutorial (1);

}

/ *

* At this point, we shop has a protly setup

* Double-buffered window for use with opengl.

* /

Setup_opengl (width, height);

/ *

* Now we want to beg, ot Normal App Process -

* An Event loop with a lot of redrawing.

* /

While (1) {

/ * Process Incoming Events. * /

PROCESS_EVENTS ();

/ * DRAW the screen. * /

Draw_screen ();

}

/ *

* EXERCISE:

* Record Timings Using SDL_GETTICKS () and

* And Print Out Frames Per Second At Program

* end.

* /

/ * Never reached. * /

Return 0;

}

Chapter IIP Input Processing Initialization The first step of using the joystick is to initialize the game rod system. That is, use the parameter SDL_INIT_JOYSTICK when SDL_INIT. Example 3-1 Initializing SDL and supports IF (! SDL_Init_Video | SDL_INIT_JOYSTICK))

{

FPRINTF (stderr, "couldn't Initialize SDL:% S / N", SDL_GETERROR ());

Exit (1);

}

This example starts SDL and supports video and game poles. To this, we can assume that initialization is completed. But we still need to guide whether there are several game poles. Even if you guide a joystick available, it is best to check because this can help detect the case where the joystick is unplugged. Check the function of the game rod is SDL_NumJoySticks (). This function returns to the number of game rods in the system. The next step is to determine which one wants to use. Of course, if there is only one, you don't have to decide. SDL_JOYSTICKNAME obtains the name of the system assigned to the game pole. The game rod is specified by the serial number, the first one is 0, the last one is SDL_NumJoySticks - 1. Example 3-2 Print all the names of all game rods Printf ("% i joysticks werefact./n/n/n", SDL_NumJoySticks ());

Printf ("The Names of the JoySticks Are: / N");

For (i = 0; i

{

Printf ("% S / N", SDL_JOYSTICKNAME (i));

}

Start the game rod to obtain an event SDL use the event architecture, the game pole can trigger four events.

The SDL_JOYAXISEVENT axis changes the SDL_JOYBALLEVENT track ball coordinates to change SDL_JOYHATEVENT HAT (Sorry, where you don't understand HAT) Direction Change the SDL_JOYBUTTONEVENT button Press or release all started game rods to trigger events. In order to receive an event, first call SDL_JOYSTICKEVENTSTATE to use SDL_ENABLE to allow events. Second, start the specified joystick, use SDL_JOYSTICKOPEN (). Example 3-3 Start the first game rod SDL_JOYSTICK * JOYSTICK; SDL_JOYSTICKEVENTSTATE (SDL_ENABLE);

Joystick = SDL_JOYSTICKOPEN (0);

The pointer of the game pole object is only useful when querying and closing the game lever. Now we need a message loop for response. All SDL programs are at least to accept the system exit message. Imagine our message loop like this: SDL_EVENT EVENT;

/ * Other Initialization Code Goes Here * /

/ * Start main game loop here * /

While (SDL_POLLEVENT (& Event))

{

Switch (Event.Type)

{

Case SDL_KeyDown:

/ * Handle Keyboard Stuff Here * /

Break;

Case SDL_Quit:

/ * SET WhatEVER FLAGS Are Necessary to * /

/ * end the main game loop here * /

Break;

}

}

/ * End loop here * /

To respond to the game pole event, simply add a CASE. The axial detection is somewhat technique because most of the event is garbage. There will be an event in the rocker. So a threshold must be set and an event that does not reach the threshold is ignored. Generally 10% is a better threshold. Example 3-4 Game Rod Event Case SDL_JOYAXISMOTION: / * HANDLE JOYSTICK MOTION * /

IF ((Event.jaxis.Value <-3200) || (Event.jaxis.Value> 3200))

{

/ * Code Goes Here * /

}

Break;

Another trick is that up and down and left and right are different sports. The most important axis is shaft 0 (left and right) and shaft 1 (up and down). Different processing as follows: Example 3-5 Case SDL_JOYAXISMOTION: / * HANDLE JOYSTICK MOTION * /

IF ((Event.jaxis.Value <-3200) || (Event.jaxis.Value> 3200))

{

IF (event.jaxis.axis == 0)

{

/ * Left-right movement code goes here * /

}

IF (event.jaxis.axis == 1)

{

/ * UP-DOWN MOVEMENT CODE GoES Here * /

}

}

Break;

Ideally, you should use Event.jaxis.Value to adjust some values. For example, you can control the spacecraft with the game rod, push the rocker slowly, push a lot, quickly advance. This design will make the user experience better. If your game rod has more axes, it can be used for other controls, the usage is exactly, Event.jaxis.Axis will have different values. Example 3-6 Game Rod Button Event Case SDL_JOYBUTTONDOWN: / * Handle Joystick Button Presses * / if (Event.jButton.Button == 0)

{

/ * Code Goes Here * /

}

Break;

Button detection is very simple because only two status is pressed and released. SDL_JOYBUTTONUP triggers when SDL_JOYBUTTONDOWN is pressed. Event.jbutton.Button indicates which button. Finally, use SDL_JOYSTICKCLOSE () to close the game rod at the end of the program. For example, closing the first 0 yard rod: SDL_JOYSTICKCLOSE (JoyStick); Advanced Game Rod Function Trackball Message contains a change in the X and Y directions. Example 3-7 Trackball Events Case SDL_JOYBALLMOTION: / * HANDLE JOYBALL MOTION * /

IF (event.jball.ball == 0)

{

/ * Ball handling * /

}

Break;

This example detects the first trackball. Coordinate changes in Event.jball.xrel and Event.jball.yrel. Finally, the HAT event. HAT only reports the direction. We detected by bit mask: SDL_HAT_CENTERED

SDL_HAT_UP

SDL_HAT_RIGHT

SDL_HAT_DOWN

SDL_HAT_LEFT

Predefined combination: SDL_HAT_RIGHTUP

SDL_HAT_RIGHTDOWN

SDL_HAT_LEFTUP

SDL_HAT_LEFTDOWN

Example 3-8 Game Rod HAT Events Case SDL_JoyHatMotion: / * Handle Hat Motion * /

IF (Event.jhat.hat | SDL_HAT_UP)

{

/ * DO UP stuff here * /

}

IF (Event.jhat.hat | SDL_HAT_LEFT)

{

/ * Do Left stuff here * /

}

IF (Event.JHAT.HAT | SDL_HAT_RIGHTDOWN)

{

/ * Do Right and Down together Stuff Here * /

}

Break;

In addition to the number of joysticks, you can query:

SDL_JOYSTICKNUMAXES axes SDL_JOYSTICKNUMBATONS button Quantity SDL_JOYSTICKNUMBALLS Track Ball Quantity SDL_JOYSTICKNUMHATS HAT Quantity Simply transmits the pointer to these functions to these functions. Example 3-9 Query the game pole feature int number_of_buttons;

SDL_JOYSTICK * JOYSTICK;

Joystick = SDL_JOYSTICKOPEN (0);

Number_of_buttons = SDL_JOYSTICKNUMBUTTONS (JOYSTICK);

Chapter III Next Keyboard Enter the keyboard related data structure

SDLKEY enumeration type, each symbol represents a key, such as SDLK_A, SDLK_SPACE, defined in SDL_KeysyM.H. SDLMOD enumeration type, similar to SDLKey, but used for modification, such as Control, Alt, Shift, can be combined. SDL_KEYSYM TYPEDEF STRUCT {uint8 scancode;

SDLKey SYM;

SDLMOD MOD;

UINT16 Unicode;

} SDL_KEYSYM;

Used for button and release the message. Scancode is the hardware related key code. Unless you have special purposes, it is ignored. SYM indicate key, MOD is a set of modified keys, such as KMOD_NUM | KMOD_CAPS | KMOD_Lshift is Numlock, Capslock, and Left Shift. Finally Unicode is the corresponding character. Note that the Unicode is only valid when the button message is active, and it is invalid when the message is released. UNICODE transformation must be opened with SDL_enableunicode (). SDL_KEYBOARDEVENT TYPEDEF STRUCT {

Uint8 Type;

Uint8 state;

SDL_KEYSYM Keysym;

} SDL_KEYBOARDEVENT;

Describe a keyboard message. TYPE indicates button (SDL_KeyDown) or release (SDL_Keyup). State is redundant, and the meaning of the meaning of Type is different (SDL_PRESSED, SDL_RELEASED). Read the keyboard message Use the message loop to read from the message queue with SDL_pollevent () and detect SDL_KEYUP and SDL_KEYDOWN with Switch-Case. Here is a basic example. Example 3-10 Read the keyboard message SDL_EVENT Event;

.

.

/ * Poll for Events. SDL_POLLEVENT () Returns 0 when there is no * /

/ * More Events on The Event Queue, Our While Loop Will EXIT1 * /

/ * That Occurs. * /

While (SDL_POLLEVENT (& Event)) {

/ * WE Are Only Worried About SDL_KEYDOWN AND SDL_KEYUP Events * /

Switch (Event.Type) {

Case SDL_KeyDown:

Printf ("Key Press Detected / N");

Break;

Case SDL_KEYUP:

Printf ("Key Release Detected / N);

Break;

DEFAULT:

Break;

}

}

More detailed content We already know to initialize with SDL_INIT and SDL_SETVIDEODE, but we have to use two other functions to achieve the necessary information. To call SDL_enableunicode (1) to allow Unicode transform, use SDL_GetKeyName to convert SDLKEY to a printable character. Note: Unicode characters less than 0x80 are mapped directly to the ASCII code. The following example is used in this. Example 3-11 Explain Button Message #include "SDL.H"

/ * Function protoypes * /

Void PrintKeyInfo (SDL_KEYBOARDEVENT * KEY);

Void PrintModifiers (SDLMOD MOD);

/ * main * /

INT Main (int Argc, char * argv []) {SDL_EVENT Event;

INT quit = 0;

/ * Initialise SDL * /

IF (SDL_INIT (SDL_INIT_VIDEO)) {

FPRINTF (stderr, "could not initialise SDL:% S / N", SDL_GETERROR ());

EXIT (-1);

}

/ * SET A video mode * /

IF (! SDL_SETVIDEOMODE (320, 200, 0, 0)) {

FPrintf (stderr, "could not set video mod:% s / n", SDL_GETERROR ());

SDL_QUIT ();

EXIT (-1);

}

/ * Enable Unicode Translation * /

SDL_ENABLEUNICODE (1);

/ * Loop untric an SDL_QUIT EVENT IS FOUND * /

While (! quit) {

/ * Poll for Events * /

While (SDL_POLLEVENT (& Event)) {

Switch (Event.Type) {

/ * Keyboard Event * /

/ * Pass the Event Data ONTO PrintKeyInfo () * /

Case SDL_KeyDown:

Case SDL_KEYUP:

PRINTKEYINFO (& Event.Key);

Break;

/ * SDL_QUIT EVENT (Window Close) * /

Case SDL_Quit:

Quit = 1;

Break;

DEFAULT:

Break;

}

}

}

/ * Clean Up * /

SDL_QUIT ();

exit (0);

}

/ * Print All Information About a Key Event * /

Void PrintKeyInfo (SDL_KEYBOARDEVENT * KEY) {

/ * Is IT A Release OR a Press? * /

IF (key-> type == SDL_KEYUP)

Printf ("RELEASE: -");

Else

Printf ("Press: -");

/ * Print The Hardware Scancode First * /

Printf ("Scancode: 0x% 02x", Key-> Keysym.scancode);

/ * Print the name of the key * /

Printf (", Name:% S", SDL_GetKeyname (key-> keysym.sym);

/ * WE Want to Print The Unicode Info, But We need to make * /

/ * SURE ITS a Press Event First (Remember, Release Events * /

/ * Don't have unicode info * /

IF (key-> type == SDL_KEYDOWN) {

/ * If the unicode value is less 0x80 Then THE * /

/ * Unicode Value Can Be Used to get a printable * /

/ * Repesentation of the key, using (char) unicode. * / printf (", unicode:");

IF (Key-> Keysym.Unicode <0x80 && key-> keysym.unicode> 0) {

Printf ("% C (0x% 04x)", (char) key-> keysym.unicode,

Key-> Keysym.Unicode;

}

Else {

Printf ("? (0x% 04x)", key-> keysym.Unicode);

}

}

Printf ("/ n");

/ * Print Modifier Info * /

PrintModifiers (Key-> Keysym.mod);

}

/ * Print Modifier Info * /

Void PrintModifiers (SDLMOD MOD) {

Printf ("ModiFers:");

/ * If there are none thr

IF (MOD == kmod_none) {

Printf ("none / n");

Return;

}

/ * Check for the Presence of Each SDLMOD VALUE * /

/ * This looks message, but there real isn't * /

/ * a Clearer Way. * /

IF (MOD & KMOD_NUM) Printf ("Numlock");

IF (MOD & KMOD_CAPS) Printf ("Capslock");

IF (MOD & KMOD_LCTRL) PRINTF ("LCTR");

IF (MOD & KMOD_RCTRL) Printf ("rctrl");

IF (MOD & KMOD_RSHIFT) PRINTF ("Rshift");

IF (MOD & KMOD_LSHIFT) Printf ("lshift");

IF (MOD & KMOD_RALT) PRINTF ("Ralt");

IF (MOD & KMOD_LALT) PRINTF ("Lalt");

IF (MOD & KMOD_CTRL) PRINTF ("Ctrl");

IF (MOD & KMOD_SHIFT) Printf ("shift");

IF (MOD & KMOD_ALT) PRINTF ("alt");

Printf ("/ n");

}

The game keyboard Enter the keyboard message is only triggered when the status of the key is pressed and disconnected. Imagine you to control the spacecraft with the cursor keys to change the space scene seen in front of you, when you press the left mover and want the lens to turn left. Take a look at the following code and pay attention to why it is wrong. / * Alien Screen Coordinates * /

INT Alien_x = 0, alien_y = 0;

.

.

/ * Initialise SDL and Video Modio Modes and all this * /

.

/ * Main game loop * /

/ * Check for Events * /

While (SDL_Pollevent (& Event)) {switch (Event.Type) {

/ * Look for a keypress * /

Case SDL_KeyDown:

/ * Check the SDLKEY VALUES AND MOVE CHENGE THE COORDS * /

Switch (Event.key.Keysym.SYM) {

Case SDLK_LEFT:

Alien_x - = 1;

Break;

Case SDLK_Right:

Alien_x = 1;

Break;

Case SDLK_UP:

Alien_Y - = 1;

Break;

Case SDLK_DOWN:

Alien_Y = 1;

Break;

DEFAULT:

Break;

}

}

}

}

The problem is that you must press 100 左 to get 100 keyboard messages to turn 100 pixels left. The correct way is to set the flag when it receives an event, moves according to the flag. Example 3-12 Correct Motion Control / * Alien Screen Coordinates * /

INT Alien_x = 0, alien_y = 0;

INT alien_xvel = 0, alien_yvel = 0;

.

.

/ * Initialise SDL and Video Modio Modes and all this * /

.

/ * Main game loop * /

/ * Check for Events * /

While (SDL_POLLEVENT (& Event)) {

Switch (Event.Type) {

/ * Look for a keypress * /

Case SDL_KeyDown:

/ * Check the SDLKEY VALUES AND MOVE CHENGE THE COORDS * /

Switch (Event.key.Keysym.SYM) {

Case SDLK_LEFT:

Alien_xvel = -1;

Break;

Case SDLK_Right:

Alien_xvel = 1;

Break;

Case SDLK_UP:

Alien_yvel = -1;

Break;

Case SDLK_DOWN:

Alien_yvel = 1;

Break;

DEFAULT:

Break;

}

Break;

/ * WE MUST Also Use the SDL_KEYUP Events to Zero the x * /

/ * And Y Velocity Variables. But we must also be * /

/ * Careful Not to Zero the velocities when we shopn't * /

Case SDL_KEYUP:

Switch (Event.key.Keysym.SYM) {

Case SDLK_LEFT:

/ * WE Check to make Sure the alien is moving * /

/ * to the left. if it is the weight izro the * /

/ * velocity. if the alien is moving to the * /

/ * Right THEN THE Right Key Is Still Press * /

/ * so we don't tocuh the velocity * /

IF (alien_xvel <0)

Alien_xvel = 0;

Break;

Case SDLK_Right:

IF (alien_xvel> 0)

Alien_xvel = 0;

Break; Case SDLK_UP:

IF (alien_yvel <0)

Alien_yvel = 0;

Break;

Case SDLK_DOWN:

IF (alien_yvel> 0)

Alien_yvel = 0;

Break;

DEFAULT:

Break;

}

Break;

DEFAULT:

Break;

}

}

.

.

/ * Update the alien position * /

Alien_x = alien_xvel;

Alien_y = alien_yvel;

As you can see, we used two variables Alien_xvel and Alien_yvel to represent the sport of the spacecraft and update them when responding to the keyboard message. Chapter 4 Shots: Duplicate examples do not list the fastest image flat block transfer to draw images on the screen: 1. Create an image plane and transfer to the screen with SDL_BlitSurface; 2. Create a video plane in system memory And call SDL_UPDATERECT; 3. Create a video plane in the memory and call SDL_LOCKSURFACE. The best way is a mixing method: #include

#include

#include "sdl.h"

#include "sdl_timer.h"

Void Complainandexit (Void)

{

FPRINTF (stderr, "problem:% s / n", SDL_GETERROR ());

Exit (1);

}

Int main (int Argc, char * argv [])

{

SDL_PIXELFORMAT FMT;

SDL_SURFACE * Screen, * locked;

SDL_SURFACE * imageBMP, * image;

SDL_RECT DSTRECT;

INT I;

Uint8 * buffer;

/ * Initialize SDL * /

IF (SDL_INIT (SDL_INIT_VIDEO) <0) {

Complainandexit ();

}

Atexit (SDL_QUIT);

/ * LOAD A BMP Image INTO A SURFACE * /

ImageBMP = SDL_LOADBMP ("Image.BMP");

IF (imageBMP == null) {

Complainandexit ();

}

/ * Set the video mode (640x480 at native depth) * /

Screen = SDL_SETVIDEOMODE (640, 480, 0, SDL_HWSURFACE | SDL_FULLSCREEN);

IF (screen == null) {

Complainandexit ();

}

/ * Set the video colorMap * /

IF (imageBMP-> format-> palette! = null) {

SDL_SETCOLORS (Screen,

ImageBMP-> Format-> Palette-> Colors, 0,

ImageBMP-> Format-> Palette-> ncolors);

}

/ * Convert the Image to the video format (Maps Colors) * /

Image = SDL_DISPLAYFORMAT (ImageBMP);

SDL_FREESURFACE (ImageBMP);

IF (image == null) {

Complainandexit ();

/ * Draw Bands of Color on the Raw Surface * /

IF (SDL_Mustlock (Screen)) {

IF (SDL_LOCKSURFACE (SCREEN) <0)

Complainandexit ();

}

Buffer = (uint8 *) screen-> pixels;

For (i = 0; i

h; i) {

MEMSET (Buffer, (i * 255) / screen-> H,

Screen-> w * screen-> format-> bytesperpixel);

Buffer = Screen-> Pitch;

}

IF

SDL_Mustlock (Screen)) {

SDL_Unlocksurface (screen);

}

/ * Blit the image to the center of the screen * /

DSTRECT.X = (Screen-> w-image-> w) / 2;

DSTRECT.Y = (Screen-> H-Image-> H) / 2;

DSTRECT.W = image-> w;

DSTRECT.H = image-> h;

IF

SDL_BLITSURFACE (Image, Null, Screen, & DSTRECT) <0) {

SDL_FREESURFACE (Image);

Complainandexit ();

}

SDL_FREESURFACE (Image);

/ * Update the screen * /

SDL_UPDATERECTS (Screen, 1, & DSTRECT);

SDL_DELAY (5000); / * Wait 5 seconds * /

exit (0);

}

Filtering and handling incident #include

#include

#include "sdl.h"

/ * This function allows in a Separate Event thread * /

INT Filterevents (const SDL_Event * Event) {

Static int boycott = 1;

/ * This quit event signals the closing of the window * /

IF ((Event-> Type == SDL_QUIT) && boycott) {

Printf ("Quit Event Filtered Out - Try Again./N");

Boycott = 0;

Return (0);

}

IF (Event-> Type == SDL_MOUSEMOTION) {

Printf ("Mouse Moved to (% D,% D) / N",

Event-> motion.x, esent-> motion.y);

Return (0); / * DROP IT, We've Handled It * /

}

Return (1);

}

Int main (int Argc, char * argv [])

{

SDL_EVENT EVENT;

/ * Initialize the SDL Library * /

IF (SDL_INIT (SDL_INIT_VIDEO) <0) {

FPRINTF (stderr,

"Couldn't Initialize SDL:% S / N", SDL_GETERROR ()); exit (1);

}

/ * Clean Up on exit, exit on window close and interface /

Atexit (SDL_QUIT);

/ * IGNORE Key Events * /

SDL_EventState (SDL_KEYDOWN, SDL_IGNORE);

SDL_EventState (SDL_KEYUP, SDL_IGNORE);

/ * Filter Quit and Mouse motion events * /

SDL_SETEVENTFILTER (Filterevents);

/ * The mouse isn't MUCH USE UNESS WE HAVE A DISPLAY for Reference * /

IF (SDL_SETVIDEOMODE (640, 480, 8, 0) == null) {

FPRINTF (stderr, "couldn't set 640x480x8 video mode:% s / n",

SDL_GETERROR ());

Exit (1);

}

/ * Loop wait for esc mouse_button * /

While (SDL_Waitevent (& Event)> = 0) {

Switch (Event.Type) {

Case SDL_ACTIVENT: {

IF (event.active.state & sdl_appactive) {

Event.active.gain {

Printf ("App Activated / N");

} else {

Printf ("app iconified / n");

}

}

}

Break;

Case SDL_MouseButtondown: {

Uint8 * keys;

Keys = SDL_GETKEYSTATE (NULL);

IF (Keys [SDLK_ESCAPE] == SDL_PRESSED) {

Printf ("BYE BYE ... / N");

exit (0);

}

Printf ("Mouse Button Pressed / N");

}

Break;

Case SDL_QUIT: {

Printf ("Quit Requested, Quitting./N");

exit (0);

}

Break;

}

}

/ * This kind never happen * /

Printf ("SDL_Waitevent Error:% S / N", SDL_GETERROR ());

Exit (1);

}

Open the audio device SDL_AUDIOSPEC WANTED;

EXTERN VOID FILL_AUDIO (Void * UData, uint8 * stream, int LEN);

/ * SET the AUDIO FORMAT * /

WANTED.FREQ = 22050;

WANTED.FORMAT = AUDIO_S16;

WANTED.CHANNELS = 2; / * 1 = mono, 2 = STEREO * /

WANTED.SAMPLES = 1024; / * Good low-latency value for callback * /

WANTED.CALLBACK = Fill_Audio;

WANTED.USERDATA = NULL;

/ * Open the Audio Device, Forcing the Desired Format * / IF (SDL_OpenAudio (& Wanted, NULL) <0) {

FPRINTF (stderr, "couldn't open audio:% s / n", SDL_GETERROR ());

Return (-1);

}

Return (0);

Playing audio static uint8 * audio_chunk;

Static uint32 audio_len;

Static uint8 * audio_pos;

/ * The Audio Function Callback Takes The Following Parameters:

Stream: a Pointer to the Audio Buffer to Be Filled

Len: The Length (in bytes) of the Audio Buffer

* /

Void Fill_Audio (Void * UData, uint8 * stream, int LEN)

{

/ * ONLY Play if We since Data Left * /

IF (audio_len == 0)

Return;

/ * MIX as a data as possible * /

LEN = (LEN> AUDIO_LEN? AUDIO_LEN: LEN);

SDL_MixAudio (stream, audio_pos, len, sdl_mix_maxvolume)

Audio_pos = Len;

Audio_len - = len;

}

/ * Load the Audio Data ... * /

;;;;;

Audio_pos = audio_chunk;

/ * Let the callback function play the audio chunk * /

SDL_PAUSEAUDIO (0);

/ * Do some processing * /

;;;;;

/ * Wait for Sound to Complete * /

While (Audio_len> 0) {

SDL_DELAY (100); / * Sleep 1/10 Second * /

}

SDL_Closeaudio ();

List all CDROM #include "sdl.h"

/ * Initialize SDL first * /

IF (SDL_INIT (SDL_INIT_CDROM) <0) {

FPRINTF (stderr, "couldn't Initialize SDL:% S / N", SDL_GETERROR ());

Exit (1);

}

Atexit (SDL_QUIT);

/ * Find Out How Many CD-ROM Drives Are Connected to The System * /

Printf ("Drives Available:% D / N", SDL_CDNUMDRIVES ());

For (i = 0; i

Printf ("DRIVE% D: /"% s / "/ n", i, sdl_cdname (i));

}

Open the default CDROM drive SDL_CD * CDROM;

CDSTATUS STATUS;

CHAR * STATUS_STR;

CDROM = SDL_CDOPEN (0);

IF (CDROM == NULL) {

FPRINTF (stderr, "couldn't open default cd-rom drive:% s / n", SDL_GETERROR ());

EXIT (2);

}

STATUS = SDL_CDSTATUS (CDROM);

Switch (status) {

Case CD_TRAYEMPTY:

Status_str = "TRAY EMPTY";

Break;

Case CD_Stopped:

Status_str = "stopped";

Break;

Case CD_PLAYING:

Status_str = "playing";

Break;

Case CD_PAUSED:

Status_str = "paused";

Break;

Case CD_ERROR:

Status_str = "Error State";

Break;

}

Printf ("Drive Status:% S / N", STATUS_STR);

IF (status> = cd_playing) {

INT M, S, F;

FRAMES_TO_MSF (CDROM-> Cur_Frame, & M, & S, & F);

Printf ("Currently Playing TRACK% D,% D:% 2.2D / N",

CDROM-> Track [CDROM-> CUR_TRACK] .ID, M, S);

}

List all the tracks SDL_CD * CDROM; / * Assuming this Has Already Been Set.. * /

INT I;

INT M, S, F;

SDL_CDSTATUS (CDROM);

Printf ("Drive Tracks:% D / N", CDROM-> NUMTRACKS;

For (i = 0; i nuMTracks; i) {

Frames_to_msf (CDROM-> Track [i] .length, & m, & s, & f);

IF (f> 0)

S;

Printf ("/ TTRACK (index% D)% D:% D:% 2.2D / N", I,

CDROM-> Track [i] .id, m, s);

}

Play CD SDL_CD * CDROM; / * Assuming this Has Already Been Set .. * /

// Play Entire CD:

IF (cd_indrive (SDL_CDSTATUS (CDROM)))

SDL_CDPlayTracks (CDROM, 0, 0, 0, 0);

// Play Last TRACK:

IF (cd_indrive (sdl_cdstatus (cdrom)) {

SDL_CDPlayTracks (CDROM, CDROM-> NUMTRACKS-1, 0, 0, 0);

}

// Play First and Second TRACK AND 10 SECONDS OF THIRD TRACK:

IF (cd_indrive (SDL_CDSTATUS (CDROM)))

SDL_CDPLAYTRACKS (CDROM, 0, 0, 2, 10);

Time-based game master cycle #define Tick_Interval 30

UINT32 TIMELEFT (VOID)

{

STATIC uint32 next_time = 0;

UINT32 NOW;

Now = SDL_GETTICKS (); if (Next_Time <= now) {

Next_time = now Tick_Interval;

Return (0);

}

Return (Next_Time-now);

}

/ * Main game loop

While (Game_Running) {

Updategamestate ();

SDL_DELAY (Timeleft ());

}

转载请注明原文地址:https://www.9cbs.com/read-59956.html

New Post(0)