Initial mng support
This commit is contained in:
parent
b7b2fbac5b
commit
a5aaed0da2
5 changed files with 350 additions and 9 deletions
src
|
@ -299,6 +299,7 @@ typedef struct _title_screen_ {
|
|||
char* File;
|
||||
char* Music;
|
||||
int Timeout;
|
||||
int Iterations;
|
||||
TitleScreenLabel** Labels;
|
||||
} TitleScreen;
|
||||
|
||||
|
|
|
@ -60,6 +60,25 @@ typedef struct _graphic_ {
|
|||
#endif
|
||||
} Graphic;
|
||||
|
||||
#ifdef USE_MNG
|
||||
#ifdef USE_WIN32
|
||||
#define MNG_USE_DLL
|
||||
#else
|
||||
#define MNG_USE_SO
|
||||
#endif
|
||||
#include <libmng.h>
|
||||
#undef LOCAL
|
||||
typedef struct _mng_ {
|
||||
char* Name;
|
||||
FILE* FD;
|
||||
mng_handle Handle;
|
||||
SDL_Surface* Surface;
|
||||
unsigned char* Buffer;
|
||||
unsigned long Ticks;
|
||||
int Iteration;
|
||||
} Mng;
|
||||
#endif
|
||||
|
||||
typedef struct _unit_colors_ {
|
||||
SDL_Color Colors[4];
|
||||
} UnitColors;
|
||||
|
@ -207,6 +226,15 @@ extern void ResizeGraphic(Graphic* g, int w, int h);
|
|||
/// Load graphic from PNG file
|
||||
extern Graphic* LoadGraphicPNG(const char* name);
|
||||
|
||||
#ifdef USE_MNG
|
||||
/// Load a MNG file
|
||||
extern Mng* LoadMNG(const char* name);
|
||||
/// Display a MNG file
|
||||
extern void DisplayMNG(Mng* mng, int x, int y);
|
||||
/// Free a MNG file
|
||||
extern void FreeMNG(Mng* mng);
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
/// Make an OpenGL texture
|
||||
extern void MakeTexture(Graphic* graphic, int width, int height);
|
||||
|
|
|
@ -494,7 +494,6 @@ static void ShowTitleScreens(void)
|
|||
int x;
|
||||
int y;
|
||||
|
||||
|
||||
if (!TitleScreens) {
|
||||
return;
|
||||
}
|
||||
|
@ -512,6 +511,9 @@ static void ShowTitleScreens(void)
|
|||
for (i = 0; TitleScreens[i]; ++i) {
|
||||
WaitNoEvent = 1;
|
||||
timeout = TitleScreens[i]->Timeout * CYCLES_PER_SECOND;
|
||||
if (!timeout) {
|
||||
timeout = -1;
|
||||
}
|
||||
|
||||
if (TitleScreens[i]->Music) {
|
||||
if (!strcmp(TitleScreens[i]->Music, "none") ||
|
||||
|
@ -523,12 +525,34 @@ static void ShowTitleScreens(void)
|
|||
PlayMovieZoomScreen | PlayMovieKeepAspect)) {
|
||||
TitleScreenLabel** labels;
|
||||
Graphic* g;
|
||||
#ifdef USE_MNG
|
||||
Mng* mng;
|
||||
|
||||
mng = LoadMNG(TitleScreens[i]->File);
|
||||
g = NULL;
|
||||
if (!mng) {
|
||||
#endif
|
||||
g = LoadGraphic(TitleScreens[i]->File);
|
||||
ResizeGraphic(g, VideoWidth, VideoHeight);
|
||||
#ifdef USE_MNG
|
||||
}
|
||||
#endif
|
||||
|
||||
g = LoadGraphic(TitleScreens[i]->File);
|
||||
ResizeGraphic(g, VideoWidth, VideoHeight);
|
||||
while (timeout-- && WaitNoEvent) {
|
||||
VideoDrawSubClip(g, 0, 0, g->Width, g->Height,
|
||||
(VideoWidth - g->Width) / 2, (VideoHeight - g->Height) / 2);
|
||||
#ifdef USE_MNG
|
||||
if (mng) {
|
||||
DisplayMNG(mng, (VideoWidth - mng->Surface->w) / 2,
|
||||
(VideoHeight - mng->Surface->h) / 2);
|
||||
if (mng->Iteration == TitleScreens[i]->Iterations) {
|
||||
WaitNoEvent = 0;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
VideoDrawSubClip(g, 0, 0, g->Width, g->Height,
|
||||
(VideoWidth - g->Width) / 2, (VideoHeight - g->Height) / 2);
|
||||
#ifdef USE_MNG
|
||||
}
|
||||
#endif
|
||||
labels = TitleScreens[i]->Labels;
|
||||
if (labels && labels[0] && IsFontLoaded(labels[0]->Font)) {
|
||||
for (j = 0; labels[j]; ++j) {
|
||||
|
@ -540,17 +564,22 @@ static void ShowTitleScreens(void)
|
|||
VideoDrawText(x, y, labels[j]->Font, labels[j]->Text);
|
||||
}
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
RealizeVideoMemory();
|
||||
WaitEventsOneFrame(&callbacks);
|
||||
}
|
||||
VideoFree(g);
|
||||
#ifdef USE_MNG
|
||||
if (mng) {
|
||||
FreeMNG(mng);
|
||||
}
|
||||
#endif
|
||||
VideoSafeFree(g);
|
||||
}
|
||||
|
||||
VideoClearScreen();
|
||||
Invalidate();
|
||||
RealizeVideoMemory();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -625,7 +654,6 @@ void MenuLoop(char* filename, WorldMap* map)
|
|||
//
|
||||
VideoClearScreen();
|
||||
Invalidate();
|
||||
RealizeVideoMemory();
|
||||
|
||||
//
|
||||
// Network part 1 (port set-up)
|
||||
|
|
|
@ -284,6 +284,7 @@ static int CclSetTitleScreens(lua_State* l)
|
|||
LuaError(l, "incorrect argument");
|
||||
}
|
||||
TitleScreens[j] = calloc(1, sizeof(**TitleScreens));
|
||||
TitleScreens[j]->Iterations = 1;
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, j + 1)) {
|
||||
value = LuaToString(l, -2);
|
||||
|
@ -293,6 +294,8 @@ static int CclSetTitleScreens(lua_State* l)
|
|||
TitleScreens[j]->Music = strdup(LuaToString(l, -1));
|
||||
} else if (!strcmp(value, "Timeout")) {
|
||||
TitleScreens[j]->Timeout = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(value, "Iterations")) {
|
||||
TitleScreens[j]->Iterations = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(value, "Labels")) {
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument");
|
||||
|
|
281
src/video/mng.cpp
Executable file
281
src/video/mng.cpp
Executable file
|
@ -0,0 +1,281 @@
|
|||
// _________ __ __
|
||||
// / _____// |_____________ _/ |______ ____ __ __ ______
|
||||
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
||||
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
||||
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
||||
// \/ \/ \//_____/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// Stratagus - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name mng.c - The mng graphic file loader. */
|
||||
//
|
||||
// (c) Copyright 2004 by Jimmy Salmon
|
||||
//
|
||||
// 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; only version 2 of the License.
|
||||
//
|
||||
// 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, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
#ifdef USE_MNG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "video.h"
|
||||
#include "iolib.h"
|
||||
#include "iocompat.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
static mng_ptr MNG_DECL my_alloc(mng_size_t len)
|
||||
{
|
||||
return calloc(1, len);
|
||||
}
|
||||
|
||||
static void MNG_DECL my_free(mng_ptr ptr, mng_size_t len)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_openstream(mng_handle handle)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
mng->FD = fopen(mng->Name, "rb");
|
||||
if (!mng->FD) {
|
||||
return MNG_FALSE;
|
||||
}
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_closestream(mng_handle handle)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
if (mng->FD) {
|
||||
fclose(mng->FD);
|
||||
}
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_readdata(mng_handle handle, mng_ptr buf, mng_uint32 buflen,
|
||||
mng_uint32p read)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
*read = fread(buf, 1, buflen, mng->FD);
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_processheader(mng_handle handle, mng_uint32 width,
|
||||
mng_uint32 height)
|
||||
{
|
||||
Uint32 Rmask;
|
||||
Uint32 Gmask;
|
||||
Uint32 Bmask;
|
||||
mng_imgtype type;
|
||||
Mng* mng;
|
||||
|
||||
type = mng_get_sigtype(handle);
|
||||
if (type != mng_it_mng) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
mng->Buffer = calloc(width * height * 3, 1);
|
||||
|
||||
// Allocate the SDL surface to hold the image
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
Rmask = 0x000000FF;
|
||||
Gmask = 0x0000FF00;
|
||||
Bmask = 0x00FF0000;
|
||||
#else
|
||||
Rmask = 0xFF000000 >> 8;
|
||||
Gmask = 0x00FF0000 >> 8;
|
||||
Bmask = 0x0000FF00 >> 8;
|
||||
#endif
|
||||
|
||||
mng->Surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
|
||||
8 * 3, Rmask, Gmask, Bmask, 0);
|
||||
if (mng->Surface == NULL) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_ptr MNG_DECL my_getcanvasline(mng_handle handle, mng_uint32 linenr)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
return mng->Buffer + linenr * mng->Surface->w * 3;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_refresh(mng_handle handle, mng_uint32 x, mng_uint32 y,
|
||||
mng_uint32 width, mng_uint32 height)
|
||||
{
|
||||
Mng* mng;
|
||||
int i;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
SDL_LockSurface(mng->Surface);
|
||||
for (i = 0; i < mng->Surface->h; ++i) {
|
||||
memcpy((char*)mng->Surface->pixels + i * mng->Surface->pitch,
|
||||
mng->Buffer + i * mng->Surface->w * 3, mng->Surface->w * 3);
|
||||
}
|
||||
SDL_UnlockSurface(mng->Surface);
|
||||
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_uint32 MNG_DECL my_gettickcount(mng_handle handle)
|
||||
{
|
||||
return GetTicks();
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_settimer(mng_handle handle, mng_uint32 msecs)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
mng->Ticks = GetTicks() + msecs;
|
||||
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_processmend(mng_handle handle, mng_uint32 iterationsdone,
|
||||
mng_uint32 iterationsleft)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
mng->Iteration = iterationsdone;
|
||||
|
||||
return MNG_TRUE;
|
||||
}
|
||||
|
||||
static mng_bool MNG_DECL my_errorproc(mng_handle handle, mng_int32 errorcode,
|
||||
mng_int8 severity, mng_chunkid chunkname, mng_uint32 chunkseq,
|
||||
mng_int32 extra1, mng_int32 extra2, mng_pchar errortext)
|
||||
{
|
||||
Mng* mng;
|
||||
|
||||
mng = (Mng*)mng_get_userdata(handle);
|
||||
mng->Iteration = 0x7fffffff;
|
||||
if (errortext) {
|
||||
DebugPrint("MNG error: %s\n" _C_ errortext);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Display a MNG
|
||||
**
|
||||
** @param mng Mng file to display
|
||||
*/
|
||||
void DisplayMNG(Mng* mng, int x, int y)
|
||||
{
|
||||
#ifndef USE_OPENGL
|
||||
SDL_Rect rect;
|
||||
|
||||
if (mng->Ticks <= GetTicks()) {
|
||||
mng_display_resume(mng->Handle);
|
||||
}
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.w = mng->Surface->w;
|
||||
rect.h = mng->Surface->h;
|
||||
SDL_BlitSurface(mng->Surface, NULL, TheScreen, &rect);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
** Load a MNG
|
||||
**
|
||||
** @param name Name of the MNG file
|
||||
*/
|
||||
Mng* LoadMNG(const char* name)
|
||||
{
|
||||
Mng* mng;
|
||||
mng_retcode myretcode;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
LibraryFileName(name, buf);
|
||||
|
||||
mng = calloc(1, sizeof(Mng));
|
||||
mng->Name = strdup(buf);
|
||||
mng->Handle = mng_initialize(mng, my_alloc, my_free, MNG_NULL);
|
||||
if (mng->Handle == MNG_NULL) {
|
||||
// process error
|
||||
mng = mng;
|
||||
}
|
||||
mng_setcb_openstream(mng->Handle, my_openstream);
|
||||
mng_setcb_closestream(mng->Handle, my_closestream);
|
||||
mng_setcb_readdata(mng->Handle, my_readdata);
|
||||
mng_setcb_processheader(mng->Handle, my_processheader);
|
||||
mng_setcb_processmend(mng->Handle, my_processmend);
|
||||
mng_setcb_getcanvasline(mng->Handle, my_getcanvasline);
|
||||
mng_setcb_refresh(mng->Handle, my_refresh);
|
||||
mng_setcb_gettickcount(mng->Handle, my_gettickcount);
|
||||
mng_setcb_settimer(mng->Handle, my_settimer);
|
||||
mng_setcb_errorproc(mng->Handle, my_errorproc);
|
||||
|
||||
mng_read(mng->Handle);
|
||||
if (mng->Surface && mng->Iteration != 0x7fffffff) {
|
||||
myretcode = mng_display(mng->Handle);
|
||||
}
|
||||
|
||||
if (!mng->Surface || mng->Iteration == 0x7fffffff) {
|
||||
mng_cleanup(&mng->Handle);
|
||||
free(mng->Buffer);
|
||||
free(mng);
|
||||
return NULL;
|
||||
}
|
||||
return mng;
|
||||
}
|
||||
|
||||
/**
|
||||
** Free a MNG
|
||||
**
|
||||
** @param mng Mng file to free
|
||||
*/
|
||||
void FreeMNG(Mng* mng)
|
||||
{
|
||||
mng_cleanup(&mng->Handle);
|
||||
SDL_FreeSurface(mng->Surface);
|
||||
free(mng->Buffer);
|
||||
free(mng->Name);
|
||||
free(mng);
|
||||
}
|
||||
|
||||
#endif // USE_MNG
|
||||
|
||||
//@}
|
Loading…
Add table
Reference in a new issue