⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmfile.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
字号:
/* * $Id: xmfile.c 1.6 1996/12/12 16:28:54 chasan Exp $ * * Extended module file loader routines. * * Copyright (c) 1995-1999 Carlos Hasan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <stdio.h>#include <limits.h>#include <malloc.h>#include <string.h>#include "audio.h"#include "iofile.h"/* * Extended module file structures */#define XM_FILE_HEADER_SIZE     276#define XM_PATTERN_HEADER_SIZE  9#define XM_PATCH_HEADER_SIZE    29#define XM_PATCH_BODY_SIZE      214#define XM_SAMPLE_HEADER_SIZE   40#define XM_MODULE_LINEAR        0x0001#define XM_ENVELOPE_ON          0x0001#define XM_ENVELOPE_SUSTAIN     0x0002#define XM_ENVELOPE_LOOP        0x0004#define XM_SAMPLE_LOOP          0x0001#define XM_SAMPLE_PINGPONG      0x0002#define XM_SAMPLE_16BITS        0x0010typedef struct {    CHAR    aIdText[17];    CHAR    aModuleName[20];    BYTE    bPadding;    CHAR    aTrackerName[20];    WORD    wVersion;    DWORD   dwHeaderSize;    WORD    nSongLength;    WORD    nRestart;    WORD    nTracks;    WORD    nPatterns;    WORD    nPatches;    WORD    wFlags;    WORD    nTempo;    WORD    nBPM;    BYTE    aOrderTable[256];} XMFILEHEADER;typedef struct {    DWORD   dwHeaderSize;    BYTE    nPacking;    WORD    nRows;    WORD    nSize;} XMPATTERNHEADER;typedef struct {    DWORD   dwHeaderSize;    CHAR    aPatchName[22];    BYTE    nType;    WORD    nSamples;    DWORD   dwSampleHeaderSize;    BYTE    aSampleNumber[96];    DWORD   aVolumeEnvelope[12];    DWORD   aPanningEnvelope[12];    BYTE    nVolumePoints;    BYTE    nPanningPoints;    BYTE    nVolumeSustain;    BYTE    nVolumeLoopStart;    BYTE    nVolumeLoopEnd;    BYTE    nPanningSustain;    BYTE    nPanningLoopStart;    BYTE    nPanningLoopEnd;    BYTE    bVolumeFlags;    BYTE    bPanningFlags;    BYTE    nVibratoType;    BYTE    nVibratoSweep;    BYTE    nVibratoDepth;    BYTE    nVibratoRate;    WORD    nVolumeFadeout;    WORD    wReserved;} XMPATCHHEADER;typedef struct {    DWORD   dwLength;    DWORD   dwLoopStart;    DWORD   dwLoopLength;    BYTE    nVolume;    BYTE    nFinetune;    BYTE    bFlags;    BYTE    nPanning;    BYTE    nRelativeNote;    BYTE    bReserved;    CHAR    aSampleName[22];} XMSAMPLEHEADER;/* * Extended module loader routines */static VOID XMDecodeSamples(LPAUDIOWAVE lpWave){    LPWORD lpwCode;    LPBYTE lpbCode;    UINT nDelta, nCount;    nDelta = 0;    nCount = lpWave->dwLength;    if (lpWave->wFormat & AUDIO_FORMAT_16BITS) {        lpwCode = (LPWORD) lpWave->lpData;        nCount >>= 1;        while (nCount--) {#ifdef __BIGENDIAN__            *lpwCode = MAKEWORD(HIBYTE(*lpwCode), LOBYTE(*lpwCode));#endif            nDelta = *lpwCode++ += nDelta;        }    }    else {        lpbCode = (LPBYTE) lpWave->lpData;        while (nCount--) {            nDelta = (BYTE) (*lpbCode++ += (BYTE) nDelta);        }    }}UINT AIAPI ALoadModuleXM(LPSTR lpszFileName, 			 LPAUDIOMODULE *lplpModule, DWORD dwFileOffset){    static XMFILEHEADER Header;    static XMPATTERNHEADER Pattern;    static XMPATCHHEADER Patch;    static XMSAMPLEHEADER Sample;    LPAUDIOMODULE lpModule;    LPAUDIOPATTERN lpPattern;    LPAUDIOPATCH lpPatch;    LPAUDIOSAMPLE lpSample;    UINT n, m, nErrorCode;    /* open XM module file */    if (AIOOpenFile(lpszFileName)) {        return AUDIO_ERROR_FILENOTFOUND;    }    AIOSeekFile(dwFileOffset, SEEK_SET);    if ((lpModule = (LPAUDIOMODULE) calloc(1, sizeof(AUDIOMODULE))) == NULL) {        AIOCloseFile();        return AUDIO_ERROR_NOMEMORY;    }    /* load XM module header structure */    AIOReadFile(Header.aIdText, sizeof(Header.aIdText));    AIOReadFile(Header.aModuleName, sizeof(Header.aModuleName));    AIOReadChar(&Header.bPadding);    AIOReadFile(Header.aTrackerName, sizeof(Header.aTrackerName));    AIOReadShort(&Header.wVersion);    AIOReadLong(&Header.dwHeaderSize);    AIOReadShort(&Header.nSongLength);    AIOReadShort(&Header.nRestart);    AIOReadShort(&Header.nTracks);    AIOReadShort(&Header.nPatterns);    AIOReadShort(&Header.nPatches);    AIOReadShort(&Header.wFlags);    AIOReadShort(&Header.nTempo);    AIOReadShort(&Header.nBPM);    AIOReadFile(&Header.aOrderTable, sizeof(Header.aOrderTable));    AIOSeekFile(Header.dwHeaderSize - XM_FILE_HEADER_SIZE, SEEK_CUR);    if (memcmp(Header.aIdText, "Extended Module: ", sizeof(Header.aIdText)) ||        Header.wVersion != 0x104 ||        Header.nSongLength > AUDIO_MAX_ORDERS ||        Header.nPatterns > AUDIO_MAX_PATTERNS ||        Header.nPatches > AUDIO_MAX_PATCHES ||        Header.nTracks > AUDIO_MAX_VOICES) {        AFreeModuleFile(lpModule);        AIOCloseFile();        return AUDIO_ERROR_BADFILEFORMAT;    }    /* initialize module structure */    strncpy(lpModule->szModuleName, Header.aModuleName,	    sizeof(Header.aModuleName));    if (Header.wFlags & XM_MODULE_LINEAR)        lpModule->wFlags |= AUDIO_MODULE_LINEAR;    lpModule->nOrders = Header.nSongLength;    lpModule->nRestart = Header.nRestart;    lpModule->nTracks = Header.nTracks;    lpModule->nPatterns = Header.nPatterns;    lpModule->nPatches = Header.nPatches;    lpModule->nTempo = Header.nTempo;    lpModule->nBPM = Header.nBPM;    for (n = 0; n < lpModule->nOrders; n++) {        lpModule->aOrderTable[n] = Header.aOrderTable[n];    }    for (n = 0; n < lpModule->nTracks; n++) {        lpModule->aPanningTable[n] = (AUDIO_MIN_PANNING + AUDIO_MAX_PANNING)/2;    }    if ((lpModule->aPatternTable = (LPAUDIOPATTERN)	 calloc(lpModule->nPatterns, sizeof(AUDIOPATTERN))) == NULL) {        AFreeModuleFile(lpModule);        AIOCloseFile();        return AUDIO_ERROR_NOMEMORY;    }    if ((lpModule->aPatchTable = (LPAUDIOPATCH)	 calloc(lpModule->nPatches, sizeof(AUDIOPATCH))) == NULL) {        AFreeModuleFile(lpModule);        AIOCloseFile();        return AUDIO_ERROR_NOMEMORY;    }    lpPattern = lpModule->aPatternTable;    for (n = 0; n < lpModule->nPatterns; n++, lpPattern++) {        /* load XM pattern header structure */        AIOReadLong(&Pattern.dwHeaderSize);        AIOReadChar(&Pattern.nPacking);        AIOReadShort(&Pattern.nRows);        AIOReadShort(&Pattern.nSize);        AIOSeekFile(Pattern.dwHeaderSize - XM_PATTERN_HEADER_SIZE, SEEK_CUR);        if (Pattern.nPacking != 0) {            AFreeModuleFile(lpModule);            AIOCloseFile();            return AUDIO_ERROR_BADFILEFORMAT;        }        /* initialize pattern structure */        lpPattern->nPacking = Pattern.nPacking;        lpPattern->nTracks = lpModule->nTracks;        lpPattern->nRows = Pattern.nRows;        lpPattern->nSize = Pattern.nSize;        if (lpPattern->nSize != 0) {            /* allocate and load pattern data */            if ((lpPattern->lpData = malloc(lpPattern->nSize)) == NULL) {                AFreeModuleFile(lpModule);                AIOCloseFile();                return AUDIO_ERROR_NOMEMORY;            }            AIOReadFile(lpPattern->lpData, lpPattern->nSize);        }    }    lpPatch = lpModule->aPatchTable;    for (n = 0; n < lpModule->nPatches; n++, lpPatch++) {        /* load XM patch header structure */        AIOReadLong(&Patch.dwHeaderSize);        AIOReadFile(Patch.aPatchName, sizeof(Patch.aPatchName));        AIOReadChar(&Patch.nType);        AIOReadShort(&Patch.nSamples);        if (Patch.nSamples != 0) {            AIOReadLong(&Patch.dwSampleHeaderSize);            AIOReadFile(Patch.aSampleNumber, sizeof(Patch.aSampleNumber));            for (m = 0; m < AUDIO_MAX_POINTS; m++) {                AIOReadLong(&Patch.aVolumeEnvelope[m]);            }            for (m = 0; m < AUDIO_MAX_POINTS; m++) {                AIOReadLong(&Patch.aPanningEnvelope[m]);            }            AIOReadChar(&Patch.nVolumePoints);            AIOReadChar(&Patch.nPanningPoints);            AIOReadChar(&Patch.nVolumeSustain);            AIOReadChar(&Patch.nVolumeLoopStart);            AIOReadChar(&Patch.nVolumeLoopEnd);            AIOReadChar(&Patch.nPanningSustain);            AIOReadChar(&Patch.nPanningLoopStart);            AIOReadChar(&Patch.nPanningLoopEnd);            AIOReadChar(&Patch.bVolumeFlags);            AIOReadChar(&Patch.bPanningFlags);            AIOReadChar(&Patch.nVibratoType);            AIOReadChar(&Patch.nVibratoSweep);            AIOReadChar(&Patch.nVibratoDepth);            AIOReadChar(&Patch.nVibratoRate);            AIOReadShort(&Patch.nVolumeFadeout);            AIOReadShort(&Patch.wReserved);            Patch.dwHeaderSize -= XM_PATCH_BODY_SIZE;        }        AIOSeekFile(Patch.dwHeaderSize - XM_PATCH_HEADER_SIZE, SEEK_CUR);        /* HACK: clamp envelope's number of points (12/12/96) */	if (Patch.nVolumePoints > AUDIO_MAX_POINTS)	    Patch.nVolumePoints = AUDIO_MAX_POINTS;        if (Patch.nPanningPoints > AUDIO_MAX_POINTS)            Patch.nPanningPoints = AUDIO_MAX_POINTS;        if (Patch.nSamples > AUDIO_MAX_SAMPLES ||            Patch.nVolumePoints > AUDIO_MAX_POINTS ||            Patch.nPanningPoints > AUDIO_MAX_POINTS) {            AFreeModuleFile(lpModule);            AIOCloseFile();            return AUDIO_ERROR_BADFILEFORMAT;        }        /* initialize patch structure */        strncpy(lpPatch->szPatchName, Patch.aPatchName,		sizeof(Patch.aPatchName));        for (m = 0; m < AUDIO_MAX_NOTES; m++) {            lpPatch->aSampleNumber[m] = Patch.aSampleNumber[m];            if (lpPatch->aSampleNumber[m] >= Patch.nSamples)                lpPatch->aSampleNumber[m] = 0x00;        }        lpPatch->nSamples = Patch.nSamples;        lpPatch->nVibratoType = Patch.nVibratoType;        lpPatch->nVibratoSweep = Patch.nVibratoSweep;        lpPatch->nVibratoDepth = Patch.nVibratoDepth;        lpPatch->nVibratoRate = Patch.nVibratoRate;        lpPatch->nVolumeFadeout = Patch.nVolumeFadeout;        lpPatch->Volume.nPoints = Patch.nVolumePoints;        lpPatch->Volume.nSustain = Patch.nVolumeSustain;        lpPatch->Volume.nLoopStart = Patch.nVolumeLoopStart;        lpPatch->Volume.nLoopEnd = Patch.nVolumeLoopEnd;        if (Patch.bVolumeFlags & XM_ENVELOPE_ON)            lpPatch->Volume.wFlags |= AUDIO_ENVELOPE_ON;        if (Patch.bVolumeFlags & XM_ENVELOPE_SUSTAIN)            lpPatch->Volume.wFlags |= AUDIO_ENVELOPE_SUSTAIN;        if (Patch.bVolumeFlags & XM_ENVELOPE_LOOP)            lpPatch->Volume.wFlags |= AUDIO_ENVELOPE_LOOP;        for (m = 0; m < lpPatch->Volume.nPoints; m++) {            lpPatch->Volume.aEnvelope[m].nFrame =                LOWORD(Patch.aVolumeEnvelope[m]);            lpPatch->Volume.aEnvelope[m].nValue =                HIWORD(Patch.aVolumeEnvelope[m]);        }        lpPatch->Panning.nPoints = Patch.nPanningPoints;        lpPatch->Panning.nSustain = Patch.nPanningSustain;        lpPatch->Panning.nLoopStart = Patch.nPanningLoopStart;        lpPatch->Panning.nLoopEnd = Patch.nPanningLoopEnd;        if (Patch.bPanningFlags & XM_ENVELOPE_ON)            lpPatch->Panning.wFlags |= AUDIO_ENVELOPE_ON;        if (Patch.bPanningFlags & XM_ENVELOPE_SUSTAIN)            lpPatch->Panning.wFlags |= AUDIO_ENVELOPE_SUSTAIN;        if (Patch.bPanningFlags & XM_ENVELOPE_LOOP)            lpPatch->Panning.wFlags |= AUDIO_ENVELOPE_LOOP;        for (m = 0; m < lpPatch->Panning.nPoints; m++) {            lpPatch->Panning.aEnvelope[m].nFrame =                LOWORD(Patch.aPanningEnvelope[m]);            lpPatch->Panning.aEnvelope[m].nValue =                HIWORD(Patch.aPanningEnvelope[m]);        }        if (lpPatch->nSamples != 0) {            if ((lpPatch->aSampleTable = (LPAUDIOSAMPLE)		 calloc(lpPatch->nSamples, sizeof(AUDIOSAMPLE))) == NULL) {                AFreeModuleFile(lpModule);                AIOCloseFile();                return AUDIO_ERROR_NOMEMORY;            }        }        /* load XM multi-sample header structures */        lpSample = lpPatch->aSampleTable;        for (m = 0; m < Patch.nSamples; m++, lpSample++) {            AIOReadLong(&Sample.dwLength);            AIOReadLong(&Sample.dwLoopStart);            AIOReadLong(&Sample.dwLoopLength);            AIOReadChar(&Sample.nVolume);            AIOReadChar(&Sample.nFinetune);            AIOReadChar(&Sample.bFlags);            AIOReadChar(&Sample.nPanning);            AIOReadChar(&Sample.nRelativeNote);            AIOReadChar(&Sample.bReserved);            AIOReadFile(Sample.aSampleName, sizeof(Sample.aSampleName));            AIOSeekFile(Patch.dwSampleHeaderSize -			XM_SAMPLE_HEADER_SIZE, SEEK_CUR);            strncpy(lpSample->szSampleName, Sample.aSampleName,		    sizeof(Sample.aSampleName));            lpSample->Wave.dwLength = Sample.dwLength;            lpSample->Wave.dwLoopStart = Sample.dwLoopStart;            lpSample->Wave.dwLoopEnd = Sample.dwLoopStart + Sample.dwLoopLength;            lpSample->Wave.nSampleRate = 8363;            lpSample->nVolume = Sample.nVolume;            lpSample->nPanning = Sample.nPanning;            lpSample->nRelativeNote = Sample.nRelativeNote;            lpSample->nFinetune = Sample.nFinetune;            if (Sample.bFlags & XM_SAMPLE_16BITS) {                lpSample->Wave.wFormat |= AUDIO_FORMAT_16BITS;            }            if (Sample.bFlags & XM_SAMPLE_LOOP)                lpSample->Wave.wFormat |= AUDIO_FORMAT_LOOP;            if (Sample.bFlags & XM_SAMPLE_PINGPONG)                lpSample->Wave.wFormat |= AUDIO_FORMAT_BIDILOOP;        }        /* load XM multi-sample waveform data */        lpSample = lpPatch->aSampleTable;        for (m = 0; m < Patch.nSamples; m++, lpSample++) {            if (lpSample->Wave.dwLength == 0)                continue;            nErrorCode = ACreateAudioData(&lpSample->Wave);            if (nErrorCode != AUDIO_ERROR_NONE) {                AFreeModuleFile(lpModule);                AIOCloseFile();                return nErrorCode;            }            AIOReadFile(lpSample->Wave.lpData, lpSample->Wave.dwLength);            XMDecodeSamples(&lpSample->Wave);            AWriteAudioData(&lpSample->Wave, 0, lpSample->Wave.dwLength);        }    }    AIOCloseFile();    *lplpModule = lpModule;    return AUDIO_ERROR_NONE;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -