Added a README file regarding WinRT support

To note, this file is currently formatted with CRLF line endings, rather than
LF, to allow the file to be viewed with Notepad.
This commit is contained in:
David Ludwig 2014-04-09 21:29:19 -04:00
commit 3dcb451f85
1838 changed files with 474982 additions and 0 deletions

View file

@ -0,0 +1,239 @@
/*
* accelerometer.c
* written by Holmes Futrell
* use however you want
*/
#include "SDL.h"
#include "math.h"
#include "common.h"
#define MILLESECONDS_PER_FRAME 16 /* about 60 frames per second */
#define DAMPING 0.5f; /* after bouncing off a wall, damping coefficient determines final speed */
#define FRICTION 0.0008f /* coefficient of acceleration that opposes direction of motion */
#define GRAVITY_CONSTANT 0.004f /* how sensitive the ship is to the accelerometer */
/* If we aren't on an iPhone, then this definition ought to yield reasonable behavior */
#ifndef SDL_IPHONE_MAX_GFORCE
#define SDL_IPHONE_MAX_GFORCE 5.0f
#endif
static SDL_Joystick *accelerometer; /* used for controlling the ship */
static struct
{
float x, y; /* position of ship */
float vx, vy; /* velocity of ship (in pixels per millesecond) */
SDL_Rect rect; /* (drawn) position and size of ship */
} shipData;
static SDL_Texture *ship = 0; /* texture for spaceship */
static SDL_Texture *space = 0; /* texture for space (background */
void
render(SDL_Renderer *renderer, int w, int h)
{
/* get joystick (accelerometer) axis values and normalize them */
float ax = SDL_JoystickGetAxis(accelerometer, 0);
float ay = SDL_JoystickGetAxis(accelerometer, 1);
/* ship screen constraints */
Uint32 minx = 0.0f;
Uint32 maxx = w - shipData.rect.w;
Uint32 miny = 0.0f;
Uint32 maxy = h - shipData.rect.h;
#define SINT16_MAX ((float)(0x7FFF))
/* update velocity from accelerometer
the factor SDL_IPHONE_MAX_G_FORCE / SINT16_MAX converts between
SDL's units reported from the joytick, and units of g-force, as reported by the accelerometer
*/
shipData.vx +=
ax * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
MILLESECONDS_PER_FRAME;
shipData.vy +=
ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
MILLESECONDS_PER_FRAME;
float speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy);
if (speed > 0) {
/* compensate for friction */
float dirx = shipData.vx / speed; /* normalized x velocity */
float diry = shipData.vy / speed; /* normalized y velocity */
/* update velocity due to friction */
if (speed - FRICTION * MILLESECONDS_PER_FRAME > 0) {
/* apply friction */
shipData.vx -= dirx * FRICTION * MILLESECONDS_PER_FRAME;
shipData.vy -= diry * FRICTION * MILLESECONDS_PER_FRAME;
} else {
/* applying friction would MORE than stop the ship, so just stop the ship */
shipData.vx = 0.0f;
shipData.vy = 0.0f;
}
}
/* update ship location */
shipData.x += shipData.vx * MILLESECONDS_PER_FRAME;
shipData.y += shipData.vy * MILLESECONDS_PER_FRAME;
if (shipData.x > maxx) {
shipData.x = maxx;
shipData.vx = -shipData.vx * DAMPING;
} else if (shipData.x < minx) {
shipData.x = minx;
shipData.vx = -shipData.vx * DAMPING;
}
if (shipData.y > maxy) {
shipData.y = maxy;
shipData.vy = -shipData.vy * DAMPING;
} else if (shipData.y < miny) {
shipData.y = miny;
shipData.vy = -shipData.vy * DAMPING;
}
/* draw the background */
SDL_RenderCopy(renderer, space, NULL, NULL);
/* draw the ship */
shipData.rect.x = shipData.x;
shipData.rect.y = shipData.y;
SDL_RenderCopy(renderer, ship, NULL, &shipData.rect);
/* update screen */
SDL_RenderPresent(renderer);
}
void
initializeTextures(SDL_Renderer *renderer)
{
SDL_Surface *bmp_surface;
/* load the ship */
bmp_surface = SDL_LoadBMP("ship.bmp");
if (bmp_surface == NULL) {
fatalError("could not ship.bmp");
}
/* set blue to transparent on the ship */
SDL_SetColorKey(bmp_surface, 1,
SDL_MapRGB(bmp_surface->format, 0, 0, 255));
/* create ship texture from surface */
ship = SDL_CreateTextureFromSurface(renderer, bmp_surface);
if (ship == 0) {
fatalError("could not create ship texture");
}
SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND);
/* set the width and height of the ship from the surface dimensions */
shipData.rect.w = bmp_surface->w;
shipData.rect.h = bmp_surface->h;
SDL_FreeSurface(bmp_surface);
/* load the space background */
bmp_surface = SDL_LoadBMP("space.bmp");
if (bmp_surface == NULL) {
fatalError("could not load space.bmp");
}
/* create space texture from surface */
space = SDL_CreateTextureFromSurface(renderer, bmp_surface);
if (space == 0) {
fatalError("could not create space texture");
}
SDL_FreeSurface(bmp_surface);
}
int
main(int argc, char *argv[])
{
SDL_Window *window; /* main window */
SDL_Renderer *renderer;
Uint32 startFrame; /* time frame began to process */
Uint32 endFrame; /* time frame ended processing */
Sint32 delay; /* time to pause waiting to draw next frame */
int done; /* should we clean up and exit? */
int w, h;
/* initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
fatalError("Could not initialize SDL");
}
/* create main window and renderer */
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL |
SDL_WINDOW_FULLSCREEN);
renderer = SDL_CreateRenderer(window, 0, 0);
SDL_GetWindowSize(window, &w, &h);
/* print out some info about joysticks and try to open accelerometer for use */
printf("There are %d joysticks available\n", SDL_NumJoysticks());
printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
accelerometer = SDL_JoystickOpen(0);
if (accelerometer == NULL) {
fatalError("Could not open joystick (accelerometer)");
}
printf("joystick number of axis = %d\n",
SDL_JoystickNumAxes(accelerometer));
printf("joystick number of hats = %d\n",
SDL_JoystickNumHats(accelerometer));
printf("joystick number of balls = %d\n",
SDL_JoystickNumBalls(accelerometer));
printf("joystick number of buttons = %d\n",
SDL_JoystickNumButtons(accelerometer));
/* load graphics */
initializeTextures(renderer);
/* setup ship */
shipData.x = (w - shipData.rect.w) / 2;
shipData.y = (h - shipData.rect.h) / 2;
shipData.vx = 0.0f;
shipData.vy = 0.0f;
done = 0;
/* enter main loop */
while (!done) {
startFrame = SDL_GetTicks();
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
done = 1;
}
}
render(renderer, w, h);
endFrame = SDL_GetTicks();
/* figure out how much time we have left, and then sleep */
delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
if (delay < 0) {
delay = 0;
} else if (delay > MILLESECONDS_PER_FRAME) {
delay = MILLESECONDS_PER_FRAME;
}
SDL_Delay(delay);
}
/* delete textures */
SDL_DestroyTexture(ship);
SDL_DestroyTexture(space);
/* shutdown SDL */
SDL_Quit();
return 0;
}

View file

@ -0,0 +1,36 @@
/*
* common.c
* written by Holmes Futrell
* use however you want
*/
#include "common.h"
#include "SDL.h"
#include <stdlib.h>
/*
Produces a random int x, min <= x <= max
following a uniform distribution
*/
int
randomInt(int min, int max)
{
return min + rand() % (max - min + 1);
}
/*
Produces a random float x, min <= x <= max
following a uniform distribution
*/
float
randomFloat(float min, float max)
{
return rand() / (float) RAND_MAX *(max - min) + min;
}
void
fatalError(const char *string)
{
printf("%s: %s\n", string, SDL_GetError());
exit(1);
}

View file

@ -0,0 +1,12 @@
/*
* common.h
* written by Holmes Futrell
* use however you want
*/
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
extern int randomInt(int min, int max);
extern float randomFloat(float min, float max);
extern void fatalError(const char *string);

View file

@ -0,0 +1,475 @@
/*
* fireworks.c
* written by Holmes Futrell
* use however you want
*/
#include "SDL.h"
#include "SDL_opengles.h"
#include "common.h"
#include <math.h>
#include <time.h>
#define MILLESECONDS_PER_FRAME 16 /* about 60 frames per second */
#define ACCEL 0.0001f /* acceleration due to gravity, units in pixels per millesecond squared */
#define WIND_RESISTANCE 0.00005f /* acceleration per unit velocity due to wind resistance */
#define MAX_PARTICLES 2000 /* maximum number of particles displayed at once */
static GLuint particleTextureID; /* OpenGL particle texture id */
static SDL_bool pointSizeExtensionSupported; /* is GL_OES_point_size_array supported ? */
/*
used to describe what type of particle a given struct particle is.
emitter - this particle flies up, shooting off trail particles, then finally explodes into dust particles.
trail - shoots off, following emitter particle
dust - radiates outwards from emitter explosion
*/
enum particleType
{
emitter = 0,
trail,
dust
};
/*
struct particle is used to describe each particle displayed on screen
*/
struct particle
{
GLfloat x; /* x position of particle */
GLfloat y; /* y position of particle */
GLubyte color[4]; /* rgba color of particle */
GLfloat size; /* size of particle in pixels */
GLfloat xvel; /* x velocity of particle in pixels per milesecond */
GLfloat yvel; /* y velocity of particle in pixels per millescond */
int isActive; /* if not active, then particle is overwritten */
enum particleType type; /* see enum particleType */
} particles[MAX_PARTICLES]; /* this array holds all our particles */
static int num_active_particles; /* how many members of the particle array are actually being drawn / animated? */
static int screen_w, screen_h;
/* function declarations */
void spawnTrailFromEmitter(struct particle *emitter);
void spawnEmitterParticle(GLfloat x, GLfloat y);
void explodeEmitter(struct particle *emitter);
void initializeParticles(void);
void initializeTexture();
int nextPowerOfTwo(int x);
void drawParticles();
void stepParticles(void);
/* helper function (used in texture loading)
returns next power of two greater than or equal to x
*/
int
nextPowerOfTwo(int x)
{
int val = 1;
while (val < x) {
val *= 2;
}
return val;
}
/*
steps each active particle by timestep MILLESECONDS_PER_FRAME
*/
void
stepParticles(void)
{
int i;
struct particle *slot = particles;
struct particle *curr = particles;
for (i = 0; i < num_active_particles; i++) {
/* is the particle actually active, or is it marked for deletion? */
if (curr->isActive) {
/* is the particle off the screen? */
if (curr->y > screen_h)
curr->isActive = 0;
else if (curr->y < 0)
curr->isActive = 0;
if (curr->x > screen_w)
curr->isActive = 0;
else if (curr->x < 0)
curr->isActive = 0;
/* step velocity, then step position */
curr->yvel += ACCEL * MILLESECONDS_PER_FRAME;
curr->xvel += 0.0f;
curr->y += curr->yvel * MILLESECONDS_PER_FRAME;
curr->x += curr->xvel * MILLESECONDS_PER_FRAME;
/* particle behavior */
if (curr->type == emitter) {
/* if we're an emitter, spawn a trail */
spawnTrailFromEmitter(curr);
/* if we've reached our peak, explode */
if (curr->yvel > 0.0) {
explodeEmitter(curr);
}
} else {
float speed =
sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel);
/* if wind resistance is not powerful enough to stop us completely,
then apply winde resistance, otherwise just stop us completely */
if (WIND_RESISTANCE * MILLESECONDS_PER_FRAME < speed) {
float normx = curr->xvel / speed;
float normy = curr->yvel / speed;
curr->xvel -=
normx * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
curr->yvel -=
normy * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
} else {
curr->xvel = curr->yvel = 0; /* stop particle */
}
if (curr->color[3] <= MILLESECONDS_PER_FRAME * 0.1275f) {
/* if this next step will cause us to fade out completely
then just mark for deletion */
curr->isActive = 0;
} else {
/* otherwise, let's fade a bit more */
curr->color[3] -= MILLESECONDS_PER_FRAME * 0.1275f;
}
/* if we're a dust particle, shrink our size */
if (curr->type == dust)
curr->size -= MILLESECONDS_PER_FRAME * 0.010f;
}
/* if we're still active, pack ourselves in the array next
to the last active guy (pack the array tightly) */
if (curr->isActive)
*(slot++) = *curr;
} /* endif (curr->isActive) */
curr++;
}
/* the number of active particles is computed as the difference between
old number of active particles, where slot points, and the
new size of the array, where particles points */
num_active_particles = slot - particles;
}
/*
This draws all the particles shown on screen
*/
void
drawParticles()
{
/* draw the background */
glClear(GL_COLOR_BUFFER_BIT);
/* set up the position and color pointers */
glVertexPointer(2, GL_FLOAT, sizeof(struct particle), particles);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct particle),
particles[0].color);
if (pointSizeExtensionSupported) {
/* pass in our array of point sizes */
glPointSizePointerOES(GL_FLOAT, sizeof(struct particle),
&(particles[0].size));
}
/* draw our particles! */
glDrawArrays(GL_POINTS, 0, num_active_particles);
}
/*
This causes an emitter to explode in a circular bloom of dust particles
*/
void
explodeEmitter(struct particle *emitter)
{
/* first off, we're done with this particle, so turn active off */
emitter->isActive = 0;
int i;
for (i = 0; i < 200; i++) {
if (num_active_particles >= MAX_PARTICLES)
return;
/* come up with a random angle and speed for new particle */
float theta = randomFloat(0, 2.0f * 3.141592);
float exponent = 3.0f;
float speed = randomFloat(0.00, powf(0.17, exponent));
speed = powf(speed, 1.0f / exponent);
/* select the particle at the end of our array */
struct particle *p = &particles[num_active_particles];
/* set the particles properties */
p->xvel = speed * cos(theta);
p->yvel = speed * sin(theta);
p->x = emitter->x + emitter->xvel;
p->y = emitter->y + emitter->yvel;
p->isActive = 1;
p->type = dust;
p->size = 15;
/* inherit emitter's color */
p->color[0] = emitter->color[0];
p->color[1] = emitter->color[1];
p->color[2] = emitter->color[2];
p->color[3] = 255;
/* our array has expanded at the end */
num_active_particles++;
}
}
/*
This spawns a trail particle from an emitter
*/
void
spawnTrailFromEmitter(struct particle *emitter)
{
if (num_active_particles >= MAX_PARTICLES)
return;
/* select the particle at the slot at the end of our array */
struct particle *p = &particles[num_active_particles];
/* set position and velocity to roughly that of the emitter */
p->x = emitter->x + randomFloat(-3.0, 3.0);
p->y = emitter->y + emitter->size / 2.0f;
p->xvel = emitter->xvel + randomFloat(-0.005, 0.005);
p->yvel = emitter->yvel + 0.1;
/* set the color to a random-ish orangy type color */
p->color[0] = (0.8f + randomFloat(-0.1, 0.0)) * 255;
p->color[1] = (0.4f + randomFloat(-0.1, 0.1)) * 255;
p->color[2] = (0.0f + randomFloat(0.0, 0.2)) * 255;
p->color[3] = (0.7f) * 255;
/* set other attributes */
p->size = 10;
p->type = trail;
p->isActive = 1;
/* our array has expanded at the end */
num_active_particles++;
}
/*
spawns a new emitter particle at the bottom of the screen
destined for the point (x,y).
*/
void
spawnEmitterParticle(GLfloat x, GLfloat y)
{
if (num_active_particles >= MAX_PARTICLES)
return;
/* find particle at endpoint of array */
struct particle *p = &particles[num_active_particles];
/* set the color randomly */
switch (rand() % 4) {
case 0:
p->color[0] = 255;
p->color[1] = 100;
p->color[2] = 100;
break;
case 1:
p->color[0] = 100;
p->color[1] = 255;
p->color[2] = 100;
break;
case 2:
p->color[0] = 100;
p->color[1] = 100;
p->color[2] = 255;
break;
case 3:
p->color[0] = 255;
p->color[1] = 150;
p->color[2] = 50;
break;
}
p->color[3] = 255;
/* set position to (x, screen_h) */
p->x = x;
p->y = screen_h;
/* set velocity so that terminal point is (x,y) */
p->xvel = 0;
p->yvel = -sqrt(2 * ACCEL * (screen_h - y));
/* set other attributes */
p->size = 10;
p->type = emitter;
p->isActive = 1;
/* our array has expanded at the end */
num_active_particles++;
}
/* just sets the endpoint of the particle array to element zero */
void
initializeParticles(void)
{
num_active_particles = 0;
}
/*
loads the particle texture
*/
void
initializeTexture()
{
int bpp; /* texture bits per pixel */
Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */
SDL_Surface *bmp_surface; /* the bmp is loaded here */
SDL_Surface *bmp_surface_rgba8888; /* this serves as a destination to convert the BMP
to format passed into OpenGL */
bmp_surface = SDL_LoadBMP("stroke.bmp");
if (bmp_surface == NULL) {
fatalError("could not load stroke.bmp");
}
/* Grab info about format that will be passed into OpenGL */
SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ABGR8888, &bpp, &Rmask, &Gmask,
&Bmask, &Amask);
/* Create surface that will hold pixels passed into OpenGL */
bmp_surface_rgba8888 =
SDL_CreateRGBSurface(0, bmp_surface->w, bmp_surface->h, bpp, Rmask,
Gmask, Bmask, Amask);
/* Blit to this surface, effectively converting the format */
SDL_BlitSurface(bmp_surface, NULL, bmp_surface_rgba8888, NULL);
glGenTextures(1, &particleTextureID);
glBindTexture(GL_TEXTURE_2D, particleTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
nextPowerOfTwo(bmp_surface->w),
nextPowerOfTwo(bmp_surface->h),
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* this is where we actually pass in the pixel data */
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bmp_surface->w, bmp_surface->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, bmp_surface_rgba8888->pixels);
/* free bmp surface and converted bmp surface */
SDL_FreeSurface(bmp_surface);
SDL_FreeSurface(bmp_surface_rgba8888);
}
int
main(int argc, char *argv[])
{
SDL_Window *window; /* main window */
SDL_GLContext context;
int w, h;
Uint32 startFrame; /* time frame began to process */
Uint32 endFrame; /* time frame ended processing */
Uint32 delay; /* time to pause waiting to draw next frame */
int done; /* should we clean up and exit? */
/* initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fatalError("Could not initialize SDL");
}
/* seed the random number generator */
srand(time(NULL));
/*
request some OpenGL parameters
that may speed drawing
*/
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
/* create main window and renderer */
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL |
SDL_WINDOW_BORDERLESS);
context = SDL_GL_CreateContext(window);
/* load the particle texture */
initializeTexture();
/* check if GL_POINT_SIZE_ARRAY_OES is supported
this is used to give each particle its own size
*/
pointSizeExtensionSupported =
SDL_GL_ExtensionSupported("GL_OES_point_size_array");
/* set up some OpenGL state */
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
SDL_GetWindowSize(window, &screen_w, &screen_h);
glViewport(0, 0, screen_w, screen_h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof((GLfloat) 0,
(GLfloat) screen_w,
(GLfloat) screen_h,
(GLfloat) 0, 0.0, 1.0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_POINT_SPRITE_OES);
glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, 1);
if (pointSizeExtensionSupported) {
/* we use this to set the sizes of all the particles */
glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
} else {
/* if extension not available then all particles have size 10 */
glPointSize(10);
}
done = 0;
/* enter main loop */
while (!done) {
startFrame = SDL_GetTicks();
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
done = 1;
}
if (event.type == SDL_MOUSEBUTTONDOWN) {
int x, y;
SDL_GetMouseState(&x, &y);
spawnEmitterParticle(x, y);
}
}
stepParticles();
drawParticles();
SDL_GL_SwapWindow(window);
endFrame = SDL_GetTicks();
/* figure out how much time we have left, and then sleep */
delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
if (delay > MILLESECONDS_PER_FRAME) {
delay = MILLESECONDS_PER_FRAME;
}
if (delay > 0) {
SDL_Delay(delay);
}
}
/* delete textures */
glDeleteTextures(1, &particleTextureID);
/* shutdown SDL */
SDL_Quit();
return 0;
}

177
Xcode-iOS/Demos/src/happy.c Normal file
View file

@ -0,0 +1,177 @@
/*
* happy.c
* written by Holmes Futrell
* use however you want
*/
#include "SDL.h"
#include "common.h"
#define NUM_HAPPY_FACES 100 /* number of faces to draw */
#define MILLESECONDS_PER_FRAME 16 /* about 60 frames per second */
#define HAPPY_FACE_SIZE 32 /* width and height of happyface (pixels) */
static SDL_Texture *texture = 0; /* reference to texture holding happyface */
static struct
{
float x, y; /* position of happyface */
float xvel, yvel; /* velocity of happyface */
} faces[NUM_HAPPY_FACES];
/*
Sets initial positions and velocities of happyfaces
units of velocity are pixels per millesecond
*/
void
initializeHappyFaces()
{
int i;
for (i = 0; i < NUM_HAPPY_FACES; i++) {
faces[i].x = randomFloat(0.0f, SCREEN_WIDTH - HAPPY_FACE_SIZE);
faces[i].y = randomFloat(0.0f, SCREEN_HEIGHT - HAPPY_FACE_SIZE);
faces[i].xvel = randomFloat(-0.1f, 0.1f);
faces[i].yvel = randomFloat(-0.1f, 0.1f);
}
}
void
render(SDL_Renderer *renderer)
{
int i;
SDL_Rect srcRect;
SDL_Rect dstRect;
/* setup boundaries for happyface bouncing */
Uint16 maxx = SCREEN_WIDTH - HAPPY_FACE_SIZE;
Uint16 maxy = SCREEN_HEIGHT - HAPPY_FACE_SIZE;
Uint16 minx = 0;
Uint16 miny = 0;
/* setup rects for drawing */
srcRect.x = 0;
srcRect.y = 0;
srcRect.w = HAPPY_FACE_SIZE;
srcRect.h = HAPPY_FACE_SIZE;
dstRect.w = HAPPY_FACE_SIZE;
dstRect.h = HAPPY_FACE_SIZE;
/* fill background in with black */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
/*
loop through all the happy faces:
- update position
- update velocity (if boundary is hit)
- draw
*/
for (i = 0; i < NUM_HAPPY_FACES; i++) {
faces[i].x += faces[i].xvel * MILLESECONDS_PER_FRAME;
faces[i].y += faces[i].yvel * MILLESECONDS_PER_FRAME;
if (faces[i].x > maxx) {
faces[i].x = maxx;
faces[i].xvel = -faces[i].xvel;
} else if (faces[i].y > maxy) {
faces[i].y = maxy;
faces[i].yvel = -faces[i].yvel;
}
if (faces[i].x < minx) {
faces[i].x = minx;
faces[i].xvel = -faces[i].xvel;
} else if (faces[i].y < miny) {
faces[i].y = miny;
faces[i].yvel = -faces[i].yvel;
}
dstRect.x = faces[i].x;
dstRect.y = faces[i].y;
SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
}
/* update screen */
SDL_RenderPresent(renderer);
}
/*
loads the happyface graphic into a texture
*/
void
initializeTexture(SDL_Renderer *renderer)
{
SDL_Surface *bmp_surface;
/* load the bmp */
bmp_surface = SDL_LoadBMP("icon.bmp");
if (bmp_surface == NULL) {
fatalError("could not load bmp");
}
/* set white to transparent on the happyface */
SDL_SetColorKey(bmp_surface, 1,
SDL_MapRGB(bmp_surface->format, 255, 255, 255));
/* convert RGBA surface to texture */
texture = SDL_CreateTextureFromSurface(renderer, bmp_surface);
if (texture == 0) {
fatalError("could not create texture");
}
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
/* free up allocated memory */
SDL_FreeSurface(bmp_surface);
}
int
main(int argc, char *argv[])
{
SDL_Window *window;
SDL_Renderer *renderer;
Uint32 startFrame;
Uint32 endFrame;
Uint32 delay;
int done;
/* initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fatalError("Could not initialize SDL");
}
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL |
SDL_WINDOW_BORDERLESS);
renderer = SDL_CreateRenderer(window, -1, 0);
initializeTexture(renderer);
initializeHappyFaces();
/* main loop */
done = 0;
while (!done) {
startFrame = SDL_GetTicks();
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
done = 1;
}
}
render(renderer);
endFrame = SDL_GetTicks();
/* figure out how much time we have left, and then sleep */
delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
if (delay < 0) {
delay = 0;
} else if (delay > MILLESECONDS_PER_FRAME) {
delay = MILLESECONDS_PER_FRAME;
}
SDL_Delay(delay);
}
/* cleanup */
SDL_DestroyTexture(texture);
/* shutdown SDL */
SDL_Quit();
return 0;
}

View file

@ -0,0 +1,310 @@
/*
* keyboard.c
* written by Holmes Futrell
* use however you want
*/
#import "SDL.h"
#import "common.h"
#define GLYPH_SIZE_IMAGE 16 /* size of glyphs (characters) in the bitmap font file */
#define GLYPH_SIZE_SCREEN 32 /* size of glyphs (characters) as shown on the screen */
static SDL_Texture *texture; /* texture where we'll hold our font */
/* function declarations */
void cleanup(void);
void drawBlank(int x, int y);
static SDL_Renderer *renderer;
static int numChars = 0; /* number of characters we've typed so far */
static SDL_bool lastCharWasColon = 0; /* we use this to detect sequences such as :) */
static SDL_Color bg_color = { 50, 50, 100, 255 }; /* color of background */
/* this structure maps a scancode to an index in our bitmap font.
it also contains data about under which modifiers the mapping is valid
(for example, we don't want shift + 1 to produce the character '1',
but rather the character '!')
*/
typedef struct
{
SDL_Scancode scancode; /* scancode of the key we want to map */
int allow_no_mod; /* is the map valid if the key has no modifiers? */
SDL_Keymod mod; /* what modifiers are allowed for the mapping */
int index; /* what index in the font does the scancode map to */
} fontMapping;
#define TABLE_SIZE 51 /* size of our table which maps keys and modifiers to font indices */
/* Below is the table that defines the mapping between scancodes and modifiers to indices in the
bitmap font. As an example, then line '{ SDL_SCANCODE_A, 1, KMOD_SHIFT, 33 }' means, map
the key A (which has scancode SDL_SCANCODE_A) to index 33 in the font (which is a picture of an A),
The '1' means that the mapping is valid even if there are no modifiers, and KMOD_SHIFT means the
mapping is also valid if the user is holding shift.
*/
fontMapping map[TABLE_SIZE] = {
{SDL_SCANCODE_A, 1, KMOD_SHIFT, 33}, /* A */
{SDL_SCANCODE_B, 1, KMOD_SHIFT, 34}, /* B */
{SDL_SCANCODE_C, 1, KMOD_SHIFT, 35}, /* C */
{SDL_SCANCODE_D, 1, KMOD_SHIFT, 36}, /* D */
{SDL_SCANCODE_E, 1, KMOD_SHIFT, 37}, /* E */
{SDL_SCANCODE_F, 1, KMOD_SHIFT, 38}, /* F */
{SDL_SCANCODE_G, 1, KMOD_SHIFT, 39}, /* G */
{SDL_SCANCODE_H, 1, KMOD_SHIFT, 40}, /* H */
{SDL_SCANCODE_I, 1, KMOD_SHIFT, 41}, /* I */
{SDL_SCANCODE_J, 1, KMOD_SHIFT, 42}, /* J */
{SDL_SCANCODE_K, 1, KMOD_SHIFT, 43}, /* K */
{SDL_SCANCODE_L, 1, KMOD_SHIFT, 44}, /* L */
{SDL_SCANCODE_M, 1, KMOD_SHIFT, 45}, /* M */
{SDL_SCANCODE_N, 1, KMOD_SHIFT, 46}, /* N */
{SDL_SCANCODE_O, 1, KMOD_SHIFT, 47}, /* O */
{SDL_SCANCODE_P, 1, KMOD_SHIFT, 48}, /* P */
{SDL_SCANCODE_Q, 1, KMOD_SHIFT, 49}, /* Q */
{SDL_SCANCODE_R, 1, KMOD_SHIFT, 50}, /* R */
{SDL_SCANCODE_S, 1, KMOD_SHIFT, 51}, /* S */
{SDL_SCANCODE_T, 1, KMOD_SHIFT, 52}, /* T */
{SDL_SCANCODE_U, 1, KMOD_SHIFT, 53}, /* U */
{SDL_SCANCODE_V, 1, KMOD_SHIFT, 54}, /* V */
{SDL_SCANCODE_W, 1, KMOD_SHIFT, 55}, /* W */
{SDL_SCANCODE_X, 1, KMOD_SHIFT, 56}, /* X */
{SDL_SCANCODE_Y, 1, KMOD_SHIFT, 57}, /* Y */
{SDL_SCANCODE_Z, 1, KMOD_SHIFT, 58}, /* Z */
{SDL_SCANCODE_0, 1, 0, 16}, /* 0 */
{SDL_SCANCODE_1, 1, 0, 17}, /* 1 */
{SDL_SCANCODE_2, 1, 0, 18}, /* 2 */
{SDL_SCANCODE_3, 1, 0, 19}, /* 3 */
{SDL_SCANCODE_4, 1, 0, 20}, /* 4 */
{SDL_SCANCODE_5, 1, 0, 21}, /* 5 */
{SDL_SCANCODE_6, 1, 0, 22}, /* 6 */
{SDL_SCANCODE_7, 1, 0, 23}, /* 7 */
{SDL_SCANCODE_8, 1, 0, 24}, /* 8 */
{SDL_SCANCODE_9, 1, 0, 25}, /* 9 */
{SDL_SCANCODE_SPACE, 1, 0, 0}, /* ' ' */
{SDL_SCANCODE_1, 0, KMOD_SHIFT, 1}, /* ! */
{SDL_SCANCODE_SLASH, 0, KMOD_SHIFT, 31}, /* ? */
{SDL_SCANCODE_SLASH, 1, 0, 15}, /* / */
{SDL_SCANCODE_COMMA, 1, 0, 12}, /* , */
{SDL_SCANCODE_SEMICOLON, 1, 0, 27}, /* ; */
{SDL_SCANCODE_SEMICOLON, 0, KMOD_SHIFT, 26}, /* : */
{SDL_SCANCODE_PERIOD, 1, 0, 14}, /* . */
{SDL_SCANCODE_MINUS, 1, 0, 13}, /* - */
{SDL_SCANCODE_EQUALS, 0, KMOD_SHIFT, 11}, /* = */
{SDL_SCANCODE_APOSTROPHE, 1, 0, 7}, /* ' */
{SDL_SCANCODE_APOSTROPHE, 0, KMOD_SHIFT, 2}, /* " */
{SDL_SCANCODE_5, 0, KMOD_SHIFT, 5}, /* % */
};
/*
This function maps an SDL_KeySym to an index in the bitmap font.
It does so by scanning through the font mapping table one entry
at a time.
If a match is found (scancode and allowed modifiers), the proper
index is returned.
If there is no entry for the key, -1 is returned
*/
int
keyToIndex(SDL_Keysym key)
{
int i, index = -1;
for (i = 0; i < TABLE_SIZE; i++) {
fontMapping compare = map[i];
if (key.scancode == compare.scancode) {
/* if this entry is valid with no key mod and we have no keymod, or if
the key's modifiers are allowed modifiers for that mapping */
if ((compare.allow_no_mod && key.mod == 0)
|| (key.mod & compare.mod)) {
index = compare.index;
break;
}
}
}
return index;
}
/*
This function returns and x,y position for a given character number.
It is used for positioning each character of text
*/
void
getPositionForCharNumber(int n, int *x, int *y)
{
int x_padding = 16; /* padding space on left and right side of screen */
int y_padding = 32; /* padding space at top of screen */
/* figure out the number of characters that can fit horizontally across the screen */
int max_x_chars = (SCREEN_WIDTH - 2 * x_padding) / GLYPH_SIZE_SCREEN;
int line_separation = 5; /* pixels between each line */
*x = (n % max_x_chars) * GLYPH_SIZE_SCREEN + x_padding;
*y = (n / max_x_chars) * (GLYPH_SIZE_SCREEN + line_separation) +
y_padding;
}
void
drawIndex(int index)
{
int x, y;
getPositionForCharNumber(numChars, &x, &y);
SDL_Rect srcRect =
{ GLYPH_SIZE_IMAGE * index, 0, GLYPH_SIZE_IMAGE, GLYPH_SIZE_IMAGE };
SDL_Rect dstRect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
drawBlank(x, y);
SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
}
/* draws the cursor icon at the current end position of the text */
void
drawCursor(void)
{
drawIndex(29); /* cursor is at index 29 in the bitmap font */
}
/* paints over a glyph sized region with the background color
in effect it erases the area
*/
void
drawBlank(int x, int y)
{
SDL_Rect rect = { x, y, GLYPH_SIZE_SCREEN, GLYPH_SIZE_SCREEN };
SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
SDL_RenderFillRect(renderer, &rect);
}
/* moves backwards one character, erasing the last one put down */
void
backspace(void)
{
int x, y;
if (numChars > 0) {
getPositionForCharNumber(numChars, &x, &y);
drawBlank(x, y);
numChars--;
getPositionForCharNumber(numChars, &x, &y);
drawBlank(x, y);
drawCursor();
}
}
/* this function loads our font into an SDL_Texture and returns the SDL_Texture */
SDL_Texture*
loadFont(void)
{
SDL_Surface *surface = SDL_LoadBMP("kromasky_16x16.bmp");
if (!surface) {
printf("Error loading bitmap: %s\n", SDL_GetError());
return 0;
} else {
/* set the transparent color for the bitmap font (hot pink) */
SDL_SetColorKey(surface, 1, SDL_MapRGB(surface->format, 238, 0, 252));
/* now we convert the surface to our desired pixel format */
int format = SDL_PIXELFORMAT_ABGR8888; /* desired texture format */
Uint32 Rmask, Gmask, Bmask, Amask; /* masks for desired format */
int bpp; /* bits per pixel for desired format */
SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask,
&Amask);
SDL_Surface *converted =
SDL_CreateRGBSurface(0, surface->w, surface->h, bpp, Rmask, Gmask,
Bmask, Amask);
SDL_BlitSurface(surface, NULL, converted, NULL);
/* create our texture */
texture =
SDL_CreateTextureFromSurface(renderer, converted);
if (texture == 0) {
printf("texture creation failed: %s\n", SDL_GetError());
} else {
/* set blend mode for our texture */
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
}
SDL_FreeSurface(surface);
SDL_FreeSurface(converted);
return texture;
}
}
int
main(int argc, char *argv[])
{
int index; /* index of last key we pushed in the bitmap font */
SDL_Window *window;
SDL_Event event; /* last event received */
SDL_Keymod mod; /* key modifiers of last key we pushed */
SDL_Scancode scancode; /* scancode of last key we pushed */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("Error initializing SDL: %s", SDL_GetError());
}
/* create window */
window = SDL_CreateWindow("iPhone keyboard test", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
/* create renderer */
renderer = SDL_CreateRenderer(window, -1, 0);
/* load up our font */
loadFont();
/* draw the background, we'll just paint over it */
SDL_SetRenderDrawColor(renderer, bg_color.r, bg_color.g, bg_color.b, bg_color.a);
SDL_RenderFillRect(renderer, NULL);
SDL_RenderPresent(renderer);
int done = 0;
/* loop till we get SDL_Quit */
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN:
index = keyToIndex(event.key.keysym);
scancode = event.key.keysym.scancode;
mod = event.key.keysym.mod;
if (scancode == SDL_SCANCODE_DELETE) {
/* if user hit delete, delete the last character */
backspace();
lastCharWasColon = 0;
} else if (lastCharWasColon && scancode == SDL_SCANCODE_0
&& (mod & KMOD_SHIFT)) {
/* if our last key was a colon and this one is a close paren, the make a hoppy face */
backspace();
drawIndex(32); /* index for happy face */
numChars++;
drawCursor();
lastCharWasColon = 0;
} else if (index != -1) {
/* if we aren't doing a happy face, then just draw the normal character */
drawIndex(index);
numChars++;
drawCursor();
lastCharWasColon =
(event.key.keysym.scancode == SDL_SCANCODE_SEMICOLON
&& (event.key.keysym.mod & KMOD_SHIFT));
}
/* check if the key was a colon */
/* draw our updates to the screen */
SDL_RenderPresent(renderer);
break;
case SDL_MOUSEBUTTONUP:
/* mouse up toggles onscreen keyboard visibility */
if (SDL_IsTextInputActive()) {
SDL_StopTextInput();
} else {
SDL_StartTextInput();
}
break;
}
}
cleanup();
return 0;
}
/* clean up after ourselves like a good kiddy */
void
cleanup(void)
{
SDL_DestroyTexture(texture);
SDL_Quit();
}

353
Xcode-iOS/Demos/src/mixer.c Normal file
View file

@ -0,0 +1,353 @@
/*
* mixer.c
* written by Holmes Futrell
* use however you want
*/
#import "SDL.h"
#import "common.h"
#define NUM_CHANNELS 8 /* max number of sounds we can play at once */
#define NUM_DRUMS 4 /* number of drums in our set */
#define MILLESECONDS_PER_FRAME 16 /* about 60 frames per second */
static struct
{
SDL_Rect rect; /* where the button is drawn */
SDL_Color upColor; /* color when button is not active */
SDL_Color downColor; /* color when button is active */
int isPressed; /* is the button being pressed ? */
int touchIndex; /* what mouse (touch) index pressed the button ? */
} buttons[NUM_DRUMS];
struct sound
{
Uint8 *buffer; /* audio buffer for sound file */
Uint32 length; /* length of the buffer (in bytes) */
};
/* this array holds the audio for the drum noises */
static struct sound drums[NUM_DRUMS];
/* function declarations */
void handleMouseButtonDown(SDL_Event * event);
void handleMouseButtonUp(SDL_Event * event);
int playSound(struct sound *);
void initializeButtons();
void audioCallback(void *userdata, Uint8 * stream, int len);
void loadSound(const char *file, struct sound *s);
struct
{
/* channel array holds information about currently playing sounds */
struct
{
Uint8 *position; /* what is the current position in the buffer of this sound ? */
Uint32 remaining; /* how many bytes remaining before we're done playing the sound ? */
Uint32 timestamp; /* when did this sound start playing ? */
} channels[NUM_CHANNELS];
SDL_AudioSpec outputSpec; /* what audio format are we using for output? */
int numSoundsPlaying; /* how many sounds are currently playing */
} mixer;
/* sets up the buttons (color, position, state) */
void
initializeButtons()
{
int i;
int spacing = 10; /* gap between drum buttons */
SDL_Rect buttonRect; /* keeps track of where to position drum */
SDL_Color upColor = { 86, 86, 140, 255 }; /* color of drum when not pressed */
SDL_Color downColor = { 191, 191, 221, 255 }; /* color of drum when pressed */
buttonRect.x = spacing;
buttonRect.y = spacing;
buttonRect.w = SCREEN_WIDTH - 2 * spacing;
buttonRect.h = (SCREEN_HEIGHT - (NUM_DRUMS + 1) * spacing) / NUM_DRUMS;
/* setup each button */
for (i = 0; i < NUM_DRUMS; i++) {
buttons[i].rect = buttonRect;
buttons[i].isPressed = 0;
buttons[i].upColor = upColor;
buttons[i].downColor = downColor;
buttonRect.y += spacing + buttonRect.h; /* setup y coordinate for next drum */
}
}
/*
loads a wav file (stored in 'file'), converts it to the mixer's output format,
and stores the resulting buffer and length in the sound structure
*/
void
loadSound(const char *file, struct sound *s)
{
SDL_AudioSpec spec; /* the audio format of the .wav file */
SDL_AudioCVT cvt; /* used to convert .wav to output format when formats differ */
int result;
if (SDL_LoadWAV(file, &spec, &s->buffer, &s->length) == NULL) {
fatalError("could not load .wav");
}
/* build the audio converter */
result = SDL_BuildAudioCVT(&cvt, spec.format, spec.channels, spec.freq,
mixer.outputSpec.format,
mixer.outputSpec.channels,
mixer.outputSpec.freq);
if (result == -1) {
fatalError("could not build audio CVT");
} else if (result != 0) {
/*
this happens when the .wav format differs from the output format.
we convert the .wav buffer here
*/
cvt.buf = (Uint8 *) SDL_malloc(s->length * cvt.len_mult); /* allocate conversion buffer */
cvt.len = s->length; /* set conversion buffer length */
SDL_memcpy(cvt.buf, s->buffer, s->length); /* copy sound to conversion buffer */
if (SDL_ConvertAudio(&cvt) == -1) { /* convert the sound */
fatalError("could not convert .wav");
}
SDL_free(s->buffer); /* free the original (unconverted) buffer */
s->buffer = cvt.buf; /* point sound buffer to converted buffer */
s->length = cvt.len_cvt; /* set sound buffer's new length */
}
}
/* called from main event loop */
void
handleMouseButtonDown(SDL_Event * event)
{
int x, y, mouseIndex, i, drumIndex;
mouseIndex = 0;
drumIndex = -1;
SDL_GetMouseState(&x, &y);
/* check if we hit any of the drum buttons */
for (i = 0; i < NUM_DRUMS; i++) {
if (x >= buttons[i].rect.x
&& x < buttons[i].rect.x + buttons[i].rect.w
&& y >= buttons[i].rect.y
&& y < buttons[i].rect.y + buttons[i].rect.h) {
drumIndex = i;
break;
}
}
if (drumIndex != -1) {
/* if we hit a button */
buttons[drumIndex].touchIndex = mouseIndex;
buttons[drumIndex].isPressed = 1;
playSound(&drums[drumIndex]);
}
}
/* called from main event loop */
void
handleMouseButtonUp(SDL_Event * event)
{
int i;
int mouseIndex = 0;
/* check if this should cause any of the buttons to become unpressed */
for (i = 0; i < NUM_DRUMS; i++) {
if (buttons[i].touchIndex == mouseIndex) {
buttons[i].isPressed = 0;
}
}
}
/* draws buttons to screen */
void
render(SDL_Renderer *renderer)
{
int i;
SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
SDL_RenderClear(renderer); /* draw background (gray) */
/* draw the drum buttons */
for (i = 0; i < NUM_DRUMS; i++) {
SDL_Color color =
buttons[i].isPressed ? buttons[i].downColor : buttons[i].upColor;
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderFillRect(renderer, &buttons[i].rect);
}
/* update the screen */
SDL_RenderPresent(renderer);
}
/*
finds a sound channel in the mixer for a sound
and sets it up to start playing
*/
int
playSound(struct sound *s)
{
/*
find an empty channel to play on.
if no channel is available, use oldest channel
*/
int i;
int selected_channel = -1;
int oldest_channel = 0;
if (mixer.numSoundsPlaying == 0) {
/* we're playing a sound now, so start audio callback back up */
SDL_PauseAudio(0);
}
/* find a sound channel to play the sound on */
for (i = 0; i < NUM_CHANNELS; i++) {
if (mixer.channels[i].position == NULL) {
/* if no sound on this channel, select it */
selected_channel = i;
break;
}
/* if this channel's sound is older than the oldest so far, set it to oldest */
if (mixer.channels[i].timestamp <
mixer.channels[oldest_channel].timestamp)
oldest_channel = i;
}
/* no empty channels, take the oldest one */
if (selected_channel == -1)
selected_channel = oldest_channel;
else
mixer.numSoundsPlaying++;
/* point channel data to wav data */
mixer.channels[selected_channel].position = s->buffer;
mixer.channels[selected_channel].remaining = s->length;
mixer.channels[selected_channel].timestamp = SDL_GetTicks();
return selected_channel;
}
/*
Called from SDL's audio system. Supplies sound input with data by mixing together all
currently playing sound effects.
*/
void
audioCallback(void *userdata, Uint8 * stream, int len)
{
int i;
int copy_amt;
SDL_memset(stream, mixer.outputSpec.silence, len); /* initialize buffer to silence */
/* for each channel, mix in whatever is playing on that channel */
for (i = 0; i < NUM_CHANNELS; i++) {
if (mixer.channels[i].position == NULL) {
/* if no sound is playing on this channel */
continue; /* nothing to do for this channel */
}
/* copy len bytes to the buffer, unless we have fewer than len bytes remaining */
copy_amt =
mixer.channels[i].remaining <
len ? mixer.channels[i].remaining : len;
/* mix this sound effect with the output */
SDL_MixAudioFormat(stream, mixer.channels[i].position,
mixer.outputSpec.format, copy_amt, 150);
/* update buffer position in sound effect and the number of bytes left */
mixer.channels[i].position += copy_amt;
mixer.channels[i].remaining -= copy_amt;
/* did we finish playing the sound effect ? */
if (mixer.channels[i].remaining == 0) {
mixer.channels[i].position = NULL; /* indicates no sound playing on channel anymore */
mixer.numSoundsPlaying--;
if (mixer.numSoundsPlaying == 0) {
/* if no sounds left playing, pause audio callback */
SDL_PauseAudio(1);
}
}
}
}
int
main(int argc, char *argv[])
{
int done; /* has user tried to quit ? */
SDL_Window *window; /* main window */
SDL_Renderer *renderer;
SDL_Event event;
Uint32 startFrame; /* holds when frame started processing */
Uint32 endFrame; /* holds when frame ended processing */
Uint32 delay; /* calculated delay, how long should we wait before next frame? */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
fatalError("could not initialize SDL");
}
window =
SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
renderer = SDL_CreateRenderer(window, 0, 0);
/* initialize the mixer */
SDL_memset(&mixer, 0, sizeof(mixer));
/* setup output format */
mixer.outputSpec.freq = 44100;
mixer.outputSpec.format = AUDIO_S16LSB;
mixer.outputSpec.channels = 2;
mixer.outputSpec.samples = 256;
mixer.outputSpec.callback = audioCallback;
mixer.outputSpec.userdata = NULL;
/* open audio for output */
if (SDL_OpenAudio(&mixer.outputSpec, NULL) != 0) {
fatalError("Opening audio failed");
}
/* load our drum noises */
loadSound("ds_kick_big_amb.wav", &drums[3]);
loadSound("ds_brush_snare.wav", &drums[2]);
loadSound("ds_loose_skin_mute.wav", &drums[1]);
loadSound("ds_china.wav", &drums[0]);
/* setup positions, colors, and state of buttons */
initializeButtons();
/* enter main loop */
done = 0;
while (!done) {
startFrame = SDL_GetTicks();
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
handleMouseButtonDown(&event);
break;
case SDL_MOUSEBUTTONUP:
handleMouseButtonUp(&event);
break;
case SDL_QUIT:
done = 1;
break;
}
}
render(renderer); /* draw buttons */
endFrame = SDL_GetTicks();
/* figure out how much time we have left, and then sleep */
delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
if (delay < 0) {
delay = 0;
} else if (delay > MILLESECONDS_PER_FRAME) {
delay = MILLESECONDS_PER_FRAME;
}
SDL_Delay(delay);
}
/* cleanup code, let's free up those sound buffers */
int i;
for (i = 0; i < NUM_DRUMS; i++) {
SDL_free(drums[i].buffer);
}
/* let SDL do its exit code */
SDL_Quit();
return 0;
}

View file

@ -0,0 +1,81 @@
/*
* rectangles.c
* written by Holmes Futrell
* use however you want
*/
#include "SDL.h"
#include <time.h>
#include "common.h"
void
render(SDL_Renderer *renderer)
{
Uint8 r, g, b;
/* Come up with a random rectangle */
SDL_Rect rect;
rect.w = randomInt(64, 128);
rect.h = randomInt(64, 128);
rect.x = randomInt(0, SCREEN_WIDTH);
rect.y = randomInt(0, SCREEN_HEIGHT);
/* Come up with a random color */
r = randomInt(50, 255);
g = randomInt(50, 255);
b = randomInt(50, 255);
/* Fill the rectangle in the color */
SDL_SetRenderDrawColor(renderer, r, g, b, 255);
SDL_RenderFillRect(renderer, &rect);
/* update screen */
SDL_RenderPresent(renderer);
}
int
main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO/* | SDL_INIT_AUDIO */) < 0)
{
printf("Unable to initialize SDL");
}
SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
int landscape = 1;
int modes = SDL_GetNumDisplayModes(0);
int sx = 0, sy = 0;
for (int i = 0; i < modes; i++)
{
SDL_DisplayMode mode;
SDL_GetDisplayMode(0, i, &mode);
if (landscape ? mode.w > sx : mode.h > sy)
{
sx = mode.w;
sy = mode.h;
}
}
printf("picked: %d %d\n", sx, sy);
SDL_Window *_sdl_window = NULL;
SDL_GLContext _sdl_context = NULL;
_sdl_window = SDL_CreateWindow("fred",
0, 0,
sx, sy,
SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
SDL_SetHint("SDL_HINT_ORIENTATIONS", "LandscapeLeft LandscapeRight");
int ax = 0, ay = 0;
SDL_GetWindowSize(_sdl_window, &ax, &ay);
printf("given: %d %d\n", ax, ay);
return 0;
}

125
Xcode-iOS/Demos/src/touch.c Normal file
View file

@ -0,0 +1,125 @@
/*
* touch.c
* written by Holmes Futrell
* use however you want
*/
#include "SDL.h"
#include "math.h"
#include "common.h"
#define BRUSH_SIZE 32 /* width and height of the brush */
#define PIXELS_PER_ITERATION 5 /* number of pixels between brush blots when forming a line */
static SDL_Texture *brush = 0; /* texture for the brush */
/*
draws a line from (startx, starty) to (startx + dx, starty + dy)
this is accomplished by drawing several blots spaced PIXELS_PER_ITERATION apart
*/
void
drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy)
{
float distance = sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */
int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */
float dx_prime = dx / iterations; /* x-shift per iteration */
float dy_prime = dy / iterations; /* y-shift per iteration */
SDL_Rect dstRect; /* rect to draw brush sprite into */
dstRect.w = BRUSH_SIZE;
dstRect.h = BRUSH_SIZE;
/* setup x and y for the location of the first sprite */
float x = startx - BRUSH_SIZE / 2.0f;
float y = starty - BRUSH_SIZE / 2.0f;
int i;
/* draw a series of blots to form the line */
for (i = 0; i < iterations; i++) {
dstRect.x = x;
dstRect.y = y;
/* shift x and y for next sprite location */
x += dx_prime;
y += dy_prime;
/* draw brush blot */
SDL_RenderCopy(renderer, brush, NULL, &dstRect);
}
}
/*
loads the brush texture
*/
void
initializeTexture(SDL_Renderer *renderer)
{
SDL_Surface *bmp_surface;
bmp_surface = SDL_LoadBMP("stroke.bmp");
if (bmp_surface == NULL) {
fatalError("could not load stroke.bmp");
}
brush =
SDL_CreateTextureFromSurface(renderer, bmp_surface);
SDL_FreeSurface(bmp_surface);
if (brush == 0) {
fatalError("could not create brush texture");
}
/* additive blending -- laying strokes on top of eachother makes them brighter */
SDL_SetTextureBlendMode(brush, SDL_BLENDMODE_ADD);
/* set brush color (red) */
SDL_SetTextureColorMod(brush, 255, 100, 100);
}
int
main(int argc, char *argv[])
{
int x, y, dx, dy; /* mouse location */
Uint8 state; /* mouse (touch) state */
SDL_Event event;
SDL_Window *window; /* main window */
SDL_Renderer *renderer;
int done; /* does user want to quit? */
/* initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fatalError("Could not initialize SDL");
}
/* create main window and renderer */
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL |
SDL_WINDOW_BORDERLESS);
renderer = SDL_CreateRenderer(window, 0, 0);
/* load brush texture */
initializeTexture(renderer);
/* fill canvass initially with all black */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
done = 0;
while (!done && SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = 1;
break;
case SDL_MOUSEMOTION:
state = SDL_GetMouseState(&x, &y); /* get its location */
SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */
if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */
drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */
SDL_RenderPresent(renderer);
}
break;
}
}
/* cleanup */
SDL_DestroyTexture(brush);
SDL_Quit();
return 0;
}