Post by Kyle Gagner on Nov 23, 2011 1:04:29 GMT -5
Do you want to work with high speed graphics and audio without limits? C is a rewarding language because of it's speed, but coding in C can be difficult. SDL is not easy to use, but you will have more control than using something like Pygame with Python. Also the executables compiled from C can be run on any PC without even installing, so your friends no longer have the "I'm too lazy to install Python AND Pygame" excuse.
You only have to do the first two phases for every computer you want to program on, but the last must be done for every project.
PHASE 1: GET PELLES C
Download Pelles C from www.smorgasbordet.com/pellesc/ (use Setup, 32-bit edition, not a 64 bit edition or a release candidate).
PHASE 2: SET UP SDL
Next, set up SDL (credit to www.friedspace.com/cprogramming/sdlsetup.php my instructions are only slightly different)
Download SDL
Go to the SDL webpage, click on the latest version of SDL (version 1.2 at the time of writing) in the download section of the menu on the left hand side of the page. In the source code section, download the source code zip file and in the development libraries, download the Win32 (Visual C++ 6.0) zip file.
Create a Pelles C Project
Click File->New->Project. Select "Win32 Static Library (.lib)" and call it sdlmain. Take note of the location of the project directory that will be created.
Extract the SDL source code
Inside the source code zip file you will find a src\main\win32 directory. Copy the file SDL_win32_main.c to the new Pelles C project directory you created.
Extract the Include Files
Copy all the files from the include directory of the source code zip file into Pelles C's Include directory.
Add sdl_win32_main.c to the Project
Click Project->Add files to project, and select the file sdl_win32_main.c.
Set Compiler Options
Go to Project->Project Options->Compiler and tick the box that says "Enable Microsoft Extensions" and set "Calling conv" to "__cdecl" in the drop down box.
Build the Library
Click Projects->Build sdlmain.lib. It will sit there for some time building (though it may look like nothing is happening). Eventually in the pane at the bottom it will say "Done".
Copy the .lib File
In your sdlmain project directory, you will now find the library you have just built (sdlmain.lib). Copy this to Pelles C's Lib directory.
Copy the other Libraries
Unzip the developers libraries zip file and copy the file sdl.lib to Pelles C's Lib directory. These files are in the lib folder of the zip file. Again you are probably better off extracting the whole zip file and then just copying the files you need.
PHASE 3: MAKE YOUR PROJECT
Again, credit lies mostly at www.friedspace.com/cprogramming/sdlsetup2.php
Create a Project
Create a Win32 Console Program. (File->New->Project...)
Set Compiler Options
In Project->Project Options->Compiler, set the __cdecl calling convention from the drop down list. Also select the "Enable Microsoft extensions" option.
Set Linker Options
In Project->Project Options->Linker (if this doesn't show up you haven't created a project properly yet), add "sdl.lib" and "sdlmain.lib" (just write the filenames with a space separating them) to the list of "Library and object files".
Now come my special instructions...
Then go to the folder where your project is and copy SDL.dll into that folder (that's in the developers' libraries).
Now go File->New->Source code
Write or copy/paste your code in to the source code file.
Go File->Save
Make sure you're in the folder of you project, then save it with some name like test.c
You will be asked if you want to add the file to the current projects. YES YOU DO.
To run your program, build it with Ctrl+B, then run with F5, you will need to build the project every time you make changes to the code.
Your program will display a console when it runs. This is often useful for debugging, but you can disable it by going to Project->Project options... then clicking on the linker tab, and selecting Windows instead of Console for the Type.
But how do you write these programs?
Well, you could start with MY code. It's a pretty good place to start a project because it contains a lot of commonly necessary elements, such as stereo audio capabilities, a re-sizable window, titles, icons, a routine for video, the beginnings of a keyboard interface, and a well established mouse interface. This also means that the code is long and perhaps confusing for a newbie.
To use this code you will either need to disable the icons or make icons. To disable icons comment out or delete all of the lines from "//Icon code START" to "//Icon code END". To use icons you need a folder called "Files" in the same directory as the executable (the directory of the project) and it should contain two 32 by 32 24 bit bitmaps. One is an icon, and the other is a mask that defines the transparent portions of the icon (white for opaque, black for transparent). It's easy enough to make these images in paint, just save as a 24 bit bitmap. The icon is called Icon.bmp and the mask is called Mask.bmp
You only have to do the first two phases for every computer you want to program on, but the last must be done for every project.
PHASE 1: GET PELLES C
Download Pelles C from www.smorgasbordet.com/pellesc/ (use Setup, 32-bit edition, not a 64 bit edition or a release candidate).
PHASE 2: SET UP SDL
Next, set up SDL (credit to www.friedspace.com/cprogramming/sdlsetup.php my instructions are only slightly different)
Download SDL
Go to the SDL webpage, click on the latest version of SDL (version 1.2 at the time of writing) in the download section of the menu on the left hand side of the page. In the source code section, download the source code zip file and in the development libraries, download the Win32 (Visual C++ 6.0) zip file.
Create a Pelles C Project
Click File->New->Project. Select "Win32 Static Library (.lib)" and call it sdlmain. Take note of the location of the project directory that will be created.
Extract the SDL source code
Inside the source code zip file you will find a src\main\win32 directory. Copy the file SDL_win32_main.c to the new Pelles C project directory you created.
Extract the Include Files
Copy all the files from the include directory of the source code zip file into Pelles C's Include directory.
Add sdl_win32_main.c to the Project
Click Project->Add files to project, and select the file sdl_win32_main.c.
Set Compiler Options
Go to Project->Project Options->Compiler and tick the box that says "Enable Microsoft Extensions" and set "Calling conv" to "__cdecl" in the drop down box.
Build the Library
Click Projects->Build sdlmain.lib. It will sit there for some time building (though it may look like nothing is happening). Eventually in the pane at the bottom it will say "Done".
Copy the .lib File
In your sdlmain project directory, you will now find the library you have just built (sdlmain.lib). Copy this to Pelles C's Lib directory.
Copy the other Libraries
Unzip the developers libraries zip file and copy the file sdl.lib to Pelles C's Lib directory. These files are in the lib folder of the zip file. Again you are probably better off extracting the whole zip file and then just copying the files you need.
PHASE 3: MAKE YOUR PROJECT
Again, credit lies mostly at www.friedspace.com/cprogramming/sdlsetup2.php
Create a Project
Create a Win32 Console Program. (File->New->Project...)
Set Compiler Options
In Project->Project Options->Compiler, set the __cdecl calling convention from the drop down list. Also select the "Enable Microsoft extensions" option.
Set Linker Options
In Project->Project Options->Linker (if this doesn't show up you haven't created a project properly yet), add "sdl.lib" and "sdlmain.lib" (just write the filenames with a space separating them) to the list of "Library and object files".
Now come my special instructions...
Then go to the folder where your project is and copy SDL.dll into that folder (that's in the developers' libraries).
Now go File->New->Source code
Write or copy/paste your code in to the source code file.
Go File->Save
Make sure you're in the folder of you project, then save it with some name like test.c
You will be asked if you want to add the file to the current projects. YES YOU DO.
To run your program, build it with Ctrl+B, then run with F5, you will need to build the project every time you make changes to the code.
Your program will display a console when it runs. This is often useful for debugging, but you can disable it by going to Project->Project options... then clicking on the linker tab, and selecting Windows instead of Console for the Type.
But how do you write these programs?
Well, you could start with MY code. It's a pretty good place to start a project because it contains a lot of commonly necessary elements, such as stereo audio capabilities, a re-sizable window, titles, icons, a routine for video, the beginnings of a keyboard interface, and a well established mouse interface. This also means that the code is long and perhaps confusing for a newbie.
To use this code you will either need to disable the icons or make icons. To disable icons comment out or delete all of the lines from "//Icon code START" to "//Icon code END". To use icons you need a folder called "Files" in the same directory as the executable (the directory of the project) and it should contain two 32 by 32 24 bit bitmaps. One is an icon, and the other is a mask that defines the transparent portions of the icon (white for opaque, black for transparent). It's easy enough to make these images in paint, just save as a 24 bit bitmap. The icon is called Icon.bmp and the mask is called Mask.bmp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <SDL.h>
SDL_Surface* screen;
int SamplesPerChunk;
int FrameRate = 44100; // use 22050 or 11025 for lower quality
double pi = 3.14159265358979323846264338327950288419716939937510;
double cycle;
unsigned char *keys;
unsigned char buttons[3];
int mx;
int my;
int *locks;
void draw(void) // This is video
{
while(locks[0])
{
}
locks[1]=1;
int x;
int y;
int r=0;
int g=0;
int b=0;
unsigned char *edit;
if(SDL_MUSTLOCK(screen))
{
if(SDL_LockSurface(screen) < 0)
{
return;
}
}
edit = (unsigned char*) screen->pixels;
for(y = 0; y < screen->h; y++ )
{
for(x = 0; x < screen->w; x++ )
{
// RGB values
r=x%255;
g=y%255;
b=127;
*edit = b;
edit += 1;
*edit = g;
edit += 1;
*edit = r;
edit += 2;
}
}
if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
SDL_Flip(screen);
locks[1]=0;
}
void chunk(void *userdata, unsigned char *stream, int len) // This is audio
{
double level;
signed short *FramePointer;
signed short FrameCount;
FramePointer=(signed short*)stream;
if(cycle>FrameRate*60)
{
cycle=0;
}
for(FrameCount=0;FrameCount<SamplesPerChunk;FrameCount++)
{
// Left (sometimes)
level = .1*sin(cycle*440);
*FramePointer=32767*level;
FramePointer+=1;
// Right (sometimes)
level = .1*sin(cycle*440);
*FramePointer=32767*level;
FramePointer+=1;
cycle+=2*pi/FrameRate;
}
draw();
}
int main(int argc, char **argv)
{
int run = 1;
int n;
int i;
unsigned char bits;
unsigned char bitmask[4*32];
unsigned char *edit;
locks=malloc(2*sizeof(int));
SDL_Surface *imgmask;
SDL_Event event;
SDL_AudioSpec *desired;
SDL_AudioSpec *obtained;
desired=(SDL_AudioSpec*)malloc(sizeof(SDL_AudioSpec));
obtained=(SDL_AudioSpec*)malloc(sizeof(SDL_AudioSpec));
desired->freq=FrameRate;
desired->format=AUDIO_S16SYS;
desired->channels=2;
desired->samples=1024; // Samples in a chunk, may be changed
desired->callback=chunk;
desired->userdata=NULL;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)<0)
{
SDL_Quit();
return 0;
}
// Icon code START
imgmask=SDL_LoadBMP("Files\\Mask.bmp");
if(SDL_MUSTLOCK(imgmask))
{
if(SDL_LockSurface(imgmask) < 0)
{
SDL_Quit();
return 0;
}
}
edit = (unsigned char*) imgmask->pixels;
for(n=0;n<4*32;n++)
{
bitmask[n]=0;
if(n<4*32)
{
for(i=0;i<8;i++)
{
bitmask[n]=bitmask[n]+((((unsigned char)1)<<(7-i))&*edit);
edit+=imgmask->format->BytesPerPixel;
}
}
}
SDL_WM_SetCaption("Hello World!","Example");
SDL_WM_SetIcon(SDL_LoadBMP("Files\\Icon.bmp"),bitmask);
// Icon code END
// The first number is width, the second number is height
if(!(screen = SDL_SetVideoMode(255,255, 32, SDL_HWSURFACE | SDL_RESIZABLE)))
{
SDL_Quit();
return 0;
}
if(SDL_OpenAudio(desired,obtained)<0)
{
SDL_Quit();
return 0;
}
free(desired);
desired=NULL;
if(AUDIO_S16SYS!=obtained->format)
{
SDL_Quit();
return 0;
}
SamplesPerChunk=obtained->samples;
SDL_PauseAudio(0);
while(run)
{
SDL_PumpEvents();
keys = SDL_GetKeyState(NULL);
// The keys are an array of boolean values, with each index being an ASCII character
bits = SDL_GetMouseState(&mx,&my);
for(n=0;n<3;n++)
{
buttons[n]=(bits&(1<<n))>>n;
}
// The buttons are an array buttons[0] is left, 1 is middle, 2 is right
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
run=0;
break;
case SDL_VIDEORESIZE:
locks[0]=1;
while(locks[1])
{
printf("hi");
}
// Code for what to do when the screen is resized should go here
if(!(screen = SDL_SetVideoMode(event.resize.h,event.resize.h, 32, SDL_HWSURFACE | SDL_RESIZABLE)))
{
SDL_Quit();
return 0;
}
locks[0]=0;
}
}
SDL_Delay(50);
}
SDL_PauseAudio(1);
SDL_Quit();
return 0;
}