diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index e4d9fc177..958cd4275 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2012,8 +2012,8 @@ PDynArray::PDynArray() // //========================================================================== -PDynArray::PDynArray(PType *etype) -: ElementType(etype) +PDynArray::PDynArray(PType *etype,PStruct *backing) +: ElementType(etype), BackingType(backing) { mDescriptiveName.Format("DynArray<%s>", etype->DescriptiveName()); Size = sizeof(FArray); @@ -2061,7 +2061,33 @@ PDynArray *NewDynArray(PType *type) PType *atype = TypeTable.FindType(RUNTIME_CLASS(PDynArray), (intptr_t)type, 0, &bucket); if (atype == NULL) { - atype = new PDynArray(type); + FString backingname; + + switch (type->GetRegType()) + { + case REGT_INT: + backingname.Format("DynArray_I%d", type->Size * 8); + break; + + case REGT_FLOAT: + backingname.Format("DynArray_F%d", type->Size * 8); + break; + + case REGT_STRING: + backingname = "DynArray_String"; + break; + + case REGT_POINTER: + backingname = "DynArray_Ptr"; + break; + + default: + I_Error("Unsupported dynamic array requested"); + break; + } + + auto backing = NewNativeStruct(backingname, nullptr); + atype = new PDynArray(type, backing); TypeTable.AddType(atype, RUNTIME_CLASS(PDynArray), (intptr_t)type, 0, bucket); } return (PDynArray *)atype; diff --git a/src/dobjtype.h b/src/dobjtype.h index 8cbe79966..60d410918 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -6,6 +6,7 @@ #endif typedef std::pair FTypeAndOffset; +class PStruct; #include "vm.h" @@ -649,9 +650,10 @@ class PDynArray : public PCompoundType DECLARE_CLASS(PDynArray, PCompoundType); HAS_OBJECT_POINTERS; public: - PDynArray(PType *etype); + PDynArray(PType *etype, PStruct *backing); PType *ElementType; + PStruct *BackingType; virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; diff --git a/src/namedef.h b/src/namedef.h index 2bdb74ee6..a010fbb8a 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -821,6 +821,8 @@ xx(DamageFunction) xx(Length) xx(Unit) xx(Size) +xx(Copy) +xx(Move) xx(Voidptr) xx(StateLabel) xx(SpriteID) diff --git a/src/oplsynth/deftypes.h b/src/oplsynth/deftypes.h deleted file mode 100644 index ff3754a5f..000000000 --- a/src/oplsynth/deftypes.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Name: General Use Types Definitions -- Header Include file - * Version: 1.24 - * Author: Vladimir Arnost (QA-Software) - * Last revision: Sep-4-1995 - * Compiler: Borland C++ 3.1, Watcom C/C++ 10.0 - * - */ - -#ifndef __DEFTYPES_H_ -#define __DEFTYPES_H_ - -/* Global type declarations */ - -#include "doomtype.h" - -/* machine dependent types */ -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef signed char schar; -typedef signed short sshort; -typedef signed int sint; -typedef signed long slong; - -#endif // __DEFTYPES_H_ diff --git a/src/oplsynth/fmopl.cpp b/src/oplsynth/fmopl.cpp index 5138fe0d1..0e270e6f5 100644 --- a/src/oplsynth/fmopl.cpp +++ b/src/oplsynth/fmopl.cpp @@ -105,12 +105,6 @@ Revision History: /* compiler dependence */ #ifndef OSD_CPU_H #define OSD_CPU_H -typedef unsigned char UINT8; /* unsigned 8bit */ -typedef unsigned short UINT16; /* unsigned 16bit */ -typedef unsigned int UINT32; /* unsigned 32bit */ -typedef signed char INT8; /* signed 8bit */ -typedef signed short INT16; /* signed 16bit */ -typedef signed int INT32; /* signed 32bit */ #endif #ifndef PI @@ -119,34 +113,30 @@ typedef signed int INT32; /* signed 32bit */ #ifdef _MSC_VER #pragma warning (disable: 4244) -#define INLINE __forceinline #endif -#ifdef __GNUC__ -#define INLINE __inline -#endif -#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ -#define EG_SH 16 /* 16.16 fixed point (EG timing) */ -#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ -#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ +#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */ +#define EG_SH 16 /* 16.16 fixed point (EG timing) */ +#define LFO_SH 24 /* 8.24 fixed point (LFO calculations) */ +#define TIMER_SH 16 /* 16.16 fixed point (timers calculations) */ -#define FREQ_MASK ((1<>KSR */ - UINT8 mul; /* multiple: mul_tab[ML] */ +struct OPL_SLOT +{ + uint32_t ar; /* attack rate: AR<<2 */ + uint32_t dr; /* decay rate: DR<<2 */ + uint32_t rr; /* release rate:RR<<2 */ + uint8_t KSR; /* key scale rate */ + uint8_t ksl; /* keyscale level */ + uint8_t ksr; /* key scale rate: kcode>>KSR */ + uint8_t mul; /* multiple: mul_tab[ML] */ /* Phase Generator */ - UINT32 Cnt; /* frequency counter */ - UINT32 Incr; /* frequency counter step */ - UINT8 FB; /* feedback shift value */ - INT32 *connect1; /* slot1 output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ - UINT8 CON; /* connection (algorithm) type */ + uint32_t Cnt; /* frequency counter */ + uint32_t Incr; /* frequency counter step */ + uint8_t FB; /* feedback shift value */ + int32_t *connect1; /* slot1 output pointer */ + int32_t op1_out[2]; /* slot1 output for feedback */ + uint8_t CON; /* connection (algorithm) type */ /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level: TL << 2 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level: sl_tab[SL] */ - - UINT8 eg_sh_ar; /* (attack state) */ - UINT8 eg_sel_ar; /* (attack state) */ - UINT8 eg_sh_dr; /* (decay state) */ - UINT8 eg_sel_dr; /* (decay state) */ - UINT8 eg_sh_rr; /* (release state) */ - UINT8 eg_sel_rr; /* (release state) */ - - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + uint8_t eg_type; /* percussive/non-percussive mode */ + uint8_t state; /* phase type */ + uint32_t TL; /* total level: TL << 2 */ + int32_t TLL; /* adjusted now TL */ + int32_t volume; /* envelope counter */ + uint32_t sl; /* sustain level: sl_tab[SL] */ + uint8_t eg_sh_ar; /* (attack state) */ + uint8_t eg_sel_ar; /* (attack state) */ + uint8_t eg_sh_dr; /* (decay state) */ + uint8_t eg_sel_dr; /* (decay state) */ + uint8_t eg_sh_rr; /* (release state) */ + uint8_t eg_sel_rr; /* (release state) */ + uint32_t key; /* 0 = KEY OFF, >0 = KEY ON */ /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ + uint32_t AMmask; /* LFO Amplitude Modulation enable mask */ + uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ /* waveform select */ unsigned int wavetable; -} OPL_SLOT; +}; -typedef struct{ +struct OPL_CH +{ OPL_SLOT SLOT[2]; /* phase generator state */ - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ + uint32_t block_fnum; /* block+fnum */ + uint32_t fc; /* Freq. Increment base */ + uint32_t ksl_base; /* KeyScaleLevel Base step */ + uint8_t kcode; /* key code (for key scaling) */ float LeftVol; /* volumes for stereo panning */ float RightVol; -} OPL_CH; +}; /* OPL state */ -typedef struct fm_opl_f { +struct FM_OPL +{ /* FM channel slots */ - OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ + OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ - UINT32 eg_cnt; /* global envelope generator counter */ - UINT32 eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ - UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overflows every 1 sample (on real chip) */ + uint32_t eg_cnt; /* global envelope generator counter */ + uint32_t eg_timer; /* global envelope generator counter works at frequency = chipclock/72 */ + uint32_t eg_timer_add; /* step of eg_timer */ + uint32_t eg_timer_overflow; /* envelope generator timer overflows every 1 sample (on real chip) */ - UINT8 rhythm; /* Rhythm mode */ + uint8_t rhythm; /* Rhythm mode */ - UINT32 fn_tab[1024]; /* fnumber->increment counter */ + uint32_t fn_tab[1024]; /* fnumber->increment counter */ /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise peroid */ + uint8_t lfo_am_depth; + uint8_t lfo_pm_depth_range; + uint32_t lfo_am_cnt; + uint32_t lfo_am_inc; + uint32_t lfo_pm_cnt; + uint32_t lfo_pm_inc; - UINT8 wavesel; /* waveform select enable flag */ + uint32_t noise_rng; /* 23 bit noise shift register */ + uint32_t noise_p; /* current noise 'phase' */ + uint32_t noise_f; /* current noise period */ + + uint8_t wavesel; /* waveform select enable flag */ int T[2]; /* timer counters */ - UINT8 st[2]; /* timer enable */ + uint8_t st[2]; /* timer enable */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ + + uint8_t address; /* address register */ + uint8_t status; /* status flag */ + uint8_t statusmask; /* status mask */ + uint8_t mode; /* Reg.08 : CSM,notesel,etc. */ bool IsStereo; /* Write stereo output */ -} FM_OPL; +}; @@ -278,68 +271,67 @@ static const int slot_array[32]= /* table is 3dB/octave , DV converts this into 6dB/octave */ /* 0.1875 is bit 0 weight of the envelope counter (volume) expressed in the 'decibel' scale */ #define DV (0.1875/2.0) -static const UINT32 ksl_tab[8*16]= +static const uint32_t ksl_tab[8*16]= { /* OCT 0 */ - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), /* OCT 1 */ - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(0.750/DV), UINT32(1.125/DV), UINT32(1.500/DV), - UINT32(1.875/DV), UINT32(2.250/DV), UINT32(2.625/DV), UINT32(3.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(0.750/DV), uint32_t(1.125/DV), uint32_t(1.500/DV), + uint32_t(1.875/DV), uint32_t(2.250/DV), uint32_t(2.625/DV), uint32_t(3.000/DV), /* OCT 2 */ - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), - UINT32(0.000/DV), UINT32(1.125/DV), UINT32(1.875/DV), UINT32(2.625/DV), - UINT32(3.000/DV), UINT32(3.750/DV), UINT32(4.125/DV), UINT32(4.500/DV), - UINT32(4.875/DV), UINT32(5.250/DV), UINT32(5.625/DV), UINT32(6.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), + uint32_t(0.000/DV), uint32_t(1.125/DV), uint32_t(1.875/DV), uint32_t(2.625/DV), + uint32_t(3.000/DV), uint32_t(3.750/DV), uint32_t(4.125/DV), uint32_t(4.500/DV), + uint32_t(4.875/DV), uint32_t(5.250/DV), uint32_t(5.625/DV), uint32_t(6.000/DV), /* OCT 3 */ - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(0.000/DV), UINT32(1.875/DV), - UINT32(3.000/DV), UINT32(4.125/DV), UINT32(4.875/DV), UINT32(5.625/DV), - UINT32(6.000/DV), UINT32(6.750/DV), UINT32(7.125/DV), UINT32(7.500/DV), - UINT32(7.875/DV), UINT32(8.250/DV), UINT32(8.625/DV), UINT32(9.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(1.875/DV), + uint32_t(3.000/DV), uint32_t(4.125/DV), uint32_t(4.875/DV), uint32_t(5.625/DV), + uint32_t(6.000/DV), uint32_t(6.750/DV), uint32_t(7.125/DV), uint32_t(7.500/DV), + uint32_t(7.875/DV), uint32_t(8.250/DV), uint32_t(8.625/DV), uint32_t(9.000/DV), /* OCT 4 */ - UINT32(0.000/DV), UINT32(0.000/DV), UINT32(3.000/DV), UINT32(4.875/DV), - UINT32(6.000/DV), UINT32(7.125/DV), UINT32(7.875/DV), UINT32(8.625/DV), - UINT32(9.000/DV), UINT32(9.750/DV),UINT32(10.125/DV),UINT32(10.500/DV), - UINT32(10.875/DV),UINT32(11.250/DV),UINT32(11.625/DV),UINT32(12.000/DV), + uint32_t(0.000/DV), uint32_t(0.000/DV), uint32_t(3.000/DV), uint32_t(4.875/DV), + uint32_t(6.000/DV), uint32_t(7.125/DV), uint32_t(7.875/DV), uint32_t(8.625/DV), + uint32_t(9.000/DV), uint32_t(9.750/DV),uint32_t(10.125/DV),uint32_t(10.500/DV), + uint32_t(10.875/DV),uint32_t(11.250/DV),uint32_t(11.625/DV),uint32_t(12.000/DV), /* OCT 5 */ - UINT32(0.000/DV), UINT32(3.000/DV), UINT32(6.000/DV), UINT32(7.875/DV), - UINT32(9.000/DV),UINT32(10.125/DV),UINT32(10.875/DV),UINT32(11.625/DV), - UINT32(12.000/DV),UINT32(12.750/DV),UINT32(13.125/DV),UINT32(13.500/DV), - UINT32(13.875/DV),UINT32(14.250/DV),UINT32(14.625/DV),UINT32(15.000/DV), + uint32_t(0.000/DV), uint32_t(3.000/DV), uint32_t(6.000/DV), uint32_t(7.875/DV), + uint32_t(9.000/DV),uint32_t(10.125/DV),uint32_t(10.875/DV),uint32_t(11.625/DV), + uint32_t(12.000/DV),uint32_t(12.750/DV),uint32_t(13.125/DV),uint32_t(13.500/DV), + uint32_t(13.875/DV),uint32_t(14.250/DV),uint32_t(14.625/DV),uint32_t(15.000/DV), /* OCT 6 */ - UINT32(0.000/DV), UINT32(6.000/DV), UINT32(9.000/DV),UINT32(10.875/DV), - UINT32(12.000/DV),UINT32(13.125/DV),UINT32(13.875/DV),UINT32(14.625/DV), - UINT32(15.000/DV),UINT32(15.750/DV),UINT32(16.125/DV),UINT32(16.500/DV), - UINT32(16.875/DV),UINT32(17.250/DV),UINT32(17.625/DV),UINT32(18.000/DV), + uint32_t(0.000/DV), uint32_t(6.000/DV), uint32_t(9.000/DV),uint32_t(10.875/DV), + uint32_t(12.000/DV),uint32_t(13.125/DV),uint32_t(13.875/DV),uint32_t(14.625/DV), + uint32_t(15.000/DV),uint32_t(15.750/DV),uint32_t(16.125/DV),uint32_t(16.500/DV), + uint32_t(16.875/DV),uint32_t(17.250/DV),uint32_t(17.625/DV),uint32_t(18.000/DV), /* OCT 7 */ - UINT32(0.000/DV), UINT32(9.000/DV),UINT32(12.000/DV),UINT32(13.875/DV), - UINT32(15.000/DV),UINT32(16.125/DV),UINT32(16.875/DV),UINT32(17.625/DV), - UINT32(18.000/DV),UINT32(18.750/DV),UINT32(19.125/DV),UINT32(19.500/DV), - UINT32(19.875/DV),UINT32(20.250/DV),UINT32(20.625/DV),UINT32(21.000/DV) + uint32_t(0.000/DV), uint32_t(9.000/DV),uint32_t(12.000/DV),uint32_t(13.875/DV), + uint32_t(15.000/DV),uint32_t(16.125/DV),uint32_t(16.875/DV),uint32_t(17.625/DV), + uint32_t(18.000/DV),uint32_t(18.750/DV),uint32_t(19.125/DV),uint32_t(19.500/DV), + uint32_t(19.875/DV),uint32_t(20.250/DV),uint32_t(20.625/DV),uint32_t(21.000/DV) }; #undef DV /* 0 / 3.0 / 1.5 / 6.0 dB/OCT */ -static const UINT32 ksl_shift[4] = { 31, 1, 2, 0 }; +static const uint32_t ksl_shift[4] = { 31, 1, 2, 0 }; /* sustain level table (3dB per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (UINT32) ( db * (2.0/ENV_STEP) ) -static const UINT32 sl_tab[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) +#define SC(db) (uint32_t) ( db * (2.0/ENV_STEP) ) +static const uint32_t sl_tab[16]={ + SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), + SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) }; #undef SC #define RATE_STEPS (8) static const unsigned char eg_inc[15*RATE_STEPS]={ - /*cycle:0 1 2 3 4 5 6 7*/ /* 0 */ 0,1, 0,1, 0,1, 0,1, /* rates 00..12 0 (increment by 0 or 1) */ @@ -366,7 +358,7 @@ static const unsigned char eg_inc[15*RATE_STEPS]={ #define O(a) (a*RATE_STEPS) /*note that there is no O(13) in this table - it's directly in the code */ -static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ +static const unsigned char eg_rate_select[16+64+16]={ /* Envelope Generator rates (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), O(14),O(14),O(14),O(14),O(14),O(14),O(14),O(14), @@ -407,7 +399,7 @@ O(12),O(12),O(12),O(12),O(12),O(12),O(12),O(12), /*mask 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0, 0, 0, 0 */ #define O(a) (a*1) -static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ +static const unsigned char eg_rate_shift[16+64+16]={ /* Envelope Generator counter shifts (16 + 64 rates + 16 RKS) */ /* 16 infinite time rates */ O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), O(0),O(0),O(0),O(0),O(0),O(0),O(0),O(0), @@ -446,22 +438,22 @@ O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0),O( 0), /* multiple table */ #define ML 2 -static const UINT8 mul_tab[16]= { +static const uint8_t mul_tab[16]= { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ - UINT8(0.50*ML), UINT8(1.00*ML), UINT8(2.00*ML), UINT8(3.00*ML), UINT8(4.00*ML), UINT8(5.00*ML), UINT8(6.00*ML), UINT8(7.00*ML), - UINT8(8.00*ML), UINT8(9.00*ML),UINT8(10.00*ML),UINT8(10.00*ML),UINT8(12.00*ML),UINT8(12.00*ML),UINT8(15.00*ML),UINT8(15.00*ML) + uint8_t(0.50*ML), uint8_t(1.00*ML), uint8_t(2.00*ML), uint8_t(3.00*ML), uint8_t(4.00*ML), uint8_t(5.00*ML), uint8_t(6.00*ML), uint8_t(7.00*ML), + uint8_t(8.00*ML), uint8_t(9.00*ML),uint8_t(10.00*ML),uint8_t(10.00*ML),uint8_t(12.00*ML),uint8_t(12.00*ML),uint8_t(15.00*ML),uint8_t(15.00*ML) }; #undef ML -/* TL_TAB_LEN is calculated as: -* 12 - sinus amplitude bits (Y axis) -* 2 - sinus sign bit (Y axis) -* TL_RES_LEN - sinus resolution (X axis) +/* TL_TAB_LEN is calculated as: +* 12 - sinus amplitude bits (Y axis) +* 2 - sinus sign bit (Y axis) +* TL_RES_LEN - sinus resolution (X axis) */ #define TL_TAB_LEN (12*2*TL_RES_LEN) static signed int tl_tab[TL_TAB_LEN]; -#define ENV_QUIET (TL_TAB_LEN>>4) +#define ENV_QUIET (TL_TAB_LEN>>4) /* sin waveform table in 'decibel' scale */ /* four waveforms on OPL2 type chips */ @@ -473,17 +465,17 @@ static unsigned int sin_tab[SIN_LEN * 4]; Length: 210 elements. - Each of the elements has to be repeated - exactly 64 times (on 64 consecutive samples). - The whole table takes: 64 * 210 = 13440 samples. + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. - When AM = 1 data is used directly - When AM = 0 data is divided by 4 before being used (loosing precision is important) + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (losing precision is important) */ #define LFO_AM_TAB_ELEMENTS 210 -static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { +static const uint8_t lfo_am_table[LFO_AM_TAB_ELEMENTS] = { 0,0,0,0,0,0,0, 1,1,1,1, 2,2,2,2, @@ -539,39 +531,38 @@ static const UINT8 lfo_am_table[LFO_AM_TAB_ELEMENTS] = { }; /* LFO Phase Modulation table (verified on real YM3812) */ -static const INT8 lfo_pm_table[8*8*2] = { - +static const int8_t lfo_pm_table[8*8*2] = { /* FNUM2/FNUM = 00 0xxxxxxx (0x0000) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 00 1xxxxxxx (0x0080) */ -0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ +0, 0, 0, 0, 0, 0, 0, 0, /*LFO PM depth = 0*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 01 0xxxxxxx (0x0100) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 01 1xxxxxxx (0x0180) */ -1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ +1, 0, 0, 0,-1, 0, 0, 0, /*LFO PM depth = 0*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 10 0xxxxxxx (0x0200) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +4, 2, 0,-2,-4,-2, 0, 2, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 10 1xxxxxxx (0x0280) */ -2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ -5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ +2, 1, 0,-1,-2,-1, 0, 1, /*LFO PM depth = 0*/ +5, 2, 0,-2,-5,-2, 0, 2, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 11 0xxxxxxx (0x0300) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +6, 3, 0,-3,-6,-3, 0, 3, /*LFO PM depth = 1*/ /* FNUM2/FNUM = 11 1xxxxxxx (0x0380) */ -3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ -7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ +3, 1, 0,-1,-3,-1, 0, 1, /*LFO PM depth = 0*/ +7, 3, 0,-3,-7,-3, 0, 3 /*LFO PM depth = 1*/ }; @@ -582,8 +573,8 @@ static int num_lock = 0; static signed int phase_modulation; /* phase modulation input (SLOT 2) */ static signed int output; -static UINT32 LFO_AM; -static INT32 LFO_PM; +static uint32_t LFO_AM; +static int32_t LFO_PM; static bool CalcVoice (FM_OPL *OPL, int voice, float *buffer, int length); static bool CalcRhythm (FM_OPL *OPL, float *buffer, int length); @@ -591,21 +582,21 @@ static bool CalcRhythm (FM_OPL *OPL, float *buffer, int length); /* status set and IRQ handling */ -INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) +static inline void OPL_STATUS_SET(FM_OPL *OPL,int flag) { /* set status flag */ OPL->status |= flag; if(!(OPL->status & 0x80)) { if(OPL->status & OPL->statusmask) - { /* IRQ on */ + { /* IRQ on */ OPL->status |= 0x80; } } } /* status reset and IRQ handling */ -INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) +static inline void OPL_STATUS_RESET(FM_OPL *OPL,int flag) { /* reset status flag */ OPL->status &=~flag; @@ -619,7 +610,7 @@ INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) } /* IRQ mask set */ -INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) +static inline void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) { OPL->statusmask = flag; /* IRQ handling check */ @@ -629,13 +620,13 @@ INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) /* advance LFO to next sample */ -INLINE void advance_lfo(FM_OPL *OPL) +static inline void advance_lfo(FM_OPL *OPL) { - UINT8 tmp; + uint8_t tmp; /* LFO */ OPL->lfo_am_cnt += OPL->lfo_am_inc; - if (OPL->lfo_am_cnt >= (UINT32)(LFO_AM_TAB_ELEMENTS<lfo_am_cnt >= (uint32_t)(LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; @@ -650,7 +641,7 @@ INLINE void advance_lfo(FM_OPL *OPL) } /* advance to next sample */ -INLINE void advance(FM_OPL *OPL, int loch, int hich) +static inline void advance(FM_OPL *OPL, int loch, int hich) { OPL_CH *CH; OPL_SLOT *op; @@ -690,28 +681,28 @@ INLINE void advance(FM_OPL *OPL, int loch, int hich) } break; - case EG_DEC: /* decay phase */ + case EG_DEC: /* decay phase */ if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) { op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; - if ( op->volume >= (INT32)op->sl ) + if ( op->volume >= (int32_t)op->sl ) op->state = EG_SUS; } break; - case EG_SUS: /* sustain phase */ + case EG_SUS: /* sustain phase */ /* this is important behaviour: one can change percusive/non-percussive modes on the fly and the chip will remain in sustain phase - verified on real YM3812 */ - if(op->eg_type) /* non-percussive mode */ + if(op->eg_type) /* non-percussive mode */ { /* do nothing */ } - else /* percussive mode */ + else /* percussive mode */ { /* during sustain phase chip adds Release Rate (in percussive mode) */ if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) @@ -725,7 +716,7 @@ INLINE void advance(FM_OPL *OPL, int loch, int hich) } break; - case EG_REL: /* release phase */ + case EG_REL: /* release phase */ if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) { op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; @@ -746,7 +737,7 @@ INLINE void advance(FM_OPL *OPL, int loch, int hich) /* Phase Generator */ if(op->vib) { - UINT8 block; + uint8_t block; unsigned int block_fnum = CH->block_fnum; unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; @@ -772,37 +763,37 @@ INLINE void advance(FM_OPL *OPL, int loch, int hich) } } -INLINE void advance_noise(FM_OPL *OPL) +static inline void advance_noise(FM_OPL *OPL) { int i; - /* The Noise Generator of the YM3812 is 23-bit shift register. - * Period is equal to 2^23-2 samples. - * Register works at sampling frequency of the chip, so output - * can change on every sample. + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. * - * Output of the register and input to the bit 22 is: - * bit0 XOR bit14 XOR bit15 XOR bit22 + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 * - * Simply use bit 22 as the noise output. + * Simply use bit 22 as the noise output. */ OPL->noise_p += OPL->noise_f; - i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ OPL->noise_p &= FREQ_MASK; while (i) { /* - UINT32 j; + uint32_t j; j = ( (OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22) ) & 1; OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); */ /* - Instead of doing all the logic operations above, we - use a trick here (and use bit 0 as the noise output). - The difference is only that the noise bit changes one - step ahead. This doesn't matter since we don't know + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know what is real state of the noise_rng after the reset. */ @@ -814,9 +805,9 @@ INLINE void advance_noise(FM_OPL *OPL) } -INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +static inline signed int op_calc(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) { - UINT32 p; + uint32_t p; p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm<<16))) >> FREQ_SH ) & SIN_MASK) ]; @@ -825,9 +816,9 @@ INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigne return tl_tab[p]; } -INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) +static inline signed int op_calc1(uint32_t phase, unsigned int env, signed int pm, unsigned int wave_tab) { - UINT32 p; + uint32_t p; p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm )) >> FREQ_SH ) & SIN_MASK) ]; @@ -837,10 +828,10 @@ INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsign } -#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) +#define volume_calc(OP) ((OP)->TLL + ((uint32_t)(OP)->volume) + (LFO_AM & (OP)->AMmask)) /* calculate output */ -INLINE float OPL_CALC_CH( OPL_CH *CH ) +static inline float OPL_CALC_CH( OPL_CH *CH ) { OPL_SLOT *SLOT; unsigned int env; @@ -875,9 +866,9 @@ INLINE float OPL_CALC_CH( OPL_CH *CH ) } /* - operators used in the rhythm sounds generation process: + operators used in the rhythm sounds generation process: - Envelope Generator: + Envelope Generator: channel operator register number Bass High Snare Tom Top / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal @@ -911,7 +902,7 @@ number number BLK/FNUM2 FNUM Drum Hat Drum Tom Cymbal /* calculate rhythm */ -INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) +static inline void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) { OPL_SLOT *SLOT; signed int out; @@ -988,7 +979,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) /* when res1 = 0 phase = 0x000 | 0xd0; */ /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ - UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + uint32_t phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; /* enable gate based on frequency of operator 2 in channel 8 */ unsigned char bit5e= ((CH[8].SLOT[SLOT2].Cnt>>FREQ_SH)>>5)&1; @@ -1029,7 +1020,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) /* when bit8 = 0 phase = 0x100; */ /* when bit8 = 1 phase = 0x200; */ - UINT32 phase = bit8 ? 0x200 : 0x100; + uint32_t phase = bit8 ? 0x200 : 0x100; /* Noise bit XOR'es phase by 0x100 */ /* when noisebit = 0 pass the phase from calculation above */ @@ -1059,7 +1050,7 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) /* when res1 = 0 phase = 0x000 | 0x100; */ /* when res1 = 1 phase = 0x200 | 0x100; */ - UINT32 phase = res1 ? 0x300 : 0x100; + uint32_t phase = res1 ? 0x300 : 0x100; /* enable gate based on frequency of operator 2 in channel 8 */ unsigned char bit5e= ((CH[8].SLOT[SLOT2].Cnt>>FREQ_SH)>>5)&1; @@ -1073,7 +1064,6 @@ INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) output += op_calc(phase<>= 4; /* 12 bits here */ + n = (int)m; /* 16 bits here */ + n >>= 4; /* 12 bits here */ n = (n+1)>>1; /* round to nearest */ /* 11 bits here (rounded) */ - n <<= 1; /* 12 bits here (as in real chip) */ + n <<= 1; /* 12 bits here (as in real chip) */ tl_tab[ x*2 + 0 ] = n; tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; @@ -1123,14 +1113,14 @@ static void init_tables(void) /* we never reach zero here due to ((i*2)+1) */ if (m>0.0) - o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ else - o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ o = o / (ENV_STEP/4); n = (int)(2.0*o); - if (n&1) /* round to nearest */ + if (n&1) /* round to nearest */ n = (n>>1)+1; else n = n>>1; @@ -1176,18 +1166,18 @@ static void OPL_initalize(FM_OPL *OPL) for( i=0 ; i < 1024 ; i++ ) { /* opn phase increment counter = 20bit */ - OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL_FREQBASE * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ + OPL->fn_tab[i] = (uint32_t)( (double)i * 64 * OPL_FREQBASE * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ } /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ /* One entry from LFO_AM_TABLE lasts for 64 samples */ - OPL->lfo_am_inc = UINT32((1.0 / 64.0 ) * (1<lfo_am_inc = uint32_t((1.0 / 64.0 ) * (1<lfo_pm_inc = UINT32((1.0 / 1024.0) * (1<lfo_pm_inc = uint32_t((1.0 / 1024.0) * (1<eg_timer_add = UINT32((1<eg_timer_overflow = UINT32(( 1 ) * (1<eg_timer_add = uint32_t((1<eg_timer_overflow = uint32_t(( 1 ) * (1<IsStereo = false; @@ -1198,7 +1188,7 @@ static void OPL_initalize(FM_OPL *OPL) } } -INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) +static inline void FM_KEYON(OPL_SLOT *SLOT, uint32_t key_set) { if( !SLOT->key ) { @@ -1210,7 +1200,7 @@ INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) SLOT->key |= key_set; } -INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) +static inline void FM_KEYOFF(OPL_SLOT *SLOT, uint32_t key_clr) { if( SLOT->key ) { @@ -1226,7 +1216,7 @@ INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) } /* update phase increment counter of operator (also update the EG rates if necessary) */ -void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) +static inline void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) { int ksr; @@ -1257,7 +1247,7 @@ void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) } /* set multi,am,vib,EG-TYP,KSR,mul */ -void set_mul(FM_OPL *OPL,int slot,int v) +static inline void set_mul(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; @@ -1271,7 +1261,7 @@ void set_mul(FM_OPL *OPL,int slot,int v) } /* set ksl & tl */ -void set_ksl_tl(FM_OPL *OPL,int slot,int v) +static inline void set_ksl_tl(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; @@ -1283,7 +1273,7 @@ void set_ksl_tl(FM_OPL *OPL,int slot,int v) } /* set attack rate & decay rate */ -INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) +static inline void set_ar_dr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; @@ -1307,7 +1297,7 @@ INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) } /* set sustain level & release rate */ -void set_sl_rr(FM_OPL *OPL,int slot,int v) +static inline void set_sl_rr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; @@ -1333,31 +1323,32 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) switch(r&0xe0) { - case 0x00: /* 00-1f:control */ + case 0x00: /* 00-1f:control */ switch(r&0x1f) { case 0x01: /* waveform select enable */ OPL->wavesel = v&0x20; break; - case 0x02: /* Timer 1 */ + case 0x02: /* Timer 1 */ OPL->T[0] = (256-v)*4; break; - case 0x03: /* Timer 2 */ + case 0x03: /* Timer 2 */ OPL->T[1] = (256-v)*16; break; - case 0x04: /* IRQ clear / mask and Timer enable */ + case 0x04: /* IRQ clear / mask and Timer enable */ if(v&0x80) - { /* IRQ flag clear */ + { /* IRQ flag clear */ OPL_STATUS_RESET(OPL,0x7f-0x08); /* don't reset BFRDY flag or we will have to call deltat module to set the flag */ } else - { /* set IRQ mask ,timer enable*/ - UINT8 st1 = v&1; - UINT8 st2 = (v>>1)&1; + { /* set IRQ mask ,timer enable*/ + uint8_t st1 = v&1; + uint8_t st2 = (v>>1)&1; /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ OPL_STATUS_RESET(OPL, v & (0x78-0x08) ); OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); + /* timer 2 */ if(OPL->st[1] != st2) { @@ -1375,7 +1366,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) break; } break; - case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ slot = slot_array[r&0x1f]; if(slot < 0) return; set_mul(OPL,slot,v); @@ -1396,7 +1387,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) set_sl_rr(OPL,slot,v); break; case 0xa0: - if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ { OPL->lfo_am_depth = v & 0x80; OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; @@ -1449,11 +1440,11 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) if( (r&0x0f) > 8) return; CH = &OPL->P_CH[r&0x0f]; if(!(r&0x10)) - { /* a0-a8 */ + { /* a0-a8 */ block_fnum = (CH->block_fnum&0x1f00) | v; } else - { /* b0-b8 */ + { /* b0-b8 */ block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); if(v&0x20) @@ -1468,9 +1459,9 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) } } /* update */ - if(CH->block_fnum != (UINT32)block_fnum) + if(CH->block_fnum != (uint32_t)block_fnum) { - UINT8 block = block_fnum >> 10; + uint8_t block = block_fnum >> 10; CH->block_fnum = block_fnum; @@ -1480,13 +1471,13 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ CH->kcode = (CH->block_fnum&0x1c00)>>9; - /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ + /* the info below is actually opposite to what is stated in the Manuals (verifed on real YM3812) */ /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ if (OPL->mode&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ else - CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ /* refresh Total Level in both SLOTs of this channel */ CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); @@ -1527,8 +1518,8 @@ static void OPLResetChip(FM_OPL *OPL) OPL->eg_timer = 0; OPL->eg_cnt = 0; - OPL->noise_rng = 1; /* noise shift register */ - OPL->mode = 0; /* normal mode */ + OPL->noise_rng = 1; /* noise shift register */ + OPL->mode = 0; /* normal mode */ OPL_STATUS_RESET(OPL,0x7f); /* reset with register write */ @@ -1604,15 +1595,15 @@ public: { int i; - UINT8 rhythm = Chip.rhythm&0x20; + uint8_t rhythm = Chip.rhythm&0x20; - UINT32 lfo_am_cnt_bak = Chip.lfo_am_cnt; - UINT32 eg_timer_bak = Chip.eg_timer; - UINT32 eg_cnt_bak = Chip.eg_cnt; + uint32_t lfo_am_cnt_bak = Chip.lfo_am_cnt; + uint32_t eg_timer_bak = Chip.eg_timer; + uint32_t eg_cnt_bak = Chip.eg_cnt; - UINT32 lfo_am_cnt_out = lfo_am_cnt_bak; - UINT32 eg_timer_out = eg_timer_bak; - UINT32 eg_cnt_out = eg_cnt_bak; + uint32_t lfo_am_cnt_out = lfo_am_cnt_bak; + uint32_t eg_timer_out = eg_timer_bak; + uint32_t eg_cnt_out = eg_cnt_bak; for (i = 0; i <= (rhythm ? 5 : 8); ++i) { diff --git a/src/oplsynth/mlopl.cpp b/src/oplsynth/mlopl.cpp index 7baacc946..bbff8b5fd 100644 --- a/src/oplsynth/mlopl.cpp +++ b/src/oplsynth/mlopl.cpp @@ -69,12 +69,12 @@ musicBlock::~musicBlock () if (OPLinstruments != NULL) free(OPLinstruments); } -void musicBlock::writeFrequency(uint slot, uint note, int pitch, uint keyOn) +void musicBlock::writeFrequency(uint32_t slot, uint32_t note, int pitch, uint32_t keyOn) { io->OPLwriteFreq (slot, note, pitch, keyOn); } -void musicBlock::writeModulation(uint slot, struct OPL2instrument *instr, int state) +void musicBlock::writeModulation(uint32_t slot, struct OPL2instrument *instr, int state) { if (state) state = 0x40; /* enable Frequency Vibrato */ @@ -83,17 +83,17 @@ void musicBlock::writeModulation(uint slot, struct OPL2instrument *instr, int st instr->trem_vibr_2 | state); } -uint musicBlock::calcVolume(uint channelVolume, uint channelExpression, uint noteVolume) +uint32_t musicBlock::calcVolume(uint32_t channelVolume, uint32_t channelExpression, uint32_t noteVolume) { - noteVolume = ((ulong)channelVolume * channelExpression * noteVolume) / (127*127); + noteVolume = ((uint64_t)channelVolume * channelExpression * noteVolume) / (127*127); if (noteVolume > 127) return 127; else return noteVolume; } -int musicBlock::occupyChannel(uint slot, uint channel, - int note, int volume, struct OP2instrEntry *instrument, uchar secondary) +int musicBlock::occupyChannel(uint32_t slot, uint32_t channel, + int note, int volume, struct OP2instrEntry *instrument, uint8_t secondary) { struct OPL2instrument *instr; struct channelEntry *ch = &channels[slot]; @@ -142,7 +142,7 @@ int musicBlock::occupyChannel(uint slot, uint channel, return slot; } -int musicBlock::releaseChannel(uint slot, uint killed) +int musicBlock::releaseChannel(uint32_t slot, uint32_t killed) { struct channelEntry *ch = &channels[slot]; writeFrequency(slot, ch->realnote, ch->pitch, 0); @@ -157,10 +157,10 @@ int musicBlock::releaseChannel(uint slot, uint killed) return slot; } -int musicBlock::releaseSustain(uint channel) +int musicBlock::releaseSustain(uint32_t channel) { - uint i; - uint id = channel; + uint32_t i; + uint32_t id = channel; for(i = 0; i < io->OPLchannels; i++) { @@ -170,16 +170,16 @@ int musicBlock::releaseSustain(uint channel) return 0; } -int musicBlock::findFreeChannel(uint flag, uint channel, uchar note) +int musicBlock::findFreeChannel(uint32_t flag, uint32_t channel, uint8_t note) { - uint i; + uint32_t i; - ulong bestfit = 0; - uint bestvoice = 0; + uint32_t bestfit = 0; + uint32_t bestvoice = 0; for (i = 0; i < io->OPLchannels; ++i) { - ulong magic; + uint32_t magic; magic = ((channels[i].flags & CH_FREE) << 24) | ((channels[i].note == note && @@ -200,9 +200,9 @@ int musicBlock::findFreeChannel(uint flag, uint channel, uchar note) return bestvoice; } -struct OP2instrEntry *musicBlock::getInstrument(uint channel, uchar note) +struct OP2instrEntry *musicBlock::getInstrument(uint32_t channel, uint8_t note) { - uint instrnumber; + uint32_t instrnumber; if (channel == PERCUSSION) { @@ -225,7 +225,7 @@ struct OP2instrEntry *musicBlock::getInstrument(uint channel, uchar note) // code 1: play note CVAR (Bool, opl_singlevoice, 0, 0) -void musicBlock::OPLplayNote(uint channel, uchar note, int volume) +void musicBlock::OPLplayNote(uint32_t channel, uint8_t note, int volume) { int i; struct OP2instrEntry *instr; @@ -251,11 +251,11 @@ void musicBlock::OPLplayNote(uint channel, uchar note, int volume) } // code 0: release note -void musicBlock::OPLreleaseNote(uint channel, uchar note) +void musicBlock::OPLreleaseNote(uint32_t channel, uint8_t note) { - uint i; - uint id = channel; - uint sustain = driverdata.channelSustain[channel]; + uint32_t i; + uint32_t id = channel; + uint32_t sustain = driverdata.channelSustain[channel]; for(i = 0; i < io->OPLchannels; i++) { @@ -270,10 +270,10 @@ void musicBlock::OPLreleaseNote(uint channel, uchar note) } // code 2: change pitch wheel (bender) -void musicBlock::OPLpitchWheel(uint channel, int pitch) +void musicBlock::OPLpitchWheel(uint32_t channel, int pitch) { - uint i; - uint id = channel; + uint32_t i; + uint32_t id = channel; // Convert pitch from 14-bit to 7-bit, then scale it, since the player // code only understands sensitivities of 2 semitones. @@ -292,10 +292,10 @@ void musicBlock::OPLpitchWheel(uint channel, int pitch) } // code 4: change control -void musicBlock::OPLchangeControl(uint channel, uchar controller, int value) +void musicBlock::OPLchangeControl(uint32_t channel, uint8_t controller, int value) { - uint i; - uint id = channel; + uint32_t i; + uint32_t id = channel; switch (controller) { @@ -310,7 +310,7 @@ void musicBlock::OPLchangeControl(uint channel, uchar controller, int value) struct channelEntry *ch = &channels[i]; if (ch->channel == id) { - uchar flags = ch->flags; + uint8_t flags = ch->flags; ch->time = MLtime; if (value >= MOD_MIN) { @@ -418,7 +418,7 @@ void musicBlock::OPLchangeControl(uint channel, uchar controller, int value) } } -void musicBlock::OPLresetControllers(uint chan, int vol) +void musicBlock::OPLresetControllers(uint32_t chan, int vol) { driverdata.channelVolume[chan] = vol; driverdata.channelExpression[chan] = 127; @@ -429,14 +429,14 @@ void musicBlock::OPLresetControllers(uint chan, int vol) driverdata.channelPitchSens[chan] = 200; } -void musicBlock::OPLprogramChange(uint channel, int value) +void musicBlock::OPLprogramChange(uint32_t channel, int value) { driverdata.channelInstr[channel] = value; } void musicBlock::OPLplayMusic(int vol) { - uint i; + uint32_t i; for (i = 0; i < CHANNELS; i++) { @@ -446,7 +446,7 @@ void musicBlock::OPLplayMusic(int vol) void musicBlock::OPLstopMusic() { - uint i; + uint32_t i; for(i = 0; i < io->OPLchannels; i++) if (!(channels[i].flags & CH_FREE)) releaseChannel(i, 1); @@ -454,10 +454,10 @@ void musicBlock::OPLstopMusic() int musicBlock::OPLloadBank (FileReader &data) { - static const uchar masterhdr[8] = { '#','O','P','L','_','I','I','#' }; + static const uint8_t masterhdr[8] = { '#','O','P','L','_','I','I','#' }; struct OP2instrEntry *instruments; - uchar filehdr[8]; + uint8_t filehdr[8]; data.Read (filehdr, 8); if (memcmp(filehdr, masterhdr, 8)) diff --git a/src/oplsynth/mlopl_io.cpp b/src/oplsynth/mlopl_io.cpp index e6ed3bba8..4e88ac108 100644 --- a/src/oplsynth/mlopl_io.cpp +++ b/src/oplsynth/mlopl_io.cpp @@ -22,7 +22,7 @@ * Oct-30-1994 V1.40 V.Arnost * Added BLASTER variable parsing * Apr-14-1995 V1.50 V.Arnost -* Some declarations moved from adlib.h to deftypes.h +* Some declarations moved from adlib.h to doomtype.h * Jul-22-1995 V1.60 V.Arnost * Ported to Watcom C * Simplified WriteChannel() and WriteValue() @@ -63,7 +63,7 @@ void OPLio::WriteDelay(int ticks) { } -void OPLio::OPLwriteReg(int which, uint reg, uchar data) +void OPLio::OPLwriteReg(int which, uint32_t reg, uint8_t data) { if (IsOPL3) { @@ -80,13 +80,13 @@ void OPLio::OPLwriteReg(int which, uint reg, uchar data) * Write to an operator pair. To be used for register bases of 0x20, 0x40, * 0x60, 0x80 and 0xE0. */ -void OPLio::OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2) +void OPLio::OPLwriteChannel(uint32_t regbase, uint32_t channel, uint8_t data1, uint8_t data2) { - static const uint op_num[OPL2CHANNELS] = { + static const uint32_t op_num[OPL2CHANNELS] = { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12}; - uint which = channel / OPL2CHANNELS; - uint reg = regbase + op_num[channel % OPL2CHANNELS]; + uint32_t which = channel / OPL2CHANNELS; + uint32_t reg = regbase + op_num[channel % OPL2CHANNELS]; OPLwriteReg (which, reg, data1); OPLwriteReg (which, reg+3, data2); } @@ -95,10 +95,10 @@ void OPLio::OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2 * Write to channel a single value. To be used for register bases of * 0xA0, 0xB0 and 0xC0. */ -void OPLio::OPLwriteValue(uint regbase, uint channel, uchar value) +void OPLio::OPLwriteValue(uint32_t regbase, uint32_t channel, uint8_t value) { - uint which = channel / OPL2CHANNELS; - uint reg = regbase + (channel % OPL2CHANNELS); + uint32_t which = channel / OPL2CHANNELS; + uint32_t reg = regbase + (channel % OPL2CHANNELS); OPLwriteReg (which, reg, value); } @@ -174,7 +174,7 @@ static WORD frequencies[] = * That last byte in the table doesn't look right, either, but that's what * it really is. */ -void OPLio::OPLwriteFreq(uint channel, uint note, uint pitch, uint keyon) +void OPLio::OPLwriteFreq(uint32_t channel, uint32_t note, uint32_t pitch, uint32_t keyon) { int octave = 0; int j = (note << 5) + pitch; @@ -202,9 +202,9 @@ void OPLio::OPLwriteFreq(uint channel, uint note, uint pitch, uint keyon) /* * Adjust volume value (register 0x40) */ -inline uint OPLio::OPLconvertVolume(uint data, uint volume) +inline uint32_t OPLio::OPLconvertVolume(uint32_t data, uint32_t volume) { - static uchar volumetable[128] = { + static uint8_t volumetable[128] = { 0, 1, 3, 5, 6, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 27, 29, 30, 32, 33, 34, @@ -223,11 +223,11 @@ inline uint OPLio::OPLconvertVolume(uint data, uint volume) 124, 124, 125, 125, 126, 126, 127, 127}; return 0x3F - (((0x3F - data) * - (uint)volumetable[volume <= 127 ? volume : 127]) >> 7); + (uint32_t)volumetable[volume <= 127 ? volume : 127]) >> 7); } -uint OPLio::OPLpanVolume(uint volume, int pan) +uint32_t OPLio::OPLpanVolume(uint32_t volume, int pan) { if (pan >= 0) return volume; @@ -238,7 +238,7 @@ uint OPLio::OPLpanVolume(uint volume, int pan) /* * Write volume data to a channel */ -void OPLio::OPLwriteVolume(uint channel, struct OPL2instrument *instr, uint volume) +void OPLio::OPLwriteVolume(uint32_t channel, struct OPL2instrument *instr, uint32_t volume) { if (instr != 0) { @@ -251,11 +251,11 @@ void OPLio::OPLwriteVolume(uint channel, struct OPL2instrument *instr, uint volu /* * Write pan (balance) data to a channel */ -void OPLio::OPLwritePan(uint channel, struct OPL2instrument *instr, int pan) +void OPLio::OPLwritePan(uint32_t channel, struct OPL2instrument *instr, int pan) { if (instr != 0) { - uchar bits; + uint8_t bits; if (pan < -36) bits = 0x10; // left else if (pan > 36) bits = 0x20; // right else bits = 0x30; // both @@ -292,7 +292,7 @@ void OPLio::OPLwritePan(uint channel, struct OPL2instrument *instr, int pan) * data[5] data[12] reg. 0x40 - output level (bottom 6 bits only) * data[6] reg. 0xC0 - feedback/AM-FM (both operators) */ -void OPLio::OPLwriteInstrument(uint channel, struct OPL2instrument *instr) +void OPLio::OPLwriteInstrument(uint32_t channel, struct OPL2instrument *instr) { OPLwriteChannel(0x40, channel, 0x3F, 0x3F); // no volume OPLwriteChannel(0x20, channel, instr->trem_vibr_1, instr->trem_vibr_2); @@ -307,7 +307,7 @@ void OPLio::OPLwriteInstrument(uint channel, struct OPL2instrument *instr) */ void OPLio::OPLshutup(void) { - uint i; + uint32_t i; for(i = 0; i < OPLchannels; i++) { @@ -321,10 +321,10 @@ void OPLio::OPLshutup(void) /* * Initialize hardware upon startup */ -int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3) +int OPLio::OPLinit(uint32_t numchips, bool stereo, bool initopl3) { assert(numchips >= 1 && numchips <= countof(chips)); - uint i; + uint32_t i; IsOPL3 = (current_opl_core == 1 || current_opl_core == 2 || current_opl_core == 3); memset(chips, 0, sizeof(chips)); @@ -349,7 +349,7 @@ int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3) void OPLio::OPLwriteInitState(bool initopl3) { - for (uint i = 0; i < NumChips; ++i) + for (uint32_t i = 0; i < NumChips; ++i) { int chip = i << (int)IsOPL3; if (IsOPL3 && initopl3) diff --git a/src/oplsynth/music_opl_mididevice.cpp b/src/oplsynth/music_opl_mididevice.cpp index 3cd3e625a..853a679c4 100644 --- a/src/oplsynth/music_opl_mididevice.cpp +++ b/src/oplsynth/music_opl_mididevice.cpp @@ -289,7 +289,7 @@ FString OPLMIDIDevice::GetStats() { FString out; char star[3] = { TEXTCOLOR_ESCAPE, 'A', '*' }; - for (uint i = 0; i < io->OPLchannels; ++i) + for (uint32_t i = 0; i < io->OPLchannels; ++i) { if (channels[i].flags & CH_FREE) { diff --git a/src/oplsynth/music_opldumper_mididevice.cpp b/src/oplsynth/music_opldumper_mididevice.cpp index 121ed1f58..cf20a0e73 100644 --- a/src/oplsynth/music_opldumper_mididevice.cpp +++ b/src/oplsynth/music_opldumper_mididevice.cpp @@ -336,7 +336,7 @@ DiskWriterIO::~DiskWriterIO() // //========================================================================== -int DiskWriterIO::OPLinit(uint numchips, bool, bool initopl3) +int DiskWriterIO::OPLinit(uint32_t numchips, bool, bool initopl3) { FILE *file = fopen(Filename, "wb"); if (file == NULL) diff --git a/src/oplsynth/muslib.h b/src/oplsynth/muslib.h index 7553ccc0f..e4b4ac5cb 100644 --- a/src/oplsynth/muslib.h +++ b/src/oplsynth/muslib.h @@ -76,7 +76,7 @@ Voice-mail (Czech language only, not recommended; weekends only): #define __MUSLIB_H_ #ifndef __DEFTYPES_H_ - #include "deftypes.h" + #include "doomtype.h" #endif class FileReader; @@ -119,7 +119,7 @@ struct OPL2instrument { /*0B*/ BYTE scale_2; /* OP 2: key scale level */ /*0C*/ BYTE level_2; /* OP 2: output level */ /*0D*/ BYTE unused; -/*0E*/ sshort basenote; /* base note offset */ +/*0E*/ int16_t basenote; /* base note offset */ }; /* OP2 instrument file entry */ @@ -152,41 +152,41 @@ struct OP2instrEntry { #define CH_FREE 0x80 struct OPLdata { - uint channelInstr[CHANNELS]; // instrument # - uchar channelVolume[CHANNELS]; // volume - uchar channelLastVolume[CHANNELS]; // last volume - schar channelPan[CHANNELS]; // pan, 0=normal - schar channelPitch[CHANNELS]; // pitch wheel, 64=normal - uchar channelSustain[CHANNELS]; // sustain pedal value - uchar channelModulation[CHANNELS]; // modulation pot value - ushort channelPitchSens[CHANNELS]; // pitch sensitivity, 2=default - ushort channelRPN[CHANNELS]; // RPN number for data entry - uchar channelExpression[CHANNELS]; // expression + uint32_t channelInstr[CHANNELS]; // instrument # + uint8_t channelVolume[CHANNELS]; // volume + uint8_t channelLastVolume[CHANNELS]; // last volume + int8_t channelPan[CHANNELS]; // pan, 0=normal + int8_t channelPitch[CHANNELS]; // pitch wheel, 64=normal + uint8_t channelSustain[CHANNELS]; // sustain pedal value + uint8_t channelModulation[CHANNELS]; // modulation pot value + uint16_t channelPitchSens[CHANNELS]; // pitch sensitivity, 2=default + uint16_t channelRPN[CHANNELS]; // RPN number for data entry + uint8_t channelExpression[CHANNELS]; // expression }; struct OPLio { virtual ~OPLio(); - void OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2); - void OPLwriteValue(uint regbase, uint channel, uchar value); - void OPLwriteFreq(uint channel, uint freq, uint octave, uint keyon); - uint OPLconvertVolume(uint data, uint volume); - uint OPLpanVolume(uint volume, int pan); - void OPLwriteVolume(uint channel, struct OPL2instrument *instr, uint volume); - void OPLwritePan(uint channel, struct OPL2instrument *instr, int pan); - void OPLwriteInstrument(uint channel, struct OPL2instrument *instr); + void OPLwriteChannel(uint32_t regbase, uint32_t channel, uint8_t data1, uint8_t data2); + void OPLwriteValue(uint32_t regbase, uint32_t channel, uint8_t value); + void OPLwriteFreq(uint32_t channel, uint32_t freq, uint32_t octave, uint32_t keyon); + uint32_t OPLconvertVolume(uint32_t data, uint32_t volume); + uint32_t OPLpanVolume(uint32_t volume, int pan); + void OPLwriteVolume(uint32_t channel, struct OPL2instrument *instr, uint32_t volume); + void OPLwritePan(uint32_t channel, struct OPL2instrument *instr, int pan); + void OPLwriteInstrument(uint32_t channel, struct OPL2instrument *instr); void OPLshutup(void); void OPLwriteInitState(bool initopl3); - virtual int OPLinit(uint numchips, bool stereo=false, bool initopl3=false); + virtual int OPLinit(uint32_t numchips, bool stereo=false, bool initopl3=false); virtual void OPLdeinit(void); - virtual void OPLwriteReg(int which, uint reg, uchar data); + virtual void OPLwriteReg(int which, uint32_t reg, uint8_t data); virtual void SetClockRate(double samples_per_tick); virtual void WriteDelay(int ticks); class OPLEmul *chips[MAXOPL2CHIPS]; - uint OPLchannels; - uint NumChips; + uint32_t OPLchannels; + uint32_t NumChips; bool IsOPL3; }; @@ -195,7 +195,7 @@ struct DiskWriterIO : public OPLio DiskWriterIO(const char *filename); ~DiskWriterIO(); - int OPLinit(uint numchips, bool notused, bool initopl3); + int OPLinit(uint32_t numchips, bool notused, bool initopl3); void SetClockRate(double samples_per_tick); void WriteDelay(int ticks); @@ -214,14 +214,14 @@ struct musicBlock { struct OP2instrEntry *OPLinstruments; - ulong MLtime; + uint32_t MLtime; - void OPLplayNote(uint channel, uchar note, int volume); - void OPLreleaseNote(uint channel, uchar note); - void OPLpitchWheel(uint channel, int pitch); - void OPLchangeControl(uint channel, uchar controller, int value); - void OPLprogramChange(uint channel, int value); - void OPLresetControllers(uint channel, int vol); + void OPLplayNote(uint32_t channel, uint8_t note, int volume); + void OPLreleaseNote(uint32_t channel, uint8_t note); + void OPLpitchWheel(uint32_t channel, int pitch); + void OPLchangeControl(uint32_t channel, uint8_t controller, int value); + void OPLprogramChange(uint32_t channel, int value); + void OPLresetControllers(uint32_t channel, int vol); void OPLplayMusic(int vol); void OPLstopMusic(); @@ -230,27 +230,27 @@ struct musicBlock { protected: /* OPL channel (voice) data */ struct channelEntry { - uchar channel; /* MUS channel number */ - uchar note; /* note number */ - uchar flags; /* see CH_xxx below */ - uchar realnote; /* adjusted note number */ - schar finetune; /* frequency fine-tune */ - sint pitch; /* pitch-wheel value */ - uint volume; /* note volume */ - uint realvolume; /* adjusted note volume */ + uint8_t channel; /* MUS channel number */ + uint8_t note; /* note number */ + uint8_t flags; /* see CH_xxx below */ + uint8_t realnote; /* adjusted note number */ + int8_t finetune; /* frequency fine-tune */ + int pitch; /* pitch-wheel value */ + uint32_t volume; /* note volume */ + uint32_t realvolume; /* adjusted note volume */ struct OPL2instrument *instr; /* current instrument */ - ulong time; /* note start time */ + uint32_t time; /* note start time */ } channels[MAXCHANNELS]; - void writeFrequency(uint slot, uint note, int pitch, uint keyOn); - void writeModulation(uint slot, struct OPL2instrument *instr, int state); - uint calcVolume(uint channelVolume, uint channelExpression, uint noteVolume); - int occupyChannel(uint slot, uint channel, - int note, int volume, struct OP2instrEntry *instrument, uchar secondary); - int releaseChannel(uint slot, uint killed); - int releaseSustain(uint channel); - int findFreeChannel(uint flag, uint channel, uchar note); - struct OP2instrEntry *getInstrument(uint channel, uchar note); + void writeFrequency(uint32_t slot, uint32_t note, int pitch, uint32_t keyOn); + void writeModulation(uint32_t slot, struct OPL2instrument *instr, int state); + uint32_t calcVolume(uint32_t channelVolume, uint32_t channelExpression, uint32_t noteVolume); + int occupyChannel(uint32_t slot, uint32_t channel, + int note, int volume, struct OP2instrEntry *instrument, uint8_t secondary); + int releaseChannel(uint32_t slot, uint32_t killed); + int releaseSustain(uint32_t channel); + int findFreeChannel(uint32_t flag, uint32_t channel, uint8_t note); + struct OP2instrEntry *getInstrument(uint32_t channel, uint8_t note); friend class Stat_opl; diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 76d8df3fe..33f7843ab 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -856,7 +856,8 @@ void P_Spawn3DFloors (void) { case ExtraFloor_LightOnly: if (line.args[1] < 0 || line.args[1] > 2) line.args[1] = 0; - P_Set3DFloor(&line, 3, flagvals[line.args[1]], 0); + if (line.args[0] != 0) + P_Set3DFloor(&line, 3, flagvals[line.args[1]], 0); break; case Sector_Set3DFloor: @@ -875,7 +876,8 @@ void P_Spawn3DFloors (void) line.args[4]=0; } } - P_Set3DFloor(&line, line.args[1]&~8, line.args[2], line.args[3]); + if (line.args[0] != 0) + P_Set3DFloor(&line, line.args[1]&~8, line.args[2], line.args[3]); break; default: diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index e6ab47c24..515905b27 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1097,7 +1097,7 @@ public: { ld->alpha = 0.75; } - if (strifetrans2 && ld->alpha == OPAQUE) + if (strifetrans2 && ld->alpha == 1.) { ld->alpha = 0.25; } diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index a3641269f..4d6376f3b 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -6368,11 +6368,8 @@ ExpEmit FxClassDefaults::Emit(VMFunctionBuilder *build) //========================================================================== FxGlobalVariable::FxGlobalVariable(PField* mem, const FScriptPosition &pos) - : FxExpression(EFX_GlobalVariable, pos) + : FxMemberBase(EFX_GlobalVariable, mem, pos) { - membervar = mem; - AddressRequested = false; - AddressWritable = true; // must be true unless classx tells us otherwise if requested. } //========================================================================== @@ -6548,11 +6545,8 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build) //========================================================================== FxStackVariable::FxStackVariable(PType *type, int offset, const FScriptPosition &pos) - : FxExpression(EFX_StackVariable, pos) + : FxMemberBase(EFX_StackVariable, new PField(NAME_None, type, 0, offset), pos) { - membervar = new PField(NAME_None, type, 0, offset); - AddressRequested = false; - AddressWritable = true; // must be true unless classx tells us otherwise if requested. } //========================================================================== @@ -6651,14 +6645,16 @@ ExpEmit FxStackVariable::Emit(VMFunctionBuilder *build) // // //========================================================================== +FxMemberBase::FxMemberBase(EFxType type, PField *f, const FScriptPosition &p) + :FxExpression(type, p), membervar(f) +{ +} + FxStructMember::FxStructMember(FxExpression *x, PField* mem, const FScriptPosition &pos) - : FxExpression(EFX_StructMember, pos) + : FxMemberBase(EFX_StructMember, mem, pos) { classx = x; - membervar = mem; - AddressRequested = false; - AddressWritable = true; // must be true unless classx tells us otherwise if requested. } //========================================================================== @@ -6730,35 +6726,13 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx) else if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PStruct))) { // if this is a struct within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. - if (classx->ExprType == EFX_ClassMember || classx->ExprType == EFX_StructMember) + if (classx->ExprType == EFX_ClassMember || classx->ExprType == EFX_StructMember || classx->ExprType == EFX_GlobalVariable || classx->ExprType == EFX_StackVariable) { - auto parentfield = static_cast(classx)->membervar; + auto parentfield = static_cast(classx)->membervar; // PFields are garbage collected so this will be automatically taken care of later. auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset); newfield->BitValue = membervar->BitValue; - static_cast(classx)->membervar = newfield; - classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. - auto x = classx->Resolve(ctx); - classx = nullptr; - return x; - } - else if (classx->ExprType == EFX_GlobalVariable) - { - auto parentfield = static_cast(classx)->membervar; - auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset); - newfield->BitValue = membervar->BitValue; - static_cast(classx)->membervar = newfield; - classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. - auto x = classx->Resolve(ctx); - classx = nullptr; - return x; - } - else if (classx->ExprType == EFX_StackVariable) - { - auto parentfield = static_cast(classx)->membervar; - auto newfield = new PField(membervar->SymbolName, membervar->Type, membervar->Flags | parentfield->Flags, membervar->Offset + parentfield->Offset); - newfield->BitValue = membervar->BitValue; - static_cast(classx)->ReplaceField(newfield); + static_cast(classx)->membervar = newfield; classx->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. auto x = classx->Resolve(ctx); classx = nullptr; @@ -6946,33 +6920,41 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) return nullptr; } - PArray *arraytype = dyn_cast(Array->ValueType); - if (arraytype == nullptr) + PArray *arraytype = nullptr; + PType *elementtype = nullptr; + if (Array->IsDynamicArray()) { - // Check if we got a pointer to an array. Some native data structures (like the line list in sectors) use this. - PPointer *ptype = dyn_cast(Array->ValueType); - if (ptype == nullptr || !ptype->PointedType->IsKindOf(RUNTIME_CLASS(PArray))) - { - ScriptPosition.Message(MSG_ERROR, "'[]' can only be used with arrays."); - delete this; - return nullptr; - } - arraytype = static_cast(ptype->PointedType); + PDynArray *darraytype = static_cast(Array->ValueType); + elementtype = darraytype->ElementType; + Array->ValueType = NewPointer(NewResizableArray(elementtype)); // change type so that this can use the code for resizable arrays unchanged. arrayispointer = true; } + else + { + arraytype = dyn_cast(Array->ValueType); + if (arraytype == nullptr) + { + // Check if we got a pointer to an array. Some native data structures (like the line list in sectors) use this. + PPointer *ptype = dyn_cast(Array->ValueType); + if (ptype == nullptr || !ptype->PointedType->IsKindOf(RUNTIME_CLASS(PArray))) + { + ScriptPosition.Message(MSG_ERROR, "'[]' can only be used with arrays."); + delete this; + return nullptr; + } + arraytype = static_cast(ptype->PointedType); + arrayispointer = true; + } + elementtype = arraytype->ElementType; + } if (Array->IsResizableArray()) { // if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. - if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) + if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember || Array->ExprType == EFX_GlobalVariable || Array->ExprType == EFX_StackVariable) { - auto parentfield = static_cast(Array)->membervar; - SizeAddr = parentfield->Offset + parentfield->Type->Align; - } - else if (Array->ExprType == EFX_GlobalVariable) - { - auto parentfield = static_cast(Array)->membervar; - SizeAddr = parentfield->Offset + parentfield->Type->Align; + auto parentfield = static_cast(Array)->membervar; + SizeAddr = parentfield->Offset + sizeof(void*); } else { @@ -6981,54 +6963,32 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) return nullptr; } } - else if (index->isConstant()) + // constant indices can only be resolved at compile time for statically sized arrays. + else if (index->isConstant() && arraytype != nullptr && !arrayispointer) { unsigned indexval = static_cast(index)->GetValue().GetInt(); - if (indexval >= arraytype->ElementCount && !Array->IsResizableArray()) + if (indexval >= arraytype->ElementCount) { ScriptPosition.Message(MSG_ERROR, "Array index out of bounds"); delete this; return nullptr; } - if (!arrayispointer) + // if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. + if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember || Array->ExprType == EFX_GlobalVariable || Array->ExprType == EFX_StackVariable) { - // if this is an array within a class or another struct we can simplify the expression by creating a new PField with a cumulative offset. - if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) - { - auto parentfield = static_cast(Array)->membervar; - // PFields are garbage collected so this will be automatically taken care of later. - auto newfield = new PField(NAME_None, arraytype->ElementType, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); - static_cast(Array)->membervar = newfield; - Array->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. - auto x = Array->Resolve(ctx); - Array = nullptr; - return x; - } - else if (Array->ExprType == EFX_GlobalVariable) - { - auto parentfield = static_cast(Array)->membervar; - auto newfield = new PField(NAME_None, arraytype->ElementType, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); - static_cast(Array)->membervar = newfield; - Array->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. - auto x = Array->Resolve(ctx); - Array = nullptr; - return x; - } - else if (Array->ExprType == EFX_StackVariable) - { - auto parentfield = static_cast(Array)->membervar; - auto newfield = new PField(NAME_None, arraytype->ElementType, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); - static_cast(Array)->ReplaceField(newfield); - Array->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. - auto x = Array->Resolve(ctx); - Array = nullptr; - return x; - } + auto parentfield = static_cast(Array)->membervar; + // PFields are garbage collected so this will be automatically taken care of later. + auto newfield = new PField(NAME_None, elementtype, parentfield->Flags, indexval * arraytype->ElementSize + parentfield->Offset); + static_cast(Array)->membervar = newfield; + Array->isresolved = false; // re-resolve the parent so it can also check if it can be optimized away. + auto x = Array->Resolve(ctx); + Array = nullptr; + return x; } } - ValueType = arraytype->ElementType; + ValueType = elementtype; if (!Array->RequestAddress(ctx, &AddressWritable)) { ScriptPosition.Message(MSG_ERROR, "Unable to dereference array."); @@ -7067,17 +7027,8 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0)); auto f = new PField(NAME_None, TypeUInt32, 0, SizeAddr); - if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) - { - static_cast(Array)->membervar = f; - static_cast(Array)->AddressRequested = false; - } - else if (Array->ExprType == EFX_GlobalVariable) - { - static_cast(Array)->membervar = f; - static_cast(Array)->AddressRequested = false; - } - + static_cast(Array)->membervar = f; + static_cast(Array)->AddressRequested = false; Array->ValueType = TypeUInt32; bound = Array->Emit(build); } @@ -7804,6 +7755,70 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) // same for String methods. It also uses a hidden struct type to define them. Self->ValueType = TypeStringStruct; } + else if (Self->IsDynamicArray()) + { + if (MethodName == NAME_Size) + { + FxExpression *x = new FxMemberIdentifier(Self, NAME_Size, ScriptPosition); // todo: obfuscate the name to prevent direct access. + Self = nullptr; + delete this; + return x->Resolve(ctx); + } + else + { + auto elementType = static_cast(Self->ValueType)->ElementType; + Self->ValueType = static_cast(Self->ValueType)->BackingType; + // this requires some added type checks for the passed types. + for (auto &a : ArgList) + { + a = a->Resolve(ctx); + if (a == nullptr) + { + delete this; + return nullptr; + } + if (a->IsDynamicArray()) + { + // Copy and Move must turn their parameter into a pointer to the backing struct type. + auto backingtype = static_cast(a->ValueType)->BackingType; + if (elementType != static_cast(a->ValueType)->ElementType) + { + ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument"); + delete this; + return nullptr; + } + bool writable; + if (!a->RequestAddress(ctx, &writable)) + { + ScriptPosition.Message(MSG_ERROR, "Unable to dereference array variable"); + delete this; + return nullptr; + } + a->ValueType = NewPointer(backingtype); + + // Also change the field's type so the code generator can work with this (actually this requires swapping out the entire field.) + if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_StackVariable) + { + auto member = static_cast(Self); + auto newfield = new PField(NAME_None, backingtype, 0, member->membervar->Offset); + member->membervar = newfield; + } + } + else if (a->IsPointer() && Self->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))) + { + // the only case which must be checked up front is for pointer arrays receiving a new element. + // Since there is only one native backing class it uses a neutral void pointer as its argument, + // meaning that FxMemberFunctionCall is unable to do a proper check. So we have to do it here. + if (a->ValueType != elementType) + { + ScriptPosition.Message(MSG_ERROR, "Type mismatch in function argument. Got %s, expected %s", a->ValueType->DescriptiveName(), elementType->DescriptiveName()); + delete this; + return nullptr; + } + } + } + } + } else if (Self->IsArray()) { if (MethodName == NAME_Size) @@ -7826,19 +7841,9 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) else { // Resizable arrays can only be defined in C code and they can only exist in pointer form to reduce their impact on the code generator. - if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember) + if (Self->ExprType == EFX_StructMember || Self->ExprType == EFX_ClassMember || Self->ExprType == EFX_GlobalVariable) { - auto member = static_cast(Self); - auto newfield = new PField(NAME_None, TypeUInt32, VARF_ReadOnly, member->membervar->Offset + member->membervar->Type->Align); // the size is stored right behind the pointer. - member->membervar = newfield; - Self = nullptr; - delete this; - member->ValueType = TypeUInt32; - return member; - } - else if (Self->ExprType == EFX_GlobalVariable) - { - auto member = static_cast(Self); + auto member = static_cast(Self); auto newfield = new PField(NAME_None, TypeUInt32, VARF_ReadOnly, member->membervar->Offset + member->membervar->Type->Align); // the size is stored right behind the pointer. member->membervar = newfield; Self = nullptr; diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index 6438e0868..c64ec2094 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -333,6 +333,7 @@ public: bool IsObject() const { return ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && !ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)) && ValueType != TypeNullPtr && static_cast(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PClass)); } bool IsArray() const { return ValueType->IsKindOf(RUNTIME_CLASS(PArray)) || (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PArray))); } bool IsResizableArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PResizableArray))); } // can only exist in pointer form. + bool IsDynamicArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PDynArray))); } virtual ExpEmit Emit(VMFunctionBuilder *build); void EmitStatement(VMFunctionBuilder *build); @@ -1313,19 +1314,30 @@ public: }; +//========================================================================== +// +// FxMemberBase +// +//========================================================================== + +class FxMemberBase : public FxExpression +{ +public: + PField *membervar; + bool AddressRequested = false; + bool AddressWritable = true; + FxMemberBase(EFxType type, PField *f, const FScriptPosition &p); +}; + //========================================================================== // // FxGlobalVariaböe // //========================================================================== -class FxGlobalVariable : public FxExpression +class FxGlobalVariable : public FxMemberBase { public: - PField *membervar; - bool AddressRequested; - bool AddressWritable; - FxGlobalVariable(PField*, const FScriptPosition&); FxExpression *Resolve(FCompileContext&); bool RequestAddress(FCompileContext &ctx, bool *writable); @@ -1342,19 +1354,17 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; + //========================================================================== // // FxClassMember // //========================================================================== -class FxStructMember : public FxExpression +class FxStructMember : public FxMemberBase { public: FxExpression *classx; - PField *membervar; - bool AddressRequested; - bool AddressWritable; FxStructMember(FxExpression*, PField*, const FScriptPosition&); ~FxStructMember(); @@ -1402,13 +1412,9 @@ public: // //========================================================================== -class FxStackVariable : public FxExpression +class FxStackVariable : public FxMemberBase { public: - PField *membervar; - bool AddressRequested; - bool AddressWritable; - FxStackVariable(PType *type, int offset, const FScriptPosition&); ~FxStackVariable(); void ReplaceField(PField *newfield); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 9c36f0e49..8786a31bf 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -1136,4 +1136,51 @@ DEFINE_ACTION_FUNCTION(FStringStruct, AppendFormat) FString s = FStringFormat(param+1, defaultparam, numparam-1, ret, numret); (*self) += s; return 0; -} \ No newline at end of file +} + +DEFINE_ACTION_FUNCTION(FStringStruct, Mid) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + PARAM_INT(ipos); + PARAM_INT(ilen); + // validate. we don't want to crash if someone passes negative values. + // with size_t it's handled naturally I think, as it's unsigned, but not in ZScript. + if (ipos < 0) ipos = 0; + if (ilen < 0) ilen = 0; + // convert to size_t to prevent overflows here + size_t slen = self->Len(); + size_t pos = (size_t)ipos; + size_t len = (size_t)ilen; + if (pos > slen) pos = slen - 1; + if (pos + len > slen) + len = slen - pos; + FString s = self->Mid(pos, len); + ACTION_RETURN_STRING(s); +} + +DEFINE_ACTION_FUNCTION(FStringStruct, Len) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + ACTION_RETURN_INT(self->Len()); +} + +// CharAt and CharCodeAt is how JS does it, and JS is similar here in that it doesn't have char type as int. +DEFINE_ACTION_FUNCTION(FStringStruct, CharAt) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + PARAM_INT(pos); + int slen = self->Len(); + if (pos < 0 || pos >= slen) + ACTION_RETURN_STRING(""); + ACTION_RETURN_STRING(FString((*self)[pos])); +} + +DEFINE_ACTION_FUNCTION(FStringStruct, CharCodeAt) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + PARAM_INT(pos); + int slen = self->Len(); + if (pos < 0 || pos >= slen) + ACTION_RETURN_INT(0); + ACTION_RETURN_INT((*self)[pos]); +} diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 610e7554d..44428ab88 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -1358,9 +1358,16 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n case AST_DynArrayType: if (allowarraytypes) { - Error(field, "%s: Dynamic array types not implemented yet", name.GetChars()); auto atype = static_cast(ztype); - retval = NewDynArray(DetermineType(outertype, field, name, atype->ElementType, false, false)); + auto ftype = DetermineType(outertype, field, name, atype->ElementType, false, true); + if (ftype->GetRegType() == REGT_NIL || ftype->GetRegCount() > 1) + { + Error(field, "%s: Base type for dynamic array types nust be integral, but got %s", name.GetChars(), ftype->DescriptiveName()); + } + else + { + retval = NewDynArray(ftype); + } break; } break; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 175f8341d..83d714684 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -417,9 +417,14 @@ enum EPickStart // Although String is a builtin type, this is a convenient way to attach methods to it. struct StringStruct native { - native void Replace(String pattern, String replacement); native static vararg String Format(String fmt, ...); native vararg void AppendFormat(String fmt, ...); + + native void Replace(String pattern, String replacement); + native String Mid(int pos = 0, int len = 2147483647); + native int Len(); + native String CharAt(int pos); + native int CharCodeAt(int pos); } class Floor : Thinker native diff --git a/wadsrc/static/zscript/shared/fastprojectile.txt b/wadsrc/static/zscript/shared/fastprojectile.txt index fd877bd83..657c4680e 100644 --- a/wadsrc/static/zscript/shared/fastprojectile.txt +++ b/wadsrc/static/zscript/shared/fastprojectile.txt @@ -156,7 +156,7 @@ class FastProjectile : Actor ExplodeMissile (NULL, NULL); return; } - if (frac != (0, 0, 0) && ripcount <= 0) + if (!(frac.xy ~== (0, 0)) && ripcount <= 0) { ripcount = count >> 3;