* Some files were still encoded with Windows newlines. I fixed all of that.

* Started using the static keyword in a few more places in the client
* Updated libpng, libmpg123, and freetype to the latest versions, with position-independent code turned off rather than set to "both"
This commit is contained in:
Fatbag 2012-06-27 22:44:50 -05:00
parent ecafff8c5c
commit 5713fc1bd1
23 changed files with 1432 additions and 1456 deletions

View file

@ -1,5 +1,5 @@
#include <initguid.h>
DEFINE_GUID(CLSID_XAudio2, 0xe21a7345, 0xeb21, 0x468e, 0xbe, 0x50, 0x80, 0x4d, 0xb9, 0x7c, 0xf7, 0x08);
DEFINE_GUID(CLSID_XAudio2_Debug, 0xf7a76c21, 0x53d4, 0x46bb, 0xac, 0x53, 0x8b, 0x45, 0x9c, 0xae, 0x46, 0xbd);
#include <initguid.h>
DEFINE_GUID(CLSID_XAudio2, 0xe21a7345, 0xeb21, 0x468e, 0xbe, 0x50, 0x80, 0x4d, 0xb9, 0x7c, 0xf7, 0x08);
DEFINE_GUID(CLSID_XAudio2_Debug, 0xf7a76c21, 0x53d4, 0x46bb, 0xac, 0x53, 0x8b, 0x45, 0x9c, 0xae, 0x46, 0xbd);
DEFINE_GUID(IID_IXAudio2, 0x8bcf1f58, 0x9fe7, 0x4583, 0x8a, 0xc6, 0xe2, 0xad, 0xc4, 0x65, 0xc8, 0xbb);

View file

@ -20,7 +20,7 @@
#include "EngineInterface.hpp"
void Shutdown();
static void Shutdown();
Scene * CurrentScene;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
@ -115,7 +115,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
return 0;
}
void Shutdown()
static void Shutdown()
{
Audio::Shutdown();
Graphics::Shutdown();

View file

@ -1,179 +1,179 @@
/*
Niotso - The New Implementation of The Sims Online
Graphics/Font.cpp
Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../EngineInterface.hpp"
namespace Graphics {
FT_Library FreeTypeLibrary;
FT_Face FontFace;
static void FindStringSize(const wchar_t * String, unsigned * width, unsigned * height, int * xoffset, int * yoffset, int font){
int x = 0, y = 0;
int lowestx = 0, lowesty = 0, highestx = 0, highesty = 0;
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int bottomx = x + FontFace->glyph->bitmap_left;
int bottomy = y + FontFace->glyph->bitmap_top - FontFace->glyph->bitmap.rows;
if(bottomx < lowestx) lowestx = bottomx;
if(bottomy < lowesty) lowesty = bottomy;
int topx = x + FontFace->glyph->bitmap_left + FontFace->glyph->bitmap.width;
int topy = y + FontFace->glyph->bitmap_top;
if(topx > highestx) highestx = topx;
if(topy > highesty) highesty = topy;
x += FontFace->glyph->advance.x >> 6;
y += FontFace->glyph->advance.y >> 6;
}
*width = highestx-lowestx, *height = highesty-lowesty;
*xoffset = -lowestx, *yoffset = -lowesty;
}
void DrawText(Image_t * Image, const wchar_t * String, int x, int y, unsigned width, unsigned height,
TextAlignment Alignment, int font, COLORREF Color){
//x, y, width, height form the bounding rectangle into which the text should be drawn.
//(x,y) defines the offset to the top-left of the rectangle from the top left of the background.
//The destination image must be stored in bottom-up order.
if(x >= (signed)Image->Width || y >= (signed)Image->Height) return;
//(stringx,stringy) will refer to the top-left of the string in bottom-up coordinates
int stringx, stringy;
unsigned StringWidth, StringHeight;
FindStringSize(String, &StringWidth, &StringHeight, &stringx, &stringy, font);
//Horizontal alignment
if(Alignment < 2) stringx = x; //Left
else if(Alignment < 4) stringx = x+(width-StringWidth+1)/2; //Middle
else stringx = x+width-StringWidth; //Right
//Vertical alignment
if(!(Alignment&1)) stringy = y; //Top
else stringy = y+(height-StringHeight+1)/2; //Middle
stringy = Image->Height-stringy-StringHeight;
//Now that we've done the alignment, we can crop the bounding box within the limits of the background image
if(x < 0){ Image->Width += x; x = 0; }
if(y < 0){ Image->Height += y; y = 0; }
if(width > Image->Width) width = Image->Width;
if(height > Image->Height) height = Image->Height;
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int cWidth = FontFace->glyph->bitmap.width, cHeight = FontFace->glyph->bitmap.rows;
if(cWidth && cHeight){
uint8_t * cRender; /* Convert to Bottom-up */
uint8_t * OriginalRender = FontFace->glyph->bitmap.buffer;
if(FontFace->glyph->bitmap.pitch > 0){
cRender = (uint8_t *) malloc(cWidth * cHeight);
for(int i=0; i<cHeight; i++)
memcpy(cRender + i*cWidth, OriginalRender + (cHeight-i-1)*cWidth, cWidth);
}else cRender = OriginalRender;
stringx += FontFace->glyph->bitmap_left;
stringy += FontFace->glyph->bitmap_top-cHeight;
for(int i=max(-stringy, 0); i<cHeight && (unsigned)stringy+i < height; i++){
for(int j=max(-stringx, 0); j<cWidth && (unsigned)stringx+j < width; j++){
int value = cRender[i*cWidth + j];
uint8_t *ptr = Image->Data + 3*((stringy+i)*width + (stringx+j));
int originalcolor;
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetBValue(Color)-originalcolor)*2*value+255)/510);
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetGValue(Color)-originalcolor)*2*value+255)/510);
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetRValue(Color)-originalcolor)*2*value+255)/510);
}
}
stringx -= FontFace->glyph->bitmap_left;
stringy -= FontFace->glyph->bitmap_top-cHeight;
if(FontFace->glyph->bitmap.pitch > 0) free(cRender);
}
stringx += FontFace->glyph->advance.x >> 6;
stringy += FontFace->glyph->advance.y >> 6;
}
}
Image_t * StringImage(const wchar_t * String, int font, COLORREF Color){
Image_t * Image = (Image_t*) malloc(sizeof(Image_t));
if(Image == NULL) return NULL;
unsigned StringWidth, StringHeight;
int stringx, stringy;
FindStringSize(String, &StringWidth, &StringHeight, &stringx, &stringy, font);
Image->Data = (uint8_t*) malloc(4 * StringWidth * StringHeight);
if(Image->Data == NULL){
free(Image);
return NULL;
}
for(unsigned i=0; i<4*StringWidth*StringHeight;){
Image->Data[i++] = GetBValue(Color);
Image->Data[i++] = GetGValue(Color);
Image->Data[i++] = GetRValue(Color);
Image->Data[i++] = 0;
}
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int cWidth = FontFace->glyph->bitmap.width, cHeight = FontFace->glyph->bitmap.rows;
if(cWidth && cHeight){
uint8_t * cRender; /* Convert to Bottom-up */
uint8_t * OriginalRender = FontFace->glyph->bitmap.buffer;
if(FontFace->glyph->bitmap.pitch > 0){
cRender = (uint8_t *) malloc(cWidth * cHeight);
for(int i=0; i<cHeight; i++)
memcpy(cRender + i*cWidth, OriginalRender + (cHeight-i-1)*cWidth, cWidth);
}else cRender = OriginalRender;
stringx += FontFace->glyph->bitmap_left;
stringy += FontFace->glyph->bitmap_top-cHeight;
for(int i=0; i<cHeight; i++){
for(int j=0; j<cWidth; j++){
uint8_t *ptr = Image->Data + 4*((stringy+i)*StringWidth + (stringx+j));
ptr[3] = cRender[i*cWidth + j];
}
}
stringx -= FontFace->glyph->bitmap_left;
stringy -= FontFace->glyph->bitmap_top-cHeight;
if(FontFace->glyph->bitmap.pitch > 0) free(cRender);
}
stringx += FontFace->glyph->advance.x >> 6;
stringy += FontFace->glyph->advance.y >> 6;
}
Image->Width = StringWidth;
Image->Height = StringHeight;
Image->Format = FIMG_BGRA32;
return Image;
}
/*
Niotso - The New Implementation of The Sims Online
Graphics/Font.cpp
Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../EngineInterface.hpp"
namespace Graphics {
FT_Library FreeTypeLibrary;
FT_Face FontFace;
static void FindStringSize(const wchar_t * String, unsigned * width, unsigned * height, int * xoffset, int * yoffset, int font){
int x = 0, y = 0;
int lowestx = 0, lowesty = 0, highestx = 0, highesty = 0;
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int bottomx = x + FontFace->glyph->bitmap_left;
int bottomy = y + FontFace->glyph->bitmap_top - FontFace->glyph->bitmap.rows;
if(bottomx < lowestx) lowestx = bottomx;
if(bottomy < lowesty) lowesty = bottomy;
int topx = x + FontFace->glyph->bitmap_left + FontFace->glyph->bitmap.width;
int topy = y + FontFace->glyph->bitmap_top;
if(topx > highestx) highestx = topx;
if(topy > highesty) highesty = topy;
x += FontFace->glyph->advance.x >> 6;
y += FontFace->glyph->advance.y >> 6;
}
*width = highestx-lowestx, *height = highesty-lowesty;
*xoffset = -lowestx, *yoffset = -lowesty;
}
void DrawText(Image_t * Image, const wchar_t * String, int x, int y, unsigned width, unsigned height,
TextAlignment Alignment, int font, COLORREF Color){
//x, y, width, height form the bounding rectangle into which the text should be drawn.
//(x,y) defines the offset to the top-left of the rectangle from the top left of the background.
//The destination image must be stored in bottom-up order.
if(x >= (signed)Image->Width || y >= (signed)Image->Height) return;
//(stringx,stringy) will refer to the top-left of the string in bottom-up coordinates
int stringx, stringy;
unsigned StringWidth, StringHeight;
FindStringSize(String, &StringWidth, &StringHeight, &stringx, &stringy, font);
//Horizontal alignment
if(Alignment < 2) stringx = x; //Left
else if(Alignment < 4) stringx = x+(width-StringWidth+1)/2; //Middle
else stringx = x+width-StringWidth; //Right
//Vertical alignment
if(!(Alignment&1)) stringy = y; //Top
else stringy = y+(height-StringHeight+1)/2; //Middle
stringy = Image->Height-stringy-StringHeight;
//Now that we've done the alignment, we can crop the bounding box within the limits of the background image
if(x < 0){ Image->Width += x; x = 0; }
if(y < 0){ Image->Height += y; y = 0; }
if(width > Image->Width) width = Image->Width;
if(height > Image->Height) height = Image->Height;
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int cWidth = FontFace->glyph->bitmap.width, cHeight = FontFace->glyph->bitmap.rows;
if(cWidth && cHeight){
uint8_t * cRender; /* Convert to Bottom-up */
uint8_t * OriginalRender = FontFace->glyph->bitmap.buffer;
if(FontFace->glyph->bitmap.pitch > 0){
cRender = (uint8_t *) malloc(cWidth * cHeight);
for(int i=0; i<cHeight; i++)
memcpy(cRender + i*cWidth, OriginalRender + (cHeight-i-1)*cWidth, cWidth);
}else cRender = OriginalRender;
stringx += FontFace->glyph->bitmap_left;
stringy += FontFace->glyph->bitmap_top-cHeight;
for(int i=max(-stringy, 0); i<cHeight && (unsigned)stringy+i < height; i++){
for(int j=max(-stringx, 0); j<cWidth && (unsigned)stringx+j < width; j++){
int value = cRender[i*cWidth + j];
uint8_t *ptr = Image->Data + 3*((stringy+i)*width + (stringx+j));
int originalcolor;
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetBValue(Color)-originalcolor)*2*value+255)/510);
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetGValue(Color)-originalcolor)*2*value+255)/510);
originalcolor = *ptr;
*ptr++ = (uint8_t) (originalcolor + (int)((GetRValue(Color)-originalcolor)*2*value+255)/510);
}
}
stringx -= FontFace->glyph->bitmap_left;
stringy -= FontFace->glyph->bitmap_top-cHeight;
if(FontFace->glyph->bitmap.pitch > 0) free(cRender);
}
stringx += FontFace->glyph->advance.x >> 6;
stringy += FontFace->glyph->advance.y >> 6;
}
}
Image_t * StringImage(const wchar_t * String, int font, COLORREF Color){
Image_t * Image = (Image_t*) malloc(sizeof(Image_t));
if(Image == NULL) return NULL;
unsigned StringWidth, StringHeight;
int stringx, stringy;
FindStringSize(String, &StringWidth, &StringHeight, &stringx, &stringy, font);
Image->Data = (uint8_t*) malloc(4 * StringWidth * StringHeight);
if(Image->Data == NULL){
free(Image);
return NULL;
}
for(unsigned i=0; i<4*StringWidth*StringHeight;){
Image->Data[i++] = GetBValue(Color);
Image->Data[i++] = GetGValue(Color);
Image->Data[i++] = GetRValue(Color);
Image->Data[i++] = 0;
}
for(wchar_t letter=*String; letter!='\0'; letter=*(++String)){
int error = FT_Load_Char(FontFace, letter, FT_LOAD_RENDER);
if(error) continue;
int cWidth = FontFace->glyph->bitmap.width, cHeight = FontFace->glyph->bitmap.rows;
if(cWidth && cHeight){
uint8_t * cRender; /* Convert to Bottom-up */
uint8_t * OriginalRender = FontFace->glyph->bitmap.buffer;
if(FontFace->glyph->bitmap.pitch > 0){
cRender = (uint8_t *) malloc(cWidth * cHeight);
for(int i=0; i<cHeight; i++)
memcpy(cRender + i*cWidth, OriginalRender + (cHeight-i-1)*cWidth, cWidth);
}else cRender = OriginalRender;
stringx += FontFace->glyph->bitmap_left;
stringy += FontFace->glyph->bitmap_top-cHeight;
for(int i=0; i<cHeight; i++){
for(int j=0; j<cWidth; j++){
uint8_t *ptr = Image->Data + 4*((stringy+i)*StringWidth + (stringx+j));
ptr[3] = cRender[i*cWidth + j];
}
}
stringx -= FontFace->glyph->bitmap_left;
stringy -= FontFace->glyph->bitmap_top-cHeight;
if(FontFace->glyph->bitmap.pitch > 0) free(cRender);
}
stringx += FontFace->glyph->advance.x >> 6;
stringy += FontFace->glyph->advance.y >> 6;
}
Image->Width = StringWidth;
Image->Height = StringHeight;
Image->Format = FIMG_BGRA32;
return Image;
}
}

View file

@ -1,226 +1,226 @@
/*
Niotso - The New Implementation of The Sims Online
Scene/LoginScreen/LoginScreen.cpp
Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../EngineInterface.hpp"
static const wchar_t * const StatusStrings[] = {
L"Extruding Terrain Web",
L"Adjusting Emotional Weights",
L"Calibrating Personality Matrix",
L"Calculating Domestic Coefficients",
L"Readjusting Career Ladder",
L"Accessing Money Supply",
L"Hacking the Social Network",
L"Tweaking Chaos Control",
L"Downloading Reticulated Splines"
};
static const char * const images[] = {"eagames.bmp", "maxis.png", "setup.bmp"};
static const char * const sounds[] = {"loadloop.wav"};
LoginScreen::LoginScreen() : Scene(0){
Screen = Screen_EAGames;
Time = 0;
ScrollPos = -1;
memset(image, 0, IMG_COUNT * sizeof(Image_t *));
memset(texture, 0, TEX_COUNT * sizeof(GLuint));
memset(sound, 0, SND_COUNT * sizeof(PlayableSound_t *));
glMatrixMode(GL_TEXTURE);
glGenTextures(TEX_COUNT, texture);
FT_Set_Char_Size(Graphics::FontFace, 0, 22*64, 0, 0);
for(int i=TEX_EAGAMES; i<=TEX_SETUP; i++){
Image_t * Image = File::ReadImageFile(images[i]);
if(!Image){
const char * Message;
switch(File::Error){
case FERR_NOT_FOUND:
Message = "%s does not exist.";
break;
case FERR_OPEN:
Message = "%s could not be opened for reading.";
break;
case FERR_BLANK:
case FERR_UNRECOGNIZED:
case FERR_INVALIDDATA:
Message = "%s is corrupt or invalid.";
break;
case FERR_MEMORY:
Message = "Memory for %s could not be allocated.";
break;
default:
Message = "%s could not be read.";
}
char Buffer[1024];
sprintf(Buffer, Message, images[i]);
MessageBox(Window::hWnd, Buffer, NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
if(i == TEX_MAXIS){
Graphics::DrawText(Image, L"Maxis\x2122 is an Electronic Arts\x2122 brand.", 0, 600-146, 800, 146,
Graphics::ALIGN_CENTER_CENTER, 0, RGB(0xef, 0xe3, 0x8c));
}
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Image->Width, Image->Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->Data);
free(Image->Data);
free(Image);
}
image[IMG_COPYRIGHT] = Graphics::StringImage(L"(c) 2002, 2003 Electronic Arts Inc. All rights reserved.",
0, RGB(0xef, 0xe3, 0x8c));
if(image[IMG_COPYRIGHT] == NULL){
EXIT_SCENE();
}
glBindTexture(GL_TEXTURE_2D, texture[TEX_COPYRIGHT]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image[IMG_COPYRIGHT]->Width, image[IMG_COPYRIGHT]->Height, 0, GL_BGRA,
GL_UNSIGNED_BYTE, image[IMG_COPYRIGHT]->Data);
free(image[IMG_COPYRIGHT]->Data);
for(int i=0; i<9; i++){
image[IMG_STATUS+i] = Graphics::StringImage(StatusStrings[i], 0, RGB(0xef, 0xe3, 0x8c));
if(image[IMG_STATUS+i] == NULL){
EXIT_SCENE();
}
glBindTexture(GL_TEXTURE_2D, texture[TEX_STATUS+i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image[IMG_STATUS+i]->Width, image[IMG_STATUS+i]->Height, 0, GL_BGRA,
GL_UNSIGNED_BYTE, image[IMG_STATUS+i]->Data);
free(image[IMG_STATUS+i]->Data);
}
for(int i=0; i<SND_COUNT; i++){
Sound_t * Sound = File::ReadSoundFile(sounds[i]);
if(!Sound){
const char * Message;
switch(File::Error){
case FERR_NOT_FOUND:
Message = "%s does not exist.";
break;
case FERR_OPEN:
Message = "%s could not be opened for reading.";
break;
case FERR_BLANK:
case FERR_UNRECOGNIZED:
case FERR_INVALIDDATA:
Message = "%s is corrupt or invalid.";
break;
case FERR_MEMORY:
Message = "Memory for %s could not be allocated.";
break;
default:
Message = "%s could not be read.";
}
char Buffer[1024];
sprintf(Buffer, Message, sounds[i]);
MessageBox(Window::hWnd, Buffer, NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
sound[i] = Audio::LoadSound(Sound);
free(Sound);
if(!sound){
MessageBox(Window::hWnd, "Sound could not be created", NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
Audio::PlaySound(sound[i]);
}
}
LoginScreen::~LoginScreen(){
for(int i=0; i<IMG_COUNT; i++){ if(image[i]) free(image[i]); }
glDeleteTextures(TEX_COUNT, texture);
for(int i=0; i<SND_COUNT; i++){
if(sound[i]){
Audio::DeleteSound(sound[i]);
free(sound[i]->Data);
free(sound[i]);
}
}
}
int LoginScreen::Run(float TimeDelta){
Time += TimeDelta;
if(ScrollPos != 8){
ScrollPos += TimeDelta*0.75;
if(ScrollPos > 8) ScrollPos = 8;
}
if(Screen != Screen_Setup && Time >= 4.0){
Screen = (Screen==Screen_EAGames) ? Screen_Maxis : Screen_Setup;
Time = 0;
}
if(System::UserInput.CloseWindow){
return SCENE_EXIT;
}
return SCENE_NEED_REDRAW;
}
void LoginScreen::Render(){
glMatrixMode(GL_TEXTURE);
//Background
glBindTexture(GL_TEXTURE_2D, texture[Screen]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i(0,0);
glTexCoord2i(1,0); glVertex2i(800,0);
glTexCoord2i(1,1); glVertex2i(800,600);
glTexCoord2i(0,1); glVertex2i(0,600);
glEnd();
if(Screen != Screen_Setup) return;
glBindTexture(GL_TEXTURE_2D, texture[TEX_COPYRIGHT]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2,58);
glTexCoord2i(1,0); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2 + image[IMG_COPYRIGHT]->Width,58);
glTexCoord2i(1,1); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2 + image[IMG_COPYRIGHT]->Width,image[IMG_COPYRIGHT]->Height + 58);
glTexCoord2i(0,1); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2,image[IMG_COPYRIGHT]->Height + 58);
glEnd();
for(int i=0; i<9; i++){
glBindTexture(GL_TEXTURE_2D, texture[TEX_STATUS+i]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2,20);
glTexCoord2i(1,0); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2 + image[IMG_STATUS+i]->Width,20);
glTexCoord2i(1,1); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2 + image[IMG_STATUS+i]->Width,image[IMG_STATUS+i]->Height + 20);
glTexCoord2i(0,1); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2,image[IMG_STATUS+i]->Height + 20);
glEnd();
}
/*
Niotso - The New Implementation of The Sims Online
Scene/LoginScreen/LoginScreen.cpp
Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Fatbag <X-Fi6@phppoll.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../EngineInterface.hpp"
static const wchar_t * const StatusStrings[] = {
L"Extruding Terrain Web",
L"Adjusting Emotional Weights",
L"Calibrating Personality Matrix",
L"Calculating Domestic Coefficients",
L"Readjusting Career Ladder",
L"Accessing Money Supply",
L"Hacking the Social Network",
L"Tweaking Chaos Control",
L"Downloading Reticulated Splines"
};
static const char * const images[] = {"eagames.bmp", "maxis.png", "setup.bmp"};
static const char * const sounds[] = {"loadloop.wav"};
LoginScreen::LoginScreen() : Scene(0){
Screen = Screen_EAGames;
Time = 0;
ScrollPos = -1;
memset(image, 0, IMG_COUNT * sizeof(Image_t *));
memset(texture, 0, TEX_COUNT * sizeof(GLuint));
memset(sound, 0, SND_COUNT * sizeof(PlayableSound_t *));
glMatrixMode(GL_TEXTURE);
glGenTextures(TEX_COUNT, texture);
FT_Set_Char_Size(Graphics::FontFace, 0, 22*64, 0, 0);
for(int i=TEX_EAGAMES; i<=TEX_SETUP; i++){
Image_t * Image = File::ReadImageFile(images[i]);
if(!Image){
const char * Message;
switch(File::Error){
case FERR_NOT_FOUND:
Message = "%s does not exist.";
break;
case FERR_OPEN:
Message = "%s could not be opened for reading.";
break;
case FERR_BLANK:
case FERR_UNRECOGNIZED:
case FERR_INVALIDDATA:
Message = "%s is corrupt or invalid.";
break;
case FERR_MEMORY:
Message = "Memory for %s could not be allocated.";
break;
default:
Message = "%s could not be read.";
}
char Buffer[1024];
sprintf(Buffer, Message, images[i]);
MessageBox(Window::hWnd, Buffer, NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
if(i == TEX_MAXIS){
Graphics::DrawText(Image, L"Maxis\x2122 is an Electronic Arts\x2122 brand.", 0, 600-146, 800, 146,
Graphics::ALIGN_CENTER_CENTER, 0, RGB(0xef, 0xe3, 0x8c));
}
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Image->Width, Image->Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Image->Data);
free(Image->Data);
free(Image);
}
image[IMG_COPYRIGHT] = Graphics::StringImage(L"(c) 2002, 2003 Electronic Arts Inc. All rights reserved.",
0, RGB(0xef, 0xe3, 0x8c));
if(image[IMG_COPYRIGHT] == NULL){
EXIT_SCENE();
}
glBindTexture(GL_TEXTURE_2D, texture[TEX_COPYRIGHT]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image[IMG_COPYRIGHT]->Width, image[IMG_COPYRIGHT]->Height, 0, GL_BGRA,
GL_UNSIGNED_BYTE, image[IMG_COPYRIGHT]->Data);
free(image[IMG_COPYRIGHT]->Data);
for(int i=0; i<9; i++){
image[IMG_STATUS+i] = Graphics::StringImage(StatusStrings[i], 0, RGB(0xef, 0xe3, 0x8c));
if(image[IMG_STATUS+i] == NULL){
EXIT_SCENE();
}
glBindTexture(GL_TEXTURE_2D, texture[TEX_STATUS+i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image[IMG_STATUS+i]->Width, image[IMG_STATUS+i]->Height, 0, GL_BGRA,
GL_UNSIGNED_BYTE, image[IMG_STATUS+i]->Data);
free(image[IMG_STATUS+i]->Data);
}
for(int i=0; i<SND_COUNT; i++){
Sound_t * Sound = File::ReadSoundFile(sounds[i]);
if(!Sound){
const char * Message;
switch(File::Error){
case FERR_NOT_FOUND:
Message = "%s does not exist.";
break;
case FERR_OPEN:
Message = "%s could not be opened for reading.";
break;
case FERR_BLANK:
case FERR_UNRECOGNIZED:
case FERR_INVALIDDATA:
Message = "%s is corrupt or invalid.";
break;
case FERR_MEMORY:
Message = "Memory for %s could not be allocated.";
break;
default:
Message = "%s could not be read.";
}
char Buffer[1024];
sprintf(Buffer, Message, sounds[i]);
MessageBox(Window::hWnd, Buffer, NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
sound[i] = Audio::LoadSound(Sound);
free(Sound);
if(!sound){
MessageBox(Window::hWnd, "Sound could not be created", NULL, MB_OK | MB_ICONERROR);
EXIT_SCENE();
}
Audio::PlaySound(sound[i]);
}
}
LoginScreen::~LoginScreen(){
for(int i=0; i<IMG_COUNT; i++){ if(image[i]) free(image[i]); }
glDeleteTextures(TEX_COUNT, texture);
for(int i=0; i<SND_COUNT; i++){
if(sound[i]){
Audio::DeleteSound(sound[i]);
free(sound[i]->Data);
free(sound[i]);
}
}
}
int LoginScreen::Run(float TimeDelta){
Time += TimeDelta;
if(ScrollPos != 8){
ScrollPos += TimeDelta*0.75;
if(ScrollPos > 8) ScrollPos = 8;
}
if(Screen != Screen_Setup && Time >= 4.0){
Screen = (Screen==Screen_EAGames) ? Screen_Maxis : Screen_Setup;
Time = 0;
}
if(System::UserInput.CloseWindow){
return SCENE_EXIT;
}
return SCENE_NEED_REDRAW;
}
void LoginScreen::Render(){
glMatrixMode(GL_TEXTURE);
//Background
glBindTexture(GL_TEXTURE_2D, texture[Screen]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i(0,0);
glTexCoord2i(1,0); glVertex2i(800,0);
glTexCoord2i(1,1); glVertex2i(800,600);
glTexCoord2i(0,1); glVertex2i(0,600);
glEnd();
if(Screen != Screen_Setup) return;
glBindTexture(GL_TEXTURE_2D, texture[TEX_COPYRIGHT]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2,58);
glTexCoord2i(1,0); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2 + image[IMG_COPYRIGHT]->Width,58);
glTexCoord2i(1,1); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2 + image[IMG_COPYRIGHT]->Width,image[IMG_COPYRIGHT]->Height + 58);
glTexCoord2i(0,1); glVertex2i((800-image[IMG_COPYRIGHT]->Width)/2,image[IMG_COPYRIGHT]->Height + 58);
glEnd();
for(int i=0; i<9; i++){
glBindTexture(GL_TEXTURE_2D, texture[TEX_STATUS+i]);
glBegin(GL_QUADS);
glTexCoord2i(0,0); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2,20);
glTexCoord2i(1,0); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2 + image[IMG_STATUS+i]->Width,20);
glTexCoord2i(1,1); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2 + image[IMG_STATUS+i]->Width,image[IMG_STATUS+i]->Height + 20);
glTexCoord2i(0,1); glVertex2i(((float)i - ScrollPos)*800 + (800-image[IMG_STATUS+i]->Width)/2,image[IMG_STATUS+i]->Height + 20);
glEnd();
}
}

View file

@ -42,14 +42,14 @@ int Initialize(){
Shutdown();
return ERROR_WINDOW_SYNCOBJECT;
}
Thread = CreateThread(NULL, 1024 /* very tiny stack size is needed */, Window::Procedure, NULL, 0, &ThreadID);
if(Thread == NULL){
MessageBox(NULL, "Failed to create the message loop thread.", NULL, MB_OK | MB_ICONERROR);
Shutdown();
return ERROR_WINDOW_CREATE_THREAD;
}
if(WaitForSingleObject(Window::Response, INFINITE) != WAIT_OBJECT_0){
MessageBox(NULL, "Failed to synchronize with the message loop thread.", NULL, MB_OK | MB_ICONERROR);
Shutdown();
@ -60,14 +60,14 @@ int Initialize(){
Shutdown();
return Result;
}
hWnd = FindWindow("TSO_NIOTSO", "The Sims Online");
if(hWnd == NULL){
MessageBox(NULL, "Failed to obtain a handle for the window.", NULL, MB_OK | MB_ICONERROR);
Shutdown();
return ERROR_WINDOW_HANDLE;
}
return 0;
}
@ -88,7 +88,7 @@ void Shutdown(){
CloseHandle(Response);
Response = NULL;
}
UnregisterClass("TSO_NIOTSO", System::hInst);
}
@ -103,7 +103,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_KEYUP:
System::UserInput_v.Keys[wParam] = (uMsg == WM_KEYDOWN);
return 0;
case WM_CLOSE:
System::UserInput_v.CloseWindow = true;
return 0;
@ -113,7 +113,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
System::FramePeriod = 1.0f/dm.dmDisplayFrequency;
} return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
@ -126,13 +126,13 @@ static DWORD WINAPI Procedure(LPVOID){
return 0;
}
SetEvent(Window::Response);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
@ -179,7 +179,7 @@ static int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Heigh
if(hWnd == NULL){
Fullscreen = false;
RECT WindowRect = {0, 0, Width, Height};
//Use a style of WS_OVERLAPPEDWINDOW to allow resizing
AdjustWindowRectEx(&WindowRect, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE,
WS_EX_APPWINDOW); //This finds the dimensions of a window with a client area of our specified dimensions
@ -189,14 +189,14 @@ static int CreateWindowInvisible(HINSTANCE hInst, unsigned Width, unsigned Heigh
unsigned WindowWidth = WindowRect.right-WindowRect.left, WindowHeight = WindowRect.bottom-WindowRect.top;
RECT WorkspaceRect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &WorkspaceRect, 0);
hWnd = CreateWindowEx(WS_EX_APPWINDOW, "TSO_NIOTSO", "The Sims Online",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
((WorkspaceRect.right-WorkspaceRect.left - WindowWidth)>>1) + WorkspaceRect.left,
((WorkspaceRect.bottom-WorkspaceRect.top - WindowHeight)>>1) + WorkspaceRect.top,
WindowWidth, WindowHeight, 0, 0, hInst, NULL);
}
if(hWnd == NULL){
MessageBox(NULL, "Failed to create the window.", NULL, MB_OK | MB_ICONERROR);
return ERROR_WINDOW_CREATE;

View file

@ -1,208 +1,208 @@
/*
FileHandler - General-purpose file handling library for Niotso
Audio.cpp - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
Author(s): 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 "FileHandler.hpp"
#include "wav/read_wav.h"
#include "xa/read_xa.h"
#include "utk/read_utk.h"
#include "libmpg123/mpg123.h"
namespace File {
enum SoundType {
FSND_WAV,
FSND_XA,
FSND_UTK,
FSND_MP3,
FSND_COUNT
};
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
'X', //XA
'U', //UTK
0xFF //MP3
};
static uint8_t* (* const SoundFunction[])(Sound_t*, const uint8_t*, size_t) = {
ReadWAV,
ReadXA,
ReadUTK,
ReadMP3
};
Sound_t * ReadSoundFile(const char * Filename){
uint8_t * InData = File::ReadFile(Filename);
if(InData == NULL) return NULL;
if(File::FileSize < 4){
free(InData);
File::Error = FERR_INVALIDDATA;
return NULL;
}
Sound_t * Sound = (Sound_t*) malloc(sizeof(Sound_t));
if(Sound == NULL){
free(InData);
File::Error = FERR_MEMORY;
return NULL;
}
for(int i=0; i<FSND_COUNT; i++){
if(InData[0] == Signature[i]){
uint8_t * OutData = SoundFunction[i](Sound, InData, File::FileSize);
free(InData);
if(OutData == NULL){
File::Error = FERR_INVALIDDATA;
return NULL;
}
return Sound;
}
}
free(InData);
File::Error = FERR_UNRECOGNIZED;
return NULL;
}
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(WAVHeader.DataSize);
if(OutData == NULL){
return NULL;
}
memcpy(OutData, InData+44, WAVHeader.DataSize);
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 * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
xaheader_t XAHeader;
if(!xa_read_header(&XAHeader, InData, FileSize)){
return NULL;
}
uint8_t * OutData = (uint8_t*) malloc(XAHeader.dwOutSize);
if(OutData == NULL){
return NULL;
}
if(!xa_decode(InData+24, OutData, XAHeader.Frames, XAHeader.nChannels)){
free(OutData);
return NULL;
}
Sound->Channels = XAHeader.nChannels;
Sound->SamplingRate = XAHeader.nSamplesPerSec;
Sound->BitDepth = XAHeader.wBitsPerSample;
Sound->Duration = XAHeader.dwOutSize / XAHeader.nBlockAlign;
Sound->Data = OutData;
return OutData;
}
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
utkheader_t UTKHeader;
if(!utk_read_header(&UTKHeader, InData, FileSize)){
return NULL;
}
uint8_t * OutData = (uint8_t*) malloc(UTKHeader.dwOutSize);
if(OutData == NULL){
return NULL;
}
static bool generated = false;
if(!generated){
UTKGenerateTables();
generated = true;
}
if(!utk_decode(InData+32, OutData, UTKHeader.Frames)){
free(OutData);
return NULL;
}
Sound->Channels = 1;
Sound->SamplingRate = UTKHeader.nSamplesPerSec;
Sound->BitDepth = UTKHeader.wBitsPerSample;
Sound->Duration = UTKHeader.dwOutSize / UTKHeader.nBlockAlign;
Sound->Data = OutData;
return OutData;
}
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
mpg123_handle *mh;
if(mpg123_init() != MPG123_OK || (mh = mpg123_new(NULL, NULL)) == NULL){
mpg123_exit();
return NULL;
}
long rate;
int channels, encoding;
unsigned samples;
size_t OutSize;
uint8_t * OutData;
if(mpg123_format_none(mh) != MPG123_OK ||
mpg123_format(mh, 44100, MPG123_MONO | MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK ||
mpg123_open_feed(mh) != MPG123_OK ||
mpg123_feed(mh, InData, FileSize) != MPG123_OK ||
mpg123_set_filesize(mh, FileSize) != MPG123_OK ||
mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ||
(samples = mpg123_length(mh)) == 0 ||
(OutData = (uint8_t*) malloc(OutSize = samples * channels * 2)) == NULL
){
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
return NULL;
}
size_t decoded;
mpg123_read(mh, OutData, OutSize, &decoded);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
if(decoded != OutSize){
free(OutData);
return NULL;
}
Sound->Channels = channels;
Sound->SamplingRate = rate;
Sound->BitDepth = 16;
Sound->Duration = samples;
Sound->Data = OutData;
return OutData;
}
/*
FileHandler - General-purpose file handling library for Niotso
Audio.cpp - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
Author(s): 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 "FileHandler.hpp"
#include "wav/read_wav.h"
#include "xa/read_xa.h"
#include "utk/read_utk.h"
#include "libmpg123/mpg123.h"
namespace File {
enum SoundType {
FSND_WAV,
FSND_XA,
FSND_UTK,
FSND_MP3,
FSND_COUNT
};
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
'X', //XA
'U', //UTK
0xFF //MP3
};
static uint8_t* (* const SoundFunction[])(Sound_t*, const uint8_t*, size_t) = {
ReadWAV,
ReadXA,
ReadUTK,
ReadMP3
};
Sound_t * ReadSoundFile(const char * Filename){
uint8_t * InData = File::ReadFile(Filename);
if(InData == NULL) return NULL;
if(File::FileSize < 4){
free(InData);
File::Error = FERR_INVALIDDATA;
return NULL;
}
Sound_t * Sound = (Sound_t*) malloc(sizeof(Sound_t));
if(Sound == NULL){
free(InData);
File::Error = FERR_MEMORY;
return NULL;
}
for(int i=0; i<FSND_COUNT; i++){
if(InData[0] == Signature[i]){
uint8_t * OutData = SoundFunction[i](Sound, InData, File::FileSize);
free(InData);
if(OutData == NULL){
File::Error = FERR_INVALIDDATA;
return NULL;
}
return Sound;
}
}
free(InData);
File::Error = FERR_UNRECOGNIZED;
return NULL;
}
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(WAVHeader.DataSize);
if(OutData == NULL){
return NULL;
}
memcpy(OutData, InData+44, WAVHeader.DataSize);
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 * ReadXA(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
xaheader_t XAHeader;
if(!xa_read_header(&XAHeader, InData, FileSize)){
return NULL;
}
uint8_t * OutData = (uint8_t*) malloc(XAHeader.dwOutSize);
if(OutData == NULL){
return NULL;
}
if(!xa_decode(InData+24, OutData, XAHeader.Frames, XAHeader.nChannels)){
free(OutData);
return NULL;
}
Sound->Channels = XAHeader.nChannels;
Sound->SamplingRate = XAHeader.nSamplesPerSec;
Sound->BitDepth = XAHeader.wBitsPerSample;
Sound->Duration = XAHeader.dwOutSize / XAHeader.nBlockAlign;
Sound->Data = OutData;
return OutData;
}
static uint8_t * ReadUTK(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
utkheader_t UTKHeader;
if(!utk_read_header(&UTKHeader, InData, FileSize)){
return NULL;
}
uint8_t * OutData = (uint8_t*) malloc(UTKHeader.dwOutSize);
if(OutData == NULL){
return NULL;
}
static bool generated = false;
if(!generated){
UTKGenerateTables();
generated = true;
}
if(!utk_decode(InData+32, OutData, UTKHeader.Frames)){
free(OutData);
return NULL;
}
Sound->Channels = 1;
Sound->SamplingRate = UTKHeader.nSamplesPerSec;
Sound->BitDepth = UTKHeader.wBitsPerSample;
Sound->Duration = UTKHeader.dwOutSize / UTKHeader.nBlockAlign;
Sound->Data = OutData;
return OutData;
}
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
mpg123_handle *mh;
if(mpg123_init() != MPG123_OK || (mh = mpg123_new(NULL, NULL)) == NULL){
mpg123_exit();
return NULL;
}
long rate;
int channels, encoding;
unsigned samples;
size_t OutSize;
uint8_t * OutData;
if(mpg123_format_none(mh) != MPG123_OK ||
mpg123_format(mh, 44100, MPG123_MONO | MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK ||
mpg123_open_feed(mh) != MPG123_OK ||
mpg123_feed(mh, InData, FileSize) != MPG123_OK ||
mpg123_set_filesize(mh, FileSize) != MPG123_OK ||
mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ||
(samples = mpg123_length(mh)) == 0 ||
(OutData = (uint8_t*) malloc(OutSize = samples * channels * 2)) == NULL
){
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
return NULL;
}
size_t decoded;
mpg123_read(mh, OutData, OutSize, &decoded);
mpg123_close(mh);
mpg123_delete(mh);
mpg123_exit();
if(decoded != OutSize){
free(OutData);
return NULL;
}
Sound->Channels = channels;
Sound->SamplingRate = rate;
Sound->BitDepth = 16;
Sound->Duration = samples;
Sound->Data = OutData;
return OutData;
}
}

View file

@ -29,10 +29,6 @@
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
#endif
#ifndef __restrict
#define __restrict
#endif
int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t FileSize){
unsigned padding;
if(FileSize < 54) return 0;

View file

@ -1,49 +1,49 @@
/*
FileHandler - General-purpose file handling library for Niotso
cst.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 <stdlib.h>
#include <string.h>
#include "cst.h"
static unsigned cst_count_strings(const char * Buffer, size_t FileSize){
unsigned count = 0;
int instring = 0;
while(FileSize--){
if(*Buffer == '^' && (instring = !instring) == 0)
count++;
Buffer++;
}
return count;
}
int cst_read(CSTFile * CSTFileInfo, char * Buffer, size_t FileSize){
CSTFileInfo->CSTData = Buffer;
CSTFileInfo->StringCount = cst_count_strings(Buffer, FileSize);
if(CSTFileInfo->StringCount != 0){
unsigned i;
CSTFileInfo->Strings = malloc(CSTFileInfo->StringCount * sizeof(char *));
if(CSTFileInfo->Strings == NULL)
return 0;
for(i=0; i<CSTFileInfo->StringCount; i++){
CSTFileInfo->Strings[i] = Buffer = strchr(Buffer, '^') + 1;
*(Buffer = strchr(Buffer, '^')) = 0x00;
Buffer++;
}
}
return 1;
/*
FileHandler - General-purpose file handling library for Niotso
cst.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 <stdlib.h>
#include <string.h>
#include "cst.h"
static unsigned cst_count_strings(const char * Buffer, size_t FileSize){
unsigned count = 0;
int instring = 0;
while(FileSize--){
if(*Buffer == '^' && (instring = !instring) == 0)
count++;
Buffer++;
}
return count;
}
int cst_read(CSTFile * CSTFileInfo, char * Buffer, size_t FileSize){
CSTFileInfo->CSTData = Buffer;
CSTFileInfo->StringCount = cst_count_strings(Buffer, FileSize);
if(CSTFileInfo->StringCount != 0){
unsigned i;
CSTFileInfo->Strings = malloc(CSTFileInfo->StringCount * sizeof(char *));
if(CSTFileInfo->Strings == NULL)
return 0;
for(i=0; i<CSTFileInfo->StringCount; i++){
CSTFileInfo->Strings[i] = Buffer = strchr(Buffer, '^') + 1;
*(Buffer = strchr(Buffer, '^')) = 0x00;
Buffer++;
}
}
return 1;
}

View file

@ -1,23 +1,23 @@
/*
FileHandler - General-purpose file handling library for Niotso
cst.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 {
char * CSTData;
unsigned StringCount;
char ** Strings;
/*
FileHandler - General-purpose file handling library for Niotso
cst.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 {
char * CSTData;
unsigned StringCount;
char ** Strings;
} CSTFile;

View file

@ -1,17 +1,17 @@
/*
FileHandler - General-purpose file handling library for Niotso
read_cur.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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.
/*
FileHandler - General-purpose file handling library for Niotso
read_cur.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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.
*/

View file

@ -1,17 +1,17 @@
/*
FileHandler - General-purpose file handling library for Niotso
read_cur.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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.
/*
FileHandler - General-purpose file handling library for Niotso
read_cur.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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.
*/

View file

@ -17,11 +17,7 @@
*/
#include <string.h>
typedef unsigned char uint8_t;
#ifndef __restrict
#define __restrict
#endif
#include <stdint.h>
int RefPackDecompress(const uint8_t *__restrict CompressedData, size_t CompressedSize,
uint8_t *__restrict DecompressedData, size_t DecompressedSize, unsigned HNSV){

View file

@ -1,53 +1,53 @@
/*
FileHandler - General-purpose file handling library for Niotso
bcon.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
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 "iffparser.h"
int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFF_BCON *BCONData;
unsigned i;
if(ChunkInfo->Size < 2)
return 0;
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
if(ChunkInfo->FormattedData == NULL)
return 0;
BCONData = ChunkInfo->FormattedData;
BCONData->ConstantCount = read_uint8le(Buffer);
BCONData->Flags = read_uint8le(Buffer + 1);
if(BCONData->ConstantCount == 0)
return 1;
if(BCONData->ConstantCount * 2 /* bytes */ > ChunkInfo->Size - 2)
return 0;
BCONData->Constants = malloc(BCONData->ConstantCount * sizeof(uint16_t));
if(BCONData->Constants == NULL)
return 0;
Buffer += 2;
for(i=0; i<BCONData->ConstantCount; i++, Buffer += 2)
BCONData->Constants[i] = read_uint16le(Buffer);
return 1;
}
void iff_free_bcon(void * FormattedData){
IFF_BCON *BCONData = FormattedData;
free(BCONData->Constants);
/*
FileHandler - General-purpose file handling library for Niotso
bcon.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
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 "iffparser.h"
int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFF_BCON *BCONData;
unsigned i;
if(ChunkInfo->Size < 2)
return 0;
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
if(ChunkInfo->FormattedData == NULL)
return 0;
BCONData = ChunkInfo->FormattedData;
BCONData->ConstantCount = read_uint8le(Buffer);
BCONData->Flags = read_uint8le(Buffer + 1);
if(BCONData->ConstantCount == 0)
return 1;
if(BCONData->ConstantCount * 2 /* bytes */ > ChunkInfo->Size - 2)
return 0;
BCONData->Constants = malloc(BCONData->ConstantCount * sizeof(uint16_t));
if(BCONData->Constants == NULL)
return 0;
Buffer += 2;
for(i=0; i<BCONData->ConstantCount; i++, Buffer += 2)
BCONData->Constants[i] = read_uint16le(Buffer);
return 1;
}
void iff_free_bcon(void * FormattedData){
IFF_BCON *BCONData = FormattedData;
free(BCONData->Constants);
}

View file

@ -1,108 +1,108 @@
/*
FileHandler - General-purpose file handling library for Niotso
dgrp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
#define read_split(x, y, z) \
(largefields ? read_uint##z(x) : read_uint##y(x))
int iff_parse_dgrp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFDrawGroup *Group;
bytestream b;
int largefields;
unsigned i;
if(ChunkInfo->Size < 52)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
ChunkInfo->FormattedData = calloc(1, sizeof(IFFDrawGroup));
if(ChunkInfo->FormattedData == NULL)
return 0;
Group = ChunkInfo->FormattedData;
Group->Version = read_uint16(&b);
if(Group->Version < 20000 || Group->Version > 20004 || Group->Version == 20002)
return 0;
largefields = (Group->Version >= 20003);
Group->AngleCount = read_split(&b, 16, 32);
if(Group->AngleCount != 12)
return 0;
for(i=0; i<12; i++){
IFFDrawAngle * Angle = &Group->DrawAngles[i];
unsigned j;
if(b.Size < ((!largefields) ? 4 : 12))
return 0;
if(!largefields)
Angle->SpriteCount = read_uint16(&b);
Angle->Direction = read_split(&b, 8, 32);
Angle->Zoom = read_split(&b, 8, 32);
if(largefields)
Angle->SpriteCount = read_uint32(&b);
if((Angle->Direction != 1 && Angle->Direction != 4 && Angle->Direction != 16 && Angle->Direction != 64)
|| (!Angle->Zoom || Angle->Zoom > 3))
return 0;
if(Angle->SpriteCount == 0)
continue;
Angle->SpriteInfo = calloc(Angle->SpriteCount, sizeof(IFFSpriteInfo));
if(Angle->SpriteInfo == NULL)
return 0;
for(j=0; j<Angle->SpriteCount; j++){
IFFSpriteInfo * Sprite = &Angle->SpriteInfo[j];
const uint8_t size[5] = {12, 16, 0, 24, 32};
if(b.Size < size[Group->Version - 20000])
return 0;
if(!largefields)
Sprite->Type = read_uint16(&b);
Sprite->ChunkID = read_split(&b, 16, 32);
Sprite->SpriteIndex = read_split(&b, 16, 32);
if(!largefields)
Sprite->Flags = read_uint16(&b);
Sprite->SpriteX = read_split(&b, 16, 32);
Sprite->SpriteY = read_split(&b, 16, 32);
if(Group->Version >= 20001){
Sprite->ObjectZ = read_float(&b);
if(Group->Version >= 20003){
Sprite->Flags = read_uint32(&b);
if(Group->Version == 20004){
Sprite->ObjectX = read_float(&b);
Sprite->ObjectY = read_float(&b);
}
}
}
}
}
return 1;
}
void iff_free_dgrp(void * FormattedData){
IFFDrawGroup *Group = FormattedData;
int i;
for(i=0; i<12; i++){
IFFDrawAngle *Angle = &Group->DrawAngles[i];
free(Angle->SpriteInfo);
}
/*
FileHandler - General-purpose file handling library for Niotso
dgrp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
#define read_split(x, y, z) \
(largefields ? read_uint##z(x) : read_uint##y(x))
int iff_parse_dgrp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFDrawGroup *Group;
bytestream b;
int largefields;
unsigned i;
if(ChunkInfo->Size < 52)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
ChunkInfo->FormattedData = calloc(1, sizeof(IFFDrawGroup));
if(ChunkInfo->FormattedData == NULL)
return 0;
Group = ChunkInfo->FormattedData;
Group->Version = read_uint16(&b);
if(Group->Version < 20000 || Group->Version > 20004 || Group->Version == 20002)
return 0;
largefields = (Group->Version >= 20003);
Group->AngleCount = read_split(&b, 16, 32);
if(Group->AngleCount != 12)
return 0;
for(i=0; i<12; i++){
IFFDrawAngle * Angle = &Group->DrawAngles[i];
unsigned j;
if(b.Size < ((!largefields) ? 4 : 12))
return 0;
if(!largefields)
Angle->SpriteCount = read_uint16(&b);
Angle->Direction = read_split(&b, 8, 32);
Angle->Zoom = read_split(&b, 8, 32);
if(largefields)
Angle->SpriteCount = read_uint32(&b);
if((Angle->Direction != 1 && Angle->Direction != 4 && Angle->Direction != 16 && Angle->Direction != 64)
|| (!Angle->Zoom || Angle->Zoom > 3))
return 0;
if(Angle->SpriteCount == 0)
continue;
Angle->SpriteInfo = calloc(Angle->SpriteCount, sizeof(IFFSpriteInfo));
if(Angle->SpriteInfo == NULL)
return 0;
for(j=0; j<Angle->SpriteCount; j++){
IFFSpriteInfo * Sprite = &Angle->SpriteInfo[j];
const uint8_t size[5] = {12, 16, 0, 24, 32};
if(b.Size < size[Group->Version - 20000])
return 0;
if(!largefields)
Sprite->Type = read_uint16(&b);
Sprite->ChunkID = read_split(&b, 16, 32);
Sprite->SpriteIndex = read_split(&b, 16, 32);
if(!largefields)
Sprite->Flags = read_uint16(&b);
Sprite->SpriteX = read_split(&b, 16, 32);
Sprite->SpriteY = read_split(&b, 16, 32);
if(Group->Version >= 20001){
Sprite->ObjectZ = read_float(&b);
if(Group->Version >= 20003){
Sprite->Flags = read_uint32(&b);
if(Group->Version == 20004){
Sprite->ObjectX = read_float(&b);
Sprite->ObjectY = read_float(&b);
}
}
}
}
}
return 1;
}
void iff_free_dgrp(void * FormattedData){
IFFDrawGroup *Group = FormattedData;
int i;
for(i=0; i<12; i++){
IFFDrawAngle *Angle = &Group->DrawAngles[i];
free(Angle->SpriteInfo);
}
}

View file

@ -1,93 +1,93 @@
/*
FileHandler - General-purpose file handling library for Niotso
rsmp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFResourceMap *Map;
bytestream b;
unsigned i;
if(ChunkInfo->Size < 20)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
if(ChunkInfo->FormattedData == NULL)
return 0;
Map = ChunkInfo->FormattedData;
Map->Reserved = read_uint32(&b);
Map->Version = read_uint32(&b);
memcpy(Map->MagicNumber, b.Buffer, 4);
skipbytes(&b, 4);
Map->IFFSize = read_uint32(&b);
Map->TypeCount = read_uint32(&b);
if(Map->Reserved != 0 || Map->Version > 1)
return 0;
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
if(Map->ResourceTypes == NULL)
return 0;
for(i=0; i<Map->TypeCount; i++){
IFFResourceType * Type = &Map->ResourceTypes[i];
unsigned j;
if(b.Size < 8) return 0;
memcpy(Type->Type, b.Buffer, 4);
skipbytes(&b, 4);
Type->ResourceCount = read_uint32(&b);
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
if(Type->Resources == NULL)
return 0;
for(j=0; j<Type->ResourceCount; j++){
IFFResource * Resource = &Type->Resources[j];
if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
Resource->Offset = read_uint32(&b);
Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
Resource->Flags = read_uint16(&b);
if(Map->Version == 0){
if(!read_c_string(&b, &Resource->Label))
return 0;
}else{
if(!read_pascal_string(&b, &Resource->Label))
return 0;
}
}
}
return 1;
}
void iff_free_rsmp(void * FormattedData){
IFFResourceMap * Map = FormattedData;
if(Map->ResourceTypes){
unsigned t;
for(t=0; t<Map->TypeCount; t++){
IFFResourceType * Type = &Map->ResourceTypes[t];
if(Type->Resources){
unsigned r;
for(r=0; r<Type->ResourceCount; r++)
free(Type->Resources[r].Label);
free(Type->Resources);
}
}
free(Map->ResourceTypes);
}
/*
FileHandler - General-purpose file handling library for Niotso
rsmp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFResourceMap *Map;
bytestream b;
unsigned i;
if(ChunkInfo->Size < 20)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
if(ChunkInfo->FormattedData == NULL)
return 0;
Map = ChunkInfo->FormattedData;
Map->Reserved = read_uint32(&b);
Map->Version = read_uint32(&b);
memcpy(Map->MagicNumber, b.Buffer, 4);
skipbytes(&b, 4);
Map->IFFSize = read_uint32(&b);
Map->TypeCount = read_uint32(&b);
if(Map->Reserved != 0 || Map->Version > 1)
return 0;
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
if(Map->ResourceTypes == NULL)
return 0;
for(i=0; i<Map->TypeCount; i++){
IFFResourceType * Type = &Map->ResourceTypes[i];
unsigned j;
if(b.Size < 8) return 0;
memcpy(Type->Type, b.Buffer, 4);
skipbytes(&b, 4);
Type->ResourceCount = read_uint32(&b);
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
if(Type->Resources == NULL)
return 0;
for(j=0; j<Type->ResourceCount; j++){
IFFResource * Resource = &Type->Resources[j];
if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
Resource->Offset = read_uint32(&b);
Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
Resource->Flags = read_uint16(&b);
if(Map->Version == 0){
if(!read_c_string(&b, &Resource->Label))
return 0;
}else{
if(!read_pascal_string(&b, &Resource->Label))
return 0;
}
}
}
return 1;
}
void iff_free_rsmp(void * FormattedData){
IFFResourceMap * Map = FormattedData;
if(Map->ResourceTypes){
unsigned t;
for(t=0; t<Map->TypeCount; t++){
IFFResourceType * Type = &Map->ResourceTypes[t];
if(Type->Resources){
unsigned r;
for(r=0; r<Type->ResourceCount; r++)
free(Type->Resources[r].Label);
free(Type->Resources);
}
}
free(Map->ResourceTypes);
}
}

View file

@ -1,221 +1,221 @@
/*
FileHandler - General-purpose file handling library for Niotso
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFSpriteList *SpriteList;
bytestream b;
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
unsigned i;
if(ChunkInfo->Size < 12)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
if(ChunkInfo->FormattedData == NULL)
return 0;
SpriteList = ChunkInfo->FormattedData;
SpriteList->Version = read_uint32(&b);
SpriteList->SpriteCount = read_uint32(&b);
SpriteList->PaletteID = read_uint32(&b);
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
return 0;
if(SpriteList->Version != 1001){
if(SpriteList->SpriteCount > b.Size/4)
return 0;
}else{
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
** this is easy with the sprite size field */
for(SpriteList->SpriteCount = 0; b.Size >= 16; SpriteList->SpriteCount++){
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
return 0;
}
NextSpriteOffset = 16;
}
if(SpriteList->SpriteCount == 0)
return 1;
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
if(SpriteList->Sprites == NULL)
return 0;
for(i=0; i<SpriteList->SpriteCount; i++){
IFFSprite * Sprite = &SpriteList->Sprites[i];
unsigned SpriteSize;
unsigned row = 0;
if(SpriteList->Version != 1001){
/* Jump to the next sprite using the offset table; this is mandatory */
seekto(&b, 12 + 4*i);
if(!seekto(&b, read_uint32(&b)) || b.Size < 8)
return 0;
SpriteSize = b.Size;
}else{
/* Jump to the next sprite using the sprite size field; this is mandatory */
seekto(&b, NextSpriteOffset);
SpriteSize = read_uint32(&b);
NextSpriteOffset += SpriteSize + 8;
}
Sprite->Reserved = read_uint32(&b);
Sprite->Height = read_uint16(&b);
Sprite->Width = read_uint16(&b);
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
/* This happens in the third sprite of every SPR# chunk in sprites.iff */
Sprite->InvalidDimensions = 1;
continue;
}
SpriteSize -= 8;
Sprite->IndexData = calloc(Sprite->Width*Sprite->Height, 2);
if(Sprite->IndexData == NULL)
return 0;
while(1){
/****
** Row command: valid commands are 0, 4, 5, 9, and 16
*/
uint8_t RowCommand, RowCount;
if(SpriteSize < 2)
return 0;
RowCommand = *(b.Buffer++);
RowCount = *(b.Buffer++);
SpriteSize -= 2;
if(RowCommand == 0 || RowCommand == 16){
/* Start marker */
}else if(RowCommand == 4){
/****
** Pixel command: valid commands are 1, 2, and 3
*/
unsigned pixel = 0;
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
return 0;
SpriteSize -= RowCount;
while(RowCount){
uint8_t PixelCommand, PixelCount;
uint8_t * IndexData;
if(RowCount < 2)
return 0;
PixelCommand = *(b.Buffer++);
PixelCount = *(b.Buffer++);
RowCount -= 2;
if(PixelCount > Sprite->Width - pixel)
return 0;
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
pixel += PixelCount;
if(PixelCommand == 1){
/* Leave next n pixels as transparent */
}else if(PixelCommand == 2){
/* Set next n pixels to shared palette index */
uint8_t PaletteIndex;
if(RowCount < 2)
return 0;
PaletteIndex = *(b.Buffer++);
b.Buffer++; /* Padding byte */
RowCount -= 2;
while(PixelCount--){
*IndexData++ = PaletteIndex;
*IndexData++ = 0xFF;
}
}else if(PixelCommand == 3){
/* Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(PixelCount + padding > RowCount)
return 0;
RowCount -= PixelCount + padding;
while(PixelCount--){
*IndexData++ = *(b.Buffer++);
*IndexData++ = 0xFF;
}
if(padding) b.Buffer++; /* Padding byte */
}else return 0;
}
row++;
}else if(RowCommand == 5){
/* End marker */
break;
}else if(RowCommand == 9){
/* Leave rows as transparent */
if(RowCount > Sprite->Height - row)
return 0;
row += RowCount;
}else return 0;
}
}
return 1;
}
void iff_free_spr(void * FormattedData){
IFFSpriteList *SpriteList = FormattedData;
if(SpriteList->Sprites){
unsigned s;
for(s=0; s<SpriteList->SpriteCount; s++){
IFFSprite *Sprite = &SpriteList->Sprites[s];
free(Sprite->IndexData);
free(Sprite->BGRA32Data);
free(Sprite->ZBuffer);
}
free(SpriteList->Sprites);
}
}
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
unsigned PixelCount = Sprite->Width*Sprite->Height;
unsigned i;
Sprite->BGRA32Data = malloc(PixelCount*4);
if(Sprite->BGRA32Data == NULL) return 0;
for(i=0; i<PixelCount; i++){
uint8_t Index = Sprite->IndexData[2*i + 0];
if(Index >= Palette->ColorCount){
free(Sprite->BGRA32Data);
Sprite->BGRA32Data = NULL;
return 0;
}
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
}
return 1;
/*
FileHandler - General-purpose file handling library for Niotso
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFSpriteList *SpriteList;
bytestream b;
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
unsigned i;
if(ChunkInfo->Size < 12)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
if(ChunkInfo->FormattedData == NULL)
return 0;
SpriteList = ChunkInfo->FormattedData;
SpriteList->Version = read_uint32(&b);
SpriteList->SpriteCount = read_uint32(&b);
SpriteList->PaletteID = read_uint32(&b);
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
return 0;
if(SpriteList->Version != 1001){
if(SpriteList->SpriteCount > b.Size/4)
return 0;
}else{
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
** this is easy with the sprite size field */
for(SpriteList->SpriteCount = 0; b.Size >= 16; SpriteList->SpriteCount++){
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
return 0;
}
NextSpriteOffset = 16;
}
if(SpriteList->SpriteCount == 0)
return 1;
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
if(SpriteList->Sprites == NULL)
return 0;
for(i=0; i<SpriteList->SpriteCount; i++){
IFFSprite * Sprite = &SpriteList->Sprites[i];
unsigned SpriteSize;
unsigned row = 0;
if(SpriteList->Version != 1001){
/* Jump to the next sprite using the offset table; this is mandatory */
seekto(&b, 12 + 4*i);
if(!seekto(&b, read_uint32(&b)) || b.Size < 8)
return 0;
SpriteSize = b.Size;
}else{
/* Jump to the next sprite using the sprite size field; this is mandatory */
seekto(&b, NextSpriteOffset);
SpriteSize = read_uint32(&b);
NextSpriteOffset += SpriteSize + 8;
}
Sprite->Reserved = read_uint32(&b);
Sprite->Height = read_uint16(&b);
Sprite->Width = read_uint16(&b);
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
/* This happens in the third sprite of every SPR# chunk in sprites.iff */
Sprite->InvalidDimensions = 1;
continue;
}
SpriteSize -= 8;
Sprite->IndexData = calloc(Sprite->Width*Sprite->Height, 2);
if(Sprite->IndexData == NULL)
return 0;
while(1){
/****
** Row command: valid commands are 0, 4, 5, 9, and 16
*/
uint8_t RowCommand, RowCount;
if(SpriteSize < 2)
return 0;
RowCommand = *(b.Buffer++);
RowCount = *(b.Buffer++);
SpriteSize -= 2;
if(RowCommand == 0 || RowCommand == 16){
/* Start marker */
}else if(RowCommand == 4){
/****
** Pixel command: valid commands are 1, 2, and 3
*/
unsigned pixel = 0;
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
return 0;
SpriteSize -= RowCount;
while(RowCount){
uint8_t PixelCommand, PixelCount;
uint8_t * IndexData;
if(RowCount < 2)
return 0;
PixelCommand = *(b.Buffer++);
PixelCount = *(b.Buffer++);
RowCount -= 2;
if(PixelCount > Sprite->Width - pixel)
return 0;
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
pixel += PixelCount;
if(PixelCommand == 1){
/* Leave next n pixels as transparent */
}else if(PixelCommand == 2){
/* Set next n pixels to shared palette index */
uint8_t PaletteIndex;
if(RowCount < 2)
return 0;
PaletteIndex = *(b.Buffer++);
b.Buffer++; /* Padding byte */
RowCount -= 2;
while(PixelCount--){
*IndexData++ = PaletteIndex;
*IndexData++ = 0xFF;
}
}else if(PixelCommand == 3){
/* Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(PixelCount + padding > RowCount)
return 0;
RowCount -= PixelCount + padding;
while(PixelCount--){
*IndexData++ = *(b.Buffer++);
*IndexData++ = 0xFF;
}
if(padding) b.Buffer++; /* Padding byte */
}else return 0;
}
row++;
}else if(RowCommand == 5){
/* End marker */
break;
}else if(RowCommand == 9){
/* Leave rows as transparent */
if(RowCount > Sprite->Height - row)
return 0;
row += RowCount;
}else return 0;
}
}
return 1;
}
void iff_free_spr(void * FormattedData){
IFFSpriteList *SpriteList = FormattedData;
if(SpriteList->Sprites){
unsigned s;
for(s=0; s<SpriteList->SpriteCount; s++){
IFFSprite *Sprite = &SpriteList->Sprites[s];
free(Sprite->IndexData);
free(Sprite->BGRA32Data);
free(Sprite->ZBuffer);
}
free(SpriteList->Sprites);
}
}
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
unsigned PixelCount = Sprite->Width*Sprite->Height;
unsigned i;
Sprite->BGRA32Data = malloc(PixelCount*4);
if(Sprite->BGRA32Data == NULL) return 0;
for(i=0; i<PixelCount; i++){
uint8_t Index = Sprite->IndexData[2*i + 0];
if(Index >= Palette->ColorCount){
free(Sprite->BGRA32Data);
Sprite->BGRA32Data = NULL;
return 0;
}
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
}
return 1;
}

View file

@ -1,227 +1,227 @@
/*
FileHandler - General-purpose file handling library for Niotso
spr2.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_spr2(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFSpriteList *SpriteList;
bytestream b;
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
unsigned i;
if(ChunkInfo->Size < 12)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
if(ChunkInfo->FormattedData == NULL)
return 0;
SpriteList = ChunkInfo->FormattedData;
SpriteList->Version = read_uint32(&b);
if(SpriteList->Version != 1000 && SpriteList->Version != 1001)
return 0;
if(SpriteList->Version == 1000){
SpriteList->SpriteCount = read_uint32(&b);
SpriteList->PaletteID = read_uint32(&b);
if(SpriteList->SpriteCount > b.Size/4)
return 0;
}else{
SpriteList->PaletteID = read_uint32(&b);
skipbytes(&b, 4);
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
** this is easy with the sprite size field */
for(SpriteList->SpriteCount = 0; b.Size >= 24; SpriteList->SpriteCount++){
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
return 0;
}
NextSpriteOffset = 16;
}
if(SpriteList->SpriteCount == 0)
return 1;
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
if(SpriteList->Sprites == NULL)
return 0;
for(i=0; i<SpriteList->SpriteCount; i++){
IFFSprite * Sprite = &SpriteList->Sprites[i];
unsigned SpriteSize;
unsigned row = 0;
int j;
if(SpriteList->Version != 1001){
/* Jump to the next sprite using the offset table; this is mandatory */
seekto(&b, 12 + 4*i);
if(!seekto(&b, read_uint32(&b)) || b.Size < 16)
return 0;
SpriteSize = b.Size;
}else{
/* Jump to the next sprite using the sprite size field; this is mandatory */
seekto(&b, NextSpriteOffset);
SpriteSize = read_uint32(&b);
NextSpriteOffset += SpriteSize + 8;
}
Sprite->Width = read_uint16(&b);
Sprite->Height = read_uint16(&b);
Sprite->Flags = read_uint32(&b);
Sprite->PaletteID = read_uint16(&b);
Sprite->TransparentColor = read_uint16(&b);
Sprite->YLoc = read_uint16(&b);
Sprite->XLoc = read_uint16(&b);
if((Sprite->Flags != 1 && Sprite->Flags != 3 && Sprite->Flags != 7) || Sprite->TransparentColor >= 256)
return 0;
if(Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
/* This happens in the many chunks in 2personportal.spf */
Sprite->InvalidDimensions = 1;
continue;
}
SpriteSize -= 16;
Sprite->IndexData = malloc(Sprite->Width*Sprite->Height*2);
if(Sprite->IndexData == NULL)
return 0;
for(j=0; j<Sprite->Width*Sprite->Height; j++){
Sprite->IndexData[2*j + 0] = Sprite->TransparentColor;
Sprite->IndexData[2*j + 1] = 0x00;
}
if(Sprite->Flags >= 3){ /* Has the Z-Buffer flag */
Sprite->ZBuffer = malloc(Sprite->Width*Sprite->Height);
if(Sprite->ZBuffer == NULL)
return 0;
memset(Sprite->ZBuffer, 0xFF, Sprite->Width*Sprite->Height);
}
while(1){
/****
** Row command: valid commands are 0, 4, and 5
*/
uint8_t RowCommand; /* 3 bits */
uint16_t RowCount; /* 13 bits */
if(SpriteSize < 2)
return 0;
RowCount = read_uint16le(b.Buffer);
RowCommand = RowCount >> 13;
RowCount &= 0x1FFF;
b.Buffer += 2;
SpriteSize -= 2;
if(RowCommand == 0){
/****
** Pixel command: valid commands are 1, 2, 3, and 6
*/
unsigned pixel = 0;
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
return 0;
SpriteSize -= RowCount;
while(RowCount){
uint8_t PixelCommand; /* 3 bits */
uint16_t PixelCount; /* 13 bits */
uint8_t * IndexData, * ZBuffer;
if(RowCount < 2)
return 0;
PixelCount = read_uint16le(b.Buffer);
PixelCommand = PixelCount >> 13;
PixelCount &= 0x1FFF;
b.Buffer += 2;
RowCount -= 2;
if(PixelCount > Sprite->Width - pixel)
return 0;
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
ZBuffer = Sprite->ZBuffer + (Sprite->Width*row + pixel)*1;
pixel += PixelCount;
if(PixelCommand == 1){
/* color+z-buffer: Set next n pixels to n palette indices */
if(Sprite->Flags < 3 || PixelCount*2 > RowCount)
return 0;
RowCount -= PixelCount*2;
while(PixelCount--){
*ZBuffer++ = *(b.Buffer++);
IndexData[0] = *(b.Buffer++);
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
IndexData += 2;
}
}else if(PixelCommand == 2){
/* color+z-buffer+alpha: Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(Sprite->Flags < 7 || PixelCount*3 + padding > RowCount)
return 0;
RowCount -= PixelCount*3 + padding;
while(PixelCount--){
*ZBuffer++ = *(b.Buffer++);
*IndexData++ = *(b.Buffer++);
*IndexData++ = *(b.Buffer++);
}
if(padding) b.Buffer++; /* Padding byte */
}else if(PixelCommand == 3){
/* Leave next n pixels as transparent */
}else if(PixelCommand == 6){
/* color: Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(PixelCount + padding > RowCount)
return 0;
RowCount -= PixelCount + padding;
while(PixelCount--){
IndexData[0] = *(b.Buffer++);
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
if(Sprite->Flags >= 3)
*ZBuffer++ = (IndexData[0] != Sprite->TransparentColor) ? 0x00 : 0xFF;
IndexData += 2;
}
if(padding) b.Buffer++; /* Padding byte */
} else return 0;
}
row++;
}else if(RowCommand == 4){
/* Leave rows as transparent */
if(RowCount > Sprite->Height - row)
return 0;
row += RowCount;
}else if(RowCommand == 5){
/* End marker */
break;
}else return 0;
}
}
return 1;
/*
FileHandler - General-purpose file handling library for Niotso
spr2.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
Author(s): 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 "iffparser.h"
int iff_parse_spr2(IFFChunk * ChunkInfo, const uint8_t * Buffer){
IFFSpriteList *SpriteList;
bytestream b;
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
unsigned i;
if(ChunkInfo->Size < 12)
return 0;
set_bytestream(&b, Buffer, ChunkInfo->Size);
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
if(ChunkInfo->FormattedData == NULL)
return 0;
SpriteList = ChunkInfo->FormattedData;
SpriteList->Version = read_uint32(&b);
if(SpriteList->Version != 1000 && SpriteList->Version != 1001)
return 0;
if(SpriteList->Version == 1000){
SpriteList->SpriteCount = read_uint32(&b);
SpriteList->PaletteID = read_uint32(&b);
if(SpriteList->SpriteCount > b.Size/4)
return 0;
}else{
SpriteList->PaletteID = read_uint32(&b);
skipbytes(&b, 4);
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
** this is easy with the sprite size field */
for(SpriteList->SpriteCount = 0; b.Size >= 24; SpriteList->SpriteCount++){
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
return 0;
}
NextSpriteOffset = 16;
}
if(SpriteList->SpriteCount == 0)
return 1;
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
if(SpriteList->Sprites == NULL)
return 0;
for(i=0; i<SpriteList->SpriteCount; i++){
IFFSprite * Sprite = &SpriteList->Sprites[i];
unsigned SpriteSize;
unsigned row = 0;
int j;
if(SpriteList->Version != 1001){
/* Jump to the next sprite using the offset table; this is mandatory */
seekto(&b, 12 + 4*i);
if(!seekto(&b, read_uint32(&b)) || b.Size < 16)
return 0;
SpriteSize = b.Size;
}else{
/* Jump to the next sprite using the sprite size field; this is mandatory */
seekto(&b, NextSpriteOffset);
SpriteSize = read_uint32(&b);
NextSpriteOffset += SpriteSize + 8;
}
Sprite->Width = read_uint16(&b);
Sprite->Height = read_uint16(&b);
Sprite->Flags = read_uint32(&b);
Sprite->PaletteID = read_uint16(&b);
Sprite->TransparentColor = read_uint16(&b);
Sprite->YLoc = read_uint16(&b);
Sprite->XLoc = read_uint16(&b);
if((Sprite->Flags != 1 && Sprite->Flags != 3 && Sprite->Flags != 7) || Sprite->TransparentColor >= 256)
return 0;
if(Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
/* This happens in the many chunks in 2personportal.spf */
Sprite->InvalidDimensions = 1;
continue;
}
SpriteSize -= 16;
Sprite->IndexData = malloc(Sprite->Width*Sprite->Height*2);
if(Sprite->IndexData == NULL)
return 0;
for(j=0; j<Sprite->Width*Sprite->Height; j++){
Sprite->IndexData[2*j + 0] = Sprite->TransparentColor;
Sprite->IndexData[2*j + 1] = 0x00;
}
if(Sprite->Flags >= 3){ /* Has the Z-Buffer flag */
Sprite->ZBuffer = malloc(Sprite->Width*Sprite->Height);
if(Sprite->ZBuffer == NULL)
return 0;
memset(Sprite->ZBuffer, 0xFF, Sprite->Width*Sprite->Height);
}
while(1){
/****
** Row command: valid commands are 0, 4, and 5
*/
uint8_t RowCommand; /* 3 bits */
uint16_t RowCount; /* 13 bits */
if(SpriteSize < 2)
return 0;
RowCount = read_uint16le(b.Buffer);
RowCommand = RowCount >> 13;
RowCount &= 0x1FFF;
b.Buffer += 2;
SpriteSize -= 2;
if(RowCommand == 0){
/****
** Pixel command: valid commands are 1, 2, 3, and 6
*/
unsigned pixel = 0;
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
return 0;
SpriteSize -= RowCount;
while(RowCount){
uint8_t PixelCommand; /* 3 bits */
uint16_t PixelCount; /* 13 bits */
uint8_t * IndexData, * ZBuffer;
if(RowCount < 2)
return 0;
PixelCount = read_uint16le(b.Buffer);
PixelCommand = PixelCount >> 13;
PixelCount &= 0x1FFF;
b.Buffer += 2;
RowCount -= 2;
if(PixelCount > Sprite->Width - pixel)
return 0;
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
ZBuffer = Sprite->ZBuffer + (Sprite->Width*row + pixel)*1;
pixel += PixelCount;
if(PixelCommand == 1){
/* color+z-buffer: Set next n pixels to n palette indices */
if(Sprite->Flags < 3 || PixelCount*2 > RowCount)
return 0;
RowCount -= PixelCount*2;
while(PixelCount--){
*ZBuffer++ = *(b.Buffer++);
IndexData[0] = *(b.Buffer++);
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
IndexData += 2;
}
}else if(PixelCommand == 2){
/* color+z-buffer+alpha: Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(Sprite->Flags < 7 || PixelCount*3 + padding > RowCount)
return 0;
RowCount -= PixelCount*3 + padding;
while(PixelCount--){
*ZBuffer++ = *(b.Buffer++);
*IndexData++ = *(b.Buffer++);
*IndexData++ = *(b.Buffer++);
}
if(padding) b.Buffer++; /* Padding byte */
}else if(PixelCommand == 3){
/* Leave next n pixels as transparent */
}else if(PixelCommand == 6){
/* color: Set next n pixels to n palette indices */
int padding = PixelCount%2;
if(PixelCount + padding > RowCount)
return 0;
RowCount -= PixelCount + padding;
while(PixelCount--){
IndexData[0] = *(b.Buffer++);
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
if(Sprite->Flags >= 3)
*ZBuffer++ = (IndexData[0] != Sprite->TransparentColor) ? 0x00 : 0xFF;
IndexData += 2;
}
if(padding) b.Buffer++; /* Padding byte */
} else return 0;
}
row++;
}else if(RowCommand == 4){
/* Leave rows as transparent */
if(RowCount > Sprite->Height - row)
return 0;
row += RowCount;
}else if(RowCommand == 5){
/* End marker */
break;
}else return 0;
}
}
return 1;
}

View file

@ -38,13 +38,6 @@
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef __inline
#define __inline
#endif
#ifndef __restrict
#define __restrict
#endif
static uint8_t ReadBits(utkparams_t *p, uint8_t bits);
static void SetUTKParameters(utkparams_t *p);
static void DecompressBlock(utkparams_t *p);

View file

@ -27,10 +27,6 @@
#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);

View file

@ -29,13 +29,6 @@
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
#endif
#ifndef __inline
#define __inline
#endif
#ifndef __restrict
#define __restrict
#endif
unsigned xa_compressed_size(unsigned Frames, unsigned Channels)
{
/* This function calculates the size of compressed XA data with known frames and channels, as such:

View file

@ -58,7 +58,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int){
2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107,
2108, 2109, 2200, 2201, 2202, 2203, 2204, 2205,
2206, 2207, 2208, 2209, 2210, 2300, 2301, 2302,
2303, 2400
2303, 2400, 2401
};
for(unsigned i=0; i<MENUICONS; i++){

View file

@ -36,7 +36,7 @@
#define ID_HELP_WEBSITE 1400
#define ID_HELP_ABOUT 1401
#define MENUICONS 26
#define MENUICONS 27
#define IDI_FILE_NEW 2100
#define IDI_FILE_OPEN 2101
#define IDI_FILE_SAVE 2102
@ -63,6 +63,7 @@
#define IDI_TOOLS_REMOVEHOLES 2302
#define IDI_TOOLS_BATCH 2303
#define IDI_HELP_WEBSITE 2400
#define IDI_HELP_ABOUT 2401
//Right-click menu items
#define ID_LISTMENU_ADD 3100

View file

@ -108,6 +108,7 @@ IDI_TOOLS_RESORT RCDATA "../resources/icons/mail-send-receive.png"
IDI_TOOLS_REMOVEHOLES RCDATA "../resources/icons/edit-clear.png"
IDI_TOOLS_BATCH RCDATA "../resources/icons/utilities-terminal.png"
IDI_HELP_WEBSITE RCDATA "../resources/icons/internet-web-browser.png"
IDI_HELP_ABOUT RCDATA "../resources/icons/help-about.png"
IDB_INFO BITMAP "../resources/icons/info.bmp"