Graphics: Added font rendering functions Graphics::DrawText and Graphics::StringImage.

FileHandler: Added support for wav
Audio: Added support to play back a sound with XAudio2. We can't delete sounds until we make our own system to keep track of available voices.
LoginScreen scene: Upped framerate from 15fps to tickless, and added new logic to clone the scrolling text at the bottom. All of it.
This commit is contained in:
Fatbag 2012-04-20 19:37:08 -05:00
parent 64a5c0a425
commit 06f13d50ac
14 changed files with 429 additions and 162 deletions

View file

@ -17,11 +17,7 @@
#include <stdint.h>
#include <memory.h>
#include <stdio.h>
#include <setjmp.h> //Used by libpng
#include "bmp/read_bmp.h"
#include "libjpeg-turbo/jpeglib.h"
#include "libpng/png.h"
#define NOWINDOWS
#include "wav/read_wav.h"
#include "FileHandler.hpp"
namespace File {
@ -34,10 +30,10 @@ enum SoundType {
FSND_COUNT
};
static uint8_t * ReadWAV(Image_t * Image, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadXA(Image_t * Image, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadUTK(Image_t * Image, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadMP3(Image_t * Image, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize);
static const uint8_t Signature[] = {
'R', //WAV
@ -45,14 +41,14 @@ static const uint8_t Signature[] = {
'U', //UTK
0xFF //MP3
};
static uint8_t* (* const ImageFunction[])(Image_t*, const uint8_t*, size_t) = {
static uint8_t* (* const SoundFunction[])(Sound_t*, const uint8_t*, size_t) = {
ReadWAV,
ReadXA,
ReadUTK,
ReadMP3
};
Image_t * ReadImageFile(const char * Filename){
Sound_t * ReadSoundFile(const char * Filename){
uint8_t * InData = File::ReadFile(Filename);
if(InData == NULL) return NULL;
@ -62,23 +58,22 @@ Image_t * ReadImageFile(const char * Filename){
return NULL;
}
Image_t * Image = (Image_t*) malloc(sizeof(Image_t));
if(Image == NULL){
Sound_t * Sound = (Sound_t*) malloc(sizeof(Sound_t));
if(Sound == NULL){
free(InData);
File::Error = FERR_MEMORY;
return NULL;
}
uint8_t * OutData = NULL;
for(int i=0; i<FIMG_COUNT; i++){
for(int i=0; i<FSND_COUNT; i++){
if(InData[0] == Signature[i]){
OutData = ImageFunction[i](Image, InData, File::FileSize);
uint8_t * OutData = SoundFunction[i](Sound, InData, File::FileSize);
free(InData);
if(OutData == NULL){
File::Error = FERR_INVALIDDATA;
return NULL;
}
return Image;
return Sound;
}
}
@ -87,135 +82,29 @@ Image_t * ReadImageFile(const char * Filename){
return NULL;
}
static uint8_t * ReadBMP(Image_t * Image, const uint8_t * InData, size_t FileSize){
bmpheader_t BMPHeader;
if(!bmp_read_header(&BMPHeader, InData, FileSize)){
static uint8_t * ReadWAV(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
wavheader_t WAVHeader;
if(!wav_read_header(&WAVHeader, InData, FileSize)){
return NULL;
}
uint8_t * OutData = (uint8_t*) malloc(BMPHeader.DecompressedSize);
uint8_t * OutData = (uint8_t*) malloc(WAVHeader.DataSize);
if(OutData == NULL){
return NULL;
}
if(!bmp_read_data(&BMPHeader, InData, OutData)){
free(OutData);
return NULL;
}
memcpy(OutData, InData+44, WAVHeader.DataSize);
Image->Width = BMPHeader.biWidth;
Image->Height = BMPHeader.biHeight;
Image->Format = FIMG_BGR24;
Image->Data = OutData;
Sound->Channels = WAVHeader.nChannels;
Sound->SamplingRate = WAVHeader.nSamplesPerSec;
Sound->BitDepth = WAVHeader.wBitsPerSample;
Sound->Duration = WAVHeader.DataSize / WAVHeader.nBlockAlign;
Sound->Data = OutData;
return OutData;
}
static uint8_t * ReadJPG(Image_t * Image, const uint8_t * InData, size_t FileSize){
//Initialize
jpeg_decompress_struct cinfo;
jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, (unsigned char*) InData, FileSize);
if(jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK){
jpeg_destroy_decompress(&cinfo);
return NULL;
}
cinfo.out_color_space = JCS_EXT_BGR;
if(!jpeg_start_decompress(&cinfo)){
jpeg_destroy_decompress(&cinfo);
return NULL;
}
//Read
unsigned row_stride = cinfo.output_width * cinfo.output_components;
uint8_t * OutData = (uint8_t*) malloc(cinfo.output_width * cinfo.output_height * cinfo.output_components);
if(OutData == NULL){
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return NULL;
}
for(unsigned i=cinfo.output_height; i; i--){
//According to the libjpeg documentation,
//jpeg_read_scanlines can only really read 1 scanline at a time.
//We need to convert to bottom-up format anyway.
uint8_t * Location = OutData + (i-1)*row_stride;
if(!jpeg_read_scanlines(&cinfo, &Location, 1)){
free(OutData);
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return NULL;
}
}
//Close up
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
if(Image){
Image->Width = cinfo.output_width;
Image->Height = cinfo.output_height;
Image->Format = FIMG_BGR24;
Image->Data = OutData;
}
return OutData;
}
struct pngdata_t {
const uint8_t * buffer;
size_t size;
};
static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length){
pngdata_t *pngdata = (pngdata_t *) png_get_io_ptr(png_ptr);
if(length > pngdata->size) png_error(png_ptr, "");
memcpy(data, pngdata->buffer, length);
pngdata->buffer += length;
pngdata->size -= length;
}
static uint8_t * ReadPNG(Image_t * Image, const uint8_t * InData, size_t FileSize){
pngdata_t pngdata;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(png_ptr == NULL) return 0;
png_infop info_ptr = png_create_info_struct(png_ptr);
if(info_ptr == NULL){
png_destroy_read_struct(&png_ptr, NULL, NULL);
return NULL;
}
if(setjmp(png_jmpbuf(png_ptr))){
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
pngdata.buffer = InData;
pngdata.size = FileSize;
png_set_read_fn(png_ptr, &pngdata, user_read_data);
png_set_user_limits(png_ptr, 4096, 4096);
png_read_png(png_ptr, info_ptr,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA |
PNG_TRANSFORM_PACKING | PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_BGR, NULL);
//png_get_IHDR does not work in high-level mode.
unsigned width = png_get_image_width(png_ptr, info_ptr);
unsigned height = png_get_image_height(png_ptr, info_ptr);
uint8_t * OutData = (uint8_t *) malloc(width*height*3);
if(OutData == NULL){
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
uint8_t **Scanlines = png_get_rows(png_ptr, info_ptr);
for(unsigned i=0; i<height; i++)
memcpy(OutData + i*width*3, Scanlines[height-i-1], width*3);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
Image->Width = width;
Image->Height = height;
Image->Format = FIMG_BGR24;
Image->Data = OutData;
return OutData;
}
static uint8_t * ReadTGA(Image_t * Image, const uint8_t * InData, size_t FileSize){
return NULL;
}
static uint8_t * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize){};
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize){};
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){};
}