2022-11-03 06:29:20 +00:00
// Some of the original source code for this file can be found here:
// https://github.com/shbow/organya/blob/master/source/OrgFile.cpp
// https://github.com/shbow/organya/blob/master/source/OrgPlay.cpp
// https://github.com/shbow/organya/blob/master/source/Sound.cpp
// https://github.com/shbow/organya/blob/master/source/WinTimer.cpp
# include "Organya.h"
# include <stddef.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <string>
# include "WindowsWrapper.h"
# include "Backends/Audio.h"
# include "File.h"
# include "Main.h"
# include "Sound.h"
# define PANDUMMY 0xFF
# define VOLDUMMY 0xFF
# define KEYDUMMY 0xFF
# define ALLOCNOTE 4096
# define DEFVOLUME 200 //255はVOLDUMMY。MAXは254
# define DEFPAN 6
//曲情報をセットする時のフラグ
# define SETALL 0xffffffff //全てをセット
# define SETWAIT 0x00000001
# define SETGRID 0x00000002
# define SETALLOC 0x00000004
# define SETREPEAT 0x00000008
# define SETFREQ 0x00000010
# define SETWAVE 0x00000020
# define SETPIPI 0x00000040
// Below are Organya song data structures
typedef struct NOTELIST
{
NOTELIST * from ; // Previous address
NOTELIST * to ; // Next address
long x ; // Position
unsigned char length ; // Sound length
unsigned char y ; // Sound height
unsigned char volume ; // Volume
unsigned char pan ;
} NOTELIST ;
// Track data * 8
typedef struct TRACKDATA
{
unsigned short freq ; // Frequency (1000 is default)
unsigned char wave_no ; // Waveform No.
signed char pipi ;
NOTELIST * note_p ;
NOTELIST * note_list ;
} TRACKDATA ;
// Unique information held in songs
typedef struct MUSICINFO
{
unsigned short wait ;
unsigned char line ; // Number of lines in one measure
unsigned char dot ; // Number of dots per line
unsigned short alloc_note ; // Number of allocated notes
long repeat_x ; // Repeat
long end_x ; // End of song (Return to repeat)
TRACKDATA tdata [ MAXTRACK ] ;
} MUSICINFO ;
// メインクラス。このアプリケーションの中心。(クラスってやつを初めて使う) (Main class. The heart of this application. (Class is used for the first time))
typedef struct OrgData
{
OrgData ( ) ; // コンストラクタ (Constructor)
// ~OrgData(); // デストラクタ (Destructor)
MUSICINFO info ;
char track ;
char mute [ MAXTRACK ] ;
unsigned char def_pan ;
unsigned char def_volume ;
void InitOrgData ( void ) ;
void GetMusicInfo ( MUSICINFO * mi ) ; // 曲情報を取得 (Get song information)
// 曲情報を設定。flagは設定アイテムを指定 (Set song information. flag specifies the setting item)
BOOL SetMusicInfo ( MUSICINFO * mi , unsigned long flag ) ;
BOOL NoteAlloc ( unsigned short note_num ) ; // 指定の数だけNoteDataの領域を確保 (Allocate the specified number of NoteData areas.)
void ReleaseNote ( void ) ; // NoteDataを開放 (Release NoteData)
// 以下は再生 (The following is playback)
void PlayData ( void ) ;
void SetPlayPointer ( long x ) ; // 再生ポインターを指定の位置に設定 (Set playback pointer to specified position)
// 以下はファイル関係 (The following are related to files)
BOOL InitMusicData ( const char * path ) ;
} ORGDATA ;
AudioBackend_Sound * lpORGANBUFFER [ 8 ] [ 8 ] [ 2 ] = { NULL } ;
2022-11-03 07:50:55 +00:00
const char * dram_name [ ] = {
" data/Dram/Bass01.wav " ,
" data/Dram/Bass02.wav " ,
" data/Dram/Snare01.wav " ,
" data/Dram/Snare02.wav " ,
" data/Dram/Tom01.wav " ,
" data/Dram/HiClose.wav " ,
" data/Dram/HiOpen.wav " ,
" data/Dram/Crash.wav " ,
" data/Dram/Per01.wav " ,
" data/Dram/Per02.wav " ,
" data/Dram/Bass03.wav " ,
" data/Dram/Tom02.wav " ,
" data/Dram/Bass04.wav " , //新規追加
" data/Dram/Bass05.wav " ,
" data/Dram/Snare03.wav " ,
" data/Dram/Snare04.wav " ,
" data/Dram/HiClose02.wav " ,
" data/Dram/HiOpen02.wav " ,
" data/Dram/HiClose03.wav " ,
" data/Dram/HiOpen03.wav " ,
" data/Dram/Crash02.wav " ,
" data/Dram/RevSym01.wav " ,
" data/Dram/Ride01.wav " ,
" data/Dram/Tom03.wav " ,
" data/Dram/Tom04.wav " ,
" data/Dram/OrcDrm01.wav " ,
" data/Dram/Bell.wav " ,
" data/Dram/Cat.wav " ,
" data/Dram/Bass06.wav " , //さらに追加
" data/Dram/Bass07.wav " ,
" data/Dram/Snare05.wav " ,
" data/Dram/Snare06.wav " ,
" data/Dram/Snare07.wav " ,
" data/Dram/Tom05.wav " ,
" data/Dram/HiOpen04.wav " ,
" data/Dram/HiClose04.wav " ,
" data/Dram/Clap01.wav " ,
" data/Dram/Pesi01.wav " ,
" data/Dram/Quick01.wav " ,
" data/Dram/Bass08.wav " , //懲りずに追加 // 2011.10.17
" data/Dram/Snare08.wav " ,
" data/Dram/HiClose05.wav " ,
} ;
2022-11-03 06:29:20 +00:00
/////////////////////////////////////////////
//■オルガーニャ■■■■■■■■■■■■/////// (Organya)
/////////////////////
// Wave playing and loading
typedef struct
{
short wave_size ;
short oct_par ;
short oct_size ;
} OCTWAVE ;
OCTWAVE oct_wave [ 8 ] =
{
{ 256 , 1 , 4 } , // 0 Oct
{ 256 , 2 , 8 } , // 1 Oct
{ 128 , 4 , 12 } , // 2 Oct
{ 128 , 8 , 16 } , // 3 Oct
{ 64 , 16 , 20 } , // 4 Oct
{ 32 , 32 , 24 } , // 5 Oct
{ 16 , 64 , 28 } , // 6 Oct
{ 8 , 128 , 32 } , // 7 Oct
} ;
BOOL MakeSoundObject8 ( signed char * wavep , signed char track , signed char pipi )
{
unsigned long i , j , k ;
unsigned long wav_tp ; // WAVテーブルをさすポインタ (Pointer to WAV table)
unsigned long wave_size ; // 256;
unsigned long data_size ;
unsigned char * wp ;
unsigned char * wp_sub ;
int work ;
if ( ! audio_backend_initialised )
return FALSE ;
for ( j = 0 ; j < 8 ; j + + )
{
for ( k = 0 ; k < 2 ; k + + )
{
wave_size = oct_wave [ j ] . wave_size ;
if ( pipi )
data_size = wave_size * oct_wave [ j ] . oct_size ;
else
data_size = wave_size ;
wp = ( unsigned char * ) malloc ( data_size ) ;
if ( wp = = NULL )
return FALSE ;
// Get wave data
wp_sub = wp ;
wav_tp = 0 ;
for ( i = 0 ; i < data_size ; i + + )
{
work = * ( wavep + wav_tp ) ;
work + = 0x80 ;
* wp_sub = ( unsigned char ) work ;
wav_tp + = 0x100 / wave_size ;
if ( wav_tp > 0xFF )
wav_tp - = 0x100 ;
wp_sub + + ;
}
lpORGANBUFFER [ track ] [ j ] [ k ] = AudioBackend_CreateSound ( 22050 , wp , data_size ) ;
free ( wp ) ;
if ( lpORGANBUFFER [ track ] [ j ] [ k ] = = NULL )
return FALSE ;
AudioBackend_RewindSound ( lpORGANBUFFER [ track ] [ j ] [ k ] ) ;
}
}
return TRUE ;
}
short freq_tbl [ 12 ] = { 262 , 277 , 294 , 311 , 330 , 349 , 370 , 392 , 415 , 440 , 466 , 494 } ;
void ChangeOrganFrequency ( unsigned char key , signed char track , long a )
{
if ( ! audio_backend_initialised )
return ;
for ( int j = 0 ; j < 8 ; j + + )
for ( int i = 0 ; i < 2 ; i + + )
AudioBackend_SetSoundFrequency ( lpORGANBUFFER [ track ] [ j ] [ i ] , ( ( oct_wave [ j ] . wave_size * freq_tbl [ key ] ) * oct_wave [ j ] . oct_par ) / 8 + ( a - 1000 ) ) ; // 1000を+αのデフォルト値とする (1000 is the default value for + α )
}
BOOL g_mute [ MAXTRACK ] ; // Used by the debug Mute menu
short pan_tbl [ 13 ] = { 0 , 43 , 86 , 129 , 172 , 215 , 256 , 297 , 340 , 383 , 426 , 469 , 512 } ;
unsigned char old_key [ MAXTRACK ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } ; // 再生中の音 (Sound being played)
unsigned char key_on [ MAXTRACK ] ; // キースイッチ (Key switch)
unsigned char key_twin [ MAXTRACK ] ; // 今使っているキー(連続時のノイズ防止の為に二つ用意) (Currently used keys (prepared for continuous noise prevention))
void ChangeOrganPan ( unsigned char key , unsigned char pan , signed char track ) // 512がMAXで256がノーマル (512 is MAX and 256 is normal)
{
if ( ! audio_backend_initialised )
return ;
if ( old_key [ track ] ! = KEYDUMMY )
AudioBackend_SetSoundPan ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] , ( pan_tbl [ pan ] - 0x100 ) * 10 ) ;
}
void ChangeOrganVolume ( int no , long volume , signed char track ) // 300がMAXで300がノーマル (300 is MAX and 300 is normal)
{
if ( ! audio_backend_initialised )
return ;
if ( old_key [ track ] ! = KEYDUMMY )
AudioBackend_SetSoundVolume ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] , ( volume - 0xFF ) * 8 ) ;
}
// サウンドの再生 (Play sound)
void PlayOrganObject ( unsigned char key , int mode , signed char track , long freq )
{
if ( ! audio_backend_initialised )
return ;
if ( lpORGANBUFFER [ track ] [ key / 12 ] [ key_twin [ track ] ] ! = NULL )
{
switch ( mode )
{
case 0 : // 停止 (Stop)
if ( old_key [ track ] ! = 0xFF )
{
AudioBackend_StopSound ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] ) ;
AudioBackend_RewindSound ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] ) ;
}
break ;
case 1 : // 再生 (Playback)
break ;
case 2 : // 歩かせ停止 (Stop playback)
if ( old_key [ track ] ! = 0xFF )
{
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] , FALSE ) ;
old_key [ track ] = 0xFF ;
}
break ;
case - 1 :
if ( old_key [ track ] = = 0xFF ) // 新規鳴らす (New sound)
{
ChangeOrganFrequency ( key % 12 , track , freq ) ; // 周波数を設定して (Set the frequency)
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ key / 12 ] [ key_twin [ track ] ] , TRUE ) ;
old_key [ track ] = key ;
key_on [ track ] = 1 ;
}
else if ( key_on [ track ] = = 1 & & old_key [ track ] = = key ) // 同じ音 (Same sound)
{
// 今なっているのを歩かせ停止 (Stop playback now)
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] , FALSE ) ;
key_twin [ track ] + + ;
if ( key_twin [ track ] > 1 )
key_twin [ track ] = 0 ;
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ key / 12 ] [ key_twin [ track ] ] , TRUE ) ;
}
else // 違う音を鳴らすなら (If you make a different sound)
{
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ old_key [ track ] / 12 ] [ key_twin [ track ] ] , FALSE ) ; // 今なっているのを歩かせ停止 (Stop playback now)
key_twin [ track ] + + ;
if ( key_twin [ track ] > 1 )
key_twin [ track ] = 0 ;
ChangeOrganFrequency ( key % 12 , track , freq ) ; // 周波数を設定して (Set the frequency)
AudioBackend_PlaySound ( lpORGANBUFFER [ track ] [ key / 12 ] [ key_twin [ track ] ] , TRUE ) ;
old_key [ track ] = key ;
}
break ;
}
}
}
// オルガーニャオブジェクトを開放 (Open Organya object)
void ReleaseOrganyaObject ( signed char track )
{
if ( ! audio_backend_initialised )
return ;
for ( int i = 0 ; i < 8 ; i + + )
{
if ( lpORGANBUFFER [ track ] [ i ] [ 0 ] ! = NULL )
{
AudioBackend_DestroySound ( lpORGANBUFFER [ track ] [ i ] [ 0 ] ) ;
lpORGANBUFFER [ track ] [ i ] [ 0 ] = NULL ;
}
if ( lpORGANBUFFER [ track ] [ i ] [ 1 ] ! = NULL )
{
AudioBackend_DestroySound ( lpORGANBUFFER [ track ] [ i ] [ 1 ] ) ;
lpORGANBUFFER [ track ] [ i ] [ 1 ] = NULL ;
}
}
}
// 波形データをロード (Load waveform data)
signed char wave_data [ 100 ] [ 0x100 ] ;
BOOL InitWaveData100 ( void )
{
if ( ! audio_backend_initialised )
return FALSE ;
std : : string path = gDataPath + " /Resource/WAVE/Wave.dat " ;
FILE * fp = fopen ( path . c_str ( ) , " rb " ) ;
if ( fp = = NULL )
return FALSE ;
fread ( wave_data , 1 , 100 * 0x100 , fp ) ;
fclose ( fp ) ;
return TRUE ;
}
// 波形を100個の中から選択して作成 (Select from 100 waveforms to create)
BOOL MakeOrganyaWave ( signed char track , signed char wave_no , signed char pipi )
{
if ( ! audio_backend_initialised )
return FALSE ;
if ( wave_no > 99 )
return FALSE ;
ReleaseOrganyaObject ( track ) ;
MakeSoundObject8 ( wave_data [ wave_no ] , track , pipi ) ;
return TRUE ;
}
/////////////////////////////////////////////
//■オルガーニャドラムス■■■■■■■■/////// (Organya drums)
/////////////////////
void ChangeDramFrequency ( unsigned char key , signed char track )
{
if ( ! audio_backend_initialised )
return ;
2022-11-03 07:50:55 +00:00
AudioBackend_SetSoundFrequency ( lpDRAMBUFFER [ track ] , key * 800 + 100 ) ;
2022-11-03 06:29:20 +00:00
}
void ChangeDramPan ( unsigned char pan , signed char track )
{
if ( ! audio_backend_initialised )
return ;
2022-11-03 07:50:55 +00:00
AudioBackend_SetSoundPan ( lpDRAMBUFFER [ track ] , ( pan_tbl [ pan ] - 0x100 ) * 10 ) ;
2022-11-03 06:29:20 +00:00
}
void ChangeDramVolume ( long volume , signed char track )
{
if ( ! audio_backend_initialised )
return ;
2022-11-03 07:50:55 +00:00
AudioBackend_SetSoundVolume ( lpDRAMBUFFER [ track ] , ( volume - 0xFF ) * 8 ) ;
2022-11-03 06:29:20 +00:00
}
// サウンドの再生 (Play sound)
void PlayDramObject ( unsigned char key , int mode , signed char track )
{
if ( ! audio_backend_initialised )
return ;
2022-11-03 07:50:55 +00:00
if ( lpDRAMBUFFER [ track ] ! = NULL )
2022-11-03 06:29:20 +00:00
{
switch ( mode )
{
case 0 : // 停止 (Stop)
2022-11-03 07:50:55 +00:00
AudioBackend_StopSound ( lpDRAMBUFFER [ track ] ) ;
AudioBackend_RewindSound ( lpDRAMBUFFER [ track ] ) ;
2022-11-03 06:29:20 +00:00
break ;
case 1 : // 再生 (Playback)
2022-11-03 07:50:55 +00:00
AudioBackend_StopSound ( lpDRAMBUFFER [ track ] ) ;
AudioBackend_RewindSound ( lpDRAMBUFFER [ track ] ) ;
2022-11-03 06:29:20 +00:00
ChangeDramFrequency ( key , track ) ; // 周波数を設定して (Set the frequency)
2022-11-03 07:50:55 +00:00
AudioBackend_PlaySound ( lpDRAMBUFFER [ track ] , FALSE ) ;
2022-11-03 06:29:20 +00:00
break ;
case 2 : // 歩かせ停止 (Stop playback)
break ;
case - 1 :
break ;
}
}
}
ORGDATA org_data ;
static void OrganyaCallback ( void )
{
org_data . PlayData ( ) ;
}
OrgData : : OrgData ( void )
{
for ( int i = 0 ; i < MAXTRACK ; i + + )
{
info . tdata [ i ] . note_list = NULL ;
info . tdata [ i ] . note_p = NULL ;
}
}
void OrgData : : InitOrgData ( void )
{
track = 0 ;
info . alloc_note = ALLOCNOTE ; // とりあえず10000個確保 (For the time being, secure 10,000 pieces)
info . dot = 4 ;
info . line = 4 ;
info . wait = 128 ;
info . repeat_x = info . dot * info . line * 0 ;
info . end_x = info . dot * info . line * 255 ;
for ( int i = 0 ; i < MAXTRACK ; i + + )
{
info . tdata [ i ] . freq = 1000 ;
info . tdata [ i ] . wave_no = 0 ;
info . tdata [ i ] . pipi = 0 ;
}
NoteAlloc ( info . alloc_note ) ;
SetMusicInfo ( & info , SETALL ) ;
def_pan = DEFPAN ;
def_volume = DEFVOLUME ;
}
// 曲情報を設定。flagはアイテムを指定 (Set song information. flag specifies an item)
BOOL OrgData : : SetMusicInfo ( MUSICINFO * mi , unsigned long flag )
{
//char str[32]; // Leftover debug junk
int i ;
if ( flag & SETGRID ) // グリッドを有効に (Enable grid)
{
info . dot = mi - > dot ;
info . line = mi - > line ;
}
if ( flag & SETWAIT )
{
info . wait = mi - > wait ;
//itoa(mi->wait, str, 10); // Leftover debug junk
}
if ( flag & SETREPEAT )
{
info . repeat_x = mi - > repeat_x ;
info . end_x = mi - > end_x ;
}
if ( flag & SETFREQ )
{
for ( i = 0 ; i < MAXMELODY ; i + + )
{
info . tdata [ i ] . freq = mi - > tdata [ i ] . freq ;
info . tdata [ i ] . pipi = info . tdata [ i ] . pipi ; // Just sets info.tdata[i].pipi to itself (SETPIPI already sets pipi, so maybe this line shouldn't be here in the first place)
}
}
if ( flag & SETWAVE )
for ( i = 0 ; i < MAXTRACK ; i + + )
info . tdata [ i ] . wave_no = mi - > tdata [ i ] . wave_no ;
if ( flag & SETPIPI )
for ( i = 0 ; i < MAXTRACK ; i + + )
info . tdata [ i ] . pipi = mi - > tdata [ i ] . pipi ;
return TRUE ;
}
// 指定の数だけNoteDataの領域を確保(初期化) (Allocate the specified number of NoteData areas (initialization))
BOOL OrgData : : NoteAlloc ( unsigned short alloc )
{
int i , j ;
for ( j = 0 ; j < MAXTRACK ; j + + )
{
info . tdata [ j ] . wave_no = 0 ;
info . tdata [ j ] . note_list = NULL ; // コンストラクタにやらせたい (I want the constructor to do it)
info . tdata [ j ] . note_p = ( NOTELIST * ) malloc ( sizeof ( NOTELIST ) * alloc ) ;
if ( info . tdata [ j ] . note_p = = NULL )
{
for ( i = 0 ; i < MAXTRACK ; i + + )
{
if ( info . tdata [ i ] . note_p ! = NULL )
{
free ( info . tdata [ i ] . note_p ) ;
# ifdef FIX_BUGS
info . tdata [ i ] . note_p = NULL ;
# else
info . tdata [ j ] . note_p = NULL ; // Uses j instead of i
# endif
}
}
return FALSE ;
}
for ( i = 0 ; i < alloc ; i + + )
{
( info . tdata [ j ] . note_p + i ) - > from = NULL ;
( info . tdata [ j ] . note_p + i ) - > to = NULL ;
( info . tdata [ j ] . note_p + i ) - > length = 0 ;
( info . tdata [ j ] . note_p + i ) - > pan = PANDUMMY ;
( info . tdata [ j ] . note_p + i ) - > volume = VOLDUMMY ;
( info . tdata [ j ] . note_p + i ) - > y = KEYDUMMY ;
}
}
for ( j = 0 ; j < MAXMELODY ; j + + )
MakeOrganyaWave ( j , info . tdata [ j ] . wave_no , info . tdata [ j ] . pipi ) ;
2022-11-03 07:50:55 +00:00
for ( j = 0 ; j < MAXDRAM ; j + + )
LoadDramObject ( " data/Dram/Bass01.wav " , j ) ;
2022-11-03 06:29:20 +00:00
track = 0 ; // 今はここに書いておく (Write here now)
return TRUE ;
}
// NoteDataを開放 (Release NoteData)
void OrgData : : ReleaseNote ( void )
{
for ( int i = 0 ; i < MAXTRACK ; i + + )
{
if ( info . tdata [ i ] . note_p ! = NULL )
{
free ( info . tdata [ i ] . note_p ) ;
info . tdata [ i ] . note_p = NULL ;
}
}
}
char pass [ 7 ] = " Org-01 " ;
char pass2 [ 7 ] = " Org-02 " ; // Pipi
BOOL OrgData : : InitMusicData ( const char * path )
{
# define READ_LE16(p) ((p[1] << 8) | p[0]); p += 2
# define READ_LE32(p) ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); p += 4
NOTELIST * np ;
int i , j ;
char pass_check [ 6 ] ;
char ver = 0 ;
unsigned short note_num [ MAXTRACK ] ;
size_t file_size ;
unsigned char * file_buffer = LoadFileToMemory ( path , & file_size ) ;
const unsigned char * p = file_buffer ;
if ( p = = NULL )
return FALSE ;
memcpy ( & pass_check [ 0 ] , p , 6 ) ;
p + = 6 ;
if ( memcmp ( pass_check , pass , 6 ) = = 0 )
ver = 1 ;
if ( memcmp ( pass_check , pass2 , 6 ) = = 0 )
ver = 2 ;
if ( ver = = 0 )
{
free ( file_buffer ) ;
return FALSE ;
}
// 曲の情報を設定 (Set song information)
info . wait = READ_LE16 ( p ) ;
info . line = * p + + ;
info . dot = * p + + ;
info . repeat_x = READ_LE32 ( p ) ;
info . end_x = READ_LE32 ( p ) ;
for ( i = 0 ; i < MAXTRACK ; i + + )
{
info . tdata [ i ] . freq = READ_LE16 ( p ) ;
info . tdata [ i ] . wave_no = * p + + ;
if ( ver = = 1 )
info . tdata [ i ] . pipi = 0 ;
else
info . tdata [ i ] . pipi = * p ;
+ + p ;
note_num [ i ] = READ_LE16 ( p ) ;
}
// 音符のロード (Loading notes)
for ( j = 0 ; j < MAXTRACK ; j + + )
{
// 最初の音符はfromがNULLとなる (The first note has from as NULL)
if ( note_num [ j ] = = 0 )
{
info . tdata [ j ] . note_list = NULL ;
continue ;
}
// リストを作る (Make a list)
np = info . tdata [ j ] . note_p ;
info . tdata [ j ] . note_list = info . tdata [ j ] . note_p ;
np - > from = NULL ;
np - > to = ( np + 1 ) ;
np + + ;
for ( i = 1 ; i < note_num [ j ] ; i + + )
{
np - > from = ( np - 1 ) ;
np - > to = ( np + 1 ) ;
np + + ;
}
// 最後の音符のtoはNULL (The last note to is NULL)
np - - ;
np - > to = NULL ;
// 内容を代入 (Assign content)
np = info . tdata [ j ] . note_p ; // X座標 (X coordinate)
for ( i = 0 ; i < note_num [ j ] ; i + + )
{
np - > x = READ_LE32 ( p ) ;
np + + ;
}
np = info . tdata [ j ] . note_p ; // Y座標 (Y coordinate)
for ( i = 0 ; i < note_num [ j ] ; i + + )
{
np - > y = * p + + ;
np + + ;
}
np = info . tdata [ j ] . note_p ; // 長さ (Length)
for ( i = 0 ; i < note_num [ j ] ; i + + )
{
np - > length = * p + + ;
np + + ;
}
np = info . tdata [ j ] . note_p ; // ボリューム (Volume)
for ( i = 0 ; i < note_num [ j ] ; i + + )
{
np - > volume = * p + + ;
np + + ;
}
np = info . tdata [ j ] . note_p ; // パン (Pan)
for ( i = 0 ; i < note_num [ j ] ; i + + )
{
np - > pan = * p + + ;
np + + ;
}
}
free ( file_buffer ) ;
// データを有効に (Enable data)
for ( j = 0 ; j < MAXMELODY ; j + + )
MakeOrganyaWave ( j , info . tdata [ j ] . wave_no , info . tdata [ j ] . pipi ) ;
// Pixel ripped out some code so he could use PixTone sounds as drums, but he left this dead code
for ( j = MAXMELODY ; j < MAXTRACK ; j + + )
{
i = info . tdata [ j ] . wave_no ;
2022-11-03 07:50:55 +00:00
LoadDramObject ( dram_name [ i ] , j - MAXMELODY ) ;
2022-11-03 06:29:20 +00:00
}
SetPlayPointer ( 0 ) ; // 頭出し (Cue)
return TRUE ;
}
// 曲情報を取得 (Get song information)
void OrgData : : GetMusicInfo ( MUSICINFO * mi )
{
mi - > dot = info . dot ;
mi - > line = info . line ;
mi - > alloc_note = info . alloc_note ;
mi - > wait = info . wait ;
mi - > repeat_x = info . repeat_x ;
mi - > end_x = info . end_x ;
for ( int i = 0 ; i < MAXTRACK ; i + + )
{
mi - > tdata [ i ] . freq = info . tdata [ i ] . freq ;
mi - > tdata [ i ] . wave_no = info . tdata [ i ] . wave_no ;
mi - > tdata [ i ] . pipi = info . tdata [ i ] . pipi ;
}
}
// Play data
long PlayPos ; // Called 'play_p' in the source code release
NOTELIST * np [ MAXTRACK ] ;
long now_leng [ MAXMELODY ] ;
int Volume = 100 ;
int TrackVol [ MAXTRACK ] ;
BOOL bFadeout = FALSE ;
void OrgData : : PlayData ( void )
{
int i ;
// Handle fading out
if ( bFadeout & & Volume )
Volume - = 2 ;
if ( Volume < 0 )
Volume = 0 ;
// メロディの再生 (Play melody)
for ( i = 0 ; i < MAXMELODY ; i + + )
{
if ( np [ i ] ! = NULL & & PlayPos = = np [ i ] - > x )
{
if ( ! g_mute [ i ] & & np [ i ] - > y ! = KEYDUMMY ) // 音が来た。 (The sound has come.)
{
PlayOrganObject ( np [ i ] - > y , - 1 , i , info . tdata [ i ] . freq ) ;
now_leng [ i ] = np [ i ] - > length ;
}
if ( np [ i ] - > pan ! = PANDUMMY )
ChangeOrganPan ( np [ i ] - > y , np [ i ] - > pan , i ) ;
if ( np [ i ] - > volume ! = VOLDUMMY )
TrackVol [ i ] = np [ i ] - > volume ;
np [ i ] = np [ i ] - > to ; // 次の音符を指す (Points to the next note)
}
if ( now_leng [ i ] = = 0 )
PlayOrganObject ( 0 , 2 , i , info . tdata [ i ] . freq ) ;
if ( now_leng [ i ] > 0 )
now_leng [ i ] - - ;
if ( np [ i ] )
ChangeOrganVolume ( np [ i ] - > y , TrackVol [ i ] * Volume / 0x7F , i ) ;
}
// ドラムの再生 (Drum playback)
2022-11-03 07:50:55 +00:00
for ( i = MAXMELODY ; i < MAXTRACK ; i + + ) {
if ( np [ i ] ! = NULL & & PlayPos = = np [ i ] - > x ) { //音が来た。
if ( np [ i ] - > y ! = KEYDUMMY ) { //ならす
if ( mute [ i ] = = 0 ) PlayDramObject ( np [ i ] - > y , 1 , i - MAXMELODY ) ;
}
if ( np [ i ] - > pan ! = PANDUMMY ) ChangeDramPan ( np [ i ] - > pan , i - MAXMELODY ) ;
if ( np [ i ] - > volume ! = VOLDUMMY ) ChangeDramVolume ( np [ i ] - > volume , i - MAXMELODY ) ;
np [ i ] = np [ i ] - > to ; //次の音符を指す
2022-11-03 06:29:20 +00:00
}
}
// Looping
PlayPos + + ;
if ( PlayPos > = info . end_x )
{
PlayPos = info . repeat_x ;
SetPlayPointer ( PlayPos ) ;
}
}
void OrgData : : SetPlayPointer ( long x )
{
for ( int i = 0 ; i < MAXTRACK ; i + + )
{
np [ i ] = info . tdata [ i ] . note_list ;
while ( np [ i ] ! = NULL & & np [ i ] - > x < x )
np [ i ] = np [ i ] - > to ; // 見るべき音符を設定 (Set note to watch)
}
PlayPos = x ;
}
// Start and end organya
BOOL StartOrganya ( const char * path_wave ) // The argument is ignored for some reason
{
if ( ! audio_backend_initialised )
return FALSE ;
if ( ! InitWaveData100 ( ) )
return FALSE ;
org_data . InitOrgData ( ) ;
AudioBackend_SetOrganyaCallback ( OrganyaCallback ) ;
return TRUE ;
}
// Load organya file
BOOL LoadOrganya ( const char * name )
{
if ( ! audio_backend_initialised )
return FALSE ;
if ( ! org_data . InitMusicData ( name ) )
return FALSE ;
Volume = 100 ;
bFadeout = 0 ;
# ifdef FIX_BUGS
return TRUE ;
# else
return FALSE ; // Err... isn't this meant to be 'TRUE'?
# endif
}
void SetOrganyaPosition ( unsigned int x )
{
if ( ! audio_backend_initialised )
return ;
org_data . SetPlayPointer ( x ) ;
Volume = 100 ;
bFadeout = FALSE ;
}
unsigned int GetOrganyaPosition ( void )
{
if ( ! audio_backend_initialised )
return 0 ;
return PlayPos ;
}
void PlayOrganyaMusic ( void )
{
if ( ! audio_backend_initialised )
return ;
AudioBackend_SetOrganyaTimer ( org_data . info . wait ) ;
}
BOOL ChangeOrganyaVolume ( signed int volume )
{
if ( ! audio_backend_initialised )
return FALSE ;
if ( volume < 0 | | volume > 100 )
return FALSE ;
Volume = volume ;
return TRUE ;
}
void StopOrganyaMusic ( void )
{
if ( ! audio_backend_initialised )
return ;
AudioBackend_SetOrganyaTimer ( 0 ) ;
// Stop notes
for ( int i = 0 ; i < MAXMELODY ; i + + )
PlayOrganObject ( 0 , 2 , i , 0 ) ;
memset ( old_key , 255 , sizeof ( old_key ) ) ;
memset ( key_on , 0 , sizeof ( key_on ) ) ;
memset ( key_twin , 0 , sizeof ( key_twin ) ) ;
// Sleep(100); // TODO - Emulate this
}
void SetOrganyaFadeout ( void )
{
bFadeout = TRUE ;
}
void EndOrganya ( void )
{
if ( ! audio_backend_initialised )
return ;
AudioBackend_SetOrganyaTimer ( 0 ) ;
// Release everything related to org
org_data . ReleaseNote ( ) ;
for ( int i = 0 ; i < MAXMELODY ; i + + )
{
PlayOrganObject ( 0 , 0 , i , 0 ) ;
ReleaseOrganyaObject ( i ) ;
}
2022-11-03 07:50:55 +00:00
}