mirror of
https://github.com/simtactics/mysimulation.git
synced 2025-07-04 21:50:35 -04:00
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:
parent
64a5c0a425
commit
06f13d50ac
14 changed files with 429 additions and 162 deletions
|
@ -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){};
|
||||
|
||||
}
|
|
@ -16,12 +16,14 @@ set(FILEHANDLER_MAJOR 0)
|
|||
set(FILEHANDLER_MINOR 0)
|
||||
|
||||
set(FILEHANDLER_SOURCES
|
||||
Audio.cpp
|
||||
File.cpp
|
||||
Image.cpp
|
||||
bmp/read_bmp.c
|
||||
cst/cst.c
|
||||
iff/chunks.c
|
||||
iff/iff.c
|
||||
wav/read_wav.c
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler)
|
||||
|
|
|
@ -42,7 +42,8 @@ enum FErr {
|
|||
};
|
||||
|
||||
enum ImageFormat_t {
|
||||
FIMG_BGR24
|
||||
FIMG_BGR24,
|
||||
FIMG_BGRA32
|
||||
};
|
||||
|
||||
struct Image_t {
|
||||
|
@ -51,7 +52,7 @@ struct Image_t {
|
|||
uint8_t * Data;
|
||||
};
|
||||
|
||||
struct Audio_t {
|
||||
struct Sound_t {
|
||||
unsigned Channels;
|
||||
unsigned SamplingRate;
|
||||
unsigned BitDepth;
|
||||
|
@ -66,7 +67,7 @@ extern size_t FileSize;
|
|||
|
||||
uint8_t * ReadFile(const char * Filename);
|
||||
Image_t * ReadImageFile(const char * Filename);
|
||||
Audio_t * ReadAudioFile(const char * Filename);
|
||||
Sound_t * ReadSoundFile(const char * Filename);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -69,10 +69,9 @@ Image_t * ReadImageFile(const char * Filename){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * OutData = NULL;
|
||||
for(int i=0; i<FIMG_COUNT; i++){
|
||||
if(InData[0] == Signature[i]){
|
||||
OutData = ImageFunction[i](Image, InData, File::FileSize);
|
||||
uint8_t * OutData = ImageFunction[i](Image, InData, File::FileSize);
|
||||
free(InData);
|
||||
if(OutData == NULL){
|
||||
File::Error = FERR_INVALIDDATA;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define BI_RGB 0
|
||||
#define BI_RLE8 1
|
||||
|
||||
#ifndef read_int32
|
||||
#ifndef read_uint32
|
||||
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#endif
|
||||
|
@ -110,7 +110,7 @@ int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, u
|
|||
|
||||
if(command == 0){
|
||||
if(value == 0) continue; /* End of scanline reminder */
|
||||
if(value == 1) return 1; /* End of bitmap reminder */
|
||||
if(value == 1) return (InBuffer == srcend && OutBuffer == destend); /* End of bitmap reminder */
|
||||
if(value == 2) return 0; /* Delta, used for ICO/CUR masks; wrong kind of bitmap */
|
||||
|
||||
/* Absolute copy */
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
read_wav.c - Copyright (c) 2012 Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "read_wav.h"
|
||||
|
||||
#define WAVE_FORMAT_PCM 1
|
||||
|
||||
#ifndef read_uint32
|
||||
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#endif
|
||||
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
|
||||
int wav_read_header(wavheader_t * WAVHeader, const uint8_t * Buffer, size_t FileSize){
|
||||
if(FileSize < 45) return 0;
|
||||
WAVHeader->sID = read_uint32(Buffer);
|
||||
WAVHeader->Size = read_uint32(Buffer+4);
|
||||
WAVHeader->DataType = read_uint32(Buffer+8);
|
||||
WAVHeader->FmtID = read_uint32(Buffer+12);
|
||||
WAVHeader->FmtSize = read_uint32(Buffer+16);
|
||||
WAVHeader->wFormatTag = read_uint16(Buffer+20);
|
||||
WAVHeader->nChannels = read_uint16(Buffer+22);
|
||||
WAVHeader->nSamplesPerSec = read_uint32(Buffer+24);
|
||||
WAVHeader->nAvgBytesPerSec = read_uint32(Buffer+28);
|
||||
WAVHeader->nBlockAlign = read_uint16(Buffer+32);
|
||||
WAVHeader->wBitsPerSample = read_uint16(Buffer+34);
|
||||
WAVHeader->DataID = read_uint32(Buffer+36);
|
||||
WAVHeader->DataSize = read_uint32(Buffer+40);
|
||||
|
||||
if(WAVHeader->sID != 0x46464952 || WAVHeader->Size != FileSize-8 || WAVHeader->DataType != 0x45564157 ||
|
||||
WAVHeader->FmtID != 0x20746D66 || WAVHeader->FmtSize != 16 || WAVHeader->wFormatTag != WAVE_FORMAT_PCM ||
|
||||
WAVHeader->nChannels < 1 || WAVHeader->nChannels > 2 || WAVHeader->nSamplesPerSec == 0 ||
|
||||
(WAVHeader->nSamplesPerSec%8000 != 0 && WAVHeader->nSamplesPerSec%11025 != 0) || WAVHeader->nSamplesPerSec > 48000 ||
|
||||
WAVHeader->nAvgBytesPerSec != WAVHeader->nSamplesPerSec * WAVHeader->nBlockAlign ||
|
||||
WAVHeader->nBlockAlign != WAVHeader->nChannels * WAVHeader->wBitsPerSample >> 3 ||
|
||||
(WAVHeader->wBitsPerSample != 8 && WAVHeader->wBitsPerSample != 16) || WAVHeader->DataID != 0x61746164 ||
|
||||
WAVHeader->DataSize != FileSize - 44 || WAVHeader->DataSize % WAVHeader->nBlockAlign != 0
|
||||
) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
read_wav.h - Copyright (c) 2012 Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t sID;
|
||||
uint32_t Size;
|
||||
uint32_t DataType;
|
||||
uint32_t FmtID;
|
||||
uint32_t FmtSize;
|
||||
uint16_t wFormatTag;
|
||||
uint16_t nChannels;
|
||||
uint32_t nSamplesPerSec;
|
||||
uint32_t nAvgBytesPerSec;
|
||||
uint16_t nBlockAlign;
|
||||
uint16_t wBitsPerSample;
|
||||
uint32_t DataID;
|
||||
uint32_t DataSize;
|
||||
} wavheader_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int wav_read_header(wavheader_t * WAVHeader, const uint8_t * Buffer, size_t FileSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue