mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
Cleanup MVE library
Remove old implementation, cleanup unused code.
This commit is contained in:
parent
def4737f53
commit
4f0e0f87a5
@ -1,5 +0,0 @@
|
||||
set(HEADERS)
|
||||
set(CPPS
|
||||
acmlib.cpp)
|
||||
|
||||
add_library(acmlib STATIC ${HEADERS} ${CPPS})
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 "Adecode.h"
|
||||
#include "mem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
AudioDecoder *Create_AudioDecoder(ReadFunction *reader, void *data, unsigned *pChannels, unsigned *pSampleRate,
|
||||
int32_t *pSampleCount) {
|
||||
return (AudioDecoder *)mem_malloc(sizeof(AudioDecoder));
|
||||
}
|
||||
|
||||
// Read from audio decoder at most the specified qty of bytes
|
||||
// (each sample takes two bytes).
|
||||
// Returns zero when the end of file is reached.
|
||||
unsigned __cdecl AudioDecoder_Read(AudioDecoder *ad, void *buf, unsigned qty) { return 0; }
|
||||
|
||||
// Close audio decoder
|
||||
void __cdecl AudioDecoder_Close(AudioDecoder *ad) {
|
||||
if (ad)
|
||||
mem_free(ad);
|
||||
}
|
||||
|
||||
// Optional interface for supplying your own malloc and free functions
|
||||
// Default is to use standard malloc and free.
|
||||
|
||||
void __cdecl AudioDecoder_MallocFree(ad_malloc *fn_malloc, ad_free *fn_free) {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
349
lib/mvelibw.h
349
lib/mvelibw.h
@ -1,349 +0,0 @@
|
||||
#if 0
|
||||
/*
|
||||
** mvelibw.h
|
||||
**
|
||||
** Interplay Movie File (MVE) Player
|
||||
** Library Definitions (32-Bit Win95 Version)
|
||||
** Written by Paul Allen Edelstein, Interplay Productions.
|
||||
**
|
||||
** (c) 1997 Interplay Productions. All Rights Reserved.
|
||||
** This file is confidential and consists of proprietary information
|
||||
** of Interplay Productions. This file and associated libraries
|
||||
** may not, in whole or in part, be disclosed to third parties,
|
||||
** incorporated into any software product which is not being created
|
||||
** for Interplay Productions, copied or duplicated in any form,
|
||||
** without the prior written permission of Interplay Productions.
|
||||
** Further, you may not reverse engineer, decompile or otherwise
|
||||
** attempt to derive source code of this material.
|
||||
*/
|
||||
|
||||
#ifndef _MVELIB_H_INCLUDED
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include "ddraw.h"
|
||||
#include "dsound.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Call this function to provide hooks into your memory management.
|
||||
*/
|
||||
typedef void *(__cdecl mve_cb_alloc)(unsigned size);
|
||||
typedef void (__cdecl mve_cb_free)(void *p);
|
||||
void __cdecl MVE_memCallbacks(mve_cb_alloc *fn_alloc,
|
||||
mve_cb_free *fn_free);
|
||||
|
||||
/* This function remains from the DOS version of mvelib.
|
||||
** It allows you to provide a preallocated buffer for file I/O,
|
||||
** but under Windows there's no real point to doing this.
|
||||
*/
|
||||
void __cdecl MVE_memIO(void *p, unsigned size);
|
||||
|
||||
/* Call this function to provide hook into your file io.
|
||||
*/
|
||||
typedef unsigned __cdecl mve_cb_read(int handle, void *buf, unsigned count);
|
||||
void __cdecl MVE_ioCallbacks(mve_cb_read *fn_read);
|
||||
|
||||
/* Call this function to provide hook into your digital sound driver.
|
||||
** Call with NULL if no sound support is available (default).
|
||||
*/
|
||||
void __cdecl MVE_sndInit(LPDIRECTSOUND lpDS);
|
||||
|
||||
/* Volume controls.
|
||||
** These functions are equivalent to the IDirectSoundBuffer
|
||||
** SetVolume and SetPan functions. They take effect immediately
|
||||
** and do NOT reset when a new movie starts.
|
||||
** Volume ranges from 0 (0 db, no volume change) to -10,000 (-100db, essentially silent).
|
||||
** Pan ranges from -10,000 (left full volume, right -100db), thru 0 (both full),
|
||||
** thru 10,000 (left -100db, right full volume).
|
||||
** The default value for volume and pan is zero.
|
||||
*/
|
||||
void __cdecl MVE_dsbSetVolume(int32_t lVolume);
|
||||
void __cdecl MVE_dsbSetPan(int32_t lPan);
|
||||
|
||||
|
||||
/* Only call this function to configure software to work with a Super VGA
|
||||
** mode if you do not have VESA support.
|
||||
**
|
||||
** Restrictions/Assumptions:
|
||||
** 64K >= WinSize >= WinGran
|
||||
** WinSize % WinGran == 0
|
||||
** WinGran of 64K is represented by 0
|
||||
** SetBank is address of function with following protocol:
|
||||
** bh: 0=Set window, 1=Get Window
|
||||
** bl: Window number (0 or 1)
|
||||
** dx: Window position in video memory in units of WinGran.
|
||||
** on return, registers AX and DX are destroyed.
|
||||
**
|
||||
** Hicolor is 0 for 8-bit color, 1 for 15-bit rgb color, 2
|
||||
** for byte swapped 15-bit rgb color.
|
||||
*/
|
||||
|
||||
/* Note: 16-bit WriteWinSeg replaced with 32-bit WriteWinPtr */
|
||||
|
||||
/* The functionality of the following function is reduced in the Windows
|
||||
** version of the player. Call it as follows:
|
||||
** MVE_sfSVGA(w,h,w,0,NULL,0,0,NULL,hicolor)
|
||||
** where w and h are the width and height of your window,
|
||||
** and hicolor is a boolean which indicates if the screen
|
||||
** is operating in hi color, rather than 8-bit paletted color.
|
||||
** Under windows, the information provided by this function
|
||||
** is just used for window centering and for determining
|
||||
** how and when to do palette callbacks.
|
||||
*/
|
||||
void __cdecl
|
||||
MVE_sfSVGA(unsigned w, unsigned h, unsigned LineWidth,
|
||||
unsigned WriteWin, uint8_t *WriteWinPtr,
|
||||
uint32_t WinSize, unsigned WinGran,
|
||||
void *SetBank, unsigned hicolor);
|
||||
|
||||
/* This function alters the display from 640x480 or 640x400 to 640x350 resolution.
|
||||
*/
|
||||
void __cdecl
|
||||
MVE_ForceVres350(void);
|
||||
|
||||
/* This function alters the display from 640x480/400/350 to
|
||||
** 640x240/200/175.
|
||||
*/
|
||||
void __cdecl
|
||||
MVE_ForceVresHalf(void);
|
||||
|
||||
/* **NOTE** There still need to be calls to restore original screen resolution
|
||||
** after using MVE_ForceVres350() or MVE_ForceVresHalf()!
|
||||
*/
|
||||
|
||||
/* Only call this function to either
|
||||
** 1. Replace method of copying frame to screen (perhaps for a nonstandard
|
||||
** screen format).
|
||||
** 2. Wrap your own code around the transfer of frame to screen
|
||||
** or modify which portions of the screen are updated.
|
||||
** This function replaces calls to the default MVE_ShowFrame function
|
||||
** with calls to your function, which can itself call MVE_ShowFrame.
|
||||
*/
|
||||
typedef void __cdecl mve_cb_ShowFrame
|
||||
(LPDIRECTDRAWSURFACE buf, unsigned bufw, unsigned bufh,
|
||||
unsigned sx, unsigned sy, unsigned w, unsigned h,
|
||||
unsigned dstx, unsigned dsty, unsigned hicolor);
|
||||
void __cdecl MVE_sfCallbacks(mve_cb_ShowFrame *fn_ShowFrame);
|
||||
|
||||
typedef void __cdecl mve_cb_SetPalette
|
||||
(uint8_t *p, unsigned start, unsigned count);
|
||||
void __cdecl
|
||||
MVE_palCallbacks(mve_cb_SetPalette *fn_SetPalette);
|
||||
|
||||
void __cdecl
|
||||
MVE_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
|
||||
/* Configure the software for a graphics mode, optionally setting the
|
||||
** display to that mode (see the MVE_GFX_xxx constants defined below).
|
||||
*/
|
||||
unsigned __cdecl MVE_gfxMode(int16_t mode);
|
||||
|
||||
/* Reset the screen to text mode (usually done before exiting a program).
|
||||
*/
|
||||
void __cdecl MVE_gfxReset(void);
|
||||
|
||||
/* Set line for split screen graphics */
|
||||
/* {Use vbe_SetDisplayStart(x,y) to set vid buf for upper screen} */
|
||||
void __cdecl MVE_gfxSetSplit(unsigned line);
|
||||
|
||||
/* Setup double buffering */
|
||||
void __cdecl MVE_gfxSetDoubleBuffer(unsigned y1, unsigned y2, unsigned vis);
|
||||
|
||||
/* Get double buffering state */
|
||||
void __cdecl MVE_gfxGetDoubleBuffer(unsigned *vis_y, unsigned *hid_y);
|
||||
|
||||
/* Enable double buffering for auto screen modes */
|
||||
void __cdecl MVE_sfAutoDoubleBuffer(unsigned on);
|
||||
|
||||
/* Wait for video retrace off (0) or on (1) */
|
||||
void __cdecl MVE_gfxWaitRetrace(unsigned state);
|
||||
|
||||
/* Establish link to DirectDraw
|
||||
*/
|
||||
void __cdecl MVE_rmDirectDraw(LPDIRECTDRAW lpDD);
|
||||
|
||||
/* Establish primary to DirectDraw Surface
|
||||
** This is only necessary for playing back hi-color movies.
|
||||
** Its establishes the rgb format for decompression.
|
||||
*/
|
||||
void __cdecl MVE_rmPrimarySurface(LPDIRECTDRAWSURFACE lpDD);
|
||||
|
||||
/* Establish callback for user control of movie playback.
|
||||
*/
|
||||
typedef int __cdecl mve_cb_ctl(void);
|
||||
void __cdecl MVE_rmCallbacks(mve_cb_ctl *fn_ctl);
|
||||
|
||||
/* Specify playback fastmode option (default is MVE_RM_NORMAL).
|
||||
*/
|
||||
#define MVE_RM_NORMAL 0 /* Normal playback */
|
||||
#define MVE_RM_HALF 1 /* Half height (even lines only) */
|
||||
#define MVE_RM_DITHERED 2 /* Half height (dither between lines) */
|
||||
#define MVE_RM_HALF_2 5 /* Full height, even lines only */
|
||||
#define MVE_RM_DITHERED_2 6 /* Full height, dither, even lines only */
|
||||
|
||||
void __cdecl MVE_rmFastMode(int mode);
|
||||
|
||||
/* Specifying horizontal magnification:
|
||||
** 3: 4/3 horizontal magnification
|
||||
** 4: normal
|
||||
*/
|
||||
void __cdecl MVE_rmHScale(int hscale);
|
||||
|
||||
/* Get frame count and number of dropped frames from last movie played.
|
||||
*/
|
||||
void __cdecl MVE_rmFrameCounts(unsigned *FrameCount, unsigned *FrameDropCount);
|
||||
|
||||
/* Dump timing statistics (if enabled).
|
||||
*/
|
||||
void __cdecl MVE_logDumpStats(void);
|
||||
|
||||
/* Run a compressed movie by reading data starting at the current
|
||||
** position in the file specified by handle hFile.
|
||||
** The movie window is displaced by dx,dy from the upper left hand corner
|
||||
** or is centered if dx,dy is -1,-1.
|
||||
** track specifies which audio track to play (usually 0 for a single
|
||||
** audio track).
|
||||
**
|
||||
** Returns an error/result code.
|
||||
**
|
||||
** Memory may be dynamically allocated while movie runs.
|
||||
*/
|
||||
int __cdecl MVE_RunMovie(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
/* MVE_RunMovieContinue is the same as MVE_RunMovie except that it does not
|
||||
** automatically call MVE_rmEndMovie(). This may improve the smoothness
|
||||
** of immediately playing another movie afterwards.
|
||||
*/
|
||||
int __cdecl MVE_RunMovieContinue(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
/*
|
||||
** Alternative to using MVE_RunMovie() and MVE_rmCallbacks().
|
||||
** Call MVE_rmPrepMovie() to prepare movie for playing.
|
||||
** Call MVE_rmStepMovie() to display next frame of movie until nonzero
|
||||
** result is returned (MVE_ERR_EOF for no next frame or some other error).
|
||||
** Call MVE_rmHoldMovie() to hold on current frame (and pause audio).
|
||||
** Call MVE_rmEndMovie() to abort movie.
|
||||
** All functions except MVE_rmEndMovie() return an error code.
|
||||
*/
|
||||
int __cdecl MVE_rmPrepMovie(int hFile, int dx, int dy, unsigned track);
|
||||
int __cdecl MVE_rmStepMovie(void);
|
||||
int __cdecl MVE_rmHoldMovie(void);
|
||||
void __cdecl MVE_rmEndMovie(void);
|
||||
|
||||
/* Frame Reader Streams
|
||||
** This is a special interface to the movie system which
|
||||
** allows a movie file to be opened as a stream from which
|
||||
** its frames may be retrieved. Audio and timing information
|
||||
** are ignored. For 256-color screen applications, palette
|
||||
** information is also typically ignored, and movies with a common
|
||||
** predefined palette are used. However, for hi-color screen
|
||||
** applications, an interface to obtain palette information has
|
||||
** been provided. This system is intended for use by video sprites
|
||||
** played off of the hard drive or out of memory.
|
||||
*/
|
||||
typedef struct _MVE_frstream *MVE_frStream;
|
||||
|
||||
/* MVE_frOpen
|
||||
** Before calling this function, be sure to call MVE_memCallbacks()
|
||||
** and MVE_rmDirectDraw().
|
||||
**
|
||||
** fn_read specifies a file reader similar to the one
|
||||
** used by MVE_ioCallbacks().
|
||||
** handle specifies a file handle for an already opened
|
||||
** movie file. It is used by the file reader and is similar
|
||||
** to hFile argument used by MVE_RunMovie() and MVE_rmPrepMovie().
|
||||
** fr_callback is normally NULL, but can be used to supply
|
||||
** a handler for user data which has been interleaved into
|
||||
** the movie stream.
|
||||
**
|
||||
** If the movie file is invalid or the call otherwise fails,
|
||||
** NULL is returned.
|
||||
*/
|
||||
MVE_frStream __cdecl MVE_frOpen(unsigned (__cdecl *fn_read)(int handle, void *buf,
|
||||
unsigned count),
|
||||
int handle,
|
||||
int (__cdecl *fr_callback)(unsigned op, unsigned subop,
|
||||
void *buf));
|
||||
|
||||
/* MVE_frGet
|
||||
** Returns the next frame from the specified frame reader stream
|
||||
** a nonzero error code {the same codes as returned by MVE_RunMovie()
|
||||
** and MVE_rmStepMovie()}.
|
||||
** If successful, MVE_frGet(frs, &buf, &w, &h) returns a pointer
|
||||
** to a direct draw surface containing the frame in buf,
|
||||
** and its width and height in w and h.
|
||||
*/
|
||||
int __cdecl MVE_frGet(MVE_frStream frs,
|
||||
LPDIRECTDRAWSURFACE *pBuf,
|
||||
unsigned *width, unsigned *height);
|
||||
|
||||
/* MVE_frPal
|
||||
** After each successful call to MVE_frGet(), this call may be used to
|
||||
** obtain corresponding palette information. It returns a pointer to the
|
||||
** entire current palette for the frame, and the subportion of the palette
|
||||
** which has changed this frame is identified by start and count (they will
|
||||
** both be zero on frames for which the palette has not changed).
|
||||
**
|
||||
** Paltbl points to 256*3 bytes of 6-bit r,g,b triples.
|
||||
** Start ranges from 0 to 255. Count from 0 to 256.
|
||||
**
|
||||
** These conventions are similar to those used by the palette callback arguments
|
||||
** with the standard player interface, except that this interface requires
|
||||
** polling each frame instead, and must be passed pointers to the variables where
|
||||
** the values will be returned.
|
||||
**
|
||||
*/
|
||||
void __cdecl MVE_frPal(MVE_frStream frs,
|
||||
uint8_t **pPaltbl, unsigned *pStart, unsigned *pCount);
|
||||
|
||||
/* MVE_frClose
|
||||
** Closes the specified Frame Reader Stream frs.
|
||||
** Frees all storage associated with the stream.
|
||||
** The specified frs must not be used after this call.
|
||||
** Note that the open file handle specified in MVE_frOpen() is
|
||||
** not closed by this call...that is the caller's responsibility.
|
||||
*/
|
||||
void __cdecl MVE_frClose(MVE_frStream frs);
|
||||
|
||||
|
||||
/* Release any memory dynamically allocated by MVE_RunMovie.
|
||||
*/
|
||||
void __cdecl MVE_ReleaseMem(void);
|
||||
|
||||
/* Return string corresponding to MVE_RunMovie result code.
|
||||
*/
|
||||
const char* __cdecl MVE_strerror(int code);
|
||||
|
||||
/* RunMovie callback control code and result codes.
|
||||
** Codes > 1 are user defined.
|
||||
*/
|
||||
|
||||
#define MVE_CTL_HOLD -1 /* Returned by rmCtl() to hold current frame */
|
||||
#define MVE_CTL_EXIT 1 /* Returned by rmCtl() to end movie */
|
||||
|
||||
#define MVE_ERR_EOF -1 /* Returned by StepMovie() for end of movie */
|
||||
#define MVE_ERR_IO -2 /* File I/O error or unable to alloc memory. */
|
||||
#define MVE_ERR_SYNC -3 /* Timer error. */
|
||||
#define MVE_ERR_SND -4 /* Unable to allocate memory for sound */
|
||||
#define MVE_ERR_NF -5 /* Unable to allocate memory for video */
|
||||
#define MVE_ERR_GFX_FIT -6 /* Screen size too small for movie */
|
||||
#define MVE_ERR_GFX_FAIL -7 /* Failed to set desired graphics mode */
|
||||
#define MVE_ERR_BADFMT -8 /* Not a MVE file or unacceptable version */
|
||||
#define MVE_ERR_GFX_CLR -9 /* Incorrect screen color mode */
|
||||
#define MVE_ERR_PREP -10 /* StepMovie() without PrepMovie() */
|
||||
#define MVE_ERR_DD -11 /* Unable to initialize DirectDraw */
|
||||
#define MVE_ERR_LOST -12 /* Direct Draw Surface Lost */
|
||||
|
||||
#define MVE_ERR_LAST -12
|
||||
|
||||
#define _MVELIB_H_INCLUDED
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include "../libmve/mvelibl.h"
|
||||
#endif
|
Binary file not shown.
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MVE_SYSTEM_INTERFACES_H__
|
||||
#define MVE_SYSTEM_INTERFACES_H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Max&Min values for settings
|
||||
#define LNXSND_VOLUME_MAX 0
|
||||
#define LNXSND_VOLUME_MIN (-10000)
|
||||
#define LNXSND_PAN_LEFT (-10000)
|
||||
#define LNXSND_PAN_RIGHT 10000
|
||||
|
||||
// Status/Buffer flags
|
||||
#define LNXSND_PLAYING 0x0001
|
||||
#define LNXSND_LOOPING 0x0002
|
||||
|
||||
// Buffer lock flags
|
||||
#define LNXSND_LOCK_FROMWRITECURSOR 0x0001
|
||||
#define LNXSND_LOCK_ENTIREBUFFER 0x0002
|
||||
|
||||
// Capability flags
|
||||
#define LNXSND_CAPS_PRIMARYBUFFER 0x0001
|
||||
#define LNXSND_CAPS_CTRLVOLUME 0x0080
|
||||
#define LNXSND_CAPS_CTRLPAN 0x0040
|
||||
#define LNXSND_CAPS_CTRLFREQUENCY 0x0020
|
||||
#define LNXSND_CAPS_CTRLDEFAULT 0x00E0
|
||||
#define LNXSND_CAPS_LOCSOFTWARE 0x0008
|
||||
#define LNXSND_CAPS_LOCHARDWARE 0x0004
|
||||
|
||||
struct SoundWAVEFormatEx {
|
||||
uint16_t wFormatTag;
|
||||
uint16_t nChannels;
|
||||
uint32_t nSamplesPerSec;
|
||||
uint32_t nAvgBytesPerSec;
|
||||
uint16_t nBlockAlign;
|
||||
uint16_t wBitsPerSample;
|
||||
uint16_t cbSize;
|
||||
};
|
||||
#define SOUND_WAVE_FORMAT_PCM 0x01
|
||||
|
||||
struct SysSoundCaps {
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwBufferBytes;
|
||||
};
|
||||
|
||||
class SysSoundBufferDesc {
|
||||
public:
|
||||
SoundWAVEFormatEx *lpwfxFormat;
|
||||
uint32_t dwBufferBytes;
|
||||
uint32_t dwFlags;
|
||||
};
|
||||
|
||||
class ISysSoundBuffer {
|
||||
public:
|
||||
////////////////////////////
|
||||
// Release
|
||||
////////////////////////////
|
||||
// Releases the memory associated with a sound buffer. This pointer is
|
||||
// no longer valid after return.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// 0 : Ok!
|
||||
virtual int Release() = 0;
|
||||
|
||||
//////////////////////////////
|
||||
// SetVolume
|
||||
//////////////////////////////
|
||||
// Sets the volume of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set volume
|
||||
// -2 : Invalid parameters
|
||||
virtual int SetVolume(int32_t vol) = 0;
|
||||
|
||||
///////////////////////////
|
||||
// SetPan
|
||||
///////////////////////////
|
||||
// Sets the pan of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set pan
|
||||
// -2 : Invalid parameters
|
||||
virtual int SetPan(int32_t pan) = 0;
|
||||
|
||||
/////////////////////////
|
||||
// Stop
|
||||
/////////////////////////
|
||||
// Stops a buffer from playing
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int Stop() = 0;
|
||||
|
||||
/////////////////////////
|
||||
// Play
|
||||
/////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int Play(uint32_t flags) = 0;
|
||||
|
||||
////////////////////////////
|
||||
// GetCaps
|
||||
////////////////////////////
|
||||
// Get the capabilities of a sound buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int GetCaps(SysSoundCaps *caps) = 0;
|
||||
|
||||
//////////////////////////////
|
||||
// GetStatus
|
||||
//////////////////////////////
|
||||
// Returns the status of a buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int GetStatus(uint32_t *status) = 0;
|
||||
|
||||
///////////////////////////////////////
|
||||
// GetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Returns the current play and write positions of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int GetCurrentPosition(uint32_t *ppos, uint32_t *wpos) = 0;
|
||||
|
||||
///////////////////////////////////////
|
||||
// SetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Sets the current play position of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int SetCurrentPosition(uint32_t pos) = 0;
|
||||
|
||||
/////////////////////////
|
||||
// Lock
|
||||
/////////////////////////
|
||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
||||
// available the size of the buffer(s) for writing.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int Lock(uint32_t pos, uint32_t numbytes, void **ptr1, uint32_t *numbytes1, void **ptr2,
|
||||
uint32_t *numbytes2, uint32_t flags) = 0;
|
||||
|
||||
///////////////////////////
|
||||
// Unlock
|
||||
///////////////////////////
|
||||
// Unlocks a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
virtual int Unlock(void *ptr1, uint32_t num1, void *ptr2, uint32_t num2) = 0;
|
||||
};
|
||||
|
||||
class ISoundDevice {
|
||||
public:
|
||||
///////////////////////////////
|
||||
// CreateSoundBuffer
|
||||
///////////////////////////////
|
||||
// Creates a sound buffer to be used with mixing and output.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// -2 : Out of memory
|
||||
// 0 : Ok!
|
||||
virtual int CreateSoundBuffer(SysSoundBufferDesc *lbdesc, ISysSoundBuffer **lsndb) = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,779 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 <cassert>
|
||||
#ifdef __LINUX__
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#include <SDL_audio.h>
|
||||
|
||||
#include "args.h"
|
||||
#include "lnxdsound.h"
|
||||
|
||||
#define FRAGMENT_LENGTH (LnxBuffers[0]->bps >> 4)
|
||||
#define FREQUENCY_SHIFT (14)
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* * Might be wise to use mutex's for the enter/exit critical functions
|
||||
*/
|
||||
static int LnxNumBuffers = 0;
|
||||
static LnxSoundBuffer **LnxBuffers = NULL;
|
||||
static LnxSoundDevice LinuxSoundDevice;
|
||||
|
||||
static bool StartupSoundSystem(LnxSoundDevice *dev);
|
||||
static void ShutdownSoundSystem(void);
|
||||
static void LinuxSoundMixWithVolume(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len);
|
||||
static uint32_t LinuxSoundMixNormalize(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len);
|
||||
static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len);
|
||||
static void LinuxSoundMixBuffersIntoMain(int len);
|
||||
static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len);
|
||||
|
||||
static inline void enter_critical() { SDL_LockAudio(); }
|
||||
|
||||
static inline void exit_critical() { SDL_UnlockAudio(); }
|
||||
|
||||
///////////////////////////////
|
||||
// LnxSound_CreateSoundBuffer
|
||||
///////////////////////////////
|
||||
// Creates a sound buffer to be used with mixing and output.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// -2 : Out of memory
|
||||
// 0 : Ok!
|
||||
int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSoundBuffer **lsndb) {
|
||||
WAVEFORMATEX *wfex;
|
||||
|
||||
if (!lbdesc || !lsndb || !dev)
|
||||
return -1;
|
||||
|
||||
wfex = lbdesc->lpwfxFormat;
|
||||
if (!wfex)
|
||||
return -1;
|
||||
|
||||
// Check to see if we have a primary buffer yet, if not, create it
|
||||
// now
|
||||
if (lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
if (LnxNumBuffers != 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (LnxNumBuffers == 0) {
|
||||
// we need to create a primary buffer
|
||||
LnxSoundBuffer *primary;
|
||||
LnxBufferDesc primdesc;
|
||||
WAVEFORMATEX wf;
|
||||
|
||||
memset(&primdesc, 0, sizeof(LnxBufferDesc));
|
||||
memset(&wf, 0, sizeof(wf));
|
||||
|
||||
primdesc.dwBufferBytes = 0;
|
||||
primdesc.dwFlags = LNXSND_CAPS_PRIMARYBUFFER;
|
||||
primdesc.lpwfxFormat = &wf;
|
||||
|
||||
int ret = LnxSound_CreateSoundBuffer(dev, &primdesc, &primary);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
*lsndb = (LnxSoundBuffer *)malloc(sizeof(LnxSoundBuffer));
|
||||
if (!(*lsndb))
|
||||
return -2;
|
||||
memset(*lsndb, 0, sizeof(LnxSoundBuffer));
|
||||
|
||||
if (lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
(*lsndb)->buffer_len = dev->bps;
|
||||
(*lsndb)->freq = dev->freq;
|
||||
(*lsndb)->bps = dev->bps;
|
||||
(*lsndb)->buffer = nullptr;
|
||||
} else {
|
||||
(*lsndb)->buffer_len = lbdesc->dwBufferBytes;
|
||||
(*lsndb)->freq = lbdesc->lpwfxFormat->nSamplesPerSec;
|
||||
|
||||
(*lsndb)->buffer = (uint8_t *)malloc((*lsndb)->buffer_len);
|
||||
if (!(*lsndb)->buffer) {
|
||||
free(*lsndb);
|
||||
*lsndb = nullptr;
|
||||
return -2;
|
||||
}
|
||||
memset((*lsndb)->buffer, 0, (*lsndb)->buffer_len);
|
||||
}
|
||||
|
||||
(*lsndb)->play_cursor = 0;
|
||||
(*lsndb)->write_cursor = 0;
|
||||
(*lsndb)->playing = 0;
|
||||
(*lsndb)->left_vol = (1 << 15);
|
||||
(*lsndb)->right_vol = (1 << 15);
|
||||
|
||||
if (!(lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
(*lsndb)->freq_adjustment = ((*lsndb)->freq << FREQUENCY_SHIFT) / LnxBuffers[0]->freq;
|
||||
(*lsndb)->bps = (*lsndb)->freq * lbdesc->lpwfxFormat->nBlockAlign;
|
||||
}
|
||||
|
||||
memcpy(&((*lsndb)->lbdesc), lbdesc, sizeof(LnxBufferDesc));
|
||||
|
||||
if (!(lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
memcpy(&((*lsndb)->wfx), lbdesc->lpwfxFormat, sizeof(WAVEFORMATEX));
|
||||
} else {
|
||||
// set up the wave format based on the device settings (primary)
|
||||
(*lsndb)->wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
(*lsndb)->wfx.nChannels = dev->channels;
|
||||
(*lsndb)->wfx.nSamplesPerSec = dev->freq;
|
||||
(*lsndb)->wfx.nBlockAlign = dev->channels * (dev->bit_depth / 8);
|
||||
(*lsndb)->wfx.nAvgBytesPerSec = dev->freq * (*lsndb)->wfx.nBlockAlign;
|
||||
(*lsndb)->wfx.wBitsPerSample = dev->bit_depth;
|
||||
(*lsndb)->wfx.cbSize = 0;
|
||||
}
|
||||
|
||||
if (LnxBuffers) {
|
||||
enter_critical();
|
||||
LnxBuffers = (LnxSoundBuffer **)realloc(LnxBuffers, sizeof(LnxSoundBuffer *) * (LnxNumBuffers + 1));
|
||||
LnxBuffers[LnxNumBuffers] = *lsndb;
|
||||
LnxNumBuffers++;
|
||||
exit_critical();
|
||||
} else {
|
||||
LnxBuffers = (LnxSoundBuffer **)malloc(sizeof(LnxSoundBuffer *));
|
||||
LnxBuffers[0] = *lsndb;
|
||||
LnxNumBuffers++;
|
||||
|
||||
// Initialize the Sound system and thread
|
||||
StartupSoundSystem(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_Release
|
||||
////////////////////////////
|
||||
// Releases the memory associated with a sound buffer. This pointer is
|
||||
// no longer valid after return.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// 0 : Ok!
|
||||
int LnxSoundBuffer_Release(LnxSoundBuffer *buff) {
|
||||
int i;
|
||||
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < LnxNumBuffers; i++) {
|
||||
if (LnxBuffers[i] == buff)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < LnxNumBuffers) {
|
||||
if (LnxNumBuffers == 1) {
|
||||
// stop the thread! primary going down
|
||||
ShutdownSoundSystem();
|
||||
|
||||
LnxNumBuffers = 0;
|
||||
LnxBuffers = nullptr;
|
||||
} else {
|
||||
// wait until it is ok (our thread is in a good position)
|
||||
enter_critical();
|
||||
|
||||
if (i == 0) {
|
||||
// can't delete the primary! whats going on here?
|
||||
return -1;
|
||||
}
|
||||
|
||||
LnxBuffers[i] = LnxBuffers[LnxNumBuffers - 1];
|
||||
LnxBuffers = (LnxSoundBuffer **)realloc(LnxBuffers, sizeof(LnxSoundBuffer *) * (LnxNumBuffers - 1));
|
||||
LnxNumBuffers--;
|
||||
|
||||
exit_critical();
|
||||
}
|
||||
|
||||
if (buff->buffer)
|
||||
free(buff->buffer);
|
||||
free(buff);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
if (LnxNumBuffers == 1) {
|
||||
// we freed the last non-primary buffer
|
||||
// so remove the primary buffer that is remaining
|
||||
return LnxSoundBuffer_Release(LnxBuffers[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_SetVolume
|
||||
//////////////////////////////
|
||||
// Sets the volume of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set volume
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetVolume(LnxSoundBuffer *buff, int32_t vol) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (!(buff->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME))
|
||||
return -1;
|
||||
|
||||
if ((vol > LNXSND_VOLUME_MAX) || (vol < LNXSND_VOLUME_MIN))
|
||||
return -2;
|
||||
|
||||
if (buff->lbdesc.dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
// not supported
|
||||
enter_critical();
|
||||
buff->volume = vol;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
enter_critical();
|
||||
|
||||
buff->volume = vol;
|
||||
|
||||
double vt;
|
||||
vt = (double)(buff->volume - (buff->pan > 0 ? buff->pan : 0));
|
||||
buff->left_vol = (uint32_t)(pow(2.0, vt / 600.0) * 32768.0);
|
||||
vt = (double)(buff->volume + (buff->pan < 0 ? buff->pan : 0));
|
||||
buff->right_vol = (uint32_t)(pow(2.0, vt / 600.0) * 32768.0);
|
||||
|
||||
exit_critical();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_SetPan
|
||||
///////////////////////////
|
||||
// Sets the pan of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set pan
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetPan(LnxSoundBuffer *buff, int32_t pan) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if ((pan > LNXSND_PAN_RIGHT) || (pan < LNXSND_PAN_LEFT))
|
||||
return -2;
|
||||
|
||||
if (!(buff->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (buff->lbdesc.dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enter_critical();
|
||||
|
||||
buff->pan = pan;
|
||||
|
||||
double pt;
|
||||
pt = (double)(buff->volume - (buff->pan > 0 ? buff->pan : 0));
|
||||
buff->left_vol = (uint32_t)(pow(2.0, pt / 600.0) * 32768.0);
|
||||
pt = (double)(buff->volume + (buff->pan < 0 ? buff->pan : 0));
|
||||
buff->right_vol = (uint32_t)(pow(2.0, pt / 600.0) * 32768.0);
|
||||
|
||||
exit_critical();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Stop
|
||||
/////////////////////////
|
||||
// Stops a buffer from playing
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Stop(LnxSoundBuffer *buff) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->playing = 0;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Play
|
||||
/////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Play(LnxSoundBuffer *buff, uint32_t flags) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->flags = flags;
|
||||
buff->playing = 1;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_GetCaps
|
||||
////////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCaps(LnxSoundBuffer *buff, LinuxSoundCaps *caps) {
|
||||
if (!caps || !buff)
|
||||
return -1;
|
||||
|
||||
caps->dwFlags = buff->lbdesc.dwFlags | LNXSND_CAPS_LOCSOFTWARE;
|
||||
caps->dwBufferBytes = buff->lbdesc.dwBufferBytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_GetStatus
|
||||
//////////////////////////////
|
||||
// Returns the status of a buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetStatus(LnxSoundBuffer *buff, uint32_t *status) {
|
||||
if (!status || !buff)
|
||||
return -1;
|
||||
|
||||
*status = 0;
|
||||
if (buff->playing)
|
||||
*status |= LNXSND_PLAYING;
|
||||
if (buff->flags & LNXSND_LOOPING)
|
||||
*status |= LNXSND_LOOPING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_GetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Returns the current play and write positions of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCurrentPosition(LnxSoundBuffer *buff, uint32_t *ppos, uint32_t *wpos) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (ppos)
|
||||
*ppos = buff->play_cursor;
|
||||
if (wpos)
|
||||
*wpos = buff->write_cursor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_SetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Sets the current play position of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_SetCurrentPosition(LnxSoundBuffer *buff, uint32_t pos) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->play_cursor = pos;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Lock
|
||||
/////////////////////////
|
||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
||||
// available the size of the buffer(s) for writing.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Lock(LnxSoundBuffer *buff, uint32_t pos, uint32_t numbytes, void **ptr1,
|
||||
uint32_t *numbytes1, void **ptr2, uint32_t *numbytes2, uint32_t flags) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (flags & LNXSND_LOCK_FROMWRITECURSOR)
|
||||
pos += buff->write_cursor;
|
||||
if (flags & LNXSND_LOCK_ENTIREBUFFER)
|
||||
numbytes = buff->buffer_len;
|
||||
if (numbytes > buff->buffer_len)
|
||||
numbytes = buff->buffer_len;
|
||||
|
||||
assert(numbytes1 != numbytes2);
|
||||
assert(ptr1 != ptr2);
|
||||
|
||||
if (pos + numbytes <= buff->buffer_len) {
|
||||
*(uint8_t **)ptr1 = buff->buffer + pos;
|
||||
*numbytes1 = numbytes;
|
||||
if (ptr2)
|
||||
*(uint8_t **)ptr2 = nullptr;
|
||||
if (numbytes2)
|
||||
*numbytes2 = 0;
|
||||
} else {
|
||||
*(uint8_t **)ptr1 = buff->buffer + pos;
|
||||
*numbytes1 = buff->buffer_len - pos;
|
||||
if (ptr2)
|
||||
*(uint8_t **)ptr2 = buff->buffer;
|
||||
if (numbytes2)
|
||||
*numbytes2 = numbytes - (buff->buffer_len - pos);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_Unlock
|
||||
///////////////////////////
|
||||
// Unlocks a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Unlock(LnxSoundBuffer *buff, void *ptr1, uint32_t num1, void *ptr2, uint32_t num2) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Internal Sound System routines
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Starts up the sound processing thread
|
||||
static bool StartupSoundSystem(LnxSoundDevice *dev) {
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
if (LnxNumBuffers < 1)
|
||||
return false;
|
||||
|
||||
const int kDefaultSampleCount = 1024;
|
||||
int sampleCount = kDefaultSampleCount;
|
||||
int sampleArgIndex = FindArg("-sdlSndSizeMovie");
|
||||
if (sampleArgIndex == 0) {
|
||||
sampleArgIndex = FindArg("-sdlSndSize");
|
||||
}
|
||||
if (sampleArgIndex != 0) {
|
||||
const char *sampleCountStr = GetArg(sampleArgIndex + 1);
|
||||
if (sampleCountStr) {
|
||||
sampleCount = atoi(sampleCountStr);
|
||||
if (sampleCount <= 0) {
|
||||
sampleCount = kDefaultSampleCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&LinuxSoundDevice, dev, sizeof(LnxSoundDevice));
|
||||
spec.freq = dev->freq;
|
||||
spec.format = dev->bit_depth == 8 ? AUDIO_U8 : AUDIO_S16SYS;
|
||||
spec.channels = dev->channels;
|
||||
spec.samples = sampleCount;
|
||||
spec.callback = LinuxSoundThreadHandler;
|
||||
|
||||
if (SDL_OpenAudio(&spec, nullptr) < 0) {
|
||||
return false;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Shutsdown the sound processing thread
|
||||
static void ShutdownSoundSystem() { SDL_CloseAudio(); }
|
||||
|
||||
static inline void GetValues(const LnxSoundBuffer *dsb, uint8_t *buf, uint32_t *fl, uint32_t *fr) {
|
||||
int16_t *bufs = (int16_t *)buf;
|
||||
|
||||
// 8 bit stereo
|
||||
if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 2) {
|
||||
*fl = (*buf - 128) << 8;
|
||||
*fr = (*(buf + 1) - 128) << 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit stereo
|
||||
if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 2) {
|
||||
*fl = *bufs;
|
||||
*fr = *(bufs + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 8 bit mono
|
||||
if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 1) {
|
||||
*fl = (*buf - 128) << 8;
|
||||
*fr = *fl;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit mono
|
||||
if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 1) {
|
||||
*fl = *bufs;
|
||||
*fr = *bufs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetValues(uint8_t *buf, uint32_t fl, uint32_t fr) {
|
||||
int16_t *bufs = (int16_t *)buf;
|
||||
|
||||
// 8 bit stereo
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 8) && (LnxBuffers[0]->wfx.nChannels == 2)) {
|
||||
*buf = (fl + 32768) >> 8;
|
||||
*(buf + 1) = (fr + 32768) >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit stereo
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 16) && (LnxBuffers[0]->wfx.nChannels == 2)) {
|
||||
*bufs = fl;
|
||||
*(bufs + 1) = fr;
|
||||
return;
|
||||
}
|
||||
|
||||
// 8 bit mono
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 8) && (LnxBuffers[0]->wfx.nChannels == 1)) {
|
||||
*buf = (((fl + fr) >> 1) + 32768) >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit mono
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 16) && (LnxBuffers[0]->wfx.nChannels == 1)) {
|
||||
*bufs = (fl + fr) >> 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void LinuxSoundMixWithVolume(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len) {
|
||||
uint32_t i, inc = (LnxBuffers[0]->wfx.wBitsPerSample >> 3);
|
||||
uint8_t *bpc = buf;
|
||||
int16_t *bps = (int16_t *)buf;
|
||||
|
||||
if ((!(dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (dsb->pan == 0)) &&
|
||||
(!(dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME) || (dsb->volume == 0)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i += inc) {
|
||||
uint32_t val;
|
||||
switch (inc) {
|
||||
case 1: {
|
||||
val = *bpc - 128;
|
||||
val = ((val * (i & inc ? dsb->right_vol : dsb->left_vol)) >> 15);
|
||||
*bpc = val + 128;
|
||||
bpc++;
|
||||
} break;
|
||||
case 2: {
|
||||
val = *bps;
|
||||
val = ((val * ((i & inc) ? dsb->right_vol : dsb->left_vol)) >> 15);
|
||||
*bps = val;
|
||||
bps++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t LinuxSoundMixNormalize(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len) {
|
||||
uint32_t i, size, ipos, ilen, fieldL = 0, fieldR = 0;
|
||||
uint8_t *ibp, *obp;
|
||||
uint32_t iAdvance = dsb->wfx.nBlockAlign;
|
||||
uint32_t oAdvance = LnxBuffers[0]->wfx.nBlockAlign;
|
||||
|
||||
ibp = dsb->buffer + dsb->play_cursor;
|
||||
obp = buf;
|
||||
|
||||
if ((dsb->freq == LnxBuffers[0]->wfx.nSamplesPerSec) &&
|
||||
(dsb->wfx.wBitsPerSample == LnxBuffers[0]->wfx.wBitsPerSample) &&
|
||||
(dsb->wfx.nChannels == LnxBuffers[0]->wfx.nChannels)) {
|
||||
if ((ibp + len) < (uint8_t *)(dsb->buffer + dsb->buffer_len))
|
||||
memcpy(obp, ibp, len);
|
||||
else {
|
||||
memcpy(obp, ibp, dsb->buffer_len - dsb->play_cursor);
|
||||
memcpy(obp + (dsb->buffer_len - dsb->play_cursor), dsb->buffer, len - (dsb->buffer_len - dsb->play_cursor));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (dsb->freq == LnxBuffers[0]->wfx.nSamplesPerSec) {
|
||||
ilen = 0;
|
||||
for (i = 0; i < len; i += oAdvance) {
|
||||
GetValues(dsb, ibp, &fieldL, &fieldR);
|
||||
ibp += iAdvance;
|
||||
ilen += iAdvance;
|
||||
SetValues(obp, fieldL, fieldR);
|
||||
obp += oAdvance;
|
||||
if (ibp >= (uint8_t *)(dsb->buffer + dsb->buffer_len))
|
||||
ibp = dsb->buffer;
|
||||
}
|
||||
return (ilen);
|
||||
}
|
||||
|
||||
size = len / oAdvance;
|
||||
ilen = ((size * dsb->freq_adjustment) >> FREQUENCY_SHIFT) * iAdvance;
|
||||
for (i = 0; i < size; i++) {
|
||||
ipos = (((i * dsb->freq_adjustment) >> FREQUENCY_SHIFT) * iAdvance) + dsb->play_cursor;
|
||||
|
||||
if (ipos >= dsb->buffer_len)
|
||||
ipos %= dsb->buffer_len;
|
||||
|
||||
GetValues(dsb, (dsb->buffer + ipos), &fieldL, &fieldR);
|
||||
SetValues(obp, fieldL, fieldR);
|
||||
obp += oAdvance;
|
||||
}
|
||||
return ilen;
|
||||
}
|
||||
|
||||
int DoMulDiv(int nNumber, int nNumerator, int nDenominator) {
|
||||
if (!nDenominator)
|
||||
return -1;
|
||||
int64_t ret;
|
||||
ret = (((int64_t)nNumber * nNumerator) + (nDenominator / 2)) / nDenominator;
|
||||
|
||||
if ((ret > 0x7FFFFFFF) || (ret < 0xFFFFFFFF))
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *TempSoundBuffer = nullptr;
|
||||
static int TempSoundBufferLen = 0;
|
||||
static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len) {
|
||||
uint32_t i, ilen, advance = (LnxBuffers[0]->wfx.wBitsPerSample >> 3);
|
||||
uint8_t *buf, *ibuf, *obuf;
|
||||
int32_t temp, field;
|
||||
int16_t *ibufs, *obufs;
|
||||
|
||||
if (!(dsb->flags & LNXSND_LOOPING)) {
|
||||
temp = DoMulDiv(LnxBuffers[0]->wfx.nAvgBytesPerSec, dsb->buffer_len, dsb->bps) -
|
||||
DoMulDiv(LnxBuffers[0]->wfx.nAvgBytesPerSec, dsb->play_cursor, dsb->bps);
|
||||
len = (len > temp) ? temp : len;
|
||||
}
|
||||
len &= ~3; // align to 4 byte boundary
|
||||
|
||||
if (!len) {
|
||||
dsb->playing = 0;
|
||||
dsb->write_cursor = 0;
|
||||
dsb->play_cursor = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > TempSoundBufferLen) {
|
||||
void *nb = realloc(TempSoundBuffer, len);
|
||||
if (nb) {
|
||||
TempSoundBuffer = nb;
|
||||
TempSoundBufferLen = len;
|
||||
buf = ibuf = (uint8_t *)nb;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = ibuf = (uint8_t *)TempSoundBuffer;
|
||||
}
|
||||
|
||||
ilen = LinuxSoundMixNormalize(dsb, ibuf, len);
|
||||
if ((dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME)) {
|
||||
LinuxSoundMixWithVolume(dsb, ibuf, len);
|
||||
}
|
||||
|
||||
obuf = LnxBuffers[0]->buffer + LnxBuffers[0]->play_cursor;
|
||||
for (i = 0; i < len; i += advance) {
|
||||
obufs = (int16_t *)obuf;
|
||||
ibufs = (int16_t *)ibuf;
|
||||
if (LnxBuffers[0]->wfx.wBitsPerSample == 16) {
|
||||
field = *ibufs;
|
||||
field += *obufs;
|
||||
field = (field > 32767) ? (32767) : field;
|
||||
field = (field < -32768) ? (-32768) : field;
|
||||
*obufs = field;
|
||||
} else {
|
||||
field = (*ibuf - 128);
|
||||
field += (*obuf - 128);
|
||||
field = (field > 127) ? (127) : field;
|
||||
field = (field < -128) ? (-128) : field;
|
||||
*obuf = field + 128;
|
||||
}
|
||||
ibuf += advance;
|
||||
obuf += advance;
|
||||
if (obuf >= (uint8_t *)(LnxBuffers[0]->buffer + LnxBuffers[0]->buffer_len))
|
||||
obuf = LnxBuffers[0]->buffer;
|
||||
}
|
||||
|
||||
// adjust positions of the cursors in the buffer
|
||||
dsb->play_cursor += ilen;
|
||||
dsb->write_cursor = dsb->play_cursor + ilen;
|
||||
|
||||
if (dsb->play_cursor >= dsb->buffer_len) {
|
||||
if (!(dsb->flags & LNXSND_LOOPING)) {
|
||||
// we're not looping, this buffer is done, reset it
|
||||
dsb->playing = 0;
|
||||
dsb->write_cursor = 0;
|
||||
dsb->play_cursor = 0;
|
||||
} else {
|
||||
// loop back around
|
||||
dsb->play_cursor = dsb->play_cursor % dsb->buffer_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsb->write_cursor >= dsb->buffer_len) {
|
||||
dsb->write_cursor = dsb->write_cursor % dsb->buffer_len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void LinuxSoundMixBuffersIntoMain(int len) {
|
||||
LnxSoundBuffer *dsb;
|
||||
|
||||
// only go to 1 since 0 is the main buffer
|
||||
for (int i = LnxNumBuffers - 1; i > 0; i--) {
|
||||
if (!(dsb = LnxBuffers[i]))
|
||||
continue;
|
||||
|
||||
if (dsb->buffer_len && dsb->playing) {
|
||||
LinuxSoundMixInMainBuffer(dsb, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len) {
|
||||
SDL_memset(stream, '\0', len);
|
||||
|
||||
LnxBuffers[0]->buffer = stream;
|
||||
LnxBuffers[0]->buffer_len = len;
|
||||
LnxBuffers[0]->play_cursor = 0;
|
||||
LnxBuffers[0]->write_cursor = 0;
|
||||
|
||||
LinuxSoundMixBuffersIntoMain(len);
|
||||
|
||||
LnxBuffers[0]->buffer = nullptr;
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __LNX_DSOUND_H_
|
||||
#define __LNX_DSOUND_H_
|
||||
|
||||
#include "SystemInterfaces.h"
|
||||
struct LnxSoundDevice {
|
||||
int sound_device; // file device handle for sound
|
||||
uint32_t bps; // (bytes per second) channels*freq*bit_depth/8
|
||||
uint32_t freq; // frequency (22050, etc.)
|
||||
uint32_t bit_depth; // 8 or 16
|
||||
uint32_t channels; // 1 or 2 (mono or stereo)
|
||||
};
|
||||
|
||||
#define WAVEFORMATEX SoundWAVEFormatEx
|
||||
|
||||
#define WAVE_FORMAT_PCM 0x01
|
||||
|
||||
#define LinuxSoundCaps SysSoundCaps
|
||||
|
||||
#define LnxBufferDesc SysSoundBufferDesc
|
||||
|
||||
struct LnxSoundBuffer {
|
||||
int freq_adjustment;
|
||||
int bps;
|
||||
uint32_t buffer_len;
|
||||
uint32_t play_cursor;
|
||||
uint32_t write_cursor;
|
||||
uint32_t flags;
|
||||
uint32_t left_vol, right_vol;
|
||||
|
||||
uint8_t *buffer;
|
||||
|
||||
int32_t volume;
|
||||
int32_t pan;
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
LnxBufferDesc lbdesc;
|
||||
|
||||
uint16_t freq;
|
||||
char playing;
|
||||
char __pad;
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
// LnxSound_CreateSoundBuffer
|
||||
///////////////////////////////
|
||||
// Creates a sound buffer to be used with mixing and output.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// -2 : Out of memory
|
||||
// 0 : Ok!
|
||||
int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSoundBuffer **lsndb);
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_Release
|
||||
////////////////////////////
|
||||
// Releases the memory associated with a sound buffer. This pointer is
|
||||
// no longer valid after return.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// 0 : Ok!
|
||||
int LnxSoundBuffer_Release(LnxSoundBuffer *buff);
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_SetVolume
|
||||
//////////////////////////////
|
||||
// Sets the volume of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set volume
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetVolume(LnxSoundBuffer *buff, int32_t vol);
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_SetPan
|
||||
///////////////////////////
|
||||
// Sets the pan of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set pan
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetPan(LnxSoundBuffer *buff, int32_t pan);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Stop
|
||||
/////////////////////////
|
||||
// Stops a buffer from playing
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Stop(LnxSoundBuffer *buff);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Play
|
||||
/////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Play(LnxSoundBuffer *buff, uint32_t flags);
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_GetCaps
|
||||
////////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCaps(LnxSoundBuffer *buff, LinuxSoundCaps *caps);
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_GetStatus
|
||||
//////////////////////////////
|
||||
// Returns the status of a buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetStatus(LnxSoundBuffer *buff, uint32_t *status);
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_GetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Returns the current play and write positions of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCurrentPosition(LnxSoundBuffer *buff, uint32_t *ppos, uint32_t *wpos);
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_SetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Sets the current play position of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_SetCurrentPosition(LnxSoundBuffer *buff, uint32_t pos);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Lock
|
||||
/////////////////////////
|
||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
||||
// available the size of the buffer(s) for writing.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Lock(LnxSoundBuffer *buff, uint32_t pos, uint32_t numbytes, void **ptr1,
|
||||
uint32_t *numbytes1, void **ptr2, uint32_t *numbytes2, uint32_t flags);
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_Unlock
|
||||
///////////////////////////
|
||||
// Unlocks a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Unlock(LnxSoundBuffer *buff, void *ptr1, uint32_t num1, void *ptr2, uint32_t num2);
|
||||
|
||||
#endif
|
9635
libmve/mve.asm
9635
libmve/mve.asm
File diff suppressed because it is too large
Load Diff
2347
libmve/mveasm.cpp
2347
libmve/mveasm.cpp
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define MVE_GFX_VESA_640_400 0x100
|
||||
#define MVE_GFX_VESA_640_200 0x8100
|
||||
#define MVE_GFX_VESA_640_480 0x101
|
||||
#define MVE_GFX_VESA_640_240 0x8101
|
||||
#define MVE_GFX_VESA_800_600 0x103
|
||||
#define MVE_GFX_VESA_800_300 0x8103
|
||||
#define MVE_GFX_VESA_1024_768 0x105
|
||||
#define MVE_GFX_VESA_1024_384 0x8105
|
||||
#define MVE_GFX_VESA_1280_1024 0x107
|
||||
#define MVE_GFX_VESA_1280_512 0x8107
|
||||
|
||||
#define MVE_GFX_VESA_320_200_HI 0x10d /* 1:5:5:5 Hi Color modes */
|
||||
#define MVE_GFX_VESA_640_480_HI 0x110
|
||||
#define MVE_GFX_VESA_800_600_HI 0x113
|
||||
#define MVE_GFX_VESA_1024_768_HI 0x116
|
||||
#define MVE_GFX_VESA_1280_1024_HI 0x119
|
||||
|
||||
/* Some hacked vesa modes */
|
||||
#define MVE_GFX_VESA_640_350 0x0F00 /* 640x350 */
|
||||
#define MVE_GFX_VESA_640_175 0x8F00 /* 640x175 */
|
||||
#define MVE_GFX_VESA_640_160 0x0F01 /* 640x160 */
|
||||
|
||||
#define MVE_GFX_VESA_CURRENT 0 /* Use current VESA mode */
|
||||
|
||||
#define MVE_GFX_AUTO (-1) /* Choose mode based on movie's preference */
|
||||
#define MVE_GFX_VGA 0x13 /* 320x200 */
|
||||
#define MVE_GFX_VGA_CURRENT (-2) /* 320x200 (mode already set) */
|
||||
#define MVE_GFX_VGA_MEDRES (-3) /* 248x264 out of 320x350 */
|
||||
#define MVE_GFX_VGA_HIRES (-4) /* 224x288 out of 360x480 */
|
||||
#define MVE_GFX_VGA_LORES (-5) /* 288x224 out of 320x240 */
|
||||
#define MVE_GFX_VESA_320_480 (-6) /* 320x480 */
|
@ -21,8 +21,6 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "SystemInterfaces.h"
|
||||
|
||||
/* callback for reading stream */
|
||||
typedef unsigned int (*mve_cb_Read)(void *stream, void *buffer, unsigned int count);
|
||||
/* callback for memore allocating */
|
||||
@ -77,8 +75,6 @@ void MVE_rmEndMovie(MVESTREAM *mve);
|
||||
|
||||
void MVE_getVideoSpec(MVE_videoSpec *vSpec);
|
||||
|
||||
void MVE_sndInit(ISoundDevice *lpDS);
|
||||
|
||||
void MVE_sndInit(int x);
|
||||
|
||||
void MVE_ioCallbacks(mve_cb_Read io_read);
|
||||
|
299
libmve/mvelibi.h
299
libmve/mvelibi.h
@ -1,299 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MVELIBI_H__
|
||||
#define MVELIBI_H__
|
||||
|
||||
#if __SC__
|
||||
#pragma SC align 1
|
||||
#elif __WATCOMC__
|
||||
#pragma pack(1);
|
||||
#elif _MSC_VER
|
||||
#pragma pack(1)
|
||||
#elif __LINUX__
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#error No platform defined
|
||||
#endif
|
||||
|
||||
#include "byteswap.h"
|
||||
//--------------------------------
|
||||
// Compressed Video Constants
|
||||
//--------------------------------
|
||||
|
||||
// Width and height of sections in pixels.
|
||||
#define SWIDTH 8
|
||||
#define SHEIGHT 8
|
||||
|
||||
#define LOG2_SWIDTH 3
|
||||
#define LOG2_SHEIGHT 3
|
||||
|
||||
//------------------------------
|
||||
// Movie File Header
|
||||
//------------------------------
|
||||
|
||||
#define MVE_FILE_TYPE "Interplay MVE File\x1A\0"
|
||||
#define MVE_FILE_VERSION 0x0100
|
||||
|
||||
// some inlines to prevent macro craziness when using incrementers and dereferencing, and so I can use operator
|
||||
// overloading
|
||||
inline uint16_t IntelSwapper(uint16_t a) { return INTEL_SHORT(a); }
|
||||
|
||||
inline int16_t IntelSwapper(int16_t a) { return INTEL_SHORT(a); }
|
||||
|
||||
inline uint32_t IntelSwapper(uint32_t a) { return INTEL_INT(a); }
|
||||
|
||||
inline int IntelSwapper(int a) { return INTEL_INT(a); }
|
||||
|
||||
struct mve_hdr {
|
||||
char FileType[20]; // MVE_FILE_TYPE
|
||||
uint16_t HdrSize; // sizeof(mve_hdr)
|
||||
uint16_t version; // MVE_FILE_VERSION
|
||||
uint16_t id; // ~MVE_FILE_VERSION+0x1234
|
||||
void SwapBytes() {
|
||||
HdrSize = IntelSwapper(HdrSize);
|
||||
version = IntelSwapper(version);
|
||||
id = IntelSwapper(id);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------
|
||||
// Movie File Records
|
||||
//------------------------------
|
||||
|
||||
struct ioHdrRec {
|
||||
uint16_t len; // Length of record data (pad to even)
|
||||
uint16_t kind; // See IO_REC_xxx
|
||||
// uint8_t data[0]; // Record data
|
||||
void SwapBytes() {
|
||||
len = IntelSwapper(len);
|
||||
kind = IntelSwapper(kind);
|
||||
}
|
||||
};
|
||||
|
||||
// This record classifications simplify utilities which must operate on
|
||||
// records. They are not used by this library when running a movie.
|
||||
//
|
||||
#define IO_REC_SND_INIT 0 // Sound setup
|
||||
#define IO_REC_SND_PRELOAD 1 // Sound preload
|
||||
#define IO_REC_FRAME_INIT 2 // Frame (video) setup
|
||||
#define IO_REC_FRAME 3 // Movie frames
|
||||
#define IO_REC_END 4 // Last Record (End of Movie)
|
||||
#define IO_REC_EOF 5 // Empty eof record at end of file.
|
||||
|
||||
//------------------------------
|
||||
// Movie File Major Opcodes
|
||||
//------------------------------
|
||||
//
|
||||
|
||||
#define MCMD_DATA(arg) ((uint8_t *)((arg) + 1))
|
||||
|
||||
struct mcmd_hdr {
|
||||
uint16_t len; // Length of data (pad to even)
|
||||
uint8_t major; // Major opcode
|
||||
uint8_t minor; // Minor opcode
|
||||
// uint8_t data[0]; // Opcode data
|
||||
void SwapBytes() { len = IntelSwapper(len); }
|
||||
};
|
||||
|
||||
#define mcmd_end 0 // End processing of movie
|
||||
|
||||
#define mcmd_next 1 // Advance to next movie record
|
||||
|
||||
#define mcmd_syncInit 2
|
||||
struct marg_syncInit {
|
||||
uint32_t period; // period of quanta
|
||||
uint16_t wait_quanta; // # of quanta per frame
|
||||
void SwapBytes() {
|
||||
period = IntelSwapper(period);
|
||||
wait_quanta = IntelSwapper(wait_quanta);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_sndConfigure 3
|
||||
struct marg_sndConfigure {
|
||||
uint16_t rate; // 65536-(256E6/(frequency*(stereo+1)))
|
||||
// comp16 is a minor opcode 1 field
|
||||
// It indicates that 16-bit data has been compressed to 8-bits.
|
||||
// When it is set, bits16 will also be set.
|
||||
// Each record will contain initial 16-bit sample followed
|
||||
// by remaining compressed 8-bit samples.
|
||||
// For stereo, there will be two initial 16-bit samples.
|
||||
// and compressed streams will be interleaved.
|
||||
#ifdef OUTRAGE_BIG_ENDIAN
|
||||
uint8_t pad : 5;
|
||||
uint8_t stereo : 1, bits16 : 1, comp16 : 1;
|
||||
uint8_t pad2;
|
||||
#else
|
||||
uint8_t stereo : 1, bits16 : 1, comp16 : 1;
|
||||
uint8_t pad;
|
||||
#endif
|
||||
uint16_t frequency;
|
||||
// Minor opcode 1 extends buflen to be a long
|
||||
uint32_t buflen;
|
||||
void SwapBytes() {
|
||||
rate = IntelSwapper(rate);
|
||||
frequency = IntelSwapper(frequency);
|
||||
buflen = IntelSwapper(buflen);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_sndSync 4
|
||||
|
||||
#define mcmd_nfConfig 5
|
||||
struct marg_nfConfig {
|
||||
uint16_t wqty;
|
||||
uint16_t hqty;
|
||||
// Minor opcode 1 fields:
|
||||
uint16_t fqty;
|
||||
// Minor opcode 2 fields:
|
||||
uint16_t hicolor; /*0=256-color, 1=HiColor, 2=HiColorSwapped*/
|
||||
void SwapBytes() {
|
||||
wqty = IntelSwapper(wqty);
|
||||
hqty = IntelSwapper(hqty);
|
||||
fqty = IntelSwapper(fqty);
|
||||
hicolor = IntelSwapper(hicolor);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_nfDecomp 6
|
||||
#define mcmd_nfDecompChg 16
|
||||
#define mcmd_nfPkDecomp 17
|
||||
struct marg_nfDecomp {
|
||||
uint16_t prev; // info:Prev frames+1 needed for full picture
|
||||
uint16_t iframe; // info:Current internal frame #
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
#ifdef OUTRAGE_BIG_ENDIAN
|
||||
uint8_t bitpadder : 7;
|
||||
uint8_t advance : 1;
|
||||
uint8_t dummy1;
|
||||
#else
|
||||
uint16_t advance : 1;
|
||||
uint16_t pad : 15;
|
||||
#endif
|
||||
|
||||
void SwapBytes() {
|
||||
prev = IntelSwapper(prev);
|
||||
iframe = IntelSwapper(iframe);
|
||||
x = IntelSwapper(x);
|
||||
y = IntelSwapper(y);
|
||||
w = IntelSwapper(w);
|
||||
h = IntelSwapper(h);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_sfShowFrame 7
|
||||
#if 0 // Not supported
|
||||
#define mcmd_sfPkShowFrameChg 18
|
||||
#endif
|
||||
struct marg_sfShowFrame {
|
||||
uint16_t pal_start;
|
||||
uint16_t pal_count;
|
||||
// Minor opcode 1 fields:
|
||||
uint16_t field; // 0:none, 2:send to even, 3:send to odd
|
||||
void SwapBytes() {
|
||||
pal_start = IntelSwapper(pal_start);
|
||||
pal_count = IntelSwapper(pal_count);
|
||||
field = IntelSwapper(field);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_sndAdd 8
|
||||
#define mcmd_sndSilence 9
|
||||
struct marg_sndAdd {
|
||||
uint16_t iframe; // info: iframe # of sound
|
||||
uint16_t TrackMask;
|
||||
uint16_t qty; // Uncompressed audio size in bytes
|
||||
// uint8_t data[0];
|
||||
void SwapBytes() {
|
||||
iframe = IntelSwapper(iframe);
|
||||
TrackMask = IntelSwapper(TrackMask);
|
||||
qty = IntelSwapper(qty);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_gfxMode 10
|
||||
struct marg_gfxMode {
|
||||
uint16_t minw;
|
||||
uint16_t minh;
|
||||
uint16_t mode;
|
||||
void SwapBytes() {
|
||||
minw = IntelSwapper(minw);
|
||||
minh = IntelSwapper(minh);
|
||||
mode = IntelSwapper(mode);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_palMakeSynthPalette 11
|
||||
struct marg_palMakeSynthPalette {
|
||||
uint8_t base_r;
|
||||
uint8_t range_r;
|
||||
uint8_t range_rb;
|
||||
uint8_t base_g;
|
||||
uint8_t range_g;
|
||||
uint8_t range_gb;
|
||||
void SwapBytes() {}
|
||||
};
|
||||
|
||||
#define mcmd_palLoadPalette 12
|
||||
struct marg_palLoadPalette {
|
||||
uint16_t start;
|
||||
uint16_t count;
|
||||
// uint8_t data[0];
|
||||
void SwapBytes() {
|
||||
start = IntelSwapper(start);
|
||||
count = IntelSwapper(count);
|
||||
}
|
||||
};
|
||||
|
||||
#define mcmd_palLoadCompPalette 13
|
||||
|
||||
#define mcmd_nfChanges 14
|
||||
#define mcmd_nfParms 15
|
||||
// 16 is used for mcmd_nfDecompChg, see above.
|
||||
// 17 is used for mcmd_nfPkDecomp, see above.
|
||||
// 18 is used for mcmd_nfPkShowFrameChg, see above
|
||||
|
||||
#define mcmd_nfPkInfo 19
|
||||
#define mcmd_nfHPkInfo 20
|
||||
struct marg_nfPkInfo {
|
||||
uint32_t error; // scaled by 10000
|
||||
uint16_t usage[64];
|
||||
};
|
||||
|
||||
#define mcmd_idcode 21
|
||||
struct marg_idcode {
|
||||
uint32_t idcode; // Code identifying version mcomp used to create
|
||||
};
|
||||
|
||||
#if __SC__
|
||||
#pragma SC align
|
||||
#elif __WATCOMC__
|
||||
#pragma pack();
|
||||
#elif _MSC_VER
|
||||
#pragma pack()
|
||||
#elif __LINUX__
|
||||
#pragma pack()
|
||||
#else
|
||||
#error No platform defined
|
||||
#endif
|
||||
|
||||
#endif
|
1762
libmve/mvelibl.cpp
1762
libmve/mvelibl.cpp
File diff suppressed because it is too large
Load Diff
277
libmve/mvelibl.h
277
libmve/mvelibl.h
@ -1,277 +0,0 @@
|
||||
|
||||
/*
|
||||
** mvelibl.h
|
||||
**
|
||||
** Interplay Movie File (MVE) Player
|
||||
** Library Definitions (32-Bit Linux Version)
|
||||
** Written by Paul Allen Edelstein, Interplay Productions.
|
||||
** Partial Linux port by Jeff Slutter, Outrage Entertainment.
|
||||
**
|
||||
** (c) 1997 Interplay Productions. All Rights Reserved.
|
||||
** This file is confidential and consists of proprietary information
|
||||
** of Interplay Productions. This file and associated libraries
|
||||
** may not, in whole or in part, be disclosed to third parties,
|
||||
** incorporated into any software product which is not being created
|
||||
** for Interplay Productions, copied or duplicated in any form,
|
||||
** without the prior written permission of Interplay Productions.
|
||||
** Further, you may not reverse engineer, decompile or otherwise
|
||||
** attempt to derive source code of this material.
|
||||
*/
|
||||
#ifndef MVELIB_H_INCLUDED
|
||||
#define MVELIB_H_INCLUDED
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "SystemInterfaces.h"
|
||||
#include "lnxdsound.h"
|
||||
|
||||
// Call this function to provide hooks into your memory management.
|
||||
typedef void *(mve_cb_alloc)(unsigned size);
|
||||
typedef void(mve_cb_free)(void *p);
|
||||
void MVE_memCallbacks(mve_cb_alloc *fn_alloc, mve_cb_free *fn_free);
|
||||
|
||||
// This function remains from the DOS version of mvelib.
|
||||
// It allows you to provide a preallocated buffer for file I/O,
|
||||
// but under Windows there's no real point to doing this.
|
||||
void MVE_memIO(void *p, unsigned size);
|
||||
|
||||
// Call this function to provide hook into your file io.
|
||||
typedef unsigned mve_cb_read(int handle, void *buf, unsigned count);
|
||||
void MVE_ioCallbacks(mve_cb_read *fn_read);
|
||||
|
||||
// Call this function to provide hook into your digital sound driver.
|
||||
// Call with NULL if no sound support is available (default).
|
||||
void MVE_sndInit(ISoundDevice *lpDS);
|
||||
|
||||
// Volume controls.
|
||||
// These functions are equivalent to the IDirectSoundBuffer
|
||||
// SetVolume and SetPan functions. They take effect immediately
|
||||
// and do NOT reset when a new movie starts.
|
||||
// Volume ranges from 0 (0 db, no volume change) to -10,000 (-100db, essentially silent).
|
||||
// Pan ranges from -10,000 (left full volume, right -100db), thru 0 (both full),
|
||||
// thru 10,000 (left -100db, right full volume).
|
||||
// The default value for volume and pan is zero.
|
||||
void MVE_dsbSetVolume(int32_t lVolume);
|
||||
void MVE_dsbSetPan(int32_t lPan);
|
||||
|
||||
// Only call this function to configure software to work with a Super VGA
|
||||
// mode if you do not have VESA support.
|
||||
// Restrictions/Assumptions:
|
||||
// 64K >= WinSize >= WinGran
|
||||
// WinSize % WinGran == 0
|
||||
// WinGran of 64K is represented by 0
|
||||
// SetBank is address of function with following protocol:
|
||||
// bh: 0=Set window, 1=Get Window
|
||||
// bl: Window number (0 or 1)
|
||||
// dx: Window position in video memory in units of WinGran.
|
||||
// on return, registers AX and DX are destroyed.
|
||||
//
|
||||
// Hicolor is 0 for 8-bit color, 1 for 15-bit rgb color, 2
|
||||
// for byte swapped 15-bit rgb color.
|
||||
//
|
||||
// Note: 16-bit WriteWinSeg replaced with 32-bit WriteWinPtr
|
||||
//
|
||||
// The functionality of the following function is reduced in the Windows
|
||||
// version of the player. Call it as follows:
|
||||
// MVE_sfSVGA(w,h,w,0,NULL,0,0,NULL,hicolor)
|
||||
// where w and h are the width and height of your window,
|
||||
// and hicolor is a boolean which indicates if the screen
|
||||
// is operating in hi color, rather than 8-bit paletted color.
|
||||
// Under windows, the information provided by this function
|
||||
// is just used for window centering and for determining
|
||||
// how and when to do palette callbacks.
|
||||
void MVE_sfSVGA(unsigned w, unsigned h, unsigned LineWidth, unsigned WriteWin, uint8_t *WriteWinPtr,
|
||||
uint32_t WinSize, unsigned WinGran, void *SetBank, unsigned hicolor);
|
||||
|
||||
// This function alters the display from 640x480 or 640x400 to 640x350 resolution.
|
||||
void MVE_ForceVres350(void);
|
||||
|
||||
// This function alters the display from 640x480/400/350 to 640x240/200/175.
|
||||
void MVE_ForceVresHalf(void);
|
||||
|
||||
// **NOTE** There still need to be calls to restore original screen resolution
|
||||
// after using MVE_ForceVres350() or MVE_ForceVresHalf()!
|
||||
// Only call this function to either
|
||||
// 1. Replace method of copying frame to screen (perhaps for a nonstandard
|
||||
// screen format).
|
||||
// 2. Wrap your own code around the transfer of frame to screen
|
||||
// or modify which portions of the screen are updated.
|
||||
// This function replaces calls to the default MVE_ShowFrame function
|
||||
// with calls to your function, which can itself call MVE_ShowFrame.
|
||||
typedef void (*mve_cb_ShowFrame)(uint8_t *buf, uint32_t bufw, uint32_t bufh, uint32_t sx,
|
||||
uint32_t sy, uint32_t w, uint32_t h, uint32_t dstx, uint32_t dsty,
|
||||
uint32_t hicolor);
|
||||
void MVE_sfCallbacks(mve_cb_ShowFrame fn_ShowFrame);
|
||||
|
||||
typedef void mve_cb_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
void MVE_palCallbacks(mve_cb_SetPalette *fn_SetPalette);
|
||||
|
||||
void MVE_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
|
||||
// Configure the software for a graphics mode, optionally setting the
|
||||
// display to that mode (see the MVE_GFX_xxx constants defined below).
|
||||
bool MVE_gfxMode(int16_t mode);
|
||||
|
||||
// Reset the screen to text mode (usually done before exiting a program).
|
||||
void MVE_gfxReset(void);
|
||||
|
||||
// Set line for split screen graphics
|
||||
// {Use vbe_SetDisplayStart(x,y) to set vid buf for upper screen}
|
||||
void MVE_gfxSetSplit(unsigned line);
|
||||
|
||||
// Setup double buffering
|
||||
void MVE_gfxSetDoubleBuffer(unsigned y1, unsigned y2, unsigned vis);
|
||||
|
||||
// Get double buffering state
|
||||
void MVE_gfxGetDoubleBuffer(unsigned *vis_y, unsigned *hid_y);
|
||||
|
||||
// Enable double buffering for auto screen modes
|
||||
void MVE_sfAutoDoubleBuffer(unsigned on);
|
||||
|
||||
// Wait for video retrace off (0) or on (1)
|
||||
void MVE_gfxWaitRetrace(unsigned state);
|
||||
|
||||
//---------------------------------------------
|
||||
// Establish callback for user control of movie playback.
|
||||
typedef int mve_cb_ctl(void);
|
||||
void MVE_rmCallbacks(mve_cb_ctl *fn_ctl);
|
||||
|
||||
// Specify playback fastmode option (default is MVE_RM_NORMAL).
|
||||
#define MVE_RM_NORMAL 0 // Normal playback
|
||||
#define MVE_RM_HALF 1 // Half height (even lines only)
|
||||
#define MVE_RM_DITHERED 2 // Half height (dither between lines)
|
||||
#define MVE_RM_HALF_2 5 // Full height, even lines only
|
||||
#define MVE_RM_DITHERED_2 6 // Full height, dither, even lines only
|
||||
|
||||
void MVE_rmFastMode(int mode);
|
||||
|
||||
// Specifying horizontal magnification:
|
||||
// 3: 4/3 horizontal magnification
|
||||
// 4: normal
|
||||
void MVE_rmHScale(int hscale);
|
||||
|
||||
// Get frame count and number of dropped frames from last movie played.
|
||||
void MVE_rmFrameCounts(unsigned *FrameCount, unsigned *FrameDropCount);
|
||||
|
||||
// Dump timing statistics (if enabled).
|
||||
void MVE_logDumpStats(void);
|
||||
|
||||
// Run a compressed movie by reading data starting at the current
|
||||
// position in the file specified by handle hFile.
|
||||
// The movie window is displaced by dx,dy from the upper left hand corner
|
||||
// or is centered if dx,dy is -1,-1.
|
||||
// track specifies which audio track to play (usually 0 for a single
|
||||
// audio track).
|
||||
//
|
||||
// Returns an error/result code.
|
||||
//
|
||||
// Memory may be dynamically allocated while movie runs.
|
||||
int MVE_RunMovie(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
// MVE_RunMovieContinue is the same as MVE_RunMovie except that it does not
|
||||
// automatically call MVE_rmEndMovie(). This may improve the smoothness
|
||||
// of immediately playing another movie afterwards.
|
||||
int MVE_RunMovieContinue(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
// Alternative to using MVE_RunMovie() and MVE_rmCallbacks().
|
||||
// Call MVE_rmPrepMovie() to prepare movie for playing.
|
||||
// Call MVE_rmStepMovie() to display next frame of movie until nonzero
|
||||
// result is returned (MVE_ERR_EOF for no next frame or some other error).
|
||||
// Call MVE_rmHoldMovie() to hold on current frame (and pause audio).
|
||||
// Call MVE_rmEndMovie() to abort movie.
|
||||
// All functions except MVE_rmEndMovie() return an error code.
|
||||
int MVE_rmPrepMovie(int hFile, int dx, int dy, unsigned track);
|
||||
int MVE_rmStepMovie(void);
|
||||
int MVE_rmHoldMovie(void);
|
||||
void MVE_rmEndMovie(void);
|
||||
|
||||
// Frame Reader Streams
|
||||
// This is a special interface to the movie system which
|
||||
// allows a movie file to be opened as a stream from which
|
||||
// its frames may be retrieved. Audio and timing information
|
||||
// are ignored. For 256-color screen applications, palette
|
||||
// information is also typically ignored, and movies with a common
|
||||
// predefined palette are used. However, for hi-color screen
|
||||
// applications, an interface to obtain palette information has
|
||||
// been provided. This system is intended for use by video sprites
|
||||
// played off of the hard drive or out of memory.
|
||||
typedef struct MVE_frStreamRec* MVE_frStream;
|
||||
|
||||
// MVE_frOpen
|
||||
// Before calling this function, be sure to call MVE_memCallbacks()
|
||||
// and MVE_rmDirectDraw().
|
||||
// fn_read specifies a file reader similar to the one
|
||||
// used by MVE_ioCallbacks().
|
||||
// handle specifies a file handle for an already opened
|
||||
// movie file. It is used by the file reader and is similar
|
||||
// to hFile argument used by MVE_RunMovie() and MVE_rmPrepMovie().
|
||||
// fr_callback is normally NULL, but can be used to supply
|
||||
// a handler for user data which has been interleaved into
|
||||
// the movie stream.
|
||||
//
|
||||
// If the movie file is invalid or the call otherwise fails,
|
||||
// NULL is returned.
|
||||
MVE_frStream MVE_frOpen(unsigned (*fn_read)(int handle, void *buf, unsigned count), int handle,
|
||||
int (*fr_callback)(unsigned op, unsigned subop, void *buf));
|
||||
|
||||
// MVE_frGet
|
||||
// Returns the next frame from the specified frame reader stream
|
||||
// a nonzero error code {the same codes as returned by MVE_RunMovie()
|
||||
// and MVE_rmStepMovie()}.
|
||||
// If successful, MVE_frGet(frs, &buf, &w, &h) returns a pointer
|
||||
// to a surface containing the frame in pBuf,
|
||||
// and its width and height in w and h.
|
||||
int MVE_frGet(MVE_frStream frs, uint8_t **pBuf, uint32_t *width, uint32_t *height, uint32_t *hicolor);
|
||||
|
||||
// MVE_frPal
|
||||
// After each successful call to MVE_frGet(), this call may be used to
|
||||
// obtain corresponding palette information. It returns a pointer to the
|
||||
// entire current palette for the frame, and the subportion of the palette
|
||||
// which has changed this frame is identified by start and count (they will
|
||||
// both be zero on frames for which the palette has not changed).
|
||||
//
|
||||
// Paltbl points to 256*3 bytes of 6-bit r,g,b triples.
|
||||
// Start ranges from 0 to 255. Count from 0 to 256.
|
||||
//
|
||||
// These conventions are similar to those used by the palette callback arguments
|
||||
// with the standard player interface, except that this interface requires
|
||||
// polling each frame instead, and must be passed pointers to the variables where
|
||||
// the values will be returned.
|
||||
//
|
||||
void MVE_frPal(MVE_frStream frs, uint8_t **pPaltbl, unsigned *pStart, unsigned *pCount);
|
||||
|
||||
// MVE_frClose
|
||||
// Closes the specified Frame Reader Stream frs.
|
||||
// Frees all storage associated with the stream.
|
||||
// The specified frs must not be used after this call.
|
||||
// Note that the open file handle specified in MVE_frOpen() is
|
||||
// not closed by this call...that is the caller's responsibility.
|
||||
void MVE_frClose(MVE_frStream frs);
|
||||
|
||||
// Release any memory dynamically allocated by MVE_RunMovie.
|
||||
void MVE_ReleaseMem(void);
|
||||
|
||||
// Return string corresponding to MVE_RunMovie result code.
|
||||
const char *MVE_strerror(int code);
|
||||
|
||||
// RunMovie callback control code and result codes.
|
||||
// Codes > 1 are user defined.
|
||||
#define MVE_CTL_HOLD -1 // Returned by rmCtl() to hold current frame
|
||||
#define MVE_CTL_EXIT 1 // Returned by rmCtl() to end movie
|
||||
|
||||
#define MVE_ERR_EOF -1 // Returned by StepMovie() for end of movie
|
||||
#define MVE_ERR_IO -2 // File I/O error or unable to alloc memory.
|
||||
#define MVE_ERR_SYNC -3 // Timer error.
|
||||
#define MVE_ERR_SND -4 // Unable to allocate memory for sound
|
||||
#define MVE_ERR_NF -5 // Unable to allocate memory for video
|
||||
#define MVE_ERR_GFX_FIT -6 // Screen size too small for movie
|
||||
#define MVE_ERR_GFX_FAIL -7 // Failed to set desired graphics mode
|
||||
#define MVE_ERR_BADFMT -8 // Not a MVE file or unacceptable version
|
||||
#define MVE_ERR_GFX_CLR -9 // Incorrect screen color mode
|
||||
#define MVE_ERR_PREP -10 // StepMovie() without PrepMovie()
|
||||
#define MVE_ERR_LD -11 // Unable to initialize Draw system (DirectDraw, etc)
|
||||
#define MVE_ERR_LOST -12 // Direct Draw Surface Lost
|
||||
|
||||
#define MVE_ERR_LAST -12
|
||||
|
||||
#endif
|
15054
libmve/mvelibwa.asm
15054
libmve/mvelibwa.asm
File diff suppressed because it is too large
Load Diff
@ -476,12 +476,6 @@ void MVE_rmEndMovie(MVESTREAM *mve) {
|
||||
|
||||
void MVE_rmHoldMovie() { timer_started = 0; }
|
||||
|
||||
void MVE_sndInit(ISoundDevice *lpDS) {
|
||||
#ifdef AUDIO
|
||||
// snd_ds = lpDS;
|
||||
#endif
|
||||
}
|
||||
|
||||
void MVE_sndInit(int x) {
|
||||
#ifdef AUDIO
|
||||
if (x == -1)
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 <cstdint>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#include <MMSystem.h>
|
||||
|
||||
uint32_t platform_timeGetTime(void) { return timeGetTime(); }
|
||||
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
uint32_t platform_timeGetTime(void) {
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
|
||||
return (t.tv_sec * 1000 + t.tv_usec / 1000);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef MVEPLATFORM_H_
|
||||
#define MVEPLATFORM_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t platform_timeGetTime(void);
|
||||
|
||||
#endif
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
|
||||
--- HISTORICAL COMMENTS FOLLOW ---
|
||||
|
||||
** #include <math.h>
|
||||
** void init_snd_8to16(void)
|
||||
** {
|
||||
** int i;
|
||||
** for (i=0; i<44; ++i)
|
||||
** snd_8to16[i] = i;
|
||||
** for (i=44; i<128; ++i)
|
||||
** snd_8to16[i] = (unsigned)floor(pow(65535,i/127.0)+.5);
|
||||
** for (i=1; i<128; ++i)
|
||||
** snd_8to16[256-i] = -snd_8to16[i];
|
||||
** snd_8to16[128] = snd_8to16[129];
|
||||
** }
|
||||
*/
|
||||
|
||||
#define S int16_t
|
||||
int16_t snd_8to16[256] = {
|
||||
(S)0, (S)1, (S)2, (S)3, (S)4, (S)5,
|
||||
(S)6, (S)7, (S)(S)8, (S)9, (S)10, (S)11,
|
||||
(S)12, (S)13, (S)14, (S)15, (S)(S)16, (S)17,
|
||||
(S)18, (S)19, (S)20, (S)21, (S)22, (S)23,
|
||||
(S)(S)24, (S)25, (S)26, (S)27, (S)28, (S)29,
|
||||
(S)30, (S)31, (S)(S)32, (S)33, (S)34, (S)35,
|
||||
(S)36, (S)37, (S)38, (S)39, (S)(S)40, (S)41,
|
||||
(S)42, (S)43, (S)47, (S)51, (S)56, (S)61,
|
||||
(S)(S)66, (S)72, (S)79, (S)86, (S)94, (S)102,
|
||||
(S)112, (S)122, (S)(S)133, (S)145, (S)158, (S)173,
|
||||
(S)189, (S)206, (S)225, (S)245, (S)(S)267, (S)292,
|
||||
(S)318, (S)348, (S)379, (S)414, (S)452, (S)493,
|
||||
(S)(S)538, (S)587, (S)640, (S)699, (S)763, (S)832,
|
||||
(S)908, (S)991, (S)(S)1081, (S)1180, (S)1288, (S)1405,
|
||||
(S)1534, (S)1673, (S)1826, (S)1993, (S)(S)2175, (S)2373,
|
||||
(S)2590, (S)2826, (S)3084, (S)3365, (S)3672, (S)4008,
|
||||
(S)(S)4373, (S)4772, (S)5208, (S)5683, (S)6202, (S)6767,
|
||||
(S)7385, (S)8059, (S)(S)8794, (S)9597, (S)10472, (S)11428,
|
||||
(S)12471, (S)13609, (S)14851, (S)16206, (S)(S)17685, (S)19298,
|
||||
(S)21060, (S)22981, (S)25078, (S)27367, (S)29864, (S)32589,
|
||||
(S)(S)35563, (S)38808, (S)42350, (S)46214, (S)50431, (S)55033,
|
||||
(S)60055, (S)65535, (S)(S)-65535, (S)-65535, (S)-60055, (S)-55033,
|
||||
(S)-50431, (S)-46214, (S)-42350, (S)-38808, (S)(S)-35563, (S)-32589,
|
||||
(S)-29864, (S)-27367, (S)-25078, (S)-22981, (S)-21060, (S)-19298,
|
||||
(S)(S)-17685, (S)-16206, (S)-14851, (S)-13609, (S)-12471, (S)-11428,
|
||||
(S)-10472, (S)-9597, (S)(S)-8794, (S)-8059, (S)-7385, (S)-6767,
|
||||
(S)-6202, (S)-5683, (S)-5208, (S)-4772, (S)(S)-4373, (S)-4008,
|
||||
(S)-3672, (S)-3365, (S)-3084, (S)-2826, (S)-2590, (S)-2373,
|
||||
(S)(S)-2175, (S)-1993, (S)-1826, (S)-1673, (S)-1534, (S)-1405,
|
||||
(S)-1288, (S)-1180, (S)(S)-1081, (S)-991, (S)-908, (S)-832,
|
||||
(S)-763, (S)-699, (S)-640, (S)-587, (S)(S)-538, (S)-493,
|
||||
(S)-452, (S)-414, (S)-379, (S)-348, (S)-318, (S)-292,
|
||||
(S)(S)-267, (S)-245, (S)-225, (S)-206, (S)-189, (S)-173,
|
||||
(S)-158, (S)-145, (S)(S)-133, (S)-122, (S)-112, (S)-102,
|
||||
(S)-94, (S)-86, (S)-79, (S)-72, (S)(S)-66, (S)-61,
|
||||
(S)-56, (S)-51, (S)-47, (S)-43, (S)-42, (S)-41,
|
||||
(S)(S)-40, (S)-39, (S)-38, (S)-37, (S)-36, (S)-35,
|
||||
(S)-34, (S)-33, (S)(S)-32, (S)-31, (S)-30, (S)-29,
|
||||
(S)-28, (S)-27, (S)-26, (S)-25, (S)(S)-24, (S)-23,
|
||||
(S)-22, (S)-21, (S)-20, (S)-19, (S)-18, (S)-17,
|
||||
(S)(S)-16, (S)-15, (S)-14, (S)-13, (S)-12, (S)-11,
|
||||
(S)-10, (S)-9, (S)(S)-8, (S)-7, (S)-6, (S)-5,
|
||||
(S)-4, (S)-3, (S)-2, (S)-1
|
||||
};
|
||||
#undef S
|
||||
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* 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 "win_sound.h"
|
||||
|
||||
namespace D3 {
|
||||
|
||||
MovieSoundDevice::MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size,
|
||||
bool is_compressed) {
|
||||
m_is_compressed = is_compressed;
|
||||
|
||||
m_lpDS = nullptr;
|
||||
m_lpDSB = nullptr;
|
||||
|
||||
m_WFE.wFormatTag = WAVE_FORMAT_PCM;
|
||||
m_WFE.nChannels = channels;
|
||||
m_WFE.nSamplesPerSec = sample_rate;
|
||||
m_WFE.nAvgBytesPerSec = sample_rate * channels * sample_size;
|
||||
m_WFE.nBlockAlign = channels * sample_size;
|
||||
m_WFE.wBitsPerSample = sample_size * 8;
|
||||
|
||||
// Initialize DSound
|
||||
if (FAILED(DirectSoundCreate(nullptr, &m_lpDS, nullptr))) {
|
||||
return;
|
||||
}
|
||||
// Set Cooperative Level
|
||||
HWND hWnd = GetForegroundWindow();
|
||||
if (hWnd == nullptr) {
|
||||
hWnd = GetDesktopWindow();
|
||||
}
|
||||
if (FAILED(m_lpDS->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create Primary Buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory(&dsbd, sizeof(dsbd));
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbd.dwBufferBytes = 0;
|
||||
dsbd.lpwfxFormat = nullptr;
|
||||
|
||||
LPDIRECTSOUNDBUFFER lpDSB = nullptr;
|
||||
if (FAILED(m_lpDS->CreateSoundBuffer(&dsbd, &lpDSB, nullptr))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set Primary Buffer Format
|
||||
if (FAILED(lpDSB->SetFormat(&m_WFE))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create Second Sound Buffer
|
||||
dsbd.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
|
||||
dsbd.dwBufferBytes = (buf_size + (buf_size >> 1)) & ~3;
|
||||
dsbd.lpwfxFormat = &m_WFE;
|
||||
|
||||
if (FAILED(m_lpDS->CreateSoundBuffer(&dsbd, &m_lpDSB, nullptr))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MovieSoundDevice::~MovieSoundDevice() {
|
||||
if (m_lpDSB != nullptr) {
|
||||
m_lpDSB->Stop();
|
||||
m_lpDSB->Release();
|
||||
}
|
||||
m_sound_buffer.reset();
|
||||
}
|
||||
|
||||
void MovieSoundDevice::Play() {
|
||||
if (!m_lpDSB)
|
||||
return;
|
||||
|
||||
// Check if the DirectSound was created successfully
|
||||
if (m_lpDS == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
LPBYTE lpvAudio1 = nullptr, lpvAudio2 = nullptr;
|
||||
DWORD dwBytesAudio1 = 0, dwBytesAudio2 = 0;
|
||||
|
||||
if (FAILED(m_lpDSB->Lock(0, (DWORD)GetBuffer()->size() * 2, reinterpret_cast<LPVOID *>(&lpvAudio1), &dwBytesAudio1,
|
||||
reinterpret_cast<LPVOID *>(&lpvAudio2), &dwBytesAudio2, DSBLOCK_FROMWRITECURSOR)))
|
||||
return;
|
||||
|
||||
if (dwBytesAudio1 > 0) {
|
||||
memset(lpvAudio1, 0, dwBytesAudio1);
|
||||
auto limit = std::min(dwBytesAudio1 / 2, (DWORD)GetBuffer()->size());
|
||||
for (int i = 0; i < limit; i += 2) {
|
||||
int16_t sample = GetBuffer()->front();
|
||||
GetBuffer()->pop_front();
|
||||
lpvAudio1[i] = sample & 0xff;
|
||||
lpvAudio1[i + 1] = sample >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (dwBytesAudio2 > 0) {
|
||||
memset(lpvAudio2, 0, dwBytesAudio2);
|
||||
auto limit = std::min(dwBytesAudio2 / 2, (DWORD)GetBuffer()->size());
|
||||
for (int i = 0; i < limit; i += 2) {
|
||||
int16_t sample = GetBuffer()->front();
|
||||
GetBuffer()->pop_front();
|
||||
lpvAudio2[i] = sample & 0xff;
|
||||
lpvAudio2[i + 1] = sample >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
m_lpDSB->Unlock(lpvAudio1, dwBytesAudio1, lpvAudio2, dwBytesAudio2);
|
||||
|
||||
// Begin Play
|
||||
m_lpDSB->Play(0, 0, DSBPLAY_LOOPING);
|
||||
|
||||
}
|
||||
|
||||
void MovieSoundDevice::Stop() {
|
||||
if (m_lpDSB != nullptr) {
|
||||
|
||||
m_lpDSB->Stop();
|
||||
|
||||
// Empty the buffer
|
||||
LPVOID lpvAudio1 = nullptr;
|
||||
DWORD dwBytesAudio1 = 0;
|
||||
HRESULT hr = m_lpDSB->Lock(0, 0, &lpvAudio1, &dwBytesAudio1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
memset(lpvAudio1, 0, dwBytesAudio1);
|
||||
m_lpDSB->Unlock(lpvAudio1, dwBytesAudio1, nullptr, 0);
|
||||
|
||||
// Move the current play position to begin
|
||||
m_lpDSB->SetCurrentPosition(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MovieSoundDevice::Lock(){}
|
||||
|
||||
void MovieSoundDevice::Unlock(){}
|
||||
|
||||
} // namespace D3
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Descent Developers
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef WIN_SOUND_H
|
||||
#define WIN_SOUND_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "win/DirectX/dsound.h"
|
||||
|
||||
#include "sound_interface.h"
|
||||
|
||||
namespace D3 {
|
||||
|
||||
class MovieSoundDevice : ISoundDevice {
|
||||
public:
|
||||
MovieSoundDevice(int sample_rate, uint16_t sample_size, uint8_t channels, uint32_t buf_size, bool is_compressed);
|
||||
~MovieSoundDevice();
|
||||
|
||||
[[nodiscard]] bool IsInitialized() const { return m_lpDS != nullptr; }
|
||||
|
||||
void Play() override;
|
||||
void Stop() override;
|
||||
void Lock() override;
|
||||
void Unlock() override;
|
||||
|
||||
using ISoundDevice::GetBuffer;
|
||||
using ISoundDevice::IsCompressed;
|
||||
|
||||
private:
|
||||
WAVEFORMATEX m_WFE{};
|
||||
LPDIRECTSOUND m_lpDS;
|
||||
LPDIRECTSOUNDBUFFER m_lpDSB;
|
||||
|
||||
};
|
||||
|
||||
} // namespace D3
|
||||
|
||||
#endif // WIN_SOUND_H
|
@ -1,17 +0,0 @@
|
||||
set(HEADERS
|
||||
dyna_pthread.h
|
||||
lnxdsound.h
|
||||
mvegfx.h
|
||||
mvelibi.h
|
||||
mvelibl.h
|
||||
snd8to16.h)
|
||||
|
||||
set(CPPS
|
||||
lnxdraw.cpp
|
||||
lnxdsound.cpp
|
||||
mveasm.cpp
|
||||
mvelibl.cpp)
|
||||
|
||||
# asmstub.c
|
||||
|
||||
add_library(lnxmvelib STATIC ${HEADERS} ${CPPS})
|
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* These are our global variables for passing values - AH */
|
||||
/* For _asm_sndDecompM16 */
|
||||
uint16_t *sndDecompM16_dst;
|
||||
uint8_t *sndDecompM16_src;
|
||||
uint32_t sndDecompM16_len;
|
||||
uint32_t sndDecompM16_prev;
|
||||
uint32_t sndDecompM16_return;
|
||||
/* For _asm_sndDecompM16 */
|
||||
uint16_t *sndDecompS16_dst;
|
||||
uint8_t *sndDecompS16_src;
|
||||
uint32_t sndDecompS16_len;
|
||||
uint32_t sndDecompS16_prev;
|
||||
uint32_t sndDecompS16_return;
|
||||
/* For _asm_nfHPkDecomp */
|
||||
uint8_t *nfHPkDecomp_ops;
|
||||
uint8_t *nfHPkDecomp_comp;
|
||||
uint32_t nfHPkDecomp_x;
|
||||
uint32_t nfHPkDecomp_y;
|
||||
uint32_t nfHPkDecomp_w;
|
||||
uint32_t nfHPkDecomp_h;
|
||||
|
||||
#ifdef __cplusplus /* Avoid C++ name mangling - AH */
|
||||
extern "C" {
|
||||
#endif
|
||||
void _asm_sndDecompM16(void);
|
||||
void _asm_sndDecompS16(void);
|
||||
void _asm_nfPkConfig(void);
|
||||
void _asm_nfHPkDecomp(void);
|
||||
void _asm_selfModify(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_MEM_UNLOCK_POINTS 20
|
||||
int global_unlock_memory_pointers[MAX_MEM_UNLOCK_POINTS]; // _asm_selfModify() sets these
|
||||
|
||||
int allow_self_modification(void) {
|
||||
int i;
|
||||
uint32_t page_start;
|
||||
|
||||
for (i = 0; i < MAX_MEM_UNLOCK_POINTS; i++)
|
||||
global_unlock_memory_pointers[i] = 0;
|
||||
|
||||
_asm_selfModify();
|
||||
|
||||
for (i = 0; i < MAX_MEM_UNLOCK_POINTS; i++)
|
||||
if (global_unlock_memory_pointers[i] != 0) {
|
||||
page_start = global_unlock_memory_pointers[i] - (global_unlock_memory_pointers[i] % getpagesize());
|
||||
mprotect((void *)page_start, getpagesize() * 2, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
// fprintf(stderr, "Unlocked memory location %x for location %x.\n",page_start, global_unlock_memory_pointers[i]);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
unsigned sndDecompM16(uint16_t *dst, const uint8_t *src, unsigned len, unsigned prev) {
|
||||
sndDecompM16_dst = dst;
|
||||
sndDecompM16_src = src;
|
||||
sndDecompM16_len = len;
|
||||
sndDecompM16_prev = prev;
|
||||
__asm__(" call _asm_sndDecompM16" : : : "%esi", "%edi", "%ebx", "cc", "memory");
|
||||
return (sndDecompM16_return);
|
||||
}
|
||||
|
||||
unsigned sndDecompS16(uint16_t *dst, const uint8_t *src, unsigned len, unsigned prev) {
|
||||
sndDecompS16_dst = dst;
|
||||
sndDecompS16_src = src;
|
||||
sndDecompS16_len = len;
|
||||
sndDecompS16_prev = prev;
|
||||
__asm__("call _asm_sndDecompS16" : : : "%esi", "%edi", "%ebx", "cc", "memory");
|
||||
return (sndDecompS16_return);
|
||||
}
|
||||
|
||||
void nfPkConfig(void) {
|
||||
__asm__("call _asm_nfPkConfig" : : : "%esi", "%edi", "%ebx", "cc", "memory");
|
||||
return;
|
||||
}
|
||||
|
||||
void nfHPkDecomp(uint8_t *ops, uint8_t *comp, uint32_t x, uint32_t y, uint32_t w,
|
||||
uint32_t h) {
|
||||
nfHPkDecomp_ops = ops;
|
||||
nfHPkDecomp_comp = comp;
|
||||
nfHPkDecomp_x = x;
|
||||
nfHPkDecomp_y = y;
|
||||
nfHPkDecomp_w = w;
|
||||
nfHPkDecomp_h = h;
|
||||
__asm__("call _asm_nfHPkDecomp" : : : "%esi", "%edi", "%ebx", "cc", "memory");
|
||||
return;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* Non-Implemented functions (from inside mveasm.cpp - AH) */
|
||||
/***********************************************************/
|
||||
|
||||
void nfHiColorDecomp(uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
void nfHiColorDecompChg(uint16_t *chgs, uint16_t *parms, uint8_t *comp, unsigned x, unsigned y,
|
||||
unsigned w, unsigned h);
|
||||
void nfDecomp(uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
void nfDecompChg(uint16_t *chgs, uint16_t *parms, uint8_t *comp, unsigned x, unsigned y, unsigned w,
|
||||
unsigned h);
|
||||
void nfPkPal(void);
|
||||
void nfPkDecomp(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
void nfPkDecompH(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
void nfPkDecompD(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
void mve_ShowFrameField(uint8_t *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
||||
unsigned h, unsigned dstx, unsigned dsty, unsigned field);
|
||||
void mve_ShowFrameFieldHi(uint8_t *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
||||
unsigned h, unsigned dstx, unsigned dsty, unsigned field);
|
||||
void mve_sfShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint16_t *chgs,
|
||||
unsigned dstx, unsigned dsty);
|
||||
void mve_sfHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint16_t *chgs,
|
||||
unsigned dstx, unsigned dsty);
|
||||
void mve_sfPkShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint8_t *ops,
|
||||
unsigned dstx, unsigned dsty);
|
||||
void mve_sfPkHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint8_t *ops,
|
||||
unsigned dstx, unsigned dsty);
|
||||
|
||||
void MVE_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
void palLoadCompPalette(uint8_t *buf);
|
||||
void gfxMode(unsigned mode);
|
||||
void gfxLoadCrtc(uint8_t *crtc, uint8_t chain4, uint8_t res);
|
||||
void gfxGetCrtc(uint8_t *crtc);
|
||||
void gfxVres(uint8_t misc, uint8_t *crtc);
|
||||
void MVE_gfxWaitRetrace(int state);
|
||||
void MVE_gfxSetSplit(unsigned line);
|
||||
|
||||
// rcg07272000
|
||||
// need this on non-Intel platforms. Intel uses int $3.
|
||||
#if (defined __i386__) || defined(__x86_64__)
|
||||
#define int3 __asm__ __volatile__("int $3");
|
||||
#else
|
||||
#define int3 raise(SIGTRAP);
|
||||
#endif
|
||||
|
||||
void nfHiColorDecomp(uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h) { int3 }
|
||||
void nfHiColorDecompChg(uint16_t *chgs, uint16_t *parms, uint8_t *comp, unsigned x, unsigned y,
|
||||
unsigned w, unsigned h) {
|
||||
int3
|
||||
}
|
||||
void nfDecomp(uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h) { int3 }
|
||||
void nfDecompChg(uint16_t *chgs, uint16_t *parms, uint8_t *comp, unsigned x, unsigned y, unsigned w,
|
||||
unsigned h) {
|
||||
int3
|
||||
}
|
||||
void nfPkPal(void) { int3 }
|
||||
void nfPkDecomp(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h) { int3 }
|
||||
void nfPkDecompH(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h) { int3 }
|
||||
void nfPkDecompD(uint8_t *ops, uint8_t *comp, unsigned x, unsigned y, unsigned w, unsigned h) { int3 }
|
||||
void mve_ShowFrameField(uint8_t *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
||||
unsigned h, unsigned dstx, unsigned dsty, unsigned field) {
|
||||
int3
|
||||
}
|
||||
void mve_ShowFrameFieldHi(uint8_t *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
||||
unsigned h, unsigned dstx, unsigned dsty, unsigned field) {
|
||||
int3
|
||||
}
|
||||
void mve_sfShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint16_t *chgs,
|
||||
unsigned dstx, unsigned dsty) {
|
||||
int3
|
||||
}
|
||||
void mve_sfHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint16_t *chgs,
|
||||
unsigned dstx, unsigned dsty) {
|
||||
int3
|
||||
}
|
||||
void mve_sfPkShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint8_t *ops,
|
||||
unsigned dstx, unsigned dsty) {
|
||||
int3
|
||||
}
|
||||
void mve_sfPkHiColorShowFrameChg(bool prvbuf, unsigned x, unsigned y, unsigned w, unsigned h, uint8_t *ops,
|
||||
unsigned dstx, unsigned dsty) {
|
||||
int3
|
||||
}
|
||||
/* Avoid name mangling issues by moving this into mvelibl.cpp - AH
|
||||
void MVE_SetPalette(uint8_t *p, unsigned start, unsigned count)
|
||||
{
|
||||
int3
|
||||
} */
|
||||
void palLoadCompPalette(uint8_t *buf) { int3 }
|
||||
void gfxMode(unsigned mode) { int3 }
|
||||
void gfxLoadCrtc(uint8_t *crtc, uint8_t chain4, uint8_t res) { int3 }
|
||||
void gfxGetCrtc(uint8_t *crtc) { int3 }
|
||||
void gfxVres(uint8_t misc, uint8_t *crtc) { int3 }
|
||||
void MVE_gfxWaitRetrace(int state) { int3 }
|
||||
void MVE_gfxSetSplit(unsigned line) { int3 }
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef DECLARE_POINTERS
|
||||
#define FEXTERN
|
||||
#else
|
||||
#define FEXTERN extern
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
|
||||
#define pthread_create sopthread_create
|
||||
#define pthread_exit sopthread_exit
|
||||
#define pthread_detach sopthread_detach
|
||||
#define pthread_self sopthread_self
|
||||
|
||||
typedef int (*pthread_create_fp)(pthread_t *__thread, __const pthread_attr_t *__attr, void *(*__start_routine)(void *),
|
||||
void *__arg);
|
||||
FEXTERN pthread_create_fp sopthread_create;
|
||||
|
||||
typedef void (*pthread_exit_fp)(void *__retval);
|
||||
FEXTERN pthread_exit_fp sopthread_exit;
|
||||
|
||||
typedef int (*pthread_detach_fp)(pthread_t __th);
|
||||
FEXTERN pthread_detach_fp sopthread_detach;
|
||||
|
||||
typedef pthread_t (*pthread_self_fp)(void);
|
||||
FEXTERN pthread_self_fp sopthread_self;
|
||||
|
||||
#ifndef DECLARE_POINTERS
|
||||
bool LoadPThreadLib(bool load = true);
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
void LoadPThreadLibSetNULL(void) {
|
||||
sopthread_create = NULL;
|
||||
sopthread_exit = NULL;
|
||||
sopthread_detach = NULL;
|
||||
sopthread_self = NULL;
|
||||
}
|
||||
|
||||
bool LoadPThreadLib(bool load) {
|
||||
#define PTHREADLIB "libpthread.so"
|
||||
static void *handle = NULL;
|
||||
|
||||
if (!load) {
|
||||
LoadPThreadLibSetNULL();
|
||||
if (handle) {
|
||||
dlclose(handle);
|
||||
handle = NULL;
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr, "Library Unload Failed: %s\n", PTHREADLIB);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (handle)
|
||||
return true;
|
||||
|
||||
// Load the library
|
||||
handle = dlopen(PTHREADLIB, RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "Library Load Failed: %s\n", PTHREADLIB);
|
||||
return false;
|
||||
}
|
||||
|
||||
sopthread_create = (pthread_create_fp)dlsym(handle, "pthread_create");
|
||||
if (!sopthread_create)
|
||||
goto load_error;
|
||||
|
||||
sopthread_exit = (pthread_exit_fp)dlsym(handle, "pthread_exit");
|
||||
if (!sopthread_exit)
|
||||
goto load_error;
|
||||
|
||||
sopthread_detach = (pthread_detach_fp)dlsym(handle, "pthread_detach");
|
||||
if (!sopthread_detach)
|
||||
goto load_error;
|
||||
|
||||
sopthread_self = (pthread_self_fp)dlsym(handle, "pthread_self");
|
||||
if (!sopthread_self)
|
||||
goto load_error;
|
||||
|
||||
return true;
|
||||
|
||||
load_error:
|
||||
LoadPThreadLibSetNULL();
|
||||
fprintf(stderr, "Library Symbol Resolve Error: %s\n", PTHREADLIB);
|
||||
dlclose(handle);
|
||||
handle = NULL;
|
||||
return false;
|
||||
}
|
||||
#endif
|
@ -1,781 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <errno.h>
|
||||
#include "linux/lnxdraw.h"
|
||||
#include "lnxscreenmode.h"
|
||||
|
||||
// static Display *lpDisplay = NULL;
|
||||
static int nDefaultScreen = -1;
|
||||
static uint32_t dwOriginalWidth, dwOriginalHeight;
|
||||
static LnxWindow **WindowList;
|
||||
static int NumWindows = 0;
|
||||
// static int GetXSharedMemory(int size);
|
||||
inline void BltBuffer16ToPixMap24(uint8_t *pixmap, uint8_t *buffer, int width, int height);
|
||||
inline void BltBuffer32ToPixMap24(uint8_t *pixmap, uint8_t *buffer, int width, int height);
|
||||
inline void BltBuffer16ToPixMap16(uint8_t *pixmap, uint8_t *buffer, int width, int height);
|
||||
inline void BltBuffer32ToPixMap16(uint8_t *pixmap, uint8_t *buffer, int width, int height);
|
||||
|
||||
static SDL_Rect dispSize;
|
||||
|
||||
//////////////////////
|
||||
// LnxDraw_InitVideo
|
||||
//////////////////////
|
||||
// Initializes the Linux video system (for X-Windows)
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameter
|
||||
// -2 : already initialized
|
||||
int LnxDraw_InitVideo(LnxVideoDesc *ldesc) {
|
||||
return -1;
|
||||
if (!ldesc)
|
||||
return -1;
|
||||
// if(lpDisplay)
|
||||
// return -2;
|
||||
|
||||
// lpDisplay = ldesc->dDisplay;
|
||||
// nDefaultScreen = ldesc->nScreen;
|
||||
|
||||
// dwOriginalWidth = DisplayWidth(lpDisplay,nDefaultScreen);
|
||||
// dwOriginalHeight = DisplayHeight(lpDisplay,nDefaultScreen);
|
||||
|
||||
memset(&dispSize, '\0', sizeof(dispSize));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDLCALL d3SDLEventFilter(void *userdata, SDL_Event *event);
|
||||
|
||||
/////////////////////////
|
||||
// LnxDraw_CreateWindow
|
||||
/////////////////////////
|
||||
// Creates and displays a window
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error (handle in lphandle)
|
||||
// -1 : invalid parameter
|
||||
// -2 : Display not opened
|
||||
// -3 : Out of memory
|
||||
int LnxDraw_CreateWindow(LnxWindowDesc *ldesc, LnxWindow **lphandle) {
|
||||
#if 1
|
||||
SDL_Log("!!! FIXME no movie window %s:%d\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
#else
|
||||
if (!ldesc || !lphandle)
|
||||
return -1;
|
||||
*lphandle = NULL;
|
||||
|
||||
// rcg09182000 don't need to quitsubsystem anymore...
|
||||
// SDL_QuitSubSystem(SDL_INIT_VIDEO); // here goes nothing...
|
||||
SDL_ClearError();
|
||||
int rc = SDL_Init(SDL_INIT_VIDEO);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "SDL: SDL_Init() failed! rc == (%d).\n", rc);
|
||||
fprintf(stderr, "SDL_GetError() reports \"%s\".\n", SDL_GetError());
|
||||
return (-2);
|
||||
} // if
|
||||
SDL_SetEventFilter(d3SDLEventFilter, NULL);
|
||||
|
||||
SDL_Rect **modes = LinuxVideoMode.getModes();
|
||||
Uint32 sdlflags = LinuxVideoMode.getSDLFlags();
|
||||
|
||||
// if(!lpDisplay)
|
||||
// return -2;
|
||||
|
||||
// determine what we have to work with (currently)
|
||||
// uint32_t display_width,display_height;
|
||||
// display_width = DisplayWidth(lpDisplay,nDefaultScreen);
|
||||
// display_height = DisplayHeight(lpDisplay,nDefaultScreen);
|
||||
|
||||
// allocate a window for use
|
||||
LnxWindow *wnd;
|
||||
wnd = (LnxWindow *)malloc(sizeof(*wnd));
|
||||
if (!wnd) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
dispSize.x = dispSize.y = 0;
|
||||
dispSize.w = ldesc->dwWidth;
|
||||
dispSize.h = ldesc->dwHeight;
|
||||
|
||||
// need these two lines for a Voodoo3 bug.
|
||||
SDL_ShowCursor(0);
|
||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
||||
|
||||
wnd->surface = SDL_SetVideoMode(ldesc->dwWidth, ldesc->dwHeight, ldesc->bpp, sdlflags);
|
||||
|
||||
// failed? Try a window.
|
||||
if ((wnd->surface == NULL) && (sdlflags & SDL_FULLSCREEN)) {
|
||||
sdlflags &= ~SDL_FULLSCREEN;
|
||||
wnd->surface = SDL_SetVideoMode(ldesc->dwWidth, ldesc->dwHeight, ldesc->bpp, sdlflags);
|
||||
} // if
|
||||
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
if (!(sdlflags & SDL_FULLSCREEN))
|
||||
SDL_ShowCursor(1);
|
||||
|
||||
if (wnd->surface == NULL) {
|
||||
fprintf(stderr, "ERROR: SDL could not set the video mode!\n");
|
||||
return -3;
|
||||
} // if
|
||||
|
||||
wnd->fullScreen = (sdlflags & SDL_FULLSCREEN) ? true : false;
|
||||
|
||||
SDL_WM_SetCaption("Descent 3", NULL);
|
||||
|
||||
/*
|
||||
wnd->WindowPreCreated = (ldesc->dwFlags&LNXDRAWF_USEPRECREATEDWIN)?true:false;
|
||||
|
||||
if(!wnd->WindowPreCreated)
|
||||
{
|
||||
// allocate what the hints, etc.
|
||||
wnd->lpSizeHints = XAllocSizeHints();
|
||||
if(!wnd->lpSizeHints)
|
||||
{
|
||||
// TODO: Free above allocated hints
|
||||
free(wnd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
wnd->lpWmHints = XAllocWMHints();
|
||||
if(!wnd->lpWmHints)
|
||||
{
|
||||
// TODO: Free above allocated hints
|
||||
free(wnd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
wnd->lpClassHints = XAllocClassHint();
|
||||
if(!wnd->lpClassHints)
|
||||
{
|
||||
// TODO: Free above allocated hints
|
||||
free(wnd);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
// try to match a visual
|
||||
if (!XMatchVisualInfo(lpDisplay,nDefaultScreen,16,TrueColor,&wnd->viVisualInfo))
|
||||
{
|
||||
fprintf(stderr,"Error: Unable to get 16bit TrueColor Visual\n");
|
||||
|
||||
// TODO: Free above allocated hints
|
||||
free(wnd);
|
||||
return -3;
|
||||
}
|
||||
|
||||
// see if we have shared memory available
|
||||
wnd->bHaveSharedMemory = (bool)(XShmQueryExtension(lpDisplay)!=0);
|
||||
wnd->shmInfo.shmaddr = NULL;
|
||||
|
||||
// even if the display says it has shared memory, it still might not be
|
||||
// available (if we are not running on a local connection)
|
||||
if(wnd->bHaveSharedMemory)
|
||||
{
|
||||
char *ptr;
|
||||
char *displayname = (char *)getenv("DISPLAY");
|
||||
if (displayname)
|
||||
{
|
||||
ptr = displayname;
|
||||
while (*ptr && (*ptr != ':')) ptr++;
|
||||
if (*ptr) *ptr = '\0';
|
||||
if (!(!strcasecmp(displayname, "unix") || !*displayname))
|
||||
wnd->bHaveSharedMemory = false;
|
||||
}else
|
||||
wnd->bHaveSharedMemory = false;
|
||||
}
|
||||
//fprintf(stdout,"Shared Memory: %savailable\n",wnd->bHaveSharedMemory?"":"Not ");
|
||||
|
||||
if(!wnd->WindowPreCreated)
|
||||
{
|
||||
wnd->lpXvisual = wnd->viVisualInfo.visual;
|
||||
wnd->cmColorMap = DefaultColormapOfScreen(DefaultScreenOfDisplay(lpDisplay));
|
||||
|
||||
uint32_t attrib_mask;
|
||||
XSetWindowAttributes attrib;
|
||||
|
||||
// setup some attribute and hints for actual window creation
|
||||
attrib_mask = CWEventMask | CWColormap | CWBorderPixel;
|
||||
attrib.event_mask = KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
||||
ButtonPressMask | ButtonReleaseMask | ExposureMask;
|
||||
attrib.colormap = wnd->cmColorMap;
|
||||
attrib.border_pixel = 0;
|
||||
|
||||
wnd->lpSizeHints->width = ldesc->dwWidth;
|
||||
wnd->lpSizeHints->height = ldesc->dwHeight;
|
||||
wnd->lpSizeHints->min_width = ldesc->dwWidth;
|
||||
wnd->lpSizeHints->max_width = ldesc->dwWidth;
|
||||
wnd->lpSizeHints->min_height = ldesc->dwHeight;
|
||||
wnd->lpSizeHints->max_height = ldesc->dwHeight;
|
||||
wnd->lpSizeHints->x = ldesc->dwXPos;
|
||||
wnd->lpSizeHints->y = ldesc->dwYPos;
|
||||
wnd->lpSizeHints->flags |= USSize | PMinSize | PMaxSize | USPosition;
|
||||
|
||||
wnd->wWindow = XCreateWindow(lpDisplay,RootWindow(lpDisplay,nDefaultScreen),
|
||||
ldesc->dwXPos,ldesc->dwYPos,
|
||||
ldesc->dwWidth,ldesc->dwHeight,
|
||||
0,
|
||||
wnd->viVisualInfo.depth,
|
||||
InputOutput,
|
||||
wnd->lpXvisual,
|
||||
attrib_mask,
|
||||
&attrib);
|
||||
|
||||
XStoreName(lpDisplay,wnd->wWindow,ldesc->lpszName);
|
||||
XSetIconName(lpDisplay,wnd->wWindow,ldesc->lpszName);
|
||||
XSetWMNormalHints(lpDisplay,wnd->wWindow,wnd->lpSizeHints);
|
||||
|
||||
// Display the window!
|
||||
XMapWindow(lpDisplay,wnd->wWindow);
|
||||
|
||||
// Wait until it is actually visible
|
||||
bool wait_for_draw = false;
|
||||
XEvent event;
|
||||
while (!wait_for_draw)
|
||||
{
|
||||
XNextEvent(lpDisplay, &event);
|
||||
if (event.type == Expose && !event.xexpose.count) wait_for_draw = true;
|
||||
}
|
||||
}else
|
||||
{
|
||||
wnd->wWindow = *ldesc->pre_created_window;
|
||||
|
||||
// resize window and stuff here
|
||||
wnd->viVisualInfo = ldesc->pre_created_visinfo;
|
||||
wnd->lpXvisual = wnd->viVisualInfo.visual;
|
||||
wnd->cmColorMap = DefaultColormapOfScreen(DefaultScreenOfDisplay(lpDisplay));
|
||||
}
|
||||
*/
|
||||
|
||||
// We're done, add it to our Window list
|
||||
WindowList = (LnxWindow **)realloc(WindowList, sizeof(LnxWindow *) * (NumWindows + 1));
|
||||
if (!WindowList) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
WindowList[NumWindows] = wnd;
|
||||
*lphandle = wnd;
|
||||
NumWindows++;
|
||||
|
||||
// Setup window for blitting
|
||||
wnd->bLocked = false;
|
||||
wnd->dwWidth = ldesc->dwWidth;
|
||||
wnd->dwHeight = ldesc->dwHeight;
|
||||
|
||||
// Create the Graphics Context
|
||||
// int valuemask;
|
||||
// XGCValues xgcvalues;
|
||||
// xgcvalues.graphics_exposures = False;
|
||||
// valuemask = GCGraphicsExposures;
|
||||
|
||||
// wnd->m_GC = XCreateGC(lpDisplay,wnd->wWindow,valuemask,&xgcvalues);
|
||||
// wnd->lock_ptr = (uint8_t *)malloc(wnd->dwWidth*wnd->dwHeight<<1);
|
||||
|
||||
// int id = GetXSharedMemory(wnd->dwWidth*wnd->dwHeight<<1);
|
||||
// if(id<0)
|
||||
// {
|
||||
// wnd->bHaveSharedMemory = false;
|
||||
// wnd->shmInfo.shmaddr = NULL;
|
||||
// }else
|
||||
// {
|
||||
// // attach
|
||||
// wnd->shmInfo.shmid = id;
|
||||
// wnd->shmInfo.shmaddr = (char *)shmat(id, 0, 0);
|
||||
// }
|
||||
|
||||
// fprintf(stdout,"Draw: %s shared memory\n",(wnd->bHaveSharedMemory)?"Using":"Not Using");
|
||||
|
||||
// Initial clear
|
||||
uint8_t *lock_ptr;
|
||||
int lock_pitch;
|
||||
if (LnxDraw_LockSurface(wnd, 0, 0, wnd->dwWidth - 1, wnd->dwHeight - 1, &lock_ptr, &lock_pitch)) {
|
||||
memset(lock_ptr, 0, wnd->dwWidth * wnd->dwHeight << 1);
|
||||
LnxDraw_UnlockSurface(wnd, lock_ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// LnxDraw_DestroyWindow
|
||||
//////////////////////////
|
||||
// Closes and deletes a window
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameter
|
||||
int LnxDraw_DestroyWindow(LnxWindow *handle) {
|
||||
#if 1
|
||||
SDL_Log("!!! FIXME no movie window %s:%d\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
#else
|
||||
int i;
|
||||
LnxWindow *wnd = NULL;
|
||||
|
||||
for (i = 0; i < NumWindows; i++) {
|
||||
if (WindowList[i] == handle) {
|
||||
wnd = handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wnd)
|
||||
return -1;
|
||||
|
||||
WindowList[i] = WindowList[NumWindows - 1];
|
||||
WindowList = (LnxWindow **)realloc(WindowList, sizeof(LnxWindow *) * (NumWindows - 1));
|
||||
NumWindows--;
|
||||
|
||||
/*
|
||||
if(wnd->shmInfo.shmaddr)
|
||||
{
|
||||
// Release shared memory.
|
||||
shmdt(wnd->shmInfo.shmaddr);
|
||||
shmctl(wnd->shmInfo.shmid, IPC_RMID, 0);
|
||||
}
|
||||
|
||||
if(!wnd->WindowPreCreated)
|
||||
{
|
||||
// Do what we need to do to close the window
|
||||
XDestroyWindow(lpDisplay,wnd->wWindow);
|
||||
|
||||
XFree(wnd->lpSizeHints);
|
||||
XFree(wnd->lpWmHints);
|
||||
XFree(wnd->lpClassHints);
|
||||
}
|
||||
|
||||
free(wnd->lock_ptr);
|
||||
*/
|
||||
|
||||
if (wnd->fullScreen) {
|
||||
SDL_WM_ToggleFullScreen(wnd->surface);
|
||||
SDL_ShowCursor(1);
|
||||
} // if
|
||||
|
||||
free(wnd);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// LnxDraw_LockSurface
|
||||
////////////////////////
|
||||
// Locks the window surface, giving you a pointer to write data to
|
||||
//
|
||||
// Returns:
|
||||
// true : success
|
||||
// false : error
|
||||
bool LnxDraw_LockSurface(LnxWindow *wnd, unsigned x1, unsigned y1, unsigned x2, unsigned y2, uint8_t **ptr,
|
||||
int *pitch) {
|
||||
#if 1
|
||||
SDL_Log("!!! FIXME no movie window %s:%d\n", __FILE__, __LINE__);
|
||||
return false;
|
||||
#else
|
||||
return -1;
|
||||
if (!wnd || !ptr || !pitch)
|
||||
return false;
|
||||
if (wnd->bLocked)
|
||||
return false;
|
||||
wnd->bLocked = true;
|
||||
|
||||
*pitch = wnd->dwWidth << 1;
|
||||
|
||||
/*
|
||||
int w,h;
|
||||
if(x2<x1){ int t; t = x2; x2=x1; x1=t;}
|
||||
if(y2<y2){ int t; t = y2; y2=y1; y1=t;}
|
||||
w = x2 - x1 + 1;
|
||||
h = y2 - y1 + 1;
|
||||
|
||||
try_no_shared:
|
||||
|
||||
if(wnd->bHaveSharedMemory)
|
||||
{
|
||||
wnd->lpImage =
|
||||
XShmCreateImage(lpDisplay,wnd->lpXvisual,wnd->viVisualInfo.depth,ZPixmap,0,&wnd->shmInfo,wnd->dwWidth,h);
|
||||
wnd->lpImage->bitmap_bit_order = LSBFirst;
|
||||
wnd->lpImage->byte_order = LSBFirst;
|
||||
wnd->lpImage->bits_per_pixel = 16;
|
||||
wnd->lpImage->bytes_per_line = wnd->dwWidth<<1;
|
||||
wnd->lpImage->red_mask = wnd->lpXvisual->red_mask;
|
||||
wnd->lpImage->green_mask = wnd->lpXvisual->green_mask;
|
||||
wnd->lpImage->blue_mask = wnd->lpXvisual->blue_mask;
|
||||
wnd->lpImage->data = wnd->shmInfo.shmaddr;
|
||||
|
||||
if(!wnd->lpImage->data)
|
||||
{
|
||||
wnd->bHaveSharedMemory = false;
|
||||
//fprintf(stderr,"Shared Memory: Invalid Memory\n");
|
||||
goto try_no_shared;
|
||||
}
|
||||
|
||||
// attach the X server to it
|
||||
wnd->shmInfo.readOnly = False;
|
||||
if(!XShmAttach(lpDisplay,&wnd->shmInfo))
|
||||
{
|
||||
wnd->bHaveSharedMemory = false;
|
||||
//fprintf(stderr,"Shared Memory: Unable to attach to server\n");
|
||||
goto try_no_shared;
|
||||
}
|
||||
}else
|
||||
{
|
||||
wnd->lpImage = XCreateImage(lpDisplay,wnd->lpXvisual,wnd->viVisualInfo.depth,ZPixmap,0,(char
|
||||
*)wnd->lock_ptr,wnd->dwWidth,h,16,0); wnd->lpImage->bitmap_bit_order = LSBFirst; wnd->lpImage->byte_order = LSBFirst;
|
||||
wnd->lpImage->bits_per_pixel = 16;
|
||||
wnd->lpImage->bytes_per_line = wnd->dwWidth<<1;
|
||||
wnd->lpImage->red_mask = wnd->lpXvisual->red_mask;
|
||||
wnd->lpImage->green_mask = wnd->lpXvisual->green_mask;
|
||||
wnd->lpImage->blue_mask = wnd->lpXvisual->blue_mask;
|
||||
wnd->lpImage->data = (char *)wnd->lock_ptr;
|
||||
}
|
||||
|
||||
*ptr = (uint8_t *)wnd->lpImage->data;
|
||||
wnd->lock_x = x1;
|
||||
wnd->lock_y = y1;
|
||||
wnd->lock_w = w;
|
||||
wnd->lock_h = h;
|
||||
*/
|
||||
|
||||
if (SDL_MUSTLOCK(wnd->surface)) {
|
||||
if (SDL_LockSurface(wnd->surface) < 0)
|
||||
return (false);
|
||||
} // if
|
||||
|
||||
int imgHeight = y2 - y1;
|
||||
int linesDown = (wnd->dwHeight - imgHeight) / 2;
|
||||
|
||||
*ptr = ((uint8_t *)wnd->surface->pixels) + ((wnd->surface->format->BytesPerPixel * wnd->dwWidth) * linesDown);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// LnxDraw_UnlockSurface
|
||||
//////////////////////////
|
||||
// Unlocks the window surface, blitting the buffer
|
||||
//
|
||||
void LnxDraw_UnlockSurface(LnxWindow *wnd, uint8_t *ptr) {
|
||||
#if 1
|
||||
SDL_Log("!!! FIXME no movie window %s:%d\n", __FILE__, __LINE__);
|
||||
#else
|
||||
if (!wnd->bLocked)
|
||||
return;
|
||||
bool still_have_shared = true;
|
||||
wnd->bLocked = false;
|
||||
|
||||
/*
|
||||
// blit the region
|
||||
if(wnd->bHaveSharedMemory)
|
||||
{
|
||||
if(!XShmPutImage(lpDisplay,wnd->wWindow,wnd->m_GC,wnd->lpImage,0,0,wnd->lock_x,wnd->lock_y,wnd->lock_w,wnd->lock_h,True))
|
||||
{
|
||||
//fprintf(stderr,"XShmPutImage: blit failed\n");
|
||||
wnd->bHaveSharedMemory = false;
|
||||
}
|
||||
// Detach from X server
|
||||
XShmDetach(lpDisplay,&wnd->shmInfo);
|
||||
}else
|
||||
{
|
||||
// draw the image
|
||||
if(XPutImage(lpDisplay,wnd->wWindow,wnd->m_GC,wnd->lpImage,0,0,wnd->lock_x,wnd->lock_y,wnd->lock_w,wnd->lock_h))
|
||||
{
|
||||
//fprintf(stderr,"XPutImage: blit failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
// sync up with server
|
||||
XSync(lpDisplay, False);
|
||||
|
||||
// Kill the memory
|
||||
wnd->lpImage->data = NULL;//make sure we don't delete our memory here
|
||||
XDestroyImage(wnd->lpImage);
|
||||
*/
|
||||
|
||||
if (SDL_MUSTLOCK(wnd->surface))
|
||||
SDL_UnlockSurface(wnd->surface);
|
||||
|
||||
SDL_UpdateRect(wnd->surface, 0, 0, wnd->dwWidth, wnd->dwHeight);
|
||||
|
||||
#ifdef __DUMP_MVE_TO_DISK
|
||||
static uint32_t framenum = 0;
|
||||
char filename[100];
|
||||
snprintf(filename, sizeof(filename), "./mve/frame%lu.bmp", framenum);
|
||||
SDL_SaveBMP(wnd->surface, filename);
|
||||
framenum++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
/// LnxDraw_Blit
|
||||
////////////////////////////
|
||||
// Blits a buffer to the window
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameter
|
||||
// -2 : unknown error
|
||||
int LnxDraw_Blit(LnxWindow *wnd, uint8_t *ptr, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
|
||||
return 0;
|
||||
/*
|
||||
if(!wnd || !ptr)
|
||||
return -1;
|
||||
|
||||
//blt to pixmap
|
||||
if(wnd->viVisualInfo.depth==16)
|
||||
{
|
||||
//check for best case
|
||||
if(x==0 && y==0 && w==wnd->dwWidth && h==wnd->dwHeight)
|
||||
{
|
||||
BltBuffer16ToPixMap16((uint8_t *)wnd->lpImage->data,ptr,wnd->dwWidth,wnd->dwHeight);
|
||||
}else
|
||||
{
|
||||
int num_rows_to_blit;
|
||||
int start_row,pitch;
|
||||
uint8_t *curr_dest,*curr_src;
|
||||
|
||||
pitch = wnd->dwWidth<<1;
|
||||
curr_dest = (uint8_t *)wnd->lpImage->data + (y*pitch) + (x<<1);
|
||||
curr_src = ptr;
|
||||
num_rows_to_blit = h;
|
||||
|
||||
// blit away
|
||||
while(num_rows_to_blit>0)
|
||||
{
|
||||
BltBuffer16ToPixMap16(curr_dest,curr_src,w,1);
|
||||
|
||||
num_rows_to_blit--;
|
||||
curr_dest += pitch;
|
||||
curr_src += pitch;
|
||||
}
|
||||
}
|
||||
}else
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//Update window
|
||||
if(wnd->bHaveSharedMemory)
|
||||
{
|
||||
if(!XShmPutImage(lpDisplay,wnd->wWindow,wnd->m_GC,wnd->lpImage,0, 0, 0,
|
||||
0,wnd->dwWidth,wnd->dwHeight,True))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}else
|
||||
{
|
||||
// draw the image
|
||||
XPutImage(lpDisplay,wnd->wWindow,wnd->m_GC,wnd->lpImage,0, 0,0,0,wnd->dwWidth,wnd->dwHeight);
|
||||
}
|
||||
|
||||
// sync up with server
|
||||
XSync(lpDisplay, False);
|
||||
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// LnxDraw_GetRGBMasks
|
||||
////////////////////////
|
||||
// Returns the RGB masks for the display
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxDraw_GetRGBMasks(LnxWindow *wnd, uint32_t *r, uint32_t *g, uint32_t *b) {
|
||||
return -1;
|
||||
if (!wnd || !r || !g || !b)
|
||||
return -1;
|
||||
/*
|
||||
*r = wnd->lpImage->red_mask;
|
||||
*g = wnd->lpImage->green_mask;
|
||||
*b = wnd->lpImage->blue_mask;
|
||||
*/
|
||||
|
||||
SDL_PixelFormat *pixelFmt = wnd->surface->format;
|
||||
|
||||
*r = pixelFmt->Rmask;
|
||||
*g = pixelFmt->Gmask;
|
||||
*b = pixelFmt->Bmask;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int GetXSharedMemory(int size) {
|
||||
/*
|
||||
int key = (14<<24)|(70<<16)|(81<<8)|49;
|
||||
struct shmid_ds shminfo;
|
||||
int minsize = 640*480;
|
||||
int id;
|
||||
int rc;
|
||||
int num_try=5;
|
||||
|
||||
do
|
||||
{
|
||||
//try to get the id
|
||||
id = shmget((key_t) key, minsize,0x1FF);
|
||||
|
||||
if(id!=-1)
|
||||
{
|
||||
rc = shmctl(id, IPC_STAT, &shminfo);
|
||||
if(!rc)
|
||||
{
|
||||
if(shminfo.shm_nattch)
|
||||
{
|
||||
key++;
|
||||
}else
|
||||
{
|
||||
if(getuid()==shminfo.shm_perm.cuid)
|
||||
{
|
||||
rc = shmctl(id,IPC_RMID,0);
|
||||
if(!rc)
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Stale memory killed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Unable to kill stale
|
||||
memory\n"); return -2;
|
||||
}
|
||||
|
||||
id = shmget((key_t)key,size,IPC_CREAT|0x1FF);
|
||||
if(id==-1)
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Unable to create shared
|
||||
memory block (size=%d)\n",size); return -2;
|
||||
}
|
||||
|
||||
rc=shmctl(id,IPC_STAT,&shminfo);
|
||||
break;
|
||||
}
|
||||
|
||||
if(size>=shminfo.shm_segsz)
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Using User %d's shared
|
||||
memory\n",shminfo.shm_cpid); break; }else
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Stale memory (User %d, Key=0x%x) is
|
||||
too small\n",shminfo.shm_cpid,key); key++;
|
||||
}
|
||||
}
|
||||
}else
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Unable to read stats on 0x%x\n",key);
|
||||
return -2;
|
||||
}
|
||||
}else
|
||||
{
|
||||
id = shmget((key_t)key,size,IPC_CREAT|0x1FF);
|
||||
if(id==-1)
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Unable to get shared memory (error = %d)\n",errno);
|
||||
return -2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}while (--num_try);
|
||||
|
||||
if(num_try == 0)
|
||||
{
|
||||
//fprintf(stderr,"Shared Memory: Unable to get shared memory (too many stale shared memory
|
||||
segments)\n");
|
||||
}
|
||||
|
||||
return id;
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
inline void BltBuffer32ToPixMap16(uint8_t *pixmap, uint8_t *buffer, int width, int height) {
|
||||
uint8_t *data;
|
||||
uint16_t int l;
|
||||
int r, g, b, a;
|
||||
uint32_t c;
|
||||
|
||||
data = (uint8_t *)pixmap;
|
||||
for (l = height * width; l > 0; l--) {
|
||||
c = *(uint32_t *)buffer;
|
||||
a = ((c & 0xff000000) >> 24);
|
||||
r = ((c & 0x00ff0000) >> 16);
|
||||
g = ((c & 0x0000ff00) >> 8);
|
||||
b = (c & 0x000000ff);
|
||||
|
||||
if (a)
|
||||
*(uint32_t *)data = (((r >> 3) << 10) + ((g >> 3) << 5) + (b >> 3));
|
||||
data += 2;
|
||||
buffer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
inline void BltBuffer16ToPixMap16(uint8_t *pixmap, uint8_t *buffer, int width, int height) {
|
||||
uint8_t *data;
|
||||
data = (uint8_t *)pixmap;
|
||||
memcpy(data, buffer, (width * height) << 1);
|
||||
}
|
||||
|
||||
inline void BltBuffer32ToPixMap24(uint8_t *pixmap, uint8_t *buffer, int width, int height) {
|
||||
uint8_t *data;
|
||||
uint16_t int l;
|
||||
int r, g, b, a;
|
||||
uint32_t c;
|
||||
|
||||
data = (uint8_t *)pixmap;
|
||||
for (l = height * width; l > 0; l--) {
|
||||
c = *(uint32_t *)buffer;
|
||||
a = ((c & 0xff000000) >> 24);
|
||||
r = ((c & 0x00ff0000) >> 16);
|
||||
g = ((c & 0x0000ff00) >> 8);
|
||||
b = (c & 0x000000ff);
|
||||
|
||||
if (a)
|
||||
*(uint32_t *)data = ((r << 16) + (g << 8) + b);
|
||||
data += 4;
|
||||
buffer += 4;
|
||||
}
|
||||
}
|
||||
|
||||
inline void BltBuffer16ToPixMap24(uint8_t *pixmap, uint8_t *buffer, int width, int height) {
|
||||
uint8_t *data;
|
||||
uint16_t int l;
|
||||
int r, g, b, a;
|
||||
uint16_t c;
|
||||
|
||||
data = (uint8_t *)pixmap;
|
||||
for (l = height * width; l > 0; l--) {
|
||||
c = *(uint16_t *)buffer;
|
||||
a = ((c & 0x8000) >> 15);
|
||||
r = ((c & 0x7C00) >> 10);
|
||||
g = ((c & 0x03E0) >> 5);
|
||||
b = (c & 0x001F);
|
||||
|
||||
if (a)
|
||||
*(uint32_t *)data = ((r << 19) + (g << 11) + (b << 3));
|
||||
data += 4;
|
||||
buffer += 2;
|
||||
}
|
||||
}
|
@ -1,770 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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 <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
// #include "dyna_pthread.h"//threads
|
||||
#include "linux/lnxdsound.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_audio.h"
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#define FRAGMENT_LENGTH (LnxBuffers[0]->bps >> 4)
|
||||
#define FREQUENCY_SHIFT (14)
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* * Might be wise to use mutex's for the enter/exit critical functions
|
||||
*/
|
||||
static int LnxNumBuffers = 0;
|
||||
static LnxSoundBuffer **LnxBuffers = NULL;
|
||||
static LnxSoundDevice LinuxSoundDevice;
|
||||
|
||||
static bool StartupSoundSystem(LnxSoundDevice *dev);
|
||||
static void ShutdownSoundSystem(void);
|
||||
static void LinuxSoundMixWithVolume(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len);
|
||||
static uint32_t LinuxSoundMixNormalize(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len);
|
||||
static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len);
|
||||
static void LinuxSoundMixBuffersIntoMain(int len);
|
||||
static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len);
|
||||
|
||||
static inline void enter_critical(void) { SDL_LockAudio(); }
|
||||
|
||||
static inline void exit_critical(void) { SDL_UnlockAudio(); }
|
||||
|
||||
///////////////////////////////
|
||||
// LnxSound_CreateSoundBuffer
|
||||
///////////////////////////////
|
||||
// Creates a sound buffer to be used with mixing and output.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// -2 : Out of memory
|
||||
// 0 : Ok!
|
||||
int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSoundBuffer **lsndb) {
|
||||
WAVEFORMATEX *wfex;
|
||||
|
||||
if (!lbdesc || !lsndb || !dev)
|
||||
return -1;
|
||||
|
||||
wfex = lbdesc->lpwfxFormat;
|
||||
if (!wfex)
|
||||
return -1;
|
||||
|
||||
// Check to see if we have a primary buffer yet, if not, create it
|
||||
// now
|
||||
if (lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
if (LnxNumBuffers != 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (LnxNumBuffers == 0) {
|
||||
// we need to create a primary buffer
|
||||
LnxSoundBuffer *primary;
|
||||
LnxBufferDesc primdesc;
|
||||
WAVEFORMATEX wf;
|
||||
|
||||
memset(&primdesc, 0, sizeof(LnxBufferDesc));
|
||||
memset(&wf, 0, sizeof(wf));
|
||||
|
||||
primdesc.dwBufferBytes = 0;
|
||||
primdesc.dwFlags = LNXSND_CAPS_PRIMARYBUFFER;
|
||||
primdesc.lpwfxFormat = &wf;
|
||||
|
||||
int ret = LnxSound_CreateSoundBuffer(dev, &primdesc, &primary);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
*lsndb = (LnxSoundBuffer *)malloc(sizeof(LnxSoundBuffer));
|
||||
if (!(*lsndb))
|
||||
return -2;
|
||||
memset(*lsndb, 0, sizeof(LnxSoundBuffer));
|
||||
|
||||
if (lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
(*lsndb)->buffer_len = dev->bps;
|
||||
(*lsndb)->freq = dev->freq;
|
||||
(*lsndb)->bps = dev->bps;
|
||||
(*lsndb)->buffer = NULL;
|
||||
} else {
|
||||
(*lsndb)->buffer_len = lbdesc->dwBufferBytes;
|
||||
(*lsndb)->freq = lbdesc->lpwfxFormat->nSamplesPerSec;
|
||||
|
||||
(*lsndb)->buffer = (uint8_t *)malloc((*lsndb)->buffer_len);
|
||||
if (!(*lsndb)->buffer) {
|
||||
free(*lsndb);
|
||||
*lsndb = NULL;
|
||||
return -2;
|
||||
}
|
||||
memset((*lsndb)->buffer, 0, (*lsndb)->buffer_len);
|
||||
}
|
||||
|
||||
(*lsndb)->play_cursor = 0;
|
||||
(*lsndb)->write_cursor = 0;
|
||||
(*lsndb)->playing = 0;
|
||||
(*lsndb)->left_vol = (1 << 15);
|
||||
(*lsndb)->right_vol = (1 << 15);
|
||||
|
||||
if (!(lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
(*lsndb)->freq_adjustment = ((*lsndb)->freq << FREQUENCY_SHIFT) / LnxBuffers[0]->freq;
|
||||
(*lsndb)->bps = (*lsndb)->freq * lbdesc->lpwfxFormat->nBlockAlign;
|
||||
}
|
||||
|
||||
memcpy(&((*lsndb)->lbdesc), lbdesc, sizeof(LnxBufferDesc));
|
||||
|
||||
if (!(lbdesc->dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
memcpy(&((*lsndb)->wfx), lbdesc->lpwfxFormat, sizeof(WAVEFORMATEX));
|
||||
} else {
|
||||
// set up the wave format based on the device settings (primary)
|
||||
(*lsndb)->wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
(*lsndb)->wfx.nChannels = dev->channels;
|
||||
(*lsndb)->wfx.nSamplesPerSec = dev->freq;
|
||||
(*lsndb)->wfx.nBlockAlign = dev->channels * (dev->bit_depth / 8);
|
||||
(*lsndb)->wfx.nAvgBytesPerSec = dev->freq * (*lsndb)->wfx.nBlockAlign;
|
||||
(*lsndb)->wfx.wBitsPerSample = dev->bit_depth;
|
||||
(*lsndb)->wfx.cbSize = 0;
|
||||
}
|
||||
|
||||
if (LnxBuffers) {
|
||||
enter_critical();
|
||||
LnxBuffers = (LnxSoundBuffer **)realloc(LnxBuffers, sizeof(LnxSoundBuffer *) * (LnxNumBuffers + 1));
|
||||
LnxBuffers[LnxNumBuffers] = *lsndb;
|
||||
LnxNumBuffers++;
|
||||
exit_critical();
|
||||
} else {
|
||||
LnxBuffers = (LnxSoundBuffer **)malloc(sizeof(LnxSoundBuffer *));
|
||||
LnxBuffers[0] = *lsndb;
|
||||
LnxNumBuffers++;
|
||||
|
||||
// Initialize the Sound system and thread
|
||||
StartupSoundSystem(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_Release
|
||||
////////////////////////////
|
||||
// Releases the memory associated with a sound buffer. This pointer is
|
||||
// no longer valid after return.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// 0 : Ok!
|
||||
int LnxSoundBuffer_Release(LnxSoundBuffer *buff) {
|
||||
int i;
|
||||
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < LnxNumBuffers; i++) {
|
||||
if (LnxBuffers[i] == buff)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < LnxNumBuffers) {
|
||||
if (LnxNumBuffers == 1) {
|
||||
// stop the thread! primary going down
|
||||
ShutdownSoundSystem();
|
||||
|
||||
LnxNumBuffers = 0;
|
||||
LnxBuffers = NULL;
|
||||
} else {
|
||||
// wait until it is ok (our thread is in a good position)
|
||||
enter_critical();
|
||||
|
||||
if (i == 0) {
|
||||
// can't delete the primary! whats going on here?
|
||||
return -1;
|
||||
}
|
||||
|
||||
LnxBuffers[i] = LnxBuffers[LnxNumBuffers - 1];
|
||||
LnxBuffers = (LnxSoundBuffer **)realloc(LnxBuffers, sizeof(LnxSoundBuffer *) * (LnxNumBuffers - 1));
|
||||
LnxNumBuffers--;
|
||||
|
||||
exit_critical();
|
||||
}
|
||||
|
||||
if (buff->buffer)
|
||||
free(buff->buffer);
|
||||
free(buff);
|
||||
} else
|
||||
return -1;
|
||||
|
||||
if (LnxNumBuffers == 1) {
|
||||
// we freed the last non-primary buffer
|
||||
// so remove the primary buffer that is remaining
|
||||
return LnxSoundBuffer_Release(LnxBuffers[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_SetVolume
|
||||
//////////////////////////////
|
||||
// Sets the volume of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set volume
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetVolume(LnxSoundBuffer *buff, int32_t vol) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (!(buff->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME))
|
||||
return -1;
|
||||
|
||||
if ((vol > LNXSND_VOLUME_MAX) || (vol < LNXSND_VOLUME_MIN))
|
||||
return -2;
|
||||
|
||||
if (buff->lbdesc.dwFlags & LNXSND_CAPS_PRIMARYBUFFER) {
|
||||
// not supported
|
||||
enter_critical();
|
||||
buff->volume = vol;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
enter_critical();
|
||||
|
||||
buff->volume = vol;
|
||||
|
||||
double vt;
|
||||
vt = (double)(buff->volume - (buff->pan > 0 ? buff->pan : 0));
|
||||
buff->left_vol = (uint32_t)(pow(2.0, vt / 600.0) * 32768.0);
|
||||
vt = (double)(buff->volume + (buff->pan < 0 ? buff->pan : 0));
|
||||
buff->right_vol = (uint32_t)(pow(2.0, vt / 600.0) * 32768.0);
|
||||
|
||||
exit_critical();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_SetPan
|
||||
///////////////////////////
|
||||
// Sets the pan of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set pan
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetPan(LnxSoundBuffer *buff, int32_t pan) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if ((pan > LNXSND_PAN_RIGHT) || (pan < LNXSND_PAN_LEFT))
|
||||
return -2;
|
||||
|
||||
if (!(buff->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (buff->lbdesc.dwFlags & LNXSND_CAPS_PRIMARYBUFFER)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
enter_critical();
|
||||
|
||||
buff->pan = pan;
|
||||
|
||||
double pt;
|
||||
pt = (double)(buff->volume - (buff->pan > 0 ? buff->pan : 0));
|
||||
buff->left_vol = (uint32_t)(pow(2.0, pt / 600.0) * 32768.0);
|
||||
pt = (double)(buff->volume + (buff->pan < 0 ? buff->pan : 0));
|
||||
buff->right_vol = (uint32_t)(pow(2.0, pt / 600.0) * 32768.0);
|
||||
|
||||
exit_critical();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Stop
|
||||
/////////////////////////
|
||||
// Stops a buffer from playing
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Stop(LnxSoundBuffer *buff) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->playing = 0;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Play
|
||||
/////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Play(LnxSoundBuffer *buff, uint32_t flags) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->flags = flags;
|
||||
buff->playing = 1;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_GetCaps
|
||||
////////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCaps(LnxSoundBuffer *buff, LinuxSoundCaps *caps) {
|
||||
if (!caps || !buff)
|
||||
return -1;
|
||||
|
||||
caps->dwFlags = buff->lbdesc.dwFlags | LNXSND_CAPS_LOCSOFTWARE;
|
||||
caps->dwBufferBytes = buff->lbdesc.dwBufferBytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_GetStatus
|
||||
//////////////////////////////
|
||||
// Returns the status of a buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetStatus(LnxSoundBuffer *buff, uint32_t *status) {
|
||||
if (!status || !buff)
|
||||
return -1;
|
||||
|
||||
*status = 0;
|
||||
if (buff->playing)
|
||||
*status |= LNXSND_PLAYING;
|
||||
if (buff->flags & LNXSND_LOOPING)
|
||||
*status |= LNXSND_LOOPING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_GetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Returns the current play and write positions of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCurrentPosition(LnxSoundBuffer *buff, uint32_t *ppos, uint32_t *wpos) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (ppos)
|
||||
*ppos = buff->play_cursor;
|
||||
if (wpos)
|
||||
*wpos = buff->write_cursor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_SetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Sets the current play position of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_SetCurrentPosition(LnxSoundBuffer *buff, uint32_t pos) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
enter_critical();
|
||||
buff->play_cursor = pos;
|
||||
exit_critical();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Lock
|
||||
/////////////////////////
|
||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
||||
// available the size of the buffer(s) for writing.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Lock(LnxSoundBuffer *buff, uint32_t pos, uint32_t numbytes, void **ptr1,
|
||||
uint32_t *numbytes1, void **ptr2, uint32_t *numbytes2, uint32_t flags) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
if (flags & LNXSND_LOCK_FROMWRITECURSOR)
|
||||
pos += buff->write_cursor;
|
||||
if (flags & LNXSND_LOCK_ENTIREBUFFER)
|
||||
numbytes = buff->buffer_len;
|
||||
if (numbytes > buff->buffer_len)
|
||||
numbytes = buff->buffer_len;
|
||||
|
||||
assert(numbytes1 != numbytes2);
|
||||
assert(ptr1 != ptr2);
|
||||
|
||||
if (pos + numbytes <= buff->buffer_len) {
|
||||
*(uint8_t **)ptr1 = buff->buffer + pos;
|
||||
*numbytes1 = numbytes;
|
||||
if (ptr2)
|
||||
*(uint8_t **)ptr2 = NULL;
|
||||
if (numbytes2)
|
||||
*numbytes2 = 0;
|
||||
} else {
|
||||
*(uint8_t **)ptr1 = buff->buffer + pos;
|
||||
*numbytes1 = buff->buffer_len - pos;
|
||||
if (ptr2)
|
||||
*(uint8_t **)ptr2 = buff->buffer;
|
||||
if (numbytes2)
|
||||
*numbytes2 = numbytes - (buff->buffer_len - pos);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_Unlock
|
||||
///////////////////////////
|
||||
// Unlocks a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Unlock(LnxSoundBuffer *buff, void *ptr1, uint32_t num1, void *ptr2, uint32_t num2) {
|
||||
if (!buff)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Internal Sound System routines
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Starts up the sound processing thread
|
||||
static bool StartupSoundSystem(LnxSoundDevice *dev) {
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
if (LnxNumBuffers < 1)
|
||||
return false;
|
||||
|
||||
memcpy(&LinuxSoundDevice, dev, sizeof(LnxSoundDevice));
|
||||
spec.freq = dev->freq;
|
||||
spec.format = dev->bit_depth == 8 ? AUDIO_U8 : AUDIO_S16SYS;
|
||||
spec.channels = dev->channels;
|
||||
spec.samples = 1024;
|
||||
spec.callback = LinuxSoundThreadHandler;
|
||||
|
||||
if (SDL_OpenAudio(&spec, NULL) < 0) {
|
||||
return false;
|
||||
}
|
||||
SDL_PauseAudio(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Shutsdown the sound processing thread
|
||||
static void ShutdownSoundSystem(void) { SDL_CloseAudio(); }
|
||||
|
||||
static inline void GetValues(const LnxSoundBuffer *dsb, uint8_t *buf, uint32_t *fl, uint32_t *fr) {
|
||||
int16_t *bufs = (int16_t *)buf;
|
||||
|
||||
// 8 bit stereo
|
||||
if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 2) {
|
||||
*fl = (*buf - 128) << 8;
|
||||
*fr = (*(buf + 1) - 128) << 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit stereo
|
||||
if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 2) {
|
||||
*fl = *bufs;
|
||||
*fr = *(bufs + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 8 bit mono
|
||||
if ((dsb->wfx.wBitsPerSample == 8) && dsb->wfx.nChannels == 1) {
|
||||
*fl = (*buf - 128) << 8;
|
||||
*fr = *fl;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit mono
|
||||
if ((dsb->wfx.wBitsPerSample == 16) && dsb->wfx.nChannels == 1) {
|
||||
*fl = *bufs;
|
||||
*fr = *bufs;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void SetValues(uint8_t *buf, uint32_t fl, uint32_t fr) {
|
||||
int16_t *bufs = (int16_t *)buf;
|
||||
|
||||
// 8 bit stereo
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 8) && (LnxBuffers[0]->wfx.nChannels == 2)) {
|
||||
*buf = (fl + 32768) >> 8;
|
||||
*(buf + 1) = (fr + 32768) >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit stereo
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 16) && (LnxBuffers[0]->wfx.nChannels == 2)) {
|
||||
*bufs = fl;
|
||||
*(bufs + 1) = fr;
|
||||
return;
|
||||
}
|
||||
|
||||
// 8 bit mono
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 8) && (LnxBuffers[0]->wfx.nChannels == 1)) {
|
||||
*buf = (((fl + fr) >> 1) + 32768) >> 8;
|
||||
return;
|
||||
}
|
||||
|
||||
// 16 bit mono
|
||||
if ((LnxBuffers[0]->wfx.wBitsPerSample == 16) && (LnxBuffers[0]->wfx.nChannels == 1)) {
|
||||
*bufs = (fl + fr) >> 1;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void LinuxSoundMixWithVolume(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len) {
|
||||
uint32_t i, inc = (LnxBuffers[0]->wfx.wBitsPerSample >> 3);
|
||||
uint8_t *bpc = buf;
|
||||
int16_t *bps = (int16_t *)buf;
|
||||
|
||||
if ((!(dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (dsb->pan == 0)) &&
|
||||
(!(dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME) || (dsb->volume == 0)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < len; i += inc) {
|
||||
uint32_t val;
|
||||
switch (inc) {
|
||||
case 1: {
|
||||
val = *bpc - 128;
|
||||
val = ((val * (i & inc ? dsb->right_vol : dsb->left_vol)) >> 15);
|
||||
*bpc = val + 128;
|
||||
bpc++;
|
||||
} break;
|
||||
case 2: {
|
||||
val = *bps;
|
||||
val = ((val * ((i & inc) ? dsb->right_vol : dsb->left_vol)) >> 15);
|
||||
*bps = val;
|
||||
bps++;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t LinuxSoundMixNormalize(LnxSoundBuffer *dsb, uint8_t *buf, uint32_t len) {
|
||||
uint32_t i, size, ipos, ilen, fieldL, fieldR;
|
||||
uint8_t *ibp, *obp;
|
||||
uint32_t iAdvance = dsb->wfx.nBlockAlign;
|
||||
uint32_t oAdvance = LnxBuffers[0]->wfx.nBlockAlign;
|
||||
|
||||
ibp = dsb->buffer + dsb->play_cursor;
|
||||
obp = buf;
|
||||
|
||||
if ((dsb->freq == LnxBuffers[0]->wfx.nSamplesPerSec) &&
|
||||
(dsb->wfx.wBitsPerSample == LnxBuffers[0]->wfx.wBitsPerSample) &&
|
||||
(dsb->wfx.nChannels == LnxBuffers[0]->wfx.nChannels)) {
|
||||
if ((ibp + len) < (uint8_t *)(dsb->buffer + dsb->buffer_len))
|
||||
memcpy(obp, ibp, len);
|
||||
else {
|
||||
memcpy(obp, ibp, dsb->buffer_len - dsb->play_cursor);
|
||||
memcpy(obp + (dsb->buffer_len - dsb->play_cursor), dsb->buffer, len - (dsb->buffer_len - dsb->play_cursor));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
if (dsb->freq == LnxBuffers[0]->wfx.nSamplesPerSec) {
|
||||
ilen = 0;
|
||||
for (i = 0; i < len; i += oAdvance) {
|
||||
GetValues(dsb, ibp, &fieldL, &fieldR);
|
||||
ibp += iAdvance;
|
||||
ilen += iAdvance;
|
||||
SetValues(obp, fieldL, fieldR);
|
||||
obp += oAdvance;
|
||||
if (ibp >= (uint8_t *)(dsb->buffer + dsb->buffer_len))
|
||||
ibp = dsb->buffer;
|
||||
}
|
||||
return (ilen);
|
||||
}
|
||||
|
||||
size = len / oAdvance;
|
||||
ilen = ((size * dsb->freq_adjustment) >> FREQUENCY_SHIFT) * iAdvance;
|
||||
for (i = 0; i < size; i++) {
|
||||
ipos = (((i * dsb->freq_adjustment) >> FREQUENCY_SHIFT) * iAdvance) + dsb->play_cursor;
|
||||
|
||||
if (ipos >= dsb->buffer_len)
|
||||
ipos %= dsb->buffer_len;
|
||||
|
||||
GetValues(dsb, (dsb->buffer + ipos), &fieldL, &fieldR);
|
||||
SetValues(obp, fieldL, fieldR);
|
||||
obp += oAdvance;
|
||||
}
|
||||
return ilen;
|
||||
}
|
||||
|
||||
int DoMulDiv(int nNumber, int nNumerator, int nDenominator) {
|
||||
if (!nDenominator)
|
||||
return -1;
|
||||
int64_t ret;
|
||||
ret = (((int64_t)nNumber * nNumerator) + (nDenominator / 2)) / nDenominator;
|
||||
|
||||
if ((ret > 0x7FFFFFFF) || (ret < 0xFFFFFFFF))
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void *TempSoundBuffer = NULL;
|
||||
static int TempSoundBufferLen = 0;
|
||||
static uint32_t LinuxSoundMixInMainBuffer(LnxSoundBuffer *dsb, int len) {
|
||||
uint32_t i, ilen, advance = (LnxBuffers[0]->wfx.wBitsPerSample >> 3);
|
||||
uint8_t *buf, *ibuf, *obuf;
|
||||
int32_t temp, field;
|
||||
int16_t *ibufs, *obufs;
|
||||
|
||||
if (!(dsb->flags & LNXSND_LOOPING)) {
|
||||
temp = DoMulDiv(LnxBuffers[0]->wfx.nAvgBytesPerSec, dsb->buffer_len, dsb->bps) -
|
||||
DoMulDiv(LnxBuffers[0]->wfx.nAvgBytesPerSec, dsb->play_cursor, dsb->bps);
|
||||
len = (len > temp) ? temp : len;
|
||||
}
|
||||
len &= ~3; // align to 4 byte boundary
|
||||
|
||||
if (!len) {
|
||||
dsb->playing = 0;
|
||||
dsb->write_cursor = 0;
|
||||
dsb->play_cursor = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > TempSoundBufferLen) {
|
||||
void *nb = realloc(TempSoundBuffer, len);
|
||||
if (nb) {
|
||||
TempSoundBuffer = nb;
|
||||
TempSoundBufferLen = len;
|
||||
buf = ibuf = (uint8_t *)nb;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
buf = ibuf = (uint8_t *)TempSoundBuffer;
|
||||
}
|
||||
|
||||
ilen = LinuxSoundMixNormalize(dsb, ibuf, len);
|
||||
if ((dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLPAN) || (dsb->lbdesc.dwFlags & LNXSND_CAPS_CTRLVOLUME)) {
|
||||
LinuxSoundMixWithVolume(dsb, ibuf, len);
|
||||
}
|
||||
|
||||
obuf = LnxBuffers[0]->buffer + LnxBuffers[0]->play_cursor;
|
||||
for (i = 0; i < len; i += advance) {
|
||||
obufs = (int16_t *)obuf;
|
||||
ibufs = (int16_t *)ibuf;
|
||||
if (LnxBuffers[0]->wfx.wBitsPerSample == 16) {
|
||||
field = *ibufs;
|
||||
field += *obufs;
|
||||
field = (field > 32767) ? (32767) : field;
|
||||
field = (field < -32768) ? (-32768) : field;
|
||||
*obufs = field;
|
||||
} else {
|
||||
field = (*ibuf - 128);
|
||||
field += (*obuf - 128);
|
||||
field = (field > 127) ? (127) : field;
|
||||
field = (field < -128) ? (-128) : field;
|
||||
*obuf = field + 128;
|
||||
}
|
||||
ibuf += advance;
|
||||
obuf += advance;
|
||||
if (obuf >= (uint8_t *)(LnxBuffers[0]->buffer + LnxBuffers[0]->buffer_len))
|
||||
obuf = LnxBuffers[0]->buffer;
|
||||
}
|
||||
|
||||
// adjust positions of the cursors in the buffer
|
||||
dsb->play_cursor += ilen;
|
||||
dsb->write_cursor = dsb->play_cursor + ilen;
|
||||
|
||||
if (dsb->play_cursor >= dsb->buffer_len) {
|
||||
if (!(dsb->flags & LNXSND_LOOPING)) {
|
||||
// we're not looping, this buffer is done, reset it
|
||||
dsb->playing = 0;
|
||||
dsb->write_cursor = 0;
|
||||
dsb->play_cursor = 0;
|
||||
} else {
|
||||
// loop back around
|
||||
dsb->play_cursor = dsb->play_cursor % dsb->buffer_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsb->write_cursor >= dsb->buffer_len) {
|
||||
dsb->write_cursor = dsb->write_cursor % dsb->buffer_len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void LinuxSoundMixBuffersIntoMain(int len) {
|
||||
LnxSoundBuffer *dsb;
|
||||
|
||||
// only go to 1 since 0 is the main buffer
|
||||
for (int i = LnxNumBuffers - 1; i > 0; i--) {
|
||||
if (!(dsb = LnxBuffers[i]))
|
||||
continue;
|
||||
|
||||
if (dsb->buffer_len && dsb->playing) {
|
||||
LinuxSoundMixInMainBuffer(dsb, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LinuxSoundThreadHandler(void *unused, Uint8 *stream, int len) {
|
||||
LnxBuffers[0]->buffer = stream;
|
||||
LnxBuffers[0]->buffer_len = len;
|
||||
LnxBuffers[0]->play_cursor = 0;
|
||||
LnxBuffers[0]->write_cursor = 0;
|
||||
|
||||
LinuxSoundMixBuffersIntoMain(len);
|
||||
|
||||
LnxBuffers[0]->buffer = NULL;
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __LNX_DSOUND_H_
|
||||
#define __LNX_DSOUND_H_
|
||||
|
||||
// Max&Min values for settings
|
||||
#define LNXSND_VOLUME_MAX 0
|
||||
#define LNXSND_VOLUME_MIN -10000
|
||||
#define LNXSND_PAN_LEFT -10000
|
||||
#define LNXSND_PAN_RIGHT 10000
|
||||
|
||||
// Status/Buffer flags
|
||||
#define LNXSND_PLAYING 0x0001
|
||||
#define LNXSND_LOOPING 0x0002
|
||||
|
||||
// Buffer lock flags
|
||||
#define LNXSND_LOCK_FROMWRITECURSOR 0x0001
|
||||
#define LNXSND_LOCK_ENTIREBUFFER 0x0002
|
||||
|
||||
// Capability flags
|
||||
#define LNXSND_CAPS_PRIMARYBUFFER 0x0001
|
||||
#define LNXSND_CAPS_CTRLVOLUME 0x0002
|
||||
#define LNXSND_CAPS_CTRLPAN 0x0004
|
||||
#define LNXSND_CAPS_CTRLFREQUENCY 0x0008
|
||||
#define LNXSND_CAPS_CTRLDEFAULT 0x000E
|
||||
#define LNXSND_CAPS_LOCSOFTWARE 0x0010
|
||||
|
||||
struct LnxSoundDevice {
|
||||
int sound_device; // file device handle for sound
|
||||
uint32_t bps; // (bytes per second) channels*freq*bit_depth/8
|
||||
uint32_t freq; // frequency (22050, etc.)
|
||||
uint32_t bit_depth; // 8 or 16
|
||||
uint32_t channels; // 1 or 2 (mono or stereo)
|
||||
};
|
||||
|
||||
struct WAVEFORMATEX {
|
||||
uint16_t wFormatTag;
|
||||
uint16_t nChannels;
|
||||
uint32_t nSamplesPerSec;
|
||||
uint32_t nAvgBytesPerSec;
|
||||
uint16_t nBlockAlign;
|
||||
uint16_t wBitsPerSample;
|
||||
uint16_t cbSize;
|
||||
}; // Taken from Windows for porting
|
||||
#define WAVE_FORMAT_PCM 0x01
|
||||
|
||||
struct LinuxSoundCaps {
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwBufferBytes;
|
||||
};
|
||||
|
||||
struct LnxBufferDesc {
|
||||
WAVEFORMATEX *lpwfxFormat;
|
||||
uint32_t dwBufferBytes;
|
||||
uint32_t dwFlags;
|
||||
};
|
||||
|
||||
struct LnxSoundBuffer
|
||||
int freq_adjustment;
|
||||
int bps;
|
||||
uint32_t buffer_len;
|
||||
uint32_t play_cursor;
|
||||
uint32_t write_cursor;
|
||||
uint32_t flags;
|
||||
uint32_t left_vol, right_vol;
|
||||
|
||||
uint8_t *buffer;
|
||||
|
||||
int32_t volume;
|
||||
int32_t pan;
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
|
||||
LnxBufferDesc lbdesc;
|
||||
|
||||
uint16_t freq;
|
||||
char playing;
|
||||
char __pad;
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
// LnxSound_CreateSoundBuffer
|
||||
///////////////////////////////
|
||||
// Creates a sound buffer to be used with mixing and output.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// -2 : Out of memory
|
||||
// 0 : Ok!
|
||||
int LnxSound_CreateSoundBuffer(LnxSoundDevice *dev, LnxBufferDesc *lbdesc, LnxSoundBuffer **lsndb);
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_Release
|
||||
////////////////////////////
|
||||
// Releases the memory associated with a sound buffer. This pointer is
|
||||
// no longer valid after return.
|
||||
//
|
||||
// Returns:
|
||||
// -1 : Invalid Parameter
|
||||
// 0 : Ok!
|
||||
int LnxSoundBuffer_Release(LnxSoundBuffer *buff);
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_SetVolume
|
||||
//////////////////////////////
|
||||
// Sets the volume of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set volume
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetVolume(LnxSoundBuffer *buff, int32_t vol);
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_SetPan
|
||||
///////////////////////////
|
||||
// Sets the pan of a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : Cannot set pan
|
||||
// -2 : Invalid parameters
|
||||
int LnxSoundBuffer_SetPan(LnxSoundBuffer *buff, int32_t pan);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Stop
|
||||
/////////////////////////
|
||||
// Stops a buffer from playing
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Stop(LnxSoundBuffer *buff);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Play
|
||||
/////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Play(LnxSoundBuffer *buff, uint32_t flags);
|
||||
|
||||
////////////////////////////
|
||||
// LnxSoundBuffer_GetCaps
|
||||
////////////////////////////
|
||||
// Starts a buffer playing (or changes the flags for a buffer currently
|
||||
// playing).
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCaps(LnxSoundBuffer *buff, LinuxSoundCaps *caps);
|
||||
|
||||
//////////////////////////////
|
||||
// LnxSoundBuffer_GetStatus
|
||||
//////////////////////////////
|
||||
// Returns the status of a buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetStatus(LnxSoundBuffer *buff, uint32_t *status);
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_GetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Returns the current play and write positions of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_GetCurrentPosition(LnxSoundBuffer *buff, uint32_t *ppos, uint32_t *wpos);
|
||||
|
||||
///////////////////////////////////////
|
||||
// LnxSoundBuffer_SetCurrentPosition
|
||||
///////////////////////////////////////
|
||||
// Sets the current play position of the buffer
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_SetCurrentPosition(LnxSoundBuffer *buff, uint32_t pos);
|
||||
|
||||
/////////////////////////
|
||||
// LnxSoundBuffer_Lock
|
||||
/////////////////////////
|
||||
// Locks the given buffer, returning pointer(s) to the buffer(s) along with
|
||||
// available the size of the buffer(s) for writing.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Lock(LnxSoundBuffer *buff, uint32_t pos, uint32_t numbytes, void **ptr1,
|
||||
uint32_t *numbytes1, void **ptr2, uint32_t *numbytes2, uint32_t flags);
|
||||
|
||||
///////////////////////////
|
||||
// LnxSoundBuffer_Unlock
|
||||
///////////////////////////
|
||||
// Unlocks a buffer.
|
||||
//
|
||||
// Returns:
|
||||
// 0 : no error
|
||||
// -1 : invalid parameters
|
||||
int LnxSoundBuffer_Unlock(LnxSoundBuffer *buff, void *ptr1, uint32_t num1, void *ptr2, uint32_t num2);
|
||||
|
||||
#endif
|
1630
lnxmvelib/mveasm.cpp
1630
lnxmvelib/mveasm.cpp
File diff suppressed because it is too large
Load Diff
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define MVE_GFX_VESA_640_400 0x100
|
||||
#define MVE_GFX_VESA_640_200 0x8100
|
||||
#define MVE_GFX_VESA_640_480 0x101
|
||||
#define MVE_GFX_VESA_640_240 0x8101
|
||||
#define MVE_GFX_VESA_800_600 0x103
|
||||
#define MVE_GFX_VESA_800_300 0x8103
|
||||
#define MVE_GFX_VESA_1024_768 0x105
|
||||
#define MVE_GFX_VESA_1024_384 0x8105
|
||||
#define MVE_GFX_VESA_1280_1024 0x107
|
||||
#define MVE_GFX_VESA_1280_512 0x8107
|
||||
|
||||
#define MVE_GFX_VESA_320_200_HI 0x10d /* 1:5:5:5 Hi Color modes */
|
||||
#define MVE_GFX_VESA_640_480_HI 0x110
|
||||
#define MVE_GFX_VESA_800_600_HI 0x113
|
||||
#define MVE_GFX_VESA_1024_768_HI 0x116
|
||||
#define MVE_GFX_VESA_1280_1024_HI 0x119
|
||||
|
||||
/* Some hacked vesa modes */
|
||||
#define MVE_GFX_VESA_640_350 0x0F00 /* 640x350 */
|
||||
#define MVE_GFX_VESA_640_175 0x8F00 /* 640x175 */
|
||||
#define MVE_GFX_VESA_640_160 0x0F01 /* 640x160 */
|
||||
|
||||
#define MVE_GFX_VESA_CURRENT 0 /* Use current VESA mode */
|
||||
|
||||
#define MVE_GFX_AUTO (-1) /* Choose mode based on movie's preference */
|
||||
#define MVE_GFX_VGA 0x13 /* 320x200 */
|
||||
#define MVE_GFX_VGA_CURRENT (-2) /* 320x200 (mode already set) */
|
||||
#define MVE_GFX_VGA_MEDRES (-3) /* 248x264 out of 320x350 */
|
||||
#define MVE_GFX_VGA_HIRES (-4) /* 224x288 out of 360x480 */
|
||||
#define MVE_GFX_VGA_LORES (-5) /* 288x224 out of 320x240 */
|
||||
#define MVE_GFX_VESA_320_480 (-6) /* 320x480 */
|
@ -1,248 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#if __SC__
|
||||
#pragma SC align 1
|
||||
#elif __WATCOMC__
|
||||
#pragma pack(1);
|
||||
#elif _MSC_VER
|
||||
#pragma pack(1)
|
||||
#else
|
||||
//???
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
#include "byteswap.h"
|
||||
|
||||
//--------------------------------
|
||||
// Useful type definitions
|
||||
//--------------------------------
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned bool;
|
||||
#endif
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
//--------------------------------
|
||||
// 386 Assembler Support
|
||||
//--------------------------------
|
||||
|
||||
#define OPERAND32 __asm _emit 0x66
|
||||
#define SEG_ES __asm _emit 0x26
|
||||
#define SEG_FS __asm _emit 0x64
|
||||
#define SEG_GS __asm _emit 0x65
|
||||
#define MOVZX_BP_IND_BX __asm _emit 0x0F __asm _emit 0xB6 __asm _emit 0x2F
|
||||
#define MOV_FS_AX __asm _emit 0x8e __asm _emit 0xE0
|
||||
#define MOV_GS_AX __asm _emit 0x8e __asm _emit 0xE8
|
||||
|
||||
//--------------------------------
|
||||
// Compressed Video Constants
|
||||
//--------------------------------
|
||||
|
||||
// Width and height of sections in pixels.
|
||||
#define SWIDTH 8
|
||||
#define SHEIGHT 8
|
||||
|
||||
#define LOG2_SWIDTH 3
|
||||
#define LOG2_SHEIGHT 3
|
||||
|
||||
//------------------------------
|
||||
// Movie File Header
|
||||
//------------------------------
|
||||
|
||||
#define MVE_FILE_TYPE "Interplay MVE File\x1A\0"
|
||||
#define MVE_FILE_VERSION 0x0100
|
||||
|
||||
struct mve_hdr {
|
||||
char FileType[20]; // MVE_FILE_TYPE
|
||||
uint16_t HdrSize; // sizeof(mve_hdr)
|
||||
uint16_t version; // MVE_FILE_VERSION
|
||||
uint16_t id; // ~MVE_FILE_VERSION+0x1234
|
||||
};
|
||||
|
||||
//------------------------------
|
||||
// Movie File Records
|
||||
//------------------------------
|
||||
|
||||
struct ioHdrRec {
|
||||
uint16_t len; // Length of record data (pad to even)
|
||||
uint16_t kind; // See IO_REC_xxx
|
||||
// uint8_t data[0]; // Record data
|
||||
};
|
||||
|
||||
// This record classifications simplify utilities which must operate on
|
||||
// records. They are not used by this library when running a movie.
|
||||
//
|
||||
#define IO_REC_SND_INIT 0 // Sound setup
|
||||
#define IO_REC_SND_PRELOAD 1 // Sound preload
|
||||
#define IO_REC_FRAME_INIT 2 // Frame (video) setup
|
||||
#define IO_REC_FRAME 3 // Movie frames
|
||||
#define IO_REC_END 4 // Last Record (End of Movie)
|
||||
#define IO_REC_EOF 5 // Empty eof record at end of file.
|
||||
|
||||
//------------------------------
|
||||
// Movie File Major Opcodes
|
||||
//------------------------------
|
||||
//
|
||||
|
||||
#define MCMD_DATA(arg) ((uint8_t *)((arg) + 1))
|
||||
|
||||
struct mcmd_hdr {
|
||||
uint16_t len; // Length of data (pad to even)
|
||||
uint8_t major; // Major opcode
|
||||
uint8_t minor; // Minor opcode
|
||||
// uint8_t data[0]; // Opcode data
|
||||
};
|
||||
|
||||
#define mcmd_end 0 // End processing of movie
|
||||
|
||||
#define mcmd_next 1 // Advance to next movie record
|
||||
|
||||
#define mcmd_syncInit 2
|
||||
struct marg_syncInit {
|
||||
uint32_t period; // period of quanta
|
||||
uint16_t wait_quanta; // # of quanta per frame
|
||||
};
|
||||
|
||||
#define mcmd_sndConfigure 3
|
||||
struct marg_sndConfigure {
|
||||
uint16_t rate; // 65536-(256E6/(frequency*(stereo+1)))
|
||||
// comp16 is a minor opcode 1 field
|
||||
// It indicates that 16-bit data has been compressed to 8-bits.
|
||||
// When it is set, bits16 will also be set.
|
||||
// Each record will contain initial 16-bit sample followed
|
||||
// by remaining compressed 8-bit samples.
|
||||
// For stereo, there will be two initial 16-bit samples.
|
||||
// and compressed streams will be interleaved.
|
||||
// uint16_t stereo:1, bits16:1, comp16:1;
|
||||
#ifdef OUTRAGE_BIG_ENDIAN
|
||||
uint8_t bitpadder : 5;
|
||||
#endif
|
||||
uint8_t stereo : 1, bits16 : 1, comp16 : 1;
|
||||
uint8_t dummy1;
|
||||
uint16_t frequency;
|
||||
// Minor opcode 1 extends buflen to be a long
|
||||
uint32_t buflen;
|
||||
};
|
||||
|
||||
#define mcmd_sndSync 4
|
||||
|
||||
#define mcmd_nfConfig 5
|
||||
struct marg_nfConfig {
|
||||
uint16_t wqty;
|
||||
uint16_t hqty;
|
||||
// Minor opcode 1 fields:
|
||||
uint16_t fqty;
|
||||
// Minor opcode 2 fields:
|
||||
uint16_t hicolor; /*0=256-color, 1=HiColor, 2=HiColorSwapped*/
|
||||
};
|
||||
|
||||
#define mcmd_nfDecomp 6
|
||||
#define mcmd_nfDecompChg 16
|
||||
#define mcmd_nfPkDecomp 17
|
||||
struct marg_nfDecomp {
|
||||
uint16_t prev; // info:Prev frames+1 needed for full picture
|
||||
uint16_t iframe; // info:Current internal frame #
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t w;
|
||||
uint16_t h;
|
||||
// uint16_t advance:1;
|
||||
#ifdef OUTRAGE_BIG_ENDIAN
|
||||
uint8_t bitpadder : 7;
|
||||
#endif
|
||||
uint8_t advance : 1;
|
||||
uint8_t dummy1;
|
||||
// uint8_t comp[0];
|
||||
};
|
||||
|
||||
#define mcmd_sfShowFrame 7
|
||||
#if 0 // Not supported
|
||||
#define mcmd_sfPkShowFrameChg 18
|
||||
#endif
|
||||
struct marg_sfShowFrame {
|
||||
uint16_t pal_start;
|
||||
uint16_t pal_count;
|
||||
// Minor opcode 1 fields:
|
||||
uint16_t field; // 0:none, 2:send to even, 3:send to odd
|
||||
};
|
||||
|
||||
#define mcmd_sndAdd 8
|
||||
#define mcmd_sndSilence 9
|
||||
struct marg_sndAdd {
|
||||
uint16_t iframe; // info: iframe # of sound
|
||||
uint16_t TrackMask;
|
||||
uint16_t qty; // Uncompressed audio size in bytes
|
||||
// uint8_t data[0];
|
||||
};
|
||||
|
||||
#define mcmd_gfxMode 10
|
||||
struct marg_gfxMode {
|
||||
uint16_t minw;
|
||||
uint16_t minh;
|
||||
uint16_t mode;
|
||||
};
|
||||
|
||||
#define mcmd_palMakeSynthPalette 11
|
||||
struct marg_palLoadPalette {
|
||||
uint8_t base_r;
|
||||
uint8_t range_r;
|
||||
uint8_t range_rb;
|
||||
uint8_t base_g;
|
||||
uint8_t range_g;
|
||||
uint8_t range_gb;
|
||||
};
|
||||
|
||||
#define mcmd_palLoadPalette 12
|
||||
struct marg_palLoadPalette {
|
||||
uint16_t start;
|
||||
uint16_t count;
|
||||
// uint8_t data[0];
|
||||
};
|
||||
|
||||
#define mcmd_palLoadCompPalette 13
|
||||
|
||||
#define mcmd_nfChanges 14
|
||||
#define mcmd_nfParms 15
|
||||
// 16 is used for mcmd_nfDecompChg, see above.
|
||||
// 17 is used for mcmd_nfPkDecomp, see above.
|
||||
// 18 is used for mcmd_nfPkShowFrameChg, see above
|
||||
|
||||
#define mcmd_nfPkInfo 19
|
||||
#define mcmd_nfHPkInfo 20
|
||||
struct marg_nfPkInfo {
|
||||
uint32_t error; // scaled by 10000
|
||||
uint16_t usage[64];
|
||||
};
|
||||
|
||||
#define mcmd_idcode 21
|
||||
struct marg_idcode {
|
||||
uint32_t idcode; // Code identifying version mcomp used to create
|
||||
};
|
||||
|
||||
#if __SC__
|
||||
#pragma SC align
|
||||
#elif __WATCOMC__
|
||||
#pragma pack();
|
||||
#elif _MSC_VER
|
||||
#pragma pack()
|
||||
#else
|
||||
//???
|
||||
#pragma pack(pop)
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,324 +0,0 @@
|
||||
/*
|
||||
** mvelibl.h
|
||||
**
|
||||
** Interplay Movie File (MVE) Player
|
||||
** Library Definitions (32-Bit Linux Version)
|
||||
** Written by Paul Allen Edelstein, Interplay Productions.
|
||||
** Partial Linux port by Jeff Slutter, Outrage Entertainment.
|
||||
**
|
||||
** (c) 1997 Interplay Productions. All Rights Reserved.
|
||||
** This file is confidential and consists of proprietary information
|
||||
** of Interplay Productions. This file and associated libraries
|
||||
** may not, in whole or in part, be disclosed to third parties,
|
||||
** incorporated into any software product which is not being created
|
||||
** for Interplay Productions, copied or duplicated in any form,
|
||||
** without the prior written permission of Interplay Productions.
|
||||
** Further, you may not reverse engineer, decompile or otherwise
|
||||
** attempt to derive source code of this material.
|
||||
*/
|
||||
|
||||
#ifndef _MVELIB_H_INCLUDED
|
||||
|
||||
#include "linux/lnxdsound.h"
|
||||
#include "linux/lnxdraw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Call this function to provide hooks into your memory management.
|
||||
*/
|
||||
typedef void *(mve_cb_alloc)(unsigned size);
|
||||
typedef void(mve_cb_free)(void *p);
|
||||
void MVE_memCallbacks(mve_cb_alloc *fn_alloc, mve_cb_free *fn_free);
|
||||
|
||||
/* This function remains from the DOS version of mvelib.
|
||||
** It allows you to provide a preallocated buffer for file I/O,
|
||||
** but under Windows there's no real point to doing this.
|
||||
*/
|
||||
void MVE_memIO(void *p, unsigned size);
|
||||
|
||||
/* Call this function to provide hook into your file io.
|
||||
*/
|
||||
typedef unsigned mve_cb_read(int handle, void *buf, unsigned count);
|
||||
void MVE_ioCallbacks(mve_cb_read *fn_read);
|
||||
|
||||
/* Call this function to provide hook into your digital sound driver.
|
||||
** Call with NULL if no sound support is available (default).
|
||||
*/
|
||||
void MVE_sndInit(LnxSoundDevice *lpDS);
|
||||
|
||||
/* Volume controls.
|
||||
** These functions are equivalent to the IDirectSoundBuffer
|
||||
** SetVolume and SetPan functions. They take effect immediately
|
||||
** and do NOT reset when a new movie starts.
|
||||
** Volume ranges from 0 (0 db, no volume change) to -10,000 (-100db, essentially silent).
|
||||
** Pan ranges from -10,000 (left full volume, right -100db), thru 0 (both full),
|
||||
** thru 10,000 (left -100db, right full volume).
|
||||
** The default value for volume and pan is zero.
|
||||
*/
|
||||
void MVE_dsbSetVolume(int32_t lVolume);
|
||||
void MVE_dsbSetPan(int32_t lPan);
|
||||
|
||||
/* Only call this function to configure software to work with a Super VGA
|
||||
** mode if you do not have VESA support.
|
||||
**
|
||||
** Restrictions/Assumptions:
|
||||
** 64K >= WinSize >= WinGran
|
||||
** WinSize % WinGran == 0
|
||||
** WinGran of 64K is represented by 0
|
||||
** SetBank is address of function with following protocol:
|
||||
** bh: 0=Set window, 1=Get Window
|
||||
** bl: Window number (0 or 1)
|
||||
** dx: Window position in video memory in units of WinGran.
|
||||
** on return, registers AX and DX are destroyed.
|
||||
**
|
||||
** Hicolor is 0 for 8-bit color, 1 for 15-bit rgb color, 2
|
||||
** for byte swapped 15-bit rgb color.
|
||||
*/
|
||||
|
||||
/* Note: 16-bit WriteWinSeg replaced with 32-bit WriteWinPtr */
|
||||
|
||||
/* The functionality of the following function is reduced in the Windows
|
||||
** version of the player. Call it as follows:
|
||||
** MVE_sfSVGA(w,h,w,0,NULL,0,0,NULL,hicolor)
|
||||
** where w and h are the width and height of your window,
|
||||
** and hicolor is a boolean which indicates if the screen
|
||||
** is operating in hi color, rather than 8-bit paletted color.
|
||||
** Under windows, the information provided by this function
|
||||
** is just used for window centering and for determining
|
||||
** how and when to do palette callbacks.
|
||||
*/
|
||||
void MVE_sfSVGA(unsigned w, unsigned h, unsigned LineWidth, unsigned WriteWin, uint8_t *WriteWinPtr,
|
||||
uint32_t WinSize, unsigned WinGran, void *SetBank, unsigned hicolor);
|
||||
|
||||
/* This function alters the display from 640x480 or 640x400 to 640x350 resolution.
|
||||
*/
|
||||
void MVE_ForceVres350(void);
|
||||
|
||||
/* This function alters the display from 640x480/400/350 to
|
||||
** 640x240/200/175.
|
||||
*/
|
||||
void MVE_ForceVresHalf(void);
|
||||
|
||||
/* **NOTE** There still need to be calls to restore original screen resolution
|
||||
** after using MVE_ForceVres350() or MVE_ForceVresHalf()!
|
||||
*/
|
||||
|
||||
/* Only call this function to either
|
||||
** 1. Replace method of copying frame to screen (perhaps for a nonstandard
|
||||
** screen format).
|
||||
** 2. Wrap your own code around the transfer of frame to screen
|
||||
** or modify which portions of the screen are updated.
|
||||
** This function replaces calls to the default MVE_ShowFrame function
|
||||
** with calls to your function, which can itself call MVE_ShowFrame.
|
||||
*/
|
||||
typedef void mve_cb_ShowFrame(uint8_t *buf, unsigned bufw, unsigned bufh, unsigned sx, unsigned sy, unsigned w,
|
||||
unsigned h, unsigned dstx, unsigned dsty, unsigned hicolor);
|
||||
void MVE_sfCallbacks(mve_cb_ShowFrame *fn_ShowFrame);
|
||||
|
||||
typedef void mve_cb_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
void MVE_palCallbacks(mve_cb_SetPalette *fn_SetPalette);
|
||||
|
||||
/* I'm pulling this, since it removes a C/C++ name mangling conflict - AH
|
||||
void MVE_SetPalette(uint8_t *p, unsigned start, unsigned count);
|
||||
*/
|
||||
|
||||
/* Configure the software for a graphics mode, optionally setting the
|
||||
** display to that mode (see the MVE_GFX_xxx constants defined below).
|
||||
*/
|
||||
unsigned MVE_gfxMode(int16_t mode);
|
||||
|
||||
/* Reset the screen to text mode (usually done before exiting a program).
|
||||
*/
|
||||
void MVE_gfxReset(void);
|
||||
|
||||
/* Set line for split screen graphics */
|
||||
/* {Use vbe_SetDisplayStart(x,y) to set vid buf for upper screen} */
|
||||
void MVE_gfxSetSplit(unsigned line);
|
||||
|
||||
/* Setup double buffering */
|
||||
void MVE_gfxSetDoubleBuffer(unsigned y1, unsigned y2, unsigned vis);
|
||||
|
||||
/* Get double buffering state */
|
||||
void MVE_gfxGetDoubleBuffer(unsigned *vis_y, unsigned *hid_y);
|
||||
|
||||
/* Enable double buffering for auto screen modes */
|
||||
void MVE_sfAutoDoubleBuffer(unsigned on);
|
||||
|
||||
/* Wait for video retrace off (0) or on (1) */
|
||||
void MVE_gfxWaitRetrace(unsigned state);
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* Establish link to a graphics window
|
||||
*/
|
||||
void MVE_rmWindow(LnxWindow *wnd);
|
||||
|
||||
/*---------------------------------------------*/
|
||||
|
||||
/* Establish callback for user control of movie playback.
|
||||
*/
|
||||
typedef int mve_cb_ctl(void);
|
||||
void MVE_rmCallbacks(mve_cb_ctl *fn_ctl);
|
||||
|
||||
/* Specify playback fastmode option (default is MVE_RM_NORMAL).
|
||||
*/
|
||||
#define MVE_RM_NORMAL 0 /* Normal playback */
|
||||
#define MVE_RM_HALF 1 /* Half height (even lines only) */
|
||||
#define MVE_RM_DITHERED 2 /* Half height (dither between lines) */
|
||||
#define MVE_RM_HALF_2 5 /* Full height, even lines only */
|
||||
#define MVE_RM_DITHERED_2 6 /* Full height, dither, even lines only */
|
||||
|
||||
void MVE_rmFastMode(int mode);
|
||||
|
||||
/* Specifying horizontal magnification:
|
||||
** 3: 4/3 horizontal magnification
|
||||
** 4: normal
|
||||
*/
|
||||
void MVE_rmHScale(int hscale);
|
||||
|
||||
/* Get frame count and number of dropped frames from last movie played.
|
||||
*/
|
||||
void MVE_rmFrameCounts(unsigned *FrameCount, unsigned *FrameDropCount);
|
||||
|
||||
/* Dump timing statistics (if enabled).
|
||||
*/
|
||||
void MVE_logDumpStats(void);
|
||||
|
||||
/* Run a compressed movie by reading data starting at the current
|
||||
** position in the file specified by handle hFile.
|
||||
** The movie window is displaced by dx,dy from the upper left hand corner
|
||||
** or is centered if dx,dy is -1,-1.
|
||||
** track specifies which audio track to play (usually 0 for a single
|
||||
** audio track).
|
||||
**
|
||||
** Returns an error/result code.
|
||||
**
|
||||
** Memory may be dynamically allocated while movie runs.
|
||||
*/
|
||||
int MVE_RunMovie(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
/* MVE_RunMovieContinue is the same as MVE_RunMovie except that it does not
|
||||
** automatically call MVE_rmEndMovie(). This may improve the smoothness
|
||||
** of immediately playing another movie afterwards.
|
||||
*/
|
||||
int MVE_RunMovieContinue(int hFile, int dx, int dy, unsigned track);
|
||||
|
||||
/*
|
||||
** Alternative to using MVE_RunMovie() and MVE_rmCallbacks().
|
||||
** Call MVE_rmPrepMovie() to prepare movie for playing.
|
||||
** Call MVE_rmStepMovie() to display next frame of movie until nonzero
|
||||
** result is returned (MVE_ERR_EOF for no next frame or some other error).
|
||||
** Call MVE_rmHoldMovie() to hold on current frame (and pause audio).
|
||||
** Call MVE_rmEndMovie() to abort movie.
|
||||
** All functions except MVE_rmEndMovie() return an error code.
|
||||
*/
|
||||
int MVE_rmPrepMovie(int hFile, int dx, int dy, unsigned track);
|
||||
int MVE_rmStepMovie(void);
|
||||
int MVE_rmHoldMovie(void);
|
||||
void MVE_rmEndMovie(void);
|
||||
|
||||
/* Frame Reader Streams
|
||||
** This is a special interface to the movie system which
|
||||
** allows a movie file to be opened as a stream from which
|
||||
** its frames may be retrieved. Audio and timing information
|
||||
** are ignored. For 256-color screen applications, palette
|
||||
** information is also typically ignored, and movies with a common
|
||||
** predefined palette are used. However, for hi-color screen
|
||||
** applications, an interface to obtain palette information has
|
||||
** been provided. This system is intended for use by video sprites
|
||||
** played off of the hard drive or out of memory.
|
||||
*/
|
||||
struct _MVE_frstream *MVE_frStream;
|
||||
|
||||
/* MVE_frOpen
|
||||
** Before calling this function, be sure to call MVE_memCallbacks()
|
||||
** and MVE_rmDirectDraw().
|
||||
**
|
||||
** fn_read specifies a file reader similar to the one
|
||||
** used by MVE_ioCallbacks().
|
||||
** handle specifies a file handle for an already opened
|
||||
** movie file. It is used by the file reader and is similar
|
||||
** to hFile argument used by MVE_RunMovie() and MVE_rmPrepMovie().
|
||||
** fr_callback is normally NULL, but can be used to supply
|
||||
** a handler for user data which has been interleaved into
|
||||
** the movie stream.
|
||||
**
|
||||
** If the movie file is invalid or the call otherwise fails,
|
||||
** NULL is returned.
|
||||
*/
|
||||
MVE_frStream MVE_frOpen(unsigned (*fn_read)(int handle, void *buf, unsigned count), int handle,
|
||||
int (*fr_callback)(unsigned op, unsigned subop, void *buf));
|
||||
|
||||
/* MVE_frGet
|
||||
** Returns the next frame from the specified frame reader stream
|
||||
** a nonzero error code {the same codes as returned by MVE_RunMovie()
|
||||
** and MVE_rmStepMovie()}.
|
||||
** If successful, MVE_frGet(frs, &buf, &w, &h) returns a pointer
|
||||
** to a direct draw surface containing the frame in buf,
|
||||
** and its width and height in w and h.
|
||||
*/
|
||||
int MVE_frGet(MVE_frStream frs, uint8_t **pBuf, unsigned *width, unsigned *height);
|
||||
|
||||
/* MVE_frPal
|
||||
** After each successful call to MVE_frGet(), this call may be used to
|
||||
** obtain corresponding palette information. It returns a pointer to the
|
||||
** entire current palette for the frame, and the subportion of the palette
|
||||
** which has changed this frame is identified by start and count (they will
|
||||
** both be zero on frames for which the palette has not changed).
|
||||
**
|
||||
** Paltbl points to 256*3 bytes of 6-bit r,g,b triples.
|
||||
** Start ranges from 0 to 255. Count from 0 to 256.
|
||||
**
|
||||
** These conventions are similar to those used by the palette callback arguments
|
||||
** with the standard player interface, except that this interface requires
|
||||
** polling each frame instead, and must be passed pointers to the variables where
|
||||
** the values will be returned.
|
||||
**
|
||||
*/
|
||||
void MVE_frPal(MVE_frStream frs, uint8_t **pPaltbl, unsigned *pStart, unsigned *pCount);
|
||||
|
||||
/* MVE_frClose
|
||||
** Closes the specified Frame Reader Stream frs.
|
||||
** Frees all storage associated with the stream.
|
||||
** The specified frs must not be used after this call.
|
||||
** Note that the open file handle specified in MVE_frOpen() is
|
||||
** not closed by this call...that is the caller's responsibility.
|
||||
*/
|
||||
void MVE_frClose(MVE_frStream frs);
|
||||
|
||||
/* Release any memory dynamically allocated by MVE_RunMovie.
|
||||
*/
|
||||
void MVE_ReleaseMem(void);
|
||||
|
||||
/* Return string corresponding to MVE_RunMovie result code.
|
||||
*/
|
||||
const char *MVE_strerror(int code);
|
||||
|
||||
/* RunMovie callback control code and result codes.
|
||||
** Codes > 1 are user defined.
|
||||
*/
|
||||
|
||||
#define MVE_CTL_HOLD -1 /* Returned by rmCtl() to hold current frame */
|
||||
#define MVE_CTL_EXIT 1 /* Returned by rmCtl() to end movie */
|
||||
|
||||
#define MVE_ERR_EOF -1 /* Returned by StepMovie() for end of movie */
|
||||
#define MVE_ERR_IO -2 /* File I/O error or unable to alloc memory. */
|
||||
#define MVE_ERR_SYNC -3 /* Timer error. */
|
||||
#define MVE_ERR_SND -4 /* Unable to allocate memory for sound */
|
||||
#define MVE_ERR_NF -5 /* Unable to allocate memory for video */
|
||||
#define MVE_ERR_GFX_FIT -6 /* Screen size too small for movie */
|
||||
#define MVE_ERR_GFX_FAIL -7 /* Failed to set desired graphics mode */
|
||||
#define MVE_ERR_BADFMT -8 /* Not a MVE file or unacceptable version */
|
||||
#define MVE_ERR_GFX_CLR -9 /* Incorrect screen color mode */
|
||||
#define MVE_ERR_PREP -10 /* StepMovie() without PrepMovie() */
|
||||
#define MVE_ERR_LD -11 /* Unable to initialize LinuxDraw */
|
||||
#define MVE_ERR_LOST -12 /* Direct Draw Surface Lost */
|
||||
|
||||
#define MVE_ERR_LAST -12
|
||||
|
||||
#define _MVELIB_H_INCLUDED
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Descent 3
|
||||
* Copyright (C) 2024 Parallax Software
|
||||
*
|
||||
* 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/>.
|
||||
|
||||
--- HISTORICAL COMMENTS FOLLOW ---
|
||||
|
||||
** #include <math.h>
|
||||
** void init_snd_8to16(void)
|
||||
** {
|
||||
** int i;
|
||||
** for (i=0; i<44; ++i)
|
||||
** snd_8to16[i] = i;
|
||||
** for (i=44; i<128; ++i)
|
||||
** snd_8to16[i] = (unsigned)floor(pow(65535,i/127.0)+.5);
|
||||
** for (i=1; i<128; ++i)
|
||||
** snd_8to16[256-i] = -snd_8to16[i];
|
||||
** snd_8to16[128] = snd_8to16[129];
|
||||
** }
|
||||
*/
|
||||
#pragma warning(disable : 4245)
|
||||
|
||||
int16_t snd_8to16[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
|
||||
42, 43, 47, 51, 56, 61, 66, 72, 79, 86, 94, 102, 112, 122,
|
||||
133, 145, 158, 173, 189, 206, 225, 245, 267, 292, 318, 348, 379, 414,
|
||||
452, 493, 538, 587, 640, 699, 763, 832, 908, 991, 1081, 1180, 1288, 1405,
|
||||
1534, 1673, 1826, 1993, 2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008, 4373, 4772,
|
||||
5208, 5683, 6202, 6767, 7385, 8059, 8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
|
||||
17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589, 35563, 38808, 42350, 46214, 50431, 55033,
|
||||
60055, 65535, -65535, -65535, -60055, -55033, -50431, -46214, -42350, -38808, -35563, -32589, -29864, -27367,
|
||||
-25078, -22981, -21060, -19298, -17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597, -8794, -8059,
|
||||
-7385, -6767, -6202, -5683, -5208, -4772, -4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373,
|
||||
-2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180, -1081, -991, -908, -832, -763, -699,
|
||||
-640, -587, -538, -493, -452, -414, -379, -348, -318, -292, -267, -245, -225, -206,
|
||||
-189, -173, -158, -145, -133, -122, -112, -102, -94, -86, -79, -72, -66, -61,
|
||||
-56, -51, -47, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33,
|
||||
-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19,
|
||||
-18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5,
|
||||
-4, -3, -2, -1};
|
||||
#pragma warning(default : 4245)
|
@ -16,23 +16,9 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <unistd.h>
|
||||
#include "lnxdsound.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <io.h>
|
||||
#include "dsound.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "movie.h"
|
||||
//#include "mvelibw.h"
|
||||
#include "mvelib.h"
|
||||
#include "pserror.h"
|
||||
#include "renderer.h"
|
||||
|
Loading…
Reference in New Issue
Block a user