From 7354f08f1b7f08e7edd9fa58a6bb07f5daaeb8d5 Mon Sep 17 00:00:00 2001 From: Masanao Izumo Date: Mon, 9 Aug 1999 06:10:45 +0900 Subject: [PATCH] TiMidity++-2.4.0 --- ChangeLog | 64 ++- NEWS | 5 + configure | 2 +- configure.in | 2 +- interface/Makefile.in | 7 +- interface/VTPrsTbl.c | 4 + interface/mac_c.c | 59 +- interface/mac_trace.c | 24 +- interface/mac_wrdwindow.c | 62 ++- interface/mac_wrdwindow.h | 14 +- interface/ncurs_c.c | 75 +-- interface/vt100_c.c | 9 +- interface/w32g.h | 3 + interface/w32g_c.c | 6 +- interface/w32g_canvas.c | 2 +- interface/w32g_i.c | 122 ++--- interface/w32g_utl.c | 1 + interface/wrdt_mac.c | 281 ++++++---- interface/xaw_c.c | 12 +- interface/xskin.h | 9 +- libarc/Makefile.am | 7 +- libarc/Makefile.in | 32 +- libarc/arc.c | 1334 ++++++++++++++++++--------------------------- libarc/arc.h | 172 ++---- libarc/arc_dir.c | 49 -- libarc/arc_lzh.c | 46 +- libarc/arc_mime.c | 217 ++++---- libarc/arc_newsgroup.c | 52 -- libarc/arc_tar.c | 103 ++-- libarc/arc_zip.c | 46 +- libarc/url.c | 49 ++ libarc/url.h | 7 +- libarc/url_file.c | 3 + libarc/url_newsgroup.c | 2 + timidity/Makefile.in | 10 +- timidity/aq.c | 39 +- timidity/common.c | 62 +-- timidity/linux_a.c | 56 +- timidity/mac_a.c | 40 +- timidity/mac_com.h | 5 +- timidity/mac_dlog.c | 20 +- timidity/mac_main.c | 85 ++- timidity/mac_main.h | 19 +- timidity/mac_qt_a.c | 696 ++++++++++++++++++----- timidity/output.h | 12 + timidity/playmidi.c | 54 +- timidity/playmidi.h | 13 +- timidity/readmidi.c | 77 ++- timidity/timidity.c | 171 ++++-- timidity/wrdt.c | 2 +- utils/mac_readdir.c | 3 + utils/mac_util.c | 24 +- utils/mac_util.h | 6 +- utils/support.c | 15 +- 54 files changed, 2450 insertions(+), 1841 deletions(-) delete mode 100644 libarc/arc_dir.c delete mode 100644 libarc/arc_newsgroup.c diff --git a/ChangeLog b/ChangeLog index ed81cd3a..7dd813b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +1999-08-09 Masanao Izumo + + * Version 2.4.0 released. + +1999-08-09 Masanao Izumo + Takaya Nogami + * utils/{support.c,mac_readdir.c,mac_util.c,mac_util.h}, + interface/{xskin.h,VTPrsTbl.c,mac_c.c,mac_loadBMP.c,mac_loadBMP.h, + mac_loadpng.c,mac_oms.c,mac_oms.h,mac_sherry.c,mac_skin.c,mac_skin.h, + mac_trace.c,mac_wrd.h,mac_wrdwindow.c,mac_wrdwindow.h,wrdt_mac.c}, + timidity/{output.h,playmidi.h,playmidi.c,readmidi.c,wrdt.c, + mac_a.c,mac_com.h,mac_dlog.c,mac_main.c,mac_main.h,mac_oms_a.c + mac_qt_a.c} + Imported Macinotsh sources from the 1999.8.7 of T.Nogami released + Added GS lcd event by T.Nogami. + +1999-08-08 Masanao Izumo + + * timidity/playmidi.c (ctl_updatetime): New function to + update interface time. + * timidity/common.c (DECOMPRESSOR_LIST, PATCH_CONVERTERS): + Ignored for Windows. These filters are not worked yet. + * interface/w32g.h (RC_EXT_UPDATE_PLAYLIST): New macro. + * interface/{w32g_c.c,w32g_i.c}: w32g_update_playlist() only + called from w32g_c.c. Don't call it from w32g_i.c. + * interface/vt100_c.c: Change a old copyright to new one. + +1999-08-07 Masanao Izumo + + * libarc: Make archive library code more simple. + Some interfaces are changed. + New archive library can expand more archive files. + * timidity/{timidity.c,common.c} interface/{ncurs_c.c,xaw_c.c}: + Change to new libarc interface. + * timidity/playmidi.c (midi_program_change): + Don't change the instrument of SPECIAL_PROGRAM channel. + * timidity/output.h (PM_REQ_GETFILLABLE): New macro. + play_mode->acntl(PM_REQ_GETFILLABLE, &fillable) gets + number of samples can write. + * timidity/output.h (PM_REQ_GETFILLED): New macro. + play_mode->acntl(PM_REQ_GETFILLED, &filled) gets + number of samples in audio device. + * timidity/aq.c (aq_fillable): Check PM_REQ_GETFILLABLE. + * timidity/aq.c (aq_filled): Check PM_REQ_GETFILLED. + * timidity/linux_a.c (acntl): + PM_REQ_GETQSIZ, PM_REQ_GETFILLABLE, PM_REQ_GETFILLED, + PM_REQ_GETSAMPLES, and PM_REQ_FLUSH are implemented. + (Tested SOUND_VERSION 0x030802) + * timidity/aq.c (aq_flush): Avoid unterminated loop. + * interface/ncurs_c.c: Bug fixed about displaying instrum name scroll. + +1999-08-02 Masanao Izumo + + * interface/w32g_i.c (hListWnd, hSettingWnd): Create at first open. + * interface/w32g_i.c (w32g_i_init): New function. It is called just + last of w32g_initialize(). + * interface/w32g_canvas.c (TmCanvasMode): Global. + * interface/w32g_i.c (SettingWndApply): Restore ctl->trace_playing after + ApplySettingTiMidity(). + * interface/w32g_i.c: Remove warning message that was displayed when + a user tries to change the timidity parameter. + 1999-08-01 Masanao Izumo * Version 2.3.0 released. @@ -448,7 +510,7 @@ Files: libarc/arc_lzh.c libarc/url_dir.c timidity/common.c utils/timer.c Date: Fri Mar 26 1999 From: Masanao Izumo - Imported macinotsh sources from the 1999.3.13 of T.Nogami released + Imported Macinotsh sources from the 1999.3.13 of T.Nogami released Date: Fri Mar 26 1999 From: Masanao Izumo diff --git a/NEWS b/NEWS index cb725671..881bf6a9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +8/9, 1999 + * Version 2.4.0 released. + * Make archive library (libarc) code more simple. + * On linux, fixed probrem of audio queue analysing. + 8/1, 1999 * Version 2.3.0 released. * Make Windows GUI code elegant. diff --git a/configure b/configure index e2f9ad8b..b6063b1c 100755 --- a/configure +++ b/configure @@ -856,7 +856,7 @@ fi PACKAGE=TiMidity++ -VERSION=2.3.0 +VERSION=2.4.0 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } diff --git a/configure.in b/configure.in index 4dd60220..377c0b1a 100644 --- a/configure.in +++ b/configure.in @@ -53,7 +53,7 @@ dnl SHCFLAGS - Additional flags to compile shared object library. AC_INIT(timidity/timidity.c) AC_CANONICAL_SYSTEM -AM_INIT_AUTOMAKE(TiMidity++, 2.3.0, no-define) +AM_INIT_AUTOMAKE(TiMidity++, 2.4.0, no-define) dnl To use CONTAINS() macro (See acinclude.m4) CONTAINS_INIT diff --git a/interface/Makefile.in b/interface/Makefile.in index 40c063ac..c18ea867 100644 --- a/interface/Makefile.in +++ b/interface/Makefile.in @@ -403,8 +403,8 @@ ncurs_c.o: ncurs_c.c ../config.h ../timidity/timidity.h \ ../utils/mblock.h ../timidity/instrum.h ../timidity/playmidi.h \ ../timidity/readmidi.h ../timidity/output.h \ ../timidity/controls.h ../timidity/miditrace.h ../utils/timer.h \ - ../utils/bitset.h ../libarc/arc.h ../utils/memb.h \ - ../timidity/aq.h ../timidity/mid-j.defs + ../utils/bitset.h ../libarc/arc.h ../timidity/aq.h \ + ../timidity/mid-j.defs server_c.o: server_c.c ../config.h ../timidity/timidity.h \ ../utils/support.h ../timidity/common.h ../libarc/url.h \ ../utils/mblock.h ../timidity/controls.h ../timidity/instrum.h \ @@ -483,8 +483,7 @@ xskin_i.o: xskin_i.c xskin.h ../config.h ../timidity/timidity.h \ xskin_loadBMP.o: xskin_loadBMP.c ../config.h ../timidity/timidity.h \ ../utils/support.h ../timidity/common.h ../libarc/url.h \ ../utils/mblock.h ../timidity/instrum.h ../timidity/playmidi.h \ - ../timidity/controls.h ../timidity/output.h ../libarc/arc.h \ - ../utils/memb.h + ../timidity/controls.h ../timidity/output.h ../libarc/arc.h xskin_spectrum.o: xskin_spectrum.c xskin.h ../config.h \ ../timidity/timidity.h ../utils/support.h ../timidity/common.h \ ../libarc/url.h ../utils/mblock.h ../timidity/instrum.h \ diff --git a/interface/VTPrsTbl.c b/interface/VTPrsTbl.c index 5b7f2acc..9fe49a6a 100644 --- a/interface/VTPrsTbl.c +++ b/interface/VTPrsTbl.c @@ -406,7 +406,11 @@ CASE_IGNORE, CASE_IGNORE, CASE_IGNORE, /* SP ! " # */ +#ifndef BUGGY_VTPARSE CASE_ESC_IGNORE, +#else +CASE_ESC_DIGIT, +#endif CASE_ESC_IGNORE, CASE_ESC_IGNORE, CASE_ESC_IGNORE, diff --git a/interface/mac_c.c b/interface/mac_c.c index 229c4d90..f99ff262 100644 --- a/interface/mac_c.c +++ b/interface/mac_c.c @@ -52,6 +52,9 @@ #include "mac_main.h" #include "mac_util.h" #include "mac_c.h" +#ifdef MAC_USE_OMS +#include "mac_oms.h" +#endif // ******************************* @@ -858,6 +861,7 @@ static void mac_AdjustMenus(short modifiers) if( modifiers & optionKey ){ //EnableItem(filenemu, iSkinWindow); EnableItem(synthemu, iQuickTime); + EnableItem(synthemu, iOMS); } } @@ -876,7 +880,7 @@ void HandleMouseDown(EventRecord *event) { case inMenuBar: mac_AdjustMenus(event->modifiers); - mac_HandleMenuSelect(MenuSelect(event->where)); + mac_HandleMenuSelect(MenuSelect(event->where), event->modifiers); HiliteMenu(0); break; case inContent: @@ -951,6 +955,18 @@ static void ctl_pass_playing_list(int init_number_of_files, cmsg(CMSG_FATAL, VERB_NORMAL, "ctl_pass_playing_list: Sorry. Fatal error."); } + +#ifdef MAC_USE_OMS + mac_oms_setup(); +#endif + + { + FSSpec spec; + OSErr err; + err=FSMakeFSSpec(0, 0, MAC_STARTUP_FOLDER_NAME, &spec); + if( err==noErr ){ mac_add_fsspec( &spec ); } + } + gQuit=false; while(!gQuit) { @@ -967,7 +983,7 @@ static Boolean UserWantsControl() GetKeys(km); km[1] &= ~0x02; /* exclude caps lock */ - return Button() || km[0]|| km[1] || km[2] || km[3]; + return Button() || km[0]|| km[1] || km[2] || km[3] || skin_state==PAUSE; } static int ctl_read(int32* /*valp*/) @@ -976,13 +992,48 @@ static int ctl_read(int32* /*valp*/) //if( gCursorIsWatch ){ gCursorIsWatch=false; InitCursor(); } if( gQuit ) DoQuit(); /* Quit Apple event occured */ + if( mac_rc ){ret=mac_rc; mac_rc=0; return ret;} if( !gBusy || UserWantsControl()){ YieldToAnyThread(); } - if( mac_rc ){ret=mac_rc; mac_rc=0; return ret;} return RC_NONE; } +static void ctl_lyric(int lyricid) +{ + char *lyric; + + lyric = event2string(lyricid); + if(lyric == NULL) return; + + if( strncmp(lyric+1, "gslcd: ",7)==0 ){ + int i,j, data, mask; + char tmp[3]= "00"; + + lyric+=8; + for( j=0; j<4; j++ ){ + for( i=0; i<16; i++ ){ + tmp[0]= lyric[0]; tmp[1]= lyric[1]; lyric+=2; + sscanf(tmp, "%X", &data); + mask=0x10; + ctl_note((data&mask)? VOICE_ON:-1, i, 40+j*10, 127); + ctl_note((data&mask)? VOICE_ON:-1, i, 41+j*10, 127); mask>>=1; + ctl_note((data&mask)? VOICE_ON:-1, i, 42+j*10, 127); + ctl_note((data&mask)? VOICE_ON:-1, i, 43+j*10, 127); mask>>=1; + ctl_note((data&mask)? VOICE_ON:-1, i, 44+j*10, 127); + ctl_note((data&mask)? VOICE_ON:-1, i, 45+j*10, 127); mask>>=1; + ctl_note((data&mask)? VOICE_ON:-1, i, 46+j*10, 127); + ctl_note((data&mask)? VOICE_ON:-1, i, 47+j*10, 127); mask>>=1; + ctl_note((data&mask)? VOICE_ON:-1, i, 48+j*10, 127); + ctl_note((data&mask)? VOICE_ON:-1, i, 49+j*10, 127); mask>>=1; + } + } + return; + } + //else normal text + ctl.cmsg(CMSG_TEXT, VERB_VERBOSE, "%s", lyric + 1); +} + static int cmsg(int type, int verbosity_level, char * fmt, ...) { #define BUFSIZE 1024 @@ -1152,7 +1203,7 @@ static void ctl_event(CtlEvent *e) case CTLE_REVERB_EFFECT: break; case CTLE_LYRIC: - default_ctl_lyric((int)e->v1); + ctl_lyric((int)e->v1); break; case CTLE_REFRESH: ctl_refresh(); diff --git a/interface/mac_trace.c b/interface/mac_trace.c index a14a76fd..f496f218 100644 --- a/interface/mac_trace.c +++ b/interface/mac_trace.c @@ -38,6 +38,7 @@ #include "miditrace.h" #include "bitset.h" #include "mfnode.h" +#include "aq.h" #include "mac_main.h" #include "mac_util.h" @@ -107,6 +108,7 @@ static void mac_ctl_refresh_trc() RGBColor black={0,0,0}, darkGray={0x2000,0x2000,0x2000}; + if( !win.show ) return; SetPortWindowPort(win.ref); for( i=0; i<16; i++ ){ DrawInstrumentName(i, instr_comment[i].comm); @@ -228,17 +230,23 @@ static void update_title() void mac_trc_update_time( int cur_sec, int tot_sec ) { static int save_tot_sec=0, save_cur_sec; + int rate; char buf[80]; if( cur_sec!=-1 ) save_cur_sec=tot_sec; if( tot_sec!=-1 ) save_tot_sec=tot_sec; + if( cur_sec==-1 ) cur_sec=0; if( cur_sec > save_tot_sec ) cur_sec=save_tot_sec; + + if( !win.show ) return; + rate = (int)(aq_filled_ratio() * 100 + 0.5); SetPortWindowPort(win.ref); - snprintf(buf, 80," %3d:%02d /%3d:%02d buffering=?? sec ", - cur_sec/60, cur_sec%60, save_tot_sec/60,save_tot_sec%60 ); + snprintf(buf, 80," %3d:%02d /%3d:%02d buffering=%3d %% " "buffer %d/256 ", + cur_sec/60, cur_sec%60, save_tot_sec/60,save_tot_sec%60, + rate ,mac_buf_using_num ); RGBForeColor(&black); - MoveTo(450,12); DrawText(buf, 0, strlen(buf)); + MoveTo(400,12); DrawText(buf, 0, strlen(buf)); } void mac_trc_update_voices() @@ -337,11 +345,12 @@ static unsigned int UpdateNote(int status, int ch, int note, int vel) //int vel; Rect r1,r2; unsigned int onoff=0 /*, check, prev_check*/; - const RGBColor dieColor= {0x3000,0x3000,0x3000}, //dark gray + const RGBColor dieColor= {0x3000,0x3000,0x3000}, //dark gray freeColor= {0x3000,0x3000,0x3000}, //dark gray - onColor= {0xffff,0xffff,0}, //yellow + onColor= {0xffff,0xffff,0}, //yellow sustainedColor={0x8000,0x8000,0}, //dark yellow - offColor= {0x4000,0x4000,0}; //dark yellow + offColor= {0x4000,0x4000,0}, //dark yellow + noColor= {0x2000,0x2000,0x2000}; RGBColor color; vel=(10 * vel) / 128; /* 0-9 */ @@ -363,7 +372,8 @@ static unsigned int UpdateNote(int status, int ch, int note, int vel) case VOICE_FREE: color=freeColor; onoff = 0; break; case VOICE_SUSTAINED:DARKEN2(color); onoff = 1; break; case VOICE_OFF: DARKEN4(color); onoff = 1; break; - case VOICE_ON: onoff = 1; break; + case VOICE_ON: onoff = 1; break; + default: color= noColor; break; } RGBForeColor(&freeColor); PaintRect(&r1); diff --git a/interface/mac_wrdwindow.c b/interface/mac_wrdwindow.c index f763530e..5e80f17f 100644 --- a/interface/mac_wrdwindow.c +++ b/interface/mac_wrdwindow.c @@ -81,12 +81,26 @@ void dev_init_text_color() } } +static void expand_horizontality( PixMapHandle pixmap, int width, int height ) +{ //pixmap must be locked //for @TON(2) + int x,y; + Ptr baseAdr= GetPixBaseAddr(pixmap), xbase; + int rowBytes= (**pixmap).rowBytes & 0x1FFF; + + for( y=0; y=0; x-- ){ + xbase[x*2]= xbase[x*2+1]= xbase[x]; + } + } +} + void dev_draw_text_gmode(PixMapHandle pixmap, int x, int y, const char* s, int len, - int pmask, int mode, int fgcolor, int bgcolor ) + int pmask, int mode, int fgcolor, int bgcolor, int ton_mode) { //pixmap must be already locked GDHandle oldGD; GWorldPtr oldGW; - int color, trans; + int color, trans, width; Rect rect= {0,0,16,32}, destrect; @@ -106,10 +120,16 @@ void dev_draw_text_gmode(PixMapHandle pixmap, int x, int y, const char* s, int l TextMode(srcOr); MoveTo(0,13); DrawText(s,0,len); + if( ton_mode==2 ){ + expand_horizontality(charbufWorld->portPixMap, len*8, 16); + } + + width= len*8; + if( ton_mode==2 ) width*=2; - rect.right=len*8; + rect.right=width; destrect.left=x; destrect.top=y; - destrect.right=x+len*8; destrect.bottom=destrect.top+16; + destrect.right=x+width; destrect.bottom=destrect.top+16; MyCopyBits(charbufWorld->portPixMap, pixmap, rect, destrect, 0x11/*trans*/, trans, pmask, @@ -218,7 +238,7 @@ void MyCopyBits(PixMapHandle srcPixmap, PixMapHandle dstPixmap, //check left if( srcRect.left srcBounds.right ) return; //chech src bottom @@ -252,7 +272,7 @@ void MyCopyBits(PixMapHandle srcPixmap, PixMapHandle dstPixmap, //check left if( dstRect.left dstBounds.right ) return; //check width @@ -313,13 +333,19 @@ void MyCopyBits(PixMapHandle srcPixmap, PixMapHandle dstPixmap, } } -void dev_line(int x1, int y1, int x2, int y2, int color, int pmask, - PixMapHandle pixmap ) +void dev_line(int x1, int y1, int x2, int y2, int color, int style, + int pmask, PixMapHandle pixmap ) { int i, dx, dy, s, step; int rowBytes= (**pixmap).rowBytes & 0x1FFF; Ptr baseAdr= GetPixBaseAddr(pixmap); -#define DOT(x,y) {Ptr p=&baseAdr[y*rowBytes+x]; (*p)&=~pmask; (*p)|=color; } + Rect bounds= (**pixmap).bounds; + Point pt; + static const int mask[8]={0x80,0x40,0x20,0x10, 0x08,0x04,0x02,0x01}; + int style_count=0; + +#define DOT(x,y,col) {Ptr p=&baseAdr[y*rowBytes+x]; pt.h=x;pt.v=y; \ + if(PtInRect(pt,&bounds)){(*p)&=~pmask; (*p)|=col;} } color &= pmask; step= ( (x1dy ){ if( x1>x2 ){ x1=x2; y1=y2; } - DOT(x1,y1); + if(style & mask[style_count]){ DOT(x1,y1,color); } + //else { DOT(x1,y1,0); } + style_count= (style_count+1)%8; s= dx/2; for(i=x1+1; iy2 ){ x1=x2; y1=y2; } - DOT(x1,y1); + if(style & mask[style_count]){ DOT(x1,y1,color); } + //else{ DOT(x1,y1,0); } + style_count= (style_count+1)%8; s= dy/2; for(i=y1+1; iportPixMap); diff --git a/interface/mac_wrdwindow.h b/interface/mac_wrdwindow.h index 48a17dc6..d7b2e473 100644 --- a/interface/mac_wrdwindow.h +++ b/interface/mac_wrdwindow.h @@ -50,7 +50,7 @@ EXTERN GWorldPtr graphicWorld[8], dispWorld, charbufWorld; #define GACTIVE_PIX (graphicWorld[activeGraphics]->portPixMap) #define GDISP_PIX (graphicWorld[dispGraphics]->portPixMap) #define DISP_PIX (dispWorld->portPixMap) -EXTERN int gmode_mask, gmode_mask_gline, dev_gon_flag; +EXTERN int gmode_mask, gmode_mask_gline, dev_gon_flag, dev_redrawflag; #define DEV_SET_GMODE(mask) (gmode_mask=gmode_mask_gline=(mask)) EXTERN RGBColor dev_palette[20][17]; EXTERN int startpal, endpal; //for @FADE @@ -78,8 +78,8 @@ EXTERN int activeGraphics, dispGraphics, gvram_bank_num; EXTERN int pallette_exist, fading; -EXTERN int wrd_coursor_x,wrd_coursor_y; -EXTERN int wrd_text_color_attr; +EXTERN int wrd_coursor_x,wrd_coursor_y; +EXTERN int wrd_text_color_attr; #define CATTR_LPART (1) #define CATTR_16FONT (1<<1) #define CATTR_COLORED (1<<2) @@ -97,7 +97,7 @@ void dev_set_height(int height); void dev_redisp(Rect rect); void dev_remake_disp(Rect rect); void dev_draw_text_gmode(PixMapHandle pixmap, int x, int y, const char* s, int len, - int pmask, int mode, int fgcolor, int bgcolor ); + int pmask, int mode, int fgcolor, int bgcolor, int ton_mode); void dev_change_palette(RGBColor pal[16]); void dev_change_1_palette(int code, RGBColor color); @@ -109,10 +109,12 @@ void dev_gmove(int x1, int y1, int x2, int y2, int xd, int yd, GWorldPtr srcworld, GWorldPtr destworld, int sw, int trans, int mask, int maskx, int masky, const uint8 maskdata[]); void dev_box(PixMapHandle pixmap, Rect rect, int color, int pmask); -void dev_line(int x1, int y1, int x2, int y2, int color, int pmask, - PixMapHandle pixmap ); +void dev_line(int x1, int y1, int x2, int y2, int color, int style, + int pmask, PixMapHandle pixmap ); void dev_gline(int x1, int y1, int x2, int y2, int p1, int sw, int p2, GWorldPtr world); void mac_setfont(GWorldPtr world, Str255 fontname); +//#define WRD_FONTNAME "\p“™•–¾’©" +#define WRD_FONTNAME "\pOsaka|“™•" void sry_start(); void sry_end(); diff --git a/interface/ncurs_c.c b/interface/ncurs_c.c index ff516e60..9f2b6bbc 100644 --- a/interface/ncurs_c.c +++ b/interface/ncurs_c.c @@ -1036,6 +1036,10 @@ static void ctl_event(CtlEvent *e) break; case CTLE_SPEANA: break; + case CTLE_PAUSE: + ctl_current_time((int)e->v2, 0); + N_ctl_refresh(); + break; } } @@ -1234,6 +1238,9 @@ static void ctl_program(int ch, int val, char *comm) if(ch >= 16) return; + if(comm != NULL) + indicator_set_prog(ch, val, comm); + if(!ctl.trace_playing) return; @@ -1260,11 +1267,7 @@ static void ctl_program(int ch, int val, char *comm) } } - if(comm != NULL) - indicator_set_prog(ch, val, comm); scr_modified_flag = 1; - - } static void ctl_volume(int ch, int vol) @@ -1716,9 +1719,10 @@ static int ctl_cmd_L_enter(void) char *text; MFnode *mfp; int i, rc = RC_NONE; - extern ArchiveFileList *archive_file_list; - ArchiveFileList *lp; struct double_list_string *hist; + int nfiles; + char *files[1], **new_files; + MFnode *tail, *head; ctl_cmd_dir_close(); text = mini_buff_gets(command_buffer); @@ -1742,36 +1746,18 @@ static int ctl_cmd_L_enter(void) i--; ctl_mode_L_lastenter[i] = '\0'; - archive_file_list = add_archive_list(archive_file_list, text); - lp = find_archiver(archive_file_list, text, NULL); - if(lp == NULL || lp->archiver == NULL) - { - if(last_archive_file_list != NULL && - last_archive_file_list->errstatus != 0) - { - errno = last_archive_file_list->errstatus; - mfp = NULL; - } - else - { - mfp = make_new_MFnode_entry(text); - if(mfp != NULL) - mfp->file = safe_strdup(mfp->file); - } - } + /* Add new files */ + files[0] = text; + nfiles = 1; + new_files = expand_file_archives(files, &nfiles); + if(new_files == NULL) + { + rc = RC_NONE; + beep(); + } else - { - int nfiles; - char *files[1], **new_files; - MFnode *tail, *head; - int i; - - /* make archive file table */ - files[0] = text; - nfiles = 1; - new_files = expand_archive_names(archive_file_list, &nfiles, files); - + { head = tail = NULL; for(i = 0; i < nfiles; i++) { @@ -1784,20 +1770,9 @@ static int ctl_cmd_L_enter(void) } } mfp = head; - if(new_files != files && new_files != NULL) - { - free(new_files[0]); - free(new_files); - } - } + free(new_files[0]); + free(new_files); - if(mfp == NULL) - { - rc = RC_NONE; - beep(); - } - else - { insert_MFnode_entrys(mfp, nc_playfile); ctl_list_mode(NC_LIST_NEW); rc = RC_NEXT; @@ -2780,6 +2755,7 @@ static void reset_indicator(void) static void display_aq_ratio(void) { +#if 1 static int last_rate = -1; int rate, devsiz; @@ -2800,6 +2776,11 @@ static void display_aq_ratio(void) wprintw(dftwin, " Audio queue:%3d%% ", rate); scr_modified_flag = 1; } +#else + wmove(dftwin, VOICE_LINE + 1, 30); + wprintw(dftwin, " Audio queue: %d %d %d %d", + aq_get_dev_queuesize(), aq_filled(), aq_soft_filled(), aq_fillable()); +#endif } static void update_indicator(void) diff --git a/interface/vt100_c.c b/interface/vt100_c.c index 74786b03..a81c513c 100644 --- a/interface/vt100_c.c +++ b/interface/vt100_c.c @@ -1,7 +1,7 @@ /* - - TiMidity -- Experimental MIDI to WAVE converter - Copyright (C) 1995 Tuukka Toivonen + TiMidity++ -- MIDI to WAVE converter and player + Copyright (C) 1999 Masanao Izumo + Copyright (C) 1995 Tuukka Toivonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,7 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. vt_100_c.c - written by Masanao Izumo - */ #ifdef HAVE_CONFIG_H @@ -509,7 +508,7 @@ static int ctl_open(int using_stdin, int using_stdout) vt100_move(0, 0); fprintf(stdout, "TiMidity++ v%s" NLS, timidity_version); vt100_move(0, VT100_COLS-45); - fputs("(C) 1995 Tuukka Toivonen ", stdout); + fputs("(C) 1995 Tuukka Toivonen ", stdout); vt100_move(1,0); fputs("vt100 Interface mode - Written by Masanao Izumo ", stdout); diff --git a/interface/w32g.h b/interface/w32g.h index 24165e8d..60fca7f3 100644 --- a/interface/w32g.h +++ b/interface/w32g.h @@ -14,6 +14,7 @@ enum { RC_EXT_MODE_CHANGE, RC_EXT_APPLY_SETTING, RC_EXT_DELETE_PLAYLIST, + RC_EXT_UPDATE_PLAYLIST, }; #define W32G_TIMIDITY_CFG "C:\\WINDOWS\\TIMIDITY.CFG" @@ -86,6 +87,7 @@ extern void PutsConsoleWnd(char *str); extern void w32g_ctle_play_start(int sec); extern void SettingWndApply(void); extern int w32g_lock_open_file; +extern void w32g_i_init(); extern HINSTANCE hInst; @@ -123,6 +125,7 @@ extern void TmCanvasRefresh(void); extern void TmCanvasReset(void); extern void TmCanvasNote(int status, int ch, int note, int vel); extern int TmCanvasChange(void); +extern int TmCanvasMode; /* w32g_c.c */ extern int w32g_play_active; diff --git a/interface/w32g_c.c b/interface/w32g_c.c index ddefc67f..d8472b56 100644 --- a/interface/w32g_c.c +++ b/interface/w32g_c.c @@ -214,6 +214,9 @@ static int w32g_ext_control(int rc, int32 value) rc = ctl_delete_playlist(value); TmPanelUpdateList(); return rc; + case RC_EXT_UPDATE_PLAYLIST: + w32g_update_playlist(); + return rc; } return RC_NONE; } @@ -257,7 +260,8 @@ static void ctl_pass_playing_list(int number_of_files, char *list_of_files[]) w32g_play_active = 0; errcnt = 0; - if(w32g_valid_playlist() && (ctl.flags & CTLF_AUTOSTART)) + if(play_mode->fd != -1 && + w32g_valid_playlist() && (ctl.flags & CTLF_AUTOSTART)) rc = RC_LOAD_FILE; else rc = RC_NONE; diff --git a/interface/w32g_canvas.c b/interface/w32g_canvas.c index a145bdd6..d96f7cdc 100644 --- a/interface/w32g_canvas.c +++ b/interface/w32g_canvas.c @@ -84,7 +84,7 @@ static struct Bitset channel_on_flags[TCTM_MAX_CHANNELS]; } TmCanvas; -static int TmCanvasMode = TMCM_SLEEP; +int TmCanvasMode = TMCM_SLEEP; static HWND hCanvasWnd; static char CanvasWndClassName[] = "TiMidity Canvas"; diff --git a/interface/w32g_i.c b/interface/w32g_i.c index 3f6f42d9..e798d890 100644 --- a/interface/w32g_i.c +++ b/interface/w32g_i.c @@ -83,6 +83,7 @@ static char StartWndClassName[] = "MainWindow"; HINSTANCE hInst; // HWND +static HWND hStartWnd; static HWND hMainWnd = 0; static HWND hConsoleWnd = 0; static HWND hTracerWnd = 0; @@ -120,6 +121,7 @@ static WINBOOL CALLBACK MainProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lP static WINBOOL CALLBACK ListWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam); static WINBOOL CALLBACK ConsoleWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam); static void ConsoleWndVerbosityApplyIncDec(int diff); +static void InitListWnd(HWND hParentWnd); static void InitSettingWnd(HWND hParentWnd); static void OpenSettingWnd(HWND hwnd); static void SettingWndSetup(SETTING_TIMIDITY *st); @@ -248,15 +250,41 @@ static void NotImplemented(char *msg) w32g_msg_box(buff, "TiMidity Notice", MB_OK); } + +#define MAX_PLAY_MODE_LIST 8 +extern PlayMode w32_play_mode, wave_play_mode, raw_play_mode, au_play_mode, + aiff_play_mode; +static struct +{ + PlayMode *play_mode; + int32 orig_encoding; +} w32g_play_mode_list[] = +{ +{&w32_play_mode,0}, +{&wave_play_mode,0}, +{&au_play_mode,0}, +{&aiff_play_mode,0}, +{&raw_play_mode,0}, +{NULL,0} +}; + +void w32g_i_init(void) +{ + int i; + /* Save the original encoding */ + for(i = 0; w32g_play_mode_list[i].play_mode != NULL; i++) + { + w32g_play_mode_list[i].orig_encoding = + w32g_play_mode_list[i].play_mode->encoding; + } +} + void PutsConsoleWnd(char *str) { HWND hwnd; -// #### for debug -// fputs(str, stdout); -// fflush(stdout); - - if(!IsWindow(hConsoleWnd) || + if(!hConsoleWnd || + !IsWindow(hConsoleWnd) || !IsDlgButtonChecked(hConsoleWnd,IDC_CHECKBOX_VALID)) return; @@ -294,15 +322,7 @@ static void ToggleSubWindow(int id) if(IsWindowVisible(hwnd)) ShowWindow(hwnd,SW_HIDE); else - { ShowWindow(hwnd,SW_SHOW); - switch(id) - { - case IDM_LIST: - w32g_update_playlist(); - break; - } - } update_subwindow(id); MainWndUpdateButton(id); } @@ -432,6 +452,11 @@ void MainCmdProc(HWND hwnd, int wId, HWND hwndCtl, UINT wNotifyCode) break; case IDM_LIST: case IDM_MWPLAYLIST: + if(!hListWnd) + { + InitListWnd(hStartWnd); + w32g_send_rc(RC_EXT_UPDATE_PLAYLIST, 0); + } ToggleSubWindow(IDM_LIST); break; case IDM_DOC: @@ -476,6 +501,8 @@ void MainCmdProc(HWND hwnd, int wId, HWND hwndCtl, UINT wNotifyCode) OnExit(); break; case IDM_SETTING: + if(!hSettingWnd) + InitSettingWnd(hStartWnd); OpenSettingWnd(hwnd); break; case IDM_MCSAVEINIFILE: @@ -693,7 +720,6 @@ StartWinProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam) static void GUIThread(void *arglist) { MSG msg; - HWND hStartWnd; HICON hIcon; WNDCLASSEX wcl; @@ -735,11 +761,9 @@ static void GUIThread(void *arglist) InitToolbar(hMainWnd); - /* ListWnd */ - hListWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG_SIMPLE_LIST), - hStartWnd, ListWndProc); - ShowWindow(hListWnd,SW_HIDE); - UpdateWindow(hListWnd); +// /* ListWnd */ +// ShowWindow(hListWnd,SW_HIDE); +// UpdateWindow(hListWnd); /* ConsoleWnd */ hConsoleWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG_CONSOLE), @@ -758,9 +782,6 @@ static void GUIThread(void *arglist) SetScrollPos(hMainWndScrollbarVolumeWnd, SB_CTL, W32G_VOLUME_MAX - amplification, TRUE); - /* TiMidity Setting */ - InitSettingWnd(hStartWnd); - update_subwindow(-1); TmInitColor(); @@ -895,7 +916,7 @@ ListWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam) switch(uMess) { case WM_INITDIALOG: - w32g_update_playlist(); + w32g_send_rc(RC_EXT_UPDATE_PLAYLIST, 0); break; case WM_COMMAND: switch(HIWORD(wParam)) @@ -1063,6 +1084,12 @@ void MainWndScrollbarProgressUpdate(int sec) lastsec = sec; } +static void InitListWnd(HWND hParentWnd) +{ + hListWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG_SIMPLE_LIST), + hStartWnd, ListWndProc); +} + // ***************************************************************************** // TiMidity settings @@ -1071,31 +1098,14 @@ static BOOL CALLBACK SettingWndProc(HWND hwnd, UINT uMess, static HWND hComboOutput, hOutputEdit, hOutputRefBtn; -#define MAX_PLAY_MODE_LIST 8 -extern PlayMode w32_play_mode, wave_play_mode, raw_play_mode, au_play_mode, - aiff_play_mode; -static struct -{ - PlayMode *play_mode; - int32 orig_encoding; -} w32g_play_mode_list[] = -{ -{&w32_play_mode,0}, -{&wave_play_mode,0}, -{&au_play_mode,0}, -{&aiff_play_mode,0}, -{&raw_play_mode,0}, -{NULL,0} -}; - static void InitSettingWnd(HWND hParentWnd) { int i, selected, output_enabled; hSettingWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG_SETTING), hParentWnd, SettingWndProc); - ShowWindow(hSettingWnd,SW_HIDE); - UpdateWindow(hSettingWnd); +// ShowWindow(hSettingWnd,SW_HIDE); +// UpdateWindow(hSettingWnd); hComboOutput = GetDlgItem(hSettingWnd, IDC_COMBO_OUTPUT_MODE); hOutputEdit = GetDlgItem(hSettingWnd, IDC_EDIT_OUTPUT_FILE); @@ -1104,8 +1114,6 @@ static void InitSettingWnd(HWND hParentWnd) selected = 0; for(i = 0; w32g_play_mode_list[i].play_mode != NULL; i++) { - w32g_play_mode_list[i].orig_encoding = - w32g_play_mode_list[i].play_mode->encoding; ComboBox_InsertString(hComboOutput, i, w32g_play_mode_list[i].play_mode->id_name); if(w32g_play_mode_list[i].play_mode->id_character == @@ -1122,9 +1130,9 @@ static void InitSettingWnd(HWND hParentWnd) static void OpenSettingWnd(HWND hParentWnd) { + SettingWndSetup(st_current); ShowWindow(hSettingWnd,SW_SHOW); UpdateWindow(hSettingWnd); - SettingWndSetup(st_current); } #define IS_CHECKED(hwnd, id) (SendDlgItemMessage(hwnd, id, BM_GETCHECK, 0, 0) == BST_CHECKED) @@ -1272,9 +1280,16 @@ void SettingWndApply(void) } free_instruments(1); - play_mode->close_output(); + if(play_mode->fd != -1) + { + play_mode->close_output(); +// w32g_msg_box("Stopped playing because the parameters are changed.", +// "Warning", MB_OK); + } ApplySettingTiMidity(st_current); + ctl->trace_playing = (TmCanvasMode != TMCM_SLEEP); + restore_voices(1); } static void DlgSelectOutputFile(void) @@ -1323,23 +1338,8 @@ static void DlgSelectOutputFile(void) static BOOL CALLBACK SettingWndProc(HWND hwnd, UINT uMess, WPARAM wParam, LPARAM lParam) { - static int setting_warning_displayed = 0; - switch(uMess) { - case WM_SHOWWINDOW: - if(wParam) - { - if(w32g_play_active && - !setting_warning_displayed) - w32g_msg_box("Don't change parameter while playing", - "Warning", MB_OK); - setting_warning_displayed = 1; - SettingWndSetup(st_current); - } - else - setting_warning_displayed = 0; - break; case WM_COMMAND: switch (LOWORD(wParam)) { diff --git a/interface/w32g_utl.c b/interface/w32g_utl.c index 1f771ce6..b0db7976 100644 --- a/interface/w32g_utl.c +++ b/interface/w32g_utl.c @@ -710,6 +710,7 @@ void w32g_initialize(void) memcpy(sp_default, sp_current, sizeof(SETTING_PLAYER)); memcpy(st_default, st_current, sizeof(SETTING_TIMIDITY)); + w32g_i_init(); } int IniVersionCheck(void) diff --git a/interface/wrdt_mac.c b/interface/wrdt_mac.c index 83663d71..08556f66 100644 --- a/interface/wrdt_mac.c +++ b/interface/wrdt_mac.c @@ -49,21 +49,25 @@ #include "mac_wrdwindow.h" #include "mac_mag.h" #include "mac_wrd.h" +#include "aq.h" static int wrd_argc; //static int wrd_args[WRD_MAXPARAM]; static int inkey_flag; +//#define WRD_DEBUG(x) ctl->cmsg x +#define WRD_DEBUG(x) /*nothing*/ static int wrdt_open(char *wrdt_opts); static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]); static void wrdt_update_events(void); -static void wrdt_start(int wrdflag) +static int wrdt_start(int wrdflag) { if( wrdflag ){ sry_start(); ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "WRD START"); } + return 0; } static void wrdt_end(void) @@ -102,11 +106,18 @@ void dev_set_height(int height) SizeWindow(win.ref, WRD_GSCR_WIDTH, height, false); } +static void mac_RedrawControl(int flag) +{ + dev_redrawflag=flag; +} + void dev_redisp(Rect rect) { GDHandle oldGD; GWorldPtr oldGW; + if( !dev_redrawflag ) return; + //ActivatePalette(win.ref); LOCK_ALL_PIXMAP(); GetGWorld(&oldGW, &oldGD); @@ -121,9 +132,26 @@ void dev_redisp(Rect rect) UNLOCK_ALL_PIXMAP(); } +static void reverse_helper(int x, int y, int byte) +{ + Rect rect; + + rect.left=WRD_LOCX(x); //erase upper + rect.top=WRD_LOCY(y-1)+3; + rect.right=rect.left+BASE_X*byte; + rect.bottom=rect.top+1; + PaintRect(&rect); + + rect.left=WRD_LOCX(x)+7*byte; //erase right + //rect.top=WRD_LOCY(y-1)+2; + rect.right=rect.left+byte; + rect.bottom=WRD_LOCY(y)+3; + PaintRect(&rect); +} + static void dev_text_redraw(int locx1, int locy1, int locx2, int locy2) { - int x,y,startx, mode,color; + int x,y,startx, mode,color, len; GDHandle oldGD; GWorldPtr oldGW; @@ -131,8 +159,12 @@ static void dev_text_redraw(int locx1, int locy1, int locx2, int locy2) if( locx1<1 ) locx1=1; if( locx2>80 ) locx2=80; - if( locy1>1 ) locy1=1; + if( locy1<1 ) locy1=1; if( locy2>25 ) locy2=25; + if( wrd_ton==2 ){ + //locx1-= (locx1-1)%4; + locx1=1; + } LOCK_ALL_PIXMAP(); GetGWorld(&oldGW, &oldGD); @@ -148,10 +180,28 @@ static void dev_text_redraw(int locx1, int locy1, int locx2, int locy2) SET_T_RGBFORECOLOR_TMP(CHAR_COLOR_VRAM(x,y)&CATTR_TXTCOL_MASK); mode= (CHAR_COLOR_VRAM(x,y)&CATTR_BGCOLORED)? 2:1; color= TCODE2INDEX(CHAR_COLOR_VRAM(x,y)); + len= MULTI_BYTE_FLAG(x,y)? 2:1; + if( wrd_ton==2 ){ + char *cp; + if( MULTI_BYTE_FLAG(x-1,y) ){ + cp= &CHAR_VRAM(x-1,y); len=2; + SET_T_RGBFORECOLOR_TMP(CHAR_COLOR_VRAM(x-1,y)&CATTR_TXTCOL_MASK); + mode= (CHAR_COLOR_VRAM(x-1,y)&CATTR_BGCOLORED)? 2:1; + color= TCODE2INDEX(CHAR_COLOR_VRAM(x-1,y)); + }else{ + cp= &CHAR_VRAM(x,y); + } + dev_draw_text_gmode( dispWorld->portPixMap, WRD_LOCX(x), WRD_LOCY(y-1)+3, + cp, len, 0xFF, mode, color, color, wrd_ton ); + x+= len*2; + continue; + } + (CHAR_COLOR_VRAM(x,y)&CATTR_BGCOLORED)? + TextMode(notSrcOr) : TextMode(srcOr); WRD_MOVE_COURSOR_TMP(x,y); if( MULTI_BYTE_FLAG(x,y) ){ - dev_draw_text_gmode( dispWorld->portPixMap, WRD_LOCX(x), WRD_LOCY(y-1)+3, - &CHAR_VRAM(x,y), 2, 0xFF, mode, color, color ); + DrawText(&CHAR_VRAM(x,y), 0, 2); + if(CHAR_COLOR_VRAM(x,y)&CATTR_BGCOLORED) reverse_helper(x,y, 2); x+=2; }else{ if( CHAR_VRAM(x,y)==' ' && (CHAR_COLOR_VRAM(x,y)&CATTR_BGCOLORED) ){ @@ -162,9 +212,8 @@ static void dev_text_redraw(int locx1, int locy1, int locx2, int locy2) rect.right=rect.left+BASE_X; PaintRect(&rect); x++; }else{ - dev_draw_text_gmode( dispWorld->portPixMap, WRD_LOCX(x), WRD_LOCY(y-1)+3, - &CHAR_VRAM(x,y), 1, 0xFF, mode, color, color ); - x++; + DrawText(&CHAR_VRAM(x,y), 0, 1); + if(CHAR_COLOR_VRAM(x,y)&CATTR_BGCOLORED) reverse_helper(x,y, 1); x++; } } } @@ -185,7 +234,7 @@ void dev_remake_disp(Rect rect) LOCK_ALL_PIXMAP(); if( dev_gon_flag) MyCopyBits(GDISP_PIX, DISP_PIX, rect, rect, 0, 0, 0xFF, 0,0,0); - else dev_box(DISP_PIX, rect, 16, 0xFF); + else dev_box(DISP_PIX, rect, 0, 0xFF); //all pal=0 color UNLOCK_ALL_PIXMAP(); dev_text_redraw_rect(rect); @@ -271,6 +320,7 @@ static void dev_text_output(const char* text, int n) } } wrd_coursor_x+=n; + if( wrd_ton==2) endx+=2; dev_remake_disp(loc2rect(startx-1, wrd_coursor_y, endx+1, wrd_coursor_y)); dev_redisp(loc2rect(startx-1, wrd_coursor_y, endx+1, wrd_coursor_y)); @@ -285,21 +335,21 @@ static void dev_text_scroll(int x1, int y1, int x2, int y2, int mode, int color, { case 0: //scroll upper for( y=y1; y<=y2 && y<=LINES; y++ ){ - if( y-num <1 ) continue; + if( y-num =y1 && y>=1; y-- ){ - if( y+num> LINES ) continue; + if( y+num> y2 ) continue; memcpy(&CHAR_VRAM(1,y+num),&CHAR_VRAM(1,y),COLS); memcpy(&CHAR_COLOR_VRAM(1,y+num),&CHAR_COLOR_VRAM(1,y),COLS); memcpy(&MULTI_BYTE_FLAG(1,y+num),&MULTI_BYTE_FLAG(1,y),COLS); } - dev_text_clear(x1, 1, x2, y1+num-1, color, ch, false); + dev_text_clear(x1, y1, x2, y1+num-1, color, ch, false); break; case 2: //scroll right case 3: //scroll left @@ -469,23 +519,26 @@ void dev_gline(int x1, int y1, int x2, int y2, int p1, int sw, int p2, GWorldPtr switch(sw) { case 0: //line - dev_line(x1, y1, x2, y2, p1, gmode_mask_gline, + if( p2==0 || p2==WRD_NOARG ) p2= 0xFF; + dev_line(x1, y1, x2, y2, p1,p2, gmode_mask_gline, world->portPixMap ); break; case 1: //rect - dev_line(x1, y1, x2, y1, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x1, y1, x1, y2, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x2, y1, x2, y2, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x1, y2, x2, y2, p1, gmode_mask_gline,world->portPixMap ); + if( p2==0 || p2==WRD_NOARG ) p2= 0xFF; + dev_line(x1, y1, x2, y1, p1,p2, gmode_mask_gline,world->portPixMap ); + dev_line(x1, y1, x1, y2, p1,p2, gmode_mask_gline,world->portPixMap ); + dev_line(x2, y1, x2, y2, p1,p2, gmode_mask_gline,world->portPixMap ); + dev_line(x1, y2, x2, y2, p1,p2, gmode_mask_gline,world->portPixMap ); break; case 2: //filled rect + if( p2==WRD_NOARG ) p2= p1; rect.right++; rect.bottom++; dev_box(world->portPixMap, rect, p2, gmode_mask_gline); if( p1!=p2 ){ - dev_line(x1, y1, x2, y1, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x1, y1, x1, y2, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x2, y1, x2, y2, p1, gmode_mask_gline,world->portPixMap ); - dev_line(x1, y2, x2, y2, p1, gmode_mask_gline,world->portPixMap ); + dev_line(x1, y1, x2, y1, p1,0xFF, gmode_mask_gline,world->portPixMap ); + dev_line(x1, y1, x1, y2, p1,0xFF, gmode_mask_gline,world->portPixMap ); + dev_line(x2, y1, x2, y2, p1,0xFF, gmode_mask_gline,world->portPixMap ); + dev_line(x1, y2, x2, y2, p1,0xFF, gmode_mask_gline,world->portPixMap ); } break; } @@ -536,6 +589,7 @@ static void dev_gcircle(int x, int y, int r, int p1, int sw, int p2) } } +static void dev_set_text_attr(int esccode); static int Parse(int c); void dev_init(int version) @@ -544,7 +598,7 @@ void dev_init(int version) inkey_flag = 0; dev_gon_flag=1; - SET_T_COLOR(37); //white + dev_set_text_attr(37); //white dev_change_1_palette(0, black); dev_change_1_palette(16, black); //for gon(0) @@ -604,8 +658,6 @@ static OSErr dev_setup() static OSErr err=0; int i; Rect destRect; - GDHandle oldGD; - GWorldPtr oldGW; if( err ) return err; // once errored, do not retry @@ -621,7 +673,7 @@ static OSErr dev_setup() Rect charbufRect={0,0,16,32}; err=NewGWorld(&charbufWorld, 8, &charbufRect,0,0,0); if( err ) return err; - mac_setfont(charbufWorld, "\pOsaka|“™•"); + mac_setfont(charbufWorld, WRD_FONTNAME); } //wrd_palette= NewPalette( 33, 0, pmTolerant, 0x0000); @@ -634,18 +686,7 @@ static OSErr dev_setup() dev_init_text_color(); - GetGWorld(&oldGW, &oldGD); - LockPixels(DISP_PIX); - { - //short fontID; - //SetGWorld(dispWorld,0); - //GetFNum("\pOsaka|“™•", &fontID); - mac_setfont(dispWorld, "\pOsaka|“™•"); - //TextFont(fontID); - //TextSize(14); - } - SetGWorld(oldGW, oldGD); - UnlockPixels(DISP_PIX); + mac_setfont(dispWorld, WRD_FONTNAME); dev_init(-1); return 0; //noErr @@ -695,7 +736,7 @@ static void dev_set_text_attr(int esccode) { start: switch(esccode){ - default: + default: esccode=37; goto start; case 17: esccode=31; goto start; @@ -779,6 +820,9 @@ static int Parse(int c) if(params[nparam]==DEFAULT){ params[nparam]=0; } + if( c==' ' ){ + c='0'; + } params[nparam]*=10; params[nparam]+=c-'0'; } @@ -1134,11 +1178,26 @@ static void wrd_fadestep(int nowstep, int maxstep) RGBColor pal[16]; int code; //static unsigned long lasttick=0; + static int skip_num; //if( nowstep!=1 && nowstep!=maxstep /*&& (nowstep%4)==0*/ && lasttick==TickCount() ){ // return; //too fast fade. skip fading. //} + if( nowstep==1 ){ + skip_num=0; + } + + if( nowstep!=maxstep && !mac_flushing_flag){ //consider skipping + const int skip_threshold[11]={99,99,6,5,4, 2,1,0,0,0,0}; + int threshold= skip_threshold[ (int)(aq_filled_ratio()*10) ]; + if( skip_numcmsg(CMSG_INFO, VERB_VERBOSE, "%s", p); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "%s", p)); reuse_mblock(&tmpbuffer); } @@ -1306,9 +1364,14 @@ static void mac_wrd_DrawText(const char* str, int len) int i; for( i=0; i<=len; ){ - if( str[i]==0 ){ + if( str[i]==0 || i==len ){ dev_text_output(str, i); break; + }else if( wrd_coursor_x+i>80 ){ + dev_text_output(str, i); + dev_newline(); + //i++; + str+=i; len-=i; i=0; }else if( str[i]=='\x1b' ){ //esc sequence if( i ){ dev_text_output(str, i); @@ -1347,20 +1410,6 @@ static void mac_wrd_event_esc(int esc) mac_wrd_doESC(event2string(esc)+1); } -static int sry_decode_bindata( char *data ) -{ - int i; - for( i=0; data[i*2]; i++ ){ - if( data[i*2]==1 ){ - data[i]=0; - }else{ - data[i]=data[i*2+1]; - } - } - data[i]='\0'; - return i; -} - static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) { char *p; @@ -1375,8 +1424,8 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) if(cmd == WRD_MAGPRELOAD){ //char *p = wrd_event2string(arg); /* Load MAG file */ - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@WRD_MAGPRELOAD"); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@WRD_MAGPRELOAD")); wrd_argc = 0; return; } @@ -1395,67 +1444,69 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) code_convert(p, text, SAFE_CONVERT_LENGTH(len), NULL, NULL); } len = strlen(text); + if( len ){ mac_wrd_DrawText(text, text[len-1]=='\n'? len-1:len); if( text[len-1]=='\n' ){ dev_newline(); } ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%s", text); + } reuse_mblock(&tmpbuffer); break; case WRD_COLOR: mac_wrd_color(wrd_args[0]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "@COLOR(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@COLOR(%d)", wrd_args[0])); break; case WRD_END: /* Never call */ - ctl->cmsg(CMSG_INFO, VERB_VERBOSE,"@END"); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE,"@END")); break; case WRD_ESC: mac_wrd_event_esc(wrd_args[0]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@ESC(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@ESC(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_EXEC: - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@EXEC(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@EXEC(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_FADE: mac_wrd_fade(wrd_args[0], wrd_args[1], wrd_args[2]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@FADE(%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@FADE(%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2])); break; case WRD_FADESTEP: wrd_fadestep(wrd_args[0], WRD_MAXFADESTEP); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@FADESTEP(%d/%d)", wrd_args[0], WRD_MAXFADESTEP); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@FADESTEP(%d/%d)", wrd_args[0], WRD_MAXFADESTEP)); break; case WRD_GCIRCLE: dev_gcircle(wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4], wrd_args[5]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@GCIRCLE(%d,%d,%d,%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], - wrd_args[4], wrd_args[5]); + wrd_args[4], wrd_args[5])); break; case WRD_GCLS: dev_clear_graphics(wrd_args[0]? wrd_args[0]:0xFF); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@GCLS(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@GCLS(%d)", wrd_args[0])); break; case WRD_GINIT: - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "@GINIT()"); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@GINIT()")); break; case WRD_GLINE: dev_gline(wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4], wrd_args[5], wrd_args[6],graphicWorld[activeGraphics]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@GLINE(%d,%d,%d,%d,%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4], - wrd_args[5], wrd_args[6]); + wrd_args[5], wrd_args[6])); break; case WRD_GMODE: DEV_SET_GMODE(wrd_args[0]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@GMODE(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@GMODE(%d)", wrd_args[0])); break; case WRD_GMOVE: wrd_args[0] &= ~0x7; wrd_args[4] &= ~0x7; @@ -1463,33 +1514,33 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) dev_gmove(wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4], wrd_args[5], graphicWorld[wrd_args[6]], graphicWorld[wrd_args[7]], wrd_args[8], 0, gmode_mask, 0,0,0); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@GMOVE(%d,%d, %d,%d, %d,%d, %d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4], - wrd_args[5], wrd_args[6], wrd_args[7], wrd_args[8]); + wrd_args[5], wrd_args[6], wrd_args[7], wrd_args[8])); break; case WRD_GON: dev_gon(wrd_args[0]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@GON(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@GON(%d)", wrd_args[0])); break; case WRD_GSCREEN: dev_gscreen(wrd_args[0], wrd_args[1]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@GSCREEN(%d,%d)", wrd_args[0], wrd_args[1]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@GSCREEN(%d,%d)", wrd_args[0], wrd_args[1])); break; case WRD_INKEY: inkey_flag = 1; - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "@INKEY - begin"); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@INKEY - begin")); break; case WRD_OUTKEY: inkey_flag = 0; - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "@INKEY - end"); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@INKEY - end")); break; case WRD_LOCATE: dev_move_coursor(wrd_args[0], wrd_args[1]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@LOCATE(%d,%d)", wrd_args[0], wrd_args[1]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@LOCATE(%d,%d)", wrd_args[0], wrd_args[1])); break; case WRD_LOOP: /* Never call */ break; @@ -1507,7 +1558,7 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) sprintf(p + strlen(p), "%d,", wrd_args[i]); } sprintf(p + strlen(p), "%d,%d)", wrd_args[3], wrd_args[4]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%s", p); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "%s", p)); reuse_mblock(&tmpbuffer); break; case WRD_MIDI: /* Never call */ @@ -1521,38 +1572,38 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) for(i = 1; i < 17; i++) sprintf(p + strlen(p), ",%03x", wrd_args[i]); strcat(p, ")"); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%s", p); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "%s", p)); reuse_mblock(&tmpbuffer); break; case WRD_PALCHG: - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@PALCHG(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@PALCHG(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_PALREV: dev_palrev(wrd_args[0]); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@PALREV(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@PALREV(%d)", wrd_args[0])); break; case WRD_PATH: - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@PATH(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@PATH(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_PLOAD: wrd_pho(wrd_event2string(wrd_args[0])); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@PLOAD(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@PLOAD(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_REM: p = wrd_event2string(wrd_args[0]); len = strlen(p); text = (char *)new_segment(&tmpbuffer, SAFE_CONVERT_LENGTH(len)); code_convert(p, text, SAFE_CONVERT_LENGTH(len), NULL, NULL); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "@REM %s", text); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@REM %s", text)); reuse_mblock(&tmpbuffer); break; case WRD_REMARK: - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@REMARK(%s)", wrd_event2string(wrd_args[0])); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@REMARK(%s)", wrd_event2string(wrd_args[0]))); break; case WRD_REST: /* Never call */ break; @@ -1563,10 +1614,10 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) wrd_args[4], wrd_args[5], wrd_args[6], 1); dev_remake_disp(portRect); dev_redisp(portRect); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@SCROLL(%d,%d,%d,%d,%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], - wrd_args[4], wrd_args[5], wrd_args[6]); + wrd_args[4], wrd_args[5], wrd_args[6])); break; case WRD_STARTUP: dev_init(wrd_args[0]); @@ -1574,24 +1625,24 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) wrd_load_default_image(); inkey_flag = 0; dev_set_height(400); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@STARTUP(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@STARTUP(%d)", wrd_args[0])); break; case WRD_STOP: /* Never call */ break; case WRD_TCLS: dev_text_clear(wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3],wrd_args[4],wrd_args[5], true); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, "@TCLS(%d,%d,%d,%d,%d,%d)", wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], - wrd_args[4], wrd_args[5]); + wrd_args[4], wrd_args[5])); break; case WRD_TON: wrd_ton=wrd_args[0]; dev_remake_disp(portRect); dev_redisp(portRect); - ctl->cmsg(CMSG_INFO, VERB_VERBOSE, - "@TON(%d)", wrd_args[0]); + WRD_DEBUG((CMSG_INFO, VERB_VERBOSE, + "@TON(%d)", wrd_args[0])); break; case WRD_WAIT: /* Never call */ break; @@ -1633,6 +1684,8 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) print_ecmd("TSCRL", wrd_args, 0); break; case WRD_eVCOPY: + wrd_args[0] &= ~0x7; wrd_args[4] &= ~0x7; + wrd_args[2] |= 0x7; dev_gmove(wrd_args[0], wrd_args[1], wrd_args[2], wrd_args[3], wrd_args[4],wrd_args[5], graphicWorld[wrd_args[6]+(wrd_args[8]? 2:0)], @@ -1657,24 +1710,18 @@ static void wrdt_apply(int cmd, int wrd_argc, int wrd_args[]) /* Extensionals */ case WRD_START_SKIP: + mac_RedrawControl(0); ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "WRD START SKIP"); break; case WRD_END_SKIP: + mac_RedrawControl(1); ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "WRD END SKIP"); break; case WRD_SHERRY_UPDATE: sry_update(); break; - /*case WRD_SHERRY: - { - char* data= wrd_event2string(wrd_args[0]); - int len= strlen(data)/2; //decoded length - sry_decode_bindata(data); - sry_wrdt_apply(data, len); - } - break;*/ } wrd_argc = 0; } diff --git a/interface/xaw_c.c b/interface/xaw_c.c index 8a985304..35831667 100644 --- a/interface/xaw_c.c +++ b/interface/xaw_c.c @@ -306,14 +306,13 @@ static void ctl_close(void) static void xaw_add_midi_file(char *additional_path) { char *files[1],**ret,**tmp; int i,nfiles,nfit; - char *p,*elem; + char *p; files[0] = additional_path; nfiles = 1; - if((elem = strrchr(additional_path,'#')) != NULL) - ret = files; - else - ret = expand_file_archives(files, &nfiles); + ret = expand_file_archives(files, &nfiles); + if(ret == NULL) + return; tmp = list_of_files; titles=(char **)safe_realloc(titles,(number_of_files+nfiles)*sizeof(char *)); list_of_files=(char **)safe_malloc((number_of_files+nfiles)*sizeof(char *)); @@ -340,7 +339,8 @@ static void xaw_add_midi_file(char *additional_path) { for (i=0;i #include +#ifndef __MACOS__ #include #include #include #include +#endif /* __MACOS__ */ #ifndef NO_STRING_H #include @@ -40,11 +42,12 @@ #include #endif /* NO_STRING_H */ +#ifndef __MACOS__ #include #include #include #include - +#endif /* __MACOS__ */ #define XSKIN_WINDOW_NAME "Timidity" #define XSKIN_RES_CLASS "timidity" @@ -150,8 +153,8 @@ extern void ts_spectrum( int, unsigned char * ); #define BITRATE_Y 43 #define SAMPLE_X 156 #define SAMPLE_Y 43 -#define MESSAGE_X 110 -#define MESSAGE_Y 24 +#define MESSAGE_X 112 +#define MESSAGE_Y 27 /* numbers */ diff --git a/libarc/Makefile.am b/libarc/Makefile.am index f9a32416..5b191a12 100644 --- a/libarc/Makefile.am +++ b/libarc/Makefile.am @@ -30,7 +30,6 @@ noinst_LIBRARIES = libarc.a libarc_a_SOURCES = \ arc.c \ arc.h \ - arc_dir.c \ arc_lzh.c \ arc_mime.c \ arc_tar.c \ @@ -60,16 +59,14 @@ EXTRA_libarc_a_SOURCES = \ url_http.c \ url_ftp.c \ url_news.c \ - url_newsgroup.c \ - arc_newsgroup.c + url_newsgroup.c if ENABLE_NETWORK NET_OBJS = \ url_http.o \ url_ftp.o \ url_news.o \ - url_newsgroup.o \ - arc_newsgroup.o + url_newsgroup.o endif libarc_a_LIBADD = $(NET_OBJS) diff --git a/libarc/Makefile.in b/libarc/Makefile.in index 4b94fc3d..70a341d3 100644 --- a/libarc/Makefile.in +++ b/libarc/Makefile.in @@ -116,13 +116,13 @@ INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/timidity -I$(top_srcdir)/utils $ noinst_LIBRARIES = libarc.a -libarc_a_SOURCES = arc.c arc.h arc_dir.c arc_lzh.c arc_mime.c arc_tar.c arc_zip.c deflate.c explode.c explode.h inflate.c unlzh.c unlzh.h url.c url.h url_b64decode.c url_buff.c url_cache.c url_dir.c url_file.c url_hqxdecode.c url_inflate.c url_mem.c url_pipe.c url_qsdecode.c url_uudecode.c zip.h +libarc_a_SOURCES = arc.c arc.h arc_lzh.c arc_mime.c arc_tar.c arc_zip.c deflate.c explode.c explode.h inflate.c unlzh.c unlzh.h url.c url.h url_b64decode.c url_buff.c url_cache.c url_dir.c url_file.c url_hqxdecode.c url_inflate.c url_mem.c url_pipe.c url_qsdecode.c url_uudecode.c zip.h -EXTRA_libarc_a_SOURCES = url_http.c url_ftp.c url_news.c url_newsgroup.c arc_newsgroup.c +EXTRA_libarc_a_SOURCES = url_http.c url_ftp.c url_news.c url_newsgroup.c -@ENABLE_NETWORK_TRUE@NET_OBJS = url_http.o url_ftp.o url_news.o url_newsgroup.o arc_newsgroup.o +@ENABLE_NETWORK_TRUE@NET_OBJS = url_http.o url_ftp.o url_news.o url_newsgroup.o libarc_a_LIBADD = $(NET_OBJS) libarc_a_DEPENDENCIES = $(NET_OBJS) @@ -140,10 +140,10 @@ X_CFLAGS = @X_CFLAGS@ X_LIBS = @X_LIBS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ -libarc_a_OBJECTS = arc.o arc_dir.o arc_lzh.o arc_mime.o arc_tar.o \ -arc_zip.o deflate.o explode.o inflate.o unlzh.o url.o url_b64decode.o \ -url_buff.o url_cache.o url_dir.o url_file.o url_hqxdecode.o \ -url_inflate.o url_mem.o url_pipe.o url_qsdecode.o url_uudecode.o +libarc_a_OBJECTS = arc.o arc_lzh.o arc_mime.o arc_tar.o arc_zip.o \ +deflate.o explode.o inflate.o unlzh.o url.o url_b64decode.o url_buff.o \ +url_cache.o url_dir.o url_file.o url_hqxdecode.o url_inflate.o \ +url_mem.o url_pipe.o url_qsdecode.o url_uudecode.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -247,27 +247,23 @@ distdir: $(DISTFILES) || cp -p $$d/$$file $(distdir)/$$file || :; \ fi; \ done -arc.o: arc.c ../config.h ../timidity/timidity.h ../utils/support.h arc.h \ - ../utils/memb.h ../utils/mblock.h url.h zip.h unlzh.h explode.h \ - ../utils/strtab.h +arc.o: arc.c ../config.h ../timidity/timidity.h ../utils/support.h \ + ../timidity/common.h url.h ../utils/mblock.h arc.h \ + ../utils/strtab.h zip.h unlzh.h explode.h arc_dir.o: arc_dir.c ../config.h ../timidity/timidity.h \ ../utils/support.h arc.h ../utils/memb.h ../utils/mblock.h \ url.h arc_lzh.o: arc_lzh.c ../config.h ../timidity/timidity.h \ - ../utils/support.h arc.h ../utils/memb.h ../utils/mblock.h \ - url.h + ../utils/support.h arc.h url.h ../utils/mblock.h arc_mime.o: arc_mime.c ../config.h ../timidity/timidity.h \ - ../utils/support.h ../utils/mblock.h zip.h arc.h \ - ../utils/memb.h url.h + ../utils/support.h ../utils/mblock.h zip.h arc.h url.h arc_newsgroup.o: arc_newsgroup.c ../config.h ../timidity/timidity.h \ ../utils/support.h arc.h ../utils/memb.h ../utils/mblock.h \ url.h arc_tar.o: arc_tar.c ../config.h ../timidity/timidity.h \ - ../utils/support.h ../utils/mblock.h zip.h arc.h \ - ../utils/memb.h url.h + ../utils/support.h ../utils/mblock.h zip.h arc.h url.h arc_zip.o: arc_zip.c ../config.h ../timidity/timidity.h \ - ../utils/support.h arc.h ../utils/memb.h ../utils/mblock.h \ - url.h + ../utils/support.h arc.h url.h ../utils/mblock.h deflate.o: deflate.c ../config.h ../timidity/timidity.h \ ../utils/support.h ../utils/mblock.h zip.h explode.o: explode.c ../config.h ../timidity/timidity.h \ diff --git a/libarc/arc.c b/libarc/arc.c index 802ec472..812b14c5 100644 --- a/libarc/arc.c +++ b/libarc/arc.c @@ -1,29 +1,22 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ -#include -#include - #ifndef NO_STRING_H #include #else #include #endif - -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ +#include #include "timidity.h" +#include "common.h" #include "arc.h" -#include "mblock.h" +#include "strtab.h" #include "zip.h" #include "unlzh.h" #include "explode.h" -#include "strtab.h" char *arc_lib_version = ARC_LIB_VERSION; -ArchiveFileList *last_archive_file_list = NULL; #define GZIP_ASCIIFLAG (1u<<0) #define GZIP_MULTIPARTFLAG (1u<<1) @@ -40,15 +33,21 @@ ArchiveFileList *last_archive_file_list = NULL; #endif /* FALSE */ #define ABORT -1 -static void fix_path_sep(char *s); -static long url_arc_read(URL url, void *buff, long n); -static long url_arc_tell(URL url); -static void url_arc_close(URL url); -static char *archive_base_name(MBlockList *pool, char *name); -static int DoMatch(char *text, char *p); -static int DoCaseMatch(char *text, char *p); +ArchiveHandler arc_handler; + +typedef struct _ArchiveFileList +{ + char *archive_name; + ArchiveEntryNode *entry_list; + struct _ArchiveFileList *next; +} ArchiveFileList; +static ArchiveFileList *arc_filelist = NULL; -struct archive_ext_type_t archive_ext_list[] = +static struct +{ + char *ext; + int type; +} archive_ext_list[] = { {".tar", ARCHIVE_TAR}, {".tar.gz", ARCHIVE_TGZ}, @@ -142,47 +141,114 @@ int skip_gzip_header(URL url) return -1; } while(c != '\0'); } + return method; } -ArchiveEntryNode *new_entry_node(MBlockList *pool, char *filename, int len) +int parse_gzip_header_bytes(char *gz, long maxparse, int *hdrsiz) { - ArchiveEntryNode *p; + URL url = url_mem_open(gz, maxparse, 0); + int method; + + if(!url) + return -1; + method = skip_gzip_header(url); + *hdrsiz = url_tell(url); + url_close(url); + return method; +} + +void (* arc_error_handler)(char *error_message) = NULL; - p = (ArchiveEntryNode *) - new_segment(pool, sizeof(ArchiveEntryNode) + len + 1); - memset(p, 0, sizeof(ArchiveEntryNode)); - if(filename != NULL) +static void arc_cant_open(char *s) +{ + if(arc_error_handler != NULL) { - memcpy(p->filename, filename, len); - p->filename[len] = '\0'; + char buff[BUFSIZ]; + snprintf(buff, sizeof(buff), "%s: Can't open", s); + arc_error_handler(buff); } - p->compsize = p->origsize = -1; - return p; } -ArchiveHandler open_archive_handler(URL url, int archive_type) +int get_archive_type(char *archive_name) { - ArchiveHandler archiver; - ArchiveEntryNode *entry; - ArchiveEntryNode *(* next_header_entry)(ArchiveHandler archiver); - URL gzip_stream = NULL; - int gzip_method; + int i, len; + char *p; + int archive_name_length, delim; + +#ifdef SUPPORT_SOCKET + int type = url_check_type(archive_name); + if(type == URL_news_t) + return ARCHIVE_MIME; + if(type == URL_newsgroup_t) + return ARCHIVE_NEWSGROUP; +#endif /* SUPPORT_SOCKET */ + + if(strncmp(archive_name, "mail:", 5) == 0 || + strncmp(archive_name, "mime:", 5) == 0) + return ARCHIVE_MIME; + + if((p = strrchr(archive_name, '#')) != NULL) + { + archive_name_length = p - archive_name; + delim = '#'; + } + else + { + archive_name_length = strlen(archive_name); + delim = '\0'; + } + + for(i = 0; archive_ext_list[i].ext; i++) + { + len = strlen(archive_ext_list[i].ext); + if(len <= archive_name_length && + strncasecmp(archive_name + archive_name_length - len, + archive_ext_list[i].ext, len) == 0 && + archive_name[archive_name_length] == delim) + return archive_ext_list[i].type; /* Found */ + } + + if(url_check_type(archive_name) == URL_dir_t) + return ARCHIVE_DIR; + + return -1; /* Not found */ +} + +static ArchiveFileList *find_arc_filelist(char *basename) +{ + ArchiveFileList *p; + + for(p = arc_filelist; p; p = p->next) + { + if(strcmp(basename, p->archive_name) == 0) + return p; + } + return NULL; +} +ArchiveEntryNode *arc_parse_entry(URL url, int archive_type) +{ + ArchiveEntryNode *entry_first, *entry_last, *entry; + ArchiveEntryNode *(* next_header_entry)(void); + int gzip_method; + URL orig; + + orig = NULL; switch(archive_type) { case ARCHIVE_TAR: next_header_entry = next_tar_entry; break; case ARCHIVE_TGZ: - gzip_stream = url; - gzip_method = skip_gzip_header(gzip_stream); + gzip_method = skip_gzip_header(url); if(gzip_method != ARCHIVEC_DEFLATED) { url_close(url); return NULL; } - if((url = url_inflate_open(gzip_stream, -1, 1)) == NULL) + orig = url; + if((url = url_inflate_open(orig, -1, 0)) == NULL) return NULL; next_header_entry = next_tar_entry; break; @@ -192,306 +258,498 @@ ArchiveHandler open_archive_handler(URL url, int archive_type) case ARCHIVE_LZH: next_header_entry = next_lzh_entry; break; - case ARCHIVE_DIR: - if(url->type != URL_dir_t) - { - url_close(url); - return NULL; - } - next_header_entry = next_dir_entry; - break; case ARCHIVE_MIME: if(!IS_URL_SEEK_SAFE(url)) { - if((url = url_cache_open(url, 1)) == NULL) + orig = url; + if((url = url_cache_open(orig, 0)) == NULL) return NULL; } next_header_entry = next_mime_entry; break; -#ifdef SUPPORT_SOCKET - case ARCHIVE_NEWSGROUP: - if(url->type != URL_newsgroup_t) - { - url_close(url); - return NULL; - } - next_header_entry = next_newsgroup_entry; - break; -#endif /* SUPPORT_SOCKET */ default: return NULL; } - archiver = (ArchiveHandler)malloc(sizeof(struct _ArchiveHandler)); - if(archiver == NULL) + arc_handler.isfile = (url->type == URL_file_t); + arc_handler.url = url; + arc_handler.counter = 0; + entry_first = entry_last = NULL; + arc_handler.pos = 0; + while((entry = next_header_entry()) != NULL) { - url_close(url); - return NULL; + if(entry_first != NULL) + entry_last->next = entry; + else + entry_first = entry_last = entry; + while(entry_last->next) + entry_last = entry_last->next; + arc_handler.counter++; } - memset(archiver, 0, sizeof(struct _ArchiveHandler)); - archiver->decode_stream = url; + url_close(url); + if(orig) + url_close(orig); + return entry_first; /* Note that NULL if no archive file */ +} - if(archive_type == ARCHIVE_DIR) - archiver->type = AHANDLER_DIR; -#ifdef SUPPORT_SOCKET - else if(archive_type == ARCHIVE_NEWSGROUP) - archiver->type = AHANDLER_NEWSGROUP; -#endif /* SUPPORT_SOCKET */ - else if(!IS_URL_SEEK_SAFE(url)) - archiver->type = AHANDLER_CACHED; - else +static ArchiveFileList *add_arc_filelist(char *basename, int archive_type) +{ + URL url; + ArchiveFileList *afl; + ArchiveEntryNode *entry; + + switch(archive_type) { - archiver->type = AHANDLER_SEEK; - url_rewind(url); + case ARCHIVE_TAR: + case ARCHIVE_TGZ: + case ARCHIVE_ZIP: + case ARCHIVE_LZH: + case ARCHIVE_MIME: + break; + default: + return NULL; } - if((entry = next_header_entry(archiver)) == NULL) + if((url = url_open(basename)) == NULL) { - url_close(archiver->decode_stream); - archiver->decode_stream = NULL; - close_archive_handler(archiver); + arc_cant_open(basename); return NULL; } - fix_path_sep(entry->filename); - archiver->entry_head = archiver->entry_tail = entry; - archiver->nfiles = 1; - if(archive_type == ARCHIVE_MIME) + entry = arc_parse_entry(url, archive_type); + + afl = (ArchiveFileList *)safe_malloc(sizeof(ArchiveFileList)); + afl->archive_name = safe_strdup(basename); + afl->entry_list = entry; + afl->next = arc_filelist; + arc_filelist = afl; + return afl; +} + +int regist_archive(char *archive_filename, int archive_type) +{ + if(archive_type < 0) + archive_type = get_archive_type(archive_filename); + if(archive_type < 0) + return 0; /* Unknown archive */ + archive_filename = url_expand_home_dir(archive_filename); + if(find_arc_filelist(archive_filename)) + return 0; /* Already registerd */ + if(add_arc_filelist(archive_filename, archive_type)) { - while(archiver->entry_tail->next != NULL) - { - archiver->entry_tail = archiver->entry_tail->next; - fix_path_sep(archiver->entry_tail->filename); - archiver->nfiles++; - } + reuse_mblock(&arc_handler.pool); + return 1; } - else + return 0; +} + +static int arc_expand_newfile(StringTable *s, ArchiveFileList *afl, + char *pattern) +{ + ArchiveEntryNode *entry; + char *p; + + for(entry = afl->entry_list; entry; entry = entry->next) { - while((entry = next_header_entry(archiver)) != NULL) + if(arc_case_wildmat(entry->name, pattern)) { - fix_path_sep(entry->filename); - archiver->entry_tail = archiver->entry_tail->next = entry; - archiver->nfiles++; + p = new_segment(&arc_handler.pool, strlen(afl->archive_name) + + strlen(entry->name) + 2); + strcpy(p, afl->archive_name); + strcat(p, "#"); + strcat(p, entry->name); + if(put_string_table(s, p, strlen(p)) == NULL) + return -1; } } + return 0; +} - if(archiver->type == AHANDLER_SEEK) +char **expand_archive_names(int *nfiles_in_out, char **files) +{ + int i, nfiles, arc_type; + char *infile_name; + char *base, *pattern, *p, buff[BUFSIZ]; + char *one_file[1]; + int one; + ArchiveFileList *afl; + + /* Recusive global */ + static MBlockList *pool; + static StringTable stab; + static int error_flag = 0; + static int depth = 0; + + if(depth == 0) { - archiver->seek_stream = archiver->decode_stream; - if(archive_type == ARCHIVE_MIME) - url_cache_detach(archiver->seek_stream); + error_flag = 0; + init_string_table(&stab); + pool = &arc_handler.pool; } - else - url_close(archiver->decode_stream); - archiver->decode_stream = NULL; - archiver->pos = -1; - return archiver; -} + nfiles = *nfiles_in_out; -ArchiveHandler open_archive_handler_name(char *name) -{ - URL url; - int type; + for(i = 0; i < nfiles; i++) + { + infile_name = url_expand_home_dir(files[i]); + if((p = strrchr(infile_name, '#')) == NULL) + { + base = infile_name; + pattern = "*"; + } + else + { + int len = p - infile_name; + base = new_segment(pool, len + 1); /* +1 for '\0' */ + memcpy(base, infile_name, len); + base[len] = '\0'; + pattern = p + 1; + } - if((type = get_archive_type(name)) == -1) - return NULL; + if((afl = find_arc_filelist(base)) != NULL) + { + if(arc_expand_newfile(&stab, afl, pattern) == -1) + goto abort_expand; + continue; + } - /* open archiver stream */ - if(type != ARCHIVE_MIME) - { - if((url = url_open(name)) == NULL) - return NULL; - } - else - { - int len, method; - len = strlen(name); + arc_type = get_archive_type(base); + if(arc_type == -1) + { + if(put_string_table(&stab, infile_name, strlen(infile_name)) + == NULL) + goto abort_expand; + continue; + } - if(strncmp(name, "mail:", 5) == 0 || strncmp(name, "mime:", 5) == 0) - url = url_open(name + 5); - else - url = url_open(name); - if(url == NULL) - return NULL; +#ifdef SUPPORT_SOCKET + if(arc_type == ARCHIVE_NEWSGROUP) + { + URL url; + int len1, len2; + char *news_prefix; + + if((url = url_newsgroup_open(base)) == NULL) + { + arc_cant_open(base); + continue; + } + + strcpy(buff, base); + p = strchr(buff + 7, '/') + 1; /* news://..../ */ + *p = '\0'; + news_prefix = strdup_mblock(pool, buff); + len1 = strlen(news_prefix); + + while(url_gets(url, buff, sizeof(buff))) + { + len2 = strlen(buff); + p = (char *)new_segment(pool, len1 + len2 + 1); + strcpy(p, news_prefix); + strcpy(p + len1, buff); + one_file[0] = p; + one = 1; + depth++; + expand_archive_names(&one, one_file); + depth--; + } + url_close(url); + if(error_flag) + goto abort_expand; + continue; + } +#endif /* SUPPORT_SOCKET */ - if(len >= 3 && strcmp(name + len - 3, ".gz") == 0) + if(arc_type == ARCHIVE_DIR) { - method = skip_gzip_header(url); - if(method != ARCHIVEC_DEFLATED) + URL url; + int len1, len2; + + if((url = url_dir_open(base)) == NULL) { - url_close(url); - return NULL; + arc_cant_open(base); + continue; } - if((url = url_inflate_open(url, -1, 1)) == NULL) - return NULL; + + if(strncmp(base, "dir:", 4) == 0) + base += 4; + len1 = strlen(base); + if(base[len1 - 1] == PATH_SEP) + len1--; + while(url_gets(url, buff, sizeof(buff))) + { + if(strcmp(buff, ".") == 0 || strcmp(buff, "..") == 0) + continue; + + len2 = strlen(buff); + p = (char *)new_segment(pool, len1 + len2 + 2); + strcpy(p, base); + p[len1] = PATH_SEP; + strcpy(p + len1 + 1, buff); + one_file[0] = p; + one = 1; + depth++; + expand_archive_names(&one, one_file); + depth--; + } + url_close(url); + if(error_flag) + goto abort_expand; + continue; + } + + if((afl = add_arc_filelist(base, arc_type)) != NULL) + { + if(arc_expand_newfile(&stab, afl, pattern) == -1) + goto abort_expand; } } - return open_archive_handler(url, type); + if(depth) + return NULL; + *nfiles_in_out = stab.nstring; + reuse_mblock(pool); + return make_string_array(&stab); /* It is possible NULL */ + + abort_expand: + error_flag = 1; + if(depth) + return NULL; + delete_string_table(&stab); + free_global_mblock(); + *nfiles_in_out = 0; + return NULL; +} + +ArchiveEntryNode *new_entry_node(char *name, int len) +{ + ArchiveEntryNode *entry; + entry = (ArchiveEntryNode *)safe_malloc(sizeof(ArchiveEntryNode)); + memset(entry, 0, sizeof(ArchiveEntryNode)); + entry->name = (char *)safe_malloc(len + 1); + memcpy(entry->name, name, len); + entry->name[len] = '\0'; + return entry; +} + +void free_entry_node(ArchiveEntryNode *entry) +{ + free(entry->name); + if(entry->cache != NULL) + free(entry->cache); + free(entry); } -#ifndef __MACOS__ -static void fix_path_sep(char *s) + +static char *compress_buff; +long compress_buff_len; +static long arc_compress_func(char *buff, long size, void *user_val) { - int from, to; + if(compress_buff_len <= 0) + return 0; + if(size > compress_buff_len) + size = compress_buff_len; + memcpy(buff, compress_buff, size); + compress_buff += size; + compress_buff_len -= size; + return size; +} - if(PATH_SEP == '/') +void *arc_compress(void *buff, long bufsiz, + int compress_level, long *compressed_size) +{ + DeflateHandler compressor; + long allocated, offset, space, nbytes; + char *compressed; + + compress_buff = (char *)buff; + compress_buff_len = bufsiz; + compressor = open_deflate_handler(arc_compress_func, NULL, + compress_level); + allocated = 1024; + compressed = (char *)safe_malloc(allocated); + offset = 0; + space = allocated; + while((nbytes = zip_deflate(compressor, compressed + offset, space)) > 0) { - from = '\\'; - to = '/'; + offset += nbytes; + space -= nbytes; + if(space == 0) + { + space = allocated; + allocated += space; + compressed = (char *)safe_realloc(compressed, allocated); + } } - else + close_deflate_handler(compressor); + if(offset == 0) { - from = '/'; - to = '\\'; + free(buff); + return NULL; } + *compressed_size = offset; + return compressed; +} - while(*s) +void *arc_decompress(void *buff, long bufsiz, long *decompressed_size) +{ + InflateHandler decompressor; + long allocated, offset, space, nbytes; + char *decompressed; + + compress_buff = (char *)buff; + compress_buff_len = bufsiz; + decompressor = open_inflate_handler(arc_compress_func, NULL); + allocated = 1024; + decompressed = (char *)safe_malloc(allocated); + offset = 0; + space = allocated; + while((nbytes = zip_inflate(decompressor, decompressed + offset, space)) > 0) + { + offset += nbytes; + space -= nbytes; + if(space == 0) + { + space = allocated; + allocated += space; + decompressed = (char *)safe_realloc(decompressed, allocated); + } + } + close_inflate_handler(decompressor); + if(offset == 0) { - if(*s == from) - *s = to; - s++; + free(buff); + return NULL; } + *decompressed_size = offset; + return decompressed; } -#else -static void fix_path_sep(char *s) + +void free_archive_files(void) { - while(*s) + ArchiveEntryNode *entry, *ecur; + ArchiveFileList *acur; + + while(arc_filelist) { - if(*s == '/' || *s == '\\') - *s = ':'; - s++; + acur = arc_filelist; + arc_filelist = arc_filelist->next; + entry = acur->entry_list; + while(entry) + { + ecur = entry; + entry = entry->next; + free_entry_node(ecur); + } + free(acur->archive_name); + free(acur); } } -#endif /* __MACOS__ */ -long archiver_read_func(char *buff, long buff_size, void *v) + +/****************************************************************************** + * url_arc + *****************************************************************************/ +typedef struct _URL_arc +{ + char common[sizeof(struct _URL)]; + URL instream; + long pos, size; + int comptype; + void *decoder; +} URL_arc; + +static long url_arc_read(URL url, void *buff, long n); +static long url_arc_tell(URL url); +static void url_arc_close(URL url); + +static long archiver_read_func(char *buff, long buff_size, void *v) { - ArchiveHandler archiver; + URL_arc *url; long n; - archiver = (ArchiveHandler)v; - n = archiver->pos; - if(n <= 0 || archiver->decode_stream == NULL) - return 0; - if(n > buff_size) - n = buff_size; - n = url_read(archiver->decode_stream, buff, n); + url = (URL_arc *)v; + + if(url->size < 0) + n = buff_size; + else + { + n = url->size - url->pos; + if(n > buff_size) + n = buff_size; + } + + if(n <= 0) + return 0; + n = url_read(url->instream, buff, n); if(n <= 0) return n; - archiver->pos -= n; return n; } -typedef struct _URL_arc -{ - char common[sizeof(struct _URL)]; - ArchiveHandler archiver; - long pos; -} URL_arc; - -URL archive_extract_open(ArchiveHandler archiver, int idx) +URL url_arc_open(char *name) { - int i; - ArchiveEntryNode *p; URL_arc *url; - URL fileurl; + char *base, *p; + int len; + ArchiveFileList *afl; + ArchiveEntryNode *entry; + URL instream; - archiver->pos = -1; - if(idx == -1) - { - errno = ENOENT; + if((p = strrchr(name, '#')) == NULL) return NULL; - } - for(i = 0, p = archiver->entry_head; i < idx && p; i++, p = p->next) - ; - if(p == NULL) + len = p - name; + base = new_segment(&arc_handler.pool, len + 1); + memcpy(base, name, len); + base[len] = '\0'; + base = url_expand_home_dir(base); + if((afl = find_arc_filelist(base)) == NULL) { - errno = ENOENT; + reuse_mblock(&arc_handler.pool); return NULL; } + reuse_mblock(&arc_handler.pool); /* free `base' */ + name += len + 1; - archiver->pos = p->compsize; - if(archiver->pos == 0) + for(entry = afl->entry_list; entry; entry = entry->next) { - archiver->pos = -1; - return NULL; + if(strcasecmp(entry->name, name) == 0) + break; } - - if(p->comptype == -1) + if(entry == NULL) return NULL; - archiver->entry_cur = p; - archiver->decoder = NULL; - - switch(p->strmtype) - { - case ARCSTRM_MEMBUFFER: - if((archiver->decode_stream = memb_open_stream(&p->u.compdata, 0)) - == NULL) - return NULL; - break; - - case ARCSTRM_SEEK_URL: - archiver->decode_stream = archiver->seek_stream; - url_seek(archiver->decode_stream, p->u.seek_start, SEEK_SET); - break; - - case ARCSTRM_PATHNAME: - if((fileurl = url_file_open(p->u.pathname)) == NULL) - return NULL; - if(p->compsize != -1) - url_set_readlimit(fileurl, p->compsize); - return fileurl; - - case ARCSTRM_URL: - archiver->decode_stream = p->u.aurl.url; - url_seek(archiver->decode_stream, p->u.aurl.seek_start, SEEK_SET); - break; - } + if(entry->cache != NULL) + instream = url_mem_open((char *)entry->cache + entry->start, + entry->compsize, 0); + else + { + if((instream = url_file_open(base)) == NULL) + return NULL; + url_seek(instream, entry->start, 0); + } url = (URL_arc *)alloc_url(sizeof(URL_arc)); if(url == NULL) { - int save_errno = errno; - - if(p->strmtype == ARCSTRM_MEMBUFFER && archiver->decode_stream != NULL) - url_close(archiver->decode_stream); - archiver->decode_stream = NULL; - archiver->pos = -1; - errno = save_errno; - + url_errno = errno; return NULL; } - /* common members */ - URLm(url, type) = URL_arc_stream_t; - URLm(url, url_read) = url_arc_read; - URLm(url, url_gets) = NULL; - URLm(url, url_fgetc) = NULL; - URLm(url, url_seek) = NULL; - URLm(url, url_tell) = url_arc_tell; - URLm(url, url_close) = url_arc_close; - - /* private members */ - url->archiver = archiver; - url->pos = 0; - /* open decoder */ - switch(p->comptype) + switch(entry->comptype) { case ARCHIVEC_STORED: /* No compression */ case ARCHIVEC_LZHED_LH0: /* -lh0- */ case ARCHIVEC_LZHED_LZ4: /* -lz4- */ - p->comptype = ARCHIVEC_STORED; - archiver->decoder = NULL; + url->comptype = ARCHIVEC_STORED; + url->decoder = NULL; case ARCHIVEC_DEFLATED: /* deflate */ - archiver->decoder = - (void *)open_inflate_handler(archiver_read_func, archiver); - if(archiver->decoder == NULL) + url->decoder = + (void *)open_inflate_handler(archiver_read_func, url); + if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; @@ -502,11 +760,11 @@ URL archive_extract_open(ArchiveHandler archiver, int idx) case ARCHIVEC_IMPLODED_LIT4: case ARCHIVEC_IMPLODED_NOLIT8: case ARCHIVEC_IMPLODED_NOLIT4: - archiver->decoder = + url->decoder = (void *)open_explode_handler(archiver_read_func, - p->comptype - ARCHIVEC_IMPLODED - 1, - p->compsize, p->origsize, archiver); - if(archiver->decoder == NULL) + entry->comptype - ARCHIVEC_IMPLODED - 1, + entry->compsize, entry->origsize, url); + if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; @@ -523,114 +781,57 @@ URL archive_extract_open(ArchiveHandler archiver, int idx) case ARCHIVEC_LZHED_LHD: /* -lhd- */ case ARCHIVEC_LZHED_LH6: /* -lh6- */ case ARCHIVEC_LZHED_LH7: /* -lh7- */ - archiver->decoder = + url->decoder = (void *)open_unlzh_handler( archiver_read_func, - lzh_methods[p->comptype - ARCHIVEC_LZHED - 1], - p->compsize, p->origsize, archiver); - if(archiver->decoder == NULL) + lzh_methods[entry->comptype - ARCHIVEC_LZHED - 1], + entry->compsize, entry->origsize, url); + if(url->decoder == NULL) { url_arc_close((URL)url); return NULL; } break; + default: + url_arc_close((URL)url); + return NULL; + } - case ARCHIVEC_UU: /* uu encoded */ - if((archiver->decoder = - (void *)url_uudecode_open(archiver->decode_stream, 0)) == NULL) - { - url_arc_close((URL)url); - return NULL; - } - break; - - case ARCHIVEC_B64: /* base64 encoded */ - if((archiver->decoder = - (void *)url_b64decode_open(archiver->decode_stream, 0)) == NULL) - { - url_arc_close((URL)url); - return NULL; - } - break; - case ARCHIVEC_QS: /* quoted string encoded */ - if((archiver->decoder = - (void *)url_qsdecode_open(archiver->decode_stream, 0)) == NULL) - { - url_arc_close((URL)url); - return NULL; - } - break; - - case ARCHIVEC_HQX: /* HQX encoded */ - if((archiver->decoder = - (void *)url_hqxdecode_open(archiver->decode_stream, 1, 0)) == NULL) - { - url_arc_close((URL)url); - return NULL; - } - break; - - default: - url_arc_close((URL)url); - return NULL; - } + /* common members */ + URLm(url, type) = URL_arc_t; + URLm(url, url_read) = url_arc_read; + URLm(url, url_gets) = NULL; + URLm(url, url_fgetc) = NULL; + URLm(url, url_seek) = NULL; + URLm(url, url_tell) = url_arc_tell; + URLm(url, url_close) = url_arc_close; + /* private members */ + url->instream = instream; + url->pos = 0; + url->size = entry->origsize; + url->comptype = entry->comptype; return (URL)url; } -URL archive_extract_open_name(ArchiveHandler archiver, char *entry_name) -{ - int i; - ArchiveEntryNode *entry; - - if(entry_name == NULL || *entry_name == '\0') - return archive_extract_open(archiver, 0); - - i = 0; - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(arc_case_wildmat(entry->filename, entry_name)) - return archive_extract_open(archiver, i); - i++; - } - errno = ENOENT; - return NULL; -} - -URL archive_file_extract_open(ArchiveFileList *list, char *name) -{ - int idx; - ArchiveHandler archiver; - ArchiveFileList *lp; - - if((lp = find_archiver(list, name, &idx)) == NULL) - return NULL; - if((archiver = lp->archiver) == NULL) - return NULL; - if(idx == -1) - return NULL; - return archive_extract_open(archiver, idx); -} - static long url_arc_read(URL url, void *vp, long bufsiz) { URL_arc *urlp = (URL_arc *)url; - ArchiveHandler archiver = urlp->archiver; long n = 0; int comptype; void *decoder; char *buff = (char *)vp; - if(archiver->pos == -1) + if(urlp->pos == -1) return 0; - comptype = archiver->entry_cur->comptype; - decoder = archiver->decoder; + comptype = urlp->comptype; + decoder = urlp->decoder; switch(comptype) { case ARCHIVEC_STORED: - n = archiver_read_func(buff, bufsiz, (void *)archiver); + n = archiver_read_func(buff, bufsiz, (void *)urlp); break; case ARCHIVEC_DEFLATED: @@ -677,9 +878,8 @@ static long url_arc_tell(URL url) static void url_arc_close(URL url) { - ArchiveHandler archiver = ((URL_arc *)url)->archiver; + URL_arc *urlp = (URL_arc *)url; void *decoder; - ArchiveEntryNode *p; int save_errno = errno; /* 1. close decoder @@ -687,11 +887,10 @@ static void url_arc_close(URL url) * 3. free url */ - p = archiver->entry_cur; - decoder = archiver->decoder; + decoder = urlp->decoder; if(decoder != NULL) { - switch(p->comptype) + switch(urlp->comptype) { case ARCHIVEC_DEFLATED: close_inflate_handler((InflateHandler)decoder); @@ -724,474 +923,15 @@ static void url_arc_close(URL url) url_close((URL)decoder); break; } - archiver->decoder = NULL; } - if(p->strmtype == ARCSTRM_MEMBUFFER && archiver->decode_stream != NULL) - url_close(archiver->decode_stream); - archiver->decode_stream = NULL; - - archiver->pos = -1; - free(url); - errno = save_errno; + if(urlp->instream != NULL) + url_close(urlp->instream); + free(urlp); + errno = save_errno; } -void close_archive_handler(ArchiveHandler archiver) -{ - ArchiveEntryNode *entry; - if(archiver == NULL) - return; - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(entry->strmtype == ARCSTRM_MEMBUFFER) - delete_memb(&entry->u.compdata); - else if(entry->strmtype == ARCSTRM_URL && entry->u.aurl.idx == 0 && - entry->u.aurl.url != NULL) { - url_close(entry->u.aurl.url); - entry->u.aurl.url = NULL; - } - } - - if(archiver->decode_stream == archiver->seek_stream) - { - if(archiver->decode_stream != NULL) - url_close(archiver->decode_stream); - } - else - { - if(archiver->decode_stream != NULL) - url_close(archiver->decode_stream); - if(archiver->seek_stream != NULL) - url_close(archiver->seek_stream); - } - reuse_mblock(&archiver->pool); - free(archiver); -} -void close_archive_files(ArchiveFileList *list) -{ - while(list) - { - ArchiveFileList *p; - - p = list; - list = list->next; - free(p->archive_name); - close_archive_handler(p->archiver); - free(p); - } -} - -int get_archive_type(char *archive_name) -{ - int i, len; - char *p; - int archive_name_length, delim; - -#ifdef SUPPORT_SOCKET - int type = url_check_type(archive_name); - if(type == URL_news_t) - return ARCHIVE_MIME; - if(type == URL_newsgroup_t) - return ARCHIVE_NEWSGROUP; -#endif /* SUPPORT_SOCKET */ - - if(strncmp(archive_name, "mail:", 5) == 0 || - strncmp(archive_name, "mime:", 5) == 0) - return ARCHIVE_MIME; - - if((p = strchr(archive_name, '#')) != NULL) - { - archive_name_length = p - archive_name; - delim = '#'; - } - else - { - archive_name_length = strlen(archive_name); - delim = '\0'; - } - - for(i = 0; archive_ext_list[i].ext; i++) - { - len = strlen(archive_ext_list[i].ext); - if(len <= archive_name_length && - strncasecmp(archive_name + archive_name_length - len, - archive_ext_list[i].ext, len) == 0 && - archive_name[archive_name_length] == delim) - return archive_ext_list[i].type; /* Found */ - } - - if(url_check_type(archive_name) == URL_dir_t) - return ARCHIVE_DIR; - - return -1; /* Not found */ -} - -static char *archive_base_name(MBlockList *pool, char *name) -{ - char *p; - int len; - - if(*name == '\0') - return NULL; - if((p = strchr(name, '#')) == NULL) - return strdup_mblock(pool, name); - - len = p - name; - if((p = (char *)new_segment(pool, len + 1)) == NULL) - return NULL; - memcpy(p, name, len); - p[len] = '\0'; - return p; -} - -static ArchiveFileList *new_archive_list(char *filename) -{ - ArchiveFileList *node; - char *basename; - MBlockList pool; - - init_mblock(&pool); - - if((basename = archive_base_name(&pool, filename)) == NULL) - { - reuse_mblock(&pool); - return NULL; - } - - if(get_archive_type(basename) == -1) - { - reuse_mblock(&pool); - return NULL; - } - - node = (ArchiveFileList *)malloc(sizeof(ArchiveFileList)); - if(node == NULL) - { - reuse_mblock(&pool); - return NULL; - } - - node->archive_name = strdup(basename); - if(node->archive_name == NULL) - { - free(node); - reuse_mblock(&pool); - return NULL; - } - - /* open archive handler */ - if((node->archiver = open_archive_handler_name(basename)) == NULL) - { - if(errno == 0) - errno = ENOENT; - node->errstatus = errno; - reuse_mblock(&pool); - return node; - } - - node->errstatus = 0; - reuse_mblock(&pool); - return node; -} - -ArchiveFileList *add_archive_list(ArchiveFileList *list, char *name) -{ - ArchiveFileList *node; - ArchiveHandler archiver; - ArchiveEntryNode *entry; - - name = url_expand_home_dir(name); - if(find_archiver(list, name, NULL) != NULL) - return list; - if((node = new_archive_list(name)) == NULL) - return list; - - node->next = list; - archiver = node->archiver; - list = node; - - if(archiver == NULL) - return list; - - if(archiver->type == AHANDLER_DIR) - { - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(find_archiver(list, entry->u.pathname, NULL) != NULL) - continue; - if((node = new_archive_list(entry->u.pathname)) != NULL) - { - node->next = list; - list = node; - } - } - } -#ifdef SUPPORT_SOCKET - else if(archiver->type == AHANDLER_NEWSGROUP) - { - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(find_archiver(list, entry->filename, NULL) != NULL) - continue; - if((node = new_archive_list(entry->filename)) != NULL) - { - node->next = list; - list = node; - } - } - } -#endif /* SUPPORT_SOCKET */ - return list; -} - -ArchiveFileList *make_archive_list(ArchiveFileList *list, - int nfiles, char **files) -{ - int i; - for(i = 0; i < nfiles; i++) - list = add_archive_list(list, files[i]); - return list; -} - -ArchiveFileList* find_archiver(ArchiveFileList *list, char *name, int *idx) -{ - char *base_name; - MBlockList pool; - ArchiveFileList *lp; - ArchiveHandler archiver = NULL; - - last_archive_file_list = NULL; - init_mblock(&pool); - name = url_expand_home_dir(name); - if((base_name = archive_base_name(&pool, name)) == NULL) - { - reuse_mblock(&pool); - return NULL; - } - - for(lp = list; lp; lp = lp->next) - { - if(strcmp(lp->archive_name, base_name) == 0) - { - last_archive_file_list = lp; - archiver = lp->archiver; - break; - } - } - - if(archiver == NULL || lp == NULL) - { - reuse_mblock(&pool); - return lp; - } - - if(idx != NULL) - { - name += strlen(base_name); - if(*name == '#') - name++; - if(*name == '\0') - *idx = 0; - else - { - ArchiveEntryNode *entry; - int i; - - i = 0; - *idx = -1; - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(arc_case_wildmat(entry->filename, name)) - { - *idx = i; - break; - } - i++; - } - } - } - - reuse_mblock(&pool); - return lp; -} - -static int put_arc_rep(StringTable *stab, - char *basename, int blen, char *filename, int flen) -{ - MBlockList pool; - char *qp, *s; - int qplen; - StringTableNode *st; - - init_mblock(&pool); - qp = (char *)new_segment(&pool, flen * 2 + 1); - qplen = 0; - while(*filename) - { - if(*filename == '\\' || - *filename == '?' || - *filename == '*' || - *filename == '[') - qp[qplen++] = '\\'; - qp[qplen++] = *filename++; - } - qp[qplen++] = '\0'; - if((st = put_string_table(stab, NULL, blen + qplen + 1)) == NULL) - { - reuse_mblock(&pool); - return 1; - } - s = st->string; - memcpy(s, basename, blen); - s[blen] = '#'; - memcpy(s + blen + 1, qp, qplen + 1); - reuse_mblock(&pool); - return 0; -} - -static int add_archive_files(StringTable *stab, - ArchiveFileList *list, - char *pathname, char *pattern) -{ - int plen; - ArchiveEntryNode *entry; - ArchiveHandler archiver; - ArchiveFileList* lp; - - plen = strlen(pathname); - if((lp = find_archiver(list, pathname, NULL)) == NULL) - { - if(put_string_table(stab, pathname, plen) == NULL) - return 1; - return 0; - } - - if((archiver = lp->archiver) == NULL) - return 0; - - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(*pattern == '\0' || arc_case_wildmat(entry->filename, pattern)) - { - if(put_arc_rep(stab, pathname, plen, - entry->filename, strlen(entry->filename))) - return 1; - } - } - return 0; -} - -char **expand_archive_names(ArchiveFileList *list, int *nfiles, char **files) -{ - StringTable stab; - int in_nfiles; - char *infile_name, *name; - ArchiveHandler archiver; - ArchiveEntryNode *entry; - int base_name_len, i; - - if(list == NULL) - return files; - - init_string_table(&stab); - in_nfiles = *nfiles; - for(i = 0; i < in_nfiles; i++) - { - ArchiveFileList *lp; - - infile_name = url_expand_home_dir(files[i]); - lp = find_archiver(list, infile_name, NULL); - if(lp == NULL || lp->archiver == NULL) - { - if(put_string_table(&stab, infile_name, strlen(infile_name)) - == NULL) - { - /* memory error */ - delete_string_table(&stab); - return NULL; - } - continue; - } - - archiver = lp->archiver; - name = strchr(infile_name, '#'); - if(name == NULL) - { - base_name_len = strlen(infile_name); - name = infile_name + base_name_len; - } - else - { - base_name_len = name - infile_name; - name++; - } - -#ifdef SUPPORT_SOCKET - if(archiver->type == AHANDLER_NEWSGROUP) - { - for(entry = archiver->entry_head; entry; entry = entry->next) - { - ArchiveHandler subarc; - ArchiveEntryNode *subentry; - ArchiveFileList *lp; - - if((lp = find_archiver(list, entry->filename, NULL)) == NULL) - continue; - if((subarc = lp->archiver) == NULL) - continue; - for(subentry = subarc->entry_head; subentry; - subentry = subentry->next) - { - if(*name == '\0' || - arc_case_wildmat(subentry->filename, name)) - { - - if(put_arc_rep(&stab, - entry->filename, - strlen(entry->filename), - subentry->filename, - strlen(subentry->filename))) - { - delete_string_table(&stab); - return NULL; - } - } - } - } - continue; - } -#endif /* SUPPORT_SOCKET */ - - for(entry = archiver->entry_head; entry; entry = entry->next) - { - if(*name == '\0' || arc_case_wildmat(entry->filename, name)) - { - if(entry->strmtype == ARCSTRM_PATHNAME) - { - if(add_archive_files(&stab, list, - entry->u.pathname, name)) - { - delete_string_table(&stab); - return NULL; - } - } - else - { - if(put_arc_rep(&stab, - infile_name, base_name_len, - entry->filename, strlen(entry->filename))) - { - delete_string_table(&stab); - return NULL; - } - } - } - } - } - *nfiles = stab.nstring; - return make_string_array(&stab); -} /************** wildmat ***************/ /* What character marks an inverted character class? */ diff --git a/libarc/arc.h b/libarc/arc.h index 310b2d89..5e2abf2e 100644 --- a/libarc/arc.h +++ b/libarc/arc.h @@ -3,106 +3,81 @@ /* Archive library */ -#include "memb.h" +#include "url.h" +#include "mblock.h" -#define ARC_LIB_VERSION "1.4.12" +#define ARC_LIB_VERSION "2.0.0" #define ARC_DEFLATE_LEVEL 6 /* 1:Compress faster .. 9:Compress better */ +#define ARC_ENTRY_HASHSIZE 63 -typedef struct _ArchiveStreamURL -{ - int idx; - long seek_start; - URL url; -} ArchiveStreamURL; - -typedef struct _ArchiveEntryNode -{ - struct _ArchiveEntryNode *next; /* next entry */ - int comptype; /* Compression/Encoding type */ - int strmtype; /* Archive stream type */ - long compsize; /* Compressed size */ - long origsize; /* Uncompressed size */ - union - { - /* Archive streams */ - MemBuffer compdata; /* for ARCSTRM_MEMBUFFER */ - long seek_start; /* for ARCSTRM_SEEK_URL */ - char *pathname; /* for ARCSTRM_PATHNAME */ - ArchiveStreamURL aurl; /* for ARCSTRM_URL */ - } u; - char filename[1]; /* Archive file name (variable length) */ -} ArchiveEntryNode; -typedef struct _ArchiveHandler -{ - /* Archive handler type */ - int type; +/* + * Interfaces + */ - /* Number of archive entryes */ - int nfiles; +extern int regist_archive(char *archive_filename, int archive_type); +/* Regist archive file name to use url_arc_open */ - /* Archive entry */ - ArchiveEntryNode *entry_head; - ArchiveEntryNode *entry_tail; +extern char **expand_archive_names(int *nfiles_in_out, char **files_in_out); +/* Regist all archive files in `files_in_out', and expand the archive */ - /* current extract entry */ - ArchiveEntryNode *entry_cur; +extern URL url_arc_open(char *name); +/* Open input stream from registerd archive */ - /* current decode handler */ - void *decoder; +extern void free_archive_files(void); +/* Call once at the last */ - /* decode rest size */ - long pos; - - /* for decoder stream */ - URL decode_stream; +/* utilities */ +extern int skip_gzip_header(URL url); +extern int parse_gzip_header_bytes(char *gz, long maxparse, int *hdrsiz); +extern int get_archive_type(char *archive_name); +extern void *arc_compress(void *buff, long bufsiz, + int compress_level, long *compressed_size); +extern void *arc_decompress(void *buff, long bufsiz, long *decompressed_size); +extern int arc_case_wildmat(char *text, char *p); +extern int arc_wildmat(char *text, char *p); +extern void (* arc_error_handler)(char *error_message); - /* for AHANDLER_SEEK */ - URL seek_stream; - /* Memory pool */ - MBlockList pool; -} *ArchiveHandler; -typedef struct _ArchiveFileList +/* + * Internal library usage only + */ +typedef struct _ArchiveEntryNode { - char *archive_name; - int errstatus; - ArchiveHandler archiver; - struct _ArchiveFileList *next; -} ArchiveFileList; + struct _ArchiveEntryNode *next; /* next entry */ + char *name; /* Name of this entry */ -struct archive_ext_type_t -{ - char *ext; - int type; -}; + int comptype; /* Compression/Encoding type */ + long compsize; /* Compressed size */ + long origsize; /* Uncompressed size */ + long start; /* Offset start point */ + void *cache; /* Cached data */ +} ArchiveEntryNode; -/* Archive handler type */ -enum -{ - AHANDLER_CACHED, - AHANDLER_SEEK, - AHANDLER_DIR, - AHANDLER_NEWSGROUP -}; +typedef struct _ArchiveHandler { + int isfile; + URL url; /* Input stream */ + int counter;/* counter to extract the entry*/ + long pos; + MBlockList pool; +} ArchiveHandler; -/* Archive stream type */ -enum -{ - ARCSTRM_MEMBUFFER, - ARCSTRM_SEEK_URL, - ARCSTRM_PATHNAME, - ARCSTRM_URL, - ARCSTRM_NEWSGROUP -}; +extern ArchiveHandler arc_handler; +extern ArchiveEntryNode *arc_parse_entry(URL url, int archive_type); +extern ArchiveEntryNode *new_entry_node(char *name, int len); +extern ArchiveEntryNode *next_tar_entry(void); +extern ArchiveEntryNode *next_zip_entry(void); +extern ArchiveEntryNode *next_lzh_entry(void); +extern ArchiveEntryNode *next_mime_entry(void); +extern void free_entry_node(ArchiveEntryNode *entry); /* Compression/Encoding type */ enum { ARCHIVEC_STORED, /* No compression */ - ARCHIVEC_PATHNAME, /* Pathname */ + ARCHIVEC_PATHNAME, /* Pathname (Contents exists there) */ ARCHIVEC_COMPRESSED, /* Compressed */ ARCHIVEC_PACKED, /* Packed */ ARCHIVEC_DEFLATED, /* Deflate */ @@ -129,6 +104,8 @@ enum ARCHIVEC_LZHED_LHD, /* -lhd- (Directory, No compression data) */ ARCHIVEC_LZHED_LH6, /* -lh6- */ ARCHIVEC_LZHED_LH7, /* -lh7- */ + + /* Encode for MIME */ ARCHIVEC_UU, /* uu encoded */ ARCHIVEC_B64, /* base64 encoded */ ARCHIVEC_QS, /* quoted string encoded */ @@ -147,43 +124,4 @@ enum ARCHIVE_NEWSGROUP }; -/* Internal archive library functions */ -extern ArchiveEntryNode *new_entry_node(MBlockList *pool, - char *filename, int flen); -extern long archiver_read_func(char *buff, long buff_size, void *v); -extern ArchiveEntryNode *next_tar_entry(ArchiveHandler archiver); -extern ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver); -extern ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver); -extern ArchiveEntryNode *next_dir_entry(ArchiveHandler archiver); -extern ArchiveEntryNode *next_mime_entry(ArchiveHandler archiver); -extern ArchiveEntryNode *next_newsgroup_entry(ArchiveHandler archiver); -extern int skip_gzip_header(URL url); - -/* Interface functions */ -extern ArchiveHandler open_archive_handler(URL instream, int archive_type); -extern ArchiveHandler open_archive_handler_name(char *name); - -extern URL archive_extract_open(ArchiveHandler archiver, int idx); -extern URL archive_extract_open_name(ArchiveHandler archiver, - char *entry_name); -extern void close_archive_handler(ArchiveHandler archiver); -extern int get_archive_type(char *archive_name); -extern ArchiveFileList *add_archive_list(ArchiveFileList *list, - char *filename); -extern ArchiveFileList *make_archive_list(ArchiveFileList *list, - int nfiles, char **files); -extern char **expand_archive_names(ArchiveFileList *list, - int *nfiles_in_out, char **files); -extern ArchiveFileList* find_archiver(ArchiveFileList *list, - char *archive_name, int *idx_ret); -extern URL archive_file_extract_open(ArchiveFileList *list, char *name); -extern void close_archive_files(ArchiveFileList *list); -extern int arc_wildmat(char *text, char *ptn); -extern int arc_case_wildmat(char *text, char *ptn); - -extern struct archive_ext_type_t archive_ext_list[]; -extern int arc_internal_prefixID; -extern int arc_news_mime_allow; -extern ArchiveFileList *last_archive_file_list; - #endif /* ___LIBARC_H_ */ diff --git a/libarc/arc_dir.c b/libarc/arc_dir.c deleted file mode 100644 index 31095f1a..00000000 --- a/libarc/arc_dir.c +++ /dev/null @@ -1,49 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include -#ifndef NO_STRING_H -#include -#else -#include -#endif -#include "timidity.h" -#include "arc.h" - -ArchiveEntryNode *next_dir_entry(ArchiveHandler archiver) -{ - char filename[BUFSIZ]; - URL url; - char *dirname; - int flen, dlen; - ArchiveEntryNode *entry; - - url = archiver->decode_stream; - - if((dirname = url_dir_name(url)) == NULL) - return NULL; - - do - { - if(url_gets(url, filename, sizeof(filename)) == NULL) - return NULL; - } while(filename[0] == '.'); /* skip special file */ - - dlen = strlen(dirname); - flen = strlen(filename); - - entry = new_entry_node(&archiver->pool, filename, flen); - if(entry == NULL) - return NULL; - entry->comptype = ARCHIVEC_STORED; - entry->strmtype = ARCSTRM_PATHNAME; - entry->u.pathname = (char *)new_segment(&archiver->pool, dlen + flen + 2); - if(entry->u.pathname == NULL) - return NULL; - memcpy(entry->u.pathname, dirname, dlen); - if(dirname[dlen - 1] != PATH_SEP) - entry->u.pathname[dlen++] = PATH_SEP; - memcpy(entry->u.pathname + dlen, filename, flen + 1); - - return entry; -} diff --git a/libarc/arc_lzh.c b/libarc/arc_lzh.c index 8372cd7f..483995d5 100644 --- a/libarc/arc_lzh.c +++ b/libarc/arc_lzh.c @@ -209,7 +209,7 @@ static unsigned char *convdelim(unsigned char *path, unsigned char delim) return path; } -ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver) +ArchiveEntryNode *next_lzh_entry(void) { ArchiveEntryNode *entry; URL url; @@ -228,8 +228,8 @@ ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver) int macbin_check; extern char *lzh_methods[]; - url = archiver->decode_stream; - macbin_check = (archiver->nfiles == 0); + url = arc_handler.url; + macbin_check = (arc_handler.counter == 0); retry_read: dir_length = 0; @@ -242,8 +242,8 @@ ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver) { macbin_check = 0; url_skip(url, 128-1); - if(archiver->type == AHANDLER_SEEK) - archiver->pos += 128; + if(arc_handler.isfile) + arc_handler.pos += 128; goto retry_read; } return NULL; @@ -453,8 +453,8 @@ ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver) parse_ok: if(strncmp("-lhd-", method_id, 5) == 0) { - if(archiver->type == AHANDLER_SEEK) - archiver->pos += hdrsiz; + if(arc_handler.isfile) + arc_handler.pos += hdrsiz; goto retry_read; /* Skip directory entry */ } @@ -463,38 +463,30 @@ ArchiveEntryNode *next_lzh_entry(ArchiveHandler archiver) break; if(!lzh_methods[i]) return NULL; - entry = new_entry_node(&archiver->pool, filename, name_length); + entry = new_entry_node(filename, name_length); if(entry == NULL) return NULL; entry->comptype = i + ARCHIVEC_LZHED + 1; entry->compsize = compsize; entry->origsize = origsize; - if(archiver->type == AHANDLER_SEEK) + if(arc_handler.isfile) { - entry->strmtype = ARCSTRM_SEEK_URL; - archiver->pos += hdrsiz; - entry->u.seek_start = archiver->pos; + arc_handler.pos += hdrsiz; + entry->start = arc_handler.pos; + entry->cache = NULL; url_skip(url, compsize); - archiver->pos += compsize; + arc_handler.pos += compsize; } else { - char buff[BUFSIZ]; - long rest, n; - - entry->strmtype = ARCSTRM_MEMBUFFER; - rest = compsize; - while(rest > 0) + long n; + entry->start = 0; + entry->cache = url_dump(url, compsize, &n); + if(n != compsize) { - n = rest; - if(n > sizeof(buff)) - n = sizeof(buff); - n = url_read(url, buff, n); - if(n <= 0) - break; - push_memb(&entry->u.compdata, buff, n); - rest -= n; + free_entry_node(entry); + return NULL; } } return entry; diff --git a/libarc/arc_mime.c b/libarc/arc_mime.c index fdb34dbf..a8daeeca 100644 --- a/libarc/arc_mime.c +++ b/libarc/arc_mime.c @@ -13,6 +13,8 @@ #include "zip.h" #include "arc.h" +extern char *safe_strdup(char *); + #ifndef MAX_CHECK_LINES #define MAX_CHECK_LINES 1024 #endif /* MAX_CHECK_LINES */ @@ -49,12 +51,12 @@ struct MIMEHeaderStream static void init_mime_stream(struct MIMEHeaderStream *hdr, URL url); static int next_mime_header(struct MIMEHeaderStream *hdr); static void end_mime_stream(struct MIMEHeaderStream *hdr); - static int seek_next_boundary(URL url, char *boundary, long *endpoint); static int whole_read_line(URL url, char *buff, int bufsiz); -static MemBuffer *url_memb_dump(URL url, int encoding); +static void *arc_mime_decode(void *data, long size, + int comptype, long *newsize); -ArchiveEntryNode *next_mime_entry(ArchiveHandler archiver) +ArchiveEntryNode *next_mime_entry(void) { ArchiveEntryNode *head, *tail; URL url; @@ -63,11 +65,11 @@ ArchiveEntryNode *next_mime_entry(ArchiveHandler archiver) struct MIMEHeaderStream hdr; int c; - if(archiver->nfiles != 0) + if(arc_handler.counter != 0) return NULL; head = tail = NULL; - url = archiver->decode_stream; /* url_seek must be safety */ + url = arc_handler.url; /* url_seek must be safety */ init_string_stack(&boundary); url_rewind(url); @@ -85,6 +87,8 @@ ArchiveEntryNode *next_mime_entry(ArchiveHandler archiver) MBlockList pool; long data_start, data_end, savepoint; int last_check, comptype, arctype; + void *part_data; + long part_data_size; new_boundary = encoding = name = filename = NULL; init_mblock(&pool); @@ -276,68 +280,105 @@ ArchiveEntryNode *next_mime_entry(ArchiveHandler archiver) else { arctype = get_archive_type(filename); - if(arctype == ARCHIVE_DIR || arctype == ARCHIVE_MIME) + switch(arctype) + { + case ARCHIVE_TAR: + case ARCHIVE_TGZ: + case ARCHIVE_ZIP: + case ARCHIVE_LZH: + break; + default: arctype = -1; + break; + } } + if(data_start == data_end) + { + ArchiveEntryNode *entry; + entry = new_entry_node(filename, strlen(filename)); + entry->comptype = ARCHIVEC_STORED; + entry->compsize = 0; + entry->origsize = 0; + entry->start = 0; + entry->cache = safe_strdup(""); + if(head == NULL) + head = tail = entry; + else + tail = tail->next = entry; + goto next_entry; + } + + url_seek(url, data_start, SEEK_SET); + part_data = url_dump(url, data_end - data_start, &part_data_size); + part_data = arc_mime_decode(part_data, part_data_size, + comptype, &part_data_size); + if(part_data == NULL) + goto next_entry; + if(arctype == -1) { + int gzmethod, gzhdrsiz, len, gz; + ArchiveEntryNode *entry; + + len = strlen(filename); + if(len >= 3 && strcasecmp(filename + len - 3, ".gz") == 0) + { + gz = 1; + filename[len - 3] = '\0'; + } + else + gz = 0; + entry = new_entry_node(filename, strlen(filename)); + + if(gz) + gzmethod = parse_gzip_header_bytes(part_data, part_data_size, + &gzhdrsiz); + else + gzmethod = -1; + if(gzmethod == ARCHIVEC_DEFLATED) + { + entry->comptype = ARCHIVEC_DEFLATED; + entry->compsize = part_data_size - gzhdrsiz; + entry->origsize = -1; + entry->start = gzhdrsiz; + entry->cache = part_data; + } + else + { + entry->comptype = ARCHIVEC_DEFLATED; + entry->origsize = part_data_size; + entry->start = 0; + entry->cache = arc_compress(part_data, part_data_size, + ARC_DEFLATE_LEVEL, &entry->compsize); + free(part_data); + if(entry->cache == NULL) + { + free_entry_node(entry); + goto next_entry; + } + } if(head == NULL) - head = tail = new_entry_node(&archiver->pool, filename, - strlen(filename)); + head = tail = entry; else - tail = tail->next = new_entry_node(&archiver->pool, filename, - strlen(filename)); - tail->comptype = comptype; - tail->strmtype = ARCSTRM_SEEK_URL; - tail->compsize = data_end - data_start; - tail->origsize = -1; - tail->u.seek_start = data_start; + tail = tail->next = entry; } else { - MemBuffer *b; - URL newurl; - ArchiveHandler subarc; + URL arcurl; ArchiveEntryNode *entry; - int idx; + ArchiveHandler orig; - url_seek(url, data_start, SEEK_SET); - url_set_readlimit(url, data_end - data_start); - b = url_memb_dump(url, comptype); - url_set_readlimit(url, -1); - if(b == NULL) - goto next_entry; - if((newurl = memb_open_stream(b, 1)) == NULL) - goto next_entry; - if((subarc = open_archive_handler(newurl, arctype)) == NULL) - goto next_entry; - - idx = 0; - entry = subarc->entry_head; - while(entry != NULL) - { - char *fn; - - fn = entry->filename; - if(head == NULL) - head = tail = new_entry_node(&archiver->pool, fn, - strlen(fn)); - else - tail = tail->next = - new_entry_node(&archiver->pool, fn, strlen(fn)); - tail->comptype = entry->comptype; - tail->strmtype = ARCSTRM_URL; - tail->compsize = entry->compsize; - tail->origsize = entry->origsize; - tail->u.aurl.idx = idx++; - tail->u.aurl.seek_start = entry->u.seek_start; - tail->u.aurl.url = newurl; - entry = entry->next; - } - subarc->entry_head = NULL; - subarc->decode_stream = subarc->seek_stream = NULL; - close_archive_handler(subarc); + arcurl = url_mem_open(part_data, part_data_size, 1); + orig = arc_handler; /* save */ + entry = arc_parse_entry(arcurl, arctype); + arc_handler = orig; /* restore */ + if(head == NULL) + head = tail = entry; + else + tail = tail->next = entry; + while(tail->next) + tail = tail->next; } next_entry: @@ -468,7 +509,7 @@ static int next_mime_header(struct MIMEHeaderStream *hdr) break; } c = *hdr->line; - if(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) + if(c == '>' || ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) break; if(c != ' ' && c != '\t') return 0; /* ?? */ @@ -548,45 +589,39 @@ static int seek_next_boundary(URL url, char *boundary, long *endpoint) return ret; } -static MemBuffer *url_memb_dump(URL url, int encoding) +static void *arc_mime_decode(void *data, long size, + int comptype, long *newsize) { - MemBuffer *b; - char buff[BUFSIZ]; - long n; + URL url; - if((b = (MemBuffer *)malloc(sizeof(MemBuffer))) == NULL) - return NULL; - init_memb(b); + if(comptype == ARCHIVEC_STORED) + return data; - switch(encoding) - { - case ARCHIVEC_UU: /* uu encoded */ - url = url_uudecode_open(url, 0); - break; - case ARCHIVEC_B64: /* base64 encoded */ - url = url_b64decode_open(url, 0); - break; - case ARCHIVEC_QS: /* quoted string encoded */ - url = url_qsdecode_open(url, 0); - break; - case ARCHIVEC_HQX: /* HQX encoded */ - url = url_hqxdecode_open(url, 1, 0); - break; - case ARCHIVEC_STORED: - break; - default: - url = NULL; - break; - } + if(data == NULL) + return NULL; - if(url == NULL) + if((url = url_mem_open(data, size, 1)) == NULL) + return NULL; + + switch(comptype) { - free(b); - return NULL; + case ARCHIVEC_UU: /* uu encoded */ + url = url_uudecode_open(url, 1); + break; + case ARCHIVEC_B64: /* base64 encoded */ + url = url_b64decode_open(url, 1); + break; + case ARCHIVEC_QS: /* quoted string encoded */ + url = url_hqxdecode_open(url, 1, 1); + break; + case ARCHIVEC_HQX: /* HQX encoded */ + url = url_qsdecode_open(url, 1); + break; + default: + url_close(url); + return NULL; } - - while((n = url_read(url, buff, sizeof(buff))) > 0) - push_memb(b, buff, n); - - return b; + data = url_dump(url, -1, newsize); + url_close(url); + return data; } diff --git a/libarc/arc_newsgroup.c b/libarc/arc_newsgroup.c deleted file mode 100644 index bb4f81b7..00000000 --- a/libarc/arc_newsgroup.c +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ -#include -#ifndef NO_STRING_H -#include -#else -#include -#endif -#include "timidity.h" -#include "arc.h" - -ArchiveEntryNode *next_newsgroup_entry(ArchiveHandler archiver) -{ - char name[BUFSIZ]; - URL url; - char *urlname, *p; - int len, i; - ArchiveEntryNode *entry; - - url = archiver->decode_stream; - - if((urlname = url_newsgroup_name(url)) == NULL) - return NULL; - - p = urlname; - if(strncmp(p, "news://", 7) == 0) - p += 7; - if((p = strchr(p, '/')) == NULL) - return NULL; - p++; - len = p - urlname; - p = name + len; - if(url_gets(url, p, sizeof(name) - len) == NULL) - return NULL; - - i = 0; - while('0' <= p[i] && p[i] <= '9') - i++; - if(p[i] != ' ') - return NULL; - i++; - memcpy(name + i, urlname, len); - - entry = new_entry_node(&archiver->pool, name + i, strlen(name + i)); - if(entry == NULL) - return NULL; - entry->comptype = ARCHIVEC_STORED; - entry->strmtype = ARCSTRM_NEWSGROUP; - - return entry; -} diff --git a/libarc/arc_tar.c b/libarc/arc_tar.c index 1096979a..43d46092 100644 --- a/libarc/arc_tar.c +++ b/libarc/arc_tar.c @@ -2,6 +2,7 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ #include +#include #include #ifndef NO_STRING_H #include @@ -19,7 +20,7 @@ static long octal_value(char *s, int len); static int tar_checksum(char *hdr); -ArchiveEntryNode *next_tar_entry(ArchiveHandler archiver) +ArchiveEntryNode *next_tar_entry(void) { char hdr[TARHDRSIZ]; long size, sizeb; @@ -28,77 +29,81 @@ ArchiveEntryNode *next_tar_entry(ArchiveHandler archiver) int flen; int macbin_check; - url = archiver->decode_stream; - macbin_check = (archiver->nfiles == 0); + url = arc_handler.url; + macbin_check = (arc_handler.counter == 0); retry_read: - if(url_read(url, hdr, TARHDRSIZ) != TARHDRSIZ) - return NULL; - if(macbin_check && hdr[0] == 0 && hdr[128] != 0) - { - int i; - - macbin_check = 0; - if(memcmp(hdr + 128 + 257, "ustar", 5) != 0) - return NULL; - for(i = 0; i < TARHDRSIZ - 128; i++) - hdr[i] = hdr[i + 128]; - if(url_read(url, hdr + TARHDRSIZ - 128, 128) != 128) - return NULL; - if(archiver->type == AHANDLER_SEEK) - archiver->pos += 128; - } + if(!macbin_check) + { + if(url_read(url, hdr, TARHDRSIZ) != TARHDRSIZ) + return NULL; + } else - { - if(hdr[0] == '\0') - return NULL; - if(!tar_checksum(hdr)) - return NULL; - } + { + int c = url_getc(url); + if(c == 0) + { + url_skip(url, 127); + if(arc_handler.isfile) + arc_handler.pos += 128; + if(url_read(url, hdr, TARHDRSIZ) != TARHDRSIZ) + return NULL; + } + else + { + hdr[0] = c; + if(url_read(url, hdr+1, TARHDRSIZ-1) != TARHDRSIZ-1) + return NULL; + } + } + + macbin_check = 0; + + if(hdr[0] == '\0') + return NULL; + if(!tar_checksum(hdr)) + return NULL; size = octal_value(hdr + 124, 12); flen = strlen(hdr); if(size == 0 && flen > 0 && hdr[flen - 1] == '/') { - if(archiver->type == AHANDLER_SEEK) - archiver->pos += TARHDRSIZ; + if(arc_handler.isfile) + arc_handler.pos += TARHDRSIZ; goto retry_read; } - entry = new_entry_node(&archiver->pool, hdr, flen); + entry = new_entry_node(hdr, flen); if(entry == NULL) return NULL; sizeb = (((size) + (TARBLKSIZ-1)) & ~(TARBLKSIZ-1)); - if(archiver->type == AHANDLER_SEEK) + if(arc_handler.isfile) { - archiver->pos += TARHDRSIZ; - entry->strmtype = ARCSTRM_SEEK_URL; + arc_handler.pos += TARHDRSIZ; entry->comptype = ARCHIVEC_STORED; entry->compsize = entry->origsize = size; - entry->u.seek_start = archiver->pos; + entry->start = arc_handler.pos; url_skip(url, sizeb); - archiver->pos += sizeb; + arc_handler.pos += sizeb; } else { - DeflateHandler encoder; - char buff[BUFSIZ]; - long compsize, n; - - archiver->pos = entry->origsize = size; - compsize = 0; - encoder = open_deflate_handler(archiver_read_func, archiver, - ARC_DEFLATE_LEVEL); - while((n = zip_deflate(encoder, buff, sizeof(buff))) > 0) + void *data; + long n; + + data = url_dump(url, size, &n); + if(size != n) { - push_memb(&entry->u.compdata, buff, n); - compsize += n; + free_entry_node(entry); + return NULL; } - close_deflate_handler(encoder); - entry->strmtype = ARCSTRM_MEMBUFFER; - entry->comptype = ARCHIVEC_DEFLATED; - entry->compsize = compsize; - url_skip(url, sizeb - size); + entry->cache = arc_compress(data, size, ARC_DEFLATE_LEVEL, + &entry->compsize); + free(data); + entry->comptype = ARCHIVEC_DEFLATED; + entry->origsize = size; + entry->start = 0; + url_skip(url, sizeb - size); } return entry; diff --git a/libarc/arc_zip.c b/libarc/arc_zip.c index 9e631d08..eea31181 100644 --- a/libarc/arc_zip.c +++ b/libarc/arc_zip.c @@ -25,7 +25,7 @@ static unsigned long get_long(char *s) (unsigned long)p[3]<<24); } -ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver) +ArchiveEntryNode *next_zip_entry(void) { unsigned long magic; unsigned short flen, elen, hdrsiz; @@ -37,8 +37,8 @@ ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver) unsigned short flags; int macbin_check; - url = archiver->decode_stream; - macbin_check = (archiver->nfiles == 0); + url = arc_handler.url; + macbin_check = (arc_handler.counter == 0); retry_read: if(url_read(url, buff, 4) != 4) @@ -59,8 +59,8 @@ ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver) { macbin_check = 0; url_skip(url, 128-4); - if(archiver->type == AHANDLER_SEEK) - archiver->pos += 128; + if(arc_handler.isfile) + arc_handler.pos += 128; goto retry_read; } @@ -175,12 +175,12 @@ ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver) { url_skip(url, elen); hdrsiz += elen; - if(archiver->type == AHANDLER_SEEK) - archiver->pos += hdrsiz; + if(arc_handler.isfile) + arc_handler.pos += hdrsiz; goto retry_read; } - entry = new_entry_node(&archiver->pool, buff, flen); + entry = new_entry_node(buff, flen); if(entry == NULL) return NULL; @@ -192,31 +192,23 @@ ArchiveEntryNode *next_zip_entry(ArchiveHandler archiver) url_skip(url, elen); hdrsiz += elen; - if(archiver->type == AHANDLER_SEEK) + if(arc_handler.isfile) { - entry->strmtype = ARCSTRM_SEEK_URL; - archiver->pos += hdrsiz; - entry->u.seek_start = archiver->pos; + arc_handler.pos += hdrsiz; + entry->start = arc_handler.pos; + entry->cache = NULL; url_skip(url, compsize); - archiver->pos += compsize; + arc_handler.pos += compsize; } else { - char buff[BUFSIZ]; - long rest, n; - - entry->strmtype = ARCSTRM_MEMBUFFER; - rest = compsize; - while(rest > 0) + long n; + entry->start = 0; + entry->cache = url_dump(url, compsize, &n); + if(n != compsize) { - n = rest; - if(n > sizeof(buff)) - n = sizeof(buff); - n = url_read(url, buff, n); - if(n <= 0) - break; - push_memb(&entry->u.compdata, buff, n); - rest -= n; + free_entry_node(entry); + return NULL; } } diff --git a/libarc/url.c b/libarc/url.c index 84aa59b3..811e8e7f 100644 --- a/libarc/url.c +++ b/libarc/url.c @@ -15,6 +15,7 @@ #ifdef HAVE_SAFE_MALLOC extern void *safe_malloc(size_t count); +extern void *safe_realloc(void *old_ptr, size_t new_size); #endif /* HAVE_SAFE_MALLOC */ /* #define DEBUG */ @@ -492,3 +493,51 @@ char *url_strerror(int no) return "Internal error"; return url_strerror_txt[no - URLERR_NONE]; } + +void *url_dump(URL url, long nbytes, long *read_size) +{ + long allocated, offset, read_len; + char *buff; + + if(read_size != NULL) + *read_size = 0; + if(nbytes == 0) + return NULL; + if(nbytes > 0) + { + buff = (void *)safe_malloc(nbytes); + read_len = url_nread(url, buff, nbytes); + if(read_size != NULL) + *read_size = read_len; + if(read_len <= 0) + { + free(buff); + return NULL; + } + return buff; + } + + allocated = 1024; + buff = (char *)safe_malloc(allocated); + offset = 0; + read_len = allocated; + while((nbytes = url_read(url, buff + offset, read_len)) > 0) + { + offset += nbytes; + read_len -= nbytes; + if(offset == allocated) + { + read_len = allocated; + allocated *= 2; + buff = (char *)safe_realloc(buff, allocated); + } + } + if(offset == 0) + { + free(buff); + return NULL; + } + if(read_size != NULL) + *read_size = offset; + return buff; +} diff --git a/libarc/url.h b/libarc/url.h index 04174be1..124bafd0 100644 --- a/libarc/url.h +++ b/libarc/url.h @@ -6,7 +6,7 @@ * http://www.goice.co.jp/member/mo/release/index.html#liburl */ -#define URL_LIB_VERSION "1.8.8" +#define URL_LIB_VERSION "1.9.0" /* Define if you want to enable pipe command scheme ("command|") */ #define PIPE_SCHEME_ENABLE @@ -85,6 +85,9 @@ extern void url_skip(URL url, long n); /* seek to first position */ extern void url_rewind(URL url); +/* dump */ +void *url_dump(URL url, long nbytes, long *real_read); + /* set read limit */ void url_set_readlimit(URL url, long readlimit); @@ -190,8 +193,8 @@ enum url_types URL_hqxdecode_t, /* HQX decoder */ URL_cgi_escape_t, /* WWW CGI Escape */ URL_cgi_unescape_t, /* WWW CGI Unescape */ + URL_arc_t, /* arc stream */ - URL_arc_stream_t = 98, /* arc stream */ URL_inflate_t = 99, /* LZ77 decode stream */ URL_extension_t = 100 /* extentional stream >= 100 */ diff --git a/libarc/url_file.c b/libarc/url_file.c index 4108aa5b..0112bad1 100644 --- a/libarc/url_file.c +++ b/libarc/url_file.c @@ -185,6 +185,9 @@ URL url_file_open(char *fname) mac_TransPathSeparater(fname, cnvname); fp = fopen(cnvname, "rb"); reuse_mblock(&pool); + if( fp==NULL ){ /*try original name*/ + fp = fopen(fname, "rb"); + } #else fp = fopen(fname, "rb"); #endif diff --git a/libarc/url_newsgroup.c b/libarc/url_newsgroup.c index 7aa4b30e..8fc0900a 100644 --- a/libarc/url_newsgroup.c +++ b/libarc/url_newsgroup.c @@ -499,6 +499,8 @@ static char *url_newsgroup_gets(URL url, char *buff, int n) } #ifdef NEWSGROUP_MAIN +void *safe_malloc(int n) { return malloc(n); } +void *safe_realloc(void *p, int n) { return realloc(p, n); } void main(int argc, char **argv) { URL url; diff --git a/timidity/Makefile.in b/timidity/Makefile.in index 3e847c6c..6bf2669d 100644 --- a/timidity/Makefile.in +++ b/timidity/Makefile.in @@ -279,8 +279,7 @@ audio_cnv.o: audio_cnv.c ../config.h timidity.h ../utils/support.h \ audio_cnv.h common.o: common.c ../config.h timidity.h ../utils/support.h common.h \ ../libarc/url.h ../utils/mblock.h output.h controls.h \ - ../libarc/arc.h ../utils/memb.h ../utils/nkflib.h wrd.h \ - ../utils/strtab.h + ../libarc/arc.h ../utils/nkflib.h wrd.h ../utils/strtab.h controls.o: controls.c ../config.h ../interface.h timidity.h \ ../utils/support.h controls.h effect.o: effect.c ../config.h timidity.h ../utils/support.h instrum.h \ @@ -315,8 +314,8 @@ output.o: output.c ../config.h timidity.h ../utils/support.h output.h \ playmidi.o: playmidi.c ../config.h timidity.h ../utils/support.h \ common.h ../libarc/url.h ../utils/mblock.h instrum.h playmidi.h \ readmidi.h output.h mix.h controls.h miditrace.h recache.h \ - ../libarc/arc.h ../utils/memb.h reverb.h wrd.h aq.h \ - ../interface/soundspec.h tables.h + ../libarc/arc.h reverb.h wrd.h aq.h ../interface/soundspec.h \ + tables.h raw_a.o: raw_a.c ../config.h timidity.h ../utils/support.h output.h \ controls.h rcp.o: rcp.c ../config.h timidity.h ../utils/support.h common.h \ @@ -353,8 +352,7 @@ timidity.o: timidity.c ../config.h ../interface.h timidity.h \ ../utils/support.h common.h ../libarc/url.h ../utils/mblock.h \ instrum.h playmidi.h readmidi.h output.h controls.h tables.h \ miditrace.h reverb.h ../interface/soundspec.h recache.h \ - ../libarc/arc.h ../utils/memb.h ../utils/strtab.h wrd.h \ - mid.defs aq.h + ../libarc/arc.h ../utils/strtab.h wrd.h mid.defs aq.h wave_a.o: wave_a.c ../config.h timidity.h ../utils/support.h output.h \ controls.h wrd_read.o: wrd_read.c ../config.h timidity.h ../utils/support.h \ diff --git a/timidity/aq.c b/timidity/aq.c index 7a8ca1fd..c82f0f45 100644 --- a/timidity/aq.c +++ b/timidity/aq.c @@ -438,10 +438,14 @@ int32 aq_samples(void) int32 aq_filled(void) { double realtime, es; + int filled; if(!IS_STREAM_TRACE) return 0; + if(play_mode->acntl(PM_REQ_GETFILLED, &filled) != -1) + return filled; + realtime = get_current_calender_time(); if(play_counter == 0) { @@ -473,8 +477,11 @@ int32 aq_soft_filled(void) int32 aq_fillable(void) { + int fillable; if(!IS_STREAM_TRACE) return 0; + if(play_mode->acntl(PM_REQ_GETFILLABLE, &fillable) != -1) + return fillable; return device_qsize / Bps - aq_filled(); } @@ -523,7 +530,7 @@ int aq_flush(int discard) int more_trace; /* to avoid infinite loop */ - double t1, t2; + double t1, t2, timeout_expect; int32 last_point; aq_add_count = 0; @@ -554,6 +561,8 @@ int aq_flush(int discard) more_trace = 1; t1 = get_current_calender_time(); last_point = aq_samples(); + timeout_expect = t1 + (double)aq_filled() / play_mode->rate; + while(more_trace || aq_filled() > 0) { rc = check_apply_control(); @@ -566,16 +575,26 @@ int aq_flush(int discard) aq_wait_ticks(); more_trace = trace_loop(); t2 = get_current_calender_time(); - if(t2 - t1 > 1.0 && more_trace) - { - int32 cur; - cur = aq_samples(); - if(last_point == cur) - break; /* Must be bug */ - last_point = cur; - t1 = t2; - } + + if(more_trace) + { + if(t2 - t1 > 1.0) + { + int32 cur; + cur = aq_samples(); + if(last_point == cur) + break; /* Must be bug */ + last_point = cur; + t1 = t2; + } + } + else + { + if(t2 > timeout_expect) + break; + } } + trace_flush(); play_mode->acntl(PM_REQ_FLUSH, NULL); play_counter = play_offset_counter = 0; return RC_NONE; diff --git a/timidity/common.c b/timidity/common.c index 17d0b260..8b388fbf 100644 --- a/timidity/common.c +++ b/timidity/common.c @@ -61,7 +61,6 @@ char *program_name, current_filename[1024]; MBlockList tmpbuffer; -ArchiveFileList *archive_file_list = NULL; char *output_text_code = NULL; #ifdef DEFAULT_PATH @@ -123,24 +122,9 @@ struct timidity_file *try_to_open(char *name, int decompress) URL url; int len; - archive_file_list = add_archive_list(archive_file_list, name); - errno = 0; - url = archive_file_extract_open(archive_file_list, name); - if(url == NULL) - { - if(last_archive_file_list != NULL && - last_archive_file_list->errstatus != 0) - { - errno = last_archive_file_list->errstatus; - return NULL; - } - - if(strchr(name, '#') != NULL) - return NULL; - - if((url = url_open(name)) == NULL) - return NULL; - } + if((url = url_arc_open(name)) == NULL) + if((url = url_open(name)) == NULL) + return NULL; tf = (struct timidity_file *)safe_malloc(sizeof(struct timidity_file)); tf->url = url; @@ -178,6 +162,11 @@ struct timidity_file *try_to_open(char *name, int decompress) url_cache_disable(tf->url); } +#ifdef __W32__ + /* Sorry, DECOMPRESSOR_LIST and PATCH_CONVERTERS are not worked yet. */ + return tf; +#endif /* __W32__ */ + #if defined(DECOMPRESSOR_LIST) if(decompress) { @@ -828,7 +817,7 @@ static char **expand_file_lists(char **files, int *nfiles_in_out) } nfiles = *nfiles_in_out; - /* count number of new files to add */ + /* Expand playlist recursively */ for(i = 0; i < nfiles; i++) { /* extract the file extension */ @@ -873,29 +862,26 @@ static char **expand_file_lists(char **files, int *nfiles_in_out) char **expand_file_archives(char **files, int *nfiles_in_out) { int nfiles; + char **new_files; + int new_nfiles; + /* First, expand playlist files */ nfiles = *nfiles_in_out; files = expand_file_lists(files, &nfiles); + if(files == NULL) + { + *nfiles_in_out = 0; + return NULL; + } - archive_file_list = make_archive_list(archive_file_list, nfiles, files); - if(archive_file_list != NULL) - { - char **new_files; - int new_nfiles; + /* Second, expand archive files */ + new_nfiles = nfiles; + new_files = expand_archive_names(&new_nfiles, files); + free(files[0]); + free(files); - new_nfiles = nfiles; - new_files = expand_archive_names(archive_file_list, - &new_nfiles, files); - if(new_files != NULL) - { - free(files[0]); - free(files); - nfiles = new_nfiles; - files = new_files; - } - } - *nfiles_in_out = nfiles; - return files; + *nfiles_in_out = new_nfiles; + return new_files; } #ifdef RAND_MAX diff --git a/timidity/linux_a.c b/timidity/linux_a.c index 2334e20b..9397fabf 100644 --- a/timidity/linux_a.c +++ b/timidity/linux_a.c @@ -205,13 +205,13 @@ static int open_output(void) tmp = AUDIO_BUFFER_BITS; if(!(dpm.encoding & PE_MONO)) tmp++; if(dpm.encoding & PE_16BIT) tmp++; - tmp |= (dpm.extra_param[0] << 16); i = tmp; + tmp |= (dpm.extra_param[0] << 16); if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) < 0) { ctl->cmsg(CMSG_WARNING, VERB_NORMAL, - "%s doesn't support %d-byte buffer fragments", - dpm.name, (1<rate = rate; return 0; } + + case PM_REQ_GETFILLABLE: + if(ioctl(dpm.fd, SNDCTL_DSP_GETOSPACE, &info) == -1) + return -1; + total = info.fragstotal * info.fragsize; + bytes = info.bytes; + if(bytes > total) + bytes = total; + if(!(dpm.encoding & PE_MONO)) bytes >>= 1; + if(dpm.encoding & PE_16BIT) bytes >>= 1; + *((int *)arg) = bytes; + return 0; + + case PM_REQ_GETFILLED: + if(ioctl(dpm.fd, SNDCTL_DSP_GETOSPACE, &info) == -1) + return -1; + total = info.fragstotal * info.fragsize; + bytes = info.bytes; + if(bytes > total) + bytes = total; + bytes = total - bytes; + if(!(dpm.encoding & PE_MONO)) bytes >>= 1; + if(dpm.encoding & PE_16BIT) bytes >>= 1; + *((int *)arg) = bytes; + return 0; + + case PM_REQ_GETSAMPLES: + if(ioctl(dpm.fd, SNDCTL_DSP_GETOPTR, &cinfo) == -1) + return -1; + bytes = cinfo.bytes; + if(!(dpm.encoding & PE_MONO)) bytes >>= 1; + if(dpm.encoding & PE_16BIT) bytes >>= 1; + *((int *)arg) = bytes; + return 0; + + case PM_REQ_FLUSH: + return ioctl(dpm.fd, SNDCTL_DSP_SYNC); } return -1; } diff --git a/timidity/mac_a.c b/timidity/mac_a.c index 8670294e..2d15a24a 100644 --- a/timidity/mac_a.c +++ b/timidity/mac_a.c @@ -49,7 +49,7 @@ extern int default_play_event(void *); static int open_output(void); /* 0=success, 1=warning, -1=fatal error */ static void close_output(void); -static void output_data(char *buf, int32 nbytes); +static int output_data(char *buf, int32 nbytes); static int acntl(int request, void *arg); @@ -82,7 +82,8 @@ SndChannelPtr gSndCannel=0; short mac_amplitude=0x00FF; unsigned long start_tic; volatile static int32 play_counter; -static int filling_flag, flushing_flag; +volatile int mac_buf_using_num, mac_flushing_flag; +static int filling_flag; /* ******************************************************************* */ static SndChannelPtr MyCreateSndChannel(short synth, long initOptions, SndCallBackUPP userRoutine, short queueLength) @@ -111,18 +112,20 @@ static void initCounter() { start_tic=TickCount(); play_counter=0; + mac_buf_using_num=0; filling_flag=0; play_mode->extra_param[0]=0; - flushing_flag=0; + mac_flushing_flag=0; } static pascal void callback( SndChannelPtr /*chan*/, SndCommand * cmd) { if( cmd->param2==FLUSH_END ){ - flushing_flag=0; + mac_flushing_flag=0; }else{ play_counter+= cmd->param2; } + mac_buf_using_num--; } static int open_output (void) @@ -152,6 +155,7 @@ static int open_output (void) theCmd.param1=mac_amplitude; SndDoCommand(gSndCannel, &theCmd, 0); initCounter(); + do_initial_filling=1; //experimental return 0; } @@ -190,7 +194,7 @@ static void QuingSndCommand(SndChannelPtr chan, const SndCommand *cmd) } } -static void output_data (char *buf, int32 nbytes) +static int output_data (char *buf, int32 nbytes) { short err,headerLen; //long len = count; @@ -198,6 +202,10 @@ static void output_data (char *buf, int32 nbytes) long offset; SndCommand theCmd; + if( gCursorIsWatch ){ + InitCursor(); gCursorIsWatch=false; + } + // start INITIAL FILLING if( play_counter==0 && filling_flag==0 && do_initial_filling){ filling_flag=1; @@ -221,7 +229,6 @@ static void output_data (char *buf, int32 nbytes) //s32tos16 (buf, count); /*power mac always 16bit*/ - if( nbytes>MACBUFSIZE) mac_ErrorExit("\pTiMidity Error--sound packet is too large"); err= SetupSndHeader((SndListHandle)soundHandle[nextBuf], @@ -239,13 +246,14 @@ static void output_data (char *buf, int32 nbytes) theCmd.param2=(long)( *(soundHandle[nextBuf])+offset); QuingSndCommand(gSndCannel, &theCmd); - nextBuf++; if( nextBuf>=MACBUFNUM ) nextBuf=0; + nextBuf++; mac_buf_using_num++; if( nextBuf>=MACBUFNUM ) nextBuf=0; theCmd.cmd= callBackCmd; // post set theCmd.param1= 0; theCmd.param2= samples; QuingSndCommand(gSndCannel, &theCmd); play_mode->extra_param[0] += samples; + return 0; /*good*/ } static void fade_output() @@ -267,8 +275,9 @@ static void purge_output (void) { OSErr err; SndCommand theCmd; - +#if FADE_AT_PURGE if( skin_state==PLAYING ) fade_output(); +#endif theCmd.cmd=flushCmd; /*clear buffer*/ err= SndDoImmediate(gSndCannel, &theCmd); theCmd.cmd=quietCmd; @@ -311,7 +320,7 @@ static int flush_output (void) int ret=RC_NONE; SndCommand theCmd; - flushing_flag=1; + mac_flushing_flag=1; theCmd.cmd= callBackCmd; theCmd.param1= 0; theCmd.param2= FLUSH_END; @@ -322,7 +331,7 @@ static int flush_output (void) trace_loop(); YieldToAnyThread(); //ctl->current_time(current_samples()); - if( ! flushing_flag ){ //end of midi + if( ! mac_flushing_flag ){ //end of midi ret= RC_NONE; break; }else if( mac_rc!=RC_NONE ){ @@ -339,16 +348,19 @@ static int32 current_samples(void) return play_counter; } -static int acntl(int request, void *arg) +static int acntl(int request, void * arg) { switch(request) { case PM_REQ_DISCARD: purge_output(); return 0; - /*case PM_REQ_GETQSIZ: - *(int32*)arg= MACBUFNUM*AUDIO_BUFFER_SIZE*40; - return 0;*/ + case PM_REQ_GETQSIZ: + *(int32*)arg= MACBUFNUM*AUDIO_BUFFER_SIZE*10; + return 0; + case PM_REQ_GETSAMPLES: + *(int*)arg= current_samples(); + return 0; } return -1; } diff --git a/timidity/mac_com.h b/timidity/mac_com.h index fb81dd8b..e37f72a3 100644 --- a/timidity/mac_com.h +++ b/timidity/mac_com.h @@ -27,10 +27,9 @@ #define MAC_COM_H #define SUPPORT_SOUNDSPEC -//#undef DECOMPRESSOR_LIST -//#define DECOMPRESSOR_LIST { 0 } #undef PATCH_EXT_LIST #define PATCH_EXT_LIST { ".pat", 0 } +#define URL_DIR_CACHE_DISABLE #undef DEFAULT_RATE #define DEFAULT_RATE 22050 @@ -42,6 +41,8 @@ #define DEFAULT_PATH "" #undef CONFIG_FILE #define CONFIG_FILE DEFAULT_PATH "timidity.cfg" +#define MAC_SIGNATURE 'TIMI' +#define MAC_STARTUP_FOLDER_NAME "\pStartup items" #define ENABLE_SHERRY #define MAC_SOUNDBUF_QLENGTH (stdQLength*4) diff --git a/timidity/mac_dlog.c b/timidity/mac_dlog.c index 7607b183..7d20df99 100644 --- a/timidity/mac_dlog.c +++ b/timidity/mac_dlog.c @@ -66,12 +66,19 @@ void mac_DefaultOption() opt_modulation_wheel = 1; opt_portamento = 1; opt_nrpn_vibrato = 1; +#ifdef REVERB_CONTROL_ALLOW + opt_reverb_control = 1; +#else opt_reverb_control = 0; +#endif +#ifdef CHORUS_CONTROL_ALLOW + opt_chorus_control = 1; +#else opt_chorus_control = 0; +#endif opt_channel_pressure = 0; opt_trace_text_meta_event = 0; opt_overlap_voice_allow = 1; - //do_reverb_flag = 0; effect_lr_mode=-1; //no effect modify_release=0; @@ -81,6 +88,7 @@ void mac_DefaultOption() evil_level=EVIL_NORMAL; do_initial_filling=0; + reduce_voice_threshold = -1; } enum{iOK=1, iCancel=2, iDefault=3, iRate=5, iMono=6, iStereo=7, @@ -100,7 +108,7 @@ enum{iOK=1, iCancel=2, iDefault=3, iRate=5, iMono=6, iStereo=7, iPresence_balance=32, iManufacture=33, iEvil_level=34, - iDo_initial_filling=35, + /*iDo_initial_filling=35,*/ iShuffle= 36 }; @@ -147,7 +155,7 @@ static void SetDialogValue(DialogRef theDialog) opt_default_mid==0x43? 2:3 ); //XG:GM SetDialogItemValue(theDialog, iManufacture, value); SetDialogItemValue(theDialog, iEvil_level, evil_level); - SetDialogItemValue(theDialog, iDo_initial_filling, do_initial_filling); + //SetDialogItemValue(theDialog, iDo_initial_filling, do_initial_filling); SetDialogItemValue(theDialog, iShuffle, gShuffle); } @@ -296,7 +304,7 @@ OSErr mac_SetPlayOption() case iText_meta_event: ToggleDialogItem(dialog, iText_meta_event); break; case iOverlap_voice: ToggleDialogItem(dialog, iOverlap_voice); break; case iPReverb: ToggleDialogItem(dialog, iPReverb); break; - case iDo_initial_filling: ToggleDialogItem(dialog, iDo_initial_filling); break; + //case iDo_initial_filling: ToggleDialogItem(dialog, iDo_initial_filling); break; case iShuffle: ToggleDialogItem(dialog, iShuffle); break; } } @@ -338,9 +346,9 @@ struct{ }Preference; -#define PREF_VER 12 +#define PREF_VER 13 + /* ++ 2.1.0 ->prefver=13 */ /* ++ beta1 ->prefver=12 */ - /* Mac release 3.24->prefver=11 */ #define PREF_NUM (sizeof(Preference)) /*pref data bytes*/ OSErr mac_GetPreference() diff --git a/timidity/mac_main.c b/timidity/mac_main.c index 670554c6..0bc2fd02 100644 --- a/timidity/mac_main.c +++ b/timidity/mac_main.c @@ -32,6 +32,7 @@ #include #include #include +#include "OMS.h" #include "timidity.h" #include "common.h" @@ -51,6 +52,7 @@ #include "mac_main.h" #include "mac_c.h" +#include "mac_oms.h" #include "mac_util.h" #define MAIN_INTERFACE /* non-static */ @@ -60,6 +62,7 @@ MAIN_INTERFACE int timidity_post_load_configuration(void); MAIN_INTERFACE void timidity_init_player(void); MAIN_INTERFACE int timidity_play_main(int nfiles, char **files); MAIN_INTERFACE int read_config_file(char *name, int self); +MAIN_INTERFACE void timidity_init_aq_buff(void); extern char *wrdt_open_opts; char *timidity_version = TIMID_VERSION; @@ -181,6 +184,7 @@ static void mac_init() InitMenuBar(); } + int main() { int32 output_rate=DEFAULT_RATE; @@ -204,16 +208,17 @@ int main() // "Try %s -h for help", program_name); return 1; /* problems with command line */ } + timidity_init_player(); wrdt=wrdt_list[0]; //dirty!! wrdt_open_opts= "m"; timidity_play_main(0, NULL); + //CPU won't return from timidity_play_main return 0; } static pascal void* StartPlay(void *) { - SndCommand theCmd; int rc; //for( i=0; imodifiers&cmdKey ) { - mac_HandleMenuSelect(MenuKey(event->message&charCodeMask)); + mac_HandleMenuSelect(MenuKey(event->message&charCodeMask), event->modifiers); HiliteMenu(0); break; }else{ //no command key @@ -326,8 +336,8 @@ void mac_HandleControl() else if( skin_state==PAUSE ){ mac_rc=RC_CONTINUE; mac_HandleControl(); } break; /*and wait ctl_read*/ case RC_TOGGLE_PAUSE: - if( skin_state==PAUSE ){ mac_rc=RC_CONTINUE; mac_HandleControl(); } - else if( skin_state==PLAYING ){ mac_rc=RC_PAUSE; mac_HandleControl(); } + if( skin_state==PAUSE ){ theCmd.cmd=resumeCmd; SndDoImmediate(gSndCannel, &theCmd); skin_state=PLAYING;} + else if( skin_state==PLAYING ){theCmd.cmd=pauseCmd; SndDoImmediate(gSndCannel, &theCmd); skin_state=PAUSE;} break; case RC_RESTART: break; /*and wait ctl_read*/ @@ -336,13 +346,13 @@ void mac_HandleControl() { mac_rc=RC_CONTINUE; mac_HandleControl(); mac_rc=RC_LOAD_FILE;} skin_state=WAITING; break; - case RC_PAUSE: + /*case RC_PAUSE: if( skin_state==PLAYING ){theCmd.cmd=pauseCmd; SndDoImmediate(gSndCannel, &theCmd); skin_state=PAUSE;} - break; - case RC_CONTINUE: + break;*/ + /*case RC_CONTINUE: if( skin_state==PAUSE ){ theCmd.cmd=resumeCmd; SndDoImmediate(gSndCannel, &theCmd); skin_state=PLAYING;} else if( skin_state==STOP ){ skin_state=WAITING; mac_rc=0; } - break; + break;*/ case RC_REALLY_PREVIOUS: break; /*and wait ctl_read*/ } @@ -355,8 +365,9 @@ void mac_HandleControl() extern PlayMode wave_play_mode; extern PlayMode aiff_play_mode; -extern PlayMode mac_quicktime_play_mode; extern PlayMode mac_play_mode; +extern PlayMode mac_quicktime_play_mode; +extern PlayMode mac_oms_play_mode; static pascal void* ConvertToAiffFile(void*) { @@ -375,6 +386,7 @@ static pascal void* ConvertToAiffFile(void*) { play_mode=&aiff_play_mode; if( play_mode->open_output()==-1 ) return 0; + aq_setup(); tmp=skin_state; skin_state=PLAYING; err=GetFullPath( &stdReply.sfFile, fullPath); @@ -383,6 +395,8 @@ static pascal void* ConvertToAiffFile(void*) skin_state=tmp; play_mode->close_output(); play_mode=&mac_play_mode; + aq_setup(); + timidity_init_aq_buff(); p2cstrcpy(newfile, stdReply.sfFile.name); strcat(newfile,".aiff"); rename("output.aiff", newfile); } @@ -437,7 +451,7 @@ static void CloseFrontWindow() macwin->goaway(macwin); } -void mac_HandleMenuSelect(long select) +void mac_HandleMenuSelect(long select, short modifiers) { StandardFileReply stdReply; Str255 str; @@ -493,15 +507,16 @@ void mac_HandleMenuSelect(long select) //Synth menu case iTiMidity:{ MenuHandle menu=GetMenu(mSynth); - CheckItem(menu, iTiMidity, 1); - CheckItem(menu, iQuickTime, 0); + CheckItem(menu, iTiMidity & 0x0000FFFF, 1); + CheckItem(menu, iQuickTime & 0x0000FFFF, 0); + CheckItem(menu, iOMS & 0x0000FFFF, 0); play_mode=&mac_play_mode; } return; case iQuickTime:{ MenuHandle menu=GetMenu(mSynth); - if( ! mac_quicktime_play_mode.fd ){ //not opened yet + if( mac_quicktime_play_mode.fd==-1 ){ //not opened yet if( mac_quicktime_play_mode.open_output()!=0 ){ SysBeep(0); return; //can't open device @@ -509,9 +524,25 @@ void mac_HandleMenuSelect(long select) } CheckItem(menu, iTiMidity & 0x0000FFFF, 0); CheckItem(menu, iQuickTime & 0x0000FFFF, 1); + CheckItem(menu, iOMS & 0x0000FFFF, 0); play_mode=&mac_quicktime_play_mode; } return; + case iOMS:{ + MenuHandle menu=GetMenu(mSynth); + + if( mac_oms_play_mode.fd==-1 || (modifiers & optionKey) ){ + if( mac_oms_play_mode.open_output()!=0 ){ + SysBeep(0); + return; //can't open device + } + } + CheckItem(menu, iTiMidity & 0x0000FFFF, 0); + CheckItem(menu, iQuickTime & 0x0000FFFF, 0); + CheckItem(menu, iOMS & 0x0000FFFF, 1); + play_mode=&mac_oms_play_mode; + } + return; } if( (select>>16)==mApple ) @@ -523,9 +554,21 @@ void mac_HandleMenuSelect(long select) void DoQuit() { - play_mode->close_output(); - ctl->close(); + if( mac_play_mode.fd!=-1 ) + mac_play_mode.close_output(); + if( mac_quicktime_play_mode.fd!=-1 ) + mac_quicktime_play_mode.close_output(); + if( mac_oms_play_mode.fd!=-1 ) + mac_oms_play_mode.close_output(); + if( ctl ) + ctl->close(); + mac_SetPreference(); + +#ifdef MAC_USE_OMS + mac_oms_quit(); +#endif + ExitToShell(); } @@ -580,8 +623,10 @@ static int isArchiveFilename(const char *fn) char *p; p= strrchr(fn, '.'); if( p==0 ) return 0; - if( strcasecmp(p, ".lzh")==0 || - strcasecmp(p, ".zip")==0 + if( strcasecmp(p, ".lzh")==0 || + strcasecmp(p, ".zip")==0 || + strcasecmp(p, ".tar")==0 || + strcasecmp(p, ".gz")==0 ){ return 1; }else{ diff --git a/timidity/mac_main.h b/timidity/mac_main.h index 31c7287b..b931b395 100644 --- a/timidity/mac_main.h +++ b/timidity/mac_main.h @@ -55,7 +55,7 @@ void mac_ErrorExit(Str255 msg); void mac_HandleEvent(EventRecord*); void mac_HandleControl(); void HandleMouseDown(EventRecord *event); -void mac_HandleMenuSelect(long select); +void mac_HandleMenuSelect(long select, short modifiers); OSErr mac_SetPlayOption(); void mac_DefaultOption(); @@ -74,13 +74,7 @@ void init_ListWin(); void HandleSpecKeydownEvent(long message, short /*modifiers*/); void ShuffleList(int start, int end); -//int isMidiFile(const FSSpec *spec); -//int isArchiveFile(const FSSpec *spec); -//void mac_add_midi_file(const FSSpec *spec); -//void mac_add_midi_file(const char *fullpath); -//oid mac_add_archive_file(const FSSpec *spec); void mac_add_fsspec( FSSpec *spec ); -//void mac_add_file(const char *fullpath); void read_viscolor(const char * viscolor_file); /******************************/ enum{ @@ -123,7 +117,8 @@ enum{ mSynth=0x00A0, iTiMidity=0x00A00001, - iQuickTime=0x00A00002 + iQuickTime=0x00A00002, + iOMS=0x00A00003 }; @@ -135,6 +130,7 @@ enum{ #define kSpecWinID 133 #define kTraceWinID 134 #define kSkinWinID 135 +#define kOmsWinID 136 enum{ MW_NOMSG=0, @@ -167,11 +163,11 @@ extern MacWindow mac_PlayerWindow, #define SHOW_WINDOW(mwin) {ShowWindow(mwin.ref);SelectWindow(mwin.ref);mwin.show=true;} #ifdef __POWERPC__ -#define PREF_FILENAME "\pTiMidity pref" +#define PREF_FILENAME "\pTiMidity++ pref" #elif __MC68881__ -#define PREF_FILENAME "\pTiMidity68kFPU pref" +#define PREF_FILENAME "\pTiMidity++68kFPU pref" #else -#define PREF_FILENAME "\pTiMidity68k pref" +#define PREF_FILENAME "\pTiMidity++68k pref" #endif extern int evil_level; @@ -180,5 +176,6 @@ extern int evil_level; #define EVIL_SPECIAL 3 extern int do_initial_filling; +extern volatile int mac_buf_using_num, mac_flushing_flag; #endif //MAC_MAIN_H diff --git a/timidity/mac_qt_a.c b/timidity/mac_qt_a.c index ccde21dd..6e70bc99 100644 --- a/timidity/mac_qt_a.c +++ b/timidity/mac_qt_a.c @@ -19,7 +19,7 @@ Macintosh interface for TiMidity by T.Nogami - KINOSHITA, K. + K.KINOSHITA mac_qt_a.c Macintosh QuickTime audio driver @@ -29,7 +29,7 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ #include -#ifdef HAVE_UNISTD_H +#ifndef __WIN32__ #include #endif #include @@ -55,12 +55,15 @@ #include "mac_main.h" -static int do_event(void *); static int open_output(void); static void close_output(void); -static int32 current_samples(void); +static int output_data(char *buf, int32 count); static int acntl(int request, void *arg); +static void play_event_prescan(void *); +static int wait_event_time(void *); +static void qt_play_event(void *); + static unsigned long start_tic; static NoteAllocator gNoteAllocator; @@ -68,17 +71,171 @@ static NoteAllocator gNoteAllocator; PlayMode dmp = { - DEFAULT_RATE, 0, PF_CAN_TRACE|PF_MIDI_EVENT, + DEFAULT_RATE, PE_16BIT|PE_SIGNED, PF_MIDI_EVENT|PF_CAN_TRACE, -1, {0,0,0,0,0}, "QuickTime MIDI mode", 'q', "-", open_output, close_output, - NULL, + output_data, acntl }; +static uint16 xg_sfx_voice[] = { // bank msb 64, lsb 0 + (1<<7)+120, // 0: cutting noise + (1<<7)+120, // 1: cutting noise 2 + (1<<7)+120, // 2: distotion cutting noise + (2<<7)+120, // 3: string slap + (0<<7)+120, // 4: bass slide -> guitar fret noise + 5, // 5: pick scrape -> (no tone) + 6,7,8,9,10,11,12,13,14,15, + (1<<7)+121, // 16: flute key click + 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, + (1<<7)+122, // 32: rain + (2<<7)+122, // 33: thunder + (3<<7)+122, // 34: wind + (4<<7)+122, // 35: stream + (5<<7)+122, // 36: bubble + 37, // 37: feed -> (no tone) + 38,39,40,41,42,43,44,45,46,47, + (1<<7)+123, // 48: dog + (2<<7)+123, // 49: horse + (3<<7)+123, // 50: bird 2 + 51, // 51: kitty -> (no tone) + 52, // 52: growl -> (no tone) + 53, // 53: haunted -> (no tone) + 54, // 54: ghost -> (no tone) + 55, // 55: maou -> (no tone) + 56,57,58,59,60,61,62,63, + (0<<7)+124, // 64: telephone dial + (2<<7)+124, // 65: door squeek? + (3<<7)+124, // 66: door slam + (4<<7)+124, // 67: scratch + (4<<7)+124, // 68: scratch 2 + (5<<7)+124, // 69: wind chime + (1<<7)+124, // 70: telephone 2 + 71,72,73,74,75,76,77,78,79, + (1<<7)+125, // 80: car engine + (2<<7)+125, // 81: car stop + (3<<7)+125, // 82: car pass + (4<<7)+125, // 83: car crash + (5<<7)+125, // 84: siren + (6<<7)+125, // 85: train + (7<<7)+125, // 86: jetplane + (8<<7)+125, // 87: starship + (9<<7)+125, // 88: burst + 89, // 89: coaster + 90, // 90: submarine + 91,92,93,94,95, + (1<<7)+126, // 96: laughing + (2<<7)+126, // 97: scream + (3<<7)+126, // 98: punch + (4<<7)+126, // 99: heart + (5<<7)+126, // 100: footstep + (0<<7)+126, // 101: applause 2 + 102,103,104,105,106,107,108,109,110,111, + (1<<7)+127, // 112: machine gun + (2<<7)+127, // 113: laser gun + (3<<7)+127, // 114: explosion + 115 // 115: fire work +}; + +static uint16 sc88_drum_kit[] = { + 0, // 0: Standard 1 -> Standard + 0, // 1: Standard 2 -> Standard + 2,3,4,5,6,7, + 8, // 8: Room -> Room + 9,10,11,12,13,14,15, + 16, // 16: Power -> Power + 17,18,19,20,21,22,23, + 24, // 24: Electronic -> Electronic + 25, // 25: TR-808 -> TR-808 + 24, // 26: Dance -> Electronic + 27,28,29,30,31, + 32, // 32: Jazz -> Jazz + 33,34,35,36,37,38,39, + 40, // 40: Brush -> Brush + 41,42,43,44,45,46,47, + 48, // 48: Orchestra -> Orchestra + 49, // 49: Ethnic -> + 50, // Kick & Snare -> + 51,52,53,54,55, + 56, // 56: SFX -> SFX + 57 // 57: Rhythm FX -> +}; +static uint16 sc88pro_drum_kit[] = { + 0, // 0: Standard 1 -> Standard + 0, // 1: Standard 2 -> Standard + 0, // 2: Standard 3 -> Standard + 3,4,5,6,7, + 8, // 8: Room -> Room + 25, // 9: Hip-Hop -> TR-808 + 25, // 10: Jungle -> TR-808 + 25, // 11: Techno -> TR-808 + 12,13,14,15, + 16, // 16: Power -> Power + 17,18,19,20,21,22,23, + 24, // 24: Electronic -> Electronic + 25, // 25: TR-808 -> TR-808 + 24, // 26: Dance -> Electronic + 0, // 27: CR-78 -> Standard + 25, // 28: TR-606 -> TR-808 + 25, // 29: TR-707 -> TR-808 + 25, // 30: TR-909 -> TR-808 + 31, + 32, // 32: Jazz -> Jazz + 33,34,35,36,37,38,39, + 40, // 40: Brush -> Brush + 41,42,43,44,45,46,47, + 48, // 48: Orchestra -> Orchestra + 49, // 49: Ethnic -> + 50, // 50: Kick & Snare -> + 51, + 52, // 52: Asia -> + 53, // 53: Cymbal & Claps -> + 54,55, + 56, // 56: SFX -> SFX + 57, // 57: Rhythm FX -> + 58 // 58: Rhythm FX 2 -> +}; + +#define XG_DRUM_VOICE_FIRST_NOTE 13 +#define XG_DRUM_VOICE_LAST_NOTE 34 +static uint8 xg_drum_voice[][2] = { // bank msb 127, lsb 0, prog 0 + {0,86}, // 13: surdo mute + {0,87}, // 14: surdo open + {0,27}, // 15: hi q + {0,28}, // 16: whip slap + {0,29}, // 17: scratch push + {0,30}, // 18: scratch pull + {0,26}, // 19: finger snap (no tone) + {56,51}, // 20: click noise + {0,33}, // 21: metronome click + {0,34}, // 22: metronome bell + {0,32}, // 23: seq click l + {0,32}, // 24: seq click h + {40,38}, // 25: brush tap + {40,40}, // 26: brush swirl l + {40,39}, // 27: brush slap + {40,40}, // 28: brush swirl h + {0,25}, // 29: snare roll + {0,85}, // 30: castanet + {0,38}, // 31: snare l + {0,31}, // 32: sticks + {0,36}, // 33: bass drum l + {0,38} // 34: open rim shot +}; + +#define MAX_NOTE_CHANNELS 64 + +static NoteChannel note_channel[MAX_NOTE_CHANNELS]; +static uint16 bend_sense[MAX_CHANNELS], master_tune[MAX_CHANNELS]; +static uint8 rpn_addr[MAX_CHANNELS], nrpn_lsb[MAX_CHANNELS], nrpn_msb[MAX_CHANNELS]; +static long instrument_number[MAX_CHANNELS]; +static char instrument_name[MAX_CHANNELS][32]; +static Boolean drum_part[MAX_CHANNELS], rpn_flag, prescan = 0; + static void init_variable(void) { start_tic = TickCount(); @@ -86,18 +243,30 @@ static void init_variable(void) static int open_output(void) { - init_variable(); + int i; + // open the note allocator component gNoteAllocator = OpenDefaultComponent(kNoteAllocatorComponentType, 0); if(gNoteAllocator == NULL){ + ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"open_output fail:"); close_output(); return -1; + }else{ + ctl->cmsg(CMSG_INFO,VERB_VERBOSE,"open_output success:"); } dmp.fd = 1; //normaly opened flag + for(i = 0; i < MAX_CHANNELS; i++) + bend_sense[i] = 0x100; return 0; } -static unsigned long current_tick(void) +static int output_data(char *, int32) +{ + // Never called + return 0; +} + +static long current_tick(void) { return TickCount() - start_tic; } @@ -115,65 +284,283 @@ static void close_output(void) dmp.fd = -1; //disabled } +static void qt_ctl_note_event(int channel, int note, int velocity) +{ + CtlEvent ce; + ce.type = CTLE_NOTE; + ce.v1 = (velocity ? VOICE_ON : VOICE_FREE); + ce.v2 = channel; + ce.v3 = note; + ce.v4 = velocity; + if(ctl->trace_playing && !midi_trace.flush_flag) + push_midi_trace_ce(ctl->event, &ce); + else + ctl->event(&ce); +} + static void ctl_timestamp(void) { long secs; CtlEvent ce; static int last_secs = -1; - secs = (long)(current_tick() / 60); + secs = current_tick() / 60; if(secs == last_secs) return; ce.type = CTLE_CURRENT_TIME; ce.v1 = last_secs = secs; - ctl->event(&ce); + if(ctl->trace_playing && !midi_trace.flush_flag) + push_midi_trace_ce(ctl->event, &ce); + else + ctl->event(&ce); +} + +static void ctl_prog_event(int channel, int program) +{ + CtlEvent ce; + ce.type = CTLE_PROGRAM; + ce.v1 = channel; + ce.v2 = program; + ce.v3 = (long)instrument_name[channel]; + if(ctl->trace_playing && !midi_trace.flush_flag) + push_midi_trace_ce(ctl->event, &ce); + else + ctl->event(&ce); +} + +static int xg_instrument_number(int ch, int program) +{ + if(channel[ch].bank_msb == 64) + return kFirstGSInstrument + xg_sfx_voice[program]; + switch(channel[ch].bank_lsb){ + case 8: + switch(program){ + case 40: return kFirstGSInstrument + (8<<7) + 40; // Slow Violin + case 80: return kFirstGSInstrument + (1<<7) + 80; // Square + case 81: return kFirstGSInstrument + (1<<7) + 81; // Saw + case 102: return kFirstGSInstrument + (2<<7) + 102; // Echo Pan + } + break; + case 14: + switch(program){ + case 102: return kFirstGSInstrument + (2<<7) + 102; // Echo Pan + } + break; + case 16: + switch(program){ + case 24: return kFirstGSInstrument + (32<<7) + 24; // Nylon Gt.2 + case 52: return kFirstGSInstrument + (32<<7) + 52; // Choir Aahs 2 + } + break; + case 18: + switch(program){ + case 0: return kFirstGSInstrument + (16<<7) + 0; // Piano 1d + case 57: return kFirstGSInstrument + (1<<7) + 57; // Trombone 2 + } + break; + case 25: + switch(program){ + case 6: return kFirstGSInstrument + (24<<7) + 6; // Coupled hps. + case 24: return kFirstGSInstrument + (16<<7) + 24; // Nylon Gt.3 + } + break; + case 27: + switch(program){ + case 62: return kFirstGSInstrument + (8<<7) + 62; // Synth Brass 3 + } + break; + case 32: + switch(program){ + case 2: return kFirstGSInstrument + (8<<7) + 4; // Detuned EP1 + case 16: return kFirstGSInstrument + (8<<7) + 16; // Detuned Or.1 + case 17: return kFirstGSInstrument + (8<<7) + 17; // Detuned Or.2 + case 19: return kFirstGSInstrument + (16<<7) + 19; // Church Or.2 + case 21: return kFirstGSInstrument + (8<<7) + 21; // Accordion It. + case 27: return kFirstGSInstrument + (8<<7) + 27; // Chorus Gt. + case 60: return kFirstGSInstrument + (1<<7) + 60; // French horn 2 + } + break; + case 33: + switch(program){ + case 16: return kFirstGSInstrument + (16<<7) + 16; // 60's Organ 1 + } + break; + case 34: + switch(program){ + case 16: return kFirstGSInstrument + (16<<7) + 16; // 60's Organ 1 + } + break; + case 35: + switch(program){ + case 6: return kFirstGSInstrument + (8<<7) + 6; // Coupled hps. + case 19: return kFirstGSInstrument + (8<<7) + 19; // Church Or.2 + case 25: return kFirstGSInstrument + (8<<7) + 25; // 12-str Gt. + case 50: return kFirstGSInstrument + (8<<7) + 50; // Syn.String 3 + case 104: return kFirstGSInstrument + (1<<7) + 104; // Sitar 2 + } + break; + case 37: + switch(program){ + case 16: return kFirstGSInstrument + (16<<7) + 16; // 60's Organ 1 + } + break; + case 40: + switch(program){ + case 28: return kFirstGSInstrument + (8<<7) + 28; // Funk Gt. + case 30: return kFirstGSInstrument + (8<<7) + 30; // DistortionGt + case 38: return kFirstGSInstrument + (1<<7) + 38; // SynthBass101 + case 48: return kFirstGSInstrument + (8<<7) + 48; // Orchestra + case 61: return kFirstGSInstrument + (8<<7) + 61; // Brass 2 + case 63: return kFirstGSInstrument + (8<<7) + 63; // Synth Brass4 + } + break; + case 41: + switch(program){ + case 30: return kFirstGSInstrument + (8<<7) + 30; // Feedback Gt. + case 48: return kFirstGSInstrument + (8<<7) + 48; // Orchestra + case 81: return kFirstGSInstrument + (8<<7) + 81; // Doctor Solo + } + break; + case 43: + switch(program){ + case 28: return kFirstGSInstrument + (16<<7) + 28; // Funk Gt.2 + } + break; + case 64: + switch(program){ + case 4: return kFirstGSInstrument + (24<<7) + 4; // 60's E.Piano + case 62: return kFirstGSInstrument + (16<<7) + 62; // AnalogBrass1 + case 63: return kFirstGSInstrument + (16<<7) + 63; // AnalogBrass2 + case 98: return kFirstGSInstrument + (1<<7) + 98; // Syn Mallet + case 102: return kFirstGSInstrument + (1<<7) + 102; // Echo Bell + case 117: return kFirstGSInstrument + (8<<7) + 117; // Melo.Tom 2 + case 118: return kFirstGSInstrument + (8<<7) + 118; // 808 Tom + } + break; + case 65: + switch(program){ + case 31: return kFirstGSInstrument + (8<<7) + 31; // Gt.Feedback + case 80: return kFirstGSInstrument + (8<<7) + 80; // Sine Wave + case 117: return kFirstGSInstrument + (8<<7) + 117; // Melo.Tom 2 + case 118: return kFirstGSInstrument + (9<<7) + 118; // Elec Prec + } + break; + case 66: + switch(program){ + case 38: return kFirstGSInstrument + (16<<7) + 39; // Rubber Bass + case 80: return kFirstGSInstrument + (8<<7) + 80; // Sine Wave + case 117: return kFirstGSInstrument + (8<<7) + 117; // Melo.Tom 2 + } + break; + case 96: + switch(program){ + case 14: return kFirstGSInstrument + (8<<7) + 14; // Church Bell + case 24: return kFirstGSInstrument + (8<<7) + 24; // Ukulele + case 25: return kFirstGSInstrument + (16<<7) + 25; // Mandolin + case 107: return kFirstGSInstrument + (8<<7) + 107; // Taisho Koto + case 115: return kFirstGSInstrument + (8<<7) + 115; // Castanets + } + break; + case 97: + switch(program){ + case 14: return kFirstGSInstrument + (9<<7) + 14; // Carillon + } + break; + } + return kFirstGMInstrument + program; } -static int do_event(void *p) +static void set_instrument(MidiEvent *ev) +{ + long instrumentNumber; + int ch = ev->channel; + + channel[ch].program = ev->a; + if(drum_part[ch]){ + if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 2) // SC-88 Map + instrumentNumber = kFirstDrumkit + sc88_drum_kit[ev->a] + 1; + else if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 3) // SC-88Pro Map + instrumentNumber = kFirstDrumkit + sc88pro_drum_kit[ev->a] + 1; + else + instrumentNumber = kFirstDrumkit + ev->a + 1; + } + else { + if(play_system_mode == GS_SYSTEM_MODE) + instrumentNumber = kFirstGSInstrument + (channel[ch].bank_msb<<7) + ev->a; + else if(play_system_mode == XG_SYSTEM_MODE) + instrumentNumber = xg_instrument_number(ch, ev->a); + else + instrumentNumber = kFirstGMInstrument + ev->a; + } + if(instrument_number[ch] != instrumentNumber){ + NoteRequest nr; + long index, part; + OSType synthType; + Str31 name; + SynthesizerConnections connections; + MusicComponent mc; + + instrument_number[ch] = instrumentNumber; + if(note_channel[ch] != NULL) + NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); + nr.info.flags = 0; + nr.info.reserved = 0; + *(short *)(&nr.info.polyphony) = EndianS16_NtoB(8); // 8 voices poliphonic + *(Fixed *)(&nr.info.typicalPolyphony) = EndianU32_NtoB(0x00010000); + NAStuffToneDescription(gNoteAllocator, instrumentNumber, &nr.tone); + NANewNoteChannel(gNoteAllocator, &nr, ¬e_channel[ch]); + NAGetNoteChannelInfo(gNoteAllocator, note_channel[ch], &index, &part); + NAGetRegisteredMusicDevice(gNoteAllocator, index, &synthType, name, &connections, &mc); + MusicGetPartName(mc, part, name); + p2cstrcpy(instrument_name[ch], name); + } + ctl_prog_event(ch, ev->a); +} + +static void play_event_prescan(void *p) { MidiEvent *ev = (MidiEvent *)p; - int ch, rc = RC_NONE, i; - static NoteChannel note_channel[MAX_CHANNELS]; - static uint8 bank_lsb[MAX_CHANNELS], bank_msb[MAX_CHANNELS]; - static uint8 bend_sense[MAX_CHANNELS], master_tune[MAX_CHANNELS]; - static uint8 rpn_flag, rpn_addr[MAX_CHANNELS], nrpn_lsb[MAX_CHANNELS], nrpn_msb[MAX_CHANNELS]; - static Boolean prescan = 0; - - if(!prescan){ - for(ch = 0; ch < MAX_CHANNELS; ch++){ - if(note_channel[ch] != NULL){ - NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); - note_channel[ch] = NULL; - } - bank_lsb[ch] = 0; - bank_msb[ch] = 0; + int ch; + + for(ch = 0; ch < MAX_CHANNELS; ch++){ + if(note_channel[ch] != NULL){ + NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); + note_channel[ch] = NULL; } + instrument_number[ch] = -1; + instrument_name[ch][0] = '\0'; + drum_part[ch] = false; + channel[ch].bank_lsb = 0; + channel[ch].bank_msb = 0; + } + drum_part[9] = true; for(;; ev++){ ch = ev->channel; - if(ev->type == ME_PROGRAM){ - if(note_channel[ch] == NULL){ - long instrumentNumber; - NoteRequest myNoteRequest; - - if(ISDRUMCHANNEL(ch)) - instrumentNumber = kFirstDrumkit + ev->a + 1; - else if(play_system_mode == GS_SYSTEM_MODE) - instrumentNumber = kFirstGSInstrument + ((bank_msb[ch]+1)<<7) + ev->a; - else - instrumentNumber = kFirstGMInstrument + ev->a; - myNoteRequest.info.flags = 0; - myNoteRequest.info.reserved = 0; - *(short *)(&myNoteRequest.info.polyphony) = EndianS16_NtoB(8); // 8 voices poliphonic - *(Fixed *)(&myNoteRequest.info.typicalPolyphony) = EndianU32_NtoB(0x00010000); - NAStuffToneDescription(gNoteAllocator, instrumentNumber, &myNoteRequest.tone); - NANewNoteChannel(gNoteAllocator, &myNoteRequest, ¬e_channel[ch]); - } - } - else if(ev->type == ME_TONE_BANK_LSB){ - bank_lsb[ch] = ev->a; - } - else if(ev->type == ME_TONE_BANK_MSB){ - bank_msb[ch] = ev->a; + if(ev->type == ME_NOTEON && note_channel[ch] == NULL){ + MidiEvent *ev; + + ev->channel = ch; + ev->a = 0; + set_instrument(ev); + } + else if(ev->type == ME_PROGRAM){ + set_instrument(ev); + } + else if(ev->type == ME_TONE_BANK_LSB && ev->a != channel[ch].bank_lsb){ + channel[ch].bank_lsb = ev->a; + } + else if(ev->type == ME_TONE_BANK_MSB && ev->a != channel[ch].bank_msb){ + channel[ch].bank_msb = ev->a; + if(play_system_mode == XG_SYSTEM_MODE && (ev->a == 126 || ev->a == 127) && !drum_part[ch]) + drum_part[ch] = true; + } + else if(ev->type == ME_DRUMPART && !drum_part[ch]){ + MidiEvent *ev; + + ev->channel = ch; + ev->a = channel[ch].program; + set_instrument(ev); + drum_part[ch] = true; } else if(ev->type == ME_RESET){ play_system_mode = ev->a; @@ -181,28 +568,25 @@ static int do_event(void *p) else if(ev->type == ME_EOT){ prescan = 1; for(ch = 0; ch < MAX_CHANNELS; ch++){ - bank_lsb[ch] = 0; - bank_msb[ch] = 0; - } - init_variable(); - break; + channel[ch].bank_lsb = 0; + channel[ch].bank_msb = 0; } + init_variable(); + break; } - return RC_NONE; } +} + +static int wait_event_time(void *p) +{ + MidiEvent *ev = (MidiEvent *)p; + int rc, ch; + for(;;){ - static int timestamp = 1; - long myDelay; - - if( (myDelay = ev->time - (current_tick()*play_mode->rate+30)/60) < 0 ){ - timestamp = 1; + if(ev->time - (current_tick()*play_mode->rate+30)/60 < 0) break; - } - if(timestamp && myDelay > (play_mode->rate>>2)){ - timestamp = 0; - ctl_timestamp(); - } - Delay(1, &myDelay); + trace_loop(); + YieldToAnyThread(); rc = check_apply_control(); if(RC_IS_SKIP_FILE(rc)){ prescan = 0; @@ -211,39 +595,60 @@ static int do_event(void *p) NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); note_channel[ch] = NULL; } - bank_lsb[ch] = 0; - bank_msb[ch] = 0; + channel[ch].bank_lsb = 0; + channel[ch].bank_msb = 0; } + trace_flush(); return rc; } } + return RC_NONE; +} + +static void qt_play_event(void *p) +{ + MidiEvent *ev = (MidiEvent *)p; + int ch, i; + ch = ev->channel; switch(ev->type) { case ME_NOTEON: - NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, ev->b); + if(play_system_mode == XG_SYSTEM_MODE && channel[ch].bank_msb == 127 + && ev->a >= XG_DRUM_VOICE_FIRST_NOTE && ev->a <= XG_DRUM_VOICE_LAST_NOTE){ + int a = ev->a - XG_DRUM_VOICE_FIRST_NOTE; + a = xg_drum_voice[a][1]; + NAPlayNote(gNoteAllocator, note_channel[ch], a, ev->b); + qt_ctl_note_event(ch, ev->a, ev->b); + } + else if(play_system_mode == XG_SYSTEM_MODE && channel[ch].bank_msb == 126){ + NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, ev->b); + qt_ctl_note_event(ch, ev->a, ev->b); + } + else { + NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, ev->b); + qt_ctl_note_event(ch, ev->a, ev->b); + } break; case ME_NOTEOFF: - NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, 0); + if(play_system_mode == XG_SYSTEM_MODE && channel[ch].bank_msb == 127 + && ev->a >= XG_DRUM_VOICE_FIRST_NOTE && ev->a <= XG_DRUM_VOICE_LAST_NOTE){ + int a = ev->a - XG_DRUM_VOICE_FIRST_NOTE; + a = xg_drum_voice[a][1]; + NAPlayNote(gNoteAllocator, note_channel[ch], a, 0); + qt_ctl_note_event(ch, ev->a, 0); + } + else if(play_system_mode == XG_SYSTEM_MODE && channel[ch].bank_msb == 126){ + NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, 0); + qt_ctl_note_event(ch, ev->a, 0); + } + else { + NAPlayNote(gNoteAllocator, note_channel[ch], ev->a, 0); + qt_ctl_note_event(ch, ev->a, 0); + } break; case ME_PROGRAM: - if(note_channel[ch] == NULL){ - long instrumentNumber; - NoteRequest myNoteRequest; - - if(ISDRUMCHANNEL(ch)) - instrumentNumber = kFirstDrumkit + ev->a + 1; - else if(play_system_mode == GS_SYSTEM_MODE) - instrumentNumber = kFirstGSInstrument + ((bank_msb[ch]+1)<<7) + ev->a; - else - instrumentNumber = kFirstGMInstrument + ev->a; - myNoteRequest.info.flags = 0; - myNoteRequest.info.reserved = 0; - *(short *)(&myNoteRequest.info.polyphony) = EndianS16_NtoB(8); // 8 voices poliphonic - *(Fixed *)(&myNoteRequest.info.typicalPolyphony) = EndianU32_NtoB(0x00010000); - NAStuffToneDescription(gNoteAllocator, instrumentNumber, &myNoteRequest.tone); - NANewNoteChannel(gNoteAllocator, &myNoteRequest, ¬e_channel[ch]); - } + set_instrument(ev); break; /* MIDI Events */ case ME_KEYPRESSURE: @@ -251,22 +656,24 @@ static int do_event(void *p) NASetController(gNoteAllocator, note_channel[ch], kControllerAfterTouch, ev->a<<8); break; case ME_PITCHWHEEL: - if(bend_sense[ch]) - NASetController(gNoteAllocator, note_channel[ch], kControllerPitchBend, - ((ev->a + (ev->b<<7) - 0x2000 + 2)>>2)/bend_sense[ch]*bend_sense[ch]); - else - NASetController(gNoteAllocator, note_channel[ch], kControllerPitchBend, - ((ev->a + (ev->b<<7) - 0x2000 + 2)>>2)); + // kControllerPitchBend 256/halfnote + i = (ev->b<<7) + ev->a - 0x2000; + i *= (bend_sense[ch]<<1); + i += (i > 0 ? (1<<12) : -(1<<12)); + i >>= 13; + NASetController(gNoteAllocator, note_channel[ch], kControllerPitchBend, i); break; /* Controls */ case ME_TONE_BANK_LSB: - bank_lsb[ch] = ev->a; + channel[ch].bank_lsb = ev->a; break; case ME_TONE_BANK_MSB: - bank_msb[ch] = ev->a; + channel[ch].bank_msb = ev->a; + if(play_system_mode == XG_SYSTEM_MODE && (ev->a == 126 || ev->a == 127) && !drum_part[ch]) + drum_part[ch] = true; break; case ME_MODULATION_WHEEL: - NASetController(gNoteAllocator, note_channel[ch], kControllerModulationWheel, ev->a<<8); + NASetController(gNoteAllocator, note_channel[ch], kControllerModulationWheel, ev->a); break; case ME_BREATH: NASetController(gNoteAllocator, note_channel[ch], kControllerBreath, ev->a<<8); @@ -291,37 +698,50 @@ static int do_event(void *p) break; case ME_SUSTAIN: // kControllerSustain on/off only - NASetController(gNoteAllocator, note_channel[ch], kControllerSustain, ev->a); - ctl_mode_event(CTLE_SUSTAIN, 1, ch, ev->a >= 64); + NASetController(gNoteAllocator, note_channel[ch], kControllerSustain, ev->a<<8); + ctl_mode_event(CTLE_SUSTAIN, 1, ch, ev->a); break; case ME_PORTAMENTO_TIME_MSB: - // kControllerPortamentoTime - NASetController(gNoteAllocator, note_channel[ch], kControllerPortamentoTime, ev->a); + channel[ch].portamento_time_msb = ev->a; + NASetController(gNoteAllocator, note_channel[ch], kControllerPortamentoTime, + (channel[ch].portamento_time_msb + (channel[ch].portamento_time_lsb<<7))<<1); + break; + case ME_PORTAMENTO_TIME_LSB: + channel[ch].portamento_time_lsb = ev->a; + NASetController(gNoteAllocator, note_channel[ch], kControllerPortamentoTime, + (channel[ch].portamento_time_msb + (channel[ch].portamento_time_lsb<<7))<<1); break; case ME_PORTAMENTO: - NASetController(gNoteAllocator, note_channel[ch], kControllerPortamentoTime, ev->a); + NASetController(gNoteAllocator, note_channel[ch], kControllerPortamento, ev->a<<8); break; case ME_DATA_ENTRY_MSB: if(rpn_flag){ if(rpn_addr[ch] == 0) // pitchbend sensitivity - bend_sense[ch] = ev->a; - else if(rpn_addr[ch] == 1) // master tuning (fine) + bend_sense[ch] = (ev->a<<7) + ev->b; + else if(rpn_addr[ch] == 1){ // master tuning (fine) master_tune[ch] |= ev->a; - else if(rpn_addr[ch] == 2) // master tuning (coarse) + NASetController(gNoteAllocator, note_channel[ch], kControllerMasterTune, master_tune[ch]); + } + else if(rpn_addr[ch] == 2){ // master tuning (coarse) master_tune[ch] |= (ev->a<<7); + NASetController(gNoteAllocator, note_channel[ch], kControllerMasterTune, master_tune[ch]); + } } else { } break; case ME_REVERB_EFFECT: NASetController(gNoteAllocator, note_channel[ch], kControllerReverb, ev->a<<8); + channel[ch].reverb_level = ev->a; + ctl_mode_event(CTLE_REVERB_EFFECT, 1, ch, ev->a); break; case ME_TREMOLO_EFFECT: NASetController(gNoteAllocator, note_channel[ch], kControllerTremolo, ev->a<<8); break; case ME_CHORUS_EFFECT: NASetController(gNoteAllocator, note_channel[ch], kControllerChorus, ev->a<<8); - ctl_mode_event(CTLE_CHORUS_EFFECT, 1, ch, channel[ch].chorus_level); + channel[ch].chorus_level = ev->a; + ctl_mode_event(CTLE_CHORUS_EFFECT, 1, ch, ev->a); break; case ME_CELESTE_EFFECT: NASetController(gNoteAllocator, note_channel[ch], kControllerCeleste, ev->a<<8); @@ -357,6 +777,14 @@ static int do_event(void *p) break; case ME_RESET_CONTROLLERS: NAResetNoteChannel(gNoteAllocator, note_channel[ch]); + ctl_mode_event(CTLE_VOLUME, 1, ch, 0); + ctl_mode_event(CTLE_EXPRESSION, 1, ch, 127); + ctl_mode_event(CTLE_SUSTAIN, 1, ch, 0); + ctl_mode_event(CTLE_MOD_WHEEL, 1, ch, 0); + ctl_mode_event(CTLE_PITCH_BEND, 1, ch, 0x2000); + ctl_prog_event(ch, channel[ch].program); + ctl_mode_event(CTLE_CHORUS_EFFECT, 1, ch, 0); + ctl_mode_event(CTLE_REVERB_EFFECT, 1, ch, 0); break; case ME_ALL_NOTES_OFF: for(i = 0; i < 128; i++) @@ -367,10 +795,10 @@ static int do_event(void *p) case ME_POLY: break; case ME_SOSTENUTO: - NASetController(gNoteAllocator, note_channel[ch], kControllerSostenuto, ev->a<<8); + NASetController(gNoteAllocator, note_channel[ch], kControllerSostenuto, ev->a); break; case ME_SOFT_PEDAL: - NASetController(gNoteAllocator, note_channel[ch], kControllerSoftPedal, ev->a<<8); + NASetController(gNoteAllocator, note_channel[ch], kControllerSoftPedal, ev->a); break; /* TiMidity Extensionals */ case ME_RANDOM_PAN: @@ -397,10 +825,17 @@ static int do_event(void *p) play_system_mode = ev->a; break; case ME_WRD: - push_midi_trace2(wrd_midi_event, - ch, ev->a | (ev->b << 8)); + push_midi_trace2(wrd_midi_event, ch, ev->a | (ev->b<<8)); break; case ME_DRUMPART: + if(!drum_part[ch]){ + MidiEvent *ev; + + ev->channel = ch; + ev->a = channel[ch].program; + set_instrument(ev); + drum_part[ch] = true; + } break; case ME_KEYSHIFT: NASetController(gNoteAllocator, NULL, kControllerMasterTune, ev->a); @@ -409,33 +844,46 @@ static int do_event(void *p) break; case ME_EOT: prescan = 0; - for(ch = 0; ch < MAX_CHANNELS; ch++){ - if(note_channel[ch] != NULL){ - NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); - note_channel[ch] = NULL; - } - bank_lsb[ch] = 0; - bank_msb[ch] = 0; - } - return RC_NONE; + break; } - - return rc; + if(ev->type != ME_EOT) + ctl_timestamp(); } static int acntl(int request, void *arg) { + int rc, ch; + switch(request) { case PM_REQ_MIDI: - return do_event(arg); + if(!prescan) + play_event_prescan(arg); + rc = wait_event_time(arg); + if(RC_IS_SKIP_FILE(rc)) + return rc; + qt_play_event(arg); + return RC_NONE; + case PM_REQ_INST_NAME: + ch = (int)*(char **)arg; + *(char **)arg = instrument_name[ch]; + return 0; case PM_REQ_GETSAMPLES: *(int32 *)arg = current_samples(); return 0; + case PM_REQ_PLAY_START: + init_variable(); case PM_REQ_DISCARD: case PM_REQ_FLUSH: - case PM_REQ_PLAY_START: - init_variable(); + for(ch = 0; ch < MAX_CHANNELS; ch++){ + if(note_channel[ch] != NULL){ + NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); + note_channel[ch] = NULL; + } + channel[ch].bank_lsb = 0; + channel[ch].bank_msb = 0; + } + trace_flush(); return 0; } return -1; diff --git a/timidity/output.h b/timidity/output.h index 1033e82b..015899b7 100644 --- a/timidity/output.h +++ b/timidity/output.h @@ -43,6 +43,10 @@ enum { * with this request. */ + PM_REQ_INST_NAME, /* ARG: char** + * Get Instrument name of channel. + */ + PM_REQ_DISCARD, /* ARG: not-used * Discard the audio device buffer and returns * immediatly. @@ -79,6 +83,14 @@ enum { PM_REQ_PLAY_START, /* ARG: not-used * PM_REQ_PLAY_START is called just before playing. */ + + PM_REQ_GETFILLABLE, /* ARG: int + * Get fillable device queue size + */ + + PM_REQ_GETFILLED /* ARG: int + * Get filled device queue size + */ }; diff --git a/timidity/playmidi.c b/timidity/playmidi.c index b0846075..098d50be 100644 --- a/timidity/playmidi.c +++ b/timidity/playmidi.c @@ -190,6 +190,7 @@ static void update_portamento_controls(int ch); static void update_rpn_map(int ch, int addr, int update_now); static void ctl_prog_event(int ch); static void ctl_timestamp(void); +static void ctl_updatetime(int32 samples); static void ctl_pause_event(int pause, int32 samples); static char *event_name(int type) @@ -214,19 +215,18 @@ static char *event_name(int type) EVENT_NAME(ME_PAN); EVENT_NAME(ME_EXPRESSION); EVENT_NAME(ME_SUSTAIN); - EVENT_NAME(ME_PORTAMENTO_TIME_LSB); EVENT_NAME(ME_PORTAMENTO_TIME_MSB); + EVENT_NAME(ME_PORTAMENTO_TIME_LSB); EVENT_NAME(ME_PORTAMENTO); + EVENT_NAME(ME_PORTAMENTO_CONTROL); EVENT_NAME(ME_DATA_ENTRY_MSB); EVENT_NAME(ME_DATA_ENTRY_LSB); EVENT_NAME(ME_SOSTENUTO); EVENT_NAME(ME_SOFT_PEDAL); -#if 0 EVENT_NAME(ME_HARMONIC_CONTENT); EVENT_NAME(ME_RELEASE_TIME); EVENT_NAME(ME_ATTACK_TIME); EVENT_NAME(ME_BRIGHTNESS); -#endif EVENT_NAME(ME_REVERB_EFFECT); EVENT_NAME(ME_TREMOLO_EFFECT); EVENT_NAME(ME_CHORUS_EFFECT); @@ -243,13 +243,13 @@ static char *event_name(int type) EVENT_NAME(ME_ALL_NOTES_OFF); EVENT_NAME(ME_MONO); EVENT_NAME(ME_POLY); +#if 0 + EVENT_NAME(ME_VOLUME_ONOFF); /* Not supported */ +#endif EVENT_NAME(ME_RANDOM_PAN); EVENT_NAME(ME_SET_PATCH); EVENT_NAME(ME_DRUMPART); EVENT_NAME(ME_KEYSHIFT); -#if 0 - EVENT_NAME(ME_VOLUME_ONOFF); -#endif EVENT_NAME(ME_TEMPO); EVENT_NAME(ME_CHORUS_TEXT); EVENT_NAME(ME_LYRIC); @@ -261,8 +261,11 @@ static char *event_name(int type) EVENT_NAME(ME_RESET); EVENT_NAME(ME_NOTE_STEP); EVENT_NAME(ME_PATCH_OFFS); - EVENT_NAME(ME_WRD); EVENT_NAME(ME_TIMESIG); + EVENT_NAME(ME_WRD); + EVENT_NAME(ME_SHERRY); + EVENT_NAME(ME_BARMARKER); + EVENT_NAME(ME_STEP); EVENT_NAME(ME_LAST); EVENT_NAME(ME_EOT); } @@ -1957,7 +1960,11 @@ static void midi_program_change(int ch, int prog) channel[ch].bank = newbank; channel[ch].altassign = NULL; } - channel[ch].program = prog; + + if(!ISDRUMCHANNEL(ch) && default_program[ch] == SPECIAL_PROGRAM) + channel[ch].program = SPECIAL_PROGRAM; + else + channel[ch].program = prog; if(opt_realtime_playing == 2 && !dr) { @@ -2835,6 +2842,7 @@ static int apply_controls(void) } aq_flush(1); skip_to(0); + ctl_updatetime(0); jump_flag = 1; continue; @@ -2849,6 +2857,7 @@ static int apply_controls(void) if (val >= sample_count) return RC_NEXT; skip_to(val); + ctl_updatetime(val); return rc; case RC_FORWARD: /* >> */ @@ -2867,6 +2876,7 @@ static int apply_controls(void) if(val + cur >= sample_count) return RC_NEXT; skip_to(val + cur); + ctl_updatetime(val + cur); return RC_JUMP; case RC_BACK: /* << */ @@ -2883,9 +2893,15 @@ static int apply_controls(void) if(cur == -1) cur = current_sample; if(cur > val) + { skip_to(cur - val); + ctl_updatetime(cur - val); + } else + { skip_to(0); + ctl_updatetime(0); + } return RC_JUMP; case RC_TOGGLE_PAUSE: @@ -3022,11 +3038,13 @@ static int apply_controls(void) playmidi_output_changed(0); return RC_RELOAD; } + if(intr) + return RC_QUIT; if(play_pause_flag) #ifdef HAVE_USLEEP usleep(300000); #else - sleep(1); + sleep(1); #endif } while (rc != RC_NONE || play_pause_flag); return jump_flag ? RC_JUMP : RC_NONE; @@ -4161,8 +4179,24 @@ static void ctl_timestamp(void) ce.v2 = last_voices = voices; if(ctl->trace_playing && !midi_trace.flush_flag) push_midi_trace_ce(ctl->event, &ce); - else + else if(ctl->event) + ctl->event(&ce); +} + +static void ctl_updatetime(int32 samples) +{ + long secs; + CtlEvent ce; + + secs = (long)(samples / (midi_time_ratio * play_mode->rate)); + ce.type = CTLE_CURRENT_TIME; + ce.v1 = secs; + ce.v2 = 0; + if(ctl->event) + { ctl->event(&ce); + ctl_mode_event(CTLE_REFRESH, 0, 0, 0); + } } static void ctl_prog_event(int ch) diff --git a/timidity/playmidi.h b/timidity/playmidi.h index 76e88704..23ed7bca 100644 --- a/timidity/playmidi.h +++ b/timidity/playmidi.h @@ -64,16 +64,15 @@ enum midi_event_t ME_PORTAMENTO_TIME_MSB, ME_PORTAMENTO_TIME_LSB, ME_PORTAMENTO, + ME_PORTAMENTO_CONTROL, ME_DATA_ENTRY_MSB, ME_DATA_ENTRY_LSB, ME_SOSTENUTO, ME_SOFT_PEDAL, -#if 0 - ME_HARMONIC_CONTENT, /* Not supported */ - ME_RELEASE_TIME, /* Not supported */ - ME_ATTACK_TIME, /* Not supported */ - ME_BRIGHTNESS, /* Not supported */ -#endif + ME_HARMONIC_CONTENT, + ME_RELEASE_TIME, + ME_ATTACK_TIME, + ME_BRIGHTNESS, ME_REVERB_EFFECT, ME_TREMOLO_EFFECT, ME_CHORUS_EFFECT, @@ -120,6 +119,8 @@ enum midi_event_t ME_WRD, /* for MIMPI WRD tracer */ ME_SHERRY, /* for Sherry WRD tracer */ + ME_BARMARKER, + ME_STEP, ME_LAST = 254, /* Last sequence of MIDI list. * This event is reserved for realtime player. diff --git a/timidity/readmidi.c b/timidity/readmidi.c index 5089015e..53b5c816 100644 --- a/timidity/readmidi.c +++ b/timidity/readmidi.c @@ -242,6 +242,45 @@ char *readmidi_make_string_event(int type, char *string, MidiEvent *ev, return text; } +static char *readmidi_make_lcd_event(int type, const uint8 *data, MidiEvent *ev) +{ + char *text; + int len; + StringTableNode *st; + int a, b, i; + + if(string_event_strtab.nstring == 0) + put_string_table(&string_event_strtab, "", 0); + else if(string_event_strtab.nstring == 0x7FFE) + { + SETMIDIEVENT(*ev, 0, type, 0, 0, 0); + return NULL; /* Over flow */ + } + a = (string_event_strtab.nstring & 0xff); + b = ((string_event_strtab.nstring >> 8) & 0xff); + + len = 7+128; + + text = (char *)new_segment(&tmpbuffer, len + 1); + + strcpy(text+1, "gslcd: "); + for( i=0; i<64; i++){ + const char tbl[]= "0123456789ABCDEF"; + text[8+i*2 ]=tbl[data[i]>>4]; + text[8+i*2+1]=tbl[data[i]&0xF]; + } + text[len + 1] = '\0'; + + + st = put_string_table(&string_event_strtab, text, strlen(text + 1) + 1); + reuse_mblock(&tmpbuffer); + + text = st->string; + *text = type; + SETMIDIEVENT(*ev, 0, type, 0, a, b); + return text; +} + /* Computes how many (fractional) samples one MIDI delta-time unit contains */ static void compute_sample_increment(int32 tempo, int32 divisions) { @@ -434,6 +473,11 @@ int convert_midi_control_change(int chn, int type, int val, MidiEvent *ev_ret) case 65: type = ME_PORTAMENTO; break; case 66: type = ME_SOSTENUTO; break; case 67: type = ME_SOFT_PEDAL; break; + case 71: type = ME_HARMONIC_CONTENT; break; + case 72: type = ME_RELEASE_TIME; break; + case 73: type = ME_ATTACK_TIME; break; + case 74: type = ME_BRIGHTNESS; break; + case 84: type = ME_PORTAMENTO_CONTROL; break; case 91: type = ME_REVERB_EFFECT; break; case 92: type = ME_TREMOLO_EFFECT; break; case 93: type = ME_CHORUS_EFFECT; break; @@ -450,13 +494,6 @@ int convert_midi_control_change(int chn, int type, int val, MidiEvent *ev_ret) case 123: type = ME_ALL_NOTES_OFF; break; case 126: type = ME_MONO; break; case 127: type = ME_POLY; break; -#if 0 /* Not supported */ - case 71: type = ME_HARMONIC_CONTENT; break; - case 72: type = ME_RELEASE_TIME; break; - case 73: type = ME_ATTACK_TIME; break; - case 74: type = ME_BRIGHTNESS; break; - case 94: type = ME_VARIATION_EFFECT; break; -#endif default: type = -1; break; } @@ -642,6 +679,30 @@ int parse_sysex_event(uint8 *val, int32 len, MidiEvent *ev) return 0; } + if(len > 9 && /* GS lcd event. by T.Nogami*/ + val[0] == 0x41 && /* Roland ID */ + val[1] == 0x10 && /* Device ID */ + val[2] == 0x45 && + val[3] == 0x12 && + val[4] == 0x10 && + val[5] == 0x01 && + val[6] == 0x00) + { + /* Text Insert for SC */ + uint8 save; + + len -= 2; + save = val[len]; + val[len] = '\0'; + if(readmidi_make_lcd_event(ME_INSERT_TEXT, (uint8 *)val + 7, ev)) + { + val[len] = save; + return 1; + } + val[len] = save; + return 0; + } + if(len >= 8 && val[0] == 0x43 && val[1] == 0x10 && @@ -2211,7 +2272,7 @@ static int check_need_cache(URL url, char *filename) t1 = url_check_type(filename); t2 = url->type; return (t1 == URL_http_t || t1 == URL_ftp_t || t1 == URL_news_t) - && t2 != URL_arc_stream_t; + && t2 != URL_arc_t; } #else /*ARGSUSED*/ diff --git a/timidity/timidity.c b/timidity/timidity.c index 3bf56d65..aadaee35 100644 --- a/timidity/timidity.c +++ b/timidity/timidity.c @@ -2670,13 +2670,21 @@ static RETSIGTYPE sigterm_exit(int sig) s[2] = '\n'; write(2, s, 3); - if(sig == SIGINT) - intr = 1; + if(sig == SIGINT && intr < 5) + { + intr++; + signal(SIGINT, sigterm_exit); /* For SysV base */ + } else safe_exit(1); } #endif /* HAVE_SIGNAL */ +static void timidity_arc_error_handler(char *error_message) +{ + ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "%s", error_message); +} + MAIN_INTERFACE void timidity_start_initialize(void) { int i; @@ -2727,6 +2735,7 @@ MAIN_INTERFACE void timidity_start_initialize(void) default_program[i] = DEFAULT_PROGRAM; memset(channel[i].drums, 0, sizeof(channel[i].drums)); } + arc_error_handler = timidity_arc_error_handler; if(is_first) /* initialize once time */ { @@ -2762,38 +2771,62 @@ MAIN_INTERFACE void timidity_start_initialize(void) MAIN_INTERFACE int timidity_pre_load_configuration(void) { -#ifdef IA_W32GUI - extern char *ConfigFile; - if(!read_config_file(ConfigFile, 0)) - got_a_configuration=1; -#elif defined(__W32__) +#if defined(__W32__) + /* Windows */ char *strp; int check; - char local[1024]; - - if(GetModuleFileName(NULL,local,1023)){ - local[1023]='\0'; - if(strp=strrchr(local,'\\')){ - *(++strp)='\0'; - strcat(local,"TIMIDITY.CFG"); - if((check = open(local, 0)) >= 0){ - close(check); - if(!read_config_file(local, 0)) - got_a_configuration=1; - } - } - } - if(!got_a_configuration){ - GetWindowsDirectory(local,1023 - 13); - strcat(local,"\\TIMIDITY.CFG"); - if(!read_config_file(local, 0)) - got_a_configuration=1; + char local[1024]; + +#ifdef IA_W32GUI + extern char *ConfigFile; + strncpy(local, ConfigFile, sizeof(local)); +#else + /* !IA_W32GUI */ + GetWindowsDirectory(local, 1023 - 13); + strcat(local, "\\TIMIDITY.CFG"); +#endif + + /* First, try read system configuration file. + * Default is C:\WINDOWS\TIMIDITY.CFG + */ + if((check = open(local, 0)) >= 0) + { + close(check); + if(!read_config_file(local, 0)) + got_a_configuration = 1; + } + + /* Next, try read configuration file which is in the + * TiMidity directory. + */ + if(GetModuleFileName(NULL, local, 1023)) + { + local[1023] = '\0'; + if(strp = strrchr(local, '\\')) + { + *(++strp)='\0'; + strcat(local,"TIMIDITY.CFG"); + if((check = open(local, 0)) >= 0) + { + close(check); + if(!read_config_file(local, 0)) + got_a_configuration = 1; + } } + } + #else + /* UNIX */ if(!read_config_file(CONFIG_FILE, 0)) - got_a_configuration=1; + got_a_configuration = 1; #endif + /* Try read configuration file which is in the + * $HOME (or %HOME% for DOS) directory. + * Please setup each user preference in $HOME/.timidity.cfg + * (or %HOME%/timidity.cfg for DOS) + */ + if(read_user_config_file()) ctl->cmsg(CMSG_INFO, VERB_NOISY, "Warning: Can't read ~/.timidity.cfg correctly"); @@ -2807,8 +2840,8 @@ MAIN_INTERFACE int timidity_post_load_configuration(void) cmderr = 0; if(!got_a_configuration) { - if(!try_config_again || read_config_file(CONFIG_FILE, 0)) - cmderr++; + if(try_config_again && !read_config_file(CONFIG_FILE, 0)) + got_a_configuration = 1; } if(opt_config_string.nstring > 0) @@ -2820,13 +2853,19 @@ MAIN_INTERFACE int timidity_post_load_configuration(void) if(config_string_list != NULL) { for(i = 0; config_string_list[i]; i++) - if(read_config_file(config_string_list[i], 1)) + { + if(!read_config_file(config_string_list[i], 1)) + got_a_configuration = 1; + else cmderr++; + } free(config_string_list[0]); free(config_string_list); } } + if(!got_a_configuration) + cmderr++; return cmderr; } @@ -2888,7 +2927,7 @@ MAIN_INTERFACE int timidity_play_main(int nfiles, char **files) { int need_stdin = 0, need_stdout = 0; int i; - extern ArchiveFileList *archive_file_list; + int output_fail = 0; if(nfiles == 0 && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character)) return 0; @@ -2963,8 +3002,11 @@ MAIN_INTERFACE int timidity_play_main(int nfiles, char **files) ctl->cmsg(CMSG_FATAL, VERB_NORMAL, "Couldn't open %s (`%c')", play_mode->id_name, play_mode->id_character); + output_fail = 1; +#ifndef IA_W32GUI ctl->close(); return 2; +#endif /* IA_W32GUI */ } if(!control_ratio) @@ -2977,8 +3019,11 @@ MAIN_INTERFACE int timidity_play_main(int nfiles, char **files) } init_load_soundfont(); - aq_setup(); - timidity_init_aq_buff(); + if(!output_fail) + { + aq_setup(); + timidity_init_aq_buff(); + } if(allocate_cache_size > 0) resamp_cache_reset(); @@ -3027,7 +3072,7 @@ MAIN_INTERFACE int timidity_play_main(int nfiles, char **files) close_soundspec(); #endif /* SUPPORT_SOUNDSPEC */ - close_archive_files(archive_file_list); + free_archive_files(); #ifdef SUPPORT_SOCKET url_news_connection_cache(URL_NEWS_CLOSE_CACHE); #endif /* SUPPORT_SOCKET */ @@ -3067,18 +3112,6 @@ int main(int argc, char **argv) setreuid(uid, uid); #endif -#if 0 /* For console redirect */ - memcpy(stdout, fopen("/tmp/console", "a"), sizeof(*_iob)); - memcpy(stderr, stdout, sizeof(*_iob)); - printf("## TiMidity++ starts\n"); - { int i; - for(i = 0; i < argc; i++) - printf("[%d]: <%s>\n", i, argv[i]); - } - fflush(stdout); -#endif - - #ifdef main { static int maincnt = 0; @@ -3152,8 +3185,50 @@ int main(int argc, char **argv) if(err || (optind >= argc && !strchr(INTERACTIVE_INTERFACE_IDS, ctl->id_character))) { - ctl->cmsg(CMSG_ERROR, VERB_NORMAL, - "Try %s -h for help", program_name); + if(!got_a_configuration) + { +#ifdef __W32__ + char config1[1024]; + char config2[1024]; + + memset(config1, 0, sizeof(config1)); + memset(config2, 0, sizeof(config2)); +#ifdef IA_W32GUI + { + extern char *ConfigFile; + strncpy(config1, ConfigFile, sizeof(config1)); + } +#else + /* !IA_W32GUI */ + GetWindowsDirectory(config1, 1023 - 13); + strcat(config1, "\\TIMIDITY.CFG"); +#endif + + if(GetModuleFileName(NULL, config2, 1023)) + { + char *strp; + config2[1023] = '\0'; + if(strp = strrchr(config2, '\\')) + { + *(++strp)='\0'; + strcat(config2,"TIMIDITY.CFG"); + } + } + + ctl->cmsg(CMSG_FATAL, VERB_NORMAL, + "%s: Can't read any configuration file.\nPlease check " + "%s or %s", program_name, config1, config2); +#else + ctl->cmsg(CMSG_FATAL, VERB_NORMAL, + "%s: Can't read any configuration file.\nPlease check " + CONFIG_FILE, program_name); +#endif /* __W32__ */ + } + else + { + ctl->cmsg(CMSG_ERROR, VERB_NORMAL, + "Try %s -h for help", program_name); + } return 1; /* problems with command line */ } diff --git a/timidity/wrdt.c b/timidity/wrdt.c index dd31de5e..789d2fd7 100644 --- a/timidity/wrdt.c +++ b/timidity/wrdt.c @@ -207,7 +207,7 @@ static struct timidity_file *try_wrd_open_file(char *prefix, char *fn) path[len1] = '\0'; } strcat(path, fn); - tf = open_file(path, 0, OF_NORMAL); + tf = open_file(path, 0, OF_SILENT); reuse_mblock(&buf); return tf; } diff --git a/utils/mac_readdir.c b/utils/mac_readdir.c index 33c38a32..767ad69d 100644 --- a/utils/mac_readdir.c +++ b/utils/mac_readdir.c @@ -24,4 +24,7 @@ Macintosh readdir */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ #include "mac_readdir.h" diff --git a/utils/mac_util.c b/utils/mac_util.c index 4d8b9bb4..47f671dd 100644 --- a/utils/mac_util.c +++ b/utils/mac_util.c @@ -22,6 +22,9 @@ mac_util.c */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ #include #include #include @@ -183,6 +186,7 @@ void mac_TransPathSeparater(const char str[], char out[]) } } } +#if 0 char** sys_errlist_() { @@ -195,26 +199,14 @@ char** sys_errlist_() if( errno==ENOSPC ) strcpy(s,"Out of Space."); else - sprintf(s, "error no.%d", errno); + snprintf(s, 80, "error no.%d", errno); return(ret-errno); } - +#endif /*0*/ // ************************************************** #pragma mark - -char* strdup(const char* org) -{ - char* newstring; - - newstring=(char*)malloc(strlen(org)+1); - if( newstring==0 ){ - return 0; - } - strcpy(newstring, org); - return newstring; -} - /* special fgets */ /* allow \r as return code */ char* mac_fgets( char buf[], int n, FILE* file) @@ -229,7 +221,9 @@ char* mac_fgets( char buf[], int n, FILE* file) } buf[i]=0; - if( buf[0]==EOF && feof(file) ) return 0; + if( i>0 && buf[i-1]==EOF ){ buf[i-1]=0; i--; } + + if( i==0 && c==EOF && feof(file) ) return 0; if( i==1 && buf[0]=='\n' ){ /* probably dos LF (Unix blank line?)*/ diff --git a/utils/mac_util.h b/utils/mac_util.h index c68bfd93..92ba556f 100644 --- a/utils/mac_util.h +++ b/utils/mac_util.h @@ -57,12 +57,12 @@ void TEReadFile(char* filename, TEHandle te); Because CodeWarrior does not support sys_errlist[]. If your compiler supports, you need not applend this file. */ -char** sys_errlist_(); -#define sys_errlist sys_errlist_() +//char** sys_errlist_(); +//#define sys_errlist sys_errlist_() char* strdup(const char*); //char* strncasecmp(const char*, const char*, int); #define strcasecmp mac_strcasecmp -#define strncasecmp mac_strncasecmp +//#define strncasecmp mac_strncasecmp int mac_strcasecmp(const char *s1, const char *s2); int mac_strncasecmp(const char *s1, const char *s2, size_t n ); int strtailcasecmp(const char *s1, const char *s2); diff --git a/utils/support.c b/utils/support.c index eb581261..24c0bc6d 100644 --- a/utils/support.c +++ b/utils/support.c @@ -33,8 +33,12 @@ #include #endif /* HAVE_UNISTD_H */ #include +#ifdef HAVE_SYS_TIME_H #include +#endif /* HAVE_SYS_TIME_H */ +#ifdef HAVE_SYS_TYPES_H #include +#endif /* HAVE_SYS_TYPES_H */ #ifndef NO_STRING_H #include #else @@ -47,10 +51,13 @@ #ifdef HAVE_SYS_PARAM_H #include #endif /* HAVE_SYS_PARAM_H */ +#include #include "timidity.h" #include "mblock.h" - +#ifdef __MACOS__ +#include +#endif #ifndef HAVE_VSNPRINTF /* From glib-1.1.13:gstrfuncs.c @@ -747,6 +754,12 @@ int usleep(unsigned int usec) Sleep(usec / 1000); return 0; } +#elif __MACOS__ +int usleep(unsigned int /*usec*/) +{ + YieldToAnyThread(); + return 0; +} #else int usleep(unsigned int usec) { -- 2.11.0