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

📄 s3mfile.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: s3mfile.c 1.7 1996/09/13 15:10:01 chasan released $ * * Scream Tracker 3.0 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 <malloc.h>#include <string.h>#include "audio.h"#include "iofile.h"/* * ScreamTracker 3.0 module file structures */#define S3M_MAX_TRACKS          32#define S3M_MAX_SAMPLES         100#define S3M_MAX_PATTERNS        256#define S3M_MAX_ORDERS          256#define S3M_MAX_ROWS            64#define S3M_SCRM_MAGIC          0x4D524353L#define S3M_SCRS_MAGIC          0x53524353L#define S3M_SCRS_PCM            0x01#define S3M_SCRS_LOOPED         0x01typedef struct {    CHAR    aModuleName[28];    BYTE    bPadding;    BYTE    nFileType;    WORD    wReserved;    WORD    nSongLength;    WORD    nSamples;    WORD    nPatterns;    WORD    wFlags;    WORD    wVersion;    WORD    nSampleType;    DWORD   dwSCRM;    BYTE    nGlobalVolume;    BYTE    nTempo;    BYTE    nBPM;    BYTE    nMasterVolume;    BYTE    nUltraClick;    BYTE    nDefaultPanning;    BYTE    aReserved[8];    WORD    wSpecial;    BYTE    aChannelTable[32];} S3MFILEHEADER;typedef struct {    BYTE    nType;    CHAR    aFileName[13];    WORD    wDataSegPtr;    DWORD   dwLength;    DWORD   dwLoopStart;    DWORD   dwLoopEnd;    BYTE    nVolume;    BYTE    nReserved;    BYTE    nPacking;    BYTE    bFlags;    DWORD   nSampleRate;    BYTE    aReserved[12];    CHAR    aSampleName[28];    DWORD   dwSCRS;} S3MSAMPLEHEADER;typedef struct {    WORD    nSize;    LPBYTE  lpData;} S3MPATTERNHEADER;typedef struct {    BYTE    nNote;    BYTE    nSample;    BYTE    nVolume;    BYTE    nCommand;    BYTE    nParams;} S3MTRACKDATA;#define ACC 11#define MUL(a,b) (((a)*(b)+(1<<(ACC-1)))>>ACC)#define A (LONG)(12.0 * -2.4991805816500 * (1 << ACC))#define B (LONG)(12.0 * +4.0305172865900 * (1 << ACC))#define C (LONG)(12.0 * -2.0791605988100 * (1 << ACC))#define D (LONG)(12.0 * +0.6262992372690 * (1 << ACC))#define E (LONG)(12.0 * -0.0784753434027 * (1 << ACC))static LONG S3MGetRelativeNote(LONG dwSampleRate){    LONG dwRelativeNote;    /*     * Compute the relative note value given a sampling frequency:     *    RelativeNote = 12.0 * log2(SampleRate / 8363.0)     *     * The following algorithm uses 21.11 fixed-point arithmetic     * with an accuracy of about 1/128 for sampling frequencies     * between 522 and 65535 Hertz. (Thanks Zed!)     */    dwSampleRate = (dwSampleRate << (ACC + 4)) / 8363;    dwRelativeNote = -48L << ACC;    while (dwSampleRate > (2L << ACC)) {        dwSampleRate = (dwSampleRate + 1) >> 1;        dwRelativeNote += (12L << ACC);    }    dwRelativeNote += A + MUL(B + MUL(C + MUL(D + MUL(E, dwSampleRate),					      dwSampleRate), dwSampleRate), dwSampleRate);    return dwRelativeNote >> (ACC - 7);}static UINT S3MDecodePattern(UINT nTracks, LPBYTE lpData, UINT nSize,			     BYTE aMappingTable[], LPAUDIOPATTERN lpPattern){    static S3MTRACKDATA aTrackTable[S3M_MAX_TRACKS];    static BYTE aParamTable[S3M_MAX_TRACKS];    UINT nRow, nTrack, nFlags, nNote, nSample, nVolume, nCommand, nParams;    LPBYTE lpFTData, lpEndData;    /* initialize the pattern structure */    lpPattern->nPacking = 0;    lpPattern->nTracks = nTracks;    lpPattern->nRows = S3M_MAX_ROWS;    lpPattern->nSize = 0;    if ((lpPattern->lpData = malloc(nTracks * 6 * S3M_MAX_ROWS)) == NULL) {        return AUDIO_ERROR_NOMEMORY;    }    lpFTData = lpPattern->lpData;    lpEndData = lpData + nSize;    memset(aParamTable, 0, sizeof(aParamTable));    for (nRow = 0; nRow < S3M_MAX_ROWS; nRow++) {        /* grab the next row of notes from the S3M pattern */        memset(aTrackTable, 0, sizeof(aTrackTable));        while (lpData < lpEndData && (nFlags = *lpData++) != 0x00) {            /* get the note event */            nNote = 0xFF;            nSample = 0x00;            nVolume = 0xFF;            nCommand = 0x00;            nParams = 0x00;            nTrack = nFlags & 0x1F;            if (nFlags & 0x20) {                nNote = *lpData++;                nSample = *lpData++;            }            if (nFlags & 0x40) {                nVolume = *lpData++;            }            if (nFlags & 0x80) {                nCommand = *lpData++;                nParams = *lpData++;            }            /* skip notes for non-PCM tracks */            if ((nTrack = aMappingTable[nTrack]) >= nTracks)                continue;            /* decode note index */            if (nNote == 0xFE) {                nNote = AUDIO_MAX_NOTES + 1;            }            else if (nNote == 0xFF) {                nNote = 0x00;            }            else {                nNote = 12 * (nNote >> 4) + (nNote & 0x0F) + 1;                if (nNote > AUDIO_MAX_NOTES)                    nNote = 0;            }            /* decode S3M command effect default parameter stuff */            nCommand += 0x40;            if (nParams != 0x00) {                aParamTable[nTrack] = nParams;            }            else if (strchr("DEFGKLQ", nCommand)) {                nParams = aParamTable[nTrack];            }            /* decode S3M command effect */            switch (nCommand) {            case '@':                /* null command */                nCommand = nParams = 0x00;                break;            case 'A':                /* set tempo speed */                if (nParams < 0x20) {                    nCommand = 0x0F;                }                else {                    /* WARNING: tempo greater than 31 are not supported! */                    nCommand = nParams = 0x00;                }                break;            case 'B':                /* jump position */                nCommand = 0x0B;                break;            case 'C':                /* break pattern */                nCommand = 0x0D;                break;            case 'D':                if ((nParams & 0xF0) == 0x00) {                    /* volume slide down */                    nCommand = 0x0A;                    nParams &= 0x0F;                }                else if ((nParams & 0x0F) == 0x00) {                    /* volume slide up */                    nCommand = 0x0A;                    nParams &= 0xF0;                }                else if ((nParams & 0xF0) == 0xF0) {                    /* fine volume slide down */                    nCommand = 0x0E;                    nParams = 0xB0 | (nParams & 0x0F);                }                else if ((nParams & 0x0F) == 0x0F) {                    /* fine volume slide up */                    nCommand = 0x0E;                    nParams = 0xA0 | (nParams >> 4);                }                else {                    nCommand = nParams = 0x00;                }                break;            case 'E':                if ((nParams & 0xF0) == 0xF0) {                    /* fine porta down */                    nCommand = 0x0E;                    nParams = 0x20 | (nParams & 0x0F);                }                else if ((nParams & 0xF0) == 0xE0) {                    /* extra fine porta down */                    nCommand = 0x21;                    nParams = 0x20 | (nParams & 0x0F);                }                else {                    /* portamento down */                    nCommand = 0x02;                }                break;            case 'F':                if ((nParams & 0xF0) == 0xF0) {                    /* fine portamento up */                    nCommand = 0x0E;                    nParams = 0x10 | (nParams & 0x0F);                }                else if ((nParams & 0xF0) == 0xe0) {                    /* extra fine portamento up */                    nCommand = 0x21;                    nParams = 0x10 | (nParams & 0x0F);                }                else {                    /* portamento up */                    nCommand = 0x01;                }                break;            case 'G':                /* tone portamento */                nCommand = 0x03;                break;            case 'H':                /* vibrato */                nCommand = 0x04;                break;            case 'I':                /* tremor */                nCommand = 0x1d;                break;            case 'J':                /* arpeggio */                nCommand = 0x00;                break;            case 'K':                /* vibrato & volume slide */                nCommand = 0x06;                break;            case 'L':                /* tone portamento & volume slide */                nCommand = 0x05;                break;            case 'O':                /* set sample offset */                nCommand = 0x09;                break;            case 'Q':                /* multi-retrig */                nCommand = 0x1b;                break;            case 'R':                /* tremolo */                nCommand = 0x07;                break;            case 'S':                /* misc settings */                switch (nParams & 0xF0) {                case 0x00:                    /* set filter on/off */                    nCommand = 0x0E;                    nParams = 0x00 | (nParams & 0x0F);                    break;                case 0x10:                    /* set glissando control */                    nCommand = 0x0E;                    nParams = 0x30 | (nParams & 0x0F);                    break;                case 0x20:                    /* set fine-tune */                    nCommand = 0x0E;                    nParams = 0x50 | (nParams & 0x0F);                    break;                case 0x30:                    /* set tremolo waveform */                    nCommand = 0x0E;                    nParams = 0x70 | (nParams & 0x0F);                    break;                case 0x40:                    /* set vibrato waveform */                    nCommand = 0x0E;                    nParams = 0x40 | (nParams & 0x0F);                    break;                case 0x80:                    /* set coarse panning */                    nCommand = 0x0E;                    nParams = 0x80 | (nParams & 0x0F);                    break;                case 0xA0:                    /* set stereo control */                    nCommand = 0x08;                    switch (nParams & 0x0F) {                    case 0x00:                    case 0x02:                        /* hard left panning */                        nParams = 0x00;                        break;                    case 0x01:                    case 0x03:                        /* hard right panning */                        nParams = 0xFF;                        break;                    case 0x04:                        /* left panning */                        nParams = 0x40;                        break;

⌨️ 快捷键说明

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