Coursework: Week 11, Prep

The coursework this week will not count towards your credit for the unit. The main aim is to help you prepare for the final sketch assignment. No submission is required this week, and there won't be any assessment, but sample answers will be provided.

The sketch assignment involves I/O, particularly binary file IO and graphics using the SDL library.

I/O

The first aim is to write some small input/output programs and, in particular, try out the kind of binary file I/O needed for the final week. It is recommended that you use the idioms in the IO chapter of the lecture notes - or you can explore what happens if you don't.

Since it is difficult to automate the testing of I/O programs, it is recommended that you ignore testing. But don't forget it! As soon as you start writing programs with logic in them again, you should return to it.

Upper case program

This practices I/O too and from text files. Write a program which takes two filenames from the command line, one for input, and one for output. It reads a line of text at a time from the input file, and writes it to the output file, converted to upper case. Don't forget to close the files, especially the output file.

The program should work whether the filenames are local (e.g. in.txt), relative (e.g. data/in.txt), or absolute (e.g. /home/me/data/in.txt). You shouldn't have to do anything special to detect and deal with these cases, just check that they all work.

Ideally, your program should accept an input file with either Linux/Mac or Windows line endings, and write to the output file using the default line endings for the platform the program is running on. (There is, however, a case for using Linux/Mac line endings even on Windows - see UTF-8 Everywhere.)

Hex printer

Write a program that takes a filename (of a text or binary file), reads bytes from it one at a time, and prints them on the standard output in hex, in the same format as od -t x1 filename (but leaving out the address in the first column). You may want to write another program which creates binary files which you can use for (manual) testing.

SDL

You don't actually need to know much about SDL to do the sketch assignment, just call functions which will be provided for you. In fact, the whole sketch assignment can be done without any graphics, just by trusting the tests. However, familiarity with SDL, or at least the provided functions, will be valuable.

Read the aside on SDL and note that it is version 2 of SDL that you need.

On Codio

There is good and bad news. The good news is that you should find you have administrator access (root access) to the Codio computer in the cloud provided for this unit. And so, you can install SDL as for any Linux computer. And programs that use SDL can be compiled and run.

The bad news is that programs will probably run very badly, because they are trying to do graphics (a) over the net and (b) into a browser. So, it is recommended that you use a lab workstation or your own computer.

On a lab workstation

You should find SDL is already installed, and everything should work reasonably well.

On Windows

You need to be using Cygwin, in which case you have the pacman package manager, and you can type:

pacman -Ss sdl2

That shows all SDL2 related packages. Choose one from the list and, e.g., type:

pacman -S mingw64/mingw-w64-x86_64-SDL2

Problems may arise if you are unlucky. You may see "can't find winapifamily.h". If so, Google and download a fixed version of one of the SDL header files, and replace it.

You may also see "can't find _XGetRequest". If so, define int _XGetRequest; somewhere in the program

On Linux

On Linux, you may find SDL is installed already, or you may have an easy way of doing it, otherwise the instructions provided by Lazy Foo are reasonably good.

On Mac

On a Mac, your best friend is the homebrew package manager.

  1. check if you have it by typing the brew command and, if not, install it
  2. type brew doctor and fix up the problems it reports until you have a clean computer
  3. type brew install sdl2
Manual installation

If you need to install manually on Linux/Mac, download the relevant binary distribution, unzip it, cd into it, and type:

./configure
make
sudo make install
sudo ldconfig

(Tutorials don't tell you about ldconfig; without it, nothing works until you logout and login again)

Check SDL

To check whether SDL is working, try compiling and running a minimal SDL program. For example, this is the blue sky program from the aside, which you can copy to sky.c:

/* Display blue sky for 10 seconds. */

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>

// Fail, printing the SDL error message, and stop the program.
void fail() {
    fprintf(stderr, "%s\n", SDL_GetError());
    SDL_Quit();
    exit(1);
}

// Check the results from SDL functions for errors.
int I(int n) { if (n < 0) fail(); return n; }
void *P(void *p) { if (p == NULL) fail(); return p; }

int main() {
    int w=640, h=480;
    I(SDL_Init(SDL_INIT_VIDEO));
    SDL_Window *window = P(SDL_CreateWindow("Sky", 100, 100, w, h, 0));

    SDL_Surface *surface = P(SDL_GetWindowSurface(window));
    Uint32 skyBlue = SDL_MapRGB(surface->format, 100, 149, 237);
    I(SDL_FillRect(surface, NULL, skyBlue));
    I(SDL_UpdateWindowSurface(window));

    SDL_Delay(10000);
    SDL_Quit();
    return 0;
}

This has error checking in, to give you a better chance of diagnosing problems. Compile with:

clang -std=c11 -Wall sky.c -lSDL2 -o sky      (or sky.exe)

The option -lSDL2 must come after sky.c, to link with the SDL library.

If the compiler can't find the header, check whether you need to change the inclusion line to the (arguably) incorrect version #include <SDL2/SDL.h>.

Run with:

./sky

Try out SDL

If you don't want to do any SDL programming for yourself, at least try out the functions provided in display.h and display.c in the sketch assignment.